diff options
Diffstat (limited to 'tools/addon-sdk-1.5/packages/api-utils/docs/content')
4 files changed, 603 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.5/packages/api-utils/docs/content/loader.md b/tools/addon-sdk-1.5/packages/api-utils/docs/content/loader.md new file mode 100644 index 0000000..095e8c8 --- /dev/null +++ b/tools/addon-sdk-1.5/packages/api-utils/docs/content/loader.md @@ -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/. --> + +<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] --> + +Loader is base trait and it provides set of core properties and associated +validations. Trait is useful for all the compositions providing high level +APIs for creating JavaScript contexts that can access web content. + +Loader is composed from the +[EventEmitter](packages/api-utils/docs/events.html) trait, therefore +instances of Loader and their descendants expose all the public properties +exposed by EventEmitter along with additional public properties: + +Value changes on all of the above mentioned properties emit `propertyChange` +events on an instances. + +**Example:** + +The following code creates a wrapper on hidden frame that reloads a web page +in frame every time `contentURL` property is changed: + + var hiddenFrames = require("hidden-frame"); + var { Loader } = require("content"); + var PageLoader = Loader.compose({ + constructor: function PageLoader(options) { + options = options || {}; + if (options.contentURL) + this.contentURL = options.contentURL; + this.on('propertyChange', this._onChange = this._onChange.bind(this)); + let self = this; + hiddenFrames.add(hiddenFrames.HiddenFrame({ + onReady: function onReady() { + let frame = self._frame = this.element; + self._emit('propertyChange', { contentURL: self.contentURL }); + } + })); + }, + _onChange: function _onChange(e) { + if ('contentURL' in e) + this._frame.setAttribute('src', this._contentURL); + } + }); + +<api name="Loader"> +@class +<api name="contentScriptFile"> +@property {array} +The local file URLs of content scripts to load. Content scripts specified by +this property are loaded *before* those specified by the `contentScript` +property. +</api> + +<api name="contentScript"> +@property {array} +The texts of content scripts to load. Content scripts specified by this +property are loaded *after* those specified by the `contentScriptFile` property. +</api> + +<api name="contentScriptWhen"> +@property {string} +When to load the content scripts. This may take one of the following +values: + +* "start": load content scripts immediately after the document +element for the page is inserted into the DOM, but before the DOM content +itself has been loaded +* "ready": load content scripts once DOM content has been loaded, +corresponding to the +[DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events) +event +* "end": load content scripts once all the content (DOM, JS, CSS, +images) for the page has been loaded, at the time the +[window.onload event](https://developer.mozilla.org/en/DOM/window.onload) +fires + +</api> + +<api name="contentURL"> +@property {string} +The URL of the content loaded. +</api> + +<api name="allow"> +@property {object} +Permissions for the content, with the following keys: +@prop script {boolean} + Whether or not to execute script in the content. Defaults to true. +</api> +</api> + diff --git a/tools/addon-sdk-1.5/packages/api-utils/docs/content/proxy.md b/tools/addon-sdk-1.5/packages/api-utils/docs/content/proxy.md new file mode 100644 index 0000000..095e8ff --- /dev/null +++ b/tools/addon-sdk-1.5/packages/api-utils/docs/content/proxy.md @@ -0,0 +1,241 @@ +<!-- 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/. --> + +<!-- contributed by Alexandre Poirot [apoirot@mozilla.com] --> + +Content scripts need access to the DOM of the pages they are attached to. +However, those pages should be considered to be hostile environments: we +have no control over any other scripts loaded by the web page that may be +executing in the same context. If the content scripts and scripts loaded +by the web page were to access the same DOM objects, there are two possible +security problems: + +First, a malicious page might redefine functions and properties of DOM +objects so they don't do what the add-on expects. For example, if a +content script calls `document.getElementById()` to retrieve a DOM +element, then a malicious page could redefine its behavior to return +something unexpected: + +<pre><code> +// If the web document contains the following script: +document.getElementById = function (str) { + // Overload indexOf method of all string instances + str.__proto__.indexOf = function () {return -1;}; + // Overload toString method of all object instances + str.__proto__.__proto__.toString = function () {return "evil";}; +}; +// After the following line, the content script will be compromised: +var node = document.getElementById("element"); +// Then your content script is totally out of control. +</code></pre> + +Second, changes the content script made to the DOM objects would be visible +to the page, leaking information to it. + +The general approach to fixing these problems is to wrap DOM objects in +[`XrayWrappers`](https://developer.mozilla.org/en/XPCNativeWrapper) +(also know as `XPCNativeWrapper`). This guarantees that: + +* when the content script accesses DOM properties and functions it gets the +original native version of them, ignoring any modifications made by the web +page +* changes to the DOM made by the content script are not visible to scripts +running in the page. + +However, `XrayWrapper` has some limitations and bugs, which break many +popular web frameworks. In particular, you can't: + +* define attributes like `onclick`: you have to use `addEventListener` syntax +* overload native methods on DOM objects, like this: +<pre><code> +proxy.addEventListener = function () {}; +</code></pre> +* access named elements using properties like `window[framename]` or +`document[formname]` +* use some other features that have bugs in the `XrayWrapper` +implementation, like `mozMatchesSelector` + +The `proxy` module uses `XrayWrapper` in combination with the +experimental +[Proxy API](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Proxy) +to address both the security vulnerabilities of content scripts and the +limitations of `XrayWrapper`. + +<pre> + /--------------------\ /------------------------\ + | Web document | | Content script sandbox | + | http://mozilla.org | | data/worker.js | + | | require('content-proxy'). | | + | window >-----------|- create(window) -|-> window | + \--------------------/ \------------------------/ +</pre> + + +## The Big Picture ## + +The implementation defines two different kinds of proxy: + + 1. Content script proxies that wrap DOM objects that are exposed to + content scripts as described above. + 2. XrayWrapper proxies that wrap objects from content scripts before handing + them over to XrayWrapper functions. These proxies are internal + and are not exposed to content scripts or document content. + +<pre> + /--------------------\ /------------------------\ + | Web document | | Content script sandbox | + | http://mozilla.org | | data/worker.js | + | | /-------|-> myObject = {} | + | | /----------------v--\ | | + | | | XrayWrapper Proxy | | - document | + | | \---------v---------/ \----^-------------------/ + | | v | + | | /-------------\ /----------\ | + | - document >-------|->| XrayWrapper |<-| CS proxy |-/ + \--------------------/ \-------------/ \----------/ +</pre> + +Everything begins with a single call to the `create` function exported by the +content-proxy module: + + // Retrieve the unwrapped reference to the current web page window object + var win = gBrowser.contentDocument.defaultView.wrappedJSObject; + // Or in addon sdk style + var win = require("tab-browser").activeTab.linkedBrowser.contentWindow.wrappedJSObject; + // Now create a content script proxy for the window object + var windowProxy = require("api-utils/content/content-proxy").create(win); + + // We finally use this window object as sandbox prototype, + // so that all web page globals are accessible in CS too: + var contentScriptSandbox = new Cu.Sandbox(win, { + sandboxPrototype: windowProxy + }); + +Then all other proxies are created from this one. Attempts to access DOM +attributes of this proxy are trapped, and the proxy constructs and returns +content script proxies for those attributes: + + // For example, if you simply do this: + var document = window.document; + // accessing the `document` attribute will be trapped by the `window` content script + // proxy, and that proxy will that create another content script proxy for `document` + +So the main responsibility of the content script proxy implementation is to +ensure that we always return content script proxies to the content script. + +## Internal Implementation ## + +Each content script proxy keeps a reference to the `XrayWrapper` that enables +it to be sure of calling native DOM methods. + +There are two internal functions to convert between content script proxy +values and `XrayWrapper` values. + +1. __`wrap`__ takes an XrayWrapper value and wraps it in a content script +proxy if needed. + This method is called when: + * a content script accesses an attribute of a content script proxy. + * XrayWrapper code calls a callback function defined in the content +script, so that arguments passed into the function by the XrayWrapper are +converted into content script proxies. For example, if a content script +calls `addEventListener`, then the listener function will expect any arguments +to be content script proxies. +<br/><br/> +2. __`unwrap`__ takes an object coming from the content script context and: + * if the object is a content script proxy, unwraps it back to an +XrayWrapper reference + * if the object is not a content script proxy, wraps it in an XrayWrapper +proxy. +<br/><br/> +This means we can call a XrayWrapper method either with: + + * a raw XrayWrapper object. + + // The following line doesn't work if child is a content script proxy, + // it has to be a raw XrayWrapper reference + xrayWrapper.appendChild(child) + + * an XrayWrapper proxy when you pass a custom object from the content +script context. + + var myListener = { + handleEvent: function(event) { + // `event` should be a content script proxy + } + }; + // `myListener` has to be another kind of Proxy: XrayWrapper proxy, + // that aims to catch the call to `handleEvent` in order to wrap its + // arguments in a content script proxy. + xrayWrapper.addEventListener("click", myListener, false); + + +## Stack Traces ## + +The following code: + + function listener(event) { + + } + csProxy.addEventListener("message", listener, false); + +generates the following internal calls: + + -> CS Proxy:: get("addEventListener") + -> wrap(xrayWrapper.addEventListener) + -> NativeFunctionWrapper(xrayWrapper.addEventListener) + // NativeFunctionWrapper generates: + function ("message", listener, false) { + return xraywrapper.addEventListener("message", unwrap(listener), false); + } + -> unwrap(listener) + -> ContentScriptFunctionWrapper(listener) + // ContentScriptFunctionWrapper generates: + function (event) { + return listener(wrap(event)); + } + +<br> + + // First, create an object from content script context + var myListener = { + handleEvent: function (event) { + + } + }; + // Then, pass this object as an argument to a CS proxy method + window.addEventListener("message", myListener, false); + + // Generates the following internal calls: + -> CS Proxy:: get("addEventListener") + -> wrap(xrayWrapper.addEventListener) + -> NativeFunctionWrapper(xrayWrapper.addEventListener) + // Generate the following function: + function ("message", myListener, false) { + return xraywrapper.addEventListener("message", unwrap(myListener), false); + } + -> unwrap(myListener) + -> ContentScriptObjectWrapper(myListener) + // Generate an XrayWrapper proxy and give it to xrayWrapper method. + // Then when native code fires an event, the proxy will catch it: + -> XrayWrapper Proxy:: get("handleEvent") + -> unwrap(myListener.handleEvent) + -> ContentScriptFunctionWrapper(myListener.handleEvent) + // Generate following function: + function (event) { + return myListener.handleEvent(wrap(event)); + } + + +<api name="create"> +@function + Create a content script proxy. <br/> + Doesn't create a proxy if we are not able to create a XrayWrapper for + this object: for example, if the object comes from system principal. + +@param object {Object} + The object to proxify. + +@returns {Object} + A content script proxy that wraps `object`. +</api> diff --git a/tools/addon-sdk-1.5/packages/api-utils/docs/content/symbiont.md b/tools/addon-sdk-1.5/packages/api-utils/docs/content/symbiont.md new file mode 100644 index 0000000..3036c6d --- /dev/null +++ b/tools/addon-sdk-1.5/packages/api-utils/docs/content/symbiont.md @@ -0,0 +1,140 @@ +<!-- 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/. --> + +<!-- contributed by Myk Melez [myk@mozilla.org] --> +<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] --> + + +This module is not intended to be used directly by programs. Rather, it is +intended to be used by other modules that provide APIs to programs. + + +This module exports `Symbiont` trait that can be used for creating JavaScript +contexts that can access web content in host application frames (i.e. XUL +`<iframe>` and `<browser>` elements) and communicate with programs via +asynchronous JSON pipes. It is useful in the construction of APIs that +are compatible with the execution model codenamed "electrolysis" in which +programs run in separate processes from web content. + +Introduction +------------ + +`Symbiont` constructs a content symbiont for a given frame, it loads the +specified contentURL and scripts into it, and plumbs an asynchronous +JSON pipe between the content symbiont object and the content symbiont +context. If frame is not provided hidden frame will be created. + +Examples +-------- + + var { Symbiont } = require('content'); + var Thing = Symbiont.resolve({ constructor: '_init' }).compose({ + constructor: function Thing(options) { + // `getMyFrame` returns the host application frame in which + // the page is loaded. + this._frame = getMyFrame(); + this._init(options) + } + }); + +See the [panel][] module for a real-world example of usage of this module. + +[panel]:packages/addon-kit/docs/panel.html + +Reference +--------- + +<api name="Symbiont"> +@class +Symbiont is composed from the [Worker][] trait, therefore instances +of Symbiont and their descendants expose all the public properties +exposed by [Worker][] along with additional public properties that +are listed below: + +[Worker]:packages/api-utils/docs/content/worker.html + +<api name="Symbiont"> +@constructor +Creates a content symbiont. +@param options {object} + Options for the constructor. Includes all the keys that +the [Worker](packages/api-utils/docs/content/worker.html) +constructor accepts and a few more: + + @prop [frame] {object} + The host application frame in which the page is loaded. + If frame is not provided hidden one will be created. + @prop [contentScriptWhen="end"] {string} + When to load the content scripts. This may take one of the following + values: + + * "start": load content scripts immediately after the document + element for the page is inserted into the DOM, but before the DOM content + itself has been loaded + * "ready": load content scripts once DOM content has been loaded, + corresponding to the + [DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events) + event + * "end": load content scripts once all the content (DOM, JS, CSS, + images) for the page has been loaded, at the time the + [window.onload event](https://developer.mozilla.org/en/DOM/window.onload) + fires + + This property is optional and defaults to "end". + + @prop [allow] {object} + Permissions for the content, with the following keys: + @prop [script] {boolean} + Whether or not to execute script in the content. Defaults to true. + Optional. + Optional. +</api> + +<api name="contentScriptFile"> +@property {array} +The local file URLs of content scripts to load. Content scripts specified by +this property are loaded *before* those specified by the `contentScript` +property. +</api> + +<api name="contentScript"> +@property {array} +The texts of content scripts to load. Content scripts specified by this +property are loaded *after* those specified by the `contentScriptFile` property. +</api> + +<api name="contentScriptWhen"> +@property {string} +When to load the content scripts. This may have one of the following +values: + +* "start": load content scripts immediately after the document +element for the page is inserted into the DOM, but before the DOM content +itself has been loaded +* "ready": load content scripts once DOM content has been loaded, +corresponding to the +[DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events) +event +* "end": load content scripts once all the content (DOM, JS, CSS, +images) for the page has been loaded, at the time the +[window.onload event](https://developer.mozilla.org/en/DOM/window.onload) +fires + +</api> + +<api name="contentURL"> +@property {string} +The URL of the content loaded. +</api> + +<api name="allow"> +@property {object} +Permissions for the content, with a single boolean key called `script` which +defaults to true and indicates whether or not to execute scripts in the +content. +</api> + +</api> + + diff --git a/tools/addon-sdk-1.5/packages/api-utils/docs/content/worker.md b/tools/addon-sdk-1.5/packages/api-utils/docs/content/worker.md new file mode 100644 index 0000000..8705632 --- /dev/null +++ b/tools/addon-sdk-1.5/packages/api-utils/docs/content/worker.md @@ -0,0 +1,130 @@ +<!-- 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/. --> + +<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] --> + +This module exports the `Worker` trait, which may be used to construct objects +implementing the [Worker][] interface defined by the W3C, with minor +differences. + +Content workers are message-passing facilities for communication between +[content scripts](dev-guide/addon-development/web-content.html) and the main +add-on code. + +It is important to note that unlike "web workers," these workers run in the +same process as web content and browser chrome, so code within workers can +block the UI. + +[Worker]:http://www.w3.org/TR/workers/#worker + +<api name="Worker"> +@class +Worker is composed from the [EventEmitter][] trait, therefore instances +of Worker and their descendants expose all the public properties +exposed by [EventEmitter][] along with additional public properties that +are listed below. + +**Example** + + var workers = require("content/worker"); + let worker = workers.Worker({ + window: require("window-utils").activeWindow, + contentScript: + "self.port.on('hello', function(name) { " + + " self.port.emit('response', window.location); " + + "});" + }); + worker.port.emit("hello", { name: "worker"}); + worker.port.on("response", function (location) { + console.log(location); + }); + +[EventEmitter]:packages/api-utils/docs/events.html + +<api name="Worker"> +@constructor +Creates a content worker. +@param options {object} +Options for the constructor, with the following keys: + @prop window {object} + The content window to create JavaScript sandbox for communication with. + @prop [contentScriptFile] {string,array} + The local file URLs of content scripts to load. Content scripts specified + by this option are loaded *before* those specified by the `contentScript` + option. Optional. + @prop [contentScript] {string,array} + The texts of content scripts to load. Content scripts specified by this + option are loaded *after* those specified by the `contentScriptFile` option. + Optional. + @prop [onMessage] {function} + Functions that will registered as a listener to a 'message' events. + @prop [onError] {function} + Functions that will registered as a listener to an 'error' events. +</api> + +<api name="port"> +@property {EventEmitter} +[EventEmitter](packages/api-utils/docs/events.html) object that allows you to: + +* send customized messages to the worker using the `port.emit` function +* receive events from the worker using the `port.on` function + +</api> + +<api name="postMessage"> +@method +Asynchronously emits `"message"` events in the enclosed worker, where content +script was loaded. +@param data {number,string,JSON} +The data to send. Must be stringifiable to JSON. +</api> + +<api name="destroy"> +@method +Destroy the worker by removing the content script from the page and removing +all registered listeners. A `detach` event is fired just before removal. +</api> + +<api name="url"> +@property {string} +The URL of the content. +</api> + +<api name="tab"> +@property {object} +If this worker is attached to a content document, returns the related +[tab](packages/addon-kit/docs/tabs.html). +</api> + +<api name="message"> +@event +This event allows the content worker to receive messages from its associated +content scripts. Calling the `self.postMessage()` function from a content +script will asynchronously emit the `message` event on the corresponding +worker. + +@argument {value} +The event listener is passed the message, which must be a +<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>. +</api> + +<api name="error"> +@event +This event allows the content worker to react to an uncaught runtime script +error that occurs in one of the content scripts. + +@argument {Error} +The event listener is passed a single argument which is an +[Error](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error) +object. +</api> + +<api name="detach"> +@event +This event is emitted when the document associated with this worker is unloaded +or the worker's `destroy()` method is called. +</api> + +</api> + |