From e4dd38fc84a06f8c767cd626682cbcfa868e623b Mon Sep 17 00:00:00 2001 From: Aurimas Vinckevicius Date: Tue, 3 Jun 2014 01:44:26 -0500 Subject: [PATCH] Fix race condition when starting in Connector mode When starting in Connector mode (i.e. Standalone is open), Zotero first starts in Full mode, looks for Standalone, then "shuts down" and restarts in Connector mode. `Zotero.shutdown()` returns a promise which is then followed up by a `Zotero.init` call. Thus, when starting in Connector mode, Zotero initialization is asynchronous and makes it possible for `Zotero_Browser.init()` to be called before `Zotero.initialized` is true, which prevents `Zotero_Browser` from initializing. Additionally, even if `Zotero_Browser.init()` is called after Zotero is initialized in Connector mode, it is possible that `Zotero_Browser.init()` will be called _after_ the "load" event for browser.xul has already fired, so `chromeLoad` is never called. This patch ensures that both of these race conditions are taken into account. --- chrome/content/zotero/browser.js | 40 ++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js index a011ffb798..9fb08bbba7 100644 --- a/chrome/content/zotero/browser.js +++ b/chrome/content/zotero/browser.js @@ -102,15 +102,45 @@ 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 (!window.hasOwnProperty("gBrowser")) { return; } - window.addEventListener("load", - function(e) { Zotero_Browser.chromeLoad(e) }, false); + var zoteroInitDone; + if (!Zotero || !Zotero.initialized) { + // Zotero either failed to load or is reloading in Connector mode + // In case of the latter, listen for the 'zotero-loaded' event (once) and retry + var zoteroInitDone_deferred = Q.defer(); + var obs = Components.classes["@mozilla.org/observer-service;1"] + .getService(Components.interfaces.nsIObserverService); + var observer = { + "observe":function() { + obs.removeObserver(observer, 'zotero-loaded') + zoteroInitDone_deferred.resolve(); + } + }; + obs.addObserver(observer, 'zotero-loaded', false); + + zoteroInitDone = zoteroInitDone_deferred.promise; + } else { + zoteroInitDone = Q(); + } - ZoteroPane_Local.addReloadListener(reload); - reload(); + var chromeLoaded = Q.defer(); + window.addEventListener("load", function(e) { chromeLoaded.resolve() }, false); + + // Wait for Zotero to init and chrome to load before proceeding + Q.all([ + zoteroInitDone.then(function() { + ZoteroPane_Local.addReloadListener(reload); + reload(); + }), + chromeLoaded.promise + ]) + .then(function() { + Zotero_Browser.chromeLoad() + }) + .done(); } /**