diff options
Diffstat (limited to 'data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib')
50 files changed, 3416 insertions, 0 deletions
diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/addon/folder.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/addon/folder.js new file mode 100644 index 0000000..4b590c5 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/addon/folder.js @@ -0,0 +1,51 @@ +'use strict'; + +const JETPACK_DIR_BASENAME = "jetpack"; +const PATH_TEST = /^[\s\.\\\/]/; + +const { Cc, Ci } = require('chrome'); +const file = require('sdk/io/file'); +const jpSelf = require('sdk/self'); + +let storeFile = Cc['@mozilla.org/file/directory_service;1'] + .getService(Ci.nsIProperties) + .get('ProfD', Ci.nsIFile); +storeFile.append(JETPACK_DIR_BASENAME); +storeFile.append(jpSelf.id); +storeFile.append('addon-folder'); + +const ADDON_FOLDER_PATH = storeFile.path + '/'; + +// make the addon-folder container folder +file.mkpath(ADDON_FOLDER_PATH); + +function ioFileWrap(funcName, preMode) { + preMode = preMode || ""; + return function(filepath, mode) { + filepath = filepath || ''; + if (PATH_TEST.test(filepath)) { + throw 'The provided filepath "' + filepath + '"" is not valid'; + } + return file[funcName](ADDON_FOLDER_PATH + filepath, preMode + mode); + } +} +exports.isFile = ioFileWrap('isFile'); +exports.exists = ioFileWrap('exists'); + +exports.remove = function(filepath) { + if (exports.isFile(filepath)) { + file.remove(ADDON_FOLDER_PATH + filepath); + } + else { + file.rmdir(ADDON_FOLDER_PATH + filepath); + } +}; +exports.read = ioFileWrap('read'); +exports.write = ioFileWrap('open', 'w'); +exports.mkpath = ioFileWrap('mkpath'); +exports.list = ioFileWrap('list'); + +exports.destroy = function destroy() { + // remove the addon-folder container folder + file.rmdir(ADDON_FOLDER_PATH); +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/addon/unload.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/addon/unload.js new file mode 100644 index 0000000..78803e7 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/addon/unload.js @@ -0,0 +1,92 @@ +/* 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(); +const { when: unload } = require("sdk/system/unload"); + +var Unloader = exports.Unloader = Class({ + initialize: function Unloader() { + unloadNS(this).unloaders = []; + unloadNS(this).unloadersUnload = unloadersUnload.bind(null, unloadNS(this).unloaders); + + // run the unloaders on unload + unload(unloadNS(this).unloadersUnload); + }, + unload: function unload(callback, container) { + // Calling with no arguments runs all the unloader callbacks + if (callback == null) { + unloadNS(this).unloadersUnload(); + return null; + } + + let windowRemover = windowUnloader.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", windowRemover, false); + + // Wrap the callback to additionally remove the unload listener + let origCallback = callback; + callback = function() { + container.removeEventListener("unload", windowRemover, 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 removeUnloader.bind(null, unloader, unloadNS(this).unloaders); + } +}); + +function sliceUnloader(unloader, unloaders) { + let index = unloaders.indexOf(unloader); + if (index < 0) + return []; + return unloaders.splice(index, 1); +} +// wraps sliceUnloader and doesn't return anything +function removeUnloader(unloader, unloaders) { + sliceUnloader.apply(null, arguments); +} +function windowUnloader(unloader, unloaders) { + sliceUnloader.apply(null, arguments).forEach(function(u) u()); +} +function unloadersUnload(unloaders) { + // run all the pending unloaders + unloaders.slice().forEach(function(u) u()); + // clear the unload array + unloaders.length = 0; +} + +/** + * 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/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/addon.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/addon.js new file mode 100644 index 0000000..815f8ed --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/addon.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 {Cc, Ci, Cu} = require("chrome"); +const {AddonManager, AddonAuthor} = require("../utils/addonmanager"); +const DO_NOTHING = function(){}; + +// https://developer.mozilla.org/en/Addons/Add-on_Manager/Addon +function Addon(options) { + + this.appDisabled = !!options.appDisabled || false; + this.blocklistState = (options.blocked) ? 2 : 0; + if (options.creator) { + this.creator = new AddonAuthor(options.creator.name); + } + this.id = options.id; + if (typeof options.isActive != "undefined") this.isActive = !!options.isActive; + if (typeof options.isCompatible != "undefined") this.isCompatible = !!options.isCompatible; + if (typeof options.isPlatformCompatible != "undefined") this.isPlatformCompatible = !!options.isPlatformCompatible; + this.name = options.name || ""; + //this.pendingOperations = + this.description = options.description || ""; + if (options.iconURL) this.iconURL = options.iconURL; + + // METHODS + this.uninstall = function() { + options.uninstall && options.uninstall(); + }; + this.cancelUninstall = function() { + options.cancelUninstall && options.cancelUninstall(); + }; + + if (options.getResourceURI) { + this.getResourceURI = function(aPath) { + return options.getResourceURI(aPath); + }; + this.getXPI = function() { + return options.getResourceURI("").QueryInterface(Ci.nsIFileURL).file; + } + } + + return this; +}; + +Addon.prototype = { + // req'd + appDisabled: false, + blocklistState: 0, + creator: null, + id: null, + isActive: true, + isCompatible: true, + isPlatformCompatible: true, + name: null, + pendingOperations: AddonManager.PENDING_NONE, + permissions: AddonManager.PERM_CAN_UNINSTALL, + providesUpdatesSecurely: false, + scope: AddonManager.SCOPE_PROFILE, + type: null, + userDisabled: false, + version: null, + + //not reqd + applyBackgroundUpdates: AddonManager.AUTOUPDATE_DISABLE, + contributors: [], + description: "", + translators: [], + sourceURI: null, + + + // METHODS + uninstall: DO_NOTHING, + findUpdates: DO_NOTHING, + cancelUninstall: DO_NOTHING, + hasResource: DO_NOTHING +}; + +exports.Addon = Addon; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/manager.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/manager.js new file mode 100644 index 0000000..cc9388e --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/manager.js @@ -0,0 +1,15 @@ +/* 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 {AddonManager, AddonManagerPrivate} = require("../utils/addonmanager"); +const Addon = require("addon").Addon; + +exports.getAddonByID = exports.getAddonById = function(aID, aCallback) { + // get the addon obj + AddonManager.getAddonByID(aID, function (addon) { + // return a wrapped addon + aCallback(new Addon(addon)); + }); +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/provider.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/provider.js new file mode 100644 index 0000000..681dcd9 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/aom/provider.js @@ -0,0 +1,52 @@ +/* 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 = require("sdk/system/unload").when; + +const {AddonManager, AddonManagerPrivate, AddonType} = require("../utils/addonmanager"); + +var defaultUIPriority = 6001; // this increases when it is used + +exports.AddonProvider = function(options) { + var types = null; + + // AddonManagerPrivate.AddonType DNE in Gecko (FF) < 6 + if (AddonType) { + types = [new AddonType( + options.type, // TODO: RANDOMIZE? + null, + options.localeKey, + AddonManager.VIEW_TYPE_LIST, + options.uiPriority || defaultUIPriority++)]; + } + + var provider = { + getAddonByID: function(aId, aCallback) { + aCallback(options.getAddonByID(aId)); + }, + + getAddonsByTypes: function(aTypes, aCallback) { + if (aTypes && aTypes.indexOf(options.type) < 0) { + // not the right type, return nothing + aCallback([]); + } + else { + // the right type, return all addons + aCallback(options.getAddons()); + } + }, + + getInstallsByTypes: function(aTypes, aCallback) { + aCallback([]); + } + }; + AddonManagerPrivate.registerProvider(provider, types); + + unload(function() { + AddonManagerPrivate.unregisterProvider(provider); + }); + + return this; +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/application/restart.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/application/restart.js new file mode 100644 index 0000000..7d97f37 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/application/restart.js @@ -0,0 +1,22 @@ +/* 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 { Cc, Ci } = require("chrome"); + +exports.restart = function restart() { + let canceled = Cc["@mozilla.org/supports-PRBool;1"] + .createInstance(Ci.nsISupportsPRBool); + + Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService) + .notifyObservers(canceled, "quit-application-requested", "restart"); + + if (canceled.data) return false; // somebody canceled our quit request + + // restart + Cc['@mozilla.org/toolkit/app-startup;1'].getService(Ci.nsIAppStartup) + .quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); + + return true; +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/instances.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/instances.js new file mode 100644 index 0000000..da9edb8 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/instances.js @@ -0,0 +1,36 @@ +/* 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 { 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/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/net-utils.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/net-utils.js new file mode 100644 index 0000000..a657d20 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/net-utils.js @@ -0,0 +1,7 @@ +/* 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'; + +require("chrome").Cu.import("resource://gre/modules/NetUtil.jsm", this); +exports.NetUtil = NetUtil; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/services.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/services.js new file mode 100644 index 0000000..9df8b59 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/services.js @@ -0,0 +1,57 @@ +/* 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 { 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.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/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/xpcom-utils.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/xpcom-utils.js new file mode 100644 index 0000000..f453b34 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/chrome/xpcom-utils.js @@ -0,0 +1,3 @@ + +require("chrome").Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); +exports.XPCOMUtils = XPCOMUtils; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/events.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/events.js new file mode 100644 index 0000000..7d9071b --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/events.js @@ -0,0 +1,23 @@ +/* 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 events = require('sdk/system/events'); +const { on, once, off, emit } = require('sdk/event/core'); + +function onRequest(evt) { + emit(exports, 'modify-request', evt); +} +events.on('http-on-modify-request', onRequest); + +/* +function onResponse(evt) { + emit(exports, 'examine-response', evt); +} +events.on('http-on-examine-response', onResponse); +*/ + +exports.on = on.bind(null, exports); +exports.once = once.bind(null, exports); +exports.off = off.bind(null, exports); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/request.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/request.js new file mode 100644 index 0000000..bf93ca0 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/request.js @@ -0,0 +1,45 @@ +/* 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 { Ci } = require('chrome'); +const { List, addListItem, removeListItem } = require('sdk/util/list'); +const { ns } = require('sdk/core/namespace'); +const { Class } = require('sdk/core/heritage'); +const { Disposable } = require('sdk/core/disposable'); + +const events = require('./events'); + +const REQUEST_RULES = List(); +const requestNS = ns(); + +function onRequest(evt) { + for each (let rule in REQUEST_RULES) { + applyRequestHeaders(rule, evt) + } +} +events.on('modify-request', onRequest); + +const RequestRule = Class({ + implements: [ Disposable ], + initialize: function(details) { + requestNS(this).details = details; + addListItem(REQUEST_RULES, this); + }, + dispose: function() { + removeListItem(REQUEST_RULES, this); + } +}); +exports.RequestRule = RequestRule; + +function applyRequestHeaders(rule, evt) { + let channel = evt.subject.QueryInterface(Ci.nsIHttpChannel); + let requestURL = channel.URI.spec + + let details = requestNS(rule).details; + let { headers: rules } = details; + for each (let key in Object.keys(rules)) { + channel.setRequestHeader(key, rules[key] + '', false); + } +}
\ No newline at end of file diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/response.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/response.js new file mode 100644 index 0000000..c0ed791 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connection/response.js @@ -0,0 +1,44 @@ +/* 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 { Ci } = require('chrome'); +const { List, addListItem, removeListItem } = require('sdk/util/list'); +const { ns } = require('sdk/core/namespace'); +const { Class } = require('sdk/core/heritage'); + +const events = require('./events'); + +const RESPONSE_RULES = List(); + +const requestNS = ns(); + +function onResponse(evt) { + for each (let rule in RESPONSE_RULES) { + applyResponseHeaders(rule, evt) + } +} +events.on('examine-response', onResponse); + +const ResponseRule = Class({ + initialize: function(details) { + requestNS(this).details = details; + addListItem(RESPONSE_RULES, this); + }, + destroy: function() { + removeListItem(RESPONSE_RULES, this); + } +}); +exports.ResponseRule = ResponseRule; + +function applyResponseHeaders(rule, evt) { + let channel = evt.subject.QueryInterface(Ci.nsIHttpChannel); + let requestURL = channel.URI.spec + + let details = requestNS(rule).details; + let { headers: rules } = details; + for each (let key in Object.keys(rules)) { + channel.setResponseHeader(key, rules[key], false); + } +}
\ No newline at end of file diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connections.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connections.js new file mode 100644 index 0000000..b81eba1 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/connections.js @@ -0,0 +1,8 @@ +/* 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'; + +exports.RequestRule = require('./connection/request').RequestRule; +//exports.ResponseRule = require('./connection/response').ResponseRule; + diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/content/permissions.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/content/permissions.js new file mode 100644 index 0000000..49cc955 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/content/permissions.js @@ -0,0 +1,88 @@ +/* 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 { Cc, Ci, Cu } = require('chrome'); +const { List, addListItem } = require('sdk/util/list'); +const { URL } = require('sdk/url'); + +const { Services } = require('../chrome/services'); + +const { nsIPermissionManager } = Ci; + +const UNKNOWN = nsIPermissionManager.UNKNOWN_ACTION; // 0 +const ALLOW = nsIPermissionManager.ALLOW_ACTION; // 1 +const BLOCK = nsIPermissionManager.DENY_ACTION; // 2 +const SESSION = Ci.nsICookiePermission.ACCESS_SESSION; // 8 + +function getKey(obj, val) { + for (let key in obj) + if (obj[key] == val) + return key; + + return undefined; +} + +const PERMISSIONS = { + 'session': SESSION, + 'allow': ALLOW, + 'deny': BLOCK +}; + +const TYPES = { + 'images': 'image', + 'popups': 'popup', + 'desktop-notifications': 'desktop-notification', + 'installs': 'install', + 'location': 'geo', + 'fullscreen': 'fullscreen', + 'pointer-lock': 'pointerLock' +} + +const PM = Cc['@mozilla.org/permissionmanager;1']. + getService(nsIPermissionManager); + +function add(options) { + let uri = Services.io.newURI(options.url, null, null); + if (!/^https?/.test(uri.scheme)) { + throw new Error('invalid content url, only https or http schemes are accepted'); + } + + PM.add(uri, + TYPES[options.type], + PERMISSIONS[options.permission]); +} + +function remove(options) { + PM.remove(URL(options.url).host, TYPES[options.type]); +} + +function removeAll() { + PM.removeAll(); +} + +// TODO: cache entries after first request, and observe new additions with the "perm-changed" event + +exports.permissions = { + add: add, + remove: remove, + removeAll: removeAll, + get permissions() { + let list = List(); + let permissions = PM.enumerator; + while (permissions.hasMoreElements()) { + let permission = permissions.getNext().QueryInterface(Ci.nsIPermission); + + addListItem(list, { + type: getKey(TYPES, permission.type), + host: String(permission.host), + permission: getKey(PERMISSIONS, Number(permission.capability)) + //'expire-time': Number(permission.expireTime), + }); + } + return list; + }, + TYPES: TYPES, + PERMISSIONS: PERMISSIONS +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/content/policy.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/content/policy.js new file mode 100644 index 0000000..b764272 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/content/policy.js @@ -0,0 +1,143 @@ +/* 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 { Cc, Ci } = require('chrome'); +const { Class } = require('sdk/core/heritage'); +const CP_NS = require('sdk/core/namespace').ns(); +const { ensure } = require('sdk/system/unload'); +const { validateOptions } = require('sdk/deprecated/api-utils'); +const { id: ADDON_ID } = require('sdk/self'); +const xpcom = require('sdk/platform/xpcom'); + +const CM = Cc["@mozilla.org/categorymanager;1"] + .getService(Ci.nsICategoryManager); + +const ACCEPT = exports.ACCEPT = Ci.nsIContentPolicy.ACCEPT; +const REJECT = exports.REJECT = Ci.nsIContentPolicy.REJECT_REQUEST; + +const accept = function() ACCEPT; + +let ContentPolicy_ID = 0; + +const RULES = { + description: { + map: function(v) { + return v ? v : ''; + }, + is: ['string'] + }, + contract: { + map: function(v) { + if (v === undefined) { + v = '@erikvold.com/content-policy.' + ADDON_ID + ';' + ContentPolicy_ID++; + } + return v; + }, + is: ['string'] + }, + entry: { + is: ['string', 'undefined'] + }, + shouldLoad: { + is: ['function', 'undefined'] + }, + shouldProcess: { + is: ['function', 'undefined'] + }, +}; + +function getType(aType) { + switch (aType) { + case Ci.nsIContentPolicy.TYPE_SCRIPT: + return 'script'; + case Ci.nsIContentPolicy.TYPE_IMAGE: + return 'image'; + case Ci.nsIContentPolicy.TYPE_STYLESHEET: + return 'stylesheet'; + case Ci.nsIContentPolicy.TYPE_OBJECT: + return 'object'; + case Ci.nsIContentPolicy.TYPE_DOCUMENT: + return 'document'; + case Ci.nsIContentPolicy.TYPE_SUBDOCUMENT: + return 'subdocument'; + case Ci.nsIContentPolicy.TYPE_REFRESH: + return 'refresh'; + case Ci.nsIContentPolicy.TYPE_XBL: + return 'xbl'; + case Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST: + return 'xhr'; + case Ci.nsIContentPolicy.TYPE_PING: + return 'ping'; + // TODO: support more types + } + return 'other'; +} +const getTypeMemod = memoize(getType, 12, 1); + +function makeDetails(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess) { + return { + type: getTypeMemod(aContentType), + location: aContentLocation.spec, + origin: aRequestOrigin.spec, + context: null, // TODO: support this in a safe way somehow.. + mimeTypeGuess: String(aMimeTypeGuess) + }; +} + +let ContentPolicy = exports.ContentPolicy = Class({ + initialize: function(options) { + const self = this; + options = CP_NS(self).options = validateOptions(options, RULES); + CP_NS(self).shouldLoad = options.shouldLoad || accept; + CP_NS(self).shouldProcess = options.shouldProcess || accept; + + let factory = CP_NS(this).factory = xpcom.Factory({ + Component: getProvider(self), + description: options.description, + contract: options.contract + }); + + let entry = options.entry || options.contract; + CM.addCategoryEntry('content-policy', entry, factory.contract, false, true); + ensure(this, 'destroy'); + }, + destroy: function() { + // already destroyed? + if (!CP_NS(this).options) + return; + + let options = CP_NS(this).options; + CP_NS(this).options = null; + CP_NS(this).shouldLoad = accept; + CP_NS(this).shouldProcess = accept; + + CM.deleteCategoryEntry('content-policy', options.entry || options.contract, false); + } +}); + +function getProvider(self) { + return Class({ + extends: xpcom.Unknown, + interfaces: ['nsIContentPolicy'], + shouldLoad: function (aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) { + let load = CP_NS(self).shouldLoad(makeDetails.apply(null, arguments)); + return (load == REJECT || (!load && load !== undefined)) ? REJECT : ACCEPT; + }, + shouldProcess: function (aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) { + let load = CP_NS(self).shouldProcess(makeDetails.apply(null, arguments)); + return (load == REJECT || (!load && load !== undefined)) ? REJECT : ACCEPT; + } + }); +} + +function memoize(func) { + let cache = Object.create(null); + return function(a) { + let key = a.toString(); + if (key in cache) + return cache[key]; + return cache[key] = func.call(null, a); + }; +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/devtools/gcli.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/devtools/gcli.js new file mode 100644 index 0000000..e1bb17f --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/devtools/gcli.js @@ -0,0 +1,23 @@ +'use strict'; + +const { Cu } = require('chrome'); +const { when: unload } = require('unload'); + +try { + // Starting with FF 23, gcli.jsm moved to another location + Cu.import("resource://gre/modules/devtools/gcli.jsm"); +} catch(e) { + try { + Cu.import("resource:///modules/devtools/gcli.jsm"); + } catch(e) { + console.error("Unable to load gcli.jsm"); + } +} + +function addCommand(cmd) { + let name = cmd.name; + gcli.addCommand(cmd); + unload(gcli.removeCommand.bind(gcli, name)); +} +exports.addCommand = addCommand; +exports.removeCommand = gcli.removeCommand; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/download.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/download.js new file mode 100644 index 0000000..20fef54 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/download.js @@ -0,0 +1,95 @@ +/* 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 { Ci, Cc, Cu } = require('chrome'); +const { Class } = require('sdk/core/heritage'); +const { on, off, emit, setListeners } = require('sdk/event/core'); +const { EventTarget } = require("sdk/event/target"); +const { ns } = require("sdk/core/namespace"); +const { validateOptions } = require("sdk/deprecated/api-utils"); +const { isValidURI } = require("sdk/url"); + +const PROGRESS_LISTENER_NS = ns(); + +const { Services } = Cu.import('resource://gre/modules/Services.jsm', {}); + +const rules = { + url: { + // Also converts a URL instance to string, bug 857902 + map: function (url) url.toString(), + ok: isValidURI + }, + destination: { + is: ['string'] + } +}; + +const Download = Class({ + extends: EventTarget, + initialize: function(options) { + // Setup listeners. + setListeners(this, options); + + options = validateOptions(options, rules); + + const wbp = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] + .createInstance(Ci.nsIWebBrowserPersist); + let listener = ProgressListener({ + download: this + }); + + wbp.progressListener = listener; + + let localFile = Cc["@mozilla.org/file/local;1"] + .createInstance(Ci.nsILocalFile); + localFile.initWithPath(options.destination); + localFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0666", 8)); + localFile = localFile.QueryInterface(Ci.nsIFile); + + let uri = Services.io.newURI(options.url, null, null); + wbp.saveURI(uri, null, null, null, null, localFile, null); + } +}); +exports.Download = Download; + +const ProgressListener = Class({ + initialize: function(options) { + const internals = PROGRESS_LISTENER_NS(this); + internals.options = options; + this.onStateChange = this.onStateChange.bind(this); + }, + get options() PROGRESS_LISTENER_NS(this).options, + get download() this.options.download, + onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) { + }, + onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) { + emit(this.download, 'progress', { + current: aCurTotalProgress, + total: aMaxTotalProgress + }) + }, + onSecurityChange: function(aWebProgress, aRequest, aState) { + }, + onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) { + if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)) + return; + + try { + var { responseStatus, requestSucceeded } = aRequest.QueryInterface(Ci.nsIHttpChannel); + } + catch (e) { + //console.exception(e); + } + + emit(this.download, 'complete', { + responseStatus: responseStatus, + requestSucceeded: requestSucceeded + }); + + return; + }, + onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) { + } +}); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/l10n.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/l10n.js new file mode 100644 index 0000000..22ed58c --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/l10n.js @@ -0,0 +1,76 @@ +/* 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 global = this; +const {Cc,Ci,Cu} = require("chrome"); +Cu.import("resource://gre/modules/Services.jsm", global); + +exports.locale = Cc["@mozilla.org/chrome/chrome-registry;1"] + .getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"); + +exports.l10n = (function(global) { + let splitter = /(\w+)-\w+/; + + // get user's locale + let locale = exports.locale; + + function getStr(aStrBundle, aKey) { + if (!aStrBundle) return false; + try { + return aStrBundle.GetStringFromName(aKey); + } catch (e) { + //console.log(e); + } + return ""; + } + + function l10n(options) { + var filename = options.filename; + var baseURL = options.baseURL; + var defaultLocale = options.defaultLocale || "en"; + function filepath(locale) { + var path = baseURL + "/" + locale + "/" + filename; + //console.log(path); + return path; + } + + let defaultBundle = Services.strings.createBundle(filepath(locale)); + + let defaultBasicBundle; + let (locale_base = locale.match(splitter)) { + if (locale_base) { + defaultBasicBundle = Services.strings.createBundle( + filepath(locale_base[1])); + } + } + + let addonsDefaultBundle = + Services.strings.createBundle(filepath(defaultLocale)); + + return _ = function l10n_underscore(aKey, aLocale) { + let localeBundle, localeBasicBundle; + if (aLocale) { + localeBundle = Services.strings.createBundle(filepath(aLocale)); + + let locale_base = aLocale.match(splitter) + if (locale_base) + localeBasicBundle = Services.strings.createBundle( + filepath(locale_base[1])); + } + + var x = getStr(localeBundle, aKey) + || getStr(localeBasicBundle, aKey) + || getStr(defaultBundle, aKey) + || getStr(defaultBasicBundle, aKey) + || getStr(addonsDefaultBundle, aKey); + return x; + } + } + + return l10n; +})(this); + +require("unload").when(Services.strings.flushBundles); + diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/panic.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/panic.js new file mode 100644 index 0000000..a478077 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/panic.js @@ -0,0 +1,92 @@ +/* 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 { setTimeout } = require('sdk/timers'); +const { get, set } = require('sdk/preferences/service'); +const { add, notify } = require('sdk/deprecated/observer-service'); +const { on, once, emit, off } = require('sdk/event/core'); +const { loadReason } = require('sdk/self'); + +const { unload } = require('./addon/unload'); + +const PREF_NAME = 'security.addon.panic'; +function inPanic() get(PREF_NAME, false); +function setPanic(value) set(PREF_NAME, value); + +const PREF_END_NAME = 'security.addon.panic_end'; +function getEndTime() get(PREF_END_NAME, 0) * 1; +function setEndTime(timestamp) set(PREF_END_NAME, timestamp + ""); + +Object.defineProperty(exports, "inPanic", { + get: function() inPanic() +}); + +const panic = function (ms) { + ms = ms || 0; + let endTime = Date.now() + ms; + + // check that the current end timestamp is not greater + if (getEndTime() >= endTime) + return; + + // set the end timestamp (to handle the reboot situation) + setEndTime(endTime); + + // notify system of a panic + notify('panic-start'); + + // end the panic + setTimeout(function() { + // check that the end timestamp was not extended by another panic + // NOTE: another instance of panic module could have caused the old panic + if (getEndTime() != endTime) return; + + notify('panic-end'); + }, ms); +}; +exports.panic = panic; + +// internal object used to emit on, instead of `exports`, so that outside code +// cannot emit on this object. +const panicEmitter = {}; + +// create and expose event listener related methods for this module +exports.on = on.bind(null, panicEmitter); +exports.once = once.bind(null, panicEmitter); +exports.off = off.bind(null, panicEmitter); + +// listen to 'panic-start' events in the observer-service since they may come +// from other instances of this module +add('panic-start', function () { + setPanic(true); + emit(panicEmitter, 'start'); +}); +// listen to 'panic-end' events for the same reason as for 'panic-start' +add('panic-end', function () { + setPanic(false); + emit(panicEmitter, 'end'); +}); + +// cleanup prefs on startup, since the add-on could be installed before or +// during startup +if (loadReason == 'startup') { + // check the end timestamp (for the reboot situation) + if (getEndTime() <= Date.now()) { + setEndTime(0); + + if (inPanic()) { + setPanic(false); + } + } +} + +// clean up prefs on shutdown, don't do cleanup on other reasons because there +// may be other instances of the module running +unload(function(reason) { + if (reason == 'shutdown') { + setPanic(false); + setEndTime(0); + } +}); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/redirect.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/redirect.js new file mode 100644 index 0000000..ffd46db --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/redirect.js @@ -0,0 +1,52 @@ +/* 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 { Ci } = require('chrome'); +const { List, addListItem, removeListItem } = require('sdk/util/list'); +const { ns } = require('sdk/core/namespace'); +const { Class } = require('sdk/core/heritage'); +const { Disposable } = require('sdk/core/disposable'); +const { newURI } = require('sdk/url/utils'); + +const events = require('./connection/events'); + +const REDIRECTS = List(); +const requestNS = ns(); + +function onRequest({ subject }) { + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + for each (let redirect in REDIRECTS) + if (applyRedirect(redirect, channel)) + break; + return; +} +events.on('modify-request', onRequest); + +const Redirect = Class({ + implements: [ Disposable ], + initialize: function(details) { + details.to = newURI(details.to.toString()); + requestNS(this).details = details; + + addListItem(REDIRECTS, this); + }, + dispose: function() { + removeListItem(REDIRECTS, this); + }, + get from() requestNS(this).details.from, + get to() requestNS(this).details.to.spec +}); +exports.Redirect = Redirect; + +function applyRedirect(redirect, channel) { + let { from, to } = requestNS(redirect).details; + + if (channel.URI.spec == from) { + channel.redirectTo(to); + // emit(rule, 'redirect', {}); + return true; + } + return false; +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scheme/about.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scheme/about.js new file mode 100644 index 0000000..7d94b78 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scheme/about.js @@ -0,0 +1,84 @@ +/* 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 { Cr, Cu, Ci, Cc, Cm } = require('chrome'); +const { when: unload } = require('sdk/system/unload'); +const { validateOptions : validate } = require('sdk/deprecated/api-utils'); +const { uuid } = require('sdk/util/uuid'); +const { URL, isValidURI } = require('sdk/url'); +const tabs = require('sdk/tabs'); + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +const validOptions = { + what: { + is: ['string'], + ok: function(what) { + if (what.match(/^[a-z0-9-]+$/i)) + return true; + return false; + }, + map: function(url) url.toLowerCase() + }, + url: { + map: function(url) url.toString(), + ok: isValidURI + }, + useChrome: { + is: ['undefined', 'null', 'boolean'], + map: function(use) !!use + } +}; + +function add(options) { + let { what, url, useChrome } = validate(options, validOptions); + let classID = uuid(); + + let aboutModule = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), + newChannel: function (aURI) { + let chan = Services.io.newChannel(url, null, null); + if (useChrome) + chan.owner = Services.scriptSecurityManager.getSystemPrincipal(); + return chan; + }, + getURIFlags: function () Ci.nsIAboutModule.ALLOW_SCRIPT + }; + + let factory = { + createInstance: function(aOuter, aIID) { + if (aOuter) + throw Cr.NS_ERROR_NO_AGGREGATION; + return aboutModule.QueryInterface(aIID); + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]) + }; + + // register about:what + Cm.QueryInterface(Ci.nsIComponentRegistrar). + registerFactory(classID, '', '@mozilla.org/network/protocol/about;1?what='+what, factory); + + let remover = unloader.bind(null, what, factory, classID); + unload(remover); + + return undefined; +} +exports.add = add; + +function unloader(what, factory, classID) { + // unregister about:what + Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(classID, factory); + let regEx = new RegExp('^' + what, 'i'); + + // AMO policy, see http://maglione-k.users.sourceforge.net/bootstrapped.xhtml + // close about:what tabs + for each (let tab in tabs) { + let url = URL(tab.url); + if (url.scheme === 'about' && url.path.match(regEx)) { + tab.close(); + } + } +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scheme/resource.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scheme/resource.js new file mode 100644 index 0000000..81a4061 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scheme/resource.js @@ -0,0 +1,43 @@ +/*jshint asi:true globalstrict:true*/ +'use strict'; + +const { Cc, Ci } = require('chrome') +const ioService = Cc['@mozilla.org/network/io-service;1']. + getService(Ci.nsIIOService); +const resourceHandler = ioService.getProtocolHandler('resource'). + QueryInterface(Ci.nsIResProtocolHandler) + +function get(root) { + /** + Gets the substitution for the `root` key. + **/ + try { + return resourceHandler.getSubstitution(root).spec; + } + catch (error) {} + return null; +} +exports.get = get; + +function has(root) { + /** + Returns `true` if the substitution exists and `false` otherwise. + **/ + return resourceHandler.hasSubstitution(root); +} +exports.has = has; + +function set(root, uri) { + /** + Sets the substitution for the root key: + + resource://root/path ==> baseURI.resolve(path) + + A `null` `uri` removes substitution. A root key should + always be lowercase. However, this may not be enforced. + **/ + uri = !uri ? null : + uri instanceof Ci.nsIURI ? uri : ioService.newURI(uri, null, null); + resourceHandler.setSubstitution(root, uri); +} +exports.set = set; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/GM_xmlhttpRequester.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/GM_xmlhttpRequester.js new file mode 100644 index 0000000..8ca3f5b --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/GM_xmlhttpRequester.js @@ -0,0 +1,238 @@ +'use strict'; + +function Scriptish_stringBundle(a) a; + +const {Cc, Ci, Cu, Cr} = require("chrome"); +var {Instances} = require("../chrome/instances"); +var {XPCOMUtils} = require("../chrome/xpcom-utils"); +var {NetUtil} = require("../chrome/net-utils"); + +const MIME_JSON = /^(application|text)\/(?:x-)?json/i; + +/** + * Abstract base class for (chained) request notification callback overrides + * + * Use such overrides sparely, as the individual request performance might + * degrade quite a bit. + * + * @param req XMLHttpRequest (chrome) + * @author Nils Maier + */ +function NotificationCallbacks(req) { + throw new Error("trying to initiate an abstract NotificationCallbacks"); +} +NotificationCallbacks.prototype = { + init: function(req) { + // rewrite notification callbacks + this._channel = req.channel; + this._notificationCallbacks = this._channel.notificationCallbacks; + this._channel.notificationCallbacks = this; + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor]), + getInterface: function(iid) { + try { + return this.query(iid); + } + catch (ex) { + return this.queryOriginal(iid); + } + }, + queryOriginal: function(iid) { + if (this._notificationCallbacks) { + return this._notificationCallbacks.getInterface(iid); + } + throw Cr.NS_ERROR_NO_INTERFACE; + } +} + +/** + * Ignore (specific) redirects + * @param req XMLHttpRequest (chrome) + * @author Nils Maier + */ +function IgnoreRedirect(req, ignoreFlags) { + this.init(req); + this.ignoreFlags = ignoreFlags; +} +IgnoreRedirect.prototype = { + __proto__: NotificationCallbacks.prototype, + query: XPCOMUtils.generateQI([Ci.nsIChannelEventSink]), + asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) { + if (this.ignoreFlags & flags) { + // must throw here, not call callback.onRedirectVerifyCallback, + // or else it will completely cancel the request + throw Cr.NS_ERROR_UNEXPECTED; + } + + try { + let ces = this.queryOriginal(Ci.nsIChannelEventSink); + if (ces) { + ces.asyncOnChannelRedirect(oldChannel, newChannel, flags, callback); + return; + } + } + catch (ex) {} + + callback.onRedirectVerifyCallback(Cr.NS_OK); + } +}; + + +function GM_xmlhttpRequester(unsafeContentWin, originUrl, aScript) { + this.unsafeContentWin = unsafeContentWin; + this.originUrl = originUrl; + this.script = aScript; +} +exports.GM_xmlhttpRequester = GM_xmlhttpRequester; + +// this function gets called by user scripts in content security scope to +// start a cross-domain xmlhttp request. +// +// details should look like: +// {method,url,onload,onerror,onreadystatechange,headers,data} +// headers should be in the form {name:value,name:value,etc} +// can't support mimetype because i think it's only used for forcing +// text/xml and we can't support that +GM_xmlhttpRequester.prototype.contentStartRequest = function(details) { + try { + // Validate and parse the (possibly relative) given URL. + var uri = NetUtil.newURI(details.url, null, NetUtil.newURI(this.originUrl)); + var url = uri.spec; + } catch (e) { + // A malformed URL won't be parsed properly. + //throw new Error(Scriptish_stringBundle("error.api.reqURL") + ": " + details.url); + console.error(e); + } + + // check if the script is allowed to access the url + if (!this.script.matchesDomain(url)) + throw new Error( + "User script is attempting access to restricted domain '" + uri.host + "'", + this.script.fileURL); + + // This is important - without it, GM_xmlhttpRequest can be used to get + // access to things like files and chrome. Careful. + switch (uri.scheme) { + case "http": + case "https": + case "ftp": + var req = Instances.xhr; + this.chromeStartRequest(url, details, req); + break; + default: + throw new Error(Scriptish_stringBundle("error.api.reqURL.scheme") + ": " + details.url); + } + + return { + abort: function() { + req.abort(); + } + }; +}; + +// this function is intended to be called in chrome's security context, so +// that it can access other domains without security warning +GM_xmlhttpRequester.prototype.chromeStartRequest = + function(safeUrl, details, req) { + this.setupRequestEvent(this.unsafeContentWin, req, "onload", details); + this.setupRequestEvent(this.unsafeContentWin, req, "onerror", details); + this.setupRequestEvent( + this.unsafeContentWin, req, "onreadystatechange", details); + + if (details.mozBackgroundRequest) req.mozBackgroundRequest = true; + + req.open( + details.method || "GET", + safeUrl, + true, + details.user || "", + details.password || "" + ); + + if (details.overrideMimeType) req.overrideMimeType(details.overrideMimeType); + + if (details.ignoreCache) + req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; // bypass cache + + if (details.ignoreRedirect) + new IgnoreRedirect(req, + Ci.nsIChannelEventSink.REDIRECT_TEMPORARY | Ci.nsIChannelEventSink.REDIRECT_PERMANENT); + if (details.ignoreTempRedirect) + new IgnoreRedirect(req, Ci.nsIChannelEventSink.REDIRECT_TEMPORARY); + if (details.ignorePermanentRedirect) + new IgnoreRedirect(req, Ci.nsIChannelEventSink.REDIRECT_PERMANENT); + + let redirectionLimit = null; + if (details.failOnRedirect) { + redirectionLimit = 0; + } + if ("redirectionLimit" in details) { + if (details.redirectionLimit < 0 || details.redirectionLimit > 10) { + throw new Error("redirectionLimit must be within (0, 10), but it is " + details.redirectionLimit); + } + redirectionLimit = details.redirectionLimit; + } + if (redirectionLimit !== null && req.channel instanceof Ci.nsIHttpChannel) { + req.channel.redirectionLimit = redirectionLimit; + } + + if (details.headers) { + var headers = details.headers; + + for (var prop in headers) { + if (Object.prototype.hasOwnProperty.call(headers, prop)) + req.setRequestHeader(prop, headers[prop]); + } + } + + var body = details.data ? details.data : null; + if (details.binary) req.sendAsBinary(body); + else req.send(body); +} + +// arranges for the specified 'event' on xmlhttprequest 'req' to call the +// method by the same name which is a property of 'details' in the content +// window's security context. +GM_xmlhttpRequester.prototype.setupRequestEvent = + function(unsafeContentWin, req, event, details) { + var origMimeType = details.overrideMimeType; + var script = this.script; + + if (details[event]) { + req[event] = function() { + var responseState = { + // can't support responseXML because security won't + // let the browser call properties on it + responseText: req.responseText, + readyState: req.readyState, + responseHeaders: null, + status: null, + statusText: null, + finalUrl: null + }; + if (4 == req.readyState && 'onerror' != event) { + responseState.responseHeaders = req.getAllResponseHeaders(); + responseState.status = req.status; + responseState.statusText = req.statusText; + if (MIME_JSON.test(origMimeType) + || MIME_JSON.test(details.overrideMimeType) + || MIME_JSON.test(req.channel.contentType)) { + try { + responseState.responseJSON = JSON.parse(req.responseText); + } catch (e) { + responseState.responseJSON = {}; + } + } + responseState.finalUrl = req.channel.URI.spec; + } + + GM_apiSafeCallback( + unsafeContentWin, script, details, details[event], [responseState]); + } + } +} + +// TODO: replace!! +function GM_apiSafeCallback(aWindow, aScript, aThis, aCb, aArgs) { + aCb.apply(aThis, aArgs); +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/convert-2-regexp.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/convert-2-regexp.js new file mode 100644 index 0000000..9b79f30 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/convert-2-regexp.js @@ -0,0 +1,23 @@ +'use strict'; + +const RE_REGEXP = /^\/(.*)\/(i)?$/; +const RE_ESCAPE = /[{}()\[\]\\^$.?]/g; +const RE_WILD = /\*+/g; +const RE_TLD = /^\^[^\/]*(?:\/\/)?[^\/]*\\\.tld(?:\/.*)?\$$/; + +exports.convert2RegExp = function Scriptish_convert2RegExp(aPattern, aNoTLD, forceString) { + var s = aPattern.toString().trim(), m; + + // Already a regexp? + if (!forceString && (m = s.match(RE_REGEXP))) { + return new RegExp(m[1], m[2]); + } + + var res = "^" + s + .replace(RE_ESCAPE, "\\$&") + .replace(RE_WILD, ".*") + + "$"; + var regExp = new RegExp(res, "i"); + regExp.isTLD = !aNoTLD && RE_TLD.test(res); + return regExp; +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/greasemonkey-api.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/greasemonkey-api.js new file mode 100644 index 0000000..e465883 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/greasemonkey-api.js @@ -0,0 +1,76 @@ +'use strict'; + +var { Services } = require("services"); +var prefService = require("preferences-service"); +var tabs = require("tabs"); +var clipboard = require("clipboard"); +var {GM_xmlhttpRequester} = require("GM_xmlhttpRequester"); + +const NS_XHTML = "http://www.w3.org/1999/xhtml"; + +function GM_API(aScript, aURL, aWinID, aSafeWin, aUnsafeContentWin, aChromeWin) { + var document = aSafeWin.document; + var windowID = aWinID; + var xhr = new GM_xmlhttpRequester(aUnsafeContentWin, aURL, aScript); + + this.GM_addStyle = function GM_addStyle(css) { + var head = document.getElementsByTagName("head")[0]; + var style = document.createElement("style"); + if (head) { + style.textContent = css; + style.type = "text/css"; + head.appendChild(style); + } + return style; + }; + + // TODO: use simple storage + this.GM_getValue = function GM_getValue(name, defVal) { + return prefService.get(aScript.prefPrefix + name, defVal); + }; + this.GM_setValue = function GM_setValue(name, val) { + return prefService.set(aScript.prefPrefix + name, val); + }; + + this.GM_safeHTMLParser = function GM_safeHTMLParser(aHTMLStr) { + //if (!GM_apiLeakCheck("GM_safeHTMLParser")) return; + let doc = document.implementation.createDocument(NS_XHTML, "html", null); + let body = document.createElementNS(NS_XHTML, "body"); + doc.documentElement.appendChild(body); + body.appendChild(Services.suhtml.parseFragment(aHTMLStr, false, null, body)); + return doc; + } + + this.GM_xmlhttpRequest = function GM_xmlhttpRequest() { + //if (!GM_apiLeakCheck("GM_xmlhttpRequest")) return; + return xhr.contentStartRequest.apply(xhr, arguments); + }; +}; +exports.GM_API = GM_API; + +GM_API.prototype.GM_openInTab = + function GM_openInTab(aURL, aLoadInBackground, aReuse) { + if (aReuse) { + for each (var tab in tabs) { + if (tab.url == aURL) { + if (!aLoadInBackground) + tab.activate(); + return; + } + } + } + + tabs.open({ + url: aURL, + inBackground: aLoadInBackground + }); +}; + +GM_API.prototype.GM_setClipboard = function GM_setClipboard(aData, aType) { + return clipboard.set(aData, aType); +}; + +GM_API.prototype.GM_generateUUID = function GM_generateUUID() ( + Services.uuid.generateUUID().toString()); + +GM_API.prototype.GM_registerMenuCommand = function() {}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-header-parser.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-header-parser.js new file mode 100644 index 0000000..41f7ffd --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-header-parser.js @@ -0,0 +1,31 @@ +'use strict'; + +exports.parse = function(aSource) { + var headers = {}; + var foundMeta = false; + var line; + + // do not 'optimize' by reusing this reg exp! it should not be reused! + var metaRegExp = /\/\/[ \t]*(?:==(\/?UserScript)==|\@(\S+)(?:[ \t]+([^\r\f\n]+))?)/g; + + // read one line at a time looking for start meta delimiter or EOF + while (line = metaRegExp.exec(aSource)) { + if (line[1]) { + if ("userscript" == line[1].toLowerCase()) { + foundMeta = true; // start + continue; + } else { + break; // done + } + } + if (!foundMeta) continue; + + var header = line[2].toLowerCase(); + var value = line[3]; + + if (!headers[header]) headers[header] = [value]; + else headers[header].push(value); + } + + return headers; +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-manager.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-manager.js new file mode 100644 index 0000000..f1eec70 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-manager.js @@ -0,0 +1,44 @@ +'use strict'; + +var { Services } = require("../chrome/services"); +var obs = require("sdk/deprecated/observer-service"); + +var sandboxFactory = require("./userscript-sandbox"); + +var userscripts = []; + +// TODO: register obs only when there is a userscript +obs.add("content-document-global-created", docReady); +obs.add("chrome-document-global-created", docReady); + +function docReady(safeWin, data) { + let href = (safeWin.location.href + || (safeWin.frameElement && safeWin.frameElement.src)) || ""; + + safeWin.addEventListener("load", function() { + userscripts.forEach(function(script) { + // check that the userscript should be run on this page + if (!script.matchesURL(href)) + return; + + sandboxFactory.evalInSandbox( + script._source, + sandboxFactory.createSandbox(safeWin, script, href), + script.jsversion); + }); + }, true); +} + +exports.register = function(aScript) { + unregister(aScript); + userscripts.push(aScript); +}; + +var unregister = exports.unregister = function unregister(aScript) { + for (var i = userscripts.length - 1; ~i; i--) { + if (userscripts[i] == aScript) { + userscripts.splice(i, 1); + break; + } + } +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-sandbox.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-sandbox.js new file mode 100644 index 0000000..1c92066 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/scriptish/userscript-sandbox.js @@ -0,0 +1,24 @@ +'use strict'; + +var { Cc, Ci, Cu } = require('chrome'); +var {GM_API} = require("./greasemonkey-api"); + +exports.createSandbox = function createSandbox(safeWin, userScript, aURL) { + var script = userScript.source; + var sandbox = new Cu.Sandbox(safeWin); + sandbox.window = safeWin; + sandbox.document = sandbox.window.document; + sandbox.__proto__ = safeWin; + var api = new GM_API(userScript, aURL, null, safeWin, safeWin.wrappedJSObject); + + for (var key in api) { + sandbox[key] = api[key]; + } + + return sandbox; +}; + +exports.evalInSandbox = function(code, sandbox, jsVersion) { + jsVersion = jsVersion || "1.8"; + Cu.evalInSandbox("(function(){"+code+"})();", sandbox, jsVersion); +};
\ No newline at end of file diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/storage.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/storage.js new file mode 100644 index 0000000..3ed13d0 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/storage.js @@ -0,0 +1,126 @@ +/* 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 { Cc, Ci, Cu, components } = require('chrome'); +const { id } = require('sdk/self'); +const unload = require('sdk/system/unload'); +const { defer } = require('sdk/core/promise'); + +const { Instances } = require('./chrome/instances'); +const { Services } = require('./chrome/services'); +const { NetUtil } = require('./chrome/net-utils'); + +const { FileUtils } = Cu.import('resource://gre/modules/FileUtils.jsm', {}); + +const JETPACK_DIR_BASENAME = "jetpack"; + +let saving = false; + +function getStorageFile() { + const file = Services.dirsvc.get('ProfD', Ci.nsIFile); + file.append(JETPACK_DIR_BASENAME); + file.append(id); + file.append('pathfinder'); + file.append('storage'); + + if (!file.exists()) + file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0755', 8)); + + file.append('storage.blob'); + return file; +} + +function get(options) { + options = options || {}; + let charset = options.charset || 'UTF-8'; + + const { promise, resolve } = defer(); + const file = getStorageFile(); + const channel = NetUtil.newChannel(file); + + if (!file.exists()) { + resolve({ data: '' }); + } + else { + NetUtil.asyncFetch(channel, function(iStream, aResult) { + if (!components.isSuccessCode(aResult)) { + reject(); + } + else { + let text = NetUtil.readInputStreamToString(iStream, iStream.available()); + + let conv = Instances.suc; + conv.charset = charset; + + text = conv.ConvertToUnicode(text); + + resolve({ + data: text, + charset: charset + }); + } + }); + } + + return promise; +} +exports.get = get; + +function set({ data, charset }) { + charset = charset || 'UTF-8'; + data = data || ''; + const { promise, resolve, reject } = defer(); + const file = getStorageFile(); + + if (data == '') { + if (file.exists()) { + file.remove(false); + } + + resolve({ + data: '', + charset: charset + }); + } + else { + const converter = Instances.suc; + converter.charset = "UTF-8"; + + if (isSaving()) { + throw Error('Storage is currently in the process of saving..'); + } + saving = true; + + let iStream = converter.convertToInputStream(data); + let oStream = FileUtils.openSafeFileOutputStream(file); + + NetUtil.asyncCopy( + iStream, + oStream, + function(aResult) { + FileUtils.closeSafeFileOutputStream(oStream); + saving = false; + + if (!components.isSuccessCode(aResult)) { + reject(); + } + else { + resolve({ + data: data, + charset: charset + }); + } + } + ); + } + + return promise; +} +exports.set = set; + +function isSaving() { + return saving; +} +exports.isSaving = isSaving; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/awesomebar.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/awesomebar.js new file mode 100644 index 0000000..641dc14 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/awesomebar.js @@ -0,0 +1,205 @@ +/* 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 {Cc, Ci, Cu, Cm, components} = require('chrome'); +Cu.import("resource://gre/modules/AddonManager.jsm", this); +Cu.import("resource://gre/modules/Services.jsm", this); +Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); + +var {unload} = require("../addon/unload"); +var {listen} = require("../xul/listen"); +var {watchWindows} = require("window-watcher"); +var {clearTimeout, setTimeout} = require("timer"); + +let handlers = []; + +// public api for adding a keyword and search handler +// TODO: validate, yo +exports.AwesomeBarSuggestion = function AwesomeBarSuggestion(options) { + var i = handlers.push(options) - 1; + var destroyed = false; + + return { + destroy: function() { + if (destroyed) return; + destroyed = true; + handlers[i] = null; + } + }; +}; + +// Bool check if a given string matches a given handler +function handlerMatch(query, handler) !!(handler && handler.matches.test(query)); + +// Get first registered handler that matches a given string +function getMatchingHandler(query) handlers.filter(function(handler) handlerMatch(query, handler)).shift() + +// Add functionality to search from the location bar and hook up autocomplete +function addAddressBarSearch(window) { + let {change} = makeWindowHelpers(window); + let {BrowserUI, gBrowser, gURLBar} = window; + + // Check the input to see if the add-on icon should be shown + // Called when the location bar fires the input event + function onLocationBarInput() { + if (skipCheck()) + return; + + let icon = ""; + let handler = getMatchingHandler(urlbar.value); + if (handler && handler.icon) + icon = handler.icon; + setIcon(icon); + } + + // Implement these functions depending on the platform + let setIcon, skipCheck, urlbar; + + // mobile + if (gBrowser == null) { + setIcon = function(url) BrowserUI._updateIcon(url); + skipCheck = function() false; + urlbar = BrowserUI._edit; + + // Check the input on various events + listen(window, BrowserUI._edit, "input", onLocationBarInput); + + // Convert inputs to twitter urls + change(window.Browser, "getShortcutOrURI", function(orig) { + return function(uri, data) { + return orig.call(this, uri, data); + }; + }); + } + // desktop + else { + setIcon = function(url) window.PageProxySetIcon(url); + skipCheck = function() gURLBar.getAttribute("pageproxystate") == "valid" && + !gURLBar.hasAttribute("focused"); + urlbar = gURLBar; + + // Check the input on various events + listen(window, gURLBar, "input", onLocationBarInput); + listen(window, gBrowser.tabContainer, "TabSelect", onLocationBarInput); + + // Convert inputs to twitter urls + change(gURLBar, "_canonizeURL", function(orig) { + return function(event) { + return orig.call(this, event); + }; + }); + } + + // Provide a way to set the autocomplete search engines and initialize + function setSearch(engines) { + urlbar.setAttribute("autocompletesearch", engines); + urlbar.mSearchNames = null; + urlbar.initSearchNames(); + }; + + // Add in the twitter search and remove on cleanup + let origSearch = urlbar.getAttribute("autocompletesearch"); + setSearch(require('self').id + " " + origSearch); + unload(function() setSearch(origSearch)); +} + +// Add an autocomplete search engine to provide location bar suggestions +function addAutocomplete() { + const contract = "@mozilla.org/autocomplete/search;1?name=" + require('self').id; + const desc = "Jetpack Autocomplete"; + const uuid = components.ID("504A8466-8D3D-11E0-A57E-D2F94824019B"); + + // Keep a timer to send a delayed no match + let timer; + function clearTimer() { + if (timer != null) + clearTimeout(timer); + timer = null; + } + + // call back in one second + function setTimer(callback) { + timer = setTimeout(callback, 1000); + } + + // Implement the autocomplete search that handles twitter queries + let search = { + createInstance: function(outer, iid) search.QueryInterface(iid), + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch]), + + // Handle searches from the location bar + startSearch: function(query, param, previous, listener) { + + // Always clear the timer on a new search + clearTimer(); + + function suggest(o, done) { + listener.onSearchResult(search, { + getCommentAt: function() o.title, + getImageAt: function() o.favicon, + getLabelAt: function() o.label || o.url, + getValueAt: function() o.url, + getStyleAt: function() "favicon", + get matchCount() 1, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult]), + removeValueAt: function() {}, + searchResult: Ci.nsIAutoCompleteResult.RESULT_SUCCESS, + get searchString() query, + }); + } + + // TODO: if no search yet, but matched keyword, show example text + + // if there's a query string and a match + if (query.length) { + let handler = getMatchingHandler(query); + if (handler) { + if (query) { + handler.onSearch(query, suggest); + } + } + } + // Send a delayed NOMATCH so the autocomplete doesn't close early + else { + setTimer(function() { + listener.onSearchResult(search, { + searchResult: Ci.nsIAutoCompleteResult.RESULT_NOMATCH, + }); + }); + } + }, + + // Nothing to cancel other than a delayed search as results are synchronous + stopSearch: function() { + clearTimer(); + }, + }; + + // Register this autocomplete search service and clean up when necessary + const registrar = Ci.nsIComponentRegistrar; + Cm.QueryInterface(registrar).registerFactory(uuid, desc, contract, search); + unload(function() { + Cm.QueryInterface(registrar).unregisterFactory(uuid, search); + }); +} + +// Add support to the browser +watchWindows(addAddressBarSearch); +addAutocomplete(); + +// Take a window and create various helper properties and functions +function makeWindowHelpers(window) { + // Replace a value with another value or a function of the original value + function change(obj, prop, val) { + let orig = obj[prop]; + obj[prop] = typeof val == "function" ? val(orig) : val; + unload(function() obj[prop] = orig, window); + } + + return { + change: change, + }; +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/findbar/suggestion.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/findbar/suggestion.js new file mode 100644 index 0000000..efbc665 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/findbar/suggestion.js @@ -0,0 +1,77 @@ +/* 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 winUtils = require('sdk/deprecated/window-utils'); +const { Class } = require('sdk/core/heritage'); +const { validateOptions } = require('sdk/deprecated/api-utils'); +const { isBrowser } = require('sdk/window/utils'); +const { unload } = require('../../addon/unload'); +const { listen } = require('../../xul/listen'); + +const findsuggestionNS = require('sdk/core/namespace').ns(); +const NS_XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; + +function FindSuggestionOptions(options) { + return validateOptions(options, { + word: { is: ['string'] }, + //onClick: { is: ['undefined', 'function'] } + }); +} + +const FindSuggestion = Class({ + initialize: function(options) { + options = findsuggestionNS(this).options = FindSuggestionOptions(options); + let unloaders = findsuggestionNS(this).unloaders = []; + + winUtils.WindowTracker({ + onTrack: function(window) { + if (!isBrowser(window)) return; + + let findBar = window.gFindBar; + let findContainer = findBar.getElement('findbar-container'); + + // Show these suggestions in the findbar + let ele = window.document.createElementNS(NS_XUL, 'label'); + ele.setAttribute('value', options.word); + ele.style.margin = '2px'; + ele.style.cursor = 'pointer'; + ele.style.fontWeight = 'bold'; + findContainer.appendChild(ele); + + ele.addEventListener('click', suggestionClick.bind({ + findBar: findBar + }), false); + + // Clear out the suggestions when removing the add-on + function clearSuggestion() { + findContainer.removeChild(ele); + } + + // save a destroyer + unloaders.push( + destroyer.bind(null, unload(clearSuggestion, window), clearSuggestion)); + } + }); + }, + destroy: function() findsuggestionNS(this).unloaders.forEach(function(x) x()) +}); +exports.FindSuggestion = FindSuggestion; + +function suggestionClick(event) { + let suggestion = event.target.value; + let findField = this.findBar._findField; + + if (findField.value === suggestion) { + this.findBar.onFindAgainCommand(false); + } + else { + findField.value = suggestion; + findBar._find(); + } +} +function destroyer(remover, clearSuggestion) { + clearSuggestion(); + remover(); +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/menuitems.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/menuitems.js new file mode 100644 index 0000000..5e34106 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/menuitems.js @@ -0,0 +1,218 @@ +/* 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 windowUtils = require("sdk/deprecated/window-utils"); +const { Class } = require("sdk/core/heritage"); +const { validateOptions } = require("sdk/deprecated/api-utils"); +const { on, emit, once, off } = require("sdk/event/core"); +const { isBrowser } = require("sdk/window/utils"); +const { EventTarget } = require('sdk/event/target'); +const menuitemNS = require("sdk/core/namespace").ns(); + +const { unload } = require('../addon/unload'); + +const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +function MenuitemOptions(options) { + return validateOptions(options, { + id: { is: ['string'] }, + menuid: { is: ['undefined', 'string'] }, + insertbefore: { is: ['undefined', 'string', 'object', 'number'] }, + label: { is: ["string"] }, + include: { is: ['string', 'undefined'] }, + disabled: { is: ["undefined", "boolean"], map: function(v) !!v}, + accesskey: { is: ["undefined", "string"] }, + key: { is: ["undefined", "string"] }, + checked: { is: ['undefined', 'boolean'] }, + className: { is: ["undefined", "string"] }, + onCommand: { is: ['undefined', 'function'] }, + useChrome: { map: function(v) !!v } + }); +} + +let Menuitem = Class({ + extends: EventTarget, + initialize: function(options) { + options = menuitemNS(this).options = MenuitemOptions(options); + EventTarget.prototype.initialize.call(this, options); + + menuitemNS(this).destroyed = false; + menuitemNS(this).unloaders = []; + menuitemNS(this).menuitems = addMenuitems(this, options).menuitems; + }, + get id() menuitemNS(this).options.id, + get label() menuitemNS(this).options.label, + set label(val) updateProperty(this, 'label', val), + get checked() menuitemNS(this).options.checked, + set checked(val) updateProperty(this, 'checked', !!val), + get disabled() menuitemNS(this).options.disabled, + set disabled(val) updateProperty(this, 'disabled', !!val), + get key() menuitemNS(this).options.key, + set key(val) updateProperty(this, 'key', val), + clone: function (overwrites) { + let opts = Object.clone(menuitemNS(this).options); + for (let key in overwrites) { + opts[key] = ovrewrites[key]; + } + return Menuitem(opts); + }, + get menuid() menuitemNS(this).options.menuid, + set menuid(val) { + let options = menuitemNS(this).options; + options.menuid = val; + + forEachMI(function(menuitem, i, $) { + updateMenuitemParent(menuitem, options, $); + }); + }, + destroy: function() { + if (!menuitemNS(this).destroyed) { + menuitemNS(this).destroyed = true; + menuitemNS(this).unloaders.forEach(function(u) u()); + menuitemNS(this).unloaders = null; + menuitemNS(this).menuitems = null; + } + return true; + } +}); + +function addMenuitems(self, options) { + let menuitems = []; + + // setup window tracker + windowUtils.WindowTracker({ + onTrack: function (window) { + if (menuitemNS(self).destroyed) return; + if (options.include) { + if (options.include != window.location) return; + } + else if (!isBrowser(window)) { + return; + } + + // add the new menuitem to a menu + var menuitem = updateMenuitemAttributes( + window.document.createElementNS(NS_XUL, "menuitem"), options); + var menuitems_i = menuitems.push(menuitem) - 1; + + // add the menutiem to the ui + let added = updateMenuitemParent(menuitem, options, function(id) window.document.getElementById(id)); + + menuitem.addEventListener("command", function() { + if (!self.disabled) + emit(self, 'command', options.useChrome ? window : null); + }, true); + + // add unloader + let unloader = function unloader() { + menuitem.parentNode && menuitem.parentNode.removeChild(menuitem); + menuitems[menuitems_i] = null; + }; + + menuitemNS(self).unloaders.push(function() { + remover(); + unloader(); + }); + + let remover = unload(unloader, window); + } + + }); + + return { menuitems: menuitems }; +} + +function updateMenuitemParent(menuitem, options, $) { + // add the menutiem to the ui + if (Array.isArray(options.menuid)) { + let ids = options.menuid; + for (var len = ids.length, i = 0; i < len; i++) { + if (tryParent($(ids[i]), menuitem, options.insertbefore)) + return true; + } + } + else { + return tryParent($(options.menuid), menuitem, options.insertbefore); + } + + return false; +} + +function updateMenuitemAttributes(menuitem, options) { + menuitem.setAttribute("id", options.id); + menuitem.setAttribute("label", options.label); + + if (options.accesskey) + menuitem.setAttribute("accesskey", options.accesskey); + + if (options.key) + menuitem.setAttribute("key", options.key); + + menuitem.setAttribute("disabled", !!options.disabled); + + if (options.image) { + menuitem.classList.add("menuitem-iconic"); + menuitem.style.listStyleImage = "url('" + options.image + "')"; + } + + if (options.checked) + menuitem.setAttribute('checked', options.checked); + + if (options.className) + options.className.split(/\s+/).forEach(function(name) menuitem.classList.add(name)); + + return menuitem; +} + +function updateProperty(menuitem, key, val) { + menuitemNS(menuitem).options[key] = val; + + forEachMI(function(menuitem) { + menuitem.setAttribute(key, val); + }, menuitem); + return val; +} + +function forEachMI(callback, menuitem) { + menuitemNS(menuitem).menuitems.forEach(function(mi, i) { + if (!mi) return; + callback(mi, i, function(id) mi.ownerDocument.getElementById(id)); + }); +} + +function tryParent(parent, menuitem, before) { + if (parent) { + if (!before) { + parent.appendChild(menuitem); + return true; + } + + parent.insertBefore(menuitem, insertBefore(parent, before)); + return true; + } + + return false; +} + +function insertBefore(parent, insertBefore) { + if (typeof insertBefore == "number") { + switch (insertBefore) { + case MenuitemExport.FIRST_CHILD: + return parent.firstChild; + } + return null; + } + else if (typeof insertBefore == "string") { + return parent.querySelector("#" + insertBefore); + } + return insertBefore; +} + +function MenuitemExport(options) { + return Menuitem(options); +} +MenuitemExport.FIRST_CHILD = 1; + +exports.Menuitem = MenuitemExport; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/actions.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/actions.js new file mode 100644 index 0000000..12076ca --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/actions.js @@ -0,0 +1,9 @@ +/* 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 method = require('method/core'); + +exports.show = method('show'); +exports.hide = method('hide'); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/contract.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/contract.js new file mode 100644 index 0000000..244e60e --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/contract.js @@ -0,0 +1,30 @@ +/* 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 { contract } = require('sdk/util/contract'); +const { isValidURI } = require('sdk/url'); + +let string = { is: ['string'] }; + +exports.contract = contract({ + id: { + is: [ 'string' ], + ok: function (v) /^[a-z0-9-_]+$/i.test(v), + msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' + + 'underscores are allowed).' + }, + title: { + is: [ 'string' ], + ok: function (v) v.length + }, + url: { + is: [ 'string' ], + ok: function(url) { + return isValidURI(url); + }, + map: function(v) v.toString(), + msg: 'The option "url" must be a valid URI.' + } +}); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/state.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/state.js new file mode 100644 index 0000000..05225da --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/state.js @@ -0,0 +1,8 @@ +/* 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 method = require('method/core'); + +exports.isShowing = method('isShowing'); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/utils.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/utils.js new file mode 100644 index 0000000..4576c5b --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/sidebar/utils.js @@ -0,0 +1,31 @@ +/* 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 { getMostRecentBrowserWindow } = require('sdk/window/utils'); + +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +function create(window, details) { + let { document } = window; + + let menuitem = document.createElementNS(XUL_NS, 'menuitem'); + menuitem.setAttribute('id', details.id); + menuitem.setAttribute('label', details.title); + menuitem.setAttribute('checked', 'false'); + menuitem.setAttribute('sidebarurl', details.sidebarurl); + menuitem.setAttribute('type', 'checkbox'); + menuitem.setAttribute('group', 'sidebar'); + menuitem.setAttribute('autoCheck', 'false'); + + document.getElementById('viewSidebarMenu').appendChild(menuitem); + + return menuitem; +} +exports.create = create; + +function dispose(menuitem) { + menuitem.parentNode.removeChild(menuitem); +} +exports.dispose = dispose; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/toolbarbutton.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/toolbarbutton.js new file mode 100644 index 0000000..38bfb2e --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/toolbarbutton.js @@ -0,0 +1,179 @@ +/* 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 winUtils = require("sdk/deprecated/window-utils"); +const { isBrowser } = require('sdk/window/utils'); +const { Class } = require('sdk/core/heritage'); +const TBB_NS = require('sdk/core/namespace').ns(); + +const { validate: validateOptions } = require('./validate'); +const { getToolbarButtons, toolbarbuttonExists } = require('./utils'); +const { unload } = require("../addon/unload"); +const { listen } = require("../xul/listen"); + +const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +exports.ToolbarButton = Class({ + initialize: function(options) { + TBB_NS(this).unloaders = []; + + const self = this; + TBB_NS(this).destroyed = false; + TBB_NS(this).destroyFuncs = []; + let safeOptions = TBB_NS(this).options = validateOptions(options); + + winUtils.WindowTracker({ + onTrack: function (window) { + if (!isBrowser(window) || TBB_NS(self).destroyed) + return; + + let doc = window.document; + let $ = function(id) doc.getElementById(id); + + // create toolbar button + let tbb = doc.createElementNS(NS_XUL, "toolbarbutton"); + tbb.setAttribute("id", safeOptions.id); + tbb.setAttribute("type", "button"); + if (safeOptions.image) + tbb.setAttribute("image", safeOptions.image); + tbb.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional"); + tbb.setAttribute("label", safeOptions.label); + tbb.setAttribute('tooltiptext', safeOptions.tooltiptext); + tbb.addEventListener("command", function() { + if (safeOptions.onCommand) + safeOptions.onCommand({}); // TODO: provide something? + + if (safeOptions.panel) { + safeOptions.panel.show(tbb); + } + }, true); + + // add toolbarbutton to palette + ($("navigator-toolbox") || $("mail-toolbox")).palette.appendChild(tbb); + + // find a toolbar to insert the toolbarbutton into + if (TBB_NS(self).options.toolbarID) { + var tb = $(TBB_NS(self).options.toolbarID); + } + if (!tb) { + var tb = toolbarbuttonExists(doc, safeOptions.id); + } + + // found a toolbar to use? + if (tb) { + let b4; + + // find the toolbarbutton to insert before + if (TBB_NS(self).options.insertbefore) { + b4 = $(TBB_NS(self).options.insertbefore); + } + if (!b4) { + let currentset = tb.getAttribute("currentset").split(","); + let i = currentset.indexOf(safeOptions.id) + 1; + + // was the toolbarbutton id found in the curent set? + if (i > 0) { + let len = currentset.length; + // find a toolbarbutton to the right which actually exists + for (; i < len; i++) { + b4 = $(currentset[i]); + if (b4) break; + } + } + } + + tb.insertItem(safeOptions.id, b4, null, false); + } + + var saveTBNodeInfo = function(e) { + TBB_NS(self).options.toolbarID = tbb.parentNode.getAttribute("id") || ""; + TBB_NS(self).options.insertbefore = (tbb.nextSibling || "") + && tbb.nextSibling.getAttribute("id").replace(/^wrapper-/i, ""); + }; + + window.addEventListener("aftercustomization", saveTBNodeInfo, false); + + // add unloader to unload+'s queue + var unloadFunc = function() { + tbb.parentNode.removeChild(tbb); + window.removeEventListener("aftercustomization", saveTBNodeInfo, false); + }; + var index = TBB_NS(self).destroyFuncs.push(unloadFunc) - 1; + listen(window, window, "unload", function() { + TBB_NS(self).destroyFuncs[index] = null; + }, false); + TBB_NS(self).unloaders.push(unload(unloadFunc, window)); + } + }); + }, + destroy: function() { + if (TBB_NS(this).destroyed) return; + TBB_NS(this).destroyed = true; + + let options = TBB_NS(this).options; + + if (options.panel) + options.panel.destroy(); + + // run unload functions + TBB_NS(this).destroyFuncs.forEach(function(f) f && f()); + TBB_NS(this).destroyFuncs.length = 0; + + // remove unload functions from unload+'s queue + TBB_NS(this).unloaders.forEach(function(f) f()); + TBB_NS(this).unloaders.length = 0; + }, + moveTo: function(pos) { + if (TBB_NS(this).destroyed) return; + + let options = TBB_NS(this).options; + + // record the new position for future windows + TBB_NS(this).options.toolbarID = pos.toolbarID; + TBB_NS(this).options.insertbefore = pos.insertbefore; + + // change the current position for open windows + for each (var window in winUtils.windowIterator()) { + if (!isBrowser(window)) continue; + + let $ = function (id) window.document.getElementById(id); + + // if the move isn't being forced and it is already in the window, abort + if (!pos.forceMove && $(this.id)) continue; + + var tb = $(TBB_NS(this).options.toolbarID); + var b4 = $(TBB_NS(this).options.insertbefore); + + // TODO: if b4 dne, but insertbefore is in currentset, then find toolbar to right + + if (tb) tb.insertItem(this.id, b4, null, false); + }; + }, + get id() TBB_NS(this).options.id, + get label() TBB_NS(this).options.label, + set label(value) { + TBB_NS(this).options.label = value; + getToolbarButtons(function(tbb) { + tbb.label = value; + }, this.id); + return value; + }, + setIcon: function setIcon(options) { + let val = TBB_NS(this).options.image = options.image || options.url; + getToolbarButtons(function(tbb) { + tbb.image = val; + }, this.id); + return val; + }, + get image() TBB_NS(this).options.image, + set image(value) this.setIcon({image: value}), + get tooltiptext() TBB_NS(this).options.tooltiptext, + set tooltiptext(value) { + TBB_NS(this).options.tooltiptext = value; + getToolbarButtons(function(tbb) { + tbb.setAttribute('tooltiptext', value); + }, this.id); + } +}); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/utils.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/utils.js new file mode 100644 index 0000000..6ad0304 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/utils.js @@ -0,0 +1,28 @@ +'use strict'; + +const winUtils = require("sdk/deprecated/window-utils"); +const { isBrowser } = require('sdk/window/utils'); + +const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +function getToolbarButtons(callback, id) { + let buttons = []; + for each (var window in winUtils.windowIterator()) { + if (!isBrowser(window)) continue; + let tbb = window.document.getElementById(id); + if (tbb) buttons.push(tbb); + } + if (callback) buttons.forEach(callback); + return buttons; +} +exports.getToolbarButtons = getToolbarButtons; + +function toolbarbuttonExists(doc, id) { + var toolbars = doc.getElementsByTagNameNS(NS_XUL, "toolbar"); + for (var i = toolbars.length - 1; ~i; i--) { + if ((new RegExp("(?:^|,)" + id + "(?:,|$)")).test(toolbars[i].getAttribute("currentset"))) + return toolbars[i]; + } + return false; +} +exports.toolbarbuttonExists = toolbarbuttonExists; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/validate.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/validate.js new file mode 100644 index 0000000..3de6d30 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/validate.js @@ -0,0 +1,31 @@ +'use strict'; + +const { validateOptions } = require('sdk/deprecated/api-utils'); +const { Panel } = require('sdk/panel'); + + const RULES = { + image: { is: ["null", "undefined", "string"] }, + tooltiptext: { + is: ["null", "undefined", "string"], + defaultValue: '' + }, + id: { + is: ["string"], + ok: function (v) v.length > 0, + msg: 'BAD ID', + readonly: true + }, + label: { + is: ["string"], + ok: function (v) v.length > 0, + msg: 'BAD Label' + }, + panel: { + is: ["null", "undefined", "object"], + ok: function(v) !v || v instanceof Panel + }, + onCommand: { + is: ["null", "undefined", "function"], + } +}; +exports.validate = function(o) validateOptions(o, RULES); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/warning.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/warning.js new file mode 100644 index 0000000..bf2b449 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/warning.js @@ -0,0 +1,43 @@ +/* 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 self = require('sdk/self'); +const tabs = require('sdk/tabs'); +const { Class } = require('sdk/core/heritage'); +const { on, emit, once, off } = require('sdk/event/core'); +const { EventTarget } = require('sdk/event/target'); + +const awNS = require('sdk/core/namespace').ns(); + +let AddonWarning = Class({ + extends: EventTarget, + initialize: function initialize(options) { + EventTarget.prototype.initialize.call(this, options); + awNS(this).options = options; + }, + open: function() { + let self = this; + let options = awNS(self).options; + + tabs.open({ + url: module.uri.replace(/lib\/addon-warning\.js/, 'data/warning.html'), + onReady: function(tab) { + let worker = tab.attach({ + contentScriptFile: module.uri.replace(/lib\/addon-warning\.js/, 'data/warning-mod.js') + }); + + worker.port.on('cancel', function(data) { + emit(self, 'cancel'); + }); + worker.port.on('accept', function(data) { + emit(self, 'accept'); + }); + + worker.port.emit('load', options); + } + }); + } +}); +exports.AddonWarning = AddonWarning; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/web-panel.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/web-panel.js new file mode 100644 index 0000000..f61c958 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/ui/web-panel.js @@ -0,0 +1,289 @@ +/* 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': 'experimental', + 'engines': { + 'Firefox': '*' + } +}; + +const { Class } = require('sdk/core/heritage'); +const { merge } = require('sdk/util/object'); +const { Disposable } = require('sdk/core/disposable'); +const { off, emit, setListeners } = require('sdk/event/core'); +const { EventTarget } = require('sdk/event/target'); +const { URL } = require('sdk/url'); +const { add, remove, has, clear, iterator } = require('sdk/lang/weak-set'); +const { WindowTracker } = require('sdk/deprecated/window-utils'); +const { isBrowser, getMostRecentBrowserWindow, windows } = require('sdk/window/utils'); +const { ns } = require('sdk/core/namespace'); +const { remove: removeFromArray } = require('sdk/util/array'); +const { Worker: WorkerTrait } = require('sdk/content/worker'); + +const { create, dispose } = require('./sidebar/utils'); +const { show, hide } = require('./sidebar/actions'); +const { isShowing } = require('./sidebar/state'); +const { contract } = require('./sidebar/contract'); + +const Worker = WorkerTrait.resolve({ + _injectInDocument: '__injectInDocument' +}).compose({ + get _injectInDocument() false +}); + +const sidebarNS = ns(); + +const WEB_PANEL_BROWSER_ID = 'web-panels-browser'; + +let sidebars = {}; +let models = new WeakMap(); +let views = new WeakMap(); + +function viewsFor(sidebar) views.get(sidebar); +function modelFor(sidebar) models.get(sidebar); + +const WebPanel = Class({ + implements: [ Disposable ], + extends: EventTarget, + setup: function(options) { + let self = this; + + const windowNS = ns(); + + let model = merge({}, contract(options)); + + models.set(this, model); + + setListeners(this, options); + + let bars = []; + sidebarNS(self).tracker = WindowTracker({ + onTrack: function(window) { + if (!isBrowser(window)) + return; + + let sidebar = window.document.getElementById('sidebar'); + let sidebarBox = window.document.getElementById('sidebar-box'); + + let bar = create(window, { + id: makeID(model.id), + title: model.title, + sidebarurl: model.url + }); + bars.push(bar); + windowNS(window).bar = bar; + + bar.addEventListener('command', function() { + if (isSidebarShowing(window, self)) { + hideSidebar(window, self); + return; + } + + showSidebar(window, self); + }, false); + + function onSidebarLoad() { + // check if the sidebar is ready + let isReady = sidebar.docShell && sidebar.contentDocument; + if (!isReady) + return; + + // check if it is a web panel + let panelBrowser = sidebar.contentDocument.getElementById(WEB_PANEL_BROWSER_ID); + if (!panelBrowser) { + bar.removeAttribute('checked'); + return; + } + + let sbTitle = window.document.getElementById('sidebar-title'); + function onWebPanelSidebarLoad() { + if (panelBrowser.contentWindow.location != model.url || + sbTitle.value != model.title) { + return; + } + + let worker = windowNS(window).worker = Worker({ + window: panelBrowser.contentWindow + }); + + function onWebPanelSidebarUnload() { + panelBrowser.removeEventListener('unload', onWebPanelSidebarUnload, true); + + windowNS(window).onWebPanelSidebarLoad = null; + + // uncheck the associated menuitem + bar.setAttribute('checked', 'false'); + + emit(self, 'hide', null); + emit(self, 'detach', worker); + } + windowNS(window).onWebPanelSidebarUnload = onWebPanelSidebarUnload; + panelBrowser.contentWindow.addEventListener('unload', onWebPanelSidebarUnload, false); + + // check the associated menuitem + bar.setAttribute('checked', 'true'); + + emit(self, 'show', null); + emit(self, 'attach', worker); + } + windowNS(window).onWebPanelSidebarLoad = onWebPanelSidebarLoad; + panelBrowser.addEventListener('DOMWindowCreated', onWebPanelSidebarLoad, true); + } + windowNS(window).onSidebarLoad = onSidebarLoad; + sidebar.addEventListener('load', onSidebarLoad, true); + }, + onUntrack: function(window) { + if (!isBrowser(window)) + return; + + let { bar } = windowNS(window); + if (bar) { + removeFromArray(viewsFor(self), bar); + dispose(bar); + } + + let sidebar = window.document.getElementById('sidebar'); + if (!sidebar) + return; + + if (windowNS(window).onSidebarLoad) { + sidebar.removeEventListener('load', windowNS(window).onSidebarLoad, true) + windowNS(window).onSidebarLoad = null; + } + + if (windowNS(window).onWebPanelSidebarLoad) { + let webPanel = sidebar.contentDocument.getElementById(WEB_PANEL_BROWSER_ID); + webPanel && webPanel.removeEventListener('DOMWindowCreated', windowNS(window).onWebPanelSidebarLoad, true); + windowNS(window).onWebPanelSidebarLoad = null; + } + + if (windowNS(window).onWebPanelSidebarUnload) { + windowNS(window).onWebPanelSidebarUnload(); + } + } + }); + + views.set(this, bars); + + add(sidebars, this); + }, + get id() modelFor(this).id, + get title() modelFor(this).title, + get url() modelFor(this).url, + show: function() show(this), + hide: function() hide(this), + dispose: function() { + off(this); + + let wins = windows('navigator:browser', { includePrivate: true }); + for each (let win in wins) { + hideSidebar(win, this); + } + + remove(sidebars, this); + + // stop tracking windows + sidebarNS(this).tracker.unload(); + sidebarNS(this).tracker = null; + + views.delete(this); + } +}); +exports.WebPanel = WebPanel; + +function showSidebar(window, sidebar) { + let model = modelFor(sidebar); + //let window = window || getMostRecentBrowserWindow(); + + window.openWebPanel(model.title, model.url); + + let menuitem = window.document.getElementById(makeID(model.id)); + menuitem.setAttribute('checked', true); +} +show.define(WebPanel, showSidebar.bind(null, null)); + +function hideSidebar(window, sidebar) { + //window = window || getMostRecentBrowserWindow(); + + if (!isSidebarShowing(window, sidebar)) + return; + + // return window.toggleSidebar(); + + // Below was taken from http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#4775 + // the code for window.todggleSideBar().. + let { document } = window; + //let sidebar = document.getElementById('sidebar'); + let sidebarTitle = document.getElementById('sidebar-title'); + let sidebarBox = document.getElementById('sidebar-box'); + let sidebarSplitter = document.getElementById('sidebar-splitter'); + let commandID = sidebarBox.getAttribute('sidebarcommand'); + let sidebarBroadcaster = document.getElementById(commandID); + + sidebarBox.hidden = true; + sidebarSplitter.hidden = true; + + sidebar.setAttribute('src', 'about:blank'); + //sidebar.docShell.createAboutBlankContentViewer(null); + + sidebarBroadcaster.removeAttribute('checked'); + sidebarBox.setAttribute('sidebarcommand', ''); + sidebarTitle.value = ''; + sidebarBox.hidden = true; + sidebarSplitter.hidden = true; + + // TODO: perhaps this isn't necessary if the window is not most recent? + window.gBrowser.selectedBrowser.focus(); +} +hide.define(WebPanel, hideSidebar.bind(null, null)); + +function isSidebarShowing(window, sidebar) { + let win = window || getMostRecentBrowserWindow(); + + // make sure there is a window + if (!win) { + return false; + } + + // make sure there is a sidebar for the window + let sb = win.document.getElementById('sidebar'); + let sidebarTitle = win.document.getElementById('sidebar-title'); + if (!(sb && sidebarTitle)) { + return false; + } + + // checks if the sidebar box is hidden + let sbb = win.document.getElementById('sidebar-box'); + if (!sbb || sbb.hidden) { + return false; + } + + // checks if the sidebar is loading + if (win.gWebPanelURI == modelFor(sidebar).url) { + return false; + } + + if (sidebarTitle.value == modelFor(sidebar).title) { + // checks if the sidebar loaded already + let ele = sb.contentDocument && sb.contentDocument.getElementById(WEB_PANEL_BROWSER_ID); + + if (ele.getAttribute('cachedurl') == modelFor(sidebar).url) { + return true; + } + + if (ele && ele.contentWindow && ele.contentWindow.location == modelFor(sidebar).url) { + return true; + } + } + + // default + return false; +} +isShowing.define(WebPanel, isSidebarShowing.bind(null, null)); + +function makeID(id) { + return 'pathfinder-sidebar-' + id; +} diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/userscript.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/userscript.js new file mode 100644 index 0000000..9890200 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/userscript.js @@ -0,0 +1,116 @@ +'use strict'; + +var file = require("sdk/io/file"); +var url = require("sdk/url"); + +var convert2RegExp = require("./scriptish/convert-2-regexp").convert2RegExp; +var userscriptParser = require("./scriptish/userscript-header-parser").parse; +var manager = require("./scriptish/userscript-manager"); + +const JSVersions = ['1.6', '1.7', '1.8'/*, '1.8.1'*/]; + +var UserScript = exports.UserScript = function UserScript(aURL) { + var script = new Script(aURL); + manager.register(script); + + return { + destory: function() { + manager.unregister(script); + }, + get enabled() script.enabled, + set enabled(aVal) script.enabled = !!aVal + }; +} + +function Script(aURL) { + this._url = url.URL(aURL); + this._filepath = url.toFilename(aURL); + this._source = file.read(this._filepath); + var header = userscriptParser(this._source); + + this._name = (header.name && header.name[0]) || Script.parseScriptName(aURL); + this._namespace = (header.namespace && header.namespace[0]) || this.url.host; + this._description = (header.description && header.description[0]) || ""; + this.enabled = true; + this._includes = (header.include || []).map(convert2RegExp); + this._excludes = (header.exclude || []).map(convert2RegExp); + this._requires = (header.require || []); + this._resources = (header.resource || []); + if (header.jsversion) { + for (var i = header.jsversion.length - 1; ~i; i--) { + let val = header.jsversion[i]; + if (~JSVersions.indexOf(val)) { + this.jsversion = val; + break; + } + } + } +} + +Script.prototype = { + get prefPrefix () { + return ["greasemonkey.scriptvals.", + this._namespace, + "/", + this._name, + "."].join(""); + }, + + // TODO: actually implement this! + matchesDomain: function() { + return true; + }, + + matchesURL: function(url) { + var test = function(pattern) { + return pattern.test(url); + } + + return this.enabled + && this._includes.some(test) + && !this._excludes.some(test); + }, + + _changed: function(event, data) { + if(this._config) { + this._config._changed(this, event, data); + } + }, + + get name() { return this._name; }, + get namespace() { return this._namespace; }, + get description() { return this._description; }, + + get enabled() { return this._enabled; }, + set enabled(enabled) { + this._enabled = enabled; + this._changed("edit-enabled", enabled); + }, + + get includes() { return this._includes.concat(); }, + get excludes() { return this._excludes.concat(); }, + addInclude: function(url) { + this._includes.push(url); + this._changed("edit-include-add", url); + }, + removeIncludeAt: function(index) { + this._includes.splice(index, 1); + this._changed("edit-include-remove", index); + }, + addExclude: function(url) { + this._excludes.push(url); + this._changed("edit-exclude-add", url); + }, + removeExcludeAt: function(index) { + this._excludes.splice(index, 1); + this._changed("edit-exclude-remove", index); + }, + + get requires() { return this._requires.concat(); }, + get resources() { return this._resources.concat(); }, + get unwrap() { return this._unwrap; } +}; + + +Script.parseScriptName = function(aURL) (( + /\/([^\/]+)\.user(?:-\d+)?\.js(?:[\?#].*)?$/.test(aURL || "")) ? RegExp.$1 : ""); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/userstyles.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/userstyles.js new file mode 100644 index 0000000..0cc3414 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/userstyles.js @@ -0,0 +1,72 @@ +/* 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 { Cc, Ci } = require("chrome"); +const { unload } = require('./addon/unload'); + +const sss = Cc["@mozilla.org/content/style-sheet-service;1"] + .getService(Ci.nsIStyleSheetService); + +function getURI(aURL) Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService).newURI(aURL, null, null); + +function setOptions(url, options) { + let newOptions = {}; + options = options || {}; + + newOptions.uri = getURI(url); + newOptions.type = (options.type || 'user').toLowerCase(); + newOptions.type = (newOptions.type == 'agent') ? sss.AGENT_SHEET : sss.USER_SHEET; + + return newOptions; +}; + +// capture the unload callbacks for removing the unload function from +// the queue as they are no longer needed when a URL is unregistered manually +var unloaders = {}; + +function removeUnload(url) { + if (typeof unloaders[url] === "function") { + unloaders[url].call(null); + delete unloaders[url]; + } +} + +/** + * Load various packaged styles for the add-on and undo on unload + * + * @usage load(aURL): Load specified style + * @param [string] aURL: Style file to load + * @param [object] options: + */ +const loadSS = exports.load = function loadSS(url, options) { + let { uri, type } = setOptions(url, options); + + // load the stylesheet + sss.loadAndRegisterSheet(uri, type); + + // remove the unloader for this URL if it exists + removeUnload(url); + + // unload the stylesheet on unload + unloaders[url] = unload(unregisterSS.bind(null, url, options)); +}; + +const registeredSS = exports.registered = function registeredSS(url, options) { + let { uri, type } = setOptions(url, options); + + // check that the stylesheet is registered + return !!sss.sheetRegistered(uri, type); +}; + +const unregisterSS = exports.unload = function unregisterSS(url, options) { + let { uri, type } = setOptions(url, options); + + // remove the unloader our load function setup if it exists + removeUnload(url); + + // unregister the stylesheet + sss.unregisterSheet(uri, type); +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/utils/addonmanager.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/utils/addonmanager.js new file mode 100644 index 0000000..3e301a2 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/utils/addonmanager.js @@ -0,0 +1,19 @@ +/* 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 {Cc, Ci, Cu} = require("chrome"); + +Cu.import("resource://gre/modules/AddonManager.jsm", this); + +exports.AddonManager = AddonManager; +exports.AddonManagerPrivate = AddonManagerPrivate; + +exports.AddonType = AddonManagerPrivate.AddonType; +exports.AddonAuthor = + AddonManagerPrivate.AddonAuthor || function AddonAuthor(name, url) { + this.name = name; + this.url = url; + this.toString = function() this.name +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/browser.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/browser.js new file mode 100644 index 0000000..5b1ed47 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/browser.js @@ -0,0 +1,180 @@ +/* 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 { WindowTracker } = require("sdk/deprecated/window-utils"); +const { isBrowser, windows } = require('sdk/window/utils'); +const { validateOptions } = require("sdk/deprecated/api-utils"); +const { Class } = require("sdk/core/heritage"); +const { ns } = require("sdk/core/namespace"); +const { ensure } = require('sdk/system/unload'); + +const { xulNS } = require('./namespace'); + +const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; +const VALID_POSITIONS = ['top']; + +// Converts anything that isn't false, null or undefined into a string +function stringOrNull(val) val ? String(val) : val; + +const XUL_SKELETON = Class({ + setup: function setup(attributes) { + const internals = xulNS(this); + internals.attributes = attributes; + ensure(this, 'destroy'); + }, + appendChild: function appendChild(node) { + const ID = this.getAttribute('id'); + + // keep note to update parent in future windows + xulNS(node).parentID = ID; + xulNS(node).insertBeforeID = null; + + // update parent on current windows + windows().forEach(function(window) { + let parent = window.document.getElementById(ID); + let { element } = xulNS(node).windowsNS(window); + parent.appendChild(element); + }); + }, + insertBefore: function(node, beforeNode) { + const ID = this.getAttribute('id'); + const B4_ID = (typeof beforeNode == 'string') ? beforeNode : beforeNode.getAttribute('id'); + + // keep note to update parent in future windows + xulNS(node).parentID = ID; + xulNS(node).insertBeforeID = B4_ID; + + // update parent on current windows + windows().forEach(function(window) { + let parent = window.document.getElementById(ID); + let before = window.document.getElementById(B4_ID); + let { element } = xulNS(node).windowsNS(window); + + parent.insertBefore(element, before); + }); + }, + addEventListener: function addEventListener(type, listener, useCapture) { + internals.eles.forEach(function(ele) { + ele.addEventListener(type, listener, useCapture); + }); + }, + removeEventListener: function removeEventListener(type, listener, useCapture) { + internals.eles.forEach(function(ele) { + ele.removeEventListener(type, listener, useCapture); + }); + }, + getAttribute: function getAttribute(attr) { + return xulNS(this).attributes[attr]; + }, + setAttribute: function setAttribute(attr, value) { + const internals = xulNS(this); + internals.eles.forEach(function(ele) { + ele.setAttribute(attr, value); + }); + internals.attributes[attr] = value; + }, + destroy: function() { + const internals = xulNS(this); + internals.attributes = null; + } +}); + +const XUL = Class({ + implements: [ XUL_SKELETON ], + initialize: function(nodeName, attributes) { + const self = this; + const internals = xulNS(this); + internals.windowsNS = ns(); + internals.eles = []; + internals.attributes = attributes; + + XUL_SKELETON.prototype.setup.call(this, attributes); + + // Set Window Tracker + internals.windowtracker = WindowTracker({ + onTrack: function(window) { + if (!isBrowser(window)) return; + let ele = window.document.createElementNS(NS_XUL, nodeName); + + Object.keys(attributes).forEach(function(key) { + ele.setAttribute(key, attributes[key]); + }) + + internals.eles.push(ele); + internals.windowsNS(window).element = ele; + + // update parent? + if (internals.parentID) { + let parent = window.document.getElementById(internals.parentID); + if (internals.insertBeforeID) { + let before = window.document.getElementById(internals.insertBeforeID); + parent.insertBefore(ele, before); + } + else { + parent.appendChild(ele); + } + } + }, + onUntrack: function(window) { + if (!isBrowser(window)) return; + let { element } = internals.windowsNS(window); + element.parentNode.removeChild(element); + internals.windowsNS(window).element = null; + } + }); + }, + destroy: function() { + XUL_SKELETON.prototype.destroy.call(this); + const internals = xulNS(this); + internals.windowtracker.unload(); + internals.windowtracker = null; + internals.windowsNS = null; + } +}); +exports.XUL = XUL; + +const XUL_GETTER = Class({ + implements: [ XUL_SKELETON ], + initialize: function(attributes) { + const self = this; + const internals = xulNS(this); + internals.windowsNS = ns(); + internals.eles = []; + internals.attributes = attributes; + + XUL_SKELETON.prototype.setup.call(this, attributes); + + // Set Window Tracker + internals.windowtracker = WindowTracker({ + onTrack: function(window) { + if (!isBrowser(window)) return; + let ele = window.document.getElementById(attributes.id); + internals.eles.push(ele); + internals.windowsNS(window).element = ele; + + // update parent? + if (internals.parentID) { + let parent = window.document.getElementById(internals.parentID); + parent.appendChild(ele); + } + } + }); + }, + destroy: function() { + const internals = xulNS(this); + + XUL_SKELETON.prototype.destroy.call(this); + + internals.windowtracker.unload(); + internals.windowtracker = null; + internals.windowsNS = null; + } +}); +exports.XUL_GETTER = XUL_GETTER; + +function getXULById(id) { + return XUL_GETTER({ id: id }); +} +exports.getXULById = getXULById; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/key.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/key.js new file mode 100644 index 0000000..c855fc3 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/key.js @@ -0,0 +1,43 @@ +/* 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 NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +exports.XulKey = function XulKey(options) { + var delegate = { + onTrack: function (window) { + if ("chrome://browser/content/browser.xul" != window.location) return; + + let doc = window.document; + function $(id) doc.getElementById(id); + function xul(type) doc.createElementNS(NS_XUL, type); + + var onCmd = function() { + options.onCommand && options.onCommand(); + }; + + var keyset = xul("keyset"); + + // add hotkey + var key = xul("key"); + key.setAttribute("id", options.id); + key.setAttribute("key", options.key); + if (options.modifiers) + key.setAttribute("modifiers", options.modifiers); + key.setAttribute("oncommand", "void(0);"); + key.addEventListener("command", onCmd, true); + ($("mainKeyset") || $("mailKeys")).parentNode.appendChild(keyset).appendChild(key); + + // add unloader + require("unload+").unload(function() { + key.removeEventListener("command", onCmd, true); // must do for some reason.. + keyset.parentNode.removeChild(keyset); + }, window); + }, + onUntrack: function (window) {} + }; + var winUtils = require("window-utils"); + var tracker = new winUtils.WindowTracker(delegate); +}; diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/listen.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/listen.js new file mode 100644 index 0000000..5536e30 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/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 } = require('../addon/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/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/namespace.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/namespace.js new file mode 100644 index 0000000..1a67716 --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/xul/namespace.js @@ -0,0 +1,3 @@ +'use strict'; +const { ns } = require('sdk/core/namespace'); +exports.xulNS = ns(); diff --git a/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/zip/utils.js b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/zip/utils.js new file mode 100644 index 0000000..fa5796c --- /dev/null +++ b/data/extensions/jid1-KtlZuoiikVfFew@jetpack/node_modules/pathfinder/lib/zip/utils.js @@ -0,0 +1,13 @@ +/* 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 { Cc, Ci, Cu } = require("chrome"); + +exports.getZipReader = function(aFile) { + var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] + .createInstance(Ci.nsIZipReader); + zipReader.open(aFile); + return zipReader; +}; |