From 4af73f4a5261282f492b3a4f9b4f14567ee55107 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Aug 2013 13:41:34 -0400 Subject: [PATCH 01/13] Fix file sync error in Fx23+ for empty attachment paths And fix reporting of non-OS.File file sync errors --- chrome/content/zotero/xpcom/storage.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index 97bd845da..d7262db10 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -938,7 +938,7 @@ Zotero.Sync.Storage = new function () { Components.utils.import("resource://gre/modules/osfile.jsm") let checkItems = function () { - if (!items.length) return; + if (!items.length) return Q(); //Zotero.debug("Memory usage: " + memmgr.resident); @@ -948,6 +948,11 @@ Zotero.Sync.Storage = new function () { //Zotero.debug("Checking attachment file for item " + lk); let nsIFile = item.getFile(row, true); + if (!nsIFile) { + Zotero.debug("Marking pathless attachment " + lk + " as in-sync"); + updatedStates[item.id] = Zotero.Sync.Storage.SYNC_STATE_IN_SYNC; + return checkItems(); + } let file = null; return Q(OS.File.open(nsIFile.path)) .then(function (promisedFile) { @@ -1023,7 +1028,7 @@ Zotero.Sync.Storage = new function () { .then(function (fileHash) { if (row.hash && row.hash == fileHash) { Zotero.debug("Mod time didn't match (" + fmtime + "!=" + mtime + ") " - + "but hash did for " + file.leafName + " for item " + lk + + "but hash did for " + nsIFile.leafName + " for item " + lk + " -- updating file mod time"); try { nsIFile.lastModifiedTime = row.mtime; @@ -1054,14 +1059,16 @@ Zotero.Sync.Storage = new function () { return; } - if (e instanceof OS.File.Error && e.becauseClosed) { - Zotero.debug("File was closed", 2); - } - else { + if (e instanceof OS.File.Error) { + if (e.becauseClosed) { + Zotero.debug("File was closed", 2); + } Zotero.debug(e); Zotero.debug(e.toString()); + throw new Error("Error " + e.operation + " " + nsIFile.path); } - throw new Error("Error " + e.operation + " " + nsIFile.path); + + throw e; }) .then(function () { return checkItems(); From 610017e4dfd70a06f311ce648b540fe051019f06 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Aug 2013 14:15:41 -0400 Subject: [PATCH 02/13] Fix file sync error on Windows --- chrome/content/zotero/xpcom/storage.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index d7262db10..310eb69ee 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -1027,16 +1027,21 @@ Zotero.Sync.Storage = new function () { return Zotero.Utilities.Internal.md5Async(file) .then(function (fileHash) { if (row.hash && row.hash == fileHash) { - Zotero.debug("Mod time didn't match (" + fmtime + "!=" + mtime + ") " - + "but hash did for " + nsIFile.leafName + " for item " + lk - + " -- updating file mod time"); - try { - nsIFile.lastModifiedTime = row.mtime; - } - catch (e) { - Zotero.File.checkFileAccessError(e, nsIFile, 'update'); - } - return; + // We have to close the file before modifying it from the main + // thread (at least on Windows, where assigning lastModifiedTime + // throws an NS_ERROR_FILE_IS_LOCKED otherwise) + return Q(file.close()) + .then(function () { + Zotero.debug("Mod time didn't match (" + fmtime + "!=" + mtime + ") " + + "but hash did for " + nsIFile.leafName + " for item " + lk + + " -- updating file mod time"); + try { + nsIFile.lastModifiedTime = row.mtime; + } + catch (e) { + Zotero.File.checkFileAccessError(e, nsIFile, 'update'); + } + }); } // Mark file for upload From c29720743a6f3ef7dce9ee39fd0415a1c9440f11 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Aug 2013 14:31:53 -0400 Subject: [PATCH 03/13] Fix file sync error in Gecko 23+ if local file path is too long --- chrome/content/zotero/xpcom/storage.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index 310eb69ee..b04e7918d 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -1058,7 +1058,12 @@ Zotero.Sync.Storage = new function () { } }) .catch(function (e) { - if (e instanceof OS.File.Error && e.becauseNoSuchFile) { + if (e instanceof OS.File.Error && + (e.becauseNoSuchFile + // This can happen if a path is too long on Windows, + // e.g. a file is being accessed on a VM through a share + // (and probably in other cases). + || (e.winLastError && e.winLastError == 3))) { Zotero.debug("Marking attachment " + lk + " as missing"); updatedStates[item.id] = Zotero.Sync.Storage.SYNC_STATE_TO_DOWNLOAD; return; From 84c5a1bffac7dfaf9ddb4e8861f27e026eb6de41 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Aug 2013 14:32:44 -0400 Subject: [PATCH 04/13] Tweak error message for OS.File errors during file sync --- chrome/content/zotero/xpcom/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index b04e7918d..1c71bbfea 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -1075,7 +1075,7 @@ Zotero.Sync.Storage = new function () { } Zotero.debug(e); Zotero.debug(e.toString()); - throw new Error("Error " + e.operation + " " + nsIFile.path); + throw new Error("Error for operation '" + e.operation + "' for " + nsIFile.path); } throw e; From d5fcde0612023befa026a8de3dbe877e5626a641 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Aug 2013 15:19:37 -0400 Subject: [PATCH 05/13] Disable OS.File for file syncs on Windows Date: Thu, 8 Aug 2013 15:21:11 -0400 Subject: [PATCH 06/13] Add missing semicolon --- chrome/content/zotero/xpcom/storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/storage.js b/chrome/content/zotero/xpcom/storage.js index 0b663df4c..8b6bdbbc9 100644 --- a/chrome/content/zotero/xpcom/storage.js +++ b/chrome/content/zotero/xpcom/storage.js @@ -939,7 +939,7 @@ Zotero.Sync.Storage = new function () { throw new Task.Result(changed); } - Components.utils.import("resource://gre/modules/osfile.jsm") + Components.utils.import("resource://gre/modules/osfile.jsm"); let checkItems = function () { if (!items.length) return Q(); From 8f0dac0eb48751f52f4b68238476004562f5292a Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Aug 2013 15:24:33 -0400 Subject: [PATCH 07/13] Update version and styles --- chrome/content/zotero/xpcom/zotero.js | 2 +- install.rdf | 2 +- styles | 2 +- update.rdf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index b331840fc..2d90a8569 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -39,7 +39,7 @@ const ZOTERO_CONFIG = { BOOKMARKLET_ORIGIN : 'https://www.zotero.org', HTTP_BOOKMARKLET_ORIGIN : 'http://www.zotero.org', BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/', - VERSION: "4.0.10.SOURCE" + VERSION: "4.0.11.SOURCE" }; // Commonly used imports accessible anywhere diff --git a/install.rdf b/install.rdf index 603aad63f..458bed60a 100644 --- a/install.rdf +++ b/install.rdf @@ -6,7 +6,7 @@ zotero@chnm.gmu.edu Zotero - 4.0.10.SOURCE + 4.0.11.SOURCE Center for History and New Media
George Mason University
Dan Cohen Sean Takats diff --git a/styles b/styles index d7eaec6c1..01e0f42ae 160000 --- a/styles +++ b/styles @@ -1 +1 @@ -Subproject commit d7eaec6c1e691b661facc0b4db491a1052c3bf1a +Subproject commit 01e0f42aee7595b7cccafe731de57f277c2b76df diff --git a/update.rdf b/update.rdf index 6277e0903..5ecd6d00f 100644 --- a/update.rdf +++ b/update.rdf @@ -7,7 +7,7 @@ - 4.0.10.SOURCE + 4.0.11.SOURCE {ec8030f7-c20a-464f-9b0e-13a3a9e97384} From 2069b5b396c0ec61717f4f66e4c96e57b8c08607 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 9 Aug 2013 10:55:29 -0400 Subject: [PATCH 08/13] Fix switching in and out of connector mode Broken by 9d3f55be5193763d4c6d2afc3ddecea0bf5a9f39 --- chrome/content/zotero/xpcom/db.js | 7 +++++-- chrome/content/zotero/xpcom/zotero.js | 15 ++++++++------ components/zotero-service.js | 28 +++++++++++++++++++-------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js index e67a24dce..16cc74877 100644 --- a/chrome/content/zotero/xpcom/db.js +++ b/chrome/content/zotero/xpcom/db.js @@ -794,8 +794,11 @@ Zotero.DBConnection.prototype.checkException = function (e) { Zotero.DBConnection.prototype.closeDatabase = function () { if(this._connection) { this.stopDummyStatement(); - this._connection.asyncClose(); - return true; + var deferred = Q.defer(); + this._connection.asyncClose(deferred.resolve); + return deferred.promise; + } else { + return Q(); } } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 2d90a8569..7dbe63ba8 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -423,7 +423,7 @@ Components.utils.import("resource://gre/modules/Services.jsm"); } // Register shutdown handler to call Zotero.shutdown() - var _shutdownObserver = {observe:Zotero.shutdown}; + var _shutdownObserver = {observe:function() { Zotero.shutdown() }}; Services.obs.addObserver(_shutdownObserver, "quit-application", false); try { @@ -783,7 +783,7 @@ Components.utils.import("resource://gre/modules/Services.jsm"); } - this.shutdown = function (subject, topic, data) { + this.shutdown = function(callback) { Zotero.debug("Shutting down Zotero"); try { @@ -811,10 +811,13 @@ Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.forceGC(); // unlock DB - Zotero.DB.closeDatabase(); - - // broadcast that DB lock has been released - Zotero.IPC.broadcast("lockReleased"); + Zotero.DB.closeDatabase().then(function() { + // broadcast that DB lock has been released + Zotero.IPC.broadcast("lockReleased"); + callback(); + }); + } else { + callback(); } } catch(e) { Zotero.debug(e); diff --git a/components/zotero-service.js b/components/zotero-service.js index e00edaa59..2804361c6 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -164,11 +164,16 @@ ZoteroContext.prototype = { */ "switchConnectorMode":function(isConnector) { if(isConnector !== this.isConnector) { - zContext.Zotero.shutdown(); - - // create a new zContext - makeZoteroContext(isConnector); - zContext.Zotero.init(); + zContext.Zotero.shutdown(function() { + try { + // create a new zContext + makeZoteroContext(isConnector); + zContext.Zotero.init(); + } catch(e) { + dump(e.toSource()); + throw e; + } + }); } return zContext; @@ -294,9 +299,16 @@ function ZoteroService() { } catch(e) { if(e === "ZOTERO_SHOULD_START_AS_CONNECTOR") { // if Zotero should start as a connector, reload it - zContext.Zotero.shutdown(); - makeZoteroContext(true); - zContext.Zotero.init(); + zContext.Zotero.shutdown(function() { + try { + makeZoteroContext(true); + zContext.Zotero.init(); + } catch(e) { + dump(e.toSource()); + Components.utils.reportError(e); + throw e; + } + }); } else { dump(e.toSource()); Components.utils.reportError(e); From 8a8093028de2cf31fc90290207a76656950b9756 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 9 Aug 2013 11:00:55 -0400 Subject: [PATCH 09/13] Check if callback exists before calling --- chrome/content/zotero/xpcom/zotero.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 7dbe63ba8..76471f648 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -814,10 +814,10 @@ Components.utils.import("resource://gre/modules/Services.jsm"); Zotero.DB.closeDatabase().then(function() { // broadcast that DB lock has been released Zotero.IPC.broadcast("lockReleased"); - callback(); + if(callback) callback(); }); } else { - callback(); + if(callback) callback(); } } catch(e) { Zotero.debug(e); From a723c8599949a64f6af10c81a8a652feeeaee57c Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 9 Aug 2013 11:10:38 -0400 Subject: [PATCH 10/13] Return a promise from Zotero.shutdown() --- chrome/content/zotero/xpcom/zotero.js | 15 +++++------ components/zotero-service.js | 37 ++++++++------------------- 2 files changed, 16 insertions(+), 36 deletions(-) diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 76471f648..a1c847c17 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -423,7 +423,7 @@ Components.utils.import("resource://gre/modules/Services.jsm"); } // Register shutdown handler to call Zotero.shutdown() - var _shutdownObserver = {observe:function() { Zotero.shutdown() }}; + var _shutdownObserver = {observe:function() { Zotero.shutdown().done() }}; Services.obs.addObserver(_shutdownObserver, "quit-application", false); try { @@ -783,7 +783,7 @@ Components.utils.import("resource://gre/modules/Services.jsm"); } - this.shutdown = function(callback) { + this.shutdown = function() { Zotero.debug("Shutting down Zotero"); try { @@ -811,20 +811,17 @@ Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.forceGC(); // unlock DB - Zotero.DB.closeDatabase().then(function() { + return Zotero.DB.closeDatabase().then(function() { // broadcast that DB lock has been released Zotero.IPC.broadcast("lockReleased"); - if(callback) callback(); }); - } else { - if(callback) callback(); } + + return Q(); } catch(e) { Zotero.debug(e); - throw e; + return Q.reject(e); } - - return true; } diff --git a/components/zotero-service.js b/components/zotero-service.js index 2804361c6..14a59f6a4 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -164,16 +164,11 @@ ZoteroContext.prototype = { */ "switchConnectorMode":function(isConnector) { if(isConnector !== this.isConnector) { - zContext.Zotero.shutdown(function() { - try { - // create a new zContext - makeZoteroContext(isConnector); - zContext.Zotero.init(); - } catch(e) { - dump(e.toSource()); - throw e; - } - }); + zContext.Zotero.shutdown().then(function() { + // create a new zContext + makeZoteroContext(isConnector); + zContext.Zotero.init(); + }).done(); } return zContext; @@ -297,23 +292,11 @@ function ZoteroService() { try { zContext.Zotero.init(); } catch(e) { - if(e === "ZOTERO_SHOULD_START_AS_CONNECTOR") { - // if Zotero should start as a connector, reload it - zContext.Zotero.shutdown(function() { - try { - makeZoteroContext(true); - zContext.Zotero.init(); - } catch(e) { - dump(e.toSource()); - Components.utils.reportError(e); - throw e; - } - }); - } else { - dump(e.toSource()); - Components.utils.reportError(e); - throw e; - } + // if Zotero should start as a connector, reload it + zContext.Zotero.shutdown().then(function() { + makeZoteroContext(true); + zContext.Zotero.init(); + }).done(); } } isFirstLoadThisSession = false; // no longer first load From b82876253c9c4c349642b9df29b8c3182de87834 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 9 Aug 2013 11:37:29 -0400 Subject: [PATCH 11/13] Disable spellchecking in notes until it can be supported for real https://forums.zotero.org/discussion/19771/workaround-to-disable-spell-checker/ Right now you can't iteract with it (to add/ignore words) or change the language (which is probably only English in Standalone) or disable it (without going to about:config). --- resource/tinymce/note.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/tinymce/note.html b/resource/tinymce/note.html index 86e4dda18..d14baad77 100644 --- a/resource/tinymce/note.html +++ b/resource/tinymce/note.html @@ -14,7 +14,7 @@ button_tile_map : true, language : "en", // TODO: localize entities : "160,nbsp", - gecko_spellcheck : true, + gecko_spellcheck : false, convert_urls : false, handle_event_callback : function (event) { From ece36438e39b9fedd536484d338ca965821c5a54 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 9 Aug 2013 11:44:34 -0400 Subject: [PATCH 12/13] Revert "Disable spellchecking in notes until it can be supported for real" This reverts commit b82876253c9c4c349642b9df29b8c3182de87834. We can just leave this alone until we have a proper fix. --- resource/tinymce/note.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/tinymce/note.html b/resource/tinymce/note.html index d14baad77..86e4dda18 100644 --- a/resource/tinymce/note.html +++ b/resource/tinymce/note.html @@ -14,7 +14,7 @@ button_tile_map : true, language : "en", // TODO: localize entities : "160,nbsp", - gecko_spellcheck : false, + gecko_spellcheck : true, convert_urls : false, handle_event_callback : function (event) { From 2dc8fc6912cf9f7617f42d0fe13352d052325a49 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 9 Aug 2013 11:50:10 -0400 Subject: [PATCH 13/13] Update versions --- chrome/content/zotero/xpcom/zotero.js | 2 +- install.rdf | 2 +- update.rdf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index a1c847c17..682dd2524 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -39,7 +39,7 @@ const ZOTERO_CONFIG = { BOOKMARKLET_ORIGIN : 'https://www.zotero.org', HTTP_BOOKMARKLET_ORIGIN : 'http://www.zotero.org', BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/', - VERSION: "4.0.11.SOURCE" + VERSION: "4.0.12.SOURCE" }; // Commonly used imports accessible anywhere diff --git a/install.rdf b/install.rdf index 458bed60a..877342219 100644 --- a/install.rdf +++ b/install.rdf @@ -6,7 +6,7 @@ zotero@chnm.gmu.edu Zotero - 4.0.11.SOURCE + 4.0.12.SOURCE Center for History and New Media
George Mason University
Dan Cohen Sean Takats diff --git a/update.rdf b/update.rdf index 5ecd6d00f..adb6a004d 100644 --- a/update.rdf +++ b/update.rdf @@ -7,7 +7,7 @@ - 4.0.11.SOURCE + 4.0.12.SOURCE {ec8030f7-c20a-464f-9b0e-13a3a9e97384}