aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.12/lib/sdk/content
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.12/lib/sdk/content')
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js870
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/content-worker.js308
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/content.js15
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/loader.js204
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/symbiont.js197
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js46
-rw-r--r--tools/addon-sdk-1.12/lib/sdk/content/worker.js582
7 files changed, 0 insertions, 2222 deletions
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js b/tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js
deleted file mode 100644
index 76df7f6..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/content-proxy.js
+++ /dev/null
@@ -1,870 +0,0 @@
-/* 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";
-
-/* Trick the linker in order to avoid error on `Components.interfaces` usage.
- We are tricking the linker with `require('./content-proxy.js')` from
- worjer.js in order to ensure shipping this file! But then the linker think
- that this file is going to be used as a CommonJS module where we forbid usage
- of `Components`.
-*/
-let Ci = Components['interfaces'];
-
-/**
- * Access key that allows privileged code to unwrap proxy wrappers through
- * valueOf:
- * let xpcWrapper = proxyWrapper.valueOf(UNWRAP_ACCESS_KEY);
- * This key should only be used by proxy unit test.
- */
- const UNWRAP_ACCESS_KEY = {};
-
-
- /**
- * Returns a closure that wraps arguments before calling the given function,
- * which can be given to native functions that accept a function, such that when
- * the closure is called, the given function is called with wrapped arguments.
- *
- * @param fun {Function}
- * the function for which to create a closure wrapping its arguments
- * @param obj {Object}
- * target object from which `fun` comes from
- * (optional, for debugging purpose)
- * @param name {String}
- * name of the attribute from which `fun` is binded on `obj`
- * (optional, for debugging purpose)
- *
- * Example:
- * function contentScriptListener(event) {}
- * let wrapper = ContentScriptFunctionWrapper(contentScriptListener);
- * xray.addEventListener("...", wrapper, false);
- * -> Allow to `event` to be wrapped
- */
-function ContentScriptFunctionWrapper(fun, obj, name) {
- if ("___proxy" in fun && typeof fun.___proxy == "function")
- return fun.___proxy;
-
- let wrappedFun = function () {
- let args = [];
- for (let i = 0, l = arguments.length; i < l; i++)
- args.push(wrap(arguments[i]));
-
- //console.log("Called from native :"+obj+"."+name);
- //console.log(">args "+arguments.length);
- //console.log(fun);
-
- // Native code can execute this callback with `this` being the wrapped
- // function. For example, window.mozRequestAnimationFrame.
- if (this == wrappedFun)
- return fun.apply(fun, args);
-
- return fun.apply(wrap(this), args);
- };
-
- Object.defineProperty(fun, "___proxy", {value : wrappedFun,
- writable : false,
- enumerable : false,
- configurable : false});
-
- return wrappedFun;
-}
-
-/**
- * Returns a closure that unwraps arguments before calling the `fun` function,
- * which can be used to build a wrapper for a native function that accepts
- * wrapped arguments, since native function only accept unwrapped arguments.
- *
- * @param fun {Function}
- * the function to wrap
- * @param originalObject {Object}
- * target object from which `fun` comes from
- * (optional, for debugging purpose)
- * @param name {String}
- * name of the attribute from which `fun` is binded on `originalObject`
- * (optional, for debugging purpose)
- *
- * Example:
- * wrapper.appendChild = NativeFunctionWrapper(xray.appendChild, xray);
- * wrapper.appendChild(anotherWrapper);
- * -> Allow to call xray.appendChild with unwrapped version of anotherWrapper
- */
-function NativeFunctionWrapper(fun, originalObject, name) {
- return function () {
- let args = [];
- let obj = this && typeof this.valueOf == "function" ?
- this.valueOf(UNWRAP_ACCESS_KEY) : this;
-
- for (let i = 0, l = arguments.length; i < l; i++)
- args.push( unwrap(arguments[i], obj, name) );
-
- //if (name != "toString")
- //console.log(">>calling native ["+(name?name:'#closure#')+"]: \n"+fun.apply+"\n"+obj+"\n("+args.join(', ')+")\nthis :"+obj+"from:"+originalObject+"\n");
-
- // Need to use Function.prototype.apply.apply because XMLHttpRequest
- // is a function (typeof return 'function') and fun.apply is null :/
- let unwrapResult = Function.prototype.apply.apply(fun, [obj, args]);
- let result = wrap(unwrapResult, obj, name);
-
- //console.log("<< "+rr+" -> "+r);
-
- return result;
- };
-}
-
-/*
- * Unwrap a JS value that comes from the content script.
- * Mainly converts proxy wrapper to XPCNativeWrapper.
- */
-function unwrap(value, obj, name) {
- //console.log("unwrap : "+value+" ("+name+")");
- if (!value)
- return value;
- let type = typeof value;
-
- // In case of proxy, unwrap them recursively
- // (it should not be recursive, just in case of)
- if (["object", "function"].indexOf(type) !== -1 &&
- "__isWrappedProxy" in value) {
- while("__isWrappedProxy" in value)
- value = value.valueOf(UNWRAP_ACCESS_KEY);
- return value;
- }
-
- // In case of functions we need to return a wrapper that converts native
- // arguments applied to this function into proxies.
- if (type == "function")
- return ContentScriptFunctionWrapper(value, obj, name);
-
- // We must wrap objects coming from content script too, as they may have
- // a function that will be called by a native method.
- // For example:
- // addEventListener(..., { handleEvent: function(event) {} }, ...);
- if (type == "object")
- return ContentScriptObjectWrapper(value);
-
- if (["string", "number", "boolean"].indexOf(type) !== -1)
- return value;
- //console.log("return non-wrapped to native : "+typeof value+" -- "+value);
- return value;
-}
-
-/**
- * Returns an XrayWrapper proxy object that allow to wrap any of its function
- * though `ContentScriptFunctionWrapper`. These proxies are given to
- * XrayWrappers in order to automatically wrap values when they call a method
- * of these proxies. So that they are only used internaly and content script,
- * nor web page have ever access to them. As a conclusion, we can consider
- * this code as being safe regarding web pages overload.
- *
- *
- * @param obj {Object}
- * object coming from content script context to wrap
- *
- * Example:
- * let myListener = { handleEvent: function (event) {} };
- * node.addEventListener("click", myListener, false);
- * `event` has to be wrapped, so handleEvent has to be wrapped using
- * `ContentScriptFunctionWrapper` function.
- * In order to do so, we build this new kind of proxies.
- */
-function ContentScriptObjectWrapper(obj) {
- if ("___proxy" in obj && typeof obj.___proxy == "object")
- return obj.___proxy;
-
- function valueOf(key) {
- if (key === UNWRAP_ACCESS_KEY)
- return obj;
- return this;
- }
-
- let proxy = Proxy.create({
- // Fundamental traps
- getPropertyDescriptor: function(name) {
- return Object.getOwnPropertyDescriptor(obj, name);
- },
- defineProperty: function(name, desc) {
- return Object.defineProperty(obj, name, desc);
- },
- getOwnPropertyNames: function () {
- return Object.getOwnPropertyNames(obj);
- },
- delete: function(name) {
- return delete obj[name];
- },
- // derived traps
- has: function(name) {
- return name === "__isXrayWrapperProxy" ||
- name in obj;
- },
- hasOwn: function(name) {
- return Object.prototype.hasOwnProperty.call(obj, name);
- },
- get: function(receiver, name) {
- if (name == "valueOf")
- return valueOf;
- let value = obj[name];
- if (!value)
- return value;
-
- return unwrap(value);
- },
- set: function(receiver, name, val) {
- obj[name] = val;
- return true;
- },
- enumerate: function() {
- var result = [];
- for each (let name in obj) {
- result.push(name);
- };
- return result;
- },
- keys: function() {
- return Object.keys(obj);
- }
- });
-
- Object.defineProperty(obj, "___proxy", {value : proxy,
- writable : false,
- enumerable : false,
- configurable : false});
-
- return proxy;
-}
-
-// List of all existing typed arrays.
-// Can be found here:
-// http://mxr.mozilla.org/mozilla-central/source/js/src/jsapi.cpp#1790
-const typedArraysCtor = [
- ArrayBuffer,
- Int8Array,
- Uint8Array,
- Int16Array,
- Uint16Array,
- Int32Array,
- Uint32Array,
- Float32Array,
- Float64Array,
- Uint8ClampedArray
-];
-
-/*
- * Wrap a JS value coming from the document by building a proxy wrapper.
- */
-function wrap(value, obj, name, debug) {
- if (!value)
- return value;
- let type = typeof value;
- if (type == "object") {
- // Bug 671016: Typed arrays don't need to be proxified.
- // We avoid checking the whole constructor list on all objects
- // by doing this check only on non-extensible objects:
- if (!Object.isExtensible(value) &&
- typedArraysCtor.indexOf(value.constructor) !== -1)
- return value;
-
- // Bug 715755: do not proxify COW wrappers
- // These wrappers throw an exception when trying to access
- // any attribute that is not in a white list
- try {
- ("nonExistantAttribute" in value);
- }
- catch(e) {
- if (e.message.indexOf("Permission denied to access property") !== -1)
- return value;
- }
-
- // We may have a XrayWrapper proxy.
- // For example:
- // let myListener = { handleEvent: function () {} };
- // node.addEventListener("click", myListener, false);
- // When native code want to call handleEvent,
- // we go though ContentScriptFunctionWrapper that calls `wrap(this)`
- // `this` is the XrayWrapper proxy of myListener.
- // We return this object without building a CS proxy as it is already
- // a value coming from the CS.
- if ("__isXrayWrapperProxy" in value)
- return value.valueOf(UNWRAP_ACCESS_KEY);
-
- // Unwrap object before wrapping it.
- // It should not happen with CS proxy objects.
- while("__isWrappedProxy" in value) {
- value = value.valueOf(UNWRAP_ACCESS_KEY);
- }
-
- if (XPCNativeWrapper.unwrap(value) !== value)
- return getProxyForObject(value);
- // In case of Event, HTMLCollection or NodeList or ???
- // XPCNativeWrapper.unwrap(value) === value
- // but it's still a XrayWrapper so let's build a proxy
- return getProxyForObject(value);
- }
- if (type == "function") {
- if (XPCNativeWrapper.unwrap(value) !== value
- || (typeof value.toString === "function" &&
- value.toString().match(/\[native code\]/))) {
- return getProxyForFunction(value, NativeFunctionWrapper(value, obj, name));
- }
- return value;
- }
- if (type == "string")
- return value;
- if (type == "number")
- return value;
- if (type == "boolean")
- return value;
- //console.log("return non-wrapped to wrapped : "+value);
- return value;
-}
-
-/*
- * Wrap an object from the document to a proxy wrapper
- */
-function getProxyForObject(obj) {
- if (typeof obj != "object") {
- let msg = "tried to proxify something other than an object: " + typeof obj;
- console.warn(msg);
- throw msg;
- }
- if ("__isWrappedProxy" in obj) {
- return obj;
- }
- // Check if there is a proxy cached on this wrapper,
- // but take care of prototype ___proxy attribute inheritance!
- if (obj && obj.___proxy && obj.___proxy.valueOf(UNWRAP_ACCESS_KEY) === obj) {
- return obj.___proxy;
- }
-
- let proxy = Proxy.create(handlerMaker(obj));
-
- Object.defineProperty(obj, "___proxy", {value : proxy,
- writable : false,
- enumerable : false,
- configurable : false});
- return proxy;
-}
-
-/*
- * Wrap a function from the document to a proxy wrapper
- */
-function getProxyForFunction(fun, callTrap) {
- if (typeof fun != "function") {
- let msg = "tried to proxify something other than a function: " + typeof fun;
- console.warn(msg);
- throw msg;
- }
- if ("__isWrappedProxy" in fun)
- return obj;
- if ("___proxy" in fun)
- return fun.___proxy;
-
- let proxy = Proxy.createFunction(handlerMaker(fun), callTrap);
-
- Object.defineProperty(fun, "___proxy", {value : proxy,
- writable : false,
- enumerable : false,
- configurable : false});
-
- return proxy;
-}
-
-/*
- * Check if a DOM attribute name is an event name.
- */
-function isEventName(id) {
- if (id.indexOf("on") != 0 || id.length == 2)
- return false;
- // Taken from:
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#7616
- switch (id[2]) {
- case 'a' :
- return (id == "onabort" ||
- id == "onafterscriptexecute" ||
- id == "onafterprint");
- case 'b' :
- return (id == "onbeforeunload" ||
- id == "onbeforescriptexecute" ||
- id == "onblur" ||
- id == "onbeforeprint");
- case 'c' :
- return (id == "onchange" ||
- id == "onclick" ||
- id == "oncontextmenu" ||
- id == "oncopy" ||
- id == "oncut" ||
- id == "oncanplay" ||
- id == "oncanplaythrough");
- case 'd' :
- return (id == "ondblclick" ||
- id == "ondrag" ||
- id == "ondragend" ||
- id == "ondragenter" ||
- id == "ondragleave" ||
- id == "ondragover" ||
- id == "ondragstart" ||
- id == "ondrop" ||
- id == "ondurationchange");
- case 'e' :
- return (id == "onerror" ||
- id == "onemptied" ||
- id == "onended");
- case 'f' :
- return id == "onfocus";
- case 'h' :
- return id == "onhashchange";
- case 'i' :
- return (id == "oninput" ||
- id == "oninvalid");
- case 'k' :
- return (id == "onkeydown" ||
- id == "onkeypress" ||
- id == "onkeyup");
- case 'l' :
- return (id == "onload" ||
- id == "onloadeddata" ||
- id == "onloadedmetadata" ||
- id == "onloadstart");
- case 'm' :
- return (id == "onmousemove" ||
- id == "onmouseout" ||
- id == "onmouseover" ||
- id == "onmouseup" ||
- id == "onmousedown" ||
- id == "onmessage");
- case 'p' :
- return (id == "onpaint" ||
- id == "onpageshow" ||
- id == "onpagehide" ||
- id == "onpaste" ||
- id == "onpopstate" ||
- id == "onpause" ||
- id == "onplay" ||
- id == "onplaying" ||
- id == "onprogress");
- case 'r' :
- return (id == "onreadystatechange" ||
- id == "onreset" ||
- id == "onresize" ||
- id == "onratechange");
- case 's' :
- return (id == "onscroll" ||
- id == "onselect" ||
- id == "onsubmit" ||
- id == "onseeked" ||
- id == "onseeking" ||
- id == "onstalled" ||
- id == "onsuspend");
- case 't':
- return id == "ontimeupdate"
- /*
- // TODO: Make it work for mobile version
- ||
- (nsDOMTouchEvent::PrefEnabled() &&
- (id == "ontouchstart" ||
- id == "ontouchend" ||
- id == "ontouchmove" ||
- id == "ontouchenter" ||
- id == "ontouchleave" ||
- id == "ontouchcancel"))*/;
-
- case 'u' :
- return id == "onunload";
- case 'v':
- return id == "onvolumechange";
- case 'w':
- return id == "onwaiting";
- }
-
- return false;
-}
-
-// XrayWrappers miss some attributes.
-// Here is a list of functions that return a value when it detects a miss:
-const NODES_INDEXED_BY_NAME = ["IMG", "FORM", "APPLET", "EMBED", "OBJECT"];
-const xRayWrappersMissFixes = [
-
- // Fix bug with XPCNativeWrapper on HTMLCollection
- // We can only access array item once, then it's undefined :o
- function (obj, name) {
- let i = parseInt(name);
- if (obj.toString().match(/HTMLCollection|NodeList/) &&
- i >= 0 && i < obj.length) {
- return wrap(XPCNativeWrapper(obj.wrappedJSObject[name]), obj, name);
- }
- return null;
- },
-
- // Trap access to document["form name"]
- // that may refer to an existing form node
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#9285
- function (obj, name) {
- if ("nodeType" in obj && obj.nodeType == 9) {
- let node = obj.wrappedJSObject[name];
- // List of supported tag:
- // http://mxr.mozilla.org/mozilla-central/source/content/html/content/src/nsGenericHTMLElement.cpp#1267
- if (node && NODES_INDEXED_BY_NAME.indexOf(node.tagName) != -1)
- return wrap(XPCNativeWrapper(node));
- }
- return null;
- },
-
- // Trap access to window["frame name"] and window.frames[i]
- // that refer to an (i)frame internal window object
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#6824
- function (obj, name) {
- if (typeof obj == "object" && "document" in obj) {
- // Ensure that we are on a window object
- try {
- obj.QueryInterface(Ci.nsIDOMWindow);
- }
- catch(e) {
- return null;
- }
-
- // Integer case:
- let i = parseInt(name);
- if (i >= 0 && i in obj) {
- return wrap(XPCNativeWrapper(obj[i]));
- }
-
- // String name case:
- if (name in obj.wrappedJSObject) {
- let win = obj.wrappedJSObject[name];
- let nodes = obj.document.getElementsByName(name);
- for (let i = 0, l = nodes.length; i < l; i++) {
- let node = nodes[i];
- if ("contentWindow" in node && node.contentWindow == win)
- return wrap(node.contentWindow);
- }
- }
- }
- return null;
- },
-
- // Trap access to form["node name"]
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsDOMClassInfo.cpp#9477
- function (obj, name) {
- if (typeof obj == "object" && "tagName" in obj && obj.tagName == "FORM") {
- let match = obj.wrappedJSObject[name];
- let nodes = obj.ownerDocument.getElementsByName(name);
- for (let i = 0, l = nodes.length; i < l; i++) {
- let node = nodes[i];
- if (node == match)
- return wrap(node);
- }
- }
- return null;
- }
-
-];
-
-// XrayWrappers have some buggy methods.
-// Here is the list of them with functions returning some replacement
-// for a given object `obj`:
-const xRayWrappersMethodsFixes = {
- // postMessage method is checking the Javascript global
- // and it expects it to be a window object.
- // But in our case, the global object is our sandbox global object.
- // See nsGlobalWindow::CallerInnerWindow():
- // http://mxr.mozilla.org/mozilla-central/source/dom/base/nsGlobalWindow.cpp#5893
- // nsCOMPtr<nsPIDOMWindow> win = do_QueryWrappedNative(wrapper);
- // win is null
- postMessage: function (obj) {
- // Ensure that we are on a window object
- try {
- obj.QueryInterface(Ci.nsIDOMWindow);
- }
- catch(e) {
- return null;
- }
-
- // Create a wrapper that is going to call `postMessage` through `eval`
- let f = function postMessage(message, targetOrigin) {
- let jscode = "this.postMessage(";
- if (typeof message != "string")
- jscode += JSON.stringify(message);
- else
- jscode += "'" + message.toString().replace(/['\\]/g,"\\$&") + "'";
-
- targetOrigin = targetOrigin.toString().replace(/['\\]/g,"\\$&");
-
- jscode += ", '" + targetOrigin + "')";
- return this.wrappedJSObject.eval(jscode);
- };
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
-
- // Fix mozMatchesSelector uses that is broken on XrayWrappers
- // when we use document.documentElement.mozMatchesSelector.call(node, expr)
- // It's only working if we call mozMatchesSelector on the node itself.
- // SEE BUG 658909: mozMatchesSelector returns incorrect results with XrayWrappers
- mozMatchesSelector: function (obj) {
- // Ensure that we are on an object to expose this buggy method
- try {
- // Bug 707576 removed nsIDOMNSElement.
- // Can be simplified as soon as Firefox 11 become the minversion
- obj.QueryInterface("nsIDOMElement" in Ci ? Ci.nsIDOMElement :
- Ci.nsIDOMNSElement);
- }
- catch(e) {
- return null;
- }
- // We can't use `wrap` function as `f` is not a native function,
- // so wrap it manually:
- let f = function mozMatchesSelector(selectors) {
- return this.mozMatchesSelector(selectors);
- };
-
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
-
- // Bug 679054: History API doesn't work with Proxy objects. We have to pass
- // regular JS objects on `pushState` and `replaceState` methods.
- // In addition, the first argument has to come from the same compartment.
- pushState: function (obj) {
- // Ensure that we are on an object that expose History API
- try {
- obj.QueryInterface(Ci.nsIDOMHistory);
- }
- catch(e) {
- return null;
- }
- let f = function fix() {
- // Call native method with JSON objects
- // (need to convert `arguments` to an array via `slice`)
- return this.pushState.apply(this, JSON.parse(JSON.stringify(Array.slice(arguments))));
- };
-
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
- replaceState: function (obj) {
- // Ensure that we are on an object that expose History API
- try {
- obj.QueryInterface(Ci.nsIDOMHistory);
- }
- catch(e) {
- return null;
- }
- let f = function fix() {
- // Call native method with JSON objects
- // (need to convert `arguments` to an array via `slice`)
- return this.replaceState.apply(this, JSON.parse(JSON.stringify(Array.slice(arguments))));
- };
-
- return getProxyForFunction(f, NativeFunctionWrapper(f));
- },
-
- // Bug 769006: nsIDOMMutationObserver.observe fails with proxy as options
- // attributes
- observe: function observe(obj) {
- // Ensure that we are on a DOMMutation object
- try {
- // nsIDOMMutationObserver starts with FF14
- if ("nsIDOMMutationObserver" in Ci)
- obj.QueryInterface(Ci.nsIDOMMutationObserver);
- else
- return null;
- }
- catch(e) {
- return null;
- }
- return function nsIDOMMutationObserverObserveFix(target, options) {
- // Gets native/unwrapped this
- let self = this && typeof this.valueOf == "function" ?
- this.valueOf(UNWRAP_ACCESS_KEY) : this;
- // Unwrap the xraywrapper target out of JS proxy
- let targetXray = unwrap(target);
- // But do not wrap `options` through ContentScriptObjectWrapper
- let result = wrap(self.observe(targetXray, options));
- // Finally wrap result into JS proxies
- return wrap(result);
- };
- }
-};
-
-/*
- * Generate handler for proxy wrapper
- */
-function handlerMaker(obj) {
- // Overloaded attributes dictionary
- let overload = {};
- // Expando attributes dictionary (i.e. onclick, onfocus, on* ...)
- let expando = {};
- // Cache of methods overloaded to fix XrayWrapper bug
- let methodFixes = {};
- return {
- // Fundamental traps
- getPropertyDescriptor: function(name) {
- return Object.getOwnPropertyDescriptor(obj, name);
- },
- defineProperty: function(name, desc) {
- return Object.defineProperty(obj, name, desc);
- },
- getOwnPropertyNames: function () {
- return Object.getOwnPropertyNames(obj);
- },
- delete: function(name) {
- delete expando[name];
- delete overload[name];
- return delete obj[name];
- },
-
- // derived traps
- has: function(name) {
- if (name == "___proxy") return false;
- if (isEventName(name)) {
- // XrayWrappers throw exception when we try to access expando attributes
- // even on "name in wrapper". So avoid doing it!
- return name in expando;
- }
- return name in obj || name in overload || name == "__isWrappedProxy" ||
- undefined !== this.get(null, name);
- },
- hasOwn: function(name) {
- return Object.prototype.hasOwnProperty.call(obj, name);
- },
- get: function(receiver, name) {
- if (name == "___proxy")
- return undefined;
-
- // Overload toString in order to avoid returning "[XrayWrapper [object HTMLElement]]"
- // or "[object Function]" for function's Proxy
- if (name == "toString") {
- // Bug 714778: we should not pass obj.wrappedJSObject.toString
- // in order to avoid sharing its proxy between two contents scripts.
- // (not that `unwrappedObj` can be equal to `obj` when `obj` isn't
- // an xraywrapper)
- let unwrappedObj = XPCNativeWrapper.unwrap(obj);
- return wrap(function () {
- return unwrappedObj.toString.call(
- this.valueOf(UNWRAP_ACCESS_KEY), arguments);
- }, obj, name);
- }
-
- // Offer a way to retrieve XrayWrapper from a proxified node through `valueOf`
- if (name == "valueOf")
- return function (key) {
- if (key === UNWRAP_ACCESS_KEY)
- return obj;
- return this;
- };
-
- // Return overloaded value if there is one.
- // It allows to overload native methods like addEventListener that
- // are not saved, even on the wrapper itself.
- // (And avoid some methods like toSource from being returned here! [__proto__ test])
- if (name in overload &&
- overload[name] != Object.getPrototypeOf(overload)[name] &&
- name != "__proto__") {
- return overload[name];
- }
-
- // Catch exceptions thrown by XrayWrappers when we try to access on*
- // attributes like onclick, onfocus, ...
- if (isEventName(name)) {
- //console.log("expando:"+obj+" - "+obj.nodeType);
- return name in expando ? expando[name].original : undefined;
- }
-
- // Overload some XrayWrappers method in order to fix its bugs
- if (name in methodFixes &&
- methodFixes[name] != Object.getPrototypeOf(methodFixes)[name] &&
- name != "__proto__")
- return methodFixes[name];
- if (Object.keys(xRayWrappersMethodsFixes).indexOf(name) !== -1) {
- let fix = xRayWrappersMethodsFixes[name](obj);
- if (fix)
- return methodFixes[name] = fix;
- }
-
- let o = obj[name];
-
- // XrayWrapper miss some attributes, try to catch these and return a value
- if (!o) {
- for each(let atttributeFixer in xRayWrappersMissFixes) {
- let fix = atttributeFixer(obj, name);
- if (fix)
- return fix;
- }
- }
-
- // Generic case
- return wrap(o, obj, name);
-
- },
-
- set: function(receiver, name, val) {
-
- if (isEventName(name)) {
- //console.log("SET on* attribute : " + name + " / " + val + "/" + obj);
- let shortName = name.replace(/^on/,"");
-
- // Unregister previously set listener
- if (expando[name]) {
- obj.removeEventListener(shortName, expando[name], true);
- delete expando[name];
- }
-
- // Only accept functions
- if (typeof val != "function")
- return false;
-
- // Register a new listener
- let original = val;
- val = ContentScriptFunctionWrapper(val);
- expando[name] = val;
- val.original = original;
- obj.addEventListener(name.replace(/^on/, ""), val, true);
- return true;
- }
-
- obj[name] = val;
-
- // Handle native method not overloaded on XrayWrappers:
- // obj.addEventListener = val; -> obj.addEventlistener = native method
- // And, XPCNativeWrapper bug where nested values appear to be wrapped:
- // obj.customNestedAttribute = val -> obj.customNestedAttribute !== val
- // obj.customNestedAttribute = "waive wrapper something"
- // SEE BUG 658560: Fix identity problem with CrossOriginWrappers
- // TODO: check that DOM can't be updated by the document itself and so overloaded value becomes wrong
- // but I think such behavior is limited to primitive type
- if ((typeof val == "function" || typeof val == "object") && name) {
- overload[name] = val;
- }
-
- return true;
- },
-
- enumerate: function() {
- var result = [];
- for each (let name in Object.keys(obj)) {
- result.push(name);
- };
- return result;
- },
-
- keys: function() {
- return Object.keys(obj);
- }
- };
-};
-
-
-/*
- * Wrap an object from the document to a proxy wrapper.
- */
-function create(object) {
- if ("wrappedJSObject" in object)
- object = object.wrappedJSObject;
- let xpcWrapper = XPCNativeWrapper(object);
- // If we can't build an XPCNativeWrapper, it doesn't make sense to build
- // a proxy. All proxy code is based on having such wrapper that store
- // different JS attributes set.
- // (we can't build XPCNativeWrapper when object is from the same
- // principal/domain)
- if (object === xpcWrapper) {
- return object;
- }
- return getProxyForObject(xpcWrapper);
-}
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/content-worker.js b/tools/addon-sdk-1.12/lib/sdk/content/content-worker.js
deleted file mode 100644
index 8cf9c5c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/content-worker.js
+++ /dev/null
@@ -1,308 +0,0 @@
-/* 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/. */
-
-const ContentWorker = Object.freeze({
- // TODO: Bug 727854 Use same implementation than common JS modules,
- // i.e. EventEmitter module
-
- /**
- * Create an EventEmitter instance.
- */
- createEventEmitter: function createEventEmitter(emit) {
- let listeners = Object.create(null);
- let eventEmitter = Object.freeze({
- emit: emit,
- on: function on(name, callback) {
- if (typeof callback !== "function")
- return this;
- if (!(name in listeners))
- listeners[name] = [];
- listeners[name].push(callback);
- return this;
- },
- once: function once(name, callback) {
- eventEmitter.on(name, function onceCallback() {
- eventEmitter.removeListener(name, onceCallback);
- callback.apply(callback, arguments);
- });
- },
- removeListener: function removeListener(name, callback) {
- if (!(name in listeners))
- return;
- let index = listeners[name].indexOf(callback);
- if (index == -1)
- return;
- listeners[name].splice(index, 1);
- }
- });
- function onEvent(name) {
- if (!(name in listeners))
- return [];
- let args = Array.slice(arguments, 1);
- let results = [];
- for each (let callback in listeners[name]) {
- results.push(callback.apply(null, args));
- }
- return results;
- }
- function hasListenerFor(name) {
- if (!(name in listeners))
- return false;
- return listeners[name].length > 0;
- }
- return {
- eventEmitter: eventEmitter,
- emit: onEvent,
- hasListenerFor: hasListenerFor
- };
- },
-
- /**
- * Create an EventEmitter instance to communicate with chrome module
- * by passing only strings between compartments.
- * This function expects `emitToChrome` function, that allows to send
- * events to the chrome module. It returns the EventEmitter as `pipe`
- * attribute, and, `onChromeEvent` a function that allows chrome module
- * to send event into the EventEmitter.
- *
- * pipe.emit --> emitToChrome
- * onChromeEvent --> callback registered through pipe.on
- */
- createPipe: function createPipe(emitToChrome) {
- function onEvent() {
- // Convert to real array
- let args = Array.slice(arguments);
- // JSON.stringify is buggy with cross-sandbox values,
- // it may return "{}" on functions. Use a replacer to match them correctly.
- function replacer(k, v) {
- return typeof v === "function" ? undefined : v;
- }
- let str = JSON.stringify(args, replacer);
- emitToChrome(str);
- }
-
- let { eventEmitter, emit, hasListenerFor } =
- ContentWorker.createEventEmitter(onEvent);
-
- return {
- pipe: eventEmitter,
- onChromeEvent: function onChromeEvent(array) {
- // We either receive a stringified array, or a real array.
- // We still allow to pass an array of objects, in WorkerSandbox.emitSync
- // in order to allow sending DOM node reference between content script
- // and modules (only used for context-menu API)
- let args = typeof array == "string" ? JSON.parse(array) : array;
- return emit.apply(null, args);
- },
- hasListenerFor: hasListenerFor
- };
- },
-
- injectConsole: function injectConsole(exports, pipe) {
- exports.console = Object.freeze({
- log: pipe.emit.bind(null, "console", "log"),
- info: pipe.emit.bind(null, "console", "info"),
- warn: pipe.emit.bind(null, "console", "warn"),
- error: pipe.emit.bind(null, "console", "error"),
- debug: pipe.emit.bind(null, "console", "debug"),
- exception: pipe.emit.bind(null, "console", "exception"),
- trace: pipe.emit.bind(null, "console", "trace")
- });
- },
-
- injectTimers: function injectTimers(exports, chromeAPI, pipe, console) {
- // wrapped functions from `'timer'` module.
- // Wrapper adds `try catch` blocks to the callbacks in order to
- // emit `error` event on a symbiont if exception is thrown in
- // the Worker global scope.
- // @see http://www.w3.org/TR/workers/#workerutils
-
- // List of all living timeouts/intervals
- let _timers = Object.create(null);
-
- // Keep a reference to original timeout functions
- let {
- setTimeout: chromeSetTimeout,
- setInterval: chromeSetInterval,
- clearTimeout: chromeClearTimeout,
- clearInterval: chromeClearInterval
- } = chromeAPI.timers;
-
- function registerTimer(timer) {
- let registerMethod = null;
- if (timer.kind == "timeout")
- registerMethod = chromeSetTimeout;
- else if (timer.kind == "interval")
- registerMethod = chromeSetInterval;
- else
- throw new Error("Unknown timer kind: " + timer.kind);
- let id = registerMethod(onFire, timer.delay);
- function onFire() {
- try {
- if (timer.kind == "timeout")
- delete _timers[id];
- timer.fun.apply(null, timer.args);
- } catch(e) {
- console.exception(e);
- }
- }
- _timers[id] = timer;
- return id;
- }
-
- function unregisterTimer(id) {
- if (!(id in _timers))
- return;
- let { kind } = _timers[id];
- delete _timers[id];
- if (kind == "timeout")
- chromeClearTimeout(id);
- else if (kind == "interval")
- chromeClearInterval(id);
- else
- throw new Error("Unknown timer kind: " + kind);
- }
-
- function disableAllTimers() {
- Object.keys(_timers).forEach(unregisterTimer);
- }
-
- exports.setTimeout = function ContentScriptSetTimeout(callback, delay) {
- return registerTimer({
- kind: "timeout",
- fun: callback,
- delay: delay,
- args: Array.slice(arguments, 2)
- });
- };
- exports.clearTimeout = function ContentScriptClearTimeout(id) {
- unregisterTimer(id);
- };
-
- exports.setInterval = function ContentScriptSetInterval(callback, delay) {
- return registerTimer({
- kind: "interval",
- fun: callback,
- delay: delay,
- args: Array.slice(arguments, 2)
- });
- };
- exports.clearInterval = function ContentScriptClearInterval(id) {
- unregisterTimer(id);
- };
-
- // On page-hide, save a list of all existing timers before disabling them,
- // in order to be able to restore them on page-show.
- // These events are fired when the page goes in/out of bfcache.
- // https://developer.mozilla.org/En/Working_with_BFCache
- let frozenTimers = [];
- pipe.on("pageshow", function onPageShow() {
- frozenTimers.forEach(registerTimer);
- });
- pipe.on("pagehide", function onPageHide() {
- frozenTimers = [];
- for (let id in _timers)
- frozenTimers.push(_timers[id]);
- disableAllTimers();
- // Some other pagehide listeners may register some timers that won't be
- // frozen as this particular pagehide listener is called first.
- // So freeze these timers on next cycle.
- chromeSetTimeout(function () {
- for (let id in _timers)
- frozenTimers.push(_timers[id]);
- disableAllTimers();
- }, 0);
- });
-
- // Unregister all timers when the page is destroyed
- // (i.e. when it is removed from bfcache)
- pipe.on("detach", function clearTimeouts() {
- disableAllTimers();
- _timers = {};
- frozenTimers = [];
- });
- },
-
- injectMessageAPI: function injectMessageAPI(exports, pipe) {
-
- let { eventEmitter: port, emit : portEmit } =
- ContentWorker.createEventEmitter(pipe.emit.bind(null, "event"));
- pipe.on("event", portEmit);
-
- let self = {
- port: port,
- postMessage: pipe.emit.bind(null, "message"),
- on: pipe.on.bind(null),
- once: pipe.once.bind(null),
- removeListener: pipe.removeListener.bind(null),
- };
- Object.defineProperty(exports, "self", {
- value: self
- });
-
- // Deprecated use of on/postMessage from globals
- exports.postMessage = function deprecatedPostMessage() {
- console.error("DEPRECATED: The global `postMessage()` function in " +
- "content scripts is deprecated in favor of the " +
- "`self.postMessage()` function, which works the same. " +
- "Replace calls to `postMessage()` with calls to " +
- "`self.postMessage()`." +
- "For more info on `self.on`, see " +
- "<https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/addon-development/web-content.html>.");
- return self.postMessage.apply(null, arguments);
- };
- exports.on = function deprecatedOn() {
- console.error("DEPRECATED: The global `on()` function in content " +
- "scripts is deprecated in favor of the `self.on()` " +
- "function, which works the same. Replace calls to `on()` " +
- "with calls to `self.on()`" +
- "For more info on `self.on`, see " +
- "<https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/addon-development/web-content.html>.");
- return self.on.apply(null, arguments);
- };
-
- // Deprecated use of `onMessage` from globals
- let onMessage = null;
- Object.defineProperty(exports, "onMessage", {
- get: function () onMessage,
- set: function (v) {
- if (onMessage)
- self.removeListener("message", onMessage);
- console.error("DEPRECATED: The global `onMessage` function in content" +
- "scripts is deprecated in favor of the `self.on()` " +
- "function. Replace `onMessage = function (data){}` " +
- "definitions with calls to `self.on('message', " +
- "function (data){})`. " +
- "For more info on `self.on`, see " +
- "<https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/addon-development/web-content.html>.");
- onMessage = v;
- if (typeof onMessage == "function")
- self.on("message", onMessage);
- }
- });
- },
-
- injectOptions: function (exports, options) {
- Object.defineProperty( exports.self, "options", { value: JSON.parse( options ) });
- },
-
- inject: function (exports, chromeAPI, emitToChrome, options) {
- let { pipe, onChromeEvent, hasListenerFor } =
- ContentWorker.createPipe(emitToChrome);
-
- ContentWorker.injectConsole(exports, pipe);
- ContentWorker.injectTimers(exports, chromeAPI, pipe, exports.console);
- ContentWorker.injectMessageAPI(exports, pipe);
- if ( options !== undefined ) {
- ContentWorker.injectOptions(exports, options);
- }
-
- Object.freeze( exports.self );
-
- return {
- emitToContent: onChromeEvent,
- hasListenerFor: hasListenerFor
- };
- }
-});
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/content.js b/tools/addon-sdk-1.12/lib/sdk/content/content.js
deleted file mode 100644
index 4bffd45..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/content.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "unstable"
-};
-
-exports.Loader = require('./loader').Loader;
-exports.Symbiont = require('./symbiont').Symbiont;
-exports.Worker = require('./worker').Worker;
-
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/loader.js b/tools/addon-sdk-1.12/lib/sdk/content/loader.js
deleted file mode 100644
index b01675c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/loader.js
+++ /dev/null
@@ -1,204 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "unstable"
-};
-
-const { EventEmitter } = require('../deprecated/events');
-const { validateOptions } = require('../deprecated/api-utils');
-const { URL } = require('../url');
-const file = require('../io/file');
-
-const LOCAL_URI_SCHEMES = ['resource', 'data'];
-
-// Returns `null` if `value` is `null` or `undefined`, otherwise `value`.
-function ensureNull(value) {
- return value == null ? null : value;
-}
-
-// map of property validations
-const valid = {
- contentURL: {
- ok: function (value) {
- try {
- URL(value);
- }
- catch(e) {
- return false;
- }
- return true;
- },
- msg: 'The `contentURL` option must be a valid URL.'
- },
- contentScriptFile: {
- is: ['undefined', 'null', 'string', 'array'],
- map: ensureNull,
- ok: function(value) {
- if (value === null)
- return true;
-
- value = [].concat(value);
-
- // Make sure every item is a local file URL.
- return value.every(function (item) {
- try {
- return ~LOCAL_URI_SCHEMES.indexOf(URL(item).scheme);
- }
- catch(e) {
- return false;
- }
- });
-
- },
- msg: 'The `contentScriptFile` option must be a local URL or an array of URLs.'
- },
- contentScript: {
- is: ['undefined', 'null', 'string', 'array'],
- map: ensureNull,
- ok: function(value) {
- return !Array.isArray(value) || value.every(
- function(item) { return typeof item === 'string' }
- );
- },
- msg: 'The `contentScript` option must be a string or an array of strings.'
- },
- contentScriptWhen: {
- is: ['string'],
- ok: function(value) { return ~['start', 'ready', 'end'].indexOf(value) },
- map: function(value) {
- return value || 'end';
- },
- msg: 'The `contentScriptWhen` option must be either "start", "ready" or "end".'
- },
- contentScriptOptions: {
- ok: function(value) {
- if ( value === undefined ) { return true; }
- try { JSON.parse( JSON.stringify( value ) ); } catch(e) { return false; }
- return true;
- },
- map: function(value) 'undefined' === getTypeOf(value) ? null : value,
- msg: 'The contentScriptOptions should be a jsonable value.'
- }
-};
-exports.validationAttributes = valid;
-
-/**
- * Shortcut function to validate property with validation.
- * @param {Object|Number|String} suspect
- * value to validate
- * @param {Object} validation
- * validation rule passed to `api-utils`
- */
-function validate(suspect, validation) validateOptions(
- { $: suspect },
- { $: validation }
-).$
-
-function Allow(script) ({
- get script() script,
- set script(value) script = !!value
-})
-
-/**
- * Trait is intended to be used in some composition. It provides set of core
- * properties and bounded validations to them. Trait is useful for all the
- * compositions providing high level APIs for interaction with content.
- * Property changes emit `"propertyChange"` events on instances.
- */
-const Loader = EventEmitter.compose({
- /**
- * Permissions for the content, with the following keys:
- * @property {Object} [allow = { script: true }]
- * @property {Boolean} [allow.script = true]
- * Whether or not to execute script in the content. Defaults to true.
- */
- get allow() this._allow || (this._allow = Allow(true)),
- set allow(value) this.allow.script = value && value.script,
- _allow: null,
- /**
- * The content to load. Either a string of HTML or a URL.
- * @type {String}
- */
- get contentURL() this._contentURL,
- set contentURL(value) {
- value = validate(value, valid.contentURL);
- if (this._contentURL != value) {
- this._emit('propertyChange', {
- contentURL: this._contentURL = value
- });
- }
- },
- _contentURL: null,
- /**
- * When to load the content scripts.
- * Possible values are "end" (default), which loads them once all page
- * contents have been loaded, "ready", which loads them once DOM nodes are
- * ready (ie like DOMContentLoaded event), and "start", which loads them once
- * the `window` object for the page has been created, but before any scripts
- * specified by the page have been loaded.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {'start'|'ready'|'end'}
- */
- get contentScriptWhen() this._contentScriptWhen,
- set contentScriptWhen(value) {
- value = validate(value, valid.contentScriptWhen);
- if (value !== this._contentScriptWhen) {
- this._emit('propertyChange', {
- contentScriptWhen: this._contentScriptWhen = value
- });
- }
- },
- _contentScriptWhen: 'end',
- /**
- * Options avalaible from the content script as `self.options`.
- * The value of options can be of any type (object, array, string, etc.)
- * but only jsonable values will be available as frozen objects from the
- * content script.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {Object}
- */
- get contentScriptOptions() this._contentScriptOptions,
- set contentScriptOptions(value) this._contentScriptOptions = value,
- _contentScriptOptions: null,
- /**
- * The URLs of content scripts.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {String[]}
- */
- get contentScriptFile() this._contentScriptFile,
- set contentScriptFile(value) {
- value = validate(value, valid.contentScriptFile);
- if (value != this._contentScriptFile) {
- this._emit('propertyChange', {
- contentScriptFile: this._contentScriptFile = value
- });
- }
- },
- _contentScriptFile: null,
- /**
- * The texts of content script.
- * Property change emits `propertyChange` event on instance with this key
- * and new value.
- * @type {String|undefined}
- */
- get contentScript() this._contentScript,
- set contentScript(value) {
- value = validate(value, valid.contentScript);
- if (value != this._contentScript) {
- this._emit('propertyChange', {
- contentScript: this._contentScript = value
- });
- }
- },
- _contentScript: null
-});
-exports.Loader = Loader;
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/symbiont.js b/tools/addon-sdk-1.12/lib/sdk/content/symbiont.js
deleted file mode 100644
index 186e9d3..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/symbiont.js
+++ /dev/null
@@ -1,197 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "unstable"
-};
-
-const { Worker } = require('./worker');
-const { Loader } = require('./loader');
-const hiddenFrames = require('../frame/hidden-frame');
-const observers = require('../deprecated/observer-service');
-const unload = require('../system/unload');
-
-const assetsURI = require('../self').data.url();
-
-/**
- * This trait is layered on top of `Worker` and in contrast to symbiont
- * Worker constructor requires `content` option that represents content
- * that will be loaded in the provided frame, if frame is not provided
- * Worker will create hidden one.
- */
-const Symbiont = Worker.resolve({
- constructor: '_initWorker',
- destroy: '_workerDestroy'
- }).compose(Loader, {
-
- /**
- * The constructor requires all the options that are required by
- * `require('content').Worker` with the difference that the `frame` option
- * is optional. If `frame` is not provided, `contentURL` is expected.
- * @param {Object} options
- * @param {String} options.contentURL
- * URL of a content to load into `this._frame` and create worker for.
- * @param {Element} [options.frame]
- * iframe element that is used to load `options.contentURL` into.
- * if frame is not provided hidden iframe will be created.
- */
- constructor: function Symbiont(options) {
- options = options || {};
-
- if ('contentURL' in options)
- this.contentURL = options.contentURL;
- if ('contentScriptWhen' in options)
- this.contentScriptWhen = options.contentScriptWhen;
- if ('contentScriptOptions' in options)
- this.contentScriptOptions = options.contentScriptOptions;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('allow' in options)
- this.allow = options.allow;
- if ('onError' in options)
- this.on('error', options.onError);
- if ('onMessage' in options)
- this.on('message', options.onMessage);
- if ('frame' in options) {
- this._initFrame(options.frame);
- }
- else {
- let self = this;
- this._hiddenFrame = hiddenFrames.HiddenFrame({
- onReady: function onFrame() {
- self._initFrame(this.element);
- },
- onUnload: function onUnload() {
- // Bug 751211: Remove reference to _frame when hidden frame is
- // automatically removed on unload, otherwise we are going to face
- // "dead object" exception
- self.destroy();
- }
- });
- hiddenFrames.add(this._hiddenFrame);
- }
-
- unload.ensure(this._public, "destroy");
- },
-
- destroy: function destroy() {
- this._workerDestroy();
- this._unregisterListener();
- this._frame = null;
- if (this._hiddenFrame) {
- hiddenFrames.remove(this._hiddenFrame);
- this._hiddenFrame = null;
- }
- },
-
- /**
- * XUL iframe or browser elements with attribute `type` being `content`.
- * Used to create `ContentSymbiont` from.
- * @type {nsIFrame|nsIBrowser}
- */
- _frame: null,
-
- /**
- * Listener to the `'frameReady"` event (emitted when `iframe` is ready).
- * Removes listener, sets right permissions to the frame and loads content.
- */
- _initFrame: function _initFrame(frame) {
- if (this._loadListener)
- this._unregisterListener();
-
- this._frame = frame;
- frame.docShell.allowJavascript = this.allow.script;
- frame.setAttribute("src", this._contentURL);
-
- // Inject `addon` object in document if we load a document from
- // one of our addon folder and if no content script are defined. bug 612726
- let isDataResource =
- typeof this._contentURL == "string" &&
- this._contentURL.indexOf(assetsURI) == 0;
- let hasContentScript =
- (Array.isArray(this.contentScript) ? this.contentScript.length > 0
- : !!this.contentScript) ||
- (Array.isArray(this.contentScriptFile) ? this.contentScriptFile.length > 0
- : !!this.contentScriptFile);
- // If we have to inject `addon` we have to do it before document
- // script execution, so during `start`:
- this._injectInDocument = isDataResource && !hasContentScript;
- if (this._injectInDocument)
- this.contentScriptWhen = "start";
-
- if ((frame.contentDocument.readyState == "complete" ||
- (frame.contentDocument.readyState == "interactive" &&
- this.contentScriptWhen != 'end' )) &&
- frame.contentDocument.location == this._contentURL) {
- // In some cases src doesn't change and document is already ready
- // (for ex: when the user moves a widget while customizing toolbars.)
- this._onInit();
- return;
- }
-
- let self = this;
-
- if ('start' == this.contentScriptWhen) {
- this._loadEvent = 'start';
- observers.add('document-element-inserted',
- this._loadListener = function onStart(doc) {
-
- let window = doc.defaultView;
- if (window && window == frame.contentWindow) {
- self._unregisterListener();
- self._onInit();
- }
-
- });
- return;
- }
-
- let eventName = 'end' == this.contentScriptWhen ? 'load' : 'DOMContentLoaded';
- let self = this;
- this._loadEvent = eventName;
- frame.addEventListener(eventName,
- this._loadListener = function _onReady(event) {
-
- if (event.target != frame.contentDocument)
- return;
- self._unregisterListener();
-
- self._onInit();
-
- }, true);
-
- },
-
- /**
- * Unregister listener that watchs for document being ready to be injected.
- * This listener is registered in `Symbiont._initFrame`.
- */
- _unregisterListener: function _unregisterListener() {
- if (!this._loadListener)
- return;
- if (this._loadEvent == "start") {
- observers.remove('document-element-inserted', this._loadListener);
- }
- else {
- this._frame.removeEventListener(this._loadEvent, this._loadListener,
- true);
- }
- this._loadListener = null;
- },
-
- /**
- * Called by Symbiont itself when the frame is ready to load
- * content scripts according to contentScriptWhen. Overloaded by Panel.
- */
- _onInit: function () {
- this._initWorker({ window: this._frame.contentWindow });
- }
-
-});
-exports.Symbiont = Symbiont;
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js b/tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js
deleted file mode 100644
index 9e57274..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/thumbnail.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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': 'unstable'
-};
-
-const { Cc, Ci, Cu } = require('chrome');
-const AppShellService = Cc['@mozilla.org/appshell/appShellService;1'].
- getService(Ci.nsIAppShellService);
-
-const NS = 'http://www.w3.org/1999/xhtml';
-const COLOR = 'rgb(255,255,255)';
-
-/**
- * Creates canvas element with a thumbnail of the passed window.
- * @param {Window} window
- * @returns {Element}
- */
-function getThumbnailCanvasForWindow(window) {
- let aspectRatio = 0.5625; // 16:9
- let thumbnail = AppShellService.hiddenDOMWindow.document
- .createElementNS(NS, 'canvas');
- thumbnail.mozOpaque = true;
- thumbnail.width = Math.ceil(window.screen.availWidth / 5.75);
- thumbnail.height = Math.round(thumbnail.width * aspectRatio);
- let ctx = thumbnail.getContext('2d');
- let snippetWidth = window.innerWidth * .6;
- let scale = thumbnail.width / snippetWidth;
- ctx.scale(scale, scale);
- ctx.drawWindow(window, window.scrollX, window.scrollY, snippetWidth,
- snippetWidth * aspectRatio, COLOR);
- return thumbnail;
-}
-exports.getThumbnailCanvasForWindow = getThumbnailCanvasForWindow;
-
-/**
- * Creates Base64 encoded data URI of the thumbnail for the passed window.
- * @param {Window} window
- * @returns {String}
- */
-exports.getThumbnailURIForWindow = function getThumbnailURIForWindow(window) {
- return getThumbnailCanvasForWindow(window).toDataURL()
-};
diff --git a/tools/addon-sdk-1.12/lib/sdk/content/worker.js b/tools/addon-sdk-1.12/lib/sdk/content/worker.js
deleted file mode 100644
index b2f204c..0000000
--- a/tools/addon-sdk-1.12/lib/sdk/content/worker.js
+++ /dev/null
@@ -1,582 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* 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": "unstable"
-};
-
-const { Trait } = require('../deprecated/traits');
-const { EventEmitter, EventEmitterTrait } = require('../deprecated/events');
-const { Ci, Cu, Cc } = require('chrome');
-const timer = require('../timers');
-const { URL } = require('../url');
-const unload = require('../system/unload');
-const observers = require('../deprecated/observer-service');
-const { Cortex } = require('../deprecated/cortex');
-const { sandbox, evaluate, load } = require("../loader/sandbox");
-const { merge } = require('../util/object');
-const xulApp = require("../system/xul-app");
-const USE_JS_PROXIES = !xulApp.versionInRange(xulApp.platformVersion,
- "17.0a2", "*");
-const { getTabForWindow } = require('../tabs/helpers');
-
-/* Trick the linker in order to ensure shipping these files in the XPI.
- require('./content-proxy.js');
- require('./content-worker.js');
- Then, retrieve URL of these files in the XPI:
-*/
-let prefix = module.uri.split('worker.js')[0];
-const CONTENT_PROXY_URL = prefix + 'content-proxy.js';
-const CONTENT_WORKER_URL = prefix + 'content-worker.js';
-
-const JS_VERSION = '1.8';
-
-const ERR_DESTROYED =
- "Couldn't find the worker to receive this message. " +
- "The script may not be initialized yet, or may already have been unloaded.";
-
-const ERR_FROZEN = "The page is currently hidden and can no longer be used " +
- "until it is visible again.";
-
-/**
- * This key is not exported and should only be used for proxy tests.
- * The following `PRIVATE_KEY` is used in addon module scope in order to tell
- * Worker API to expose `UNWRAP_ACCESS_KEY` in content script.
- * This key allows test-content-proxy.js to unwrap proxy with valueOf:
- * let xpcWrapper = proxyWrapper.valueOf(UNWRAP_ACCESS_KEY);
- */
-const PRIVATE_KEY = {};
-
-
-const WorkerSandbox = EventEmitter.compose({
-
- /**
- * Emit a message to the worker content sandbox
- */
- emit: function emit() {
- // First ensure having a regular array
- // (otherwise, `arguments` would be mapped to an object by `stringify`)
- let array = Array.slice(arguments);
- // JSON.stringify is buggy with cross-sandbox values,
- // it may return "{}" on functions. Use a replacer to match them correctly.
- function replacer(k, v) {
- return typeof v === "function" ? undefined : v;
- }
- // Ensure having an asynchronous behavior
- let self = this;
- timer.setTimeout(function () {
- self._emitToContent(JSON.stringify(array, replacer));
- }, 0);
- },
-
- /**
- * Synchronous version of `emit`.
- * /!\ Should only be used when it is strictly mandatory /!\
- * Doesn't ensure passing only JSON values.
- * Mainly used by context-menu in order to avoid breaking it.
- */
- emitSync: function emitSync() {
- let args = Array.slice(arguments);
- // Bug 732716: Ensure wrapping xrays sent to the content script
- // otherwise it will have access to raw xraywrappers and content script
- // will assume it is an user object coming from the content script sandbox
- if ("_wrap" in this)
- args = args.map(this._wrap);
- return this._emitToContent(args);
- },
-
- /**
- * Tells if content script has at least one listener registered for one event,
- * through `self.on('xxx', ...)`.
- * /!\ Shouldn't be used. Implemented to avoid breaking context-menu API.
- */
- hasListenerFor: function hasListenerFor(name) {
- return this._hasListenerFor(name);
- },
-
- /**
- * Method called by the worker sandbox when it needs to send a message
- */
- _onContentEvent: function onContentEvent(args) {
- // As `emit`, we ensure having an asynchronous behavior
- let self = this;
- timer.setTimeout(function () {
- // We emit event to chrome/addon listeners
- self._emit.apply(self, JSON.parse(args));
- }, 0);
- },
-
- /**
- * Configures sandbox and loads content scripts into it.
- * @param {Worker} worker
- * content worker
- */
- constructor: function WorkerSandbox(worker) {
- this._addonWorker = worker;
-
- // Ensure that `emit` has always the right `this`
- this.emit = this.emit.bind(this);
- this.emitSync = this.emitSync.bind(this);
-
- // We receive a wrapped window, that may be an xraywrapper if it's content
- let window = worker._window;
- let proto = window;
-
- // Instantiate trusted code in another Sandbox in order to prevent content
- // script from messing with standard classes used by proxy and API code.
- let apiSandbox = sandbox(window, { wantXrays: true });
-
- // Build content proxies only if the document has a non-system principal
- // And only on old firefox versions that doesn't ship bug 738244
- if (USE_JS_PROXIES && XPCNativeWrapper.unwrap(window) !== window) {
- apiSandbox.console = console;
- // Execute the proxy code
- load(apiSandbox, CONTENT_PROXY_URL);
- // Get a reference of the window's proxy
- proto = apiSandbox.create(window);
- // Keep a reference to `wrap` function for `emitSync` usage
- this._wrap = apiSandbox.wrap;
- }
-
- // Create the sandbox and bind it to window in order for content scripts to
- // have access to all standard globals (window, document, ...)
- let content = this._sandbox = sandbox(window, {
- sandboxPrototype: proto,
- wantXrays: true
- });
- // We have to ensure that window.top and window.parent are the exact same
- // object than window object, i.e. the sandbox global object. But not
- // always, in case of iframes, top and parent are another window object.
- let top = window.top === window ? content : content.top;
- let parent = window.parent === window ? content : content.parent;
- merge(content, {
- // We need "this === window === top" to be true in toplevel scope:
- get window() content,
- get top() top,
- get parent() parent,
- // Use the Greasemonkey naming convention to provide access to the
- // unwrapped window object so the content script can access document
- // JavaScript values.
- // NOTE: this functionality is experimental and may change or go away
- // at any time!
- get unsafeWindow() window.wrappedJSObject
- });
-
- // Load trusted code that will inject content script API.
- // We need to expose JS objects defined in same principal in order to
- // avoid having any kind of wrapper.
- load(apiSandbox, CONTENT_WORKER_URL);
-
- // prepare a clean `self.options`
- let options = 'contentScriptOptions' in worker ?
- JSON.stringify( worker.contentScriptOptions ) :
- undefined;
-
- // Then call `inject` method and communicate with this script
- // by trading two methods that allow to send events to the other side:
- // - `onEvent` called by content script
- // - `result.emitToContent` called by addon script
- // Bug 758203: We have to explicitely define `__exposedProps__` in order
- // to allow access to these chrome object attributes from this sandbox with
- // content priviledges
- // https://developer.mozilla.org/en/XPConnect_wrappers#Other_security_wrappers
- let chromeAPI = {
- timers: {
- setTimeout: timer.setTimeout,
- setInterval: timer.setInterval,
- clearTimeout: timer.clearTimeout,
- clearInterval: timer.clearInterval,
- __exposedProps__: {
- setTimeout: 'r',
- setInterval: 'r',
- clearTimeout: 'r',
- clearInterval: 'r'
- }
- },
- __exposedProps__: {
- timers: 'r'
- }
- };
- let onEvent = this._onContentEvent.bind(this);
- // `ContentWorker` is defined in CONTENT_WORKER_URL file
- let result = apiSandbox.ContentWorker.inject(content, chromeAPI, onEvent, options);
- this._emitToContent = result.emitToContent;
- this._hasListenerFor = result.hasListenerFor;
-
- // Handle messages send by this script:
- let self = this;
- // console.xxx calls
- this.on("console", function consoleListener(kind) {
- console[kind].apply(console, Array.slice(arguments, 1));
- });
-
- // self.postMessage calls
- this.on("message", function postMessage(data) {
- // destroyed?
- if (self._addonWorker)
- self._addonWorker._emit('message', data);
- });
-
- // self.port.emit calls
- this.on("event", function portEmit(name, args) {
- // destroyed?
- if (self._addonWorker)
- self._addonWorker._onContentScriptEvent.apply(self._addonWorker, arguments);
- });
-
- // Internal feature that is only used by SDK tests:
- // Expose unlock key to content script context.
- // See `PRIVATE_KEY` definition for more information.
- if (apiSandbox && worker._expose_key)
- content.UNWRAP_ACCESS_KEY = apiSandbox.UNWRAP_ACCESS_KEY;
-
- // Inject `addon` global into target document if document is trusted,
- // `addon` in document is equivalent to `self` in content script.
- if (worker._injectInDocument) {
- let win = window.wrappedJSObject ? window.wrappedJSObject : window;
- Object.defineProperty(win, "addon", {
- value: content.self
- }
- );
- }
-
- // The order of `contentScriptFile` and `contentScript` evaluation is
- // intentional, so programs can load libraries like jQuery from script URLs
- // and use them in scripts.
- let contentScriptFile = ('contentScriptFile' in worker) ? worker.contentScriptFile
- : null,
- contentScript = ('contentScript' in worker) ? worker.contentScript : null;
-
- if (contentScriptFile) {
- if (Array.isArray(contentScriptFile))
- this._importScripts.apply(this, contentScriptFile);
- else
- this._importScripts(contentScriptFile);
- }
- if (contentScript) {
- this._evaluate(
- Array.isArray(contentScript) ? contentScript.join(';\n') : contentScript
- );
- }
- },
- destroy: function destroy() {
- this.emitSync("detach");
- this._sandbox = null;
- this._addonWorker = null;
- this._wrap = null;
- },
-
- /**
- * JavaScript sandbox where all the content scripts are evaluated.
- * {Sandbox}
- */
- _sandbox: null,
-
- /**
- * Reference to the addon side of the worker.
- * @type {Worker}
- */
- _addonWorker: null,
-
- /**
- * Evaluates code in the sandbox.
- * @param {String} code
- * JavaScript source to evaluate.
- * @param {String} [filename='javascript:' + code]
- * Name of the file
- */
- _evaluate: function(code, filename) {
- try {
- evaluate(this._sandbox, code, filename || 'javascript:' + code);
- }
- catch(e) {
- this._addonWorker._emit('error', e);
- }
- },
- /**
- * Imports scripts to the sandbox by reading files under urls and
- * evaluating its source. If exception occurs during evaluation
- * `"error"` event is emitted on the worker.
- * This is actually an analog to the `importScript` method in web
- * workers but in our case it's not exposed even though content
- * scripts may be able to do it synchronously since IO operation
- * takes place in the UI process.
- */
- _importScripts: function _importScripts(url) {
- let urls = Array.slice(arguments, 0);
- for each (let contentScriptFile in urls) {
- try {
- let uri = URL(contentScriptFile);
- if (uri.scheme === 'resource')
- load(this._sandbox, String(uri));
- else
- throw Error("Unsupported `contentScriptFile` url: " + String(uri));
- }
- catch(e) {
- this._addonWorker._emit('error', e);
- }
- }
- }
-});
-
-/**
- * Message-passing facility for communication between code running
- * in the content and add-on process.
- * @see https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/content/worker
- */
-const Worker = EventEmitter.compose({
- on: Trait.required,
- _removeAllListeners: Trait.required,
-
- /**
- * Sends a message to the worker's global scope. Method takes single
- * argument, which represents data to be sent to the worker. The data may
- * be any primitive type value or `JSON`. Call of this method asynchronously
- * emits `message` event with data value in the global scope of this
- * symbiont.
- *
- * `message` event listeners can be set either by calling
- * `self.on` with a first argument string `"message"` or by
- * implementing `onMessage` function in the global scope of this worker.
- * @param {Number|String|JSON} data
- */
- postMessage: function postMessage(data) {
- if (!this._contentWorker)
- throw new Error(ERR_DESTROYED);
- if (this._frozen)
- throw new Error(ERR_FROZEN);
-
- this._contentWorker.emit("message", data);
- },
-
- /**
- * EventEmitter, that behaves (calls listeners) asynchronously.
- * A way to send customized messages to / from the worker.
- * Events from in the worker can be observed / emitted via
- * worker.on / worker.emit.
- */
- get port() {
- // We generate dynamically this attribute as it needs to be accessible
- // before Worker.constructor gets called. (For ex: Panel)
-
- // create an event emitter that receive and send events from/to the worker
- let self = this;
- this._port = EventEmitterTrait.create({
- emit: function () self._emitEventToContent(Array.slice(arguments))
- });
-
- // expose wrapped port, that exposes only public properties:
- // We need to destroy this getter in order to be able to set the
- // final value. We need to update only public port attribute as we never
- // try to access port attribute from private API.
- delete this._public.port;
- this._public.port = Cortex(this._port);
- // Replicate public port to the private object
- delete this.port;
- this.port = this._public.port;
-
- return this._port;
- },
-
- /**
- * Same object than this.port but private API.
- * Allow access to _emit, in order to send event to port.
- */
- _port: null,
-
- /**
- * Emit a custom event to the content script,
- * i.e. emit this event on `self.port`
- */
- _emitEventToContent: function _emitEventToContent(args) {
- // We need to save events that are emitted before the worker is
- // initialized
- if (!this._inited) {
- this._earlyEvents.push(args);
- return;
- }
-
- if (this._frozen)
- throw new Error(ERR_FROZEN);
-
- // We throw exception when the worker has been destroyed
- if (!this._contentWorker) {
- throw new Error(ERR_DESTROYED);
- }
-
- // Forward the event to the WorkerSandbox object
- this._contentWorker.emit.apply(null, ["event"].concat(args));
- },
-
- // Is worker connected to the content worker sandbox ?
- _inited: false,
-
- // Is worker being frozen? i.e related document is frozen in bfcache.
- // Content script should not be reachable if frozen.
- _frozen: true,
-
- // List of custom events fired before worker is initialized
- get _earlyEvents() {
- delete this._earlyEvents;
- this._earlyEvents = [];
- return this._earlyEvents;
- },
-
- constructor: function Worker(options) {
- options = options || {};
-
- if ('window' in options)
- this._window = options.window;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScriptOptions' in options)
- this.contentScriptOptions = options.contentScriptOptions;
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('onError' in options)
- this.on('error', options.onError);
- if ('onMessage' in options)
- this.on('message', options.onMessage);
- if ('onDetach' in options)
- this.on('detach', options.onDetach);
-
- // Internal feature that is only used by SDK unit tests.
- // See `PRIVATE_KEY` definition for more information.
- if ('exposeUnlockKey' in options && options.exposeUnlockKey === PRIVATE_KEY)
- this._expose_key = true;
-
- // Track document unload to destroy this worker.
- // We can't watch for unload event on page's window object as it
- // prevents bfcache from working:
- // https://developer.mozilla.org/En/Working_with_BFCache
- this._windowID = this._window.
- QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).
- currentInnerWindowID;
- observers.add("inner-window-destroyed",
- this._documentUnload = this._documentUnload.bind(this));
-
- // Listen to pagehide event in order to freeze the content script
- // while the document is frozen in bfcache:
- this._window.addEventListener("pageshow",
- this._pageShow = this._pageShow.bind(this),
- true);
- this._window.addEventListener("pagehide",
- this._pageHide = this._pageHide.bind(this),
- true);
-
- unload.ensure(this._public, "destroy");
-
- // Ensure that worker._port is initialized for contentWorker to be able
- // to send use event during WorkerSandbox(this)
- this.port;
-
- // will set this._contentWorker pointing to the private API:
- this._contentWorker = WorkerSandbox(this);
-
- // Mainly enable worker.port.emit to send event to the content worker
- this._inited = true;
- this._frozen = false;
-
- // Flush all events that have been fired before the worker is initialized.
- this._earlyEvents.forEach((function (args) this._emitEventToContent(args)).
- bind(this));
- },
-
- _documentUnload: function _documentUnload(subject, topic, data) {
- let innerWinID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
- if (innerWinID != this._windowID) return false;
- this._workerCleanup();
- return true;
- },
-
- _pageShow: function _pageShow() {
- this._contentWorker.emitSync("pageshow");
- this._emit("pageshow");
- this._frozen = false;
- },
-
- _pageHide: function _pageHide() {
- this._contentWorker.emitSync("pagehide");
- this._emit("pagehide");
- this._frozen = true;
- },
-
- get url() {
- // this._window will be null after detach
- return this._window ? this._window.document.location.href : null;
- },
-
- get tab() {
- // this._window will be null after detach
- if (this._window)
- return getTabForWindow(this._window);
- return null;
- },
-
- /**
- * Tells content worker to unload itself and
- * removes all the references from itself.
- */
- destroy: function destroy() {
- this._workerCleanup();
- this._removeAllListeners();
- },
-
- /**
- * Remove all internal references to the attached document
- * Tells _port to unload itself and removes all the references from itself.
- */
- _workerCleanup: function _workerCleanup() {
- // maybe unloaded before content side is created
- // As Symbiont call worker.constructor on document load
- if (this._contentWorker)
- this._contentWorker.destroy();
- this._contentWorker = null;
- if (this._window) {
- this._window.removeEventListener("pageshow", this._pageShow, true);
- this._window.removeEventListener("pagehide", this._pageHide, true);
- }
- this._window = null;
- // This method may be called multiple times,
- // avoid dispatching `detach` event more than once
- if (this._windowID) {
- this._windowID = null;
- observers.remove("inner-window-destroyed", this._documentUnload);
- this._earlyEvents.slice(0, this._earlyEvents.length);
- this._emit("detach");
- }
- },
-
- /**
- * Receive an event from the content script that need to be sent to
- * worker.port. Provide a way for composed object to catch all events.
- */
- _onContentScriptEvent: function _onContentScriptEvent() {
- this._port._emit.apply(this._port, arguments);
- },
-
- /**
- * Reference to the content side of the worker.
- * @type {WorkerGlobalScope}
- */
- _contentWorker: null,
-
- /**
- * Reference to the window that is accessible from
- * the content scripts.
- * @type {Object}
- */
- _window: null,
-
- /**
- * Flag to enable `addon` object injection in document. (bug 612726)
- * @type {Boolean}
- */
- _injectInDocument: false
-});
-exports.Worker = Worker;