summaryrefslogtreecommitdiffstats
path: root/addon-sdk/source/lib/sdk/timers.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /addon-sdk/source/lib/sdk/timers.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'addon-sdk/source/lib/sdk/timers.js')
-rw-r--r--addon-sdk/source/lib/sdk/timers.js105
1 files changed, 105 insertions, 0 deletions
diff --git a/addon-sdk/source/lib/sdk/timers.js b/addon-sdk/source/lib/sdk/timers.js
new file mode 100644
index 000000000..e97db01f2
--- /dev/null
+++ b/addon-sdk/source/lib/sdk/timers.js
@@ -0,0 +1,105 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+'use strict';
+
+module.metadata = {
+ "stability": "stable"
+};
+
+const { CC, Cc, Ci } = require("chrome");
+const { when: unload } = require("./system/unload");
+
+const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
+const Timer = CC("@mozilla.org/timer;1", "nsITimer");
+const timers = Object.create(null);
+const threadManager = Cc["@mozilla.org/thread-manager;1"].
+ getService(Ci.nsIThreadManager);
+const prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).
+ QueryInterface(Ci.nsIPrefBranch);
+
+var MIN_DELAY = 4;
+// Try to get min timeout delay used by browser.
+try { MIN_DELAY = prefBranch.getIntPref("dom.min_timeout_value"); } finally {}
+
+
+// Last timer id.
+var lastID = 0;
+
+// Sets typer either by timeout or by interval
+// depending on a given type.
+function setTimer(type, callback, delay, ...args) {
+ let id = ++ lastID;
+ let timer = timers[id] = Timer();
+ timer.initWithCallback({
+ notify: function notify() {
+ try {
+ if (type === TYPE_ONE_SHOT)
+ delete timers[id];
+ callback.apply(null, args);
+ }
+ catch(error) {
+ console.exception(error);
+ }
+ }
+ }, Math.max(delay || MIN_DELAY), type);
+ return id;
+}
+
+function unsetTimer(id) {
+ let timer = timers[id];
+ delete timers[id];
+ if (timer) timer.cancel();
+}
+
+var immediates = new Map();
+
+var dispatcher = _ => {
+ // Allow scheduling of a new dispatch loop.
+ dispatcher.scheduled = false;
+ // Take a snapshot of timer `id`'s that have being present before
+ // starting a dispatch loop, in order to ignore timers registered
+ // in side effect to dispatch while also skipping immediates that
+ // were removed in side effect.
+ let ids = [...immediates.keys()];
+ for (let id of ids) {
+ let immediate = immediates.get(id);
+ if (immediate) {
+ immediates.delete(id);
+ try { immediate(); }
+ catch (error) { console.exception(error); }
+ }
+ }
+}
+
+function setImmediate(callback, ...params) {
+ let id = ++ lastID;
+ // register new immediate timer with curried params.
+ immediates.set(id, _ => callback.apply(callback, params));
+ // if dispatch loop is not scheduled schedule one. Own scheduler
+ if (!dispatcher.scheduled) {
+ dispatcher.scheduled = true;
+ threadManager.currentThread.dispatch(dispatcher,
+ Ci.nsIThread.DISPATCH_NORMAL);
+ }
+ return id;
+}
+
+function clearImmediate(id) {
+ immediates.delete(id);
+}
+
+// Bind timers so that toString-ing them looks same as on native timers.
+exports.setImmediate = setImmediate.bind(null);
+exports.clearImmediate = clearImmediate.bind(null);
+exports.setTimeout = setTimer.bind(null, TYPE_ONE_SHOT);
+exports.setInterval = setTimer.bind(null, TYPE_REPEATING_SLACK);
+exports.clearTimeout = unsetTimer.bind(null);
+exports.clearInterval = unsetTimer.bind(null);
+
+// all timers are cleared out on unload.
+unload(function() {
+ immediates.clear();
+ Object.keys(timers).forEach(unsetTimer)
+});