diff options
Diffstat (limited to 'packages/vold-utils/lib')
-rw-r--r-- | packages/vold-utils/lib/array.js | 6 | ||||
-rw-r--r-- | packages/vold-utils/lib/instances.js | 57 | ||||
-rw-r--r-- | packages/vold-utils/lib/listen.js | 29 | ||||
-rw-r--r-- | packages/vold-utils/lib/memoize.js | 131 | ||||
-rw-r--r-- | packages/vold-utils/lib/net-utils.js | 3 | ||||
-rw-r--r-- | packages/vold-utils/lib/services.js | 84 | ||||
-rw-r--r-- | packages/vold-utils/lib/unload+.js | 80 | ||||
-rw-r--r-- | packages/vold-utils/lib/window-watcher.js | 91 | ||||
-rw-r--r-- | packages/vold-utils/lib/xpcom-utils.js | 3 |
9 files changed, 484 insertions, 0 deletions
diff --git a/packages/vold-utils/lib/array.js b/packages/vold-utils/lib/array.js new file mode 100644 index 0000000..5ac0577 --- /dev/null +++ b/packages/vold-utils/lib/array.js @@ -0,0 +1,6 @@ +'use strict'; + +function run(array) array.forEach(function(f) f()); +exports.run = run; + + diff --git a/packages/vold-utils/lib/instances.js b/packages/vold-utils/lib/instances.js new file mode 100644 index 0000000..a33ca40 --- /dev/null +++ b/packages/vold-utils/lib/instances.js @@ -0,0 +1,57 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MIT/X11 License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Contributor(s): + * Erik Vold <erikvvold@gmail.com> (Original Author) + * + * ***** END LICENSE BLOCK ***** */ + +const {Cc, Ci, Cu} = require("chrome"); + +var Instances = exports.Instances = { + get bis() Cc["@mozilla.org/binaryinputstream;1"] + .createInstance(Ci.nsIBinaryInputStream), + get ch() Cc["@mozilla.org/security/hash;1"] + .createInstance(Ci.nsICryptoHash), + get dp() Cc["@mozilla.org/xmlextras/domparser;1"] + .createInstance(Ci.nsIDOMParser), + get ds() Cc["@mozilla.org/xmlextras/xmlserializer;1"] + .createInstance(Ci.nsIDOMSerializer), + get fos() Cc["@mozilla.org/network/file-output-stream;1"] + .createInstance(Ci.nsIFileOutputStream), + get sfos() Cc["@mozilla.org/network/safe-file-output-stream;1"] + .createInstance(Ci.nsIFileOutputStream) + .QueryInterface(Ci.nsISafeOutputStream), + get fp() Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker), + get lf() Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile), + get process() Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess), + get se() Cc["@mozilla.org/scripterror;1"].createInstance(Ci.nsIScriptError) + .QueryInterface(Ci.nsIScriptError2), + get ss() Cc["@mozilla.org/supports-string;1"] + .createInstance(Ci.nsISupportsString), + get suc() Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter), + get timer() Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer), + get wbp() Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] + .createInstance(Ci.nsIWebBrowserPersist), + get xhr() Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest) +}; diff --git a/packages/vold-utils/lib/listen.js b/packages/vold-utils/lib/listen.js new file mode 100644 index 0000000..0b947d1 --- /dev/null +++ b/packages/vold-utils/lib/listen.js @@ -0,0 +1,29 @@ +/* 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"; + +const { unload, Unload } = require("unload+"); + +/** + * Helper that adds event listeners and remembers to remove on unload + */ +function listen(window, node, event, func, capture) { + // Default to use capture + if (capture == null) + capture = true; + + node.addEventListener(event, func, capture); + function undoListen() { + node.removeEventListener(event, func, capture); + } + + // Undo the listener on unload and provide a way to undo everything + let undoUnload = unload(undoListen, window); + return function() { + undoListen(); + undoUnload(); + }; +} +exports.listen = listen; + diff --git a/packages/vold-utils/lib/memoize.js b/packages/vold-utils/lib/memoize.js new file mode 100644 index 0000000..73bb4fc --- /dev/null +++ b/packages/vold-utils/lib/memoize.js @@ -0,0 +1,131 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MIT/X11 License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Contributor(s): + * Nils Maier <MaierMan@web.de> + * Erik Vold <erikvvold@gmail.com> + * + * ***** END LICENSE BLOCK ***** */ + +"use strict"; + +/** + * Decorate a function with a memoization wrapper, with a limited-size cache + * to reduce peak memory utilization. + * + * The memoized function may have any number of arguments, but they must be + * be serializable. It's safest to use this only on functions that accept + * primitives. + * + * A memoized function is not thread-safe, but so is JS, nor re-entrant-safe! + * + * @usage var foo = Scriptish_memoize(function foo(arg1, arg2) { ... complex operation ... }); + * @param {Function} func The function to be memoized + * @param {Number} limit Optional. Cache size (default: 100) + * @param {Number} num_args Options. Number of arguments the function expects (default: func.length) + * @return {Function} Memoized function + */ +exports.memoize = function memoize(func, limit, num_args) { + limit = limit || 100; + num_args = num_args || func.length; + + var cache = Object.create(null); + var keylist = []; + var args = []; + var key, result; + + switch (num_args) { + case 0: + throw new Error("memoize does not support functions without arguments"); + case 1: + return function memoize_one_arg(a) { + key = a.toString(); + + if (key in cache) + return cache[key]; + + result = func.call(null, a); + cache[key] = result; + if (keylist.push(key) > limit) + delete cache[keylist.shift()]; + return result; + }; + case 2: + return function memoize_two_args(a, b) { + args[0] = a; args[1] = b; + key = JSON.stringify(args); + args.length = 0; + + if (key in cache) + return cache[key]; + + var result = func.call(null, a, b); + cache[key] = result; + if (keylist.push(key) > limit) + delete cache[keylist.shift()]; + return result; + }; + case 3: + return function memoize_three_args(a, b, c) { + args[0] = a; args[1] = b; args[2] = c; + key = JSON.stringify(args); + args.length = 0; + + if (key in cache) + return cache[key]; + + var result = func.call(null, a, b, c); + cache[key] = result; + if (keylist.push(key) > limit) + delete cache[keylist.shift()]; + return result; + }; + + case 4: + return function memoize_four_args(a, b, c, d) { + args[0] = a; args[1] = b; args[2] = c; args[3] = d; + key = JSON.stringify(args); + args.length = 0; + + if (key in cache) + return cache[key]; + + var result = func.call(null, a, b, c, d); + cache[key] = result; + if (keylist.push(key) > limit) + delete cache[keylist.shift()]; + return result; + }; + + default: + return function() { + var key = JSON.stringify(arguments); + if (key in cache) + return cache[key]; + + var result = func.apply(null, arguments); + cache[key] = result; + if (keylist.push(key) > limit) + delete cache[keylist.shift()]; + return result; + }; + } +} diff --git a/packages/vold-utils/lib/net-utils.js b/packages/vold-utils/lib/net-utils.js new file mode 100644 index 0000000..df7f300 --- /dev/null +++ b/packages/vold-utils/lib/net-utils.js @@ -0,0 +1,3 @@ + +require("chrome").Cu.import("resource://gre/modules/NetUtil.jsm", this); +exports.NetUtil = NetUtil; diff --git a/packages/vold-utils/lib/services.js b/packages/vold-utils/lib/services.js new file mode 100644 index 0000000..4854dfa --- /dev/null +++ b/packages/vold-utils/lib/services.js @@ -0,0 +1,84 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MIT/X11 License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Contributor(s): + * Erik Vold <erikvvold@gmail.com> (Original Author) + * + * ***** END LICENSE BLOCK ***** */ + +const {Cc, Ci, Cu} = require("chrome"); +Cu.import("resource://gre/modules/Services.jsm", this); + +const global = this; +var Services = exports.Services = {}; +(function(inc, tools){ + inc("resource://gre/modules/XPCOMUtils.jsm", global); + inc("resource://gre/modules/Services.jsm", tools); + Services.__proto__ = tools.Services; +})(Cu.import, {}); + +/* +XPCOMUtils.defineLazyGetter(Services, "scriptish", function() ( + Cc["@scriptish.erikvold.com/scriptish-service;1"] + .getService().wrappedJSObject)); +*/ + +XPCOMUtils.defineLazyServiceGetter( + Services, "as", "@mozilla.org/alerts-service;1", "nsIAlertsService"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "ass", "@mozilla.org/appshell/appShellService;1", + "nsIAppShellService"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "cb", "@mozilla.org/widget/clipboardhelper;1", + "nsIClipboardHelper"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "cs", "@mozilla.org/consoleservice;1", "nsIConsoleService"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "eps", "@mozilla.org/uriloader/external-protocol-service;1", + "nsIExternalProtocolService"); + +if (Cc["@mozilla.org/privatebrowsing;1"]) { + XPCOMUtils.defineLazyServiceGetter( + Services, "pbs", "@mozilla.org/privatebrowsing;1", + "nsIPrivateBrowsingService"); +} else { + Services.pbs = {privateBrowsingEnabled: false}; +} + +XPCOMUtils.defineLazyServiceGetter( + Services, "sis", "@mozilla.org/scriptableinputstream;1", + "nsIScriptableInputStream"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "suhtml", "@mozilla.org/feed-unescapehtml;1", + "nsIScriptableUnescapeHTML"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "tld", "@mozilla.org/network/effective-tld-service;1", + "nsIEffectiveTLDService"); + +XPCOMUtils.defineLazyServiceGetter( + Services, "uuid", "@mozilla.org/uuid-generator;1", + "nsIUUIDGenerator"); diff --git a/packages/vold-utils/lib/unload+.js b/packages/vold-utils/lib/unload+.js new file mode 100644 index 0000000..285fd46 --- /dev/null +++ b/packages/vold-utils/lib/unload+.js @@ -0,0 +1,80 @@ +/* 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"; + +const { Class } = require("sdk/core/heritage"); +const unloadNS = require("sdk/core/namespace").ns(); + +var Unloader = exports.Unloader = Class({ + initialize: function Unloader() { + let unloaders = unloadNS(this).unloaders = []; + + let unloadersUnlaod = unloadNS(this).unloadersUnlaod = function() { + unloaders.slice().forEach(function(u) u()); + unloaders.length = 0; + } + + require("sdk/system/unload").when(unloadersUnlaod); + }, + unload: function unload(callback, container) { + // Calling with no arguments runs all the unloader callbacks + if (callback == null) { + unloadNS(this).unloadersUnlaod(); + return null; + } + + var remover = removeUnloader.bind(null, unloader, unloadNS(this).unloaders); + + // The callback is bound to the lifetime of the container if we have one + if (container != null) { + // Remove the unloader when the container unloads + container.addEventListener("unload", remover, false); + + // Wrap the callback to additionally remove the unload listener + let origCallback = callback; + callback = function() { + container.removeEventListener("unload", remover, false); + origCallback(); + } + } + + // Wrap the callback in a function that ignores failures + function unloader() { + try { + callback(); + } + catch(e) { + console.error(e); + } + } + unloadNS(this).unloaders.push(unloader); + + // Provide a way to remove the unloader + return remover; + } +}); + +function removeUnloader(unloader, unloaders) { + let index = unloaders.indexOf(unloader); + if (index != -1) + unloaders.splice(index, 1); +} + +/** + * Save callbacks to run when unloading. Optionally scope the callback to a + * container, e.g., window. Provide a way to run all the callbacks. + * + * @usage unload(): Run all callbacks and release them. + * + * @usage unload(callback): Add a callback to run on unload. + * @param [function] callback: 0-parameter function to call on unload. + * @return [function]: A 0-parameter function that undoes adding the callback. + * + * @usage unload(callback, container) Add a scoped callback to run on unload. + * @param [function] callback: 0-parameter function to call on unload. + * @param [node] container: Remove the callback when this container unloads. + * @return [function]: A 0-parameter function that undoes adding the callback. + */ +const gUnload = Unloader(); +exports.unload = gUnload.unload.bind(gUnload); diff --git a/packages/vold-utils/lib/window-watcher.js b/packages/vold-utils/lib/window-watcher.js new file mode 100644 index 0000000..ab4f449 --- /dev/null +++ b/packages/vold-utils/lib/window-watcher.js @@ -0,0 +1,91 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Twitter Address Bar Search. + * + * The Initial Developer of the Original Code is The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Edward Lee <edilee@mozilla.com> + * Erik Vold <erikvvold@gmail.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +const {Cu} = require("chrome"); +Cu.import("resource://gre/modules/Services.jsm", this); + +var {unload} = require("unload+"); + +/** + * Apply a callback to each open and new browser windows. + * + * @usage watchWindows(callback): Apply a callback to each browser window. + * @param [function] callback: 1-parameter function that gets a browser window. + */ +exports.watchWindows = function watchWindows(callback) { + // Wrap the callback in a function that ignores failures + function watcher(window) { + try { + // Now that the window has loaded, only handle browser windows + let {documentElement} = window.document; + if (documentElement.getAttribute("windowtype") == "navigator:browser") + callback(window); + } + catch(ex) {} + } + + // Wait for the window to finish loading before running the callback + function runOnLoad(window) { + // Listen for one load event before checking the window type + window.addEventListener("load", function runOnce() { + window.removeEventListener("load", runOnce, false); + watcher(window); + }, false); + } + + // Add functionality to existing windows + let windows = Services.wm.getEnumerator(null); + while (windows.hasMoreElements()) { + // Only run the watcher immediately if the window is completely loaded + let window = windows.getNext(); + if (window.document.readyState == "complete") + watcher(window); + // Wait for the window to load before continuing + else + runOnLoad(window); + } + + // Watch for new browser windows opening then wait for it to load + function windowWatcher(subject, topic) { + if (topic == "domwindowopened") + runOnLoad(subject); + } + Services.ww.registerNotification(windowWatcher); + + // Make sure to stop watching for windows if we're unloading + unload(function() Services.ww.unregisterNotification(windowWatcher)); +}; diff --git a/packages/vold-utils/lib/xpcom-utils.js b/packages/vold-utils/lib/xpcom-utils.js new file mode 100644 index 0000000..f453b34 --- /dev/null +++ b/packages/vold-utils/lib/xpcom-utils.js @@ -0,0 +1,3 @@ + +require("chrome").Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); +exports.XPCOMUtils = XPCOMUtils; |