Add XPCOM clearTimeout() and remove Zotero.wait()
Properly emulate setTimeout() with support for cancelling timers.
This commit is contained in:
parent
a285e97815
commit
6907af86fd
|
@ -73,12 +73,6 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
return Services.wm.getMostRecentWindow("navigator:browser").ZoteroPane;
|
return Services.wm.getMostRecentWindow("navigator:browser").ZoteroPane;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {Boolean} waiting Whether Zotero is waiting for other
|
|
||||||
* main thread events to be processed
|
|
||||||
*/
|
|
||||||
this.__defineGetter__('waiting', function () _waiting);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Boolean} locked Whether all Zotero panes are locked
|
* @property {Boolean} locked Whether all Zotero panes are locked
|
||||||
* with an overlay
|
* with an overlay
|
||||||
|
@ -112,7 +106,6 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
var _startupErrorHandler;
|
var _startupErrorHandler;
|
||||||
var _zoteroDirectory = false;
|
var _zoteroDirectory = false;
|
||||||
var _localizedStringBundle;
|
var _localizedStringBundle;
|
||||||
var _waiting = 0;
|
|
||||||
|
|
||||||
var _locked = false;
|
var _locked = false;
|
||||||
var _shutdownListeners = [];
|
var _shutdownListeners = [];
|
||||||
|
@ -137,7 +130,7 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
/**
|
/**
|
||||||
* Maintains running nsITimers in global scope, so that they don't disappear randomly
|
* Maintains running nsITimers in global scope, so that they don't disappear randomly
|
||||||
*/
|
*/
|
||||||
var _runningTimers = [];
|
var _runningTimers = new Map();
|
||||||
|
|
||||||
// Errors that were in the console at startup
|
// Errors that were in the console at startup
|
||||||
var _startupErrors = [];
|
var _startupErrors = [];
|
||||||
|
@ -1721,41 +1714,6 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow other events (e.g., UI updates) on main thread to be processed if necessary
|
|
||||||
*
|
|
||||||
* @param {Integer} [timeout=50] Maximum number of milliseconds to wait
|
|
||||||
*/
|
|
||||||
this.wait = function (timeout) {
|
|
||||||
if (timeout === undefined) {
|
|
||||||
timeout = 50;
|
|
||||||
}
|
|
||||||
var mainThread = Zotero.mainThread;
|
|
||||||
var endTime = Date.now() + timeout;
|
|
||||||
var more;
|
|
||||||
//var cycles = 0;
|
|
||||||
|
|
||||||
_waiting++;
|
|
||||||
|
|
||||||
Zotero.debug("Spinning event loop ("+_waiting+")", 5);
|
|
||||||
do {
|
|
||||||
more = mainThread.processNextEvent(false);
|
|
||||||
//cycles++;
|
|
||||||
} while (more && Date.now() < endTime);
|
|
||||||
|
|
||||||
_waiting--;
|
|
||||||
|
|
||||||
// requeue nsITimerCallbacks that came up during Zotero.wait() but couldn't execute
|
|
||||||
for(var i in _waitTimers) {
|
|
||||||
_waitTimers[i].initWithCallback(_waitTimerCallbacks[i], 0, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
|
||||||
}
|
|
||||||
_waitTimers = [];
|
|
||||||
_waitTimerCallbacks = [];
|
|
||||||
|
|
||||||
//Zotero.debug("Waited " + cycles + " cycles");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a function that produces a static output
|
* Generate a function that produces a static output
|
||||||
*
|
*
|
||||||
|
@ -1798,38 +1756,38 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emulates the behavior of window.setTimeout, but ensures that callbacks do not get called
|
* Emulates the behavior of window.setTimeout
|
||||||
* during Zotero.wait()
|
|
||||||
*
|
*
|
||||||
* @param {Function} func The function to be called
|
* @param {Function} func The function to be called
|
||||||
* @param {Integer} ms The number of milliseconds to wait before calling func
|
* @param {Integer} ms The number of milliseconds to wait before calling func
|
||||||
* @param {Boolean} runWhenWaiting True if the callback should be run even if Zotero.wait()
|
* @return {Integer} - ID of timer to be passed to clearTimeout()
|
||||||
* is executing
|
|
||||||
*/
|
*/
|
||||||
this.setTimeout = function(func, ms, runWhenWaiting) {
|
var _lastTimeoutID = 0;
|
||||||
var timer = Components.classes["@mozilla.org/timer;1"].
|
this.setTimeout = function (func, ms) {
|
||||||
createInstance(Components.interfaces.nsITimer),
|
var id = ++_lastTimeoutID;
|
||||||
useJIT = Components.utils.methodjit;
|
|
||||||
var timerCallback = {"notify":function() {
|
|
||||||
// XXX Remove when we drop support for Fx <24
|
|
||||||
if(useJIT !== undefined) Components.utils.methodjit = useJIT;
|
|
||||||
|
|
||||||
if(_waiting && !runWhenWaiting) {
|
var timer = Components.classes["@mozilla.org/timer;1"]
|
||||||
// if our callback gets called during Zotero.wait(), queue it to be set again
|
.createInstance(Components.interfaces.nsITimer);
|
||||||
// when Zotero.wait() completes
|
var timerCallback = {
|
||||||
_waitTimers.push(timer);
|
"notify": function () {
|
||||||
_waitTimerCallbacks.push(timerCallback);
|
|
||||||
} else {
|
|
||||||
// execute callback function
|
|
||||||
func();
|
func();
|
||||||
// remove timer from global scope, so it can be garbage collected
|
_runningTimers.delete(id);
|
||||||
_runningTimers.splice(_runningTimers.indexOf(timer), 1);
|
|
||||||
}
|
}
|
||||||
}}
|
};
|
||||||
timer.initWithCallback(timerCallback, ms, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
timer.initWithCallback(timerCallback, ms, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||||
// add timer to global scope so that it doesn't get garbage collected before it completes
|
_runningTimers.set(id, timer);
|
||||||
_runningTimers.push(timer);
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.clearTimeout = function (id) {
|
||||||
|
var timer = _runningTimers.get(id);
|
||||||
|
if (timer) {
|
||||||
|
timer.cancel();
|
||||||
|
_runningTimers.delete(id);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show Zotero pane overlay and progress bar in all windows
|
* Show Zotero pane overlay and progress bar in all windows
|
||||||
|
|
|
@ -178,7 +178,11 @@ ZoteroContext.prototype = {
|
||||||
* Convenience method to replicate window.setTimeout()
|
* Convenience method to replicate window.setTimeout()
|
||||||
**/
|
**/
|
||||||
"setTimeout":function setTimeout(func, ms){
|
"setTimeout":function setTimeout(func, ms){
|
||||||
this.Zotero.setTimeout(func, ms);
|
return this.Zotero.setTimeout(func, ms);
|
||||||
|
},
|
||||||
|
|
||||||
|
"clearTimeout":function setTimeout(id) {
|
||||||
|
this.Zotero.clearTimeout(id);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user