From 5787b230f7d81abbae6ca1956fb0c2c31c18b959 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Sun, 11 Aug 2013 20:51:16 -0400 Subject: [PATCH] Use asynchronous DB and file access for schema checks/updates This change should improve Firefox startup time. If the Zotero pane is opened before Zotero has initialized, the pane will be blocked with a progress bar until it's done. Standalone currently does the same, but it should be changed to just delay opening the window if possible. The upgrade wizard has been disabled for schema upgrades, in the hope that upgrades can be done in a way that won't break compatibility with earlier versions (or that can at least be done in a way such that we can put out point releases of the last major version that provide compatibility during beta/post-upgrade periods). This patch likely breaks many things, and definitely breaks connector mode. This change also removes upgrade steps for databases from Zotero 2.1b2 and earlier. Users with such databases will need to upgrade via Zotero 4.0.x first or delete their data directories and start anew. This should only affect users who haven't opened Zotero since Nov. 2010. --- chrome/content/zotero/browser.js | 2 +- chrome/content/zotero/fileInterface.js | 2 +- chrome/content/zotero/itemPane.js | 9 +- chrome/content/zotero/overlay.js | 176 +- chrome/content/zotero/overlay.xul | 1 - .../content/zotero/standalone/standalone.js | 58 +- chrome/content/zotero/xpcom/attachments.js | 9 +- chrome/content/zotero/xpcom/schema.js | 2417 +++-------------- chrome/content/zotero/xpcom/sync.js | 4 +- chrome/content/zotero/xpcom/zotero.js | 293 +- chrome/content/zotero/zoteroPane.js | 253 +- components/zotero-service.js | 32 +- resource/schema/userdata.sql | 2 +- 13 files changed, 862 insertions(+), 2396 deletions(-) diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js index 8bb5d02ce..d5603ddef 100644 --- a/chrome/content/zotero/browser.js +++ b/chrome/content/zotero/browser.js @@ -101,7 +101,7 @@ var Zotero_Browser = new function() { * Initialize some variables and prepare event listeners for when chrome is done loading */ function init() { - if (!Zotero || !Zotero.initialized || !window.hasOwnProperty("gBrowser")) { + if (!Zotero || Zotero.skipLoading || !window.hasOwnProperty("gBrowser")) { return; } diff --git a/chrome/content/zotero/fileInterface.js b/chrome/content/zotero/fileInterface.js index 06a48b7c3..225f52fc6 100644 --- a/chrome/content/zotero/fileInterface.js +++ b/chrome/content/zotero/fileInterface.js @@ -669,6 +669,6 @@ Zotero_File_Interface.Progress = new function() { } function close() { - Zotero.hideZoteroPaneOverlay(); + Zotero.hideZoteroPaneOverlays(); } } diff --git a/chrome/content/zotero/itemPane.js b/chrome/content/zotero/itemPane.js index 0e824b0f2..a2e198113 100644 --- a/chrome/content/zotero/itemPane.js +++ b/chrome/content/zotero/itemPane.js @@ -24,17 +24,16 @@ */ var ZoteroItemPane = new function() { - this.onLoad = onLoad; - var _lastItem, _itemBox, _notesLabel, _notesButton, _notesList, _tagsBox, _relatedBox; - function onLoad() - { - if (!Zotero || !Zotero.initialized) { + this.onLoad = function () { + if (!Zotero) { return; } // Not in item pane, so skip the introductions + // + // DEBUG: remove? if (!document.getElementById('zotero-view-tabbox')) { return; } diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index 865f9f952..e71f4daea 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -29,56 +29,23 @@ var ZoteroOverlay = new function() { const DEFAULT_ZPANE_HEIGHT = 300; - var toolbarCollapseState, showInPref; + var toolbarCollapseState, showInPref; var zoteroPane, zoteroSplitter; var _stateBeforeReload = false; + var _initializationDeferred, _initializationPromise; this.isTab = false; this.onLoad = function() { - try { - zoteroPane = document.getElementById('zotero-pane-stack'); zoteroSplitter = document.getElementById('zotero-splitter'); - ZoteroPane_Overlay = ZoteroPane; - ZoteroPane.init(); - - // Open Zotero app tab, if in Fx 4 and requested by pref - showInPref = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService) - .getBranch('extensions.zotero.').getIntPref('showIn'); - this.isTab = showInPref !== 1; - - var observerService = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - var zoteroObserver = function(subject, topic, data) { - if(subject != window) return; - observerService.removeObserver(this, "browser-delayed-startup-finished"); - if(showInPref === 3) { - var tabbar = document.getElementById("TabsToolbar"); - if(tabbar && window.getComputedStyle(tabbar).display !== "none") { - // load Zotero as a tab, if it isn't loading by default - ZoteroOverlay.loadZoteroTab(true); - } - } else if(showInPref === 1) { - // close Zotero as a tab, in case it was pinned - var zoteroTab = ZoteroOverlay.findZoteroTab(); - if(zoteroTab) gBrowser.removeTab(zoteroTab); - } - }; - - observerService.addObserver(zoteroObserver, "browser-delayed-startup-finished", false); - // Make Zotero icon visible, if requested var prefBranch = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService) .getBranch('extensions.zotero.'); - var addonBar = document.getElementById('addon-bar'); - var iconPref = prefBranch.getIntPref('statusBarIcon'); - // If this is the first run, add icon to add-on bar if not // in the window already and not hidden by the Zotero prefs if (!document.getElementById("zotero-toolbar-button") && iconPref != 0) { @@ -91,10 +58,53 @@ var ZoteroOverlay = new function() var icon = document.getElementById('zotero-toolbar-button'); - // Add a listener for toolbar change events - window.addEventListener("customizationchange", onToolbarChange, false); + var self = this; - if (Zotero && Zotero.initialized){ + Q.fcall(function () { + if (!Zotero || Zotero.skipLoading) { + throw true; + } + return Zotero.unlockPromise; + }) + .then(function () { + Zotero.debug("Initializing overlay"); + + if (Zotero.skipLoading) { + throw true; + } + + ZoteroPane_Overlay = ZoteroPane; + ZoteroPane.init(); + + // Open Zotero app tab, if in Fx 4 and requested by pref + showInPref = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefService) + .getBranch('extensions.zotero.').getIntPref('showIn'); + self.isTab = showInPref !== 1; + + var observerService = Components.classes["@mozilla.org/observer-service;1"] + .getService(Components.interfaces.nsIObserverService); + var zoteroObserver = function(subject, topic, data) { + if(subject != window) return; + observerService.removeObserver(this, "browser-delayed-startup-finished"); + if(showInPref === 3) { + var tabbar = document.getElementById("TabsToolbar"); + if(tabbar && window.getComputedStyle(tabbar).display !== "none") { + // load Zotero as a tab, if it isn't loading by default + ZoteroOverlay.loadZoteroTab(true); + } + } else if(showInPref === 1) { + // close Zotero as a tab, in case it was pinned + var zoteroTab = ZoteroOverlay.findZoteroTab(); + if(zoteroTab) gBrowser.removeTab(zoteroTab); + } + }; + + observerService.addObserver(zoteroObserver, "browser-delayed-startup-finished", false); + + // Add a listener for toolbar change events + window.addEventListener("customizationchange", onToolbarChange, false); + document.getElementById('appcontent').addEventListener('mousemove', Zotero.ProgressWindowSet.updateTimers, false); if (icon) { if (iconPref == 1) { @@ -111,58 +121,49 @@ var ZoteroOverlay = new function() } } } - } - else { - if (Zotero) { - var errMsg = Zotero.startupError; + + // Used for loading pages from upgrade wizard + if (Zotero.initialURL) { + setTimeout(function () { + gBrowser.selectedTab = gBrowser.addTab(Zotero.initialURL); + Zotero.initialURL = null; + }, 1); } + // Hide browser chrome on Zotero tab + XULBrowserWindow.inContentWhitelist.push("chrome://zotero/content/tab.xul"); + + // Close pane if connector is enabled + ZoteroPane_Local.addReloadListener(function() { + if(Zotero.isConnector) { + // save current state + _stateBeforeReload = !zoteroPane.hidden && !zoteroPane.collapsed; + // ensure pane is closed + if(!zoteroPane.collapsed) ZoteroOverlay.toggleDisplay(false, true); + } else { + // reopen pane if it was open before + ZoteroOverlay.toggleDisplay(_stateBeforeReload, true); + } + }); + }) + .catch(function (e) { + var errMsg = Zotero ? Zotero.startupError : null; // Use defaults if necessary if (!errMsg) { // Get the stringbundle manually var src = 'chrome://zotero/locale/zotero.properties'; - var localeService = Components.classes['@mozilla.org/intl/nslocaleservice;1']. - getService(Components.interfaces.nsILocaleService); + var localeService = Components.classes['@mozilla.org/intl/nslocaleservice;1'] + .getService(Components.interfaces.nsILocaleService); var appLocale = localeService.getApplicationLocale(); var stringBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"] .getService(Components.interfaces.nsIStringBundleService); var stringBundle = stringBundleService.createBundle(src, appLocale); - var errMsg = stringBundle.GetStringFromName('startupError'); + errMsg = stringBundle.GetStringFromName('startupError'); } - icon.setAttribute('tooltiptext', errMsg); icon.setAttribute('error', 'true'); - } - - // Used for loading pages from upgrade wizard - if (Zotero && Zotero.initialURL) { - setTimeout(function () { - gBrowser.selectedTab = gBrowser.addTab(Zotero.initialURL); - Zotero.initialURL = null; - }, 1); - } - - // Hide browser chrome on Zotero tab - XULBrowserWindow.inContentWhitelist.push("chrome://zotero/content/tab.xul"); - - // Close pane if connector is enabled - ZoteroPane_Local.addReloadListener(function() { - if(Zotero.isConnector) { - // save current state - _stateBeforeReload = !zoteroPane.hidden && !zoteroPane.collapsed; - // ensure pane is closed - if(!zoteroPane.collapsed) ZoteroOverlay.toggleDisplay(false, true); - } else { - // reopen pane if it was open before - ZoteroOverlay.toggleDisplay(_stateBeforeReload, true); - } }); - - } - catch (e) { - Zotero.debug(e); - } } @@ -209,7 +210,7 @@ var ZoteroOverlay = new function() */ this.toggleDisplay = function(makeVisible, dontRefocus) { - if(!Zotero || !Zotero.initialized) { + if (!Zotero || Zotero.skipLoading) { ZoteroPane.displayStartupError(); return; } @@ -236,14 +237,6 @@ var ZoteroOverlay = new function() */ if(makeVisible) { - if (Zotero.locked) { - var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Components.interfaces.nsIPromptService); - var msg = Zotero.getString('general.operationInProgress') + '\n\n' + Zotero.getString('general.operationInProgress.waitUntilFinished'); - ps.alert(null, "", msg); - return false; - } - zoteroSplitter.setAttribute('hidden', false); zoteroPane.setAttribute('hidden', false); zoteroPane.setAttribute('collapsed', false); @@ -349,6 +342,19 @@ var ZoteroOverlay = new function() } } -window.addEventListener("load", function(e) { ZoteroOverlay.onLoad(e); }, false); +window.addEventListener("load", function(e) { + try { + ZoteroOverlay.onLoad(e); + } + catch (e) { + Components.utils.reportError(e); + if (Zotero) { + Zotero.debug(e, 1); + } + else { + dump(e + "\n\n"); + } + } +}, false); window.addEventListener("unload", function(e) { ZoteroOverlay.onUnload(e); }, false); window.addEventListener("beforeunload", function(e) { ZoteroOverlay.onBeforeUnload(e); }, false); diff --git a/chrome/content/zotero/overlay.xul b/chrome/content/zotero/overlay.xul index 126a714fd..f7d9a460a 100644 --- a/chrome/content/zotero/overlay.xul +++ b/chrome/content/zotero/overlay.xul @@ -38,7 +38,6 @@ -