mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 18:07:58 +01:00
Promises cleanup.
This commit is contained in:
1
common/bootstrap.js
vendored
1
common/bootstrap.js
vendored
@@ -264,6 +264,7 @@ function init() {
|
|||||||
bootstrap = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(),
|
bootstrap = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(),
|
||||||
{ sandboxName: BOOTSTRAP,
|
{ sandboxName: BOOTSTRAP,
|
||||||
addonId: addon.id,
|
addonId: addon.id,
|
||||||
|
wantGlobalProperties: ["TextDecoder", "TextEncoder"],
|
||||||
metadata: { addonID: addon.id } });
|
metadata: { addonID: addon.id } });
|
||||||
Services.scriptloader.loadSubScript(BOOTSTRAP, bootstrap);
|
Services.scriptloader.loadSubScript(BOOTSTRAP, bootstrap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
|
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
|
||||||
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
|
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
|
||||||
// Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
|
// Copyright (c) 2008-2015 Kris Maglione <maglione.k@gmail.com>
|
||||||
//
|
//
|
||||||
// This work is licensed for reuse under an MIT license. Details are
|
// This work is licensed for reuse under an MIT license. Details are
|
||||||
// given in the LICENSE.txt file included with this file.
|
// given in the LICENSE.txt file included with this file.
|
||||||
@@ -302,23 +302,22 @@ var Bookmarks = Module("bookmarks", {
|
|||||||
* @returns {Promise<Array>}
|
* @returns {Promise<Array>}
|
||||||
*/
|
*/
|
||||||
makeSuggestions: function makeSuggestions(url, parser) {
|
makeSuggestions: function makeSuggestions(url, parser) {
|
||||||
let deferred = Promise.defer();
|
return new CancelablePromise((resolve, reject, canceled) => {
|
||||||
|
let req = util.fetchUrl(url);
|
||||||
|
req.then(function process(req) {
|
||||||
|
let results = [];
|
||||||
|
try {
|
||||||
|
results = parser(req);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
reject(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(results);
|
||||||
|
});
|
||||||
|
|
||||||
let req = util.fetchUrl(url);
|
canceled.then(req.cancel);
|
||||||
req.then(function process(req) {
|
|
||||||
let results = [];
|
|
||||||
try {
|
|
||||||
results = parser(req);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
deferred.reject(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
deferred.resolve(results);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
promises.oncancel(deferred, reason => promises.cancel(req, reason));
|
|
||||||
return deferred.promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
suggestionProviders: {},
|
suggestionProviders: {},
|
||||||
|
|||||||
@@ -855,13 +855,15 @@ var CommandLine = Module("commandline", {
|
|||||||
* @... {string} default - The initial value that will be returned
|
* @... {string} default - The initial value that will be returned
|
||||||
* if the user presses <CR> straightaway. @default ""
|
* if the user presses <CR> straightaway. @default ""
|
||||||
*/
|
*/
|
||||||
input: promises.withCallbacks(function _input([callback, reject], prompt, extra={}, thing={}) {
|
input: function _input(prompt, extra={}, thing={}) {
|
||||||
if (callable(extra))
|
return new Promise((resolve, reject) => {
|
||||||
// Deprecated.
|
if (callable(extra))
|
||||||
[callback, extra] = [extra, thing];
|
// Deprecated.
|
||||||
|
[resolve, extra] = [extra, thing];
|
||||||
|
|
||||||
CommandPromptMode(prompt, update({ onSubmit: callback, onCancel: reject }, extra)).open();
|
CommandPromptMode(prompt, update({ onSubmit: resolve, onCancel: reject }, extra)).open();
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
|
|
||||||
readHeredoc: function readHeredoc(end) {
|
readHeredoc: function readHeredoc(end) {
|
||||||
return util.waitFor(commandline.inputMultiline(end));
|
return util.waitFor(commandline.inputMultiline(end));
|
||||||
@@ -876,33 +878,35 @@ var CommandLine = Module("commandline", {
|
|||||||
* @returns {Promise<string>}
|
* @returns {Promise<string>}
|
||||||
*/
|
*/
|
||||||
// FIXME: Buggy, especially when pasting.
|
// FIXME: Buggy, especially when pasting.
|
||||||
inputMultiline: promises.withCallbacks(function inputMultiline([callback], end) {
|
inputMultiline: function inputMultiline(end) {
|
||||||
let cmd = this.command;
|
return new Promise((resolve, reject) => {
|
||||||
let self = {
|
let cmd = this.command;
|
||||||
end: "\n" + end + "\n",
|
let self = {
|
||||||
callback: callback
|
end: "\n" + end + "\n",
|
||||||
};
|
callback: resolve
|
||||||
|
};
|
||||||
|
|
||||||
modes.push(modes.INPUT_MULTILINE, null, {
|
modes.push(modes.INPUT_MULTILINE, null, {
|
||||||
holdFocus: true,
|
holdFocus: true,
|
||||||
leave: function leave() {
|
leave: function leave() {
|
||||||
if (!self.done)
|
if (!self.done)
|
||||||
self.callback(null);
|
self.callback(null);
|
||||||
},
|
},
|
||||||
mappingSelf: self
|
mappingSelf: self
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cmd != false)
|
||||||
|
this._echoLine(cmd, this.HL_NORMAL);
|
||||||
|
|
||||||
|
// save the arguments, they are needed in the event handler onKeyPress
|
||||||
|
|
||||||
|
this.multilineInputVisible = true;
|
||||||
|
this.widgets.multilineInput.value = "";
|
||||||
|
this._autosizeMultilineInputWidget();
|
||||||
|
|
||||||
|
this.timeout(function () { dactyl.focus(this.widgets.multilineInput); }, 10);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
if (cmd != false)
|
|
||||||
this._echoLine(cmd, this.HL_NORMAL);
|
|
||||||
|
|
||||||
// save the arguments, they are needed in the event handler onKeyPress
|
|
||||||
|
|
||||||
this.multilineInputVisible = true;
|
|
||||||
this.widgets.multilineInput.value = "";
|
|
||||||
this._autosizeMultilineInputWidget();
|
|
||||||
|
|
||||||
this.timeout(function () { dactyl.focus(this.widgets.multilineInput); }, 10);
|
|
||||||
}),
|
|
||||||
|
|
||||||
get commandMode() this.commandSession && isinstance(modes.main, modes.COMMAND_LINE),
|
get commandMode() this.commandSession && isinstance(modes.main, modes.COMMAND_LINE),
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,6 @@ defineModule("base", {
|
|||||||
"Cr",
|
"Cr",
|
||||||
"Cs",
|
"Cs",
|
||||||
"Cu",
|
"Cu",
|
||||||
"DOMPromise",
|
|
||||||
"ErrorBase",
|
"ErrorBase",
|
||||||
"Finished",
|
"Finished",
|
||||||
"JSMLoader",
|
"JSMLoader",
|
||||||
@@ -762,12 +761,6 @@ function memoize(obj, key, getter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(),
|
|
||||||
{ wantGlobalProperties: ["TextDecoder", "TextEncoder"],
|
|
||||||
sandboxPrototype: this });
|
|
||||||
|
|
||||||
var { TextEncoder, TextDecoder, Promise: DOMPromise } = sandbox;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an object with the properties of another object. Getters
|
* Updates an object with the properties of another object. Getters
|
||||||
* and setters are copied as expected. Moreover, any function
|
* and setters are copied as expected. Moreover, any function
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ this["import"] = function import_(obj) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof TextEncoder == "undefined")
|
||||||
|
Components.utils.importGlobalProperties(["TextEncoder", "TextDecoder"]);
|
||||||
|
|
||||||
// Deal with subScriptLoader prepending crap to loaded URLs
|
// Deal with subScriptLoader prepending crap to loaded URLs
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
function loadSubScript() Services.scriptloader.loadSubScript.apply(null, arguments);
|
function loadSubScript() Services.scriptloader.loadSubScript.apply(null, arguments);
|
||||||
|
|||||||
@@ -86,26 +86,28 @@ var Buffer = Module("Buffer", {
|
|||||||
* @param {string} pref The name of the preference to return.
|
* @param {string} pref The name of the preference to return.
|
||||||
* @returns {Promise<*>}
|
* @returns {Promise<*>}
|
||||||
*/
|
*/
|
||||||
get: promises.withCallbacks(function get([resolve, reject], pref) {
|
get: function get(pref) {
|
||||||
let val = services.contentPrefs.getCachedByDomainAndName(
|
return new Promise((resolve, reject) => {
|
||||||
self.uri.spec, pref, self.loadContext);
|
let val = services.contentPrefs.getCachedByDomainAndName(
|
||||||
|
self.uri.spec, pref, self.loadContext);
|
||||||
|
|
||||||
let found = false;
|
let found = false;
|
||||||
if (val)
|
if (val)
|
||||||
resolve(val.value);
|
resolve(val.value);
|
||||||
else
|
else
|
||||||
services.contentPrefs.getByDomainAndName(
|
services.contentPrefs.getByDomainAndName(
|
||||||
self.uri.spec, pref, self.loadContext,
|
self.uri.spec, pref, self.loadContext,
|
||||||
{ handleCompletion: () => {
|
{ handleCompletion: () => {
|
||||||
if (!found)
|
if (!found)
|
||||||
resolve(undefined);
|
resolve(undefined);
|
||||||
},
|
},
|
||||||
handleResult: (pref) => {
|
handleResult: (pref) => {
|
||||||
found = true;
|
found = true;
|
||||||
resolve(pref.value);
|
resolve(pref.value);
|
||||||
},
|
},
|
||||||
handleError: reject });
|
handleError: reject });
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a content preference for the given buffer.
|
* Sets a content preference for the given buffer.
|
||||||
@@ -113,26 +115,30 @@ var Buffer = Module("Buffer", {
|
|||||||
* @param {string} pref The preference to set.
|
* @param {string} pref The preference to set.
|
||||||
* @param {string} value The value to store.
|
* @param {string} value The value to store.
|
||||||
*/
|
*/
|
||||||
set: promises.withCallbacks(function set([resolve, reject], pref, value) {
|
set: function set(pref, value) {
|
||||||
services.contentPrefs.set(
|
return new Promise((resolve, reject) => {
|
||||||
self.uri.spec, pref, value, self.loadContext,
|
services.contentPrefs.set(
|
||||||
{ handleCompletion: () => {},
|
self.uri.spec, pref, value, self.loadContext,
|
||||||
handleResult: resolve,
|
{ handleCompletion: () => {},
|
||||||
handleError: reject });
|
handleResult: resolve,
|
||||||
}),
|
handleError: reject });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear a content preference for the given buffer.
|
* Clear a content preference for the given buffer.
|
||||||
*
|
*
|
||||||
* @param {string} pref The preference to clear.
|
* @param {string} pref The preference to clear.
|
||||||
*/
|
*/
|
||||||
clear: promises.withCallbacks(function clear([resolve, reject], pref) {
|
clear: function clear(pref) {
|
||||||
services.contentPrefs.removeByDomainAndName(
|
return new Promise((resolve, reject) => {
|
||||||
self.uri.spec, pref, self.loadContext,
|
services.contentPrefs.removeByDomainAndName(
|
||||||
{ handleCompletion: () => {},
|
self.uri.spec, pref, self.loadContext,
|
||||||
handleResult: resolve,
|
{ handleCompletion: () => {},
|
||||||
handleError: reject });
|
handleResult: resolve,
|
||||||
})
|
handleError: reject });
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ var ConfigBase = Class("ConfigBase", {
|
|||||||
"options",
|
"options",
|
||||||
"overlay",
|
"overlay",
|
||||||
"prefs",
|
"prefs",
|
||||||
["promises", "Promise", "Task", "promises"],
|
["promises", "CancelablePromise", "Promise", "Task", "promises"],
|
||||||
"protocol",
|
"protocol",
|
||||||
"sanitizer",
|
"sanitizer",
|
||||||
"services",
|
"services",
|
||||||
|
|||||||
@@ -95,9 +95,9 @@ var Modules = function Modules(window) {
|
|||||||
if (normal)
|
if (normal)
|
||||||
return create(proto);
|
return create(proto);
|
||||||
|
|
||||||
sandbox = Components.utils.Sandbox(window, { sandboxPrototype: proto || modules,
|
let sandbox = Components.utils.Sandbox(window, { sandboxPrototype: proto || modules,
|
||||||
sandboxName: name || ("Dactyl Sandbox " + ++_id),
|
sandboxName: name || ("Dactyl Sandbox " + ++_id),
|
||||||
wantXrays: true });
|
wantXrays: true });
|
||||||
|
|
||||||
// Hack:
|
// Hack:
|
||||||
// sandbox.Object = jsmodules.Object;
|
// sandbox.Object = jsmodules.Object;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
defineModule("promises", {
|
defineModule("promises", {
|
||||||
exports: ["Promise", "Task", "promises"],
|
exports: ["CancelablePromise", "Promise", "Task", "promises"],
|
||||||
require: []
|
require: []
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -24,6 +24,26 @@ function withCallbacks(fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CancelablePromise(executor, oncancel) {
|
||||||
|
let deferred = Promise.defer();
|
||||||
|
let canceled = new Promise((accept, reject) => {
|
||||||
|
promises.oncancel(deferred, accept);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
executor(deferred.resolve, deferred.reject, canceled);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
deferred.reject(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.freeze(Object.create(deferred.promise, {
|
||||||
|
cancel: {
|
||||||
|
value: thing => promises.cancel(deferred.promise, thing)
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
var Promises = Module("Promises", {
|
var Promises = Module("Promises", {
|
||||||
_cancel: new WeakMap,
|
_cancel: new WeakMap,
|
||||||
|
|
||||||
@@ -38,7 +58,7 @@ var Promises = Module("Promises", {
|
|||||||
let cleanup = this._cancel.get(promise);
|
let cleanup = this._cancel.get(promise);
|
||||||
if (cleanup) {
|
if (cleanup) {
|
||||||
cleanup[0](promise);
|
cleanup[0](promise);
|
||||||
cleanup[1].reject(reason);
|
cleanup[1](reason);
|
||||||
}
|
}
|
||||||
this._cancel.delete(promise);
|
this._cancel.delete(promise);
|
||||||
},
|
},
|
||||||
@@ -50,16 +70,18 @@ var Promises = Module("Promises", {
|
|||||||
* @param {function} fn The cleanup function.
|
* @param {function} fn The cleanup function.
|
||||||
*/
|
*/
|
||||||
oncancel: function oncancel(deferred, fn) {
|
oncancel: function oncancel(deferred, fn) {
|
||||||
this._cancel.set(deferred.promise, [fn, deferred]);
|
this._cancel.set(deferred.promise, [fn, deferred.reject]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a promise which resolves after a brief delay.
|
* Returns a promise which resolves after a brief delay.
|
||||||
*/
|
*/
|
||||||
delay: withCallbacks(function delay([accept]) {
|
delay: function delay([accept]) {
|
||||||
let { mainThread } = services.threading;
|
return new Promise(resolve => {
|
||||||
mainThread.dispatch(accept, mainThread.DISPATCH_NORMAL);
|
let { mainThread } = services.threading;
|
||||||
}),
|
mainThread.dispatch(resolve, mainThread.DISPATCH_NORMAL);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a promise which resolves after the given number of
|
* Returns a promise which resolves after the given number of
|
||||||
@@ -67,9 +89,11 @@ var Promises = Module("Promises", {
|
|||||||
*
|
*
|
||||||
* @param {number} delay The number of milliseconds to wait.
|
* @param {number} delay The number of milliseconds to wait.
|
||||||
*/
|
*/
|
||||||
sleep: withCallbacks(function sleep([callback], delay) {
|
sleep: function sleep(delay) {
|
||||||
this.timeout(callback, delay);
|
return new Promise(resolve => {
|
||||||
}),
|
this.timeout(resolve, delay);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given function so that each call spawns a Task.
|
* Wraps the given function so that each call spawns a Task.
|
||||||
@@ -94,25 +118,27 @@ var Promises = Module("Promises", {
|
|||||||
* @param {number} pollInterval The poll interval, in milliseconds.
|
* @param {number} pollInterval The poll interval, in milliseconds.
|
||||||
* @default 10
|
* @default 10
|
||||||
*/
|
*/
|
||||||
waitFor: withCallbacks(function waitFor([accept, reject], test, timeout=null, pollInterval=10) {
|
waitFor: function waitFor(test, timeout=null, pollInterval=10) {
|
||||||
let end = timeout && Date.now() + timeout, result;
|
return new Promise((resolve, reject) => {
|
||||||
|
let end = timeout && Date.now() + timeout, result;
|
||||||
|
|
||||||
let timer = services.Timer(
|
let timer = services.Timer(
|
||||||
() => {
|
() => {
|
||||||
try {
|
try {
|
||||||
var result = test();
|
var result = test();
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
reject(e);
|
reject(e);
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
accept(result);
|
resolve(result);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pollInterval, services.Timer.TYPE_REPEATING_SLACK);
|
pollInterval, services.Timer.TYPE_REPEATING_SLACK);
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given function so that its first argument is an array
|
* Wraps the given function so that its first argument is an array
|
||||||
|
|||||||
@@ -828,14 +828,16 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
|||||||
* @param {string} url The URL to fetch.
|
* @param {string} url The URL to fetch.
|
||||||
* @param {object} params Parameter object, as in #httpGet.
|
* @param {object} params Parameter object, as in #httpGet.
|
||||||
*/
|
*/
|
||||||
fetchUrl: promises.withCallbacks(function fetchUrl([accept, reject, deferred], url, params) {
|
fetchUrl: function fetchUrl(url, params) {
|
||||||
params = update({}, params);
|
return new CancelablePromise((accept, reject, canceled) => {
|
||||||
params.onload = accept;
|
params = update({}, params);
|
||||||
params.onerror = reject;
|
params.onload = accept;
|
||||||
|
params.onerror = reject;
|
||||||
|
|
||||||
let req = this.httpGet(url, params);
|
let req = this.httpGet(url, params);
|
||||||
promises.oncancel(deferred, req.cancel);
|
canceled.then(req.cancel);
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identity function.
|
* The identity function.
|
||||||
|
|||||||
Reference in New Issue
Block a user