aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.4/packages/addon-kit
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.4/packages/addon-kit')
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/README.md8
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/moz_favicon.icobin1406 -> 0 bytes
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test-page-mod.html8
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.html8
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.js25
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test-request-invalid.json1
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test-request.json1
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test-request.txt1
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/data/test.html8
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/clipboard.md58
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/context-menu.md702
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/hotkeys.md74
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/notifications.md60
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/page-mod.md367
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/page-worker.md218
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/panel.md301
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/passwords.md564
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/private-browsing.md46
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/request.md192
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/selection.md86
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/self.md73
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/simple-prefs.md70
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/simple-storage.md125
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/tabs.md381
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/timers.md48
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/widget.md692
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/docs/windows.md187
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/clipboard.js266
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/context-menu.js1526
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/hotkeys.js71
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/notifications.js112
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/page-mod.js229
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/page-worker.js101
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/panel.js403
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/passwords.js92
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/private-browsing.js102
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/request.js309
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/selection.js448
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/simple-prefs.js107
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/simple-storage.js263
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/tabs.js62
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/timers.js40
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/widget.js947
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/lib/windows.js238
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/package.json12
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/helpers.js19
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/pagemod-test-helpers.js63
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-clipboard.js60
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.html78
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.js2075
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-hotkeys.js156
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-module.js33
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-notifications.js79
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-mod.js416
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-worker.js362
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-panel.js437
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-passwords.js277
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-private-browsing.js238
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-request.js358
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-selection.js490
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-prefs.js180
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-storage.js346
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-tabs.js905
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-timers.js44
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-widget.js950
-rw-r--r--tools/addon-sdk-1.4/packages/addon-kit/tests/test-windows.js342
66 files changed, 0 insertions, 17540 deletions
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/README.md b/tools/addon-sdk-1.4/packages/addon-kit/README.md
deleted file mode 100644
index 9a68554..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-The addon-kit package provides high-level APIs for add-on developers.
-Most of the needs of most add-on developers should be served by the modules
-found here. Modules in this packages don't require any special privileges to
-run.
-
-The modules in the addon-kit package are relatively stable. We intend to add
-new APIs here and extend existing ones, but will avoid making incompatible
-changes to them unless absolutely necessary.
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/moz_favicon.ico b/tools/addon-sdk-1.4/packages/addon-kit/data/moz_favicon.ico
deleted file mode 100644
index d444389..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/moz_favicon.ico
+++ /dev/null
Binary files differ
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-mod.html b/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-mod.html
deleted file mode 100644
index 9211698..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-mod.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
- <title>Page Mod test</title>
-</head>
-<body>
- <p id="paragraph">Lorem ipsum dolor sit amet.</p>
-</body>
-</html>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.html b/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.html
deleted file mode 100644
index e89a283..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
- <title>Page Worker test</title>
-</head>
-<body>
- <p id="paragraph">Lorem ipsum dolor sit amet.</p>
-</body>
-</html>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.js b/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.js
deleted file mode 100644
index d8effb9..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test-page-worker.js
+++ /dev/null
@@ -1,25 +0,0 @@
-
-// get title directly
-self.postMessage(["assertEqual", document.title, "Page Worker test",
- "Correct page title accessed directly"]);
-
-// get <p> directly
-let p = document.getElementById("paragraph");
-self.postMessage(["assert", !!p, "<p> can be accessed directly"]);
-self.postMessage(["assertEqual", p.firstChild.nodeValue,
- "Lorem ipsum dolor sit amet.",
- "Correct text node expected"]);
-
-// Modify page
-let div = document.createElement("div");
-div.setAttribute("id", "block");
-div.appendChild(document.createTextNode("Test text created"));
-document.body.appendChild(div);
-
-// Check back the modification
-div = document.getElementById("block");
-self.postMessage(["assert", !!div, "<div> can be accessed directly"]);
-self.postMessage(["assertEqual", div.firstChild.nodeValue,
- "Test text created", "Correct text node expected"]);
-self.postMessage(["done"]);
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test-request-invalid.json b/tools/addon-sdk-1.4/packages/addon-kit/data/test-request-invalid.json
deleted file mode 100644
index 35f9ff6..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test-request-invalid.json
+++ /dev/null
@@ -1 +0,0 @@
-"this": "isn't JSON"
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test-request.json b/tools/addon-sdk-1.4/packages/addon-kit/data/test-request.json
deleted file mode 100644
index 8c850a5..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test-request.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "foo": "bar" }
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test-request.txt b/tools/addon-sdk-1.4/packages/addon-kit/data/test-request.txt
deleted file mode 100644
index 390125d..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test-request.txt
+++ /dev/null
@@ -1 +0,0 @@
-Look ma, no hands!
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/data/test.html b/tools/addon-sdk-1.4/packages/addon-kit/data/test.html
deleted file mode 100644
index 39de477..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/data/test.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
- <head>
- <title>foo</title>
- </head>
- <body>
- <p>bar</p>
- </body>
-</html>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/clipboard.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/clipboard.md
deleted file mode 100644
index 7292017..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/clipboard.md
+++ /dev/null
@@ -1,58 +0,0 @@
-<!-- contributed by Dietrich Ayala [dietrich@mozilla.com] -->
-
-The `clipboard` module allows callers to interact with the system clipboard,
-setting and retrieving its contents.
-
-You can optionally specify the type of the data to set and retrieve.
-The following types are supported:
-
-* `text` (plain text)
-* `html` (a string of HTML)
-
-If no data type is provided, then the module will detect it for you.
-
-Examples
---------
-
-Set and get the contents of the clipboard.
-
- let clipboard = require("clipboard");
- clipboard.set("Lorem ipsum dolor sit amet");
- let contents = clipboard.get();
-
-Set the clipboard contents to some HTML.
-
- let clipboard = require("clipboard");
- clipboard.set("<blink>Lorem ipsum dolor sit amet</blink>", "html");
-
-If the clipboard contains HTML content, open it in a new tab.
-
- let clipboard = require("clipboard");
- if (clipboard.currentFlavors.indexOf("html") != -1)
- require("tabs").open("data:text/html," + clipboard.get("html"));
-
-<api name="set">
-@function
- Replace the contents of the user's clipboard with the provided data.
-@param data {string}
- The data to put on the clipboard.
-@param [datatype] {string}
- The type of the data (optional).
-</api>
-
-<api name="get">
-@function
- Get the contents of the user's clipboard.
-@param [datatype] {string}
- Retrieve the clipboard contents only if matching this type (optional).
- The function will return null if the contents of the clipboard do not match
- the supplied type.
-</api>
-
-<api name="currentFlavors">
-@property {array}
- Data on the clipboard is sometimes available in multiple types. For example,
- HTML data might be available as both a string of HTML (the `html` type)
- and a string of plain text (the `text` type). This function returns an array
- of all types in which the data currently on the clipboard is available.
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/context-menu.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/context-menu.md
deleted file mode 100644
index f2bb5b3..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/context-menu.md
+++ /dev/null
@@ -1,702 +0,0 @@
-<!-- contributed by Drew Willcoxon [adw@mozilla.com] -->
-<!-- edited by Noelle Murata [fiveinchpixie@gmail.com] -->
-
-The `context-menu` module lets you add items to Firefox's page context menu.
-
-
-Introduction
-------------
-
-The `context-menu` API provides a simple, declarative way to add items to the
-page's context menu. You can add items that perform an action when clicked,
-submenus, and menu separators.
-
-Instead of manually adding items when particular contexts occur and then
-removing them when those contexts go away, you *bind* items to contexts, and the
-adding and removing is automatically handled for you. Items are bound to
-contexts in much the same way that event listeners are bound to events. When
-the user invokes the context menu, all of the items bound to the current context
-are automatically added to the menu. If no items are bound, none are added.
-Likewise, any items that were previously in the menu but are not bound to the
-current context are automatically removed from the menu. You never need to
-manually remove your items from the menu unless you want them to never appear
-again.
-
-For example, if your add-on needs to add a context menu item whenever the
-user visits a certain page, don't create the item when that page loads, and
-don't remove it when the page unloads. Rather, create your item only once and
-supply a context that matches the target URL.
-
-
-Specifying Contexts
--------------------
-
-As its name implies, the context menu should be reserved for the occurrence of
-specific contexts. Contexts can be related to page content or the page itself,
-but they should never be external to the page.
-
-For example, a good use of the menu would be to show an "Edit Image" item when
-the user right-clicks an image in the page. A bad use would be to show a
-submenu that listed all the user's tabs, since tabs aren't related to the page
-or the node the user clicked to open the menu.
-
-### The Page Context
-
-First of all, you may not need to specify a context at all. When an item does
-not specify a context, the page context applies.
-
-The *page context* occurs when the user invokes the context menu on a
-non-interactive portion of the page. Try right-clicking a blank spot in this
-page, or on text. Make sure that no text is selected. The menu that appears
-should contain the items "Back", "Forward", "Reload", "Stop", and so on. This
-is the page context.
-
-The page context is appropriate when your item acts on the page as a whole. It
-does not occur when the user invokes the context menu on a link, image, or other
-non-text node, or while a selection exists.
-
-### Declarative Contexts
-
-You can specify some simple, declarative contexts when you create a menu item by
-setting the `context` property of the options object passed to its constructor,
-like this:
-
- var cm = require("context-menu");
- cm.Item({
- label: "My Menu Item",
- context: cm.URLContext("*.mozilla.org")
- });
-
-These contexts may be specified by calling the following constructors. Each is
-exported by the `context-menu` module.
-
-<table>
- <tr>
- <th>Constructor</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>
- PageContext()
- </code></td>
- <td>
- The page context.
- </td>
- </tr>
- <tr>
- <td><code>
- SelectionContext()
- </code></td>
- <td>
- This context occurs when the menu is invoked on a page in which the user
- has made a selection.
- </td>
- </tr>
- <tr>
- <td><code>
- SelectorContext(selector)
- </code></td>
- <td>
- This context occurs when the menu is invoked on a node that either matches
- <code>selector</code>, a CSS selector, or has an ancestor that matches.
- <code>selector</code> may include multiple selectors separated by commas,
- e.g., <code>"a[href], img"</code>.
- </td>
- </tr>
- <tr>
- <td><code>
- URLContext(matchPattern)
- </code></td>
- <td>
- This context occurs when the menu is invoked on pages with particular
- URLs. <code>matchPattern</code> is a match pattern string or an array of
- match pattern strings. When <code>matchPattern</code> is an array, the
- context occurs when the menu is invoked on a page whose URL matches any of
- the patterns. These are the same match pattern strings that you use with
- the <a href="packages/addon-kit/docs/page-mod.html"><code>page-mod</code></a>
- <code>include</code> property.
- <a href="packages/api-utils/docs/match-pattern.html">Read more about patterns</a>.
- </td>
- </tr>
- <tr>
- <td>
- array
- </td>
- <td>
- An array of any of the other types. This context occurs when all contexts
- in the array occur.
- </td>
- </tr>
-</table>
-
-Menu items also have a `context` property that can be used to add and remove
-declarative contexts after construction. For example:
-
- var context = require("context-menu").SelectorContext("img");
- myMenuItem.context.add(context);
- myMenuItem.context.remove(context);
-
-When a menu item is bound to more than one context, it appears in the menu when
-all of those contexts occur.
-
-### In Content Scripts
-
-The declarative contexts are handy but not very powerful. For instance, you
-might want your menu item to appear for any page that has at least one image,
-but declarative contexts won't help you there.
-
-When you need more control control over the context in which your menu items are
-shown, you can use content scripts. Like other APIs in the SDK, the
-`context-menu` API uses
-[content scripts](dev-guide/addon-development/web-content.html) to let your
-add-on interact with pages in the browser. Each menu item you create in the
-top-level context menu can have a content script.
-
-A special event named `"context"` is emitted in your content scripts whenever
-the context menu is about to be shown. If you register a listener function for
-this event and it returns true, the menu item associated with the listener's
-content script is shown in the menu.
-
-For example, this item appears whenever the context menu is invoked on a page
-that contains at least one image:
-
- require("context-menu").Item({
- label: "This Page Has Images",
- contentScript: 'self.on("context", function (node) {' +
- ' return !!document.querySelector("img");' +
- '});'
- });
-
-Note that the listener function has a parameter called `node`. This is the node
-in the page that the user context-clicked to invoke the menu. You can use it to
-determine whether your item should be shown.
-
-You can both specify declarative contexts and listen for contexts in a content
-script. In that case, the declarative contexts are evaluated first. If they
-are not current, then your context listener is never called.
-
-This example takes advantage of that fact. The listener can be assured that
-`node` will always be an image:
-
- require("context-menu").Item({
- label: "A Mozilla Image",
- context: contextMenu.SelectorContext("img"),
- contentScript: 'self.on("context", function (node) {' +
- ' return /mozilla/.test(node.src);' +
- '});'
- });
-
-Your item is shown only when all declarative contexts are current and your
-context listener returns true.
-
-
-Handling Menu Item Clicks
--------------------------
-
-In addition to using content scripts to listen for the `"context"` event as
-described above, you can use content scripts to handle item clicks. When the
-user clicks your menu item, an event named `"click"` is emitted in the item's
-content script.
-
-Therefore, to handle an item click, listen for the `"click"` event in that
-item's content script like so:
-
- require("context-menu").Item({
- label: "My Item",
- contentScript: 'self.on("click", function (node, data) {' +
- ' console.log("Item clicked!");' +
- '});'
- });
-
-Note that the listener function has parameters called `node` and `data`. `node`
-is the node that the user context-clicked to invoke the menu. You can use it
-when performing some action. `data` is the `data` property of the menu item
-that was clicked. Since only top-level menu items have content scripts, this
-comes in handy for determining which item in a `Menu` was clicked:
-
- var cm = require("context-menu");
- cm.Menu({
- label: "My Menu",
- contentScript: 'self.on("click", function (node, data) {' +
- ' console.log("You clicked " + data);' +
- '});',
- items: [
- cm.Item({ label: "Item 1", data: "item1" }),
- cm.Item({ label: "Item 2", data: "item2" }),
- cm.Item({ label: "Item 3", data: "item3" })
- ]
- });
-
-Often you will need to collect some kind of information in the click listener
-and perform an action unrelated to content. To communicate to the menu item
-associated with the content script, the content script can call the
-`postMessage` function attached to the global `self` object, passing it some
-JSON-able data. The menu item's `"message"` event listener will be called with
-that data.
-
- require("context-menu").Item({
- label: "Edit Image",
- context: contextMenu.SelectorContext("img"),
- contentScript: 'self.on("click", function (node, data) {' +
- ' self.postMessage(node.src);' +
- '});',
- onMessage: function (imgSrc) {
- openImageEditor(imgSrc);
- }
- });
-
-
-Updating a Menu Item's Label
-----------------------------
-
-Each menu item must be created with a label, but you can change its label later
-using a couple of methods.
-
-The simplest method is to set the menu item's `label` property. This example
-updates the item's label based on the number of times it's been clicked:
-
- var numClicks = 0;
- var myItem = require("context-menu").Item({
- label: "Click Me: " + numClicks,
- contentScript: 'self.on("click", self.postMessage);',
- onMessage: function () {
- numClicks++;
- this.label = "Click Me: " + numClicks;
- // Setting myItem.label is equivalent.
- }
- });
-
-Sometimes you might want to update the label based on the context. For
-instance, if your item performs a search with the user's selected text, it would
-be nice to display the text in the item to provide feedback to the user. In
-these cases you can use the second method. Recall that your content scripts can
-listen for the `"context"` event and if your listeners return true, the items
-associated with the content scripts are shown in the menu. In addition to
-returning true, your `"context"` listeners can also return strings. When a
-`"context"` listener returns a string, it becomes the item's new label.
-
-This item implements the aforementioned search example:
-
- var cm = require("context-menu");
- cm.Item({
- label: "Search Google",
- context: cm.SelectionContext(),
- contentScript: 'self.on("context", function () {' +
- ' var text = window.getSelection().toString();' +
- ' if (text.length > 20)' +
- ' text = text.substr(0, 20) + "...";' +
- ' return "Search Google for " + text;' +
- '});'
- });
-
-The `"context"` listener gets the window's current selection, truncating it if
-it's too long, and includes it in the returned string. When the item is shown,
-its label will be "Search Google for `text`", where `text` is the truncated
-selection.
-
-
-More Examples
--------------
-
-For conciseness, these examples create their content scripts as strings and use
-the `contentScript` property. In your own add-on, you will probably want to
-create your content scripts in separate files and pass their URLs using the
-`contentScriptFile` property. See
-[Working with Content Scripts](dev-guide/addon-development/web-content.html)
-for more information.
-
-Show an "Edit Page Source" item when the user right-clicks a non-interactive
-part of the page:
-
- require("context-menu").Item({
- label: "Edit Page Source",
- contentScript: 'self.on("click", function (node, data) {' +
- ' self.postMessage(document.URL);' +
- '});',
- onMessage: function (pageURL) {
- editSource(pageURL);
- }
- });
-
-Show an "Edit Image" item when the menu is invoked on an image:
-
- require("context-menu").Item({
- label: "Edit Image",
- context: contextMenu.SelectorContext("img"),
- contentScript: 'self.on("click", function (node, data) {' +
- ' self.postMessage(node.src);' +
- '});',
- onMessage: function (imgSrc) {
- openImageEditor(imgSrc);
- }
- });
-
-Show an "Edit Mozilla Image" item when the menu is invoked on an image in a
-mozilla.org or mozilla.com page:
-
- var cm = require("context-menu");
- cm.Item({
- label: "Edit Mozilla Image",
- context: [
- cm.URLContext(["*.mozilla.org", "*.mozilla.com"]),
- cm.SelectorContext("img")
- ],
- contentScript: 'self.on("click", function (node, data) {' +
- ' self.postMessage(node.src);' +
- '});',
- onMessage: function (imgSrc) {
- openImageEditor(imgSrc);
- }
- });
-
-Show an "Edit Page Images" item when the page contains at least one image:
-
- require("context-menu").Item({
- label: "Edit Page Images",
- // This ensures the item only appears during the page context.
- context: contextMenu.PageContext(),
- contentScript: 'self.on("context", function (node) {' +
- ' var pageHasImgs = !!document.querySelector("img");' +
- ' return pageHasImgs;' +
- '});' +
- 'self.on("click", function (node, data) {' +
- ' var imgs = document.querySelectorAll("img");' +
- ' var imgSrcs = [];' +
- ' for (var i = 0 ; i < imgs.length; i++)' +
- ' imgSrcs.push(imgs[i].src);' +
- ' self.postMessage(imgSrcs);' +
- '});',
- onMessage: function (imgSrcs) {
- openImageEditor(imgSrcs);
- }
- });
-
-Show a "Search With" menu when the user right-clicks an anchor that searches
-Google or Wikipedia with the text contained in the anchor:
-
- var cm = require("context-menu");
- var googleItem = cm.Item({
- label: "Google",
- data: "http://www.google.com/search?q="
- });
- var wikipediaItem = cm.Item({
- label: "Wikipedia",
- data: "http://en.wikipedia.org/wiki/Special:Search?search="
- });
- var searchMenu = cm.Menu({
- label: "Search With",
- context: contextMenu.SelectorContext("a[href]"),
- contentScript: 'self.on("click", function (node, data) {' +
- ' var searchURL = data + node.textContent;' +
- ' window.location.href = searchURL;' +
- '});',
- items: [googleItem, wikipediaItem]
- });
-
-
-<api name="Item">
-@class
-A labeled menu item that can perform an action when clicked.
-<api name="Item">
-@constructor
- Creates a labeled menu item that can perform an action when clicked.
-@param options {object}
- An object with the following keys:
- @prop label {string}
- The item's label. It must either be a string or an object that implements
- `toString()`.
- @prop [image] {string}
- The item's icon, a string URL. The URL can be remote, a reference to an
- image in the add-on's `data` directory, or a data URI.
- @prop [data] {string}
- An optional arbitrary value to associate with the item. It must be either a
- string or an object that implements `toString()`. It will be passed to
- click listeners.
- @prop [context] {value}
- If the item is contained in the top-level context menu, this declaratively
- specifies the context under which the item will appear; see Specifying
- Contexts above. Ignored if the item is contained in a submenu.
- @prop [contentScript] {string,array}
- If the item is contained in the top-level context menu, this is the content
- script or an array of content scripts that the item can use to interact with
- the page. Ignored if the item is contained in a submenu.
- @prop [contentScriptFile] {string,array}
- If the item is contained in the top-level context menu, this is the local
- file URL of the content script or an array of such URLs that the item can
- use to interact with the page. Ignored if the item is contained in a
- submenu.
- @prop [onMessage] {function}
- If the item is contained in the top-level context menu, this function will
- be called when the content script calls `self.postMessage`. It will be
- passed the data that was passed to `postMessage`. Ignored if the item is
- contained in a submenu.
-</api>
-
-<api name="label">
-@property {string}
- The menu item's label. You can set this after creating the item to update its
- label later.
-</api>
-
-<api name="image">
-@property {string}
- The item's icon, a string URL. The URL can be remote, a reference to an image
- in the add-on's `data` directory, or a data URI. You can set this after
- creating the item to update its image later. To remove the item's image, set
- it to `null`.
-</api>
-
-<api name="data">
-@property {string}
- An optional arbitrary value to associate with the item. It must be either a
- string or an object that implements `toString()`. It will be passed to
- click listeners. You can set this after creating the item to update its data
- later.
-</api>
-
-<api name="context">
-@property {list}
- A list of declarative contexts for which the menu item will appear in the
- context menu. Contexts can be added by calling `context.add()` and removed by
- called `context.remove()`. This property is meaningful only for items
- contained in the top-level context menu.
-</api>
-
-<api name="parentMenu">
-@property {Menu}
- The item's parent `Menu`, or `null` if the item is contained in the top-level
- context menu. This property is read-only. To add the item to a new menu,
- call that menu's `addItem()` method.
-</api>
-
-<api name="contentScript">
-@property {string,array}
- The content script or the array of content scripts associated with the menu
- item during creation. This property is meaningful only for items contained in
- the top-level context menu.
-</api>
-
-<api name="contentScriptFile">
-@property {string,array}
- The URL of a content script or the array of such URLs associated with the menu
- item during creation. This property is meaningful only for items contained in
- the top-level context menu.
-</api>
-
-<api name="destroy">
-@method
- Permanently removes the item from its parent menu and frees its resources.
- The item must not be used afterward. If you need to remove the item from its
- parent menu but use it afterward, call `removeItem()` on the parent menu
- instead.
-</api>
-
-<api name="message">
-@event
-If you listen to this event you can receive message events from content
-scripts associated with this menu item. When a content script posts a
-message using `self.postMessage()`, the message is delivered to the add-on
-code in the menu item's `message` event.
-
-@argument {value}
-Listeners are passed a single argument which is the message posted
-from the content script. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-</api>
-
-<api name="Menu">
-@class
-A labeled menu item that expands into a submenu.
-
-<api name="Menu">
-@constructor
- Creates a labeled menu item that expands into a submenu.
-@param options {object}
- An object with the following keys:
- @prop label {string}
- The item's label. It must either be a string or an object that implements
- `toString()`.
- @prop items {array}
- An array of menu items that the menu will contain. Each must be an `Item`,
- `Menu`, or `Separator`.
- @prop [image] {string}
- The menu's icon, a string URL. The URL can be remote, a reference to an
- image in the add-on's `data` directory, or a data URI.
- @prop [context] {value}
- If the menu is contained in the top-level context menu, this declaratively
- specifies the context under which the menu will appear; see Specifying
- Contexts above. Ignored if the menu is contained in a submenu.
- @prop [contentScript] {string,array}
- If the menu is contained in the top-level context menu, this is the content
- script or an array of content scripts that the menu can use to interact with
- the page. Ignored if the menu is contained in a submenu.
- @prop [contentScriptFile] {string,array}
- If the menu is contained in the top-level context menu, this is the local
- file URL of the content script or an array of such URLs that the menu can
- use to interact with the page. Ignored if the menu is contained in a
- submenu.
- @prop [onMessage] {function}
- If the menu is contained in the top-level context menu, this function will
- be called when the content script calls `self.postMessage`. It will be
- passed the data that was passed to `postMessage`. Ignored if the item is
- contained in a submenu.
-</api>
-
-<api name="label">
-@property {string}
- The menu's label. You can set this after creating the menu to update its
- label later.
-</api>
-
-<api name="items">
-@property {array}
- An array containing the items in the menu. The array is read-only, meaning
- that modifications to it will not affect the menu. However, setting this
- property to a new array will replace all the items currently in the menu with
- the items in the new array.
-</api>
-
-<api name="image">
-@property {string}
- The menu's icon, a string URL. The URL can be remote, a reference to an image
- in the add-on's `data` directory, or a data URI. You can set this after
- creating the menu to update its image later. To remove the menu's image, set
- it to `null`.
-</api>
-
-<api name="context">
-@property {list}
- A list of declarative contexts for which the menu will appear in the context
- menu. Contexts can be added by calling `context.add()` and removed by called
- `context.remove()`. This property is meaningful only for menus contained in
- the top-level context menu.
-</api>
-
-<api name="parentMenu">
-@property {Menu}
- The menu's parent `Menu`, or `null` if the menu is contained in the top-level
- context menu. This property is read-only. To add the menu to a new menu,
- call that menu's `addItem()` method.
-</api>
-
-<api name="contentScript">
-@property {string,array}
- The content script or the array of content scripts associated with the menu
- during creation. This property is meaningful only for menus contained in the
- top-level context menu.
-</api>
-
-<api name="contentScriptFile">
-@property {string,array}
- The URL of a content script or the array of such URLs associated with the menu
- during creation. This property is meaningful only for menus contained in the
- top-level context menu.
-</api>
-
-<api name="addItem">
-@method
- Appends a menu item to the end of the menu. If the item is already contained
- in another menu or in the top-level context menu, it's automatically removed
- first.
-@param item {Item,Menu,Separator}
- The `Item`, `Menu`, or `Separator` to add to the menu.
-</api>
-
-<api name="removeItem">
-@method
- Removes the given menu item from the menu. If the menu does not contain the
- item, this method does nothing.
-@param item {Item,Menu,Separator}
- The menu item to remove from the menu.
-</api>
-
-<api name="destroy">
-@method
- Permanently removes the menu from its parent menu and frees its resources.
- The menu must not be used afterward. If you need to remove the menu from its
- parent menu but use it afterward, call `removeItem()` on the parent menu
- instead.
-</api>
-
-<api name="message">
-@event
-If you listen to this event you can receive message events from content
-scripts associated with this menu item. When a content script posts a
-message using `self.postMessage()`, the message is delivered to the add-on
-code in the menu item's `message` event.
-
-@argument {value}
-Listeners are passed a single argument which is the message posted
-from the content script. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-</api>
-
-<api name="Separator">
-@class
-A menu separator. Separators can be contained only in `Menu`s, not in the
-top-level context menu.
-
-<api name="Separator">
-@constructor
- Creates a menu separator.
-</api>
-
-<api name="parentMenu">
-@property {Menu}
- The separator's parent `Menu`. This property is read-only. To add the
- separator to a new menu, call that menu's `addItem()` method.
-</api>
-
-<api name="destroy">
-@method
- Permanently removes the separator from its parent menu and frees its
- resources. The separator must not be used afterward. If you need to remove
- the separator from its parent menu but use it afterward, call `removeItem()`
- on the parent menu instead.
-</api>
-
-</api>
-
-<api name="PageContext">
-@class
-<api name="PageContext">
-@constructor
- Creates a page context. See Specifying Contexts above.
-</api>
-</api>
-
-<api name="SelectionContext">
-@class
-<api name="SelectionContext">
-@constructor
- Creates a context that occurs when a page contains a selection. See
- Specifying Contexts above.
-</api>
-</api>
-
-<api name="SelectorContext">
-@class
-<api name="SelectorContext">
-@constructor
- Creates a context that matches a given CSS selector. See Specifying Contexts
- above.
-@param selector {string}
- A CSS selector.
-</api>
-</api>
-
-<api name="URLContext">
-@class
-<api name="URLContext">
-@constructor
- Creates a context that matches pages with particular URLs. See Specifying
- Contexts above.
-@param matchPattern {string,array}
- A [match pattern](packages/api-utils/docs/match-pattern.html) string or an array of
- match pattern strings.
-</api>
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/hotkeys.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/hotkeys.md
deleted file mode 100644
index dfbe572..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/hotkeys.md
+++ /dev/null
@@ -1,74 +0,0 @@
-<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] -->
-
-Some add-ons may wish to define keyboard shortcuts for certain operations. This
-module exposes an API to create those.
-
-<api name="Hotkey">
-@class
-
-Module exports `Hotkey` constructor allowing users to create a `hotkey` for the
-host application.
-
-<api name="Hotkey">
-@constructor
-Creates a hotkey who's `onPress` listener method is invoked when key combination
-defined by `hotkey` is pressed.
-
-Please note: If more than one `hotkey` is created for the same key
-combination, the listener is executed only on the last one created
-
-@param options {Object}
- Options for the hotkey, with the following keys:
-
-@prop combo {String}
-Any function key: `"f1, f2, ..., f24"` or key combination in the format
-of `'modifier-key'`:
-
- "accel-s"
- "meta-shift-i"
- "control-alt-d"
-
-Modifier keynames:
-
-- **shift**: The Shift key.
-- **alt**: The Alt key. On the Macintosh, this is the Option key. On
- Macintosh this can only be used in conjunction with another modifier,
- since `Alt-Letter` combinations are reserved for entering special
- characters in text.
-- **meta**: The Meta key. On the Macintosh, this is the Command key.
-- **control**: The Control key.
-- **accel**: The key used for keyboard shortcuts on the user's platform,
- which is Control on Windows and Linux, and Command on Mac. Usually, this
- would be the value you would use.
-
-@prop onPress {Function}
-Function that is invoked when the key combination `hotkey` is pressed.
-
-</api>
-<api name="destroy">
-@method
-Stops this instance of `Hotkey` from reacting on the key combinations. Once
-destroyed it can no longer be used.
-</api>
-</api>
-
-## Example ##
-
- // Define keyboard shortcuts for showing and hiding a custom panel.
- var { Hotkey } = require("hotkeys");
-
- var showHotKey = Hotkey({
- combo: "accel-shift-o",
- onPress: function() {
- showMyPanel();
- }
- });
- var hideHotKey = Hotkey({
- combo: "accel-alt-shift-o",
- onPress: function() {
- hideMyPanel();
- }
- });
-
-[Mozilla keyboard planning FAQ]:http://www.mozilla.org/access/keyboard/
-[keyboard shortcuts]:https://developer.mozilla.org/en/XUL_Tutorial/Keyboard_Shortcuts
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/notifications.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/notifications.md
deleted file mode 100644
index 5e76c1b..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/notifications.md
+++ /dev/null
@@ -1,60 +0,0 @@
-<!-- contributed by Drew Willcoxon [adw@mozilla.com] -->
-
-The `notifications` module allows you to display transient,
-[toaster](http://en.wikipedia.org/wiki/Toast_%28computing%29)-style
-desktop messages to the user.
-
-This API supports desktop notifications on Windows, OS X using
-[Growl](http://growl.info/), and Linux using libnotify. If the user's system
-does not support desktop notifications or if its notifications service is not
-running, then notifications made with this API are logged to Firefox's error
-console and, if the user launched Firefox from the command line, the terminal.
-
-Examples
---------
-
-Here's a typical example. When the message is clicked, a string is logged to
-the console.
-
- var notifications = require("notifications");
- notifications.notify({
- title: "Jabberwocky",
- text: "'Twas brillig, and the slithy toves",
- data: "did gyre and gimble in the wabe",
- onClick: function (data) {
- console.log(data);
- // console.log(this.data) would produce the same result.
- }
- });
-
-This one displays an icon that's stored in the add-on's `data` directory. (See
-the [`self`](packages/addon-kit/docs/self.html) module documentation for more information.)
-
- var notifications = require("notifications");
- var self = require("self");
- var myIconURL = self.data.url("myIcon.png");
- notifications.notify({
- text: "I have an icon!",
- iconURL: myIconURL
- });
-
-
-<api name="notify">
-@function
- Displays a transient notification to the user.
-@param options {object}
- An object with the following keys. Each is optional.
- @prop [title] {string}
- A string to display as the message's title.
- @prop [text] {string}
- A string to display as the body of the message.
- @prop [iconURL] {string}
- The URL of an icon to display inside the message. It may be a remote URL,
- a data URI, or a URL returned by the [`self`](packages/addon-kit/docs/self.html)
- module.
- @prop [onClick] {function}
- A function to be called when the user clicks the message. It will be passed
- the value of `data`.
- @prop [data] {string}
- A string that will be passed to `onClick`.
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/page-mod.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/page-mod.md
deleted file mode 100644
index e523d48..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/page-mod.md
+++ /dev/null
@@ -1,367 +0,0 @@
-<!-- contributed by Nickolay Ponomarev [asqueella@gmail.com] -->
-<!-- contributed by Myk Melez [myk@mozilla.org] -->
-<!-- contributed by Irakli Gozalishvil [gozala@mozilla.com] -->
-
-Overview
---------
-The page-mod module enables add-on developers to execute scripts in the context
-of specific web pages. Most obviously you could use page-mod to dynamically
-modify the content of certain pages.
-
-The module exports a constructor function `PageMod` which creates a new page
-modification (or "mod" for short).
-
-A page mod does not modify its pages until those pages are loaded or reloaded.
-In other words, if your add-on is loaded while the user's browser is open, the
-user will have to reload any open pages that match the mod for the mod to affect
-them.
-
-To stop a page mod from making any more modifications, call its `destroy`
-method.
-
-Like all modules that interact with web content, page-mod uses content
-scripts that execute in the content process and defines a messaging API to
-communicate between the content scripts and the main add-on script. For more
-details on content scripting see the tutorial on [interacting with web
-content](dev-guide/addon-development/web-content.html).
-
-To create a PageMod the add-on developer supplies:
-
-* a set of rules to select the desired subset of web pages based on their URL.
-Each rule is specified using the
-[match-pattern](packages/api-utils/docs/match-pattern.html) syntax.
-
-* a set of content scripts to execute in the context of the desired pages.
-
-* a value for the onAttach option: this value is a function which will be
-called when a page is loaded that matches the ruleset. This is used to set up a
-communication channel between the add-on code and the content script.
-
-All these parameters are optional except for the ruleset, which must include
-at least one rule.
-
-The following add-on displays an alert whenever a page matching the ruleset is
-loaded:
-
- var pageMod = require("page-mod");
- pageMod.PageMod({
- include: "*.org",
- contentScript: 'window.alert("Page matches ruleset");'
- });
-
-If you specify a value of "ready" or "end" for `contentScriptWhen`,
-as opposed to "start",
-then the content script can interact with the DOM itself:
-
- var pageMod = require("page-mod");
- pageMod.PageMod({
- include: "*.org",
- contentScriptWhen: 'end',
- contentScript: 'document.body.innerHTML = ' +
- ' "<h1>Page matches ruleset</h1>";'
- });
-
-### Using `contentScriptFile` ###
-
-Most of the examples in this page define content scripts as strings,
-and use the `contentScript` option to assign them to page mods.
-
-In your code you will more often create content scripts in separate files
-under your add-on's `data` directory. Then you can use the
-[`self`](packages/addon-kit/docs/self.html) module to retrieve a URL pointing
-to the file, and assign this to the page-mod's `contentScriptFile`
-property.
-
-For example, if you save the content script
-file in your `data` directory as "myScript.js", you would assign it using
-code like:
-
- var data = require("self").data;
-
- var pageMod = require("page-mod");
- pageMod.PageMod({
- include: "*.org",
- contentScriptWhen: 'end',
- contentScriptFile: data.url("myScript.js")
- });
-
-## Communicating With Content Scripts ##
-
-When a matching page is loaded the `PageMod` will call the function that the
-add-on code supplied to `onAttach`. The `PageMod` supplies one argument to
-this function: a `worker` object.
-
-The worker can be thought of as the add-on's end of
-a communication channel between the add-on code and the content scripts that
-have been attached to this page.
-
-Thus the add-on can pass messages to the content scripts by calling the
-worker's `postMessage` function and can receive messages from the content
-scripts by registering a function as a listener to the worker's `on` function.
-
-Note that if multiple matching pages are loaded simultaneously then each page
-is loaded into its own execution context with its own copy of the content
-scripts. In this case `onAttach` is called once for each loaded page, and the
-add-on code will have a separate worker for each page:
-
-![Multiple workers](static-files/media/multiple-workers.jpg)
-
-This is demonstrated in the following example:
-
- var pageMod = require("page-mod");
- var tabs = require("tabs");
-
- var workers = [];
-
- pageMod.PageMod({
- include: ["http://www.mozilla*"],
- contentScriptWhen: 'end',
- contentScript: "onMessage = function onMessage(message) {" +
- " window.alert(message);};",
- onAttach: function onAttach(worker) {
- if (workers.push(worker) == 3) {
- workers[0].postMessage("The first worker!");
- workers[1].postMessage("The second worker!");
- workers[2].postMessage("The third worker!");
- }
- }
- });
-
- tabs.open("http://www.mozilla.com");
- tabs.open("http://www.mozilla.org");
- tabs.open("http://www.mozilla-europe.org");
-
-Here we specify a ruleset to match any URLs starting with
-"http://www.mozilla". When a page matches we add the supplied worker to
-an array, and when we have three workers in the array we send a message to
-each worker in turn, telling it the order in which it was attached. The
-worker just displays the message in an alert box.
-
-This shows that separate pages execute in separate contexts and that each
-context has its own communication channel with the add-on script.
-
-Note though that while there is a separate worker for each execution context,
-the worker is shared across all the content scripts associated with a single
-execution context. In the following example we pass two content scripts into
-the `PageMod`: these content scripts will share a worker instance.
-
-In the example each content script identifies itself to the add-on script
-by sending it a message using the global `postMessage` function. In the
-`onAttach` function the add-on code logs the fact that a new page is
-attached and registers a listener function that simply logs the message:
-
-
- var pageMod = require("page-mod");
- var data = require("self").data;
- var tabs = require("tabs");
-
- pageMod.PageMod({
- include: ["http://www.mozilla*"],
- contentScriptWhen: 'end',
- contentScript: ["postMessage('Content script 1 is attached to '+ " +
- "document.URL);",
- "postMessage('Content script 2 is attached to '+ " +
- "document.URL);"],
- onAttach: function onAttach(worker) {
- console.log("Attaching content scripts")
- worker.on('message', function(data) {
- console.log(data);
- });
- }
- });
-
- tabs.open("http://www.mozilla.com");
-
-The console output of this add-on is:
-
-<pre>
- info: Attaching content scripts
- info: Content script 1 is attached to http://www.mozilla.com/en-US/
- info: Content script 2 is attached to http://www.mozilla.com/en-US/
-</pre>
-
-### Mapping workers to tabs ###
-
-The [`worker`](packages/api-utils/docs/content/worker.html) has a `tab`
-property which returns the tab associated with this worker. You can use this
-to access the [`tabs API`](packages/addon-kit/docs/tabs.html) for the tab
-associated with a specific page:
-
- var pageMod = require("page-mod");
- var tabs = require("tabs");
-
- pageMod.PageMod({
- include: ["*"],
- onAttach: function onAttach(worker) {
- console.log(worker.tab.title);
- }
- });
-
-### Attaching content scripts to tabs ###
-
-We've seen that the page mod API attaches content scripts to pages based on
-their URL. Sometimes, though, we don't care about the URL: we just want
-to execute a script on demand in the context of a particular tab.
-
-For example, we might want to run a script in the context of the currently
-active tab when the user clicks a widget: to block certain content, to
-change the font style, or to display the page's DOM structure.
-
-Using the `attach` method of the [`tab`](packages/addon-kit/docs/tabs.html)
-object, you can attach a set of content scripts to a particular tab. The
-scripts are executed immediately.
-
-The following add-on creates a widget which, when clicked, highlights all the
-`div` elements in the page loaded into the active tab:
-
- var widgets = require("widget");
- var tabs = require("tabs");
-
- var widget = widgets.Widget({
- id: "div-show",
- label: "Show divs",
- contentURL: "http://www.mozilla.org/favicon.ico",
- onClick: function() {
- tabs.activeTab.attach({
- contentScript:
- 'var divs = document.getElementsByTagName("div");' +
- 'for (var i = 0; i < divs.length; ++i) {' +
- 'divs[i].setAttribute("style", "border: solid red 1px;");' +
- '}'
- });
- }
- });
-
-## Destroying Workers ##
-
-Workers generate a `detach` event when their associated page is closed: that
-is, when the tab is closed or the tab's location changes. If
-you are maintaining a list of workers belonging to a page mod, you can use
-this event to remove workers that are no longer valid.
-
-For example, if you maintain a list of workers attached to a page mod:
-
- var workers = [];
-
- var pageMod = require("page-mod").PageMod({
- include: ['*'],
- contentScriptWhen: 'ready',
- contentScriptFile: data.url('pagemod.js'),
- onAttach: function(worker) {
- workers.push(worker);
- }
- });
-
-You can remove workers when they are no longer valid by listening to `detach`:
-
- var workers = [];
-
- function detachWorker(worker, workerArray) {
- var index = workerArray.indexOf(worker);
- if(index != -1) {
- workerArray.splice(index, 1);
- }
- }
-
- var pageMod = require("page-mod").PageMod({
- include: ['*'],
- contentScriptWhen: 'ready',
- contentScriptFile: data.url('pagemod.js'),
- onAttach: function(worker) {
- workers.push(worker);
- worker.on('detach', function () {
- detachWorker(this, workers);
- });
- }
- });
-
-<api name="PageMod">
-@class
-A PageMod object. Once activated a page mod will execute the supplied content
-scripts in the context of any pages matching the pattern specified by the
-'include' property.
-<api name="PageMod">
-@constructor
-Creates a PageMod.
-@param options {object}
- Options for the PageMod, with the following keys:
- @prop include {string,array}
- A match pattern string or an array of match pattern strings. These define
- the pages to which the PageMod applies. See the
- [match-pattern](packages/api-utils/docs/match-pattern.html) module for
- a description of match pattern syntax.
- At least one match pattern must be supplied.
-
- @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 [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 [onAttach] {function}
-A function to call when the PageMod attaches content scripts to
-a matching page. The function will be called with one argument, a `worker`
-object which the add-on script can use to communicate with the content scripts
-attached to the page in question.
-
-</api>
-
-<api name="include">
-@property {List}
-A [list](packages/api-utils/docs/list.html) of match pattern strings. These
-define the pages to which the page mod applies. See the
-[match-pattern](packages/api-utils/docs/match-pattern.html) module for a
-description of match patterns. Rules can be added to the list by calling its
-`add` method and removed by calling its `remove` method.
-
-</api>
-
-<api name="destroy">
-@method
-Stops the page mod from making any more modifications. Once destroyed the page
-mod can no longer be used. Note that modifications already made to open pages
-will not be undone.
-</api>
-
-<api name="attach">
-@event
-This event is emitted this event when the page-mod's content scripts are
-attached to a page whose URL matches the page-mod's `include` filter.
-
-@argument {Worker}
-The listener function is passed a [`Worker`](packages/api-utils/docs/content/worker.html) object that can be used to communicate
-with any content scripts attached to this page.
-</api>
-
-<api name="error">
-@event
-This event is emitted when an uncaught runtime error occurs in one of the page
-mod's content scripts.
-
-@argument {Error}
-Listeners are passed a single argument, the
-[Error](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error)
-object.
-</api>
-
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/page-worker.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/page-worker.md
deleted file mode 100644
index 06097ae..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/page-worker.md
+++ /dev/null
@@ -1,218 +0,0 @@
-<!-- contributed by Felipe Gomes [felipc@gmail.com] -->
-
-The `page-worker` module provides a way to create a permanent, invisible page
-and access its DOM.
-
-Introduction
-------------
-
-The module exports a constructor function `Page`, which constructs a new page
-worker. A page worker may be destroyed, after which its memory is freed, and
-you must create a new instance to load another page.
-
-Page workers have associated content scripts, which are JavaScript scripts that
-have access to the content loaded into the pages. You can specify scripts to
-load for a page worker, and you communicate with those scripts over an
-asynchronous JSON pipe. For more information on content scripts, see
-[Working with Content Scripts](dev-guide/addon-development/web-content.html).
-
-Examples
---------
-
-For conciseness, these examples create their content scripts as strings and use
-the `contentScript` property. In your own add-ons, you will probably want to
-create your content scripts in separate files and pass their URLs using the
-`contentScriptFile` property. See
-[Working with Content Scripts](dev-guide/addon-development/web-content.html)
-for more information.
-
-### Print all header titles from a Wikipedia article ###
-
- var pageWorkers = require("page-worker");
-
- // This content script sends header titles from the page to the add-on:
- var script = "var elements = document.querySelectorAll('h2 > span'); " +
- "for (var i = 0; i < elements.length; i++) { " +
- " postMessage(elements[i].textContent) " +
- "}";
-
- // Create a page worker that loads Wikipedia:
- pageWorkers.Page({
- contentURL: "http://en.wikipedia.org/wiki/Internet",
- contentScript: script,
- contentScriptWhen: "ready",
- onMessage: function(message) {
- console.log(message);
- }
- });
-
-The page worker's "message" event listener, specified by `onMessage`, will print
-all the titles it receives from the content script.
-
-<api name="Page">
-@class
-A `Page` object loads the page specified by its `contentURL` option and
-executes any content scripts that have been supplied to it in the
-`contentScript` and `contentScriptFile` options.
-
-The page is not displayed to the user.
-
-The page worker is loaded as soon as the `Page` object is created and stays
-loaded until its `destroy` method is called or the add-on is unloaded.
-
-<api name="Page">
-@constructor
- Creates an uninitialized page worker instance.
-@param [options] {object}
- The *`options`* parameter is optional, and if given it should be an object
- with any of the following keys:
- @prop [contentURL] {string}
- The URL of the content to load in the panel.
- @prop [allow] {object}
- An object with keys to configure the permissions on the page worker. The
- boolean key `script` controls if scripts from the page are allowed to run.
- `script` defaults to true.
- @prop [contentScriptFile] {string,array}
- A local file URL or an array of local file URLs of content scripts to load.
- Content scripts specified by this option are loaded *before* those specified
- by the `contentScript` option. See
- [Working with Content Scripts](dev-guide/addon-development/web-content.html)
- for help on setting this property.
- @prop [contentScript] {string,array}
- A string or an array of strings containing the texts of content scripts to
- load. Content scripts specified by this option are loaded *after* those
- specified by the `contentScriptFile` option.
- @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 [onMessage] {function}
- Use this to add a listener to the page worker's `message` event.
-</api>
-
-<api name="port">
-@property {EventEmitter}
-[EventEmitter](packages/api-utils/docs/events.html) object that allows you to:
-
-* send events to the content script using the `port.emit` function
-* receive events from the content script using the `port.on` function
-
-See the guide to
-<a href="dev-guide/addon-development/content-scripts/using-port.html">
-communicating using <code>port</code></a> for details.
-</api>
-
-<api name="contentURL">
-@property {string}
-The URL of the content loaded.
-</api>
-
-<api name="allow">
-@property {object}
- A object describing permissions for the content. It contains a single key
- named `script` whose value is a boolean that indicates whether or not to
- execute script in the content. `script` defaults to true.
-</api>
-
-<api name="contentScriptFile">
-@property {string,array}
-A local file URL or an array of local file URLs of content scripts to load.
-</api>
-
-<api name="contentScript">
-@property {string,array}
-A string or an array of strings containing the texts of content scripts to
-load.
-</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="destroy">
-@method
-Unloads the page worker. After you destroy a page worker, its memory is freed
-and you must create a new instance if you need to load another page.
-</api>
-
-<api name="postMessage">
-@method
-Sends a message to the content scripts.
-@param message {value}
-The message to send. Must be JSON-able.
-</api>
-
-<api name="on">
-@method
-Registers an event listener with the page worker. See
-[Working with Events](dev-guide/addon-development/events.html) for help with
-events.
-@param type {string}
-The type of event to listen for.
-@param listener {function}
-The listener function that handles the event.
-</api>
-
-<api name="removeListener">
-@method
-Unregisters an event listener from the page worker.
-@param type {string}
-The type of event for which `listener` was registered.
-@param listener {function}
-The listener function that was registered.
-</api>
-
-<api name="message">
-@event
-If you listen to this event you can receive message events from content
-scripts associated with this page worker. When a content script posts a
-message using `self.postMessage()`, the message is delivered to the add-on
-code in the page worker's `message` event.
-
-@argument {value}
-Listeners are passed a single argument which is the message posted
-from the content script. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>
-</api>
-
-<api name="error">
-@event
-This event is emitted when an uncaught runtime error occurs in one of the
-page worker's content scripts.
-
-@argument {Error}
-Listeners are passed a single argument, the
-[Error](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error)
-object.
-</api>
-
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/panel.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/panel.md
deleted file mode 100644
index 45eea2f..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/panel.md
+++ /dev/null
@@ -1,301 +0,0 @@
-<!-- contributed by Myk Melez [myk@mozilla.org] -->
-<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] -->
-
-The `panel` module creates floating modal "popup dialogs" that appear on top of
-web content and browser chrome and persist until dismissed by users or programs.
-Panels are useful for presenting temporary interfaces to users in a way that is
-easier for users to ignore and dismiss than a modal dialog, since panels are
-hidden the moment users interact with parts of the application interface outside
-them.
-
-The module exports a single constructor function `Panel` which constructs a
-new panel.
-
-A panel's content is loaded as soon as it is created, before the panel is shown,
-and the content remains loaded when a panel is hidden, so it is possible
-to keep a panel around in the background, updating its content as appropriate
-in preparation for the next time it is shown.
-
-Your add-on can receive notifications when a panel is shown or hidden by
-listening to its `show` and `hide` events.
-
-Panels have associated content scripts, which are JavaScript scripts that have
-access to the content loaded into the panels. An add-on can specify one or
-more content scripts to load for a panel, and the add-on can communicate with
-those scripts either using the `message` event or by using user-defined
-events. See
-[Working with Content Scripts](dev-guide/addon-development/web-content.html)
-for more information.
-
-The panel's default style is different for each operating system.
-For example, suppose a panel's content is specified with the following HTML:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-<h1>Default Style</h1>
-
-This is what a panel with no custom styling looks like.
-]]>
-</script>
-
-On OS X it will look like this:
-
-<img class="image-center" src="static-files/media/screenshots/default-panel-osx.png"
-alt="OS X panel default style">
-<br>
-
-On Windows 7 it will look like this:
-
-<img class="image-center" src="static-files/media/screenshots/default-panel-windows.png"
-alt="Windows 7 panel default style">
-<br>
-
-On Ubuntu it will look like this:
-
-<img class="image-center" src="static-files/media/screenshots/default-panel-ubuntu.png"
-alt="Ubuntu panel default style">
-<br>
-
-This helps to ensure that the panel's style is consistent with the dialogs
-displayed by Firefox and other applications, but means you need to take care
-when applying your own styles. For example, if you set the panel's
-`background-color` property to `white` and do not set the `color` property,
-then the panel's text will be invisible on OS X although it looks fine on Ubuntu.
-
-Examples
---------
-
-Create and show a simple panel with content from the `data/` directory:
-
- var data = require("self").data;
- var panel = require("panel").Panel({
- contentURL: data.url("foo.html")
- });
-
- panel.show();
-
-The tutorial section on
-[web content](dev-guide/addon-development/web-content.html) has
-a more complex example using panels.
-
-<api name="Panel">
-@class
-The Panel object represents a floating modal dialog that can by an add-on to
-present user interface content.
-
-Once a panel object has been created it can be shown and hidden using its
-`show()` and `hide()` methods. Once a panel is no longer needed it can be
-deactivated using `destroy()`.
-
-The content of a panel is specified using the `contentURL` option. An add-on
-can interact with the content of a panel using content scripts which it
-supplies in the `contentScript` and/or `contentScriptFile` options. For example,
-a content script could create a menu and send the user's selection to the
-add-on.
-
-<api name="Panel">
-@constructor
-Creates a panel.
-@param options {object}
- Options for the panel, with the following keys:
- @prop [width] {number}
- The width of the panel in pixels. Optional.
- @prop [height] {number}
- The height of the panel in pixels. Optional.
- @prop [contentURL] {string}
- The URL of the content to load in the panel.
- @prop [allow] {object}
- An optional object describing permissions for the content. It should
- contain a single key named `script` whose value is a boolean that indicates
- whether or not to execute script in the content. `script` defaults to true.
- @prop [contentScriptFile] {string,array}
- A local file URL or an array of local file URLs of content scripts to load.
- Content scripts specified by this property are loaded *before* those
- specified by the `contentScript` property.
- @prop [contentScript] {string,array}
- A string or an array of strings containing the texts of content scripts to
- load. Content scripts specified by this property are loaded *after* those
- specified by the `contentScriptFile` property.
- @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 panel 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 panel 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 [onMessage] {function}
- Include this to listen to the panel's `message` event.
- @prop [onShow] {function}
- Include this to listen to the panel's `show` event.
- @prop [onHide] {function}
- Include this to listen to the panel's `hide` event.
-</api>
-
-<api name="port">
-@property {EventEmitter}
-[EventEmitter](packages/api-utils/docs/events.html) object that allows you to:
-
-* send events to the content script using the `port.emit` function
-* receive events from the content script using the `port.on` function
-
-See the guide to
-<a href="dev-guide/addon-development/content-scripts/using-port.html">
-communicating using <code>port</code></a> for details.
-</api>
-
-<api name="isShowing">
-@property {boolean}
-Tells if the panel is currently shown or not. This property is read-only.
-</api>
-
-<api name="height">
-@property {number}
-The height of the panel in pixels.
-</api>
-
-<api name="width">
-@property {number}
-The width of the panel in pixels.
-</api>
-
-<api name="contentURL">
-@property {string}
-The URL of the content loaded in the panel.
-</api>
-
-<api name="allow">
-@property {object}
-An object describing permissions for the content. It contains a single key
-named `script` whose value is a boolean that indicates whether or not to execute
-script in the content.
-</api>
-
-<api name="contentScriptFile">
-@property {string,array}
-A local file URL or an array of 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 {string,array}
-A string or an array of strings containing 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 panel 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 panel has been loaded, at the time the
-[window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
-fires
-
-</api>
-
-<api name="destroy">
-@method
-Destroys the panel, unloading any content that was loaded in it. Once
-destroyed, the panel can no longer be used. If you just want to hide
-the panel and might show it later, use `hide` instead.
-</api>
-
-<api name="postMessage">
-@method
-Sends a message to the content scripts.
-@param message {value}
-The message to send. Must be stringifiable to JSON.
-</api>
-
-<api name="show">
-@method
-Displays the panel.
-</api>
-
-<api name="hide">
-@method
-Stops displaying the panel.
-</api>
-
-<api name="resize">
-@method
-Resizes the panel.
-@param width {number}
-The new width of the panel in pixels.
-@param height {number}
-The new height of the panel in pixels.
-</api>
-
-<api name="on">
-@method
- Registers an event listener with the panel.
-@param type {string}
- The type of event to listen for.
-@param listener {function}
- The listener function that handles the event.
-</api>
-
-<api name="removeListener">
-@method
- Unregisters an event listener from the panel.
-@param type {string}
- The type of event for which `listener` was registered.
-@param listener {function}
- The listener function that was registered.
-</api>
-
-<api name="show">
-@event
-This event is emitted when the panel is shown.
-</api>
-
-<api name="hide">
-@event
-This event is emitted when the panel is hidden.
-</api>
-
-<api name="message">
-@event
-If you listen to this event you can receive message events from content
-scripts associated with this panel. When a content script posts a
-message using `self.postMessage()`, the message is delivered to the add-on
-code in the panel's `message` event.
-
-@argument {value}
-Listeners are passed a single argument which is the message posted
-from the content script. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-<api name="error">
-@event
-This event is emitted when an uncaught runtime error occurs in one of the
-panel's content scripts.
-
-@argument {Error}
-Listeners are passed a single argument, the
-[Error](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error)
-object.
-</api>
-
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/passwords.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/passwords.md
deleted file mode 100644
index 6a4b246..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/passwords.md
+++ /dev/null
@@ -1,564 +0,0 @@
-<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] -->
-
-The `passwords` module allows add-ons to interact with Firefox's
-[Password Manager](http://support.mozilla.com/en-US/kb/Remembering%20passwords)
-to add, retrieve and remove stored credentials.
-
-A _credential_ is the set of information a user supplies to authenticate
-herself with a service. Typically a credential consists of a username and a
-password.
-
-Using this module you can:
-
-1. **Search** for credentials which have been stored in the Password Manager.
- You can then use the credentials to access their related service (for
- example, by logging into a web site).
-
-2. **Store** credentials in the Password Manager. You can store different sorts
- of credentials, as outlined in the "Credentials" section below.
-
-3. **Remove** stored credentials from the Password Manager.
-
-## Credentials ##
-
-In this API, credentials are represented by objects.
-
-You create credential objects to pass into the API, and the API also returns
-credential objects to you. The sections below explain both the properties you
-should define on credential objects and the properties you can expect on
-credential objects returned by the API.
-
-All credential objects include `username` and `password` properties. Different
-sorts of stored credentials include various additional properties, as
-outlined in this section.
-
-You can use the Passwords API with three sorts of credentials:
-
-* Add-on credentials
-* HTML form credentials
-* HTTP Authentication credentials
-
-### Add-on Credential ###
-
-These are associated with your add-on rather than a particular web site.
-They contain the following properties:
-
-<table>
-<colgroup>
-<col width="25%">
-</colgroup>
-<tr>
- <td>
- <code>username</code>
- </td>
- <td>
- The username.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>password</code>
- </td>
- <td>
- The password.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>url</code>
- </td>
- <td>
- <p>For an add-on credential, this property is of the form:<br><code>
- addon:&lt;addon-id&gt;</code>, where <code>&lt;addon-id&gt;</code>
- is the add-on's
- <a href="dev-guide/addon-development/program-id.html">
- Program ID</a>.</p>
- <p>You don't supply this value when storing an add-on credential: it is
- automatically generated for you. However, you can use it to work out
- which stored credentials belong to your add-on by comparing it with the
- <code>uri</code> property of the
- <a href="packages/addon-kit/docs/self.html"><code>self</code></a>
- module.</p>
- </td>
-</tr>
-
-<tr>
- <td>
- <code>realm</code>
- </td>
- <td>
- <p>You can use this as a name for the credential, to distinguish
- it from any other credentials you've stored.</p>
- <p>The realm is displayed
- in Firefox's Password Manager, under "Site", in brackets after the URL.
- For example, if the realm for a credential is "User Registration", then
- its "Site" field will look something like:</p>
- <code>addon:jid0-01mBBFyu0ZAXCFuB1JYKooSTKIc (User Registration)</code>
- </td>
-</tr>
-
-</table>
-
-### HTML Form Credential ###
-
-If a web service uses HTML forms to authenticate its users, then the
-corresponding credential is an HTML Form credential.
-
-It contains the following properties:
-
-<table>
-<colgroup>
-<col width="25%">
-</colgroup>
-<tr>
- <td>
- <code>username</code>
- </td>
- <td>
- The username.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>password</code>
- </td>
- <td>
- The password.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>url</code>
- </td>
- <td>
- The URL for the web service which requires the credential.
- You should omit anything after the hostname and (optional) port.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>formSubmitURL</code>
- </td>
- <td>
- The value of the form's "action" attribute.
- You should omit anything after the hostname and (optional) port.
- If the form doesn't contain an "action" attribute, this property should
- match the <code>url</code> property.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>usernameField</code>
- </td>
- <td>
- The value of the "name" attribute for the form's username field.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>passwordField</code>
- </td>
- <td>
- The value of the "name" attribute for the form's password field.
- </td>
-</tr>
-
-</table>
-
-So: given a form at `http://www.example.com/login`
-with the following HTML:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-<form action="http://login.example.com/foo/authenticate.cgi">
- <div>Please log in.</div>
- <label>Username:</label> <input type="text" name="uname">
- <label>Password:</label> <input type="password" name="pword">
-</form>
-]]>
-</script>
-
-The corresponding values for the credential (excluding username and password)
-should be:
-
-<pre>
- url: "http://www.example.com"
- formSubmitURL: "http://login.example.com"
- usernameField: "uname"
- passwordField: "pword"
-</pre>
-
-Note that for both `url` and `formSubmitURL`, the portion of the URL after the
-hostname is omitted.
-
-### HTTP Authentication Credential ###
-
-These are used to authenticate the user to a web site
-which uses HTTP Authentication, as detailed in
-[RFC 2617](http://tools.ietf.org/html/rfc2617).
-They contain the following properties:
-
-<table>
-<colgroup>
-<col width="25%">
-</colgroup>
-<tr>
- <td>
- <code>username</code>
- </td>
- <td>
- The username.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>password</code>
- </td>
- <td>
- The password.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>url</code>
- </td>
- <td>
- The URL for the web service which requires the credential.
- You should omit anything after the hostname and (optional) port.
- </td>
-</tr>
-
-<tr>
- <td>
- <code>realm</code>
- </td>
- <td>
- <p>The WWW-Authenticate response header sent by the server may include a
- "realm" field as detailed in
- <a href="http://tools.ietf.org/html/rfc2617">RFC 2617</a>. If it does,
- this property contains the value for the "realm" field. Otherwise, it is
- omitted.</p>
- <p>The realm is displayed in Firefox's Password Manager, under "Site",
- in brackets after the URL.</p>
- </td>
-</tr>
-
-</table>
-
-So: if a web server at `http://www.example.com` requested authentication with
-a response code like this:
-
-<pre>
- HTTP/1.0 401 Authorization Required
- Server: Apache/1.3.27
- WWW-Authenticate: Basic realm="ExampleCo Login"
-</pre>
-
-The corresponding values for the credential (excluding username and password)
-should be:
-
-<pre>
- url: "http://www.example.com"
- realm: "ExampleCo Login"
-</pre>
-
-## onComplete and onError ##
-
-This API is explicitly asynchronous, so all its functions take two callback
-functions as additional options: `onComplete` and `onError`.
-
-`onComplete` is called when the operation has completed successfully and
-`onError` is called when the function encounters an error.
-
-Because the `search` function is expected to return a list of matching
-credentials, its `onComplete` option is mandatory. Because the other functions
-don't return a value in case of success their `onComplete` options are
-optional.
-
-For all functions, `onError` is optional.
-
-<api name="search">
-@function
-
-This function is used to retrieve a credential, or a list of credentials,
-stored in the Password Manager.
-
-You pass it any subset of the possible properties a credential can contain.
-Credentials which match all the properties you supplied are returned as an
-argument to the `onComplete` callback.
-
-So if you pass in an empty set of properties, all stored credentials are
-returned:
-
- function show_all_passwords() {
- require("passwords").search({
- onComplete: function onComplete(credentials) {
- credentials.forEach(function(credential) {
- console.log(credential.username);
- console.log(credential.password);
- });
- }
- });
- }
-
-If you pass it a single property, only credentials matching that property are
-returned:
-
- function show_passwords_for_joe() {
- require("passwords").search({
- username: "joe",
- onComplete: function onComplete(credentials) {
- credentials.forEach(function(credential) {
- console.log(credential.username);
- console.log(credential.password);
- });
- }
- });
- }
-
-If you pass more than one property, returned credentials must match all of
-them:
-
- function show_google_password_for_joe() {
- require("passwords").search({
- username: "joe",
- url: "https://www.google.com",
- onComplete: function onComplete(credentials) {
- credentials.forEach(function(credential) {
- console.log(credential.username);
- console.log(credential.password);
- });
- }
- });
- }
-
-To retrieve only credentials associated with your add-on, use the `url`
-property, initialized from `self.uri`:
-
- function show_my_addon_passwords() {
- require("passwords").search({
- url: require("self").uri,
- onComplete: function onComplete(credentials) {
- credentials.forEach(function(credential) {
- console.log(credential.username);
- console.log(credential.password);
- });
- }
- });
- }
-
-@param options {object}
-The `options` object may contain any credential properties. It is used to
-restrict the set of credentials returned by the `search` function.
-
-See "Credentials" above for details on what these properties should be.
-
-Additionally, `options` must contain a function assigned to its `onComplete`
-property: this is called when the function completes and is passed the set of
-credentials retrieved.
-
-`options` may contain a function assigned to its `onError` property, which is
-called if the function encounters an error. `onError` is passed the error as an
-[nsIException](https://developer.mozilla.org/en/nsIException) object.
-
-@prop [username] {string}
-The username for the credential.
-
-@prop [password] {string}
-The password for the credential.
-
-@prop [url] {string}
-The URL associated with the credential.
-
-@prop [formSubmitURL] {string}
-The URL an HTML form credential is submitted to.
-
-@prop [realm] {string}
-For HTTP Authentication credentials, the realm for which the credential was
-requested. For add-on credentials, a name for the credential.
-
-@prop [usernameField] {string}
-The value of the `name` attribute for the user name input field in a form.
-
-@prop [passwordField] {string}
-The value of the `name` attribute for the password input field in a form.
-
-@prop onComplete {function}
-The callback function that is called once the function completes successfully.
-It is passed all the matching credentials as a list. This is the only
-mandatory option.
-
-@prop [onError] {function}
-The callback function that is called if the function failed. The
-callback is passed an `error` containing a reason of a failure: this is an
-[nsIException](https://developer.mozilla.org/en/nsIException) object.
-
-</api>
-
-<api name="store">
-@function
-
-This function is used to store a credential in the Password Manager.
-
-It takes an `options` object as an argument: this contains all the properties
-for the new credential.
-
-As different sorts of credentials contain different properties, the
-appropriate options differ depending on the sort of credential being stored.
-
-To store an add-on credential:
-
- require("passwords").store({
- realm: "User Registration",
- username: "joe",
- password: "SeCrEt123",
- });
-
-To store an HTML form credential:
-
- require("passwords").store({
- url: "http://www.example.com",
- formSubmitURL: "http://login.example.com",
- username: "joe",
- usernameField: "uname",
- password: "SeCrEt123",
- passwordField: "pword"
- });
-
-To store an HTTP Authentication credential:
-
- require("passwords").store({
- url: "http://www.example.com",
- realm: "ExampleCo Login",
- username: "joe",
- password: "SeCrEt123",
- });
-
-See "Credentials" above for more details on how to set these properties.
-
-The options parameter may also include `onComplete` and `onError`
-callback functions, which are called when the function has completed
-successfully and when it encounters an error, respectively. These options
-are both optional.
-
-@param options {object}
-An object containing the properties of the credential to be stored, and
-optional `onComplete` and `onError` callback functions.
-
-@prop username {string}
-The username for the credential.
-
-@prop password {string}
-The password for the credential.
-
-@prop [url] {string}
-The URL to which the credential applies. Omitted for add-on
-credentials.
-
-@prop [formSubmitURL] {string}
-The URL a form-based credential was submitted to. Omitted for add-on
-credentials and HTTP Authentication credentials.
-
-@prop [realm] {string}
-For HTTP Authentication credentials, the realm for which the credential was
-requested. For add-on credentials, a name for the credential.
-
-@prop [usernameField] {string}
-The value of the `name` attribute for the username input in a form.
-Omitted for add-on credentials and HTTP Authentication credentials.
-
-@prop [passwordField] {string}
-The value of the `name` attribute for the password input in a form.
-Omitted for add-on credentials and HTTP Authentication credentials.
-
-@prop [onComplete] {function}
-The callback function that is called once the function completes successfully.
-
-@prop [onError] {function}
-The callback function that is called if the function failed. The
-callback is passed an `error` argument: this is an
-[nsIException](https://developer.mozilla.org/en/nsIException) object.
-
-</api>
-
-<api name="remove">
-@function
-
-Removes a stored credential. You supply it all the properties of the credential
-to remove, along with optional `onComplete` and `onError` callbacks.
-
-Because you must supply all the credential's properties, it may be convenient
-to call `search` first, and use its output as the input to `remove`. For
-example, to remove all of joe's stored credentials:
-
- require("passwords").search({
- username: "joe",
- onComplete: function onComplete(credentials) {
- credentials.forEach(require("passwords").remove);
- })
- });
-
-To change an existing credential just call `store` after `remove` succeeds:
-
- require("passwords").remove({
- realm: "User Registration",
- username: "joe",
- password: "SeCrEt123"
- onComplete: function onComplete() {
- require("passwords").store({
- realm: "User Registration",
- username: "joe",
- password: "{{new password}}"
- })
- }
- });
-
-@param options {object}
-
-An object containing all the properties of the credential to be removed,
-and optional `onComplete` and `onError` callback functions.
-
-@prop username {string}
-The username for the credential.
-
-@prop password {string}
-The password for the credential.
-
-@prop [url] {string}
-The URL to which the credential applies. Omitted for add-on
-credentials.
-
-@prop [formSubmitURL] {string}
-The URL a form-based credential was submitted to. Omitted for add-on
-credentials and HTTP Authentication credentials.
-
-@prop [realm] {string}
-For HTTP Authentication credentials, the realm for which the credential was
-requested. For add-on credentials, a name for the credential.
-
-@prop [usernameField] {string}
-The value of the `name` attribute for the username input in a form.
-Omitted for add-on credentials and HTTP Authentication credentials.
-
-@prop [passwordField] {string}
-The value of the `name` attribute for the password input in a form.
-Omitted for add-on credentials and HTTP Authentication credentials.
-
-@prop [onComplete] {function}
-The callback function that is called once the function has completed
-successfully.
-
-@prop [onError] {function}
-The callback function that is called if the function failed. The
-callback is passed an `error` argument: this is an
-[nsIException](https://developer.mozilla.org/en/nsIException) object.
-
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/private-browsing.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/private-browsing.md
deleted file mode 100644
index cad6166..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/private-browsing.md
+++ /dev/null
@@ -1,46 +0,0 @@
-<!-- contributed by Paul O'Shannessy [paul@oshannessy.com] -->
-<!-- edited by Noelle Murata [fiveinchpixie@gmail.com] -->
-<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] -->
-
-The `private-browsing` module allows you to access Firefox's private browsing
-mode, detecting if it is active and when its state changes.
-
-This module is available in all applications. However, only Firefox will ever
-transition into or out of private browsing mode. For all other applications,
-`pb.isActive` will always be `false`, and none of the events will be emitted.
-
-<api name="isActive">
-@property {boolean}
- This read-only boolean is true if private browsing mode is turned on.
-</api>
-
-<api name="activate">
-@function
- Turns on private browsing mode.
-</api>
-
-<api name="deactivate">
-@function
- Turns off private browsing mode.
-</api>
-
-<api name="start">
-@event
-Emitted immediately after the browser enters private browsing mode.
-
- var pb = require("private-browsing");
- pb.on("start", function() {
- // Do something when the browser starts private browsing mode.
- });
-
-</api>
-
-<api name="stop">
-@event
-Emitted immediately after the browser exits private browsing mode.
-
- var pb = require("private-browsing");
- pb.on("stop", function() {
- // Do something when the browser stops private browsing mode.
- });
-</api> \ No newline at end of file
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/request.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/request.md
deleted file mode 100644
index 77bea43..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/request.md
+++ /dev/null
@@ -1,192 +0,0 @@
-The `request` module lets you make simple yet powerful network requests.
-
-<api name="Request">
-@class
-The `Request` object is used to make `GET` or `POST` network requests. It is
-constructed with a URL to which the request is sent. Optionally the user may
-specify a collection of headers and content to send alongside the request and
-a callback which will be executed once the request completes.
-
-Once a `Request` object has been created a `GET` request can be executed by
-calling its `get()` method, or a `POST` request by calling its `post()` method.
-
-When the server completes the request, the `Request` object emits a "complete"
-event. Registered event listeners are passed a `Response` object.
-
-Each `Request` object is designed to be used once. Once `GET` or `POST` are
-called, attempting to call either will throw an error.
-
-Since the request is not being made by any particular website, requests made
-here are not subject to the same-domain restriction that requests made in web
-pages are subject to.
-
-With the exception of `response`, all of a `Request` object's properties
-correspond with the options in the constructor. Each can be set by simply
-performing an assignment. However, keep in mind that the same validation rules
-that apply to `options` in the constructor will apply during assignment. Thus,
-each can throw if given an invalid value.
-
-The example below shows how to use Request to get the most recent public tweet.
-
- var Request = require("request").Request;
- var latestTweetRequest = Request({
- url: "http://api.twitter.com/1/statuses/public_timeline.json",
- onComplete: function (response) {
- var tweet = response.json[0];
- console.log("User: " + tweet.user.screen_name);
- console.log("Tweet: " + tweet.text);
- }
- });
-
- // Be a good consumer and check for rate limiting before doing more.
- Request({
- url: "http://api.twitter.com/1/account/rate_limit_status.json",
- onComplete: function (response) {
- if (response.json.remaining_hits) {
- latestTweetRequest.get();
- } else {
- console.log("You have been rate limited!");
- }
- }
- }).get();
-
-<api name="Request">
-@constructor
-This constructor creates a request object that can be used to make network
-requests. The constructor takes a single parameter `options` which is used to
-set several properties on the resulting `Request`.
-@param options {object}
- @prop url {string}
- This is the url to which the request will be made.
-
- @prop [onComplete] {function}
- This function will be called when the request has received a response (or in
- terms of XHR, when `readyState == 4`). The function is passed a `Response`
- object.
-
- @prop [headers] {object}
- An unordered collection of name/value pairs representing headers to send
- with the request.
-
- @prop [content] {string,object}
- The content to send to the server. If `content` is a string, it should be
- URL-encoded (use `encodeURIComponent`). If `content` is an object, it
- should be a collection of name/value pairs. Nested objects & arrays should
- encode safely.
-
- For `GET` requests, the query string (`content`) will be appended to the
- URL. For `POST` requests, the query string will be sent as the body of the
- request.
-
- @prop [contentType] {string}
- The type of content to send to the server. This explicitly sets the
- `Content-Type` header. The default value is `application/x-www-form-urlencoded`.
-
- @prop [overrideMimeType] {string}
- Use this string to override the MIME type returned by the server in the
- response's Content-Type header. You can use this to treat the content as a
- different MIME type, or to force text to be interpreted using a specific
- character.
-
- For example, if you're retrieving text content which was encoded as
- ISO-8859-1 (Latin 1), it will be given a content type of "utf-8" and
- certain characters will not display correctly. To force the response to
- be interpreted as Latin-1, use `overrideMimeType`:
-
- var Request = require("request").Request;
- var quijote = Request({
- url: "http://www.latin1files.org/quijote.txt",
- overrideMimeType: "text/plain; charset=latin1",
- onComplete: function (response) {
- console.log(response.text);
- }
- });
-
- quijote.get();
-
-</api>
-
-<api name="url">
-@property {string}
-</api>
-
-<api name="headers">
-@property {object}
-</api>
-
-<api name="content">
-@property {string,object}
-</api>
-
-<api name="contentType">
-@property {string}
-</api>
-
-<api name="response">
-@property {Response}
-</api>
-
-<api name="get">
-@method
-Make a `GET` request.
-@returns {Request}
-</api>
-
-<api name="post">
-@method
-Make a `POST` request.
-@returns {Request}
-</api>
-
-<api name="complete">
-@event
-The `Request` object emits this event when the request has completed and a
-response has been received.
-
-@argument {Response}
-Listener functions are passed the response to the request as a `Response` object.
-</api>
-
-</api>
-
-
-<api name="Response">
-@class
-The Response object contains the response to a network request issued using a
-`Request` object. It is returned by the `get()` or `post()` method of a
-`Request` object.
-
-All members of a `Response` object are read-only.
-<api name="text">
-@property {string}
-The content of the response as plain text.
-</api>
-
-<api name="json">
-@property {object}
-The content of the response as a JavaScript object. The value will be `null`
-if the document cannot be processed by `JSON.parse`.
-</api>
-
-<api name="status">
-@property {string}
-The HTTP response status code (e.g. *200*).
-</api>
-
-<api name="statusText">
-@property {string}
-The HTTP response status line (e.g. *OK*).
-</api>
-
-<api name="headers">
-@property {object}
-The HTTP response headers represented as key/value pairs.
-
-To print all the headers you can do something like this:
-
- for (var headerName in response.headers) {
- console.log(headerName + " : " + response.headers[headerName]);
- }
-
-</api>
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/selection.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/selection.md
deleted file mode 100644
index 62a3d64..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/selection.md
+++ /dev/null
@@ -1,86 +0,0 @@
-<!-- contributed by Eric H. Jung [eric.jung@yahoo.com] -->
-<!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] -->
-
-The `selection` module provides a means to get and set text and HTML selections
-in the current Firefox page. It can also observe new selections.
-
-Registering for Selection Notifications
----------------------------------------
-
-To be notified when the user makes a selection, register a listener for the
-"select" event. Each listener will be called after a selection is made.
-
- function myListener() {
- console.log("A selection has been made.");
- }
- var selection = require("selection");
- selection.on('select', myListener);
-
- // You can remove listeners too.
- selection.removeListener('select', myListener);
-
-Iterating Over Discontiguous Selections
----------------------------------------
-
-Discontiguous selections can be accessed by iterating over the `selection`
-module itself. Each iteration yields a `Selection` object from which `text`,
-`html`, and `isContiguous` properties can be accessed.
-
-
-Examples
---------
-
-Log the current contiguous selection as text:
-
- var selection = require("selection");
- if (selection.text)
- console.log(selection.text);
-
-Log the current discontiguous selections as HTML:
-
- var selection = require("selection");
- if (!selection.isContiguous) {
- for (var subselection in selection) {
- console.log(subselection.html);
- }
- }
-
-Surround HTML selections with delimiters:
-
- var selection = require("selection");
- selection.on('select', function () {
- selection.html = "\\\" + selection.html + "///";
- });
-
-<api name="text">
-@property {string}
- Gets or sets the current selection as plain text. Setting the selection
- removes all current selections, inserts the specified text at the location of
- the first selection, and selects the new text. Getting the selection when
- there is no current selection returns `null`. Setting the selection when there
- is no current selection throws an exception. Getting the selection when
- `isContiguous` is `true` returns the text of the first selection.
-</api>
-
-<api name="html">
-@property {string}
- Gets or sets the current selection as HTML. Setting the selection removes all
- current selections, inserts the specified text at the location of the first
- selection, and selects the new text. Getting the selection when there is no
- current selection returns `null`. Setting the selection when there is no
- current selection throws an exception. Getting the selection when
- `isContiguous` is `true` returns the text of the first selection.
-</api>
-
-<api name="isContiguous">
-@property {boolean}
- `true` if the current selection is a single, contiguous selection, and `false`
- if there are two or more discrete selections, each of which may or may not be
- spatially adjacent. (Discontiguous selections can be created by the user with
- Ctrl+click-and-drag.)
-</api>
-
-<api name="select">
-@event
- This event is emitted whenever the user makes a new selection in a page.
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/self.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/self.md
deleted file mode 100644
index e76ad50..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/self.md
+++ /dev/null
@@ -1,73 +0,0 @@
-The `self` module provides access to data that is bundled with the add-on
-as a whole. It also provides access to the
-[Program ID](dev-guide/addon-development/program-id.html), a value which is
-unique for each add-on.
-
-Note that the `self` module is completely different from the global `self`
-object accessible to content scripts, which is used by a content script to
-[communicate with the add-on code](dev-guide/addon-development/content-scripts/using-port.html).
-
-<api name="id">
-@property {string}
-This property is a printable string that is unique for each add-on. It comes
-from the `id` property set in the `package.json` file in the main package
-(i.e. the package in which you run `cfx xpi`). While not generally of use to
-add-on code directly, it can be used by internal API code to index local
-storage and other resources that are associated with a particular add-on.
-Eventually, this ID will be unspoofable (see
-[JEP 118](https://wiki.mozilla.org/Labs/Jetpack/Reboot/JEP/118) for details).
-</api>
-
-<api name="name">
-@property {string}
-This property contains the add-on's short name. It comes from the `name`
-property in the main package's `package.json` file.
-</api>
-
-<api name="version">
-@property {string}
-This property contains the add-on's version string. It comes from the
-`version` property set in the `package.json` file in the main package.
-</api>
-
-<api name="data">
-@property {object}
-The `data` object is used to access data that was bundled with the add-on.
-This data lives in the main package's `data/` directory, immediately below
-the `package.json` file. All files in this directory will be copied into the
-XPI and made available through the `data` object.
-
-The [Package Specification](dev-guide/addon-development/package-spec.html)
-section explains the `package.json` file.
-
-<api name="data.load">
-@method
-The `data.load(NAME)` method returns the contents of an embedded data file,
-as a string. It is most useful for data that will be modified or parsed in
-some way, such as JSON, XML, plain text, or perhaps an HTML template. For
-data that can be displayed directly in a content frame, use `data.url(NAME)`.
-@param name {string} The filename to be read, relative to the
- package's `data` directory. Each package that uses the `self` module
- will see its own `data` directory.
-@returns {string}
-</api>
-
-<api name="data.url">
-@method
-The `data.url(NAME)` method returns a URL instance that points at an embedded
-data file. It is most useful for data that can be displayed directly in a
-content frame. The URL instance can be passed to a content frame constructor,
-such as the Panel:
-
- var self = require("self");
- var myPanel = require("panel").Panel({
- contentURL: self.data.url("my-panel-content.html")
- });
- myPanel.show();
-
-@param name {string} The filename to be read, relative to the
- package's `data` directory. Each package that uses the `self` module
- will see its own `data` directory.
-@returns {URL}
-</api>
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/simple-prefs.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/simple-prefs.md
deleted file mode 100644
index 824a151..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/simple-prefs.md
+++ /dev/null
@@ -1,70 +0,0 @@
-<!-- contributed by Erik Vold [erikvvold@gmail.com] -->
-
-#### *Experimental*
-
-The `simple-prefs` module lets you easily and persistently store preferences
-across application restarts, which can be configured by users in the
-Add-ons Manager.
-
-Introduction
-------------
-
-With the simple preferences module you can store booleans, integers, and string
-values.
-
-
-Inline Options & Default Values
--------------------------------
-
-In order to have a `options.xul` (for inline options) generated, or a
-`defaults/preferences/prefs.js` for default preferences, you will need to
-define the preferences in your `package.json`, like so:
-
- {
- "fullName": "Example Add-on",
- ...
- "preferences": [{
- "name": "somePreference",
- "title": "Some preference title",
- "type": "string",
- "value": "this is the default string value"
- }]
- }
-
-
-<api name="prefs">
-@property {object}
- *experimental* A persistent object private to your add-on. Properties with boolean,
- number, and string values will be persisted in the Mozilla preferences system.
-</api>
-
-
-<api name="on">
-@function
- *experimental* Registers an event `listener` that will be called when a preference is changed.
-
-**Example:**
-
- function onPrefChange(prefName) {
- console.log("The " + prefName + " preference changed.");
- }
- require("simple-prefs").on("somePreference", onPrefChange);
- require("simple-prefs").on("someOtherPreference", onPrefChange);
-
-
-@param prefName {String}
- The name of the preference to watch for changes.
-@param listener {Function}
- The listener function that processes the event.
-</api>
-
-<api name="removeListener">
-@function
- *experimental* Unregisters an event `listener` for the specified preference.
-
-@param prefName {String}
- The name of the preference to watch for changes.
-@param listener {Function}
- The listener function that processes the event.
-</api>
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/simple-storage.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/simple-storage.md
deleted file mode 100644
index e34e333..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/simple-storage.md
+++ /dev/null
@@ -1,125 +0,0 @@
-The `simple-storage` module lets you easily and persistently store data across
-application restarts. If you're familiar with [DOM storage][] on the Web, it's
-kind of like that, but for add-ons.
-
-[DOM storage]: https://developer.mozilla.org/en/DOM/Storage
-
-
-Introduction
-------------
-
-The simple storage module exports an object called `storage` that is persistent
-and private to your add-on. It's a normal JavaScript object, and you can treat
-it as you would any other.
-
-To store a value, just assign it to a property on `storage`:
-
- var ss = require("simple-storage");
- ss.storage.myArray = [1, 1, 2, 3, 5, 8, 13];
- ss.storage.myBoolean = true;
- ss.storage.myNull = null;
- ss.storage.myNumber = 3.1337;
- ss.storage.myObject = { a: "foo", b: { c: true }, d: null };
- ss.storage.myString = "O frabjous day!";
-
-You can store array, boolean, number, object, null, and string values. If you'd
-like to store other types of values, you'll first have to convert them to
-strings or another one of these types.
-
-Be careful to set properties on the `storage` object and not the module itself:
-
- // This is no good!
- var ss = require("simple-storage");
- ss.foo = "I will not be saved! :(";
-
-
-Quotas
-------
-
-The simple storage available to your add-on is limited. Currently this limit is
-about five megabytes (5,242,880 bytes). You can choose to be notified when you
-go over quota, and you should respond by reducing the amount of data in storage.
-If the user quits the application while you are over quota, all data stored
-since the last time you were under quota will not be persisted. You should not
-let that happen.
-
-To listen for quota notifications, register a listener for the `"OverQuota"`
-event. It will be called when your storage goes over quota.
-
- function myOnOverQuotaListener() {
- console.log("Uh oh.");
- }
- ss.on("OverQuota", myOnOverQuotaListener);
-
-Listeners can also be removed:
-
- ss.removeListener("OverQuota", myOnOverQuotaListener);
-
-To find out how much of your quota you're using, check the module's `quotaUsage`
-property. It indicates the percentage of quota your storage occupies. If
-you're within your quota, it's a number from 0 to 1, inclusive, and if you're
-over, it's a number greater than 1.
-
-Therefore, when you're notified that you're over quota, respond by removing
-storage until your `quotaUsage` is less than or equal to 1. Which particular
-data you remove is up to you. For example:
-
- ss.storage.myList = [ /* some long array */ ];
- ss.on("OverQuota", function () {
- while (ss.quotaUsage > 1)
- ss.storage.myList.pop();
- });
-
-
-Private Browsing
-----------------
-
-*This section applies only to add-ons running on Firefox.*
-
-If your storage is related to your users' Web history, personal information, or
-other sensitive data, your add-on should respect [private browsing mode][SUMO].
-While private browsing mode is active, you should not store any sensitive data.
-
-Because any kind of data can be placed into simple storage, support for private
-browsing is not built into the module. Instead, use the
-[`private-browsing`](packages/addon-kit/docs/private-browsing.html) module to
-check private browsing status and respond accordingly.
-
-For example, the URLs your users visit should not be stored during private
-browsing. If your add-on records the URL of the selected tab, here's how you
-might handle that:
-
- ss.storage.history = [];
- var privateBrowsing = require("private-browsing");
- if (!privateBrowsing.active) {
- var url = getSelectedTabURL();
- ss.storage.history.push(url);
- }
-
-For more information on supporting private browsing, see its [Mozilla Developer
-Network documentation][MDN]. While that page does not apply specifically to
-SDK-based add-ons (and its code samples don't apply at all), you should follow
-its guidance on best practices and policies.
-
-[SUMO]: http://support.mozilla.com/en-US/kb/Private+Browsing
-[MDN]: https://developer.mozilla.org/En/Supporting_private_browsing_mode
-
-
-<api name="storage">
-@property {object}
- A persistent object private to your add-on. Properties with array, boolean,
- number, object, null, and string values will be persisted.
-</api>
-
-<api name="quotaUsage">
-@property {number}
- A number in the range [0, Infinity) that indicates the percentage of quota
- occupied by storage. A value in the range [0, 1] indicates that the storage
- is within quota. A value greater than 1 indicates that the storage exceeds
- quota.
-</api>
-
-<api name="OverQuota">
-@event
-The module emits this event when your add-on's storage goes over its quota.
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/tabs.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/tabs.md
deleted file mode 100644
index a6a858f..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/tabs.md
+++ /dev/null
@@ -1,381 +0,0 @@
-<!-- contributed by Dietrich Ayala [dietrich@mozilla.com] -->
-<!-- edited by Noelle Murata [fiveinchpixie@gmail.com] -->
-
-The `tabs` module provides easy access to tabs and tab-related events.
-
-The module itself can be used like a basic list of all opened
-tabs across all windows. In particular, you can enumerate it:
-
- var tabs = require('tabs');
- for each (var tab in tabs)
- console.log(tab.title);
-
-You can also access individual tabs by index:
-
- var tabs = require('tabs');
-
- tabs.on('ready', function () {
- console.log('first: ' + tabs[0].title);
- console.log('last: ' + tabs[tabs.length-1].title);
- });
-
-You can open a new tab, specifying various properties including location:
-
- var tabs = require("tabs");
- tabs.open("http://www.example.com");
-
-You can register event listeners to be notified when tabs open, close, finish
-loading DOM content, or are made active or inactive:
-
- var tabs = require("tabs");
-
- // Listen for tab openings.
- tabs.on('open', function onOpen(tab) {
- myOpenTabs.push(tab);
- });
-
- // Listen for tab content loads.
- tabs.on('ready', function(tab) {
- console.log('tab is loaded', tab.title, tab.url)
- });
-
-You can get and set various properties of tabs (but note that properties
- relating to the tab's content, such as the URL, will not contain valid
-values until after the tab's `ready` event fires). By setting the `url`
-property you can load a new page in the tab:
-
- var tabs = require("tabs");
- tabs.on('activate', function(tab) {
- tab.url = "http://www.example.com";
- });
-
-You can attach a [content script](dev-guide/addon-development/web-content.html)
-to the page hosted in a tab, and use that to access and manipulate the page's
-content:
-
- var tabs = require("tabs");
-
- tabs.on('activate', function(tab) {
- tab.attach({
- contentScript: 'self.postMessage(document.body.innerHTML);',
- onMessage: function (message) {
- console.log(message);
- }
- });
- });
-
-<api name="activeTab">
-@property {Tab}
-
-The currently active tab in the active window. This property is read-only. To
-activate a `Tab` object, call its `activate` method.
-
-**Example**
-
- // Get the active tab's title.
- var tabs = require("tabs");
- console.log("title of active tab is " + tabs.activeTab.title);
-</api>
-
-<api name="length">
-@property {number}
-The number of open tabs across all windows.
-</api>
-
-<api name="open">
-@function
-Opens a new tab. The new tab will open in the active window or in a new window,
-depending on the `inNewWindow` option.
-
-**Example**
-
- var tabs = require("tabs");
-
- // Open a new tab on active window and make tab active.
- tabs.open("http://www.mysite.com");
-
- // Open a new tab in a new window and make it active.
- tabs.open({
- url: "http://www.mysite.com",
- inNewWindow: true
- });
-
- // Open a new tab on active window in the background.
- tabs.open({
- url: "http://www.mysite.com",
- inBackground: true
- });
-
- // Open a new tab as an app tab and do something once it's open.
- tabs.open({
- url: "http://www.mysite.com",
- isPinned: true,
- onOpen: function onOpen(tab) {
- // do stuff like listen for content
- // loading.
- }
- });
-
-@param options {object}
-An object containing configurable options for how and where the tab will be
-opened, as well as a listeners for the tab events.
-
-If the only option being used is `url`, then a bare string URL can be passed to
-`open` instead of adding at a property of the `options` object.
-
-@prop [url] {string}
-String URL to be opened in the new tab.
-This is a required property.
-
-@prop [inNewWindow] {boolean}
-If present and true, a new browser window will be opened and the URL will be
-opened in the first tab in that window. This is an optional property.
-
-@prop [inBackground] {boolean}
-If present and true, the new tab will be opened to the right of the active tab
-and will not be active. This is an optional property.
-
-@prop [isPinned] {boolean}
-If present and true, then the new tab will be pinned as an
-[app tab](http://support.mozilla.com/en-US/kb/what-are-app-tabs).
-
-@prop [onOpen] {function}
-A callback function that will be registered for 'open' event.
-This is an optional property.
-@prop [onClose] {function}
-A callback function that will be registered for 'close' event.
-This is an optional property.
-@prop [onReady] {function}
-A callback function that will be registered for 'ready' event.
-This is an optional property.
-@prop [onActivate] {function}
-A callback function that will be registered for 'activate' event.
-This is an optional property.
-@prop [onDeactivate] {function}
-A callback function that will be registered for 'deactivate' event.
-This is an optional property.
-</api>
-
-<api name="Tab">
-@class
-A `Tab` instance represents a single open tab. It contains various tab
-properties, several methods for manipulation, as well as per-tab event
-registration.
-
-Tabs emit all the events described in the Events section. Listeners are
-passed the `Tab` object that triggered the event.
-
-<api name="title">
-@property {string}
-The title of the page currently loaded in the tab.
-This property can be set to change the tab title.
-</api>
-
-<api name="url">
-@property {String}
-The URL of the page currently loaded in the tab.
-This property can be set to load a different URL in the tab.
-</api>
-
-<api name="favicon">
-@property {string}
-The URL of the favicon for the page currently loaded in the tab.
-This property is read-only.
-</api>
-
-<api name="index">
-@property {integer}
-The index of the tab relative to other tabs in the application window.
-This property can be set to change its relative position.
-</api>
-
-<api name="isPinned">
-@property {boolean}
-Whether or not tab is pinned as an [app tab][].
-This property is read-only.
-[app tab]:http://support.mozilla.com/en-US/kb/what-are-app-tabs
-</api>
-
-<api name="getThumbnail">
-@property {method}
-Returns thumbnail data URI of the page currently loaded in this tab.
-</api>
-
-<api name="pin">
-@method
-Pins this tab as an [app tab][].
-[app tab]:http://support.mozilla.com/en-US/kb/what-are-app-tabs
-</api>
-
-<api name="unpin">
-@method
-Unpins this tab.
-</api>
-
-<api name="close">
-@method
-Closes this tab.
-
-@param [callback] {function}
-A function to be called when the tab finishes its closing process.
-This is an optional argument.
-</api>
-
-<api name="reload">
-@method
-Reloads this tab.
-</api>
-
-<api name="activate">
-@method
-Makes this tab active, which will bring this tab to the foreground.
-</api>
-
-<api name="attach">
-@method
- Create a page mod and attach it to the document in the tab.
-
-**Example**
-
- var tabs = require("tabs");
-
- tabs.on('ready', function(tab) {
- tab.attach({
- contentScript:
- 'document.body.style.border = "5px solid red";'
- });
- });
-
-@param options {object}
- Options for the page mod, with the following keys:
-
-@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}
- A function called when the page mod receives a message from content scripts.
- Listeners are passed a single argument, the message posted from the
- content script.
-
-@returns {Worker}
- See [Content Scripts guide](dev-guide/addon-development/web-content.html)
- to learn how to use the `Worker` object to communicate with the content script.
-
-</api>
-
-<api name="close">
-@event
-
-This event is emitted when the tab is closed. It's also emitted when the
-tab's window is closed.
-
-@argument {Tab}
-Listeners are passed the tab object.
-</api>
-
-<api name="ready">
-@event
-
-This event is emitted when the DOM for the tab's content is ready. It is
-equivalent to the `DOMContentLoaded` event for the given content page.
-
-A single tab will emit this event every time the DOM is loaded: so it will be
-emitted again if the tab's location changes or the content is reloaded.
-
-After this event has been emitted, all properties relating to the tab's
-content can be used.
-
-@argument {Tab}
-Listeners are passed the tab object.
-</api>
-
-<api name="activate">
-@event
-
-This event is emitted when the tab is made active.
-
-@argument {Tab}
-Listeners are passed the tab object.
-</api>
-
-<api name="deactivate">
-@event
-
-This event is emitted when the tab is made inactive.
-
-@argument {Tab}
-Listeners are passed the tab object.
-</api>
-
-</api>
-
-<api name="open">
-@event
-
-This event is emitted when a new tab is opened. This does not mean that
-the content has loaded, only that the browser tab itself is fully visible
-to the user.
-
-Properties relating to the tab's content (for example: `title`, `favicon`,
-and `url`) will not be correct at this point. If you need to access these
-properties, listen for the `ready` event:
-
- var tabs = require("tabs");
- tabs.on('open', function(tab){
- tab.on('ready', function(tab){
- console.log(tab.url);
- });
- });
-
-@argument {Tab}
-Listeners are passed the tab object that just opened.
-</api>
-
-<api name="close">
-@event
-
-This event is emitted when a tab is closed. When a window is closed
-this event will be emitted for each of the open tabs in that window.
-
-@argument {Tab}
-Listeners are passed the tab object that has closed.
-</api>
-
-<api name="ready">
-@event
-
-This event is emitted when the DOM for a tab's content is ready.
-It is equivalent to the `DOMContentLoaded` event for the given content page.
-
-A single tab will emit this event every time the DOM is loaded: so it will be
-emitted again if the tab's location changes or the content is reloaded.
-
-After this event has been emitted, all properties relating to the tab's
-content can be used.
-
-@argument {Tab}
-Listeners are passed the tab object that has loaded.
-</api>
-
-<api name="activate">
-@event
-
-This event is emitted when an inactive tab is made active.
-
-@argument {Tab}
-Listeners are passed the tab object that has become active.
-</api>
-
-<api name="deactivate">
-@event
-
-This event is emitted when the active tab is made inactive.
-
-@argument {Tab}
-Listeners are passed the tab object that has become inactive.
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/timers.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/timers.md
deleted file mode 100644
index bc36750..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/timers.md
+++ /dev/null
@@ -1,48 +0,0 @@
-<!-- contributed by Drew Willcoxon [adw@mozilla.com] -->
-<!-- contributed by Atul Varma [atul@mozilla.com] -->
-<!-- edited by Noelle Murata [fiveinchpixie@gmail.com] -->
-<!-- contributed by Irakli Gozalishvil [gozala@mozilla.com] -->
-
-The `timers` module provides access to web-like timing functionality.
-
-<api name="setTimeout">
-@function
- Schedules `callback` to be called in `ms` milliseconds. Any additional
- arguments are passed straight through to the callback.
-@returns {integer}
- An ID that can later be used to undo this scheduling, if `callback` hasn't yet
- been called.
-@param callback {function}
- Function to be called.
-@param ms {integer}
- Interval in milliseconds after which the function will be called.
-</api>
-
-<api name="clearTimeout">
-@function
- Given an ID returned from `setTimeout()`, prevents the callback with the ID
- from being called (if it hasn't yet been called).
-@param ID {integer}
- An ID returned from `setTimeout()`.
-</api>
-
-<api name="setInterval">
-@function
- Schedules `callback` to be called repeatedly every `ms` milliseconds. Any
- additional arguments are passed straight through to the callback.
-@returns {integer}
- An ID that can later be used to unschedule the callback.
-@param callback {function}
- Function to be called.
-@param ms {integer}
- Interval in milliseconds at which the function will be called.
-</api>
-
-<api name="clearInterval">
-@function
- Given an ID returned from `setInterval()`, prevents the callback with the ID
- from being called again.
-@param ID {integer}
- An ID returned from `setInterval()`.
-</api>
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/widget.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/widget.md
deleted file mode 100644
index aa12cbe..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/widget.md
+++ /dev/null
@@ -1,692 +0,0 @@
-<!-- contributed by Dietrich Ayala [dietrich@mozilla.com] -->
-<!-- contributed by Drew Willcoxon [adw@mozilla.com] -->
-<!-- edited by Noelle Murata [fiveinchpixie@gmail.com] -->
-
-The `widget` module provides your add-on with a simple user interface that is
-consistent with other add-ons and blends in well with Firefox.
-
-## Introduction ##
-
-"Widgets" are small pieces of content that live in the Firefox 4
-[add-on bar](https://developer.mozilla.org/en/The_add-on_bar).
-They can be simple icons or complex web pages. You can attach
-[panels](packages/addon-kit/docs/panel.html) to them that open when they're
-clicked, or you can define a custom click handler to perform some other action,
-like opening a web page in a tab.
-
-There are a few advantages to using widgets over an ad hoc user interface.
-First, your users will be accustomed to interacting with add-ons via widgets and
-the add-on bar. Second, it allows Firefox to treat your interface as a
-first-class citizen. For example, in the future Firefox may allow the user to
-drag widgets from the add-on bar to other toolbars. By exposing your interface
-as a widget, your add-on would automatically inherit such functionality.
-
-## Creation and Content ##
-
-Widgets can contain images or arbitrary web content. You can include this
-content inline as a string by using the `content` property, or point to content
-using a URL with the `contentURL` property.
-
-For example, this widget contains an image, so it looks like a simple icon:
-
- require("widget").Widget({
- id: "mozilla-icon",
- label: "My Mozilla Widget",
- contentURL: "http://www.mozilla.org/favicon.ico"
- });
-
-Upon creation, the widget is automatically added to the add-on bar.
-You can set the width of a widget, but the height is fixed so as to fit in the
-add-on bar. If the content is an image, it is automatically scaled to be 16x16
-pixels.
-
-This widget contains an entire web page:
-
- require("widget").Widget({
- id: "hello-display",
- label: "My Hello Widget",
- content: "Hello!",
- width: 50
- });
-
-Widgets are quite small by default, so this example used the `width` property to
-grow it in order to show all the text.
-
-As with many SDK APIs, communication with the content inside your widgets is
-handled by [content scripts](dev-guide/addon-development/web-content.html).
-So, for example, to be notified when your widget's content has loaded, you can
-make a small script that calls back to the widget when it finishes loading.
-
-## Attaching Panels to Widgets ##
-
-You can supply a [panel](packages/addon-kit/docs/panel.html) to the widget's
-constructor: if you do this, the panel is automatically displayed when the
-user clicks the widget.
-
-<!-- The icon the widget displays, shown in the screenshot, is taken from the
-Circular icon set, http://prothemedesign.com/circular-icons/ which is made
-available under the Creative Commons Attribution 2.5 Generic License:
-http://creativecommons.org/licenses/by/2.5/ -->
-
-<img class="image-right" src="static-files/media/screenshots/widget-panel-clock.png"
-alt="Panel attached to a widget">
-
- data = require("self").data
-
- var clockPanel = require("panel").Panel({
- width:215,
- height:160,
- contentURL: data.url("clock.html")
- });
-
- require("widget").Widget({
- id: "open-clock-btn",
- label: "Clock",
- contentURL: data.url("History.png"),
- panel: clockPanel
- });
-
-Note that this is, at the moment, the only way you can attach a panel to a widget.
-
-You must supply the panel in the widget's constructor for it to work. If you
-assign the panel to the widget after construction, the panel can still be shown
-but will not be anchored to the widget:
-
- data = require("self").data
-
- var clockPanel = require("panel").Panel({
- width:215,
- height:160,
- contentURL: data.url("clock.html")
- });
-
- widget = require("widget").Widget({
- id: "open-clock-btn",
- label: "Clock",
- contentURL: data.url("History.png")
- });
-
- widget.panel = clockPanel;
-
- // Will not be anchored
- widget.panel.show();
-
-Also, if you try to call `panel.show()` inside your widget's `click` event
-listener, the panel will not be anchored:
-
- data = require("self").data
-
- var clockPanel = require("panel").Panel({
- width:215,
- height:160,
- contentURL: data.url("clock.html")
- });
-
- require("widget").Widget({
- id: "open-clock-btn",
- label: "Clock",
- contentURL: data.url("History.png"),
- panel: clockPanel,
- onClick: function() {
- // Will not be anchored
- this.panel.show();
- }
- });
-
-See [bug 638142](https://bugzilla.mozilla.org/show_bug.cgi?id=638142).
-
-## Examples ##
-
-For conciseness, these examples create their content scripts as strings and use
-the `contentScript` property. In your own add-ons, you will probably want to
-create your content scripts in separate files and pass their URLs using the
-`contentScriptFile` property. See
-[Working with Content Scripts](dev-guide/addon-development/web-content.html) for more
-information.
-
- var widgets = require("widget");
-
- // A basic click-able image widget.
- widgets.Widget({
- id: "google-link",
- label: "Widget with an image and a click handler",
- contentURL: "http://www.google.com/favicon.ico",
- onClick: function() {
- require("tabs").activeTab.url = "http://www.google.com/";
- }
- });
-<br>
-
- // A widget that changes display on mouseover.
- widgets.Widget({
- id: "mouseover-effect",
- label: "Widget with changing image on mouseover",
- contentURL: "http://www.yahoo.com/favicon.ico",
- onMouseover: function() {
- this.contentURL = "http://www.bing.com/favicon.ico";
- },
- onMouseout: function() {
- this.contentURL = "http://www.yahoo.com/favicon.ico";
- }
- });
-<br>
-
- // A widget that updates content on a timer.
- widgets.Widget({
- id: "auto-update-widget",
- label: "Widget that updates content on a timer",
- content: "0",
- contentScript: 'setTimeout(function() {' +
- ' document.body.innerHTML++;' +
- '}, 2000)',
- contentScriptWhen: "ready"
- });
-<br>
-
- // A widget that loads a random Flickr photo every 5 minutes.
- widgets.Widget({
- id: "random-flickr",
- label: "Random Flickr Photo Widget",
- contentURL: "http://www.flickr.com/explore/",
- contentScriptWhen: "ready",
- contentScript: 'postMessage(document.querySelector(".pc_img").src);' +
- 'setTimeout(function() {' +
- ' document.location = "http://www.flickr.com/explore/";' +
- '}, 5 * 60 * 1000);',
- onMessage: function(imgSrc) {
- this.contentURL = imgSrc;
- },
- onClick: function() {
- require("tabs").activeTab.url = this.contentURL;
- }
- });
-<br>
-
- // A widget created with a specified width, that grows.
- let myWidget = widgets.Widget({
- id: "widget-effect",
- label: "Wide widget that grows wider on a timer",
- content: "I'm getting longer.",
- width: 50,
- });
- require("timers").setInterval(function() {
- myWidget.width += 10;
- }, 1000);
-<br>
-
- // A widget communicating bi-directionally with a content script.
- let widget = widgets.Widget({
- id: "message-test",
- label: "Bi-directional communication!",
- content: "<foo>bar</foo>",
- contentScriptWhen: "ready",
- contentScript: 'on("message", function(message) {' +
- ' alert("Got message: " + message);' +
- '});' +
- 'postMessage("ready");',
- onMessage: function(message) {
- if (message == "ready")
- widget.postMessage("me too");
- }
- });
-
-<api-name="Widget">
-@class
-Represents a widget object.
-
-<api name="Widget">
-@constructor {options}
- Creates a new widget. The widget is immediately added to the add-on bar.
-
-@param options {object}
- An object with the following keys:
-
- @prop label {string}
- A required string description of the widget used for accessibility,
- title bars, and error reporting.
-
- @prop id {string}
- Mandatory string used to identify your widget in order to save its
- location when the user moves it in the browser.
- This string has to be unique and must not be changed over time.
-
- @prop [content] {string}
- An optional string value containing the displayed content of the widget.
- It may contain HTML. Widgets must have either the `content` property or the
- `contentURL` property set.
-
- If the content is an image, it is automatically scaled to be 16x16 pixels.
-
- @prop [contentURL] {string}
- An optional string URL to content to load into the widget. This can be
- [local content](dev-guide/addon-development/web-content.html) or remote
- content, an image or web content. Widgets must have either the `content`
- property or the `contentURL` property set.
-
- If the content is an image, it is automatically scaled to be 16x16 pixels.
-
- @prop [panel] {Panel}
- An optional [panel](packages/addon-kit/docs/panel.html) to open when the
- user clicks on the widget. Note: If you also register a "click" listener,
- it will be called instead of the panel being opened. However, you can show
- the panel from the listener by calling `this.panel.show()`.
-
- @prop [width] {integer}
- Optional width in pixels of the widget. If not given, a default width is
- used.
-
- @prop [onClick] {function}
- Include this to listen to the widget's `click` event.
-
- @prop [onMessage] {function}
- Include this to listen to the widget's `message` event.
-
- @prop [onMouseover] {function}
- Include this to listen to the widget's `mouseover` event.
-
- @prop [onMouseout] {function}
- Include this to listen to the widget's `mouseout` event.
-
- @prop [onAttach] {function}
- Include this to listen to the widget's `attach` event.
-
- @prop [tooltip] {string}
- Optional text to show when the user's mouse hovers over the widget. If not
- given, the `label` is used.
-
- @prop [allow] {object}
- An optional object describing permissions for the content. It should
- contain a single key named `script` whose value is a boolean that indicates
- whether or not to execute script in the content. `script` defaults to true.
-
- @prop [contentScriptFile] {string,array}
- A local file URL or an array of local file URLs of content scripts to load.
- Content scripts specified by this property are loaded *before* those
- specified by the `contentScript` property.
-
- @prop [contentScript] {string,array}
- A string or an array of strings containing the texts of content scripts to
- load. Content scripts specified by this property are loaded *after* those
- specified by the `contentScriptFile` property.
-
- @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 widget 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 widget 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".
-
-</api>
-
-<api name="destroy">
-@method
- Removes the widget from the add-on bar.
-</api>
-
-<api name="postMessage">
-@method
- Sends a message to the widget's content scripts.
-@param data {value}
- The message to send.
- The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-<api name="on">
-@method
- Registers an event listener with the widget.
-@param type {string}
- The type of event to listen for.
-@param listener {function}
- The listener function that handles the event.
-</api>
-
-<api name="removeListener">
-@method
- Unregisters an event listener from the widget.
-@param type {string}
- The type of event for which `listener` was registered.
-@param listener {function}
- The listener function that was registered.
-</api>
-
-<api name="getView">
-@method
- Retrieve a `WidgetView` instance of this widget relative to a browser window.
-@param window {BrowserWindow}
- The [BrowserWindow](packages/addon-kit/docs/windows.html) instance to match.
-@returns {WidgetView}
- A `WidgetView` instance associated with the browser window. Any changes
- subsequently applied to this object will only be applied to the widget
- attached to that window.
-</api>
-
-<api name="label">
-@property {string}
- The widget's label. Read-only.
-</api>
-
-<api name="content">
-@property {string}
- A string containing the widget's content. It can contain HTML. Setting it
- updates the widget's appearance immediately. However, if the widget was
- created using `contentURL`, then this property is meaningless, and setting it
- has no effect.
-</api>
-
-<api name="contentURL">
-@property {string}
- The URL of content to load into the widget. This can be
- [local content](dev-guide/addon-development/web-content.html) or remote
- content, an image or web content. Setting it updates the widget's appearance
- immediately. However, if the widget was created using `content`, then this
- property is meaningless, and setting it has no effect.
-</api>
-
-<api name="panel">
-@property {Panel}
- A [panel](packages/addon-kit/docs/panel.html) to open when the user clicks on
- the widget.
-</api>
-
-<api name="width">
-@property {number}
- The widget's width in pixels. Setting it updates the widget's appearance
- immediately.
-</api>
-
-<api name="tooltip">
-@property {string}
- The text of the tooltip that appears when the user hovers over the widget.
-</api>
-
-<api name="allow">
-@property {object}
- A object describing permissions for the content. It contains a single key
- named `script` whose value is a boolean that indicates whether or not to
- execute script in the content.
-</api>
-
-<api name="contentScriptFile">
-@property {string,array}
- A local file URL or an array of local file URLs of content scripts to load.
-</api>
-
-<api name="contentScript">
-@property {string,array}
- A string or an array of strings containing the texts of content scripts to
- load.
-</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 widget 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 widget has been loaded, at the time the
- [window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
- fires
-
-</api>
-
-<api name="port">
-@property {EventEmitter}
-[EventEmitter](packages/api-utils/docs/events.html) object that allows you to:
-
-* send events to the content script using the `port.emit` function
-* receive events from the content script using the `port.on` function
-
-See the guide to
-<a href="dev-guide/addon-development/content-scripts/using-port.html">
-communicating using <code>port</code></a> for details.
-</api>
-
-<api name="attach">
-@event
-This event is emitted when a new `WidgetView` object is created using the
-`getView()` function.
-</api>
-
-<api name="click">
-@event
-This event is emitted when the widget is clicked.
-</api>
-
-<api name="message">
-@event
-If you listen to this event you can receive message events from content
-scripts associated with this widget. When a content script posts a
-message using `self.postMessage()`, the message is delivered to the add-on
-code in the widget's `message` event.
-
-@argument {value}
-Listeners are passed a single argument which is the message posted
-from the content script. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-<api name="mouseover">
-@event
-This event is emitted when the user moves the mouse over the widget.
-</api>
-
-<api name="mouseout">
-@event
-This event is emitted when the user moves the mouse away from the widget.
-</api>
-
-</api>
-
-
-<api-name="WidgetView">
-@class
-Represents a widget instance specific to one browser window.
-
-Anything you do to an instance of this object will only be applied to the
-instance attached to its browser window: widget instances attached to other
-browser windows will be unaffected.
-
-By contrast, any changes you make to an instance of the normal `Widget` class
-will be applied across all browser windows.
-
-This class has all the same methods, attributes and events as the `Widget`
-class except for the `getView` method and the `attach` event.
-
-In this example `WidgetView` is used to display different content for
-`http` and `https` schemes:
-
- // A widget that update its content specifically to each window.
- let tabs = require("tabs");
- let windows = require("windows").browserWindows;
- let widget = widgets.Widget({
- id: "window-specific-test",
- label: "Widget with content specific to each window",
- content: " ",
- width: 50
- });
- // Observe tab switch or document changes in each existing tab:
- function updateWidgetState(tab) {
- let view = widget.getView(tab.window);
- if (!view) return;
- // Update widget displayed text:
- view.content = tab.url.match(/^https/) ? "Secured" : "Unsafe";
- }
- tabs.on('ready', updateWidgetState);
- tabs.on('activate', updateWidgetState);
-
-<api name="destroy">
-@method
- Removes the widget view from the add-on bar.
-</api>
-
-<api name="postMessage">
-@method
- Sends a message to the widget view's content scripts.
-@param data {value}
- The message to send. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-<api name="on">
-@method
- Registers an event listener with the widget view.
-@param type {string}
- The type of event to listen for.
-@param listener {function}
- The listener function that handles the event.
-</api>
-
-<api name="removeListener">
-@method
- Unregisters an event listener from the widget view.
-@param type {string}
- The type of event for which `listener` was registered.
-@param listener {function}
- The listener function that was registered.
-</api>
-
-<api name="label">
-@property {string}
- The widget view's label. Read-only.
-</api>
-
-<api name="content">
-@property {string}
- A string containing the widget view's content. It can contain HTML.
- Setting it updates the widget view's appearance immediately. However,
- if the widget view was created using `contentURL`, then this property
- is meaningless, and setting it has no effect.
-</api>
-
-<api name="contentURL">
-@property {string}
- The URL of content to load into the widget view. This can be
- [local content](dev-guide/addon-development/web-content.html) or remote
- content, an image or web content. Setting it updates the widget view's
- appearance immediately. However, if the widget view was created using
- `content`, then this property is meaningless, and setting it has no effect.
-</api>
-
-<api name="panel">
-@property {Panel}
- A [panel](packages/addon-kit/docs/panel.html) to open when the user clicks on
- the widget view.
-</api>
-
-<api name="width">
-@property {number}
- The widget view's width in pixels. Setting it updates the widget view's
- appearance immediately.
-</api>
-
-<api name="tooltip">
-@property {string}
- The text of the tooltip that appears when the user hovers over the widget
- view.
-</api>
-
-<api name="allow">
-@property {object}
- A object describing permissions for the content. It contains a single key
- named `script` whose value is a boolean that indicates whether or not to
- execute script in the content.
-</api>
-
-<api name="contentScriptFile">
-@property {string,array}
- A local file URL or an array of local file URLs of content scripts to load.
-</api>
-
-<api name="contentScript">
-@property {string,array}
- A string or an array of strings containing the texts of content scripts to
- load.
-</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 widget view 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 widget view has been loaded, at the time the
- [window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
- fires
-
-</api>
-
-<api name="port">
-@property {EventEmitter}
-[EventEmitter](packages/api-utils/docs/events.html) object that allows you to:
-
-* send events to the content script using the `port.emit` function
-* receive events from the content script using the `port.on`
-
-See the guide to
-<a href="dev-guide/addon-development/content-scripts/using-port.html">
-communicating using <code>port</code></a> for details.
-</api>
-
-<api name="detach">
-@event
-The `detach` event is fired when the widget view is removed from its related
-window.
-This can occur if the window is closed, Firefox exits, or the add-on is
-disabled.
-</api>
-
-<api name="click">
-@event
-This event is emitted when the widget view is clicked.
-</api>
-
-<api name="message">
-@event
-If you listen to this event you can receive message events from content
-scripts associated with this widget view. When a content script posts a
-message using `self.postMessage()`, the message is delivered to the add-on
-code in the widget view's `message` event.
-
-@argument {value}
-Listeners are passed a single argument which is the message posted
-from the content script. The message can be any
-<a href = "dev-guide/addon-development/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-</api>
-
-<api name="mouseover">
-@event
-This event is emitted when the user moves the mouse over the widget view.
-</api>
-
-<api name="mouseout">
-@event
-This event is emitted when the user moves the mouse away from the widget view.
-</api>
-
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/docs/windows.md b/tools/addon-sdk-1.4/packages/addon-kit/docs/windows.md
deleted file mode 100644
index a5bed95..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/docs/windows.md
+++ /dev/null
@@ -1,187 +0,0 @@
-<!-- contributed by Felipe Gomes [felipc@gmail.com] -->
-
-
-The `windows` module provides easy access to browser windows, their
-tabs, and open/close related functions and events.
-
-This module currently only supports browser windows and does not provide
-access to non-browser windows such as the Bookmarks Library, preferences
-or other non-browser windows created via add-ons.
-
-<api name="browserWindows">
-@property {List}
-An object that contains various properties and methods to access
-functionality from browser windows, such as opening new windows, accessing
-their tabs or switching the current active window.
-
-`browserWindows` provides access to all the currently open browser windows:
-
- var windows = require("windows");
- for each (var window in windows.browserWindows) {
- console.log(window.title);
- }
-
- console.log(windows.browserWindows.length);
-
-Object emits all the events listed under "Events" section.
-
-####Examples####
-
- var windows = require("windows").browserWindows;
-
- // add a listener to the 'open' event
- windows.on('open', function(window) {
- myOpenWindows.push(window);
- });
-
- // add a listener to the 'close' event
- windows.on('close', function(window) {
- console.log("A window was closed.");
- });
-
-<api name="activeWindow">
-@property {BrowserWindow}
-
-The currently active window. This property is read-only.
-
-**Example**
-
- // get
- var windows = require("windows");
- console.log("title of active window is " +
- windows.browserWindows.activeWindow.title);
-
- anotherWindow.activate();
- // set
- windows.activeWindow == anotherWindow // true
-</api>
-
-</api>
-
-<api name="open">
-@function
-Open a new window.
-
- var windows = require("windows").browserWindows;
-
- // Open a new window.
- windows.open("http://www.example.com");
-
- // Open a new window and set a listener for "open" event.
- windows.open({
- url: "http://www.example.com",
- onOpen: function(window) {
- // do stuff like listen for content
- // loading.
- }
- });
-
-Returns the window that was opened:
-
- var widgets = require("widget");
- var windows = require("windows").browserWindows;
-
- var example = windows.open("http://www.example.com");
-
- var widget = widgets.Widget({
- id: "close-window",
- label: "Close window",
- contentURL: "http://www.mozilla.org/favicon.ico",
- onClick: function() {
- example.close();
- }
- });
-
-@param options {object}
-An object containing configurable options for how this window will be opened,
-as well as a callback for being notified when the window has fully opened.
-
-If the only option being used is `url`, then a bare string URL can be passed to
-`open` instead of specifying it as a property of the `options` object.
-
-@prop url {string}
-String URL to be opened in the new window.
-This is a required property.
-
-@prop [onOpen] {function}
-A callback function that is called when the window has opened. This does not
-mean that the URL content has loaded, only that the window itself is fully
-functional and its properties can be accessed. This is an optional property.
-
-@prop [onClose] {function}
-A callback function that is called when the window will be called.
-This is an optional property.
-
-@returns {BrowserWindow}
-</api>
-
-<api name="BrowserWindow">
-@class
-A `BrowserWindow` instance represents a single open window. They can be
-retrieved from the `browserWindows` property exported by this module.
-
- var windows = require("windows").browserWindows;
-
- //Print how many tabs the current window has
- console.log("The active window has " +
- windows.activeWindow.tabs.length +
- " tabs.");
-
- // Print the title of all browser windows
- for each (var window in windows) {
- console.log(window.title);
- }
-
- // close the active window
- windows.activeWindow.close();
-
- windows.activeWindow.close(function() {
- console.log("The active window was closed");
- });
-
-<api name="title">
-@property {string}
-The current title of the window. Usually the title of the active tab,
-plus an app identifier.
-This property is read-only.
-</api>
-
-<api name="tabs">
-@property {TabList}
-A live list of tabs in this window. This object has the same interface as the
-[`tabs` API](packages/addon-kit/docs/tabs.html), except it contains only the
-tabs in this window, not all tabs in all windows. This property is read-only.
-</api>
-
-<api name="activate">
-@method
-Makes window active, which will focus that window and bring it to the
-foreground.
-</api>
-
-<api name="close">
-@method
-Close the window.
-
-@param [callback] {function}
-A function to be called when the window finishes its closing process.
-This is an optional argument.
-</api>
-
-</api>
-
-<api name="open">
-@event
-Event emitted when a new window is open.
-This does not mean that the content has loaded, only that the browser window
-itself is fully visible to the user.
-@argument {Window}
-Listeners are passed the `window` object that triggered the event.
-</api>
-
-<api name="close">
-@event
-Event emitted when a window is closed.
-@argument {Window}
-Listeners are passed the `window` object that triggered the event.
-</api>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/clipboard.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/clipboard.js
deleted file mode 100644
index 24f4641..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/clipboard.js
+++ /dev/null
@@ -1,266 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Paul O’Shannessy <paul@oshannessy.com> (Original Author)
- * Dietrich Ayala <dietrich@mozilla.com>
- * Myk Melez <myk@mozilla.org>
- * Erik Vold <erikvvold@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const {Cc,Ci} = require("chrome");
-const errors = require("api-utils/errors");
-const apiUtils = require("api-utils/api-utils");
-
-/*
-While these data flavors resemble Internet media types, they do
-no directly map to them.
-*/
-const kAllowableFlavors = [
- "text/unicode",
- "text/html"
- /* CURRENTLY UNSUPPORTED FLAVORS
- "text/plain",
- "image/png",
- "image/jpg",
- "image/gif"
- "text/x-moz-text-internal",
- "AOLMAIL",
- "application/x-moz-file",
- "text/x-moz-url",
- "text/x-moz-url-data",
- "text/x-moz-url-desc",
- "text/x-moz-url-priv",
- "application/x-moz-nativeimage",
- "application/x-moz-nativehtml",
- "application/x-moz-file-promise-url",
- "application/x-moz-file-promise-dest-filename",
- "application/x-moz-file-promise",
- "application/x-moz-file-promise-dir"
- */
-];
-
-/*
-Aliases for common flavors. Not all flavors will
-get an alias. New aliases must be approved by a
-Jetpack API druid.
-*/
-const kFlavorMap = [
- { short: "text", long: "text/unicode" },
- { short: "html", long: "text/html" }
- // Images are currently unsupported.
- //{ short: "image", long: "image/png" },
-];
-
-let clipboardService = Cc["@mozilla.org/widget/clipboard;1"].
- getService(Ci.nsIClipboard);
-
-let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
- getService(Ci.nsIClipboardHelper);
-
-
-exports.set = function(aData, aDataType) {
- let options = {
- data: aData,
- datatype: aDataType || "text"
- };
- options = apiUtils.validateOptions(options, {
- data: {
- is: ["string"]
- },
- datatype: {
- is: ["string"]
- }
- });
-
- var flavor = fromJetpackFlavor(options.datatype);
-
- if (!flavor)
- throw new Error("Invalid flavor");
-
- // Additional checks for using the simple case
- if (flavor == "text/unicode") {
- clipboardHelper.copyString(options.data);
- return true;
- }
-
- // Below are the more complex cases where we actually have to work with a
- // nsITransferable object
- var xferable = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- if (!xferable)
- throw new Error("Couldn't set the clipboard due to an internal error " +
- "(couldn't create a Transferable object).");
-
- switch (flavor) {
- case "text/html":
- // add text/html flavor
- let (str = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString))
- {
- str.data = options.data;
- xferable.addDataFlavor(flavor);
- xferable.setTransferData(flavor, str, str.data.length * 2);
- }
-
- // add a text/unicode flavor (html converted to plain text)
- let (str = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString),
- converter = Cc["@mozilla.org/feed-textconstruct;1"].
- createInstance(Ci.nsIFeedTextConstruct))
- {
- converter.type = "html";
- converter.text = options.data;
- str.data = converter.plainText();
- xferable.addDataFlavor("text/unicode");
- xferable.setTransferData("text/unicode", str, str.data.length * 2);
- }
- break;
- // TODO: images!
- default:
- throw new Error("Unable to handle the flavor " + flavor + ".");
- }
-
- // TODO: Not sure if this will ever actually throw. -zpao
- try {
- clipboardService.setData(
- xferable,
- null,
- clipboardService.kGlobalClipboard
- );
- } catch (e) {
- throw new Error("Couldn't set clipboard data due to an internal error: " + e);
- }
- return true;
-};
-
-
-exports.get = function(aDataType) {
- let options = {
- datatype: aDataType || "text"
- };
- options = apiUtils.validateOptions(options, {
- datatype: {
- is: ["string"]
- }
- });
-
- var xferable = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- if (!xferable)
- throw new Error("Couldn't set the clipboard due to an internal error " +
- "(couldn't create a Transferable object).");
-
- var flavor = fromJetpackFlavor(options.datatype);
-
- // Ensure that the user hasn't requested a flavor that we don't support.
- if (!flavor)
- throw new Error("Getting the clipboard with the flavor '" + flavor +
- "' is > not supported.");
-
- // TODO: Check for matching flavor first? Probably not worth it.
-
- xferable.addDataFlavor(flavor);
-
- // Get the data into our transferable.
- clipboardService.getData(
- xferable,
- clipboardService.kGlobalClipboard
- );
-
- var data = {};
- var dataLen = {};
- try {
- xferable.getTransferData(flavor, data, dataLen);
- } catch (e) {
- // Clipboard doesn't contain data in flavor, return null.
- return null;
- }
-
- // There's no data available, return.
- if (data.value === null)
- return null;
-
- // TODO: Add flavors here as we support more in kAllowableFlavors.
- switch (flavor) {
- case "text/unicode":
- case "text/html":
- data = data.value.QueryInterface(Ci.nsISupportsString).data;
- break;
- default:
- data = null;
- }
-
- return data;
-};
-
-exports.__defineGetter__("currentFlavors", function() {
- // Loop over kAllowableFlavors, calling hasDataMatchingFlavors for each.
- // This doesn't seem like the most efficient way, but we can't get
- // confirmation for specific flavors any other way. This is supposed to be
- // an inexpensive call, so performance shouldn't be impacted (much).
- var currentFlavors = [];
- for each (var flavor in kAllowableFlavors) {
- var matches = clipboardService.hasDataMatchingFlavors(
- [flavor],
- 1,
- clipboardService.kGlobalClipboard
- );
- if (matches)
- currentFlavors.push(toJetpackFlavor(flavor));
- }
- return currentFlavors;
-});
-
-// SUPPORT FUNCTIONS ////////////////////////////////////////////////////////
-
-function toJetpackFlavor(aFlavor) {
- for each (let flavorMap in kFlavorMap)
- if (flavorMap.long == aFlavor)
- return flavorMap.short;
- // Return null in the case where we don't match
- return null;
-}
-
-function fromJetpackFlavor(aJetpackFlavor) {
- // TODO: Handle proper flavors better
- for each (let flavorMap in kFlavorMap)
- if (flavorMap.short == aJetpackFlavor || flavorMap.long == aJetpackFlavor)
- return flavorMap.long;
- // Return null in the case where we don't match.
- return null;
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/context-menu.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/context-menu.js
deleted file mode 100644
index c9f00f9..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/context-menu.js
+++ /dev/null
@@ -1,1526 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Drew Willcoxon <adw@mozilla.com> (Original Author)
- * Irakli Gozalishvili <gozala@mozilla.com>
- * Matteo Ferretti <zer0@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const {Ci} = require("chrome");
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The context-menu module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-const apiUtils = require("api-utils/api-utils");
-const collection = require("api-utils/collection");
-const { Worker } = require("api-utils/content");
-const url = require("api-utils/url");
-const { MatchPattern } = require("api-utils/match-pattern");
-const { EventEmitterTrait: EventEmitter } = require("api-utils/events");
-const observerServ = require("api-utils/observer-service");
-const jpSelf = require("self");
-const winUtils = require("api-utils/window-utils");
-const { Trait } = require("api-utils/light-traits");
-const { Cortex } = require("api-utils/cortex");
-const timer = require("timer");
-
-// All user items we add have this class name.
-const ITEM_CLASS = "jetpack-context-menu-item";
-
-// Items in the top-level context menu also have this class.
-const TOPLEVEL_ITEM_CLASS = "jetpack-context-menu-item-toplevel";
-
-// Items in the overflow submenu also have this class.
-const OVERFLOW_ITEM_CLASS = "jetpack-context-menu-item-overflow";
-
-// The ID of the menu separator that separates standard context menu items from
-// our user items.
-const SEPARATOR_ID = "jetpack-context-menu-separator";
-
-// If more than this number of items are added to the context menu, all items
-// overflow into a "Jetpack" submenu.
-const OVERFLOW_THRESH_DEFAULT = 10;
-const OVERFLOW_THRESH_PREF =
- "extensions.addon-sdk.context-menu.overflowThreshold";
-
-// The label of the overflow sub-xul:menu.
-//
-// TODO: Localize this.
-const OVERFLOW_MENU_LABEL = "Add-ons";
-
-// The ID of the overflow sub-xul:menu.
-const OVERFLOW_MENU_ID = "jetpack-content-menu-overflow-menu";
-
-// The ID of the overflow submenu's xul:menupopup.
-const OVERFLOW_POPUP_ID = "jetpack-content-menu-overflow-popup";
-
-// These are used by PageContext.isCurrent below. If the popupNode or any of
-// its ancestors is one of these, Firefox uses a tailored context menu, and so
-// the page context doesn't apply.
-const NON_PAGE_CONTEXT_ELTS = [
- Ci.nsIDOMHTMLAnchorElement,
- Ci.nsIDOMHTMLAppletElement,
- Ci.nsIDOMHTMLAreaElement,
- Ci.nsIDOMHTMLButtonElement,
- Ci.nsIDOMHTMLCanvasElement,
- Ci.nsIDOMHTMLEmbedElement,
- Ci.nsIDOMHTMLImageElement,
- Ci.nsIDOMHTMLInputElement,
- Ci.nsIDOMHTMLMapElement,
- Ci.nsIDOMHTMLMediaElement,
- Ci.nsIDOMHTMLMenuElement,
- Ci.nsIDOMHTMLObjectElement,
- Ci.nsIDOMHTMLOptionElement,
- Ci.nsIDOMHTMLSelectElement,
- Ci.nsIDOMHTMLTextAreaElement,
-];
-
-// This is used to access private properties of Item and Menu instances.
-const PRIVATE_PROPS_KEY = {
- valueOf: function valueOf() "private properties key"
-};
-
-// Used as an internal ID for items and as part of a public ID for item DOM
-// elements. Careful: This number is not necessarily unique to any one instance
-// of the module. For each module instance, when the first item is created this
-// number will be 0, when the second is created it will be 1, and so on.
-let nextItemID = 0;
-
-// The number of items that haven't finished initializing yet. See
-// AIT__finishActiveItemInit().
-let numItemsWithUnfinishedInit = 0;
-
-exports.Item = Item;
-exports.Menu = Menu;
-exports.Separator = Separator;
-
-
-// A word about traits and privates. `this` inside of traits methods is an
-// object private to the implementation. It should never be publicly leaked.
-// We use Cortex in the exported menu item constructors to create public
-// reflections of the private objects that hide private properties -- those
-// prefixed with an underscore. Public reflections are attached to the private
-// objects via the `_public` property.
-//
-// All item objects passed into the implementation by the client will be public
-// reflections, not private objects. Likewise, all item objects passed out of
-// the implementation to the client must be public, not private. Mixing up
-// public and private is bad and easy to do, so not only are private objects
-// restricted to the implementation, but as much as possible we try to restrict
-// them to the Item, Menu, and Separator traits and constructors. Everybody
-// else in the implementation should expect to be passed public reflections, and
-// they must specifically request private objects via privateItem().
-
-// Item, Menu, and Separator are composed of this trait.
-const ItemBaseTrait = Trait({
-
- _initBase: function IBT__initBase(opts, optRules, optsToNotSet) {
- this._optRules = optRules;
- for (let optName in optRules)
- if (optsToNotSet.indexOf(optName) < 0)
- this[optName] = opts[optName];
- optsToNotSet.forEach(function (opt) validateOpt(opts[opt], optRules[opt]));
- this._isInited = true;
-
- this._id = nextItemID++;
- this._parentMenu = null;
-
- // This makes the private properties accessible to anyone with access to
- // PRIVATE_PROPS_KEY. Barring loader tricks, only this file has has access
- // to it, so only this file has access to the private properties.
- const self = this;
- this.valueOf = function IBT_valueOf(key) {
- return key === PRIVATE_PROPS_KEY ? self : self._public;
- };
- },
-
- destroy: function IBT_destroy() {
- if (this._wasDestroyed)
- return;
- if (this.parentMenu)
- this.parentMenu.removeItem(this._public);
- else if (!(this instanceof Separator) && this._hasFinishedInit)
- browserManager.removeTopLevelItem(this._public);
- browserManager.unregisterItem(this._public);
- this._wasDestroyed = true;
- },
-
- get parentMenu() {
- return this._parentMenu;
- },
-
- set parentMenu(val) {
- throw new Error("The 'parentMenu' property is not intended to be set. " +
- "Use menu.addItem(item) instead.");
- },
-
- set _isTopLevel(val) {
- if (val)
- this._workerReg = new WorkerRegistry(this._public);
- else {
- this._workerReg.destroy();
- delete this._workerReg;
- }
- },
-
- get _topLevelItem() {
- let topLevelItem = this._public;
- let parentMenu = this.parentMenu;
- while (parentMenu) {
- topLevelItem = parentMenu;
- parentMenu = parentMenu.parentMenu;
- }
- return topLevelItem;
- }
-});
-
-// Item and Menu are composed of this trait.
-const ActiveItemTrait = Trait.compose(ItemBaseTrait, EventEmitter, Trait({
-
- _initActiveItem: function AIT__initActiveItem(opts, optRules, optsToNotSet) {
- this._initBase(opts, optRules,
- optsToNotSet.concat(["onMessage", "context"]));
-
- if ("onMessage" in opts)
- this.on("message", opts.onMessage);
-
- // When a URL context is removed (by calling context.remove(urlContext)), we
- // may need to create workers for windows containing pages that the item now
- // matches. Likewise, when a URL context is added, we need to destroy
- // workers for windows containing pages that the item now does not match.
- //
- // collection doesn't provide a way to listen for removals. utils/registry
- // does, but it doesn't allow its elements to be enumerated. So as a hack,
- // use a collection for item.context and replace its add and remove methods.
- collection.addCollectionProperty(this, "context");
- if (opts.context)
- this.context.add(opts.context);
-
- const self = this;
-
- let add = this.context.add;
- this.context.add = function itemContextAdd() {
- let args = Array.slice(arguments);
- add.apply(self.context, args);
- if (self._workerReg && args.some(function (a) a instanceof URLContext))
- self._workerReg.destroyUnneededWorkers();
- };
-
- let remove = this.context.remove;
- this.context.remove = function itemContextRemove() {
- let args = Array.slice(arguments);
- remove.apply(self.context, args);
- if (self._workerReg && args.some(function (a) a instanceof URLContext))
- self._workerReg.createNeededWorkers();
- };
- },
-
- // Workers are only created for top-level menu items. When a top-level item
- // is later added to a Menu, its workers are destroyed. Well, all items start
- // out as top-level because there is, unfortunately, no contextMenu.add(). So
- // when an item is created and immediately added to a Menu, workers for it are
- // needlessly created and destroyed. The point of this timeout is to avoid
- // that. Items that are created and added to Menus in the same turn of the
- // event loop won't have workers created for them.
- _finishActiveItemInit: function AIT__finishActiveItemInit() {
- numItemsWithUnfinishedInit++;
- const self = this;
- timer.setTimeout(function AIT__finishActiveItemInitTimeout() {
- if (!self.parentMenu && !self._wasDestroyed)
- browserManager.addTopLevelItem(self._public);
- self._hasFinishedInit = true;
- numItemsWithUnfinishedInit--;
- }, 0);
- },
-
- get label() {
- return this._label;
- },
-
- set label(val) {
- this._label = validateOpt(val, this._optRules.label);
- if (this._isInited)
- browserManager.setItemLabel(this, this._label);
- return this._label;
- },
-
- get image() {
- return this._image;
- },
-
- set image(val) {
- this._image = validateOpt(val, this._optRules.image);
- if (this._isInited)
- browserManager.setItemImage(this, this._image);
- return this._image;
- },
-
- get contentScript() {
- return this._contentScript;
- },
-
- set contentScript(val) {
- this._contentScript = validateOpt(val, this._optRules.contentScript);
- return this._contentScript;
- },
-
- get contentScriptFile() {
- return this._contentScriptFile;
- },
-
- set contentScriptFile(val) {
- this._contentScriptFile =
- validateOpt(val, this._optRules.contentScriptFile);
- return this._contentScriptFile;
- }
-}));
-
-// Item is composed of this trait.
-const ItemTrait = Trait.compose(ActiveItemTrait, Trait({
-
- _initItem: function IT__initItem(opts, optRules) {
- this._initActiveItem(opts, optRules, []);
- },
-
- get data() {
- return this._data;
- },
-
- set data(val) {
- this._data = validateOpt(val, this._optRules.data);
- if (this._isInited)
- browserManager.setItemData(this, this._data);
- return this._data;
- },
-
- toString: function IT_toString() {
- return '[object Item "' + this.label + '"]';
- }
-}));
-
-// The exported Item constructor.
-function Item(options) {
- let optRules = optionsRules();
- optRules.data = {
- map: function (v) v.toString(),
- is: ["string", "undefined"]
- };
-
- let item = ItemTrait.create(Item.prototype);
- item._initItem(options, optRules);
-
- item._public = Cortex(item);
- browserManager.registerItem(item._public);
- item._finishActiveItemInit();
-
- return item._public;
-}
-
-// Menu is composed of this trait.
-const MenuTrait = Trait.compose(
- ActiveItemTrait.resolve({ destroy: "_destroyThisItem" }),
- Trait({
-
- _initMenu: function MT__initMenu(opts, optRules, optsToNotSet) {
- this._items = [];
- this._initActiveItem(opts, optRules, optsToNotSet);
- },
-
- destroy: function MT_destroy() {
- while (this.items.length)
- this.items[0].destroy();
- this._destroyThisItem();
- },
-
- get items() {
- return this._items;
- },
-
- set items(val) {
- let newItems = validateOpt(val, this._optRules.items);
- while (this.items.length)
- this.items[0].destroy();
- newItems.forEach(function (i) this.addItem(i), this);
- return newItems;
- },
-
- addItem: function MT_addItem(item) {
- // First, remove the item from its current parent.
- let privates = privateItem(item);
- if (item.parentMenu)
- item.parentMenu.removeItem(item);
- else if (!(item instanceof Separator) && privates._hasFinishedInit)
- browserManager.removeTopLevelItem(item);
-
- // Now add the item to this menu.
- this._items.push(item);
- privates._parentMenu = this._public;
- browserManager.addItemToMenu(item, this._public);
- },
-
- removeItem: function MT_removeItem(item) {
- let idx = this._items.indexOf(item);
- if (idx < 0)
- return;
- this._items.splice(idx, 1);
- privateItem(item)._parentMenu = null;
- browserManager.removeItemFromMenu(item, this._public);
- },
-
- toString: function MT_toString() {
- return '[object Menu "' + this.label + '"]';
- }
-}));
-
-// The exported Menu constructor.
-function Menu(options) {
- let optRules = optionsRules();
- optRules.items = {
- is: ["array"],
- ok: function (v) {
- return v.every(function (item) {
- return (item instanceof Item) ||
- (item instanceof Menu) ||
- (item instanceof Separator);
- });
- },
- msg: "items must be an array, and each element in the array must be an " +
- "Item, Menu, or Separator."
- };
-
- let menu = MenuTrait.create(Menu.prototype);
-
- // We can't rely on _initBase to set the `items` property, because the menu
- // needs to be registered with and added to the browserManager before any
- // child items are added to it.
- menu._initMenu(options, optRules, ["items"]);
-
- menu._public = Cortex(menu);
- browserManager.registerItem(menu._public);
- menu.items = options.items;
- menu._finishActiveItemInit();
-
- return menu._public;
-}
-
-// The exported Separator constructor.
-function Separator() {
- let sep = ItemBaseTrait.create(Separator.prototype);
- sep._initBase({}, {}, []);
-
- sep._public = Cortex(sep);
- browserManager.registerItem(sep._public);
- sep._hasFinishedInit = true;
- return sep._public;
-}
-
-
-function Context() {}
-
-function PageContext() {
- this.isCurrent = function PageContext_isCurrent(popupNode) {
- let win = popupNode.ownerDocument.defaultView;
- if (win && !win.getSelection().isCollapsed)
- return false;
-
- let cursor = popupNode;
- while (cursor && !(cursor instanceof Ci.nsIDOMHTMLHtmlElement)) {
- if (NON_PAGE_CONTEXT_ELTS.some(function (iface) cursor instanceof iface))
- return false;
- cursor = cursor.parentNode;
- }
- return true;
- };
-}
-
-PageContext.prototype = new Context();
-
-function SelectorContext(selector) {
- let opts = apiUtils.validateOptions({ selector: selector }, {
- selector: {
- is: ["string"],
- msg: "selector must be a string."
- }
- });
-
- this.adjustPopupNode = function SelectorContext_adjustPopupNode(node) {
- return closestMatchingAncestor(node);
- };
-
- this.isCurrent = function SelectorContext_isCurrent(popupNode) {
- return !!closestMatchingAncestor(popupNode);
- };
-
- // Returns node if it matches selector, or the closest ancestor of node that
- // matches, or null if node and none of its ancestors matches.
- function closestMatchingAncestor(node) {
- let cursor = node;
- while (cursor) {
- if (cursor.mozMatchesSelector(selector))
- return cursor;
- if (cursor instanceof Ci.nsIDOMHTMLHtmlElement)
- break;
- cursor = cursor.parentNode;
- }
- return null;
- }
-}
-
-SelectorContext.prototype = new Context();
-
-function SelectionContext() {
- this.isCurrent = function SelectionContext_isCurrent(popupNode) {
- let win = popupNode.ownerDocument.defaultView;
- if (!win)
- return false;
-
- let hasSelection = !win.getSelection().isCollapsed;
- if (!hasSelection) {
- // window.getSelection doesn't return a selection for text selected in a
- // form field (see bug 85686), so before returning false we want to check
- // if the popupNode is a text field.
- let { selectionStart, selectionEnd } = popupNode;
- hasSelection = !isNaN(selectionStart) &&
- !isNaN(selectionEnd) &&
- selectionStart !== selectionEnd;
- }
- return hasSelection;
- };
-}
-
-SelectionContext.prototype = new Context();
-
-function URLContext(patterns) {
- let opts = apiUtils.validateOptions({ patterns: patterns }, {
- patterns: {
- map: function (v) apiUtils.getTypeOf(v) === "array" ? v : [v],
- ok: function (v) v.every(function (p) typeof(p) === "string"),
- msg: "patterns must be a string or an array of strings."
- }
- });
- try {
- patterns = opts.patterns.map(function (p) new MatchPattern(p));
- }
- catch (err) {
- console.error("Error creating URLContext match pattern:");
- throw err;
- }
-
- const self = this;
-
- this.isCurrent = function URLContext_isCurrent(popupNode) {
- return self.isCurrentForURL(popupNode.ownerDocument.URL);
- };
-
- this.isCurrentForURL = function URLContext_isCurrentForURL(url) {
- return patterns.some(function (p) p.test(url));
- };
-}
-
-URLContext.prototype = new Context();
-
-exports.PageContext = apiUtils.publicConstructor(PageContext);
-exports.SelectorContext = apiUtils.publicConstructor(SelectorContext);
-exports.SelectionContext = apiUtils.publicConstructor(SelectionContext);
-exports.URLContext = apiUtils.publicConstructor(URLContext);
-
-
-// Returns a version of opt validated against the given rule.
-function validateOpt(opt, rule) {
- return apiUtils.validateOptions({ opt: opt }, { opt: rule }).opt;
-}
-
-// Returns rules for apiUtils.validateOptions() common to Item and Menu.
-function optionsRules() {
- return {
- context: {
- is: ["undefined", "object", "array"],
- ok: function (v) {
- if (!v)
- return true;
- let arr = apiUtils.getTypeOf(v) === "array" ? v : [v];
- return arr.every(function (o) o instanceof Context);
- },
- msg: "The 'context' option must be a Context object or an array of " +
- "Context objects."
- },
- label: {
- map: function (v) v.toString(),
- is: ["string"],
- ok: function (v) !!v,
- msg: "The item must have a non-empty string label."
- },
- image: {
- map: function (v) v.toString(),
- is: ["string", "undefined", "null"]
- },
- contentScript: {
- is: ["string", "array", "undefined"],
- ok: function (v) {
- return apiUtils.getTypeOf(v) !== "array" ||
- v.every(function (s) typeof(s) === "string");
- }
- },
- contentScriptFile: {
- is: ["string", "array", "undefined"],
- ok: function (v) {
- if (!v)
- return true;
- let arr = apiUtils.getTypeOf(v) === "array" ? v : [v];
- try {
- return arr.every(function (s) {
- return apiUtils.getTypeOf(s) === "string" && url.toFilename(s);
- });
- }
- catch (err) {}
- return false;
- },
- msg: "The 'contentScriptFile' option must be a local file URL or " +
- "an array of local file URLs."
- },
- onMessage: {
- is: ["function", "undefined"]
- }
- };
-}
-
-// Does a binary search on elts, a NodeList, and returns the DOM element
-// before which an item with targetLabel should be inserted. null is returned
-// if the new item should be inserted at the end.
-function insertionPoint(targetLabel, elts) {
- let from = 0;
- let to = elts.length - 1;
-
- while (from <= to) {
- let i = Math.floor((from + to) / 2);
- let comp = targetLabel.localeCompare(elts[i].getAttribute("label"));
- if (comp < 0)
- to = i - 1;
- else if (comp > 0)
- from = i + 1;
- else
- return elts[i];
- }
- return elts[from] || null;
-}
-
-// Builds an ID suitable for a DOM element from the given item ID.
-// isInOverflowSubtree should be true if the returned element will be inserted
-// into the DOM subtree rooted at the overflow menu.
-function domEltIDFromItemID(itemID, isInOverflowSubtree) {
- let suffix = isInOverflowSubtree ? "-overflow" : "";
- return jpSelf.id + "-context-menu-item-" + itemID + suffix;
-}
-
-// Parses the item ID out of the given DOM element ID and returns it. If the
-// element's ID is malformed or it indicates that the element was not created by
-// the instance of the module calling this function, returns -1.
-function itemIDFromDOMEltID(domEltID) {
- let match = /^(.+?)-context-menu-item-([0-9]+)[-a-z]*$/.exec(domEltID);
- return !match || match[1] !== jpSelf.id ? -1 : match[2];
-}
-
-// Returns the private version of the given public reflection.
-function privateItem(publicItem) {
- return publicItem.valueOf(PRIVATE_PROPS_KEY);
-}
-
-
-// A type of Worker tailored to our uses.
-const ContextMenuWorker = Worker.compose({
- destroy: Worker.required,
-
- // Returns true if any context listeners are defined in the worker's port.
- anyContextListeners: function CMW_anyContextListeners() {
- return this._contentWorker._listeners("context").length > 0;
- },
-
- // Returns the first string or truthy value returned by a context listener in
- // the worker's port. If none return a string or truthy value or if there are
- // no context listeners, returns false. popupNode is the node that was
- // context-clicked.
- isAnyContextCurrent: function CMW_isAnyContextCurrent(popupNode) {
- let listeners = this._contentWorker._listeners("context");
- for (let i = 0; i < listeners.length; i++) {
- try {
- let val = listeners[i].call(this._contentWorker._sandbox, popupNode);
- if (typeof(val) === "string" || val)
- return val;
- }
- catch (err) {
- console.exception(err);
- }
- }
- return false;
- },
-
- // Emits a click event in the worker's port. popupNode is the node that was
- // context-clicked, and clickedItemData is the data of the item that was
- // clicked.
- fireClick: function CMW_fireClick(popupNode, clickedItemData) {
- this._contentWorker._asyncEmit("click", popupNode, clickedItemData);
- }
-});
-
-
-// This class creates and stores content workers for pairs of menu items and
-// content windows. Use one instance for each item. Not all pairs need a
-// worker: if an item has a URL context that does not match a window's page,
-// then no worker is created for the pair.
-function WorkerRegistry(item) {
- this.item = item;
-
- // inner window ID => { win, worker }
- this.winWorkers = {};
-
- // inner window ID => content window
- this.winsWithoutWorkers = {};
-}
-
-WorkerRegistry.prototype = {
-
- // Registers a content window, creating a worker for it if it needs one.
- registerContentWin: function WR_registerContentWin(win) {
- let innerWinID = winUtils.getInnerId(win);
- if ((innerWinID in this.winWorkers) ||
- (innerWinID in this.winsWithoutWorkers))
- return;
- if (this._doesURLNeedWorker(win.document.URL))
- this.winWorkers[innerWinID] = { win: win, worker: this._makeWorker(win) };
- else
- this.winsWithoutWorkers[innerWinID] = win;
- },
-
- // Unregisters a content window, destroying its related worker if it has one.
- unregisterContentWin: function WR_unregisterContentWin(innerWinID) {
- if (innerWinID in this.winWorkers) {
- let winWorker = this.winWorkers[innerWinID];
- winWorker.worker.destroy();
- delete winWorker.worker;
- delete winWorker.win;
- delete this.winWorkers[innerWinID];
- }
- else
- delete this.winsWithoutWorkers[innerWinID];
- },
-
- // Creates a worker for each window that needs a worker but doesn't have one.
- createNeededWorkers: function WR_createNeededWorkers() {
- for (let [innerWinID, win] in Iterator(this.winsWithoutWorkers)) {
- delete this.winsWithoutWorkers[innerWinID];
- this.registerContentWin(win);
- }
- },
-
- // Destroys the worker for each window that has a worker but doesn't need it.
- destroyUnneededWorkers: function WR_destroyUnneededWorkers() {
- for (let [innerWinID, winWorker] in Iterator(this.winWorkers)) {
- if (!this._doesURLNeedWorker(winWorker.win.document.URL)) {
- this.unregisterContentWin(innerWinID);
- this.winsWithoutWorkers[innerWinID] = winWorker.win;
- }
- }
- },
-
- // Returns the worker for the item-window pair or null if none exists.
- find: function WR_find(contentWin) {
- let innerWinID = winUtils.getInnerId(contentWin);
- return (innerWinID in this.winWorkers) ?
- this.winWorkers[innerWinID].worker :
- null;
- },
-
- // Unregisters all content windows from the registry, which destroys all
- // workers.
- destroy: function WR_destroy() {
- for (let innerWinID in this.winWorkers)
- this.unregisterContentWin(innerWinID);
- for (let innerWinID in this.winsWithoutWorkers)
- this.unregisterContentWin(innerWinID);
- },
-
- // Returns false if the item has a URL context that does not match the given
- // URL.
- _doesURLNeedWorker: function WR__doesURLNeedWorker(url) {
- for (let ctxt in this.item.context)
- if ((ctxt instanceof URLContext) && !ctxt.isCurrentForURL(url))
- return false;
- return true;
- },
-
- _makeWorker: function WR__makeWorker(win) {
- let worker = ContextMenuWorker({
- window: win,
- contentScript: this.item.contentScript,
- contentScriptFile: this.item.contentScriptFile,
- onError: function (err) console.exception(err)
- });
- let item = this.item;
- worker.on("message", function workerOnMessage(msg) {
- try {
- privateItem(item)._emitOnObject(item, "message", msg);
- }
- catch (err) {
- console.exception(err);
- }
- });
- return worker;
- }
-};
-
-
-// Mirrors state across all browser windows. Also responsible for detecting
-// all content window loads and unloads.
-let browserManager = {
- topLevelItems: [],
- browserWins: [],
-
- // inner window ID => content window
- contentWins: {},
-
- // Call this when a new item is created, top-level or not.
- registerItem: function BM_registerItem(item) {
- this.browserWins.forEach(function (w) w.registerItem(item));
- },
-
- // Call this when an item is destroyed and won't be used again, top-level or
- // not.
- unregisterItem: function BM_unregisterItem(item) {
- this.browserWins.forEach(function (w) w.unregisterItem(item));
- },
-
- addTopLevelItem: function BM_addTopLevelItem(item) {
- this.topLevelItems.push(item);
- this.browserWins.forEach(function (w) w.addTopLevelItem(item));
-
- // Create the item's worker registry and register all currently loaded
- // content windows with it.
- let privates = privateItem(item);
- privates._isTopLevel = true;
- for each (let win in this.contentWins)
- privates._workerReg.registerContentWin(win);
- },
-
- removeTopLevelItem: function BM_removeTopLevelItem(item) {
- let idx = this.topLevelItems.indexOf(item);
- if (idx < 0)
- throw new Error("Internal error: item not in top-level menu: " + item);
- this.topLevelItems.splice(idx, 1);
- this.browserWins.forEach(function (w) w.removeTopLevelItem(item));
- privateItem(item)._isTopLevel = false;
- },
-
- addItemToMenu: function BM_addItemToMenu(item, parentMenu) {
- this.browserWins.forEach(function (w) w.addItemToMenu(item, parentMenu));
- },
-
- removeItemFromMenu: function BM_removeItemFromMenu(item, parentMenu) {
- this.browserWins.forEach(function (w) w.removeItemFromMenu(item,
- parentMenu));
- },
-
- setItemLabel: function BM_setItemLabel(item, label) {
- this.browserWins.forEach(function (w) w.setItemLabel(item, label));
- },
-
- setItemImage: function BM_setItemImage(item, imageURL) {
- this.browserWins.forEach(function (w) w.setItemImage(item, imageURL));
- },
-
- setItemData: function BM_setItemData(item, data) {
- this.browserWins.forEach(function (w) w.setItemData(item, data));
- },
-
- // Note that calling this method will cause onTrack to be called immediately
- // for each currently open browser window.
- init: function BM_init() {
- require("api-utils/unload").ensure(this);
- let windowTracker = new winUtils.WindowTracker(this);
-
- // Register content windows on content-document-global-created and
- // unregister them on inner-window-destroyed. For rationale, see bug 667957
- // for the former and bug 642004 for the latter.
- observerServ.add("content-document-global-created",
- this._onDocGlobalCreated, this);
- observerServ.add("inner-window-destroyed",
- this._onInnerWinDestroyed, this);
- },
-
- _onDocGlobalCreated: function BM__onDocGlobalCreated(contentWin) {
- let doc = contentWin.document;
- if (doc.readyState == "loading") {
- const self = this;
- doc.addEventListener("readystatechange", function onReadyStateChange(e) {
- if (e.target != doc || doc.readyState != "complete")
- return;
- doc.removeEventListener("readystatechange", onReadyStateChange, false);
- self._registerContentWin(contentWin);
- }, false);
- }
- else if (doc.readyState == "complete")
- this._registerContentWin(contentWin);
- },
-
- _onInnerWinDestroyed: function BM__onInnerWinDestroyed(subj) {
- this._unregisterContentWin(
- subj.QueryInterface(Ci.nsISupportsPRUint64).data);
- },
-
- // Stores the given content window with the manager and registers it with each
- // top-level item's worker registry.
- _registerContentWin: function BM__registerContentWin(win) {
- let innerID = winUtils.getInnerId(win);
-
- // It's an error to call this method for the same window more than once, but
- // we allow it in one case: when onTrack races _onDocGlobalCreated. (See
- // the comment in onTrack.) Make sure the window is registered only once.
- if (innerID in this.contentWins)
- return;
-
- this.contentWins[innerID] = win;
- this.topLevelItems.forEach(function (item) {
- privateItem(item)._workerReg.registerContentWin(win);
- });
- },
-
- // Removes the given content window from the manager and unregisters it from
- // each top-level item's worker registry.
- _unregisterContentWin: function BM__unregisterContentWin(innerID) {
- delete this.contentWins[innerID];
- this.topLevelItems.forEach(function (item) {
- privateItem(item)._workerReg.unregisterContentWin(innerID);
- });
- },
-
- unload: function BM_unload() {
- // The window tracker is unloaded at the same time this method is called,
- // which causes onUntrack to be called for each open browser window, so
- // there's no need to clean up browser windows here.
-
- while (this.topLevelItems.length) {
- let item = this.topLevelItems[0];
- this.removeTopLevelItem(item);
- this.unregisterItem(item);
- }
- delete this.contentWins;
- },
-
- // Registers a browser window with the manager. This is a WindowTracker
- // callback. Note that this is called in two cases: for each newly opened
- // chrome window, and for each chrome window that is open when the loader
- // loads this module.
- onTrack: function BM_onTrack(window) {
- if (!this._isBrowserWindow(window))
- return;
-
- let browserWin = new BrowserWindow(window);
- this.browserWins.push(browserWin);
-
- // Register all loaded content windows in the browser window. Be sure to
- // include frames and iframes. If onTrack is called as a result of a new
- // browser window being opened, as opposed to the module being loaded, then
- // this will race the content-document-global-created notification. That's
- // OK, since _registerContentWin will not register the same content window
- // more than once.
- window.gBrowser.browsers.forEach(function (browser) {
- let topContentWin = browser.contentWindow;
- let allContentWins = Array.slice(topContentWin.frames);
- allContentWins.push(topContentWin);
- allContentWins.forEach(function (contentWin) {
- if (contentWin.document.readyState == "complete")
- this._registerContentWin(contentWin);
- }, this);
- }, this);
-
- // Add all top-level items and, recursively, their child items to the new
- // browser window.
- function addItemTree(item, parentMenu) {
- browserWin.registerItem(item);
- if (parentMenu)
- browserWin.addItemToMenu(item, parentMenu);
- else
- browserWin.addTopLevelItem(item);
- if (item instanceof Menu)
- item.items.forEach(function (subitem) addItemTree(subitem, item));
- }
- this.topLevelItems.forEach(function (item) addItemTree(item, null));
- },
-
- // Unregisters a browser window from the manager. This is a WindowTracker
- // callback. Note that this is called in two cases: for each newly closed
- // chrome window, and for each chrome window that is open when this module is
- // unloaded.
- onUntrack: function BM_onUntrack(window) {
- if (!this._isBrowserWindow(window))
- return;
-
- // Remove the window from the window list.
- let idx = 0;
- for (; idx < this.browserWins.length; idx++)
- if (this.browserWins[idx].window == window)
- break;
- if (idx == this.browserWins.length)
- throw new Error("Internal error: browser window not found");
- let browserWin = this.browserWins.splice(idx, 1)[0];
-
- // Remove all top-level items from the window.
- this.topLevelItems.forEach(function (i) browserWin.removeTopLevelItem(i));
- browserWin.destroy();
- },
-
- _isBrowserWindow: function BM__isBrowserWindow(win) {
- let winType = win.document.documentElement.getAttribute("windowtype");
- return winType === "navigator:browser";
- }
-};
-
-
-// Responsible for creating and managing context menu item DOM elements for a
-// browser window. Also responsible for providing a description of the window's
-// current context and determining whether an item matches the current context.
-//
-// TODO: If other apps besides Firefox want to support the context menu in
-// whatever way is appropriate for them, plugging in a substitute for or an
-// adapter to this class should be the way to do it. Make it easy for them.
-// See bug 560716.
-function BrowserWindow(window) {
- this.window = window;
- this.doc = window.document;
-
- let popupDOMElt = this.doc.getElementById("contentAreaContextMenu");
- if (!popupDOMElt)
- throw new Error("Internal error: Context menu popup not found.");
- this.contextMenuPopup = new ContextMenuPopup(popupDOMElt, this);
-
- // item ID => { item, domElt, overflowDOMElt, popup, overflowPopup }
- // item may or may not be top-level. domElt is the item's DOM element
- // contained in the subtree rooted in the top-level context menu.
- // overflowDOMElt is the item's DOM element contained in the subtree rooted in
- // the overflow submenu. popup and overflowPopup are only defined if the item
- // is a Menu; they're the Popup instances containing the Menu's child items,
- // with the aforementioned distinction between top-level and overflow
- // subtrees.
- this.items = {};
-}
-
-BrowserWindow.prototype = {
-
- // Creates and stores DOM elements for the given item, top-level or not.
- registerItem: function BW_registerItem(item) {
- // this.items[id] is referenced by _makeMenu, so it needs to be defined
- // before _makeDOMElt is called.
- let props = { item: item };
- this.items[privateItem(item)._id] = props;
- props.domElt = this._makeDOMElt(item, false);
- props.overflowDOMElt = this._makeDOMElt(item, true);
- },
-
- // Removes the given item's DOM elements from the store.
- unregisterItem: function BW_unregisterItem(item) {
- delete this.items[privateItem(item)._id];
- },
-
- addTopLevelItem: function BW_addTopLevelItem(item) {
- this.contextMenuPopup.addItem(item);
- },
-
- removeTopLevelItem: function BW_removeTopLevelItem(item) {
- this.contextMenuPopup.removeItem(item);
- },
-
- addItemToMenu: function BW_addItemToMenu(item, parentMenu) {
- let { popup, overflowPopup } = this.items[privateItem(parentMenu)._id];
- popup.addItem(item);
- overflowPopup.addItem(item);
- },
-
- removeItemFromMenu: function BW_removeItemFromMenu(item, parentMenu) {
- let { popup, overflowPopup } = this.items[privateItem(parentMenu)._id];
- popup.removeItem(item);
- overflowPopup.removeItem(item);
- },
-
- setItemLabel: function BW_setItemLabel(item, label) {
- let privates = privateItem(item);
- let { domElt, overflowDOMElt } = this.items[privates._id];
- this._setDOMEltLabel(domElt, label);
- this._setDOMEltLabel(overflowDOMElt, label);
- if (!item.parentMenu && privates._hasFinishedInit)
- this.contextMenuPopup.itemLabelDidChange(item);
- },
-
- _setDOMEltLabel: function BW__setDOMEltLabel(domElt, label) {
- domElt.setAttribute("label", label);
- },
-
- setItemImage: function BW_setItemImage(item, imageURL) {
- let { domElt, overflowDOMElt } = this.items[privateItem(item)._id];
- let isMenu = item instanceof Menu;
- this._setDOMEltImage(domElt, imageURL, isMenu);
- this._setDOMEltImage(overflowDOMElt, imageURL, isMenu);
- },
-
- _setDOMEltImage: function BW__setDOMEltImage(domElt, imageURL, isMenu) {
- if (!imageURL) {
- domElt.removeAttribute("image");
- domElt.classList.remove("menu-iconic");
- domElt.classList.remove("menuitem-iconic");
- }
- else {
- domElt.setAttribute("image", imageURL);
- domElt.classList.add(isMenu ? "menu-iconic" : "menuitem-iconic");
- }
- },
-
- setItemData: function BW_setItemData(item, data) {
- let { domElt, overflowDOMElt } = this.items[privateItem(item)._id];
- this._setDOMEltData(domElt, data);
- this._setDOMEltData(overflowDOMElt, data);
- },
-
- _setDOMEltData: function BW__setDOMEltData(domElt, data) {
- domElt.setAttribute("value", data);
- },
-
- // The context specified for a top-level item may not match exactly the real
- // context that triggers it. For example, if the user context-clicks a span
- // inside an anchor, we want items that specify an anchor context to be
- // triggered, but the real context will indicate that the span was clicked,
- // not the anchor. Where the real context and an item's context conflict,
- // clients should be given the item's context, and this method can be used to
- // make such adjustments. Returns an adjusted popupNode.
- adjustPopupNode: function BW_adjustPopupNode(popupNode, topLevelItem) {
- for (let ctxt in topLevelItem.context) {
- if (typeof(ctxt.adjustPopupNode) === "function") {
- let ctxtNode = ctxt.adjustPopupNode(popupNode);
- if (ctxtNode) {
- popupNode = ctxtNode;
- break;
- }
- }
- }
- return popupNode;
- },
-
- // Returns true if all of item's contexts are current in the window.
- areAllContextsCurrent: function BW_areAllContextsCurrent(item, popupNode) {
- let win = popupNode.ownerDocument.defaultView;
- let worker = privateItem(item)._workerReg.find(win);
-
- // If the worker for the item-window pair doesn't exist (e.g., because the
- // page hasn't loaded yet), we can't really make a good decision since the
- // content script may have a context listener. So just don't show the item
- // at all.
- if (!worker)
- return false;
-
- // If there are no contexts given at all, the page context applies.
- let hasContentContext = worker.anyContextListeners();
- if (!hasContentContext && !item.context.length)
- return new PageContext().isCurrent(popupNode);
-
- // Otherwise, determine if all given contexts are current. Evaluate the
- // declarative contexts first and the worker's context listeners last. That
- // way the listener might be able to avoid some work.
- let curr = true;
- for (let ctxt in item.context) {
- curr = curr && ctxt.isCurrent(popupNode);
- if (!curr)
- return false;
- }
- return !hasContentContext || worker.isAnyContextCurrent(popupNode);
- },
-
- // Sets this.popupNode to the node the user context-clicked to invoke the
- // context menu. For Gecko 2.0 and later, triggerNode is this node; if it's
- // falsey, document.popupNode is used. Returns the popupNode.
- capturePopupNode: function BW_capturePopupNode(triggerNode) {
- this.popupNode = triggerNode || this.doc.popupNode;
- if (!this.popupNode)
- console.warn("popupNode is null.");
- return this.popupNode;
- },
-
- destroy: function BW_destroy() {
- this.contextMenuPopup.destroy();
- delete this.window;
- delete this.doc;
- delete this.items;
- },
-
- // Emits a click event in the port of the content worker related to given top-
- // level item and popupNode's content window. Listeners will be passed
- // popupNode and clickedItemData.
- fireClick: function BW_fireClick(topLevelItem, popupNode, clickedItemData) {
- let win = popupNode.ownerDocument.defaultView;
- let worker = privateItem(topLevelItem)._workerReg.find(win);
- if (worker)
- worker.fireClick(popupNode, clickedItemData);
- },
-
- _makeDOMElt: function BW__makeDOMElt(item, isInOverflowSubtree) {
- let elt = item instanceof Item ? this._makeMenuitem(item) :
- item instanceof Menu ? this._makeMenu(item, isInOverflowSubtree) :
- item instanceof Separator ? this._makeSeparator() :
- null;
- if (!elt)
- throw new Error("Internal error: can't make element, unknown item type");
-
- elt.id = domEltIDFromItemID(privateItem(item)._id, isInOverflowSubtree);
- elt.classList.add(ITEM_CLASS);
- return elt;
- },
-
- // Returns a new xul:menu representing the menu.
- _makeMenu: function BW__makeMenu(menu, isInOverflowSubtree) {
- let menuElt = this.doc.createElement("menu");
- this._setDOMEltLabel(menuElt, menu.label);
- if (menu.image)
- this._setDOMEltImage(menuElt, menu.image, true);
- let popupElt = this.doc.createElement("menupopup");
- menuElt.appendChild(popupElt);
-
- let popup = new Popup(popupElt, this, isInOverflowSubtree);
- let props = this.items[privateItem(menu)._id];
- if (isInOverflowSubtree)
- props.overflowPopup = popup;
- else
- props.popup = popup;
-
- return menuElt;
- },
-
- // Returns a new xul:menuitem representing the item.
- _makeMenuitem: function BW__makeMenuitem(item) {
- let elt = this.doc.createElement("menuitem");
- this._setDOMEltLabel(elt, item.label);
- if (item.image)
- this._setDOMEltImage(elt, item.image, false);
- if (item.data)
- this._setDOMEltData(elt, item.data);
- return elt;
- },
-
- // Returns a new xul:menuseparator.
- _makeSeparator: function BW__makeSeparator() {
- return this.doc.createElement("menuseparator");
- }
-};
-
-
-// Responsible for adding DOM elements to and removing them from poupDOMElt.
-function Popup(popupDOMElt, browserWin, isInOverflowSubtree) {
- this.popupDOMElt = popupDOMElt;
- this.browserWin = browserWin;
- this.isInOverflowSubtree = isInOverflowSubtree;
-}
-
-Popup.prototype = {
-
- addItem: function Popup_addItem(item) {
- let props = this.browserWin.items[privateItem(item)._id];
- let elt = this.isInOverflowSubtree ? props.overflowDOMElt : props.domElt;
- this.popupDOMElt.appendChild(elt);
- },
-
- removeItem: function Popup_removeItem(item) {
- let props = this.browserWin.items[privateItem(item)._id];
- let elt = this.isInOverflowSubtree ? props.overflowDOMElt : props.domElt;
- this.popupDOMElt.removeChild(elt);
- }
-};
-
-
-// Represents a browser window's context menu popup. Responsible for hiding and
-// showing items according to the browser window's current context and for
-// handling item clicks.
-function ContextMenuPopup(popupDOMElt, browserWin) {
- this.popupDOMElt = popupDOMElt;
- this.browserWin = browserWin;
- this.doc = popupDOMElt.ownerDocument;
-
- // item ID => item
- // Calling this variable "topLevelItems" is redundant, since Popup and
- // ContextMenuPopup are only responsible for their child items, not all their
- // descendant items. But calling it "items" might encourage one to believe
- // otherwise, so topLevelItems it is.
- this.topLevelItems = {};
-
- popupDOMElt.addEventListener("popupshowing", this, false);
- popupDOMElt.addEventListener("command", this, false);
-}
-
-ContextMenuPopup.prototype = {
-
- addItem: function CMP_addItem(item) {
- this._ensureStaticEltsExist();
- let itemID = privateItem(item)._id;
- this.topLevelItems[itemID] = item;
- let props = this.browserWin.items[itemID];
- props.domElt.classList.add(TOPLEVEL_ITEM_CLASS);
- props.overflowDOMElt.classList.add(OVERFLOW_ITEM_CLASS);
- this._insertItemInSortedOrder(item);
- },
-
- removeItem: function CMP_removeItem(item) {
- let itemID = privateItem(item)._id;
- delete this.topLevelItems[itemID];
- let { domElt, overflowDOMElt } = this.browserWin.items[itemID];
- domElt.classList.remove(TOPLEVEL_ITEM_CLASS);
- overflowDOMElt.classList.remove(OVERFLOW_ITEM_CLASS);
- this.popupDOMElt.removeChild(domElt);
- this._overflowPopup.removeChild(overflowDOMElt);
- },
-
- // Call this after the item's label changes. This re-inserts the item into
- // the popup so that it remains in sorted order.
- itemLabelDidChange: function CMP_itemLabelDidChange(item) {
- let itemID = privateItem(item)._id;
- let { domElt, overflowDOMElt } = this.browserWin.items[itemID];
- this.popupDOMElt.removeChild(domElt);
- this._overflowPopup.removeChild(overflowDOMElt);
- this._insertItemInSortedOrder(item);
- },
-
- destroy: function CMP_destroy() {
- // If there are no more items from any instance of the module, remove the
- // separator and overflow submenu, if they exist.
- let elts = this._topLevelElts;
- if (!elts.length) {
- let submenu = this._overflowMenu;
- if (submenu)
- this.popupDOMElt.removeChild(submenu);
-
- let sep = this._separator;
- if (sep)
- this.popupDOMElt.removeChild(sep);
- }
-
- this.popupDOMElt.removeEventListener("popupshowing", this, false);
- this.popupDOMElt.removeEventListener("command", this, false);
- },
-
- handleEvent: function CMP_handleEvent(event) {
- try {
- if (event.type === "command")
- this._handleClick(event.target);
- else if (event.type === "popupshowing" &&
- event.target === this.popupDOMElt)
- this._handlePopupShowing();
- }
- catch (err) {
- console.exception(err);
- }
- },
-
- // command events bubble to the context menu's top-level xul:menupopup and are
- // caught here.
- _handleClick: function CMP__handleClick(clickedDOMElt) {
- if (!clickedDOMElt.classList.contains(ITEM_CLASS))
- return;
- let itemID = itemIDFromDOMEltID(clickedDOMElt.id);
- if (itemID < 0)
- return;
- let { item, domElt, overflowDOMElt } = this.browserWin.items[itemID];
-
- // Bail if the DOM element was not created by this module instance. In
- // real-world add-ons, the itemID < 0 check above is sufficient, but for the
- // unit test the JID never changes, making this necessary.
- if (clickedDOMElt != domElt && clickedDOMElt != overflowDOMElt)
- return;
-
- let topLevelItem = privateItem(item)._topLevelItem;
- let popupNode = this.browserWin.adjustPopupNode(this.browserWin.popupNode,
- topLevelItem);
- this.browserWin.fireClick(topLevelItem, popupNode, item.data);
- },
-
- // popupshowing is used to show top-level items that match the browser
- // window's current context and hide items that don't. Each module instance
- // is responsible for showing and hiding the items it owns.
- _handlePopupShowing: function CMP__handlePopupShowing() {
- // If there are items queued up to finish initializing, let them go first.
- // Otherwise the overflow submenu and menu separator may end up in an
- // inappropriate state when those items are later added to the menu.
- if (numItemsWithUnfinishedInit) {
- const self = this;
- timer.setTimeout(function popupShowingTryAgain() {
- self._handlePopupShowing();
- }, 0);
- return;
- }
-
- // popupDOMElt.triggerNode was added in Gecko 2.0 by bug 383930. The || is
- // to avoid a Spidermonkey strict warning on earlier versions.
- let triggerNode = this.popupDOMElt.triggerNode || undefined;
- let popupNode = this.browserWin.capturePopupNode(triggerNode);
-
- // Show and hide items. Set a "jetpackContextCurrent" property on the
- // DOM elements to signal which of our items match the current context.
- for (let [itemID, item] in Iterator(this.topLevelItems)) {
- let areContextsCurr =
- this.browserWin.areAllContextsCurrent(item, popupNode);
-
- // Change the item's label if the return value was a string.
- if (typeof(areContextsCurr) === "string") {
- item.label = areContextsCurr;
- areContextsCurr = true;
- }
-
- let { domElt, overflowDOMElt } = this.browserWin.items[itemID];
- domElt.jetpackContextCurrent = areContextsCurr;
- domElt.hidden = !areContextsCurr;
- overflowDOMElt.jetpackContextCurrent = areContextsCurr;
- overflowDOMElt.hidden = !areContextsCurr;
- }
-
- // Get the total number of items that match the current context. It's a
- // little tricky: There may be other instances of this module loaded,
- // each hiding and showing their items. So we can't base this number on
- // only our items, or on the hidden state of items. That's why we set
- // the jetpackContextCurrent property above. The last instance to run
- // will leave the menupopup in the correct state.
- let elts = this._topLevelElts;
- let numShown = Array.reduce(elts, function (total, elt) {
- return total + (elt.jetpackContextCurrent ? 1 : 0);
- }, 0);
-
- // If too many items are shown, show the submenu and hide the top-level
- // items. Otherwise, hide the submenu and show the top-level items.
- let overflow = numShown > this._overflowThreshold;
- if (overflow)
- Array.forEach(elts, function (e) e.hidden = true);
-
- let submenu = this._overflowMenu;
- if (submenu)
- submenu.hidden = !overflow;
-
- // If no items are shown, hide the menu separator.
- let sep = this._separator;
- if (sep)
- sep.hidden = numShown === 0;
- },
-
- // Adds the menu separator and overflow submenu if they don't exist.
- _ensureStaticEltsExist: function CMP__ensureStaticEltsExist() {
- let sep = this._separator;
- if (!sep) {
- sep = this._makeSeparator();
- this.popupDOMElt.appendChild(sep);
- }
-
- let submenu = this._overflowMenu;
- if (!submenu) {
- submenu = this._makeOverflowMenu();
- submenu.hidden = true;
- this.popupDOMElt.insertBefore(submenu, sep.nextSibling);
- }
- },
-
- // Inserts the given item's DOM element into the popup in sorted order.
- _insertItemInSortedOrder: function CMP__insertItemInSortedOrder(item) {
- let props = this.browserWin.items[privateItem(item)._id];
- this.popupDOMElt.insertBefore(
- props.domElt, insertionPoint(item.label, this._topLevelElts));
- this._overflowPopup.insertBefore(
- props.overflowDOMElt, insertionPoint(item.label, this._overflowElts));
- },
-
- // Creates and returns the xul:menu that's shown when too many items are added
- // to the popup.
- _makeOverflowMenu: function CMP__makeOverflowMenu() {
- let submenu = this.doc.createElement("menu");
- submenu.id = OVERFLOW_MENU_ID;
- submenu.setAttribute("label", OVERFLOW_MENU_LABEL);
- let popup = this.doc.createElement("menupopup");
- popup.id = OVERFLOW_POPUP_ID;
- submenu.appendChild(popup);
- return submenu;
- },
-
- // Creates and returns the xul:menuseparator that separates the standard
- // context menu items from our items.
- _makeSeparator: function CMP__makeSeparator() {
- let elt = this.doc.createElement("menuseparator");
- elt.id = SEPARATOR_ID;
- return elt;
- },
-
- // Returns the item elements contained in the overflow menu, a NodeList.
- get _overflowElts() {
- return this._overflowPopup.getElementsByClassName(OVERFLOW_ITEM_CLASS);
- },
-
- // Returns the overflow xul:menu.
- get _overflowMenu() {
- return this.doc.getElementById(OVERFLOW_MENU_ID);
- },
-
- // Returns the overflow xul:menupopup.
- get _overflowPopup() {
- return this.doc.getElementById(OVERFLOW_POPUP_ID);
- },
-
- // Returns the OVERFLOW_THRESH_PREF pref value if it exists or
- // OVERFLOW_THRESH_DEFAULT if it doesn't.
- get _overflowThreshold() {
- let prefs = require("api-utils/preferences-service");
- return prefs.get(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
- },
-
- // Returns the xul:menuseparator.
- get _separator() {
- return this.doc.getElementById(SEPARATOR_ID);
- },
-
- // Returns the item elements contained in the top-level menu, a NodeList.
- get _topLevelElts() {
- return this.popupDOMElt.getElementsByClassName(TOPLEVEL_ITEM_CLASS);
- }
-};
-
-
-// Init the browserManager only after setting prototypes and such above, because
-// it will cause browserManager.onTrack to be called immediately if there are
-// open windows.
-browserManager.init();
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/hotkeys.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/hotkeys.js
deleted file mode 100644
index f8c6434..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/hotkeys.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Irakli Gozalishvili <gozala@mozilla.com> (Original Author)
- * Henri Wiechers <hwiechers@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const INVALID_HOTKEY = "Hotkey must have at least one modifier.";
-
-const { toJSON: jsonify, toString: stringify,
- isFunctionKey } = require("api-utils/keyboard/utils");
-const { register, unregister } = require("api-utils/keyboard/hotkeys");
-
-const Hotkey = exports.Hotkey = function Hotkey(options) {
- if (!(this instanceof Hotkey))
- return new Hotkey(options);
-
- // Parsing key combination string.
- let hotkey = jsonify(options.combo);
- if (!isFunctionKey(hotkey.key) && !hotkey.modifiers.length) {
- throw new TypeError(INVALID_HOTKEY);
- }
-
- this.onPress = options.onPress;
- this.toString = stringify.bind(null, hotkey);
- // Registering listener on keyboard combination enclosed by this hotkey.
- // Please note that `this.toString()` is a normalized version of
- // `options.combination` where order of modifiers is sorted and `accel` is
- // replaced with platform specific key.
- register(this.toString(), this.onPress);
- // We freeze instance before returning it in order to make it's properties
- // read-only.
- return Object.freeze(this);
-};
-Hotkey.prototype.destroy = function destroy() {
- unregister(this.toString(), this.onPress);
-};
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/notifications.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/notifications.js
deleted file mode 100644
index f2a4ea2..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/notifications.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Drew Willcoxon <adw@mozilla.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const { Cc, Ci, Cr } = require("chrome");
-const apiUtils = require("api-utils/api-utils");
-const errors = require("api-utils/errors");
-
-try {
- let alertServ = Cc["@mozilla.org/alerts-service;1"].
- getService(Ci.nsIAlertsService);
-
- // The unit test sets this to a mock notification function.
- var notify = alertServ.showAlertNotification.bind(alertServ);
-}
-catch (err) {
- // An exception will be thrown if the platform doesn't provide an alert
- // service, e.g., if Growl is not installed on OS X. In that case, use a
- // mock notification function that just logs to the console.
- notify = notifyUsingConsole;
-}
-
-exports.notify = function notifications_notify(options) {
- let valOpts = validateOptions(options);
- let clickObserver = !valOpts.onClick ? null : {
- observe: function notificationClickObserved(subject, topic, data) {
- if (topic === "alertclickcallback")
- errors.catchAndLog(valOpts.onClick).call(exports, valOpts.data);
- }
- };
- function notifyWithOpts(notifyFn) {
- notifyFn(valOpts.iconURL, valOpts.title, valOpts.text, !!clickObserver,
- valOpts.data, clickObserver);
- }
- try {
- notifyWithOpts(notify);
- }
- catch (err if err instanceof Ci.nsIException &&
- err.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
- console.warn("The notification icon named by " + valOpts.iconURL +
- " does not exist. A default icon will be used instead.");
- delete valOpts.iconURL;
- notifyWithOpts(notify);
- }
- catch (err) {
- notifyWithOpts(notifyUsingConsole);
- }
-};
-
-function notifyUsingConsole(iconURL, title, text) {
- title = title ? "[" + title + "]" : "";
- text = text || "";
- let str = [title, text].filter(function (s) s).join(" ");
- console.log(str);
-}
-
-function validateOptions(options) {
- return apiUtils.validateOptions(options, {
- data: {
- is: ["string", "undefined"]
- },
- iconURL: {
- is: ["string", "undefined"]
- },
- onClick: {
- is: ["function", "undefined"]
- },
- text: {
- is: ["string", "undefined"]
- },
- title: {
- is: ["string", "undefined"]
- }
- });
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/page-mod.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/page-mod.js
deleted file mode 100644
index d511464..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/page-mod.js
+++ /dev/null
@@ -1,229 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack Packages.
- *
- * The Initial Developer of the Original Code is Nickolay Ponomarev.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Nickolay Ponomarev <asqueella@gmail.com> (Original Author)
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-"use strict";
-
-const observers = require("api-utils/observer-service");
-const { Worker, Loader } = require('api-utils/content');
-const { EventEmitter } = require('api-utils/events');
-const { List } = require('api-utils/list');
-const { Registry } = require('api-utils/utils/registry');
-const xulApp = require("api-utils/xul-app");
-const { MatchPattern } = require('api-utils/match-pattern');
-
-// Whether or not the host application dispatches a document-element-inserted
-// notification when the document element is inserted into the DOM of a page.
-// The notification was added in Gecko 2.0b6, it's a better time to attach
-// scripts with contentScriptWhen "start" than content-document-global-created,
-// since libraries like jQuery assume the presence of the document element.
-const HAS_DOCUMENT_ELEMENT_INSERTED =
- xulApp.versionInRange(xulApp.platformVersion, "2.0b6", "*");
-const ON_CONTENT = HAS_DOCUMENT_ELEMENT_INSERTED ? 'document-element-inserted' :
- 'content-document-global-created';
-
-// Workaround bug 642145: document-element-inserted is fired multiple times.
-// This bug is fixed in Firefox 4.0.1, but we want to keep FF 4.0 compatibility
-// Tracking bug 641457. To be removed when 4.0 has disappeared from earth.
-const HAS_BUG_642145_FIXED =
- xulApp.versionInRange(xulApp.platformVersion, "2.0.1", "*");
-
-// rules registry
-const RULES = {};
-
-const Rules = EventEmitter.resolve({ toString: null }).compose(List, {
- add: function() Array.slice(arguments).forEach(function onAdd(rule) {
- if (this._has(rule))
- return;
- // registering rule to the rules registry
- if (!(rule in RULES))
- RULES[rule] = new MatchPattern(rule);
- this._add(rule);
- this._emit('add', rule);
- }.bind(this)),
- remove: function() Array.slice(arguments).forEach(function onRemove(rule) {
- if (!this._has(rule))
- return;
- this._remove(rule);
- this._emit('remove', rule);
- }.bind(this)),
-});
-
-/**
- * PageMod constructor (exported below).
- * @constructor
- */
-const PageMod = Loader.compose(EventEmitter, {
- on: EventEmitter.required,
- _listeners: EventEmitter.required,
- contentScript: Loader.required,
- contentScriptFile: Loader.required,
- contentScriptWhen: Loader.required,
- include: null,
- constructor: function PageMod(options) {
- this._onContent = this._onContent.bind(this);
- options = options || {};
-
- if ('contentScript' in options)
- this.contentScript = options.contentScript;
- if ('contentScriptFile' in options)
- this.contentScriptFile = options.contentScriptFile;
- if ('contentScriptWhen' in options)
- this.contentScriptWhen = options.contentScriptWhen;
- if ('onAttach' in options)
- this.on('attach', options.onAttach);
- if ('onError' in options)
- this.on('error', options.onError);
-
- let include = options.include;
- let rules = this.include = Rules();
- rules.on('add', this._onRuleAdd = this._onRuleAdd.bind(this));
- rules.on('remove', this._onRuleRemove = this._onRuleRemove.bind(this));
-
- if (Array.isArray(include))
- rules.add.apply(null, include);
- else
- rules.add(include);
-
- this.on('error', this._onUncaughtError = this._onUncaughtError.bind(this));
- pageModManager.add(this._public);
-
- this._loadingWindows = [];
- },
-
- destroy: function destroy() {
- for each (let rule in this.include)
- this.include.remove(rule);
- pageModManager.remove(this._public);
- this._loadingWindows = [];
- },
-
- _loadingWindows: [],
-
- _onContent: function _onContent(window) {
- // not registered yet
- if (!pageModManager.has(this))
- return;
-
- if (!HAS_BUG_642145_FIXED) {
- if (this._loadingWindows.indexOf(window) != -1)
- return;
- this._loadingWindows.push(window);
- }
-
- if ('start' == this.contentScriptWhen) {
- this._createWorker(window);
- return;
- }
-
- let eventName = 'end' == this.contentScriptWhen ? 'load' : 'DOMContentLoaded';
- let self = this;
- window.addEventListener(eventName, function onReady(event) {
- if (event.target.defaultView != window)
- return;
- window.removeEventListener(eventName, onReady, true);
-
- self._createWorker(window);
- }, true);
- },
- _createWorker: function _createWorker(window) {
- let worker = Worker({
- window: window,
- contentScript: this.contentScript,
- contentScriptFile: this.contentScriptFile,
- onError: this._onUncaughtError
- });
- this._emit('attach', worker);
- let self = this;
- worker.once('detach', function detach() {
- worker.destroy();
-
- if (!HAS_BUG_642145_FIXED) {
- let idx = self._loadingWindows.indexOf(window);
- if (idx != -1)
- self._loadingWindows.splice(idx, 1);
- }
- });
- },
- _onRuleAdd: function _onRuleAdd(url) {
- pageModManager.on(url, this._onContent);
- },
- _onRuleRemove: function _onRuleRemove(url) {
- pageModManager.off(url, this._onContent);
- },
- _onUncaughtError: function _onUncaughtError(e) {
- if (this._listeners('error').length == 1)
- console.exception(e);
- }
-});
-exports.PageMod = function(options) PageMod(options)
-exports.PageMod.prototype = PageMod.prototype;
-
-const PageModManager = Registry.resolve({
- constructor: '_init',
- _destructor: '_registryDestructor'
-}).compose({
- constructor: function PageModRegistry(constructor) {
- this._init(PageMod);
- observers.add(
- ON_CONTENT, this._onContentWindow = this._onContentWindow.bind(this)
- );
- },
- _destructor: function _destructor() {
- observers.remove(ON_CONTENT, this._onContentWindow);
- for (let rule in RULES) {
- this._removeAllListeners(rule);
- delete RULES[rule];
- }
- this._registryDestructor();
- },
- _onContentWindow: function _onContentWindow(domObj) {
- let window = HAS_DOCUMENT_ELEMENT_INSERTED ? domObj.defaultView : domObj;
- // XML documents don't have windows, and we don't yet support them.
- if (!window)
- return;
- for (let rule in RULES)
- if (RULES[rule].test(window.document.URL))
- this._emit(rule, window);
- },
- off: function off(topic, listener) {
- this.removeListener(topic, listener);
- if (!this._listeners(topic).length)
- delete RULES[topic];
- }
-});
-const pageModManager = PageModManager();
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/page-worker.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/page-worker.js
deleted file mode 100644
index 93750a1..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/page-worker.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Felipe Gomes <felipc@gmail.com> (Original Author)
- * Myk Melez <myk@mozilla.org>
- * Irakli Gozalishvili <gozala@mozilla.com>
- * Drew Willcoxon <adw@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-"use strict";
-
-const { Symbiont } = require("api-utils/content");
-const { Trait } = require("api-utils/traits");
-
-if (!require("api-utils/xul-app").isOneOf(["Firefox", "Thunderbird"])) {
- throw new Error([
- "The page-worker module currently supports only Firefox and Thunderbird. ",
- "In the future, we would like it to support other applications, however. ",
- "Please see https://bugzilla.mozilla.org/show_bug.cgi?id=546740 for more ",
- "information."
- ].join(""));
-}
-
-const Page = Trait.compose(
- Symbiont.resolve({
- constructor: '_initSymbiont'
- }),
- {
- _frame: Trait.required,
- _initFrame: Trait.required,
- postMessage: Symbiont.required,
- on: Symbiont.required,
- destroy: Symbiont.required,
-
- constructor: function Page(options) {
- options = options || {};
-
- this.contentURL = 'contentURL' in options ? options.contentURL
- : 'about:blank';
- if ('contentScriptWhen' in options)
- this.contentScriptWhen = options.contentScriptWhen;
- 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);
-
- this.on('propertyChange', this._onChange.bind(this));
-
- this._initSymbiont();
- },
-
- _onChange: function _onChange(e) {
- if ('contentURL' in e && this._frame) {
- // Cleanup the worker before injecting the content script in the new
- // document
- this._workerCleanup();
- this._initFrame(this._frame);
- }
- }
- }
-);
-exports.Page = function(options) Page(options);
-exports.Page.prototype = Page.prototype;
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/panel.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/panel.js
deleted file mode 100644
index 442f6a9..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/panel.js
+++ /dev/null
@@ -1,403 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Myk Melez <myk@mozilla.org> (Original Author)
- * Irakli Gozalishvili <gozala@mazilla.com>
- * Mihai Sucan <mihai.sucan@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The panel module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps ",
- "for more information."
- ].join(""));
-}
-
-const { Cc, Ci } = require("chrome");
-
-const { validateOptions: valid } = require("api-utils/api-utils");
-const { Symbiont } = require("api-utils/content");
-const { EventEmitter } = require('api-utils/events');
-const timer = require("api-utils/timer");
-const runtime = require("api-utils/runtime");
-
-const windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
- getService(Ci.nsIWindowMediator);
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- ON_SHOW = 'popupshown',
- ON_HIDE = 'popuphidden',
- validNumber = { is: ['number', 'undefined', 'null'] };
-
-/**
- * Emits show and hide events.
- */
-const Panel = Symbiont.resolve({
- constructor: '_init',
- _onInit: '_onSymbiontInit',
- destroy: '_symbiontDestructor',
- _documentUnload: '_workerDocumentUnload'
-}).compose({
- _frame: Symbiont.required,
- _init: Symbiont.required,
- _onSymbiontInit: Symbiont.required,
- _symbiontDestructor: Symbiont.required,
- _emit: Symbiont.required,
- _asyncEmit: Symbiont.required,
- on: Symbiont.required,
- removeListener: Symbiont.required,
-
- _inited: false,
-
- /**
- * If set to `true` frame loaders between xul panel frame and
- * hidden frame are swapped. If set to `false` frame loaders are
- * set back to normal. Setting the value that was already set will
- * have no effect.
- */
- set _frameLoadersSwapped(value) {
- if (this.__frameLoadersSwapped == value) return;
- this._frame.QueryInterface(Ci.nsIFrameLoaderOwner)
- .swapFrameLoaders(this._viewFrame);
- this.__frameLoadersSwapped = value;
- },
- __frameLoadersSwapped: false,
-
- constructor: function Panel(options) {
- this._onShow = this._onShow.bind(this);
- this._onHide = this._onHide.bind(this);
- this.on('inited', this._onSymbiontInit.bind(this));
-
- options = options || {};
- if ('onShow' in options)
- this.on('show', options.onShow);
- if ('onHide' in options)
- this.on('hide', options.onHide);
- if ('width' in options)
- this.width = options.width;
- if ('height' in options)
- this.height = options.height;
- if ('contentURL' in options)
- this.contentURL = options.contentURL;
-
- this._init(options);
- },
- _destructor: function _destructor() {
- this.hide();
- this._removeAllListeners('show');
- // defer cleanup to be performed after panel gets hidden
- this._xulPanel = null;
- this._symbiontDestructor(this);
- this._removeAllListeners(this, 'hide');
- },
- destroy: function destroy() {
- this._destructor();
- },
- /* Public API: Panel.width */
- get width() this._width,
- set width(value)
- this._width = valid({ $: value }, { $: validNumber }).$ || this._width,
- _width: 320,
- /* Public API: Panel.height */
- get height() this._height,
- set height(value)
- this._height = valid({ $: value }, { $: validNumber }).$ || this._height,
- _height: 240,
-
- /* Public API: Panel.isShowing */
- get isShowing() !!this._xulPanel && this._xulPanel.state == "open",
-
- /* Public API: Panel.show */
- show: function show(anchor) {
- anchor = anchor || null;
- let document = getWindow(anchor).document;
- let xulPanel = this._xulPanel;
- if (!xulPanel) {
- xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
- xulPanel.setAttribute("type", "arrow");
-
- // One anonymous node has a big padding that doesn't work well with
- // Jetpack, as we would like to display an iframe that completely fills
- // the panel.
- // -> Use a XBL wrapper with inner stylesheet to remove this padding.
- let css = ".panel-inner-arrowcontent, .panel-arrowcontent {padding: 0;}";
- let originalXBL = "chrome://global/content/bindings/popup.xml#arrowpanel";
- let binding =
- '<bindings xmlns="http://www.mozilla.org/xbl">' +
- '<binding id="id" extends="' + originalXBL + '">' +
- '<resources>' +
- '<stylesheet src="data:text/css,' +
- document.defaultView.encodeURIComponent(css) + '"/>' +
- '</resources>' +
- '</binding>' +
- '</bindings>';
- xulPanel.style.MozBinding = 'url("data:text/xml,' +
- document.defaultView.encodeURIComponent(binding) + '")';
-
- let frame = document.createElementNS(XUL_NS, 'iframe');
- frame.setAttribute('type', 'content');
- frame.setAttribute('flex', '1');
- frame.setAttribute('transparent', 'transparent');
- if (runtime.OS === "Darwin") {
- frame.style.borderRadius = "6px";
- frame.style.padding = "1px";
- }
-
- // Load an empty document in order to have an immediatly loaded iframe,
- // so swapFrameLoaders is going to work without having to wait for load.
- frame.setAttribute("src","data:,");
-
- xulPanel.appendChild(frame);
- document.getElementById("mainPopupSet").appendChild(xulPanel);
- }
- let { width, height } = this, x, y, position;
-
- if (!anchor) {
- // Open the popup in the middle of the window.
- x = document.documentElement.clientWidth / 2 - width / 2;
- y = document.documentElement.clientHeight / 2 - height / 2;
- position = null;
- }
- else {
- // Open the popup by the anchor.
- let rect = anchor.getBoundingClientRect();
-
- let window = anchor.ownerDocument.defaultView;
-
- let zoom = window.mozScreenPixelsPerCSSPixel;
- let screenX = rect.left + window.mozInnerScreenX * zoom;
- let screenY = rect.top + window.mozInnerScreenY * zoom;
-
- // Set up the vertical position of the popup relative to the anchor
- // (always display the arrow on anchor center)
- let horizontal, vertical;
- if (screenY > window.screen.availHeight / 2 + height)
- vertical = "top";
- else
- vertical = "bottom";
-
- if (screenY > window.screen.availWidth / 2 + width)
- horizontal = "left";
- else
- horizontal = "right";
-
- let verticalInverse = vertical == "top" ? "bottom" : "top";
- position = vertical + "center " + verticalInverse + horizontal;
-
- // Allow panel to flip itself if the panel can't be displayed at the
- // specified position (useful if we compute a bad position or if the
- // user moves the window and panel remains visible)
- xulPanel.setAttribute("flip","both");
- }
-
- // Resize the iframe instead of using panel.sizeTo
- // because sizeTo doesn't work with arrow panels
- xulPanel.firstChild.style.width = width + "px";
- xulPanel.firstChild.style.height = height + "px";
-
- // Wait for the XBL binding to be constructed
- function waitForBinding() {
- if (!xulPanel.openPopup) {
- timer.setTimeout(waitForBinding, 50);
- return;
- }
- xulPanel.openPopup(anchor, position, x, y);
- }
- waitForBinding();
-
- return this._public;
- },
- /* Public API: Panel.hide */
- hide: function hide() {
- // The popuphiding handler takes care of swapping back the frame loaders
- // and removing the XUL panel from the application window, we just have to
- // trigger it by hiding the popup.
- // XXX Sometimes I get "TypeError: xulPanel.hidePopup is not a function"
- // when quitting the host application while a panel is visible. To suppress
- // them, this now checks for "hidePopup" in xulPanel before calling it.
- // It's not clear if there's an actual issue or the error is just normal.
- let xulPanel = this._xulPanel;
- if (xulPanel && "hidePopup" in xulPanel)
- xulPanel.hidePopup();
- return this._public;
- },
-
- /* Public API: Panel.resize */
- resize: function resize(width, height) {
- this.width = width;
- this.height = height;
- // Resize the iframe instead of using panel.sizeTo
- // because sizeTo doesn't work with arrow panels
- let xulPanel = this._xulPanel;
- if (xulPanel) {
- xulPanel.firstChild.style.width = width + "px";
- xulPanel.firstChild.style.height = height + "px";
- }
- },
-
- // While the panel is visible, this is the XUL <panel> we use to display it.
- // Otherwise, it's null.
- get _xulPanel() this.__xulPanel,
- set _xulPanel(value) {
- let xulPanel = this.__xulPanel;
- if (value === xulPanel) return;
- if (xulPanel) {
- xulPanel.removeEventListener(ON_HIDE, this._onHide, false);
- xulPanel.removeEventListener(ON_SHOW, this._onShow, false);
- xulPanel.parentNode.removeChild(xulPanel);
- }
- if (value) {
- value.addEventListener(ON_HIDE, this._onHide, false);
- value.addEventListener(ON_SHOW, this._onShow, false);
- }
- this.__xulPanel = value;
- },
- __xulPanel: null,
- get _viewFrame() this.__xulPanel.children[0],
- /**
- * When the XUL panel becomes hidden, we swap frame loaders back to move
- * the content of the panel to the hidden frame & remove panel element.
- */
- _onHide: function _onHide() {
- try {
- this._frameLoadersSwapped = false;
- this._xulPanel = null;
- this._emit('hide');
- } catch(e) {
- this._emit('error', e);
- }
- },
- /**
- * When the XUL panel becomes shown, we swap frame loaders between panel
- * frame and hidden frame to preserve state of the content dom.
- */
- _onShow: function _onShow() {
- try {
- if (!this._inited) { // defer if not initialized yet
- this.on('inited', this._onShow.bind(this));
- } else {
- this._frameLoadersSwapped = true;
-
- // Retrieve computed text color style in order to apply to the iframe
- // document. As MacOS background is dark gray, we need to use skin's
- // text color.
- let win = this._xulPanel.ownerDocument.defaultView;
- let node = win.document.getAnonymousElementByAttribute(this._xulPanel,
- "class", "panel-inner-arrowcontent");
- let textColor = win.getComputedStyle(node).getPropertyValue("color");
- let doc = this._xulPanel.firstChild.contentDocument;
- let style = doc.createElement("style");
- style.textContent = "body { color: " + textColor + "; }";
- let container = doc.head ? doc.head : doc.documentElement;
-
- if (container.firstChild)
- container.insertBefore(style, container.firstChild);
- else
- container.appendChild(style);
-
- this._emit('show');
- }
- } catch(e) {
- this._emit('error', e);
- }
- },
- /**
- * Notification that panel was fully initialized.
- */
- _onInit: function _onInit() {
- this._inited = true;
-
- // Avoid panel document from resizing the browser window
- // New platform capability added through bug 635673
- if ("allowWindowControl" in this._frame.docShell)
- this._frame.docShell.allowWindowControl = false;
-
- // perform all deferred tasks like initSymbiont, show, hide ...
- // TODO: We're publicly exposing a private event here; this
- // 'inited' event should really be made private, somehow.
- this._emit('inited');
- },
-
- // Catch document unload event in order to rebind load event listener with
- // Symbiont._initFrame if Worker._documentUnload destroyed the worker
- _documentUnload: function(subject, topic, data) {
- if (this._workerDocumentUnload(subject, topic, data)) {
- this._initFrame(this._frame);
- return true;
- }
- return false;
- }
-});
-exports.Panel = function(options) Panel(options)
-exports.Panel.prototype = Panel.prototype;
-
-function getWindow(anchor) {
- let window;
-
- if (anchor) {
- let anchorWindow = anchor.ownerDocument.defaultView.top;
- let anchorDocument = anchorWindow.document;
-
- let enumerator = windowMediator.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements()) {
- let enumWindow = enumerator.getNext();
-
- // Check if the anchor is in this browser window.
- if (enumWindow == anchorWindow) {
- window = anchorWindow;
- break;
- }
-
- // Check if the anchor is in a browser tab in this browser window.
- let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
- if (browser) {
- window = enumWindow;
- break;
- }
-
- // Look in other subdocuments (sidebar, etc.)?
- }
- }
-
- // If we didn't find the anchor's window (or we have no anchor),
- // return the most recent browser window.
- if (!window)
- window = windowMediator.getMostRecentWindow("navigator:browser");
-
- return window;
-}
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/passwords.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/passwords.js
deleted file mode 100644
index 8225da9..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/passwords.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Irakli Gozalishvili <gozala@mozilla.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-const { Trait } = require("api-utils/light-traits");
-const utils = require("api-utils/passwords/utils");
-const defer = require("api-utils/utils/function").Enqueued;
-
-/**
- * Utility function that returns `onComplete` and `onError` callbacks form the
- * given `options` objects. Also properties are removed from the passed
- * `options` objects.
- * @param {Object} options
- * Object that is passed to the exported functions of this module.
- * @returns {Function[]}
- * Array with two elements `onComplete` and `onError` functions.
- */
-function getCallbacks(options) {
- let value = [
- 'onComplete' in options ? options.onComplete : null,
- 'onError' in options ? defer(options.onError) : console.exception
- ];
-
- delete options.onComplete;
- delete options.onError;
-
- return value;
-};
-
-/**
- * Creates a wrapper function that tries to call `onComplete` with a return
- * value of the wrapped function or falls back to `onError` if wrapped function
- * throws an exception.
- */
-function createWrapperMethod(wrapped) {
- return function (options) {
- let [ onComplete, onError ] = getCallbacks(options);
- try {
- let value = wrapped(options);
- if (onComplete) {
- defer(function() {
- try {
- onComplete(value);
- } catch (exception) {
- onError(exception);
- }
- })();
- }
- } catch (exception) {
- onError(exception);
- }
- };
-}
-
-exports.search = createWrapperMethod(utils.search);
-exports.store = createWrapperMethod(utils.store);
-exports.remove = createWrapperMethod(utils.remove);
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/private-browsing.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/private-browsing.js
deleted file mode 100644
index 8336e7b..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/private-browsing.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Paul O’Shannessy <paul@oshannessy.com>
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const {Cc,Ci} = require("chrome");
-const observers = require("api-utils/observer-service");
-const { EventEmitter } = require("api-utils/events");
-const { setTimeout } = require("api-utils/timer");
-const unload = require("api-utils/unload");
-
-const ON_START = "start";
-const ON_STOP = "stop";
-const ON_TRANSITION = "private-browsing-transition-complete";
-
-let pbService;
-// Currently, only Firefox implements the private browsing service.
-if (require("api-utils/xul-app").is("Firefox")) {
- pbService = Cc["@mozilla.org/privatebrowsing;1"].
- getService(Ci.nsIPrivateBrowsingService);
-}
-
-function toggleMode(value) pbService.privateBrowsingEnabled = !!value
-
-const privateBrowsing = EventEmitter.compose({
- constructor: function PrivateBrowsing() {
- // Binding method to instance since it will be used with `setTimeout`.
- this._emitOnObject = this._emitOnObject.bind(this);
- this.unload = this.unload.bind(this);
- // Report unhandled errors from listeners
- this.on("error", console.exception.bind(console));
- unload.ensure(this);
- // We only need to add observers if `pbService` exists.
- if (pbService) {
- observers.add(ON_TRANSITION, this.onTransition.bind(this));
- this._isActive = pbService.privateBrowsingEnabled;
- }
- },
- unload: function _destructor() {
- this._removeAllListeners(ON_START);
- this._removeAllListeners(ON_STOP);
- },
- // We don't need to do anything with cancel here.
- onTransition: function onTransition() {
- let isActive = this._isActive = pbService.privateBrowsingEnabled;
- setTimeout(this._emitOnObject, 0, exports, isActive ? ON_START : ON_STOP);
- },
- get isActive() this._isActive,
- set isActive(value) {
- if (pbService)
- // We toggle private browsing mode asynchronously in order to work around
- // bug 659629. Since private browsing transitions are asynchronous
- // anyway, this doesn't significantly change the behavior of the API.
- setTimeout(toggleMode, 0, value);
- },
- _isActive: false
-})()
-
-Object.defineProperty(exports, "isActive", {
- get: function() privateBrowsing.isActive
-});
-exports.activate = function activate() privateBrowsing.isActive = true;
-exports.deactivate = function deactivate() privateBrowsing.isActive = false;
-exports.on = privateBrowsing.on;
-exports.once = privateBrowsing.once;
-exports.removeListener = privateBrowsing.removeListener;
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/request.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/request.js
deleted file mode 100644
index a72b28c..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/request.js
+++ /dev/null
@@ -1,309 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Paul O’Shannessy <paul@oshannessy.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-const xpcom = require("api-utils/xpcom");
-const xhr = require("api-utils/xhr");
-const errors = require("api-utils/errors");
-const apiUtils = require("api-utils/api-utils");
-
-// Ugly but will fix with: https://bugzilla.mozilla.org/show_bug.cgi?id=596248
-const EventEmitter = require('api-utils/events').EventEmitter.compose({
- constructor: function EventEmitter() this
-});
-
-// Instead of creating a new validator for each request, just make one and reuse it.
-const validator = new OptionsValidator({
- url: {
- //XXXzpao should probably verify that url is a valid url as well
- is: ["string"]
- },
- headers: {
- map: function (v) v || {},
- is: ["object"],
- },
- content: {
- map: function (v) v || null,
- is: ["string", "object", "null"],
- },
- contentType: {
- map: function (v) v || "application/x-www-form-urlencoded",
- is: ["string"],
- },
- overrideMimeType: {
- map: function(v) v || null,
- is: ["string", "null"],
- }
-});
-
-const REUSE_ERROR = "This request object has been used already. You must " +
- "create a new one to make a new request."
-
-function Request(options) {
- const self = EventEmitter(),
- _public = self._public;
- // request will hold the actual XHR object
- let request;
- let response;
-
- if ('onComplete' in options)
- self.on('complete', options.onComplete)
- options = validator.validateOptions(options);
-
- // function to prep the request since it's the same between GET and POST
- function makeRequest(mode) {
- // If this request has already been used, then we can't reuse it. Throw an error.
- if (request) {
- throw new Error(REUSE_ERROR);
- }
-
- request = new xhr.XMLHttpRequest();
-
- let url = options.url;
- // Build the data to be set. For GET requests, we want to append that to
- // the URL before opening the request.
- let data = makeQueryString(options.content);
- if (mode == "GET" && data) {
- // If the URL already has ? in it, then we want to just use &
- url = url + (/\?/.test(url) ? "&" : "?") + data;
- }
-
- // open the request
- request.open(mode, url);
-
- // request header must be set after open, but before send
- request.setRequestHeader("Content-Type", options.contentType);
-
- // set other headers
- for (let k in options.headers) {
- request.setRequestHeader(k, options.headers[k]);
- }
-
- // set overrideMimeType
- if (options.overrideMimeType) {
- request.overrideMimeType(options.overrideMimeType);
- }
-
- // handle the readystate, create the response, and call the callback
- request.onreadystatechange = function () {
- if (request.readyState == 4) {
- response = new Response(request);
- errors.catchAndLog(function () {
- self._emit('complete', response);
- })();
- }
- }
-
- // actually send the request. we only want to send data on POST requests
- request.send(mode == "POST" ? data : null);
- }
-
- // Map these setters/getters to the options
- ["url", "headers", "content", "contentType"].forEach(function (k) {
- _public.__defineGetter__(k, function () options[k]);
- _public.__defineSetter__(k, function (v) {
- // This will automatically rethrow errors from apiUtils.validateOptions.
- return options[k] = validator.validateSingleOption(k, v);
- });
- });
-
- // response should be available as a getter
- _public.__defineGetter__("response", function () response);
-
- _public.get = function () {
- makeRequest("GET");
- return this;
- };
-
- _public.post = function () {
- makeRequest("POST");
- return this;
- };
-
- return _public;
-}
-exports.Request = Request;
-
-// Converts an object of unordered key-vals to a string that can be passed
-// as part of a request
-function makeQueryString(content) {
- // Explicitly return null if we have null, and empty string, or empty object.
- if (!content) {
- return null;
- }
-
- // If content is already a string, just return it as is.
- if (typeof(content) == "string") {
- return content;
- }
-
- // At this point we have a k:v object. Iterate over it and encode each value.
- // Arrays and nested objects will get encoded as needed. For example...
- //
- // { foo: [1, 2, { omg: "bbq", "all your base!": "are belong to us" }], bar: "baz" }
- //
- // will be encoded as
- //
- // foo[0]=1&foo[1]=2&foo[2][omg]=bbq&foo[2][all+your+base!]=are+belong+to+us&bar=baz
- //
- // Keys (including "[" and "]") and values will be encoded with
- // fixedEncodeURIComponent before returning.
- //
- // Execution was inspired by jQuery, but some details have changed and numeric
- // array keys are included (whereas they are not in jQuery).
-
- let encodedContent = [];
- function add(key, val) {
- encodedContent.push(fixedEncodeURIComponent(key) + "=" +
- fixedEncodeURIComponent(val));
- }
-
- function make(key, val) {
- if (typeof(val) === "object" && val !== null) {
- for ([k, v] in Iterator(val)) {
- make(key + "[" + k + "]", v);
- }
- }
- else {
- add(key, val)
- }
- }
- for ([k, v] in Iterator(content)) {
- make(k, v);
- }
- return encodedContent.join("&");
-
- //XXXzpao In theory, we can just use a FormData object on 1.9.3, but I had
- // trouble getting that working. It would also be nice to stay
- // backwards-compat as long as possible. Keeping this in for now...
- // let formData = Cc["@mozilla.org/files/formdata;1"].
- // createInstance(Ci.nsIDOMFormData);
- // for ([k, v] in Iterator(content)) {
- // formData.append(k, v);
- // }
- // return formData;
-}
-
-
-// encodes a string safely for application/x-www-form-urlencoded
-// adheres to RFC 3986
-// see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/encodeURIComponent
-function fixedEncodeURIComponent (str) {
- return encodeURIComponent(str).replace(/%20/g, "+").replace(/!/g, "%21").
- replace(/'/g, "%27").replace(/\(/g, "%28").
- replace(/\)/g, "%29").replace(/\*/g, "%2A");
-}
-
-function Response(request) {
- // Define the straight mappings of our value to original request value
- xpcom.utils.defineLazyGetter(this, "text", function () request.responseText);
- xpcom.utils.defineLazyGetter(this, "xml", function () {
- throw new Error("Sorry, the 'xml' property is no longer available. " +
- "see bug 611042 for more information.");
- });
- xpcom.utils.defineLazyGetter(this, "status", function () request.status);
- xpcom.utils.defineLazyGetter(this, "statusText", function () request.statusText);
-
- // this.json should be the JS object, so we need to attempt to parse it.
- xpcom.utils.defineLazyGetter(this, "json", function () {
- let _json = null;
- try {
- _json = JSON.parse(this.text);
- }
- catch (e) {}
- return _json;
- });
-
- // this.headers also should be a JS object, so we need to split up the raw
- // headers string provided by the request.
- xpcom.utils.defineLazyGetter(this, "headers", function () {
- let _headers = {};
- let lastKey;
- // Since getAllResponseHeaders() will return null if there are no headers,
- // defend against it by defaulting to ""
- let rawHeaders = request.getAllResponseHeaders() || "";
- rawHeaders.split("\n").forEach(function (h) {
- // According to the HTTP spec, the header string is terminated by an empty
- // line, so we can just skip it.
- if (!h.length) {
- return;
- }
-
- let index = h.indexOf(":");
- // The spec allows for leading spaces, so instead of assuming a single
- // leading space, just trim the values.
- let key = h.substring(0, index).trim(),
- val = h.substring(index + 1).trim();
-
- // For empty keys, that means that the header value spanned multiple lines.
- // In that case we should append the value to the value of lastKey with a
- // new line. We'll assume lastKey will be set because there should never
- // be an empty key on the first pass.
- if (key) {
- _headers[key] = val;
- lastKey = key;
- }
- else {
- _headers[lastKey] += "\n" + val;
- }
- });
- return _headers;
- })
-}
-
-// apiUtils.validateOptions doesn't give the ability to easily validate single
-// options, so this is a wrapper that provides that ability.
-function OptionsValidator(rules) {
- this.rules = rules;
-
- this.validateOptions = function (options) {
- return apiUtils.validateOptions(options, this.rules);
- }
-
- this.validateSingleOption = function (field, value) {
- // We need to create a single rule object from our listed rules. To avoid
- // JavaScript String warnings, check for the field & default to an empty object.
- let singleRule = {};
- if (field in this.rules) {
- singleRule[field] = this.rules[field];
- }
- let singleOption = {};
- singleOption[field] = value;
- // This should throw if it's invalid, which will bubble up & out.
- return apiUtils.validateOptions(singleOption, singleRule)[field];
- }
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/selection.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/selection.js
deleted file mode 100644
index 48db7fc..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/selection.js
+++ /dev/null
@@ -1,448 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Eric H. Jung <eric.jung@yahoo.com>
- * Irakli Gozalishivili <gozala@mozilla.com>
- * Matteo Ferretti <zer0@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The selection module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-let { Ci } = require("chrome"),
- { setTimeout } = require("api-utils/timer"),
- { EventEmitter } = require("api-utils/events");
-
-// The selection type HTML
-const HTML = 0x01;
-
-// The selection type TEXT
-const TEXT = 0x02;
-
-// The selection type DOM (internal use only)
-const DOM = 0x03;
-
-// A more developer-friendly message than the caught exception when is not
-// possible change a selection.
-const ERR_CANNOT_CHANGE_SELECTION =
- "It isn't possible to change the selection, as there isn't currently a selection";
-
-/**
- * Creates an object from which a selection can be set, get, etc. Each
- * object has an associated with a range number. Range numbers are the
- * 0-indexed counter of selection ranges as explained at
- * https://developer.mozilla.org/en/DOM/Selection.
- *
- * @param rangeNumber
- * The zero-based range index into the selection
- */
-function Selection(rangeNumber) {
-
- // In order to hide the private rangeNumber argument from API consumers while
- // still enabling Selection getters/setters to access it, the getters/setters
- // are defined as lexical closures in the Selector constructor.
-
- this.__defineGetter__("text", function () getSelection(TEXT, rangeNumber));
- this.__defineSetter__("text", function (str) setSelection(str, rangeNumber));
-
- this.__defineGetter__("html", function () getSelection(HTML, rangeNumber));
- this.__defineSetter__("html", function (str) setSelection(str, rangeNumber));
-
- this.__defineGetter__("isContiguous", function () {
- let sel = getSelection(DOM);
-
- // If there are multiple ranges, the selection is definitely discontiguous.
- // It returns `false` also if there are no selection; and `true` if there is
- // a single non empty range, or a selection in a text field - contiguous or
- // not (text field selection APIs doesn't support multiple selections).
-
- if (sel.rangeCount > 1)
- return false;
-
- return !!(safeGetRange(sel, 0) || getElementWithSelection());
- });
-}
-
-require("api-utils/xpcom").utils.defineLazyServiceGetter(this, "windowMediator",
- "@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
-
-/**
- * Returns the most recent content window
- */
-function context() {
- // Overlay names should probably go into the xul-app module instead of here
- return windowMediator.getMostRecentWindow("navigator:browser").document.
- commandDispatcher.focusedWindow;
-}
-
-/**
- * Returns the current selection from most recent content window. Depending on
- * the specified |type|, the value returned can be a string of text, stringified
- * HTML, or a DOM selection object as described at
- * https://developer.mozilla.org/en/DOM/Selection.
- *
- * @param type
- * Specifies the return type of the selection. Valid values are the one
- * of the constants HTML, TEXT, or DOM.
- *
- * @param rangeNumber
- * Specifies the zero-based range index of the returned selection.
- */
-function getSelection(type, rangeNumber) {
- let window, selection;
- try {
- window = context();
- selection = window.getSelection();
- }
- catch (e) {
- return null;
- }
-
- // Get the selected content as the specified type
- if (type == DOM)
- return selection;
- else if (type == TEXT) {
- let range = safeGetRange(selection, rangeNumber);
-
- if (range)
- return range.toString();
-
- let node = getElementWithSelection(window);
-
- if (!node)
- return null;
-
- return node.value.substring(node.selectionStart, node.selectionEnd);
- }
- else if (type == HTML) {
- let range = safeGetRange(selection, rangeNumber);
- // Another way, but this includes the xmlns attribute for all elements in
- // Gecko 1.9.2+ :
- // return Cc["@mozilla.org/xmlextras/xmlserializer;1"].
- // createInstance(Ci.nsIDOMSerializer).serializeToSTring(range.
- // cloneContents());
- if (!range)
- return null;
- let node = window.document.createElement("span");
- node.appendChild(range.cloneContents());
- return node.innerHTML;
- }
- throw new Error("Type " + type + " is unrecognized.");
-}
-
-/**
- * Returns the specified range in a selection without throwing an exception.
- *
- * @param selection
- * A selection object as described at
- * https://developer.mozilla.org/en/DOM/Selection
- *
- * @param rangeNumber
- * Specifies the zero-based range index of the returned selection.
- */
-function safeGetRange(selection, rangeNumber) {
- try {
- let range = selection.getRangeAt(rangeNumber);
- if (!range || range.toString() == "")
- return null;
- return range;
- }
- catch (e) {
- return null;
- }
-}
-
-/**
- * Returns a reference of the DOM's active element for the window given, if it
- * supports the text field selection API and has a text selected.
- *
- * Note:
- * we need this method because window.getSelection doesn't return a selection
- * for text selected in a form field (see bug 85686)
- *
- * @param {nsIWindow} [window]
- * A reference to a window
- */
-function getElementWithSelection(window) {
- let element;
-
- try {
- element = (window || context()).document.activeElement;
- }
- catch (e) {
- element = null;
- }
-
- if (!element)
- return null;
-
- let { value, selectionStart, selectionEnd } = element;
-
- let hasSelection = typeof value === "string" &&
- !isNaN(selectionStart) &&
- !isNaN(selectionEnd) &&
- selectionStart !== selectionEnd;
-
- return hasSelection ? element : null;
-}
-/**
- * Sets the current selection of the most recent content document by changing
- * the existing selected text/HTML range to the specified value.
- *
- * @param val
- * The value for the new selection
- *
- * @param rangeNumber
- * The zero-based range index of the selection to be set
- *
- */
-function setSelection(val, rangeNumber) {
- // Make sure we have a window context & that there is a current selection.
- // Selection cannot be set unless there is an existing selection.
- let window, selection;
-
- try {
- window = context();
- selection = window.getSelection();
- }
- catch (e) {
- throw new Error(ERR_CANNOT_CHANGE_SELECTION);
- }
-
- let range = safeGetRange(selection, rangeNumber);
-
- if (range) {
- // Get rid of the current selection and insert our own
- range.deleteContents();
- let node = window.document.createElement("span");
- range.surroundContents(node);
-
- // Some relevant JEP-111 requirements:
-
- // Setting the text property replaces the selection with the value to
- // which the property is set and sets the html property to the same value
- // to which the text property is being set.
-
- // Setting the html property replaces the selection with the value to
- // which the property is set and sets the text property to the text version
- // of the HTML value.
-
- // This sets both the HTML and text properties.
- node.innerHTML = val;
- } else {
- let node = getElementWithSelection(window);
-
- if (!node)
- throw new Error(ERR_CANNOT_CHANGE_SELECTION);
-
- let { value, selectionStart, selectionEnd } = node;
-
- let newSelectionEnd = selectionStart + val.length;
-
- node.value = value.substring(0, selectionStart) +
- val +
- value.substring(selectionEnd, value.length);
-
- node.setSelectionRange(selectionStart, newSelectionEnd);
- }
-}
-
-function onLoad(event) {
- SelectionListenerManager.onLoad(event);
-}
-
-function onUnload(event) {
- SelectionListenerManager.onUnload(event);
-}
-
-function onSelect() {
- SelectionListenerManager.onSelect();
-}
-
-let SelectionListenerManager = {
- QueryInterface: require("api-utils/xpcom").utils.
- generateQI([Ci.nsISelectionListener]),
-
- // The collection of listeners wanting to be notified of selection changes
- listeners: EventEmitter.compose({
- emit: function emit(type) this._emitOnObject(exports, type),
- off: function() this._removeAllListeners.apply(this, arguments)
- })(),
- /**
- * This is the nsISelectionListener implementation. This function is called
- * by Gecko when a selection is changed interactively.
- *
- * We only pay attention to the SELECTALL, KEYPRESS, and MOUSEUP selection
- * reasons. All reasons are listed here:
- *
- * http://mxr.mozilla.org/mozilla1.9.2/source/content/base/public/
- * nsISelectionListener.idl
- *
- * The other reasons (NO_REASON, DRAG_REASON, MOUSEDOWN_REASON) aren't
- * applicable to us.
- */
- notifySelectionChanged: function notifySelectionChanged(document, selection,
- reason) {
- if (!["SELECTALL", "KEYPRESS", "MOUSEUP"].some(function(type) reason &
- Ci.nsISelectionListener[type + "_REASON"]) || selection.toString() == "")
- return;
-
- this.onSelect();
- },
-
- onSelect : function onSelect() {
- setTimeout(this.listeners.emit, 0, "select");
- },
-
- /**
- * Part of the Tracker implementation. This function is called by the
- * tabs module when a browser is being tracked. Often, that means a new tab
- * has been opened, but it can also mean an addon has been installed while
- * tabs are already opened. In that case, this function is called for those
- * already-opened tabs.
- *
- * @param browser
- * The browser being tracked
- */
- onTrack: function onTrack(browser) {
- browser.addEventListener("load", onLoad, true);
- browser.addEventListener("unload", onUnload, true);
- },
-
- onLoad: function onLoad(event) {
- // Nothing to do without a useful window
- let window = event.target.defaultView;
- if (!window)
- return;
-
- // Wrap the add selection call with some number of setTimeout 0 because some
- // reason it's possible to add a selection listener "too early". 2 sometimes
- // works for gmail, and more consistently with 3, so make it 5 to be safe.
- let count = 0;
- let self = this;
- function wrap(count, func) {
- if (count-- > 0)
- require("api-utils/timer").setTimeout(wrap, 0);
- else
- self.addSelectionListener(window);
- }
- wrap();
- },
-
- addSelectionListener: function addSelectionListener(window) {
- if (window.jetpack_core_selection_listener)
- return;
- let selection = window.getSelection();
- if (selection instanceof Ci.nsISelectionPrivate)
- selection.addSelectionListener(this);
-
- // nsISelectionListener implementation seems not fire a notification if
- // a selection is in a text field, therefore we need to add a listener to
- // window.onselect, that is fired only for text fields.
- // https://developer.mozilla.org/en/DOM/window.onselect
- window.addEventListener("select", onSelect, true);
-
- window.jetpack_core_selection_listener = true;
- },
-
- onUnload: function onUnload(event) {
- // Nothing to do without a useful window
- let window = event.target.defaultView;
- if (!window)
- return;
- this.removeSelectionListener(window);
- this.listeners.off('error');
- this.listeners.off('selection');
- },
-
- removeSelectionListener: function removeSelectionListener(window) {
- if (!window.jetpack_core_selection_listener)
- return;
- let selection = window.getSelection();
- if (selection instanceof Ci.nsISelectionPrivate)
- selection.removeSelectionListener(this);
-
- window.removeEventListener("select", onSelect);
-
- window.jetpack_core_selection_listener = false;
- },
-
- /**
- * Part of the TabTracker implementation. This function is called by the
- * tabs module when a browser is being untracked. Usually, that means a tab
- * has been closed.
- *
- * @param browser
- * The browser being untracked
- */
- onUntrack: function onUntrack(browser) {
- browser.removeEventListener("load", onLoad, true);
- browser.removeEventListener("unload", onUnload, true);
- }
-};
-SelectionListenerManager.listeners.on('error', console.error);
-
-/**
- * Install |SelectionListenerManager| as tab tracker in order to watch
- * tab opening/closing
- */
-require("api-utils/tab-browser").Tracker(SelectionListenerManager);
-
-/**
- * Exports an iterator so that discontiguous selections can be iterated.
- *
- * If discontiguous selections are in a text field, only the first one
- * is returned because the text field selection APIs doesn't support
- * multiple selections.
- */
-exports.__iterator__ = function __iterator__() {
- let sel = getSelection(DOM);
- let rangeCount = sel.rangeCount || (getElementWithSelection() ? 1 : 0);
-
- for (let i = 0; i < rangeCount; i++)
- yield new Selection(i);
-};
-
-exports.on = SelectionListenerManager.listeners.on;
-exports.removeListener = SelectionListenerManager.listeners.removeListener;
-
-// Export the Selection singleton. Its rangeNumber is always zero.
-Selection.call(exports, 0);
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/simple-prefs.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/simple-prefs.js
deleted file mode 100644
index c7a059b..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/simple-prefs.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Hernan Rodriguez Colmeiro <colmeiro@gmail.com> (Original Author)
- * Erik Vold <erikvvold@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const { Cc, Ci } = require("chrome");
-const observers = require("observer-service");
-const { EventEmitter } = require("events");
-const unload = require("unload");
-const prefService = require("preferences-service");
-const { jetpackID } = require("@packaging");
-
-const ADDON_BRANCH = "extensions." + jetpackID + ".";
-const BUTTON_PRESSED = jetpackID + "-cmdPressed";
-
-// XXX Currently, only Firefox implements the inline preferences.
-if (!require("xul-app").is("Firefox"))
- throw Error("This API is only supported in Firefox");
-
-let branch = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService).
- getBranch(ADDON_BRANCH).
- QueryInterface(Ci.nsIPrefBranch2);
-
-const events = EventEmitter.compose({
- constructor: function Prefs() {
- // Log unhandled errors.
- this.on("error", console.exception.bind(console));
-
- // Make sure we remove all the listeners
- unload.ensure(this);
-
- this._prefObserver = this._prefObserver.bind(this);
- this._buttonObserver = this._buttonObserver.bind(this);
-
- // Listen to changes in the preferences
- branch.addObserver("", this._prefObserver, false);
-
- // Listen to clicks on buttons
- observers.add(BUTTON_PRESSED, this._buttonObserver, this);
- },
- _prefObserver: function PrefsPrefObserver(subject, topic, prefName) {
- if (topic == "nsPref:changed") {
- this._emit(prefName, prefName);
- }
- },
- _buttonObserver: function PrefsButtonObserver(subject, data) {
- this._emit(data);
- },
- unload: function manager_unload() {
- this._removeAllListeners("error");
- branch.removeObserver("", this._prefObserver);
- },
-})();
-
-const simple = Proxy.create({
- get: function(receiver, pref) {
- return prefService.get(ADDON_BRANCH + pref);
- },
- set: function(receiver, pref, val) {
- prefService.set(ADDON_BRANCH + pref, val);
- },
- delete: function(pref) {
- prefService.reset(ADDON_BRANCH + pref);
- return true;
- },
- has: function(pref) {
- return prefService.has(ADDON_BRANCH + pref);
- }
-});
-
-exports.on = events.on;
-exports.removeListener = events.removeListener;
-exports.prefs = simple;
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/simple-storage.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/simple-storage.js
deleted file mode 100644
index b719e27..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/simple-storage.js
+++ /dev/null
@@ -1,263 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Drew Willcoxon <adw@mozilla.com> (Original Author)
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const {Cc,Ci} = require("chrome");
-const file = require("api-utils/file");
-const prefs = require("api-utils/preferences-service");
-const jpSelf = require("self");
-const timer = require("api-utils/timer");
-const unload = require("api-utils/unload");
-const { EventEmitter } = require("api-utils/events");
-const { Trait } = require("api-utils/traits");
-
-const WRITE_PERIOD_PREF = "extensions.addon-sdk.simple-storage.writePeriod";
-const WRITE_PERIOD_DEFAULT = 300000; // 5 minutes
-
-const QUOTA_PREF = "extensions.addon-sdk.simple-storage.quota";
-const QUOTA_DEFAULT = 5242880; // 5 MiB
-
-const JETPACK_DIR_BASENAME = "jetpack";
-
-
-// simpleStorage.storage
-exports.__defineGetter__("storage", function () manager.root);
-exports.__defineSetter__("storage", function (val) manager.root = val);
-
-// simpleStorage.quotaUsage
-exports.__defineGetter__("quotaUsage", function () manager.quotaUsage);
-
-// A generic JSON store backed by a file on disk. This should be isolated
-// enough to move to its own module if need be...
-function JsonStore(options) {
- this.filename = options.filename;
- this.quota = options.quota;
- this.writePeriod = options.writePeriod;
- this.onOverQuota = options.onOverQuota;
- this.onWrite = options.onWrite;
-
- unload.ensure(this);
-
- this.writeTimer = timer.setInterval(this.write.bind(this),
- this.writePeriod);
-}
-
-JsonStore.prototype = {
- // The store's root.
- get root() {
- return this.isRootInited ? this._root : {};
- },
-
- // Performs some type checking.
- set root(val) {
- let types = ["array", "boolean", "null", "number", "object", "string"];
- if (types.indexOf(typeof(val)) < 0) {
- throw new Error("storage must be one of the following types: " +
- types.join(", "));
- }
- this._root = val;
- return val;
- },
-
- // True if the root has ever been set (either via the root setter or by the
- // backing file's having been read).
- get isRootInited() {
- return this._root !== undefined;
- },
-
- // Percentage of quota used, as a number [0, Inf). > 1 implies over quota.
- // Undefined if there is no quota.
- get quotaUsage() {
- return this.quota > 0 ?
- JSON.stringify(this.root).length / this.quota :
- undefined;
- },
-
- // Removes the backing file and all empty subdirectories.
- purge: function JsonStore_purge() {
- try {
- // This'll throw if the file doesn't exist.
- file.remove(this.filename);
- let parentPath = this.filename;
- do {
- parentPath = file.dirname(parentPath);
- // This'll throw if the dir isn't empty.
- file.rmdir(parentPath);
- } while (file.basename(parentPath) !== JETPACK_DIR_BASENAME);
- }
- catch (err) {}
- },
-
- // Initializes the root by reading the backing file.
- read: function JsonStore_read() {
- try {
- let str = file.read(this.filename);
-
- // Ideally we'd log the parse error with console.error(), but logged
- // errors cause tests to fail. Supporting "known" errors in the test
- // harness appears to be non-trivial. Maybe later.
- this.root = JSON.parse(str);
- }
- catch (err) {
- this.root = {};
- }
- },
-
- // If the store is under quota, writes the root to the backing file.
- // Otherwise quota observers are notified and nothing is written.
- write: function JsonStore_write() {
- if (this.quotaUsage > 1)
- this.onOverQuota(this);
- else
- this._write();
- },
-
- // Cleans up on unload. If unloading because of uninstall, the store is
- // purged; otherwise it's written.
- unload: function JsonStore_unload(reason) {
- timer.clearInterval(this.writeTimer);
- this.writeTimer = null;
-
- if (reason === "uninstall")
- this.purge();
- else
- this._write();
- },
-
- // True if the root is an empty object.
- get _isEmpty() {
- if (this.root && typeof(this.root) === "object") {
- let empty = true;
- for (let key in this.root) {
- empty = false;
- break;
- }
- return empty;
- }
- return false;
- },
-
- // Writes the root to the backing file, notifying write observers when
- // complete. If the store is over quota or if it's empty and the store has
- // never been written, nothing is written and write observers aren't notified.
- _write: function JsonStore__write() {
- // Don't write if the root is uninitialized or if the store is empty and the
- // backing file doesn't yet exist.
- if (!this.isRootInited || (this._isEmpty && !file.exists(this.filename)))
- return;
-
- // If the store is over quota, don't write. The current under-quota state
- // should persist.
- if (this.quotaUsage > 1)
- return;
-
- // Finally, write.
- let stream = file.open(this.filename, "w");
- try {
- stream.writeAsync(JSON.stringify(this.root), function writeAsync(err) {
- if (err)
- console.error("Error writing simple storage file: " + this.filename);
- else if (this.onWrite)
- this.onWrite(this);
- }.bind(this));
- }
- catch (err) {
- // writeAsync closes the stream after it's done, so only close on error.
- stream.close();
- }
- }
-};
-
-
-// This manages a JsonStore singleton and tailors its use to simple storage.
-// The root of the JsonStore is lazy-loaded: The backing file is only read the
-// first time the root's gotten.
-let manager = Trait.compose(EventEmitter, Trait.compose({
- jsonStore: null,
-
- // The filename of the store, based on the profile dir and extension ID.
- get filename() {
- let storeFile = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIProperties).
- get("ProfD", Ci.nsIFile);
- storeFile.append(JETPACK_DIR_BASENAME);
- storeFile.append(jpSelf.id);
- storeFile.append("simple-storage");
- file.mkpath(storeFile.path);
- storeFile.append("store.json");
- return storeFile.path;
- },
-
- get quotaUsage() {
- return this.jsonStore.quotaUsage;
- },
-
- get root() {
- if (!this.jsonStore.isRootInited)
- this.jsonStore.read();
- return this.jsonStore.root;
- },
-
- set root(val) {
- return this.jsonStore.root = val;
- },
-
- unload: function manager_unload() {
- this._removeAllListeners("OverQuota");
- this._removeAllListeners("error");
- },
-
- constructor: function manager_constructor() {
- // Log unhandled errors.
- this.on("error", console.exception.bind(console));
- unload.ensure(this);
-
- this.jsonStore = new JsonStore({
- filename: this.filename,
- writePeriod: prefs.get(WRITE_PERIOD_PREF, WRITE_PERIOD_DEFAULT),
- quota: prefs.get(QUOTA_PREF, QUOTA_DEFAULT),
- onOverQuota: this._emitOnObject.bind(this, exports, "OverQuota")
- });
- }
-}))();
-
-exports.on = manager.on;
-exports.removeListener = manager.removeListener;
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/tabs.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/tabs.js
deleted file mode 100644
index 81681d6..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/tabs.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dietrich Ayala <dietrich@mozilla.com> (Original author)
- * Felipe Gomes <felipc@gmail.com>
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-"use strict";
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The tabs module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-const { browserWindows } = require("./windows");
-const { tabs } = require("api-utils/windows/tabs");
-
-Object.defineProperties(tabs, {
- open: { value: function open(options) {
- if (options.inNewWindow)
- // `tabs` option is under review and may be removed.
- return browserWindows.open({ tabs: [ options ] });
- // Open in active window if new window was not required.
- return browserWindows.activeWindow.tabs.open(options);
- }}
-});
-// It's a hack but we will be able to remove it once will implement CommonJS
-// feature that would allow us to override exports.
-exports.__proto__ = tabs;
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/timers.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/timers.js
deleted file mode 100644
index 9373dea..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/timers.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-// This module just proxies to the low level equivalent "timer" in "api-utils".
-module.exports = require("api-utils/timer");
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/widget.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/widget.js
deleted file mode 100644
index 9a169f4..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/widget.js
+++ /dev/null
@@ -1,947 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dietrich Ayala <dietrich@mozilla.com> (Original Author)
- * Drew Willcoxon <adw@mozilla.com>
- * Irakli Gozalishvili <gozala@mozilla.com>
- * Alexandre Poirot <apoirot@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-"use strict";
-
-const {Cc, Ci} = require("chrome");
-
-// Widget content types
-const CONTENT_TYPE_URI = 1;
-const CONTENT_TYPE_HTML = 2;
-const CONTENT_TYPE_IMAGE = 3;
-
-const ERR_CONTENT = "No content or contentURL property found. Widgets must "
- + "have one or the other.",
- ERR_LABEL = "The widget must have a non-empty label property.",
- ERR_ID = "You have to specify a unique value for the id property of " +
- "your widget in order for the application to remember its " +
- "position.",
- ERR_DESTROYED = "The widget has been destroyed and can no longer be used.";
-
-// Supported events, mapping from DOM event names to our event names
-const EVENTS = {
- "click": "click",
- "mouseover": "mouseover",
- "mouseout": "mouseout",
-};
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The widget module currently supports only Firefox. In the future ",
- "it will support other applications. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=560716 for more information."
- ].join(""));
-}
-
-const { validateOptions } = require("api-utils/api-utils");
-const panels = require("./panel");
-const { EventEmitter, EventEmitterTrait } = require("api-utils/events");
-const { Trait } = require("api-utils/traits");
-const LightTrait = require('api-utils/light-traits').Trait;
-const { Loader, Symbiont } = require("api-utils/content");
-const timer = require("api-utils/timer");
-const { Cortex } = require('api-utils/cortex');
-const windowsAPI = require("./windows");
-const unload = require("api-utils/unload");
-
-// Data types definition
-const valid = {
- number: { is: ["null", "undefined", "number"] },
- string: { is: ["null", "undefined", "string"] },
- id: {
- is: ["string"],
- ok: function (v) v.length > 0,
- msg: ERR_ID,
- readonly: true
- },
- label: {
- is: ["string"],
- ok: function (v) v.length > 0,
- msg: ERR_LABEL
- },
- panel: {
- is: ["null", "undefined", "object"],
- ok: function(v) !v || v instanceof panels.Panel
- },
- width: {
- is: ["null", "undefined", "number"],
- map: function (v) {
- if (null === v || undefined === v) v = 16;
- return v;
- },
- defaultValue: 16
- },
- allow: {
- is: ["null", "undefined", "object"],
- map: function (v) {
- if (!v) v = { script: true };
- return v;
- },
- get defaultValue() ({ script: true })
- },
-};
-
-// Widgets attributes definition
-let widgetAttributes = {
- label: valid.label,
- id: valid.id,
- tooltip: valid.string,
- width: valid.width,
- content: valid.string,
- panel: valid.panel,
- allow: valid.allow
-};
-
-// Import data definitions from loader, but don't compose with it as Model
-// functions allow us to recreate easily all Loader code.
-let loaderAttributes = require("api-utils/content/loader").validationAttributes;
-for (let i in loaderAttributes)
- widgetAttributes[i] = loaderAttributes[i];
-
-widgetAttributes.contentURL.optional = true;
-
-// Widgets public events list, that are automatically binded in options object
-const WIDGET_EVENTS = [
- "click",
- "mouseover",
- "mouseout",
- "error",
- "message",
- "attach"
-];
-
-// `Model` utility functions that help creating these various Widgets objects
-let model = {
-
- // Validate one attribute using api-utils.js:validateOptions function
- _validate: function _validate(name, suspect, validation) {
- let $1 = {};
- $1[name] = suspect;
- let $2 = {};
- $2[name] = validation;
- return validateOptions($1, $2)[name];
- },
-
- /**
- * This method has two purposes:
- * 1/ Validate and define, on a given object, a set of attribute
- * 2/ Emit a "change" event on this object when an attribute is changed
- *
- * @params {Object} object
- * Object on which we can bind attributes on and watch for their changes.
- * This object must have an EventEmitter interface, or, at least `_emit`
- * method
- * @params {Object} attrs
- * Dictionary of attributes definition following api-utils:validateOptions
- * scheme
- * @params {Object} values
- * Dictionary of attributes default values
- */
- setAttributes: function setAttributes(object, attrs, values) {
- let properties = {};
- for (let name in attrs) {
- let value = values[name];
- let req = attrs[name];
-
- // Retrieve default value from typedef if the value is not defined
- if ((typeof value == "undefined" || value == null) && req.defaultValue)
- value = req.defaultValue;
-
- // Check for valid value if value is defined or mandatory
- if (!req.optional || typeof value != "undefined")
- value = model._validate(name, value, req);
-
- // In any case, define this property on `object`
- let property = null;
- if (req.readonly) {
- property = {
- value: value,
- writable: false,
- enumerable: true,
- configurable: false
- };
- }
- else {
- property = model._createWritableProperty(name, value);
- }
-
- properties[name] = property;
- }
- Object.defineProperties(object, properties);
- },
-
- // Generate ES5 property definition for a given attribute
- _createWritableProperty: function _createWritableProperty(name, value) {
- return {
- get: function () {
- return value;
- },
- set: function (newValue) {
- value = newValue;
- // The main goal of all this Model stuff is here:
- // We want to forward all changes to some listeners
- this._emit("change", name, value);
- },
- enumerable: true,
- configurable: false
- };
- },
-
- /**
- * Automagically register listeners in options dictionary
- * by detecting listener attributes with name starting with `on`
- *
- * @params {Object} object
- * Target object that need to follow EventEmitter interface, or, at least,
- * having `on` method.
- * @params {Array} events
- * List of events name to automatically bind.
- * @params {Object} listeners
- * Dictionary of event listener functions to register.
- */
- setEvents: function setEvents(object, events, listeners) {
- for (let i = 0, l = events.length; i < l; i++) {
- let name = events[i];
- let onName = "on" + name[0].toUpperCase() + name.substr(1);
- if (!listeners[onName])
- continue;
- object.on(name, listeners[onName].bind(object));
- }
- }
-
-};
-
-
-/**
- * Main Widget class: entry point of the widget API
- *
- * Allow to control all widget across all existing windows with a single object.
- * Widget.getView allow to retrieve a WidgetView instance to control a widget
- * specific to one window.
- */
-const WidgetTrait = LightTrait.compose(EventEmitterTrait, LightTrait({
-
- _initWidget: function _initWidget(options) {
- model.setAttributes(this, widgetAttributes, options);
-
- browserManager.validate(this);
-
- // We must have at least content or contentURL defined
- if (!(this.content || this.contentURL))
- throw new Error(ERR_CONTENT);
-
- this._views = [];
-
- // Set tooltip to label value if we don't have tooltip defined
- if (!this.tooltip)
- this.tooltip = this.label;
-
- model.setEvents(this, WIDGET_EVENTS, options);
-
- this.on('change', this._onChange.bind(this));
-
- let self = this;
- this._port = EventEmitterTrait.create({
- emit: function () {
- let args = arguments;
- self._views.forEach(function(v) v.port.emit.apply(v.port, args));
- }
- });
- // expose wrapped port, that exposes only public properties.
- this._port._public = Cortex(this._port);
-
- // Register this widget to browser manager in order to create new widget on
- // all new windows
- browserManager.addItem(this);
- },
-
- _onChange: function _onChange(name, value) {
- // Set tooltip to label value if we don't have tooltip defined
- if (name == 'tooltip' && !value) {
- // we need to change tooltip again in order to change the value of the
- // attribute itself
- this.tooltip = this.label;
- return;
- }
-
- // Forward attributes changes to WidgetViews
- if (['width', 'tooltip', 'content', 'contentURL'].indexOf(name) != -1) {
- this._views.forEach(function(v) v[name] = value);
- }
- },
-
- _onEvent: function _onEvent(type, eventData) {
- this._emit(type, eventData);
- },
-
- _createView: function _createView() {
- // Create a new WidgetView instance
- let view = WidgetView(this);
-
- // Keep a reference to it
- this._views.push(view);
-
- // Emit an `attach` event with a WidgetView instance without private attrs
- this._emit("attach", view._public);
-
- return view;
- },
-
- // a WidgetView instance is destroyed
- _onViewDestroyed: function _onViewDestroyed(view) {
- let idx = this._views.indexOf(view);
- this._views.splice(idx, 1);
- },
-
- /**
- * Called on browser window closed, to destroy related WidgetViews
- * @params {ChromeWindow} window
- * Window that has been closed
- */
- _onWindowClosed: function _onWindowClosed(window) {
- for each (let view in this._views) {
- if (view._isInChromeWindow(window)) {
- view.destroy();
- break;
- }
- }
- },
-
- /**
- * Get the WidgetView instance related to a BrowserWindow instance
- * @params {BrowserWindow} window
- * BrowserWindow reference from "windows" module
- */
- getView: function getView(window) {
- for each (let view in this._views) {
- if (view._isInWindow(window)) {
- return view._public;
- }
- }
- return null;
- },
-
- get port() this._port._public,
- set port(v) {}, // Work around Cortex failure with getter without setter
- // See bug 653464
- _port: null,
-
- postMessage: function postMessage(message) {
- this._views.forEach(function(v) v.postMessage(message));
- },
-
- destroy: function destroy() {
- if (this.panel)
- this.panel.destroy();
-
- // Dispatch destroy calls to views
- // we need to go backward as we remove items from this array in
- // _onViewDestroyed
- for (let i = this._views.length - 1; i >= 0; i--)
- this._views[i].destroy();
-
- // Unregister widget to stop creating it over new windows
- // and allow creation of new widget with same id
- browserManager.removeItem(this);
- }
-
-}));
-
-// Widget constructor
-const Widget = function Widget(options) {
- let w = WidgetTrait.create(Widget.prototype);
- w._initWidget(options);
-
- // Return a Cortex of widget in order to hide private attributes like _onEvent
- let _public = Cortex(w);
- unload.ensure(_public, "destroy");
- return _public;
-}
-exports.Widget = Widget;
-
-
-
-/**
- * WidgetView is an instance of a widget for a specific window.
- *
- * This is an external API that can be retrieved by calling Widget.getView or
- * by watching `attach` event on Widget.
- */
-const WidgetViewTrait = LightTrait.compose(EventEmitterTrait, LightTrait({
-
- // Reference to the matching WidgetChrome
- // set right after constructor call
- _chrome: null,
-
- // Public interface of the WidgetView, passed in `attach` event or in
- // Widget.getView
- _public: null,
-
- _initWidgetView: function WidgetView__initWidgetView(baseWidget) {
- this._baseWidget = baseWidget;
-
- model.setAttributes(this, widgetAttributes, baseWidget);
-
- this.on('change', this._onChange.bind(this));
-
- let self = this;
- this._port = EventEmitterTrait.create({
- emit: function () {
- if (!self._chrome)
- throw new Error(ERR_DESTROYED);
- self._chrome.update(self._baseWidget, "emit", arguments);
- }
- });
- // expose wrapped port, that exposes only public properties.
- this._port._public = Cortex(this._port);
-
- this._public = Cortex(this);
- },
-
- _onChange: function WidgetView__onChange(name, value) {
- if (name == 'tooltip' && !value) {
- this.tooltip = this.label;
- return;
- }
-
- // Forward attributes changes to WidgetChrome instance
- if (['width', 'tooltip', 'content', 'contentURL'].indexOf(name) != -1) {
- this._chrome.update(this._baseWidget, name, value);
- }
- },
-
- _onEvent: function WidgetView__onEvent(type, eventData, domNode) {
- // Dispatch event in view
- this._emit(type, eventData);
-
- // And forward it to the main Widget object
- if ("click" == type || type.indexOf("mouse") == 0)
- this._baseWidget._onEvent(type, this._public);
- else
- this._baseWidget._onEvent(type, eventData);
-
- // Special case for click events: if the widget doesn't have a click
- // handler, but it does have a panel, display the panel.
- if ("click" == type && !this._listeners("click").length && this.panel)
- this.panel.show(domNode);
- },
-
- _isInWindow: function WidgetView__isInWindow(window) {
- return windowsAPI.BrowserWindow({
- window: this._chrome.window
- }) == window;
- },
-
- _isInChromeWindow: function WidgetView__isInChromeWindow(window) {
- return this._chrome.window == window;
- },
-
- _onPortEvent: function WidgetView__onPortEvent(args) {
- let port = this._port;
- port._emit.apply(port, args);
- let basePort = this._baseWidget._port;
- basePort._emit.apply(basePort, args);
- },
-
- get port() this._port._public,
- set port(v) {}, // Work around Cortex failure with getter without setter
- // See bug 653464
- _port: null,
-
- postMessage: function WidgetView_postMessage(message) {
- if (!this._chrome)
- throw new Error(ERR_DESTROYED);
- this._chrome.update(this._baseWidget, "postMessage", message);
- },
-
- destroy: function WidgetView_destroy() {
- this._chrome.destroy();
- delete this._chrome;
- this._baseWidget._onViewDestroyed(this);
- this._emit("detach");
- }
-
-}));
-
-const WidgetView = function WidgetView(baseWidget) {
- let w = WidgetViewTrait.create(WidgetView.prototype);
- w._initWidgetView(baseWidget);
- return w;
-}
-
-
-
-/**
- * Keeps track of all browser windows.
- * Exposes methods for adding/removing widgets
- * across all open windows (and future ones).
- * Create a new instance of BrowserWindow per window.
- */
-let browserManager = {
- items: [],
- windows: [],
-
- // Registers the manager to listen for window openings and closings. Note
- // that calling this method can cause onTrack to be called immediately if
- // there are open windows.
- init: function () {
- let windowTracker = new (require("api-utils/window-utils").WindowTracker)(this);
- unload.ensure(windowTracker);
- },
-
- // Registers a window with the manager. This is a WindowTracker callback.
- onTrack: function browserManager_onTrack(window) {
- if (this._isBrowserWindow(window)) {
- let win = new BrowserWindow(window);
- win.addItems(this.items);
- this.windows.push(win);
- }
- },
-
- // Unregisters a window from the manager. It's told to undo all
- // modifications. This is a WindowTracker callback. Note that when
- // WindowTracker is unloaded, it calls onUntrack for every currently opened
- // window. The browserManager therefore doesn't need to specially handle
- // unload itself, since unloading the browserManager means untracking all
- // currently opened windows.
- onUntrack: function browserManager_onUntrack(window) {
- if (this._isBrowserWindow(window)) {
- this.items.forEach(function(i) i._onWindowClosed(window));
- for (let i = 0; i < this.windows.length; i++) {
- if (this.windows[i].window == window) {
- this.windows.splice(i, 1)[0];
- return;
- }
- }
-
- }
- },
-
- // Used to validate widget by browserManager before adding it,
- // in order to check input very early in widget constructor
- validate : function (item) {
- let idx = this.items.indexOf(item);
- if (idx > -1)
- throw new Error("The widget " + item + " has already been added.");
- if (item.id) {
- let sameId = this.items.filter(function(i) i.id == item.id);
- if (sameId.length > 0)
- throw new Error("This widget ID is already used: " + item.id);
- } else {
- item.id = this.items.length;
- }
- },
-
- // Registers an item with the manager. It's added to all currently registered
- // windows, and when new windows are registered it will be added to them, too.
- addItem: function browserManager_addItem(item) {
- this.items.push(item);
- this.windows.forEach(function (w) w.addItems([item]));
- },
-
- // Unregisters an item from the manager. It's removed from all windows that
- // are currently registered.
- removeItem: function browserManager_removeItem(item) {
- let idx = this.items.indexOf(item);
- if (idx > -1)
- this.items.splice(idx, 1);
- },
-
- _isBrowserWindow: function browserManager__isBrowserWindow(win) {
- let winType = win.document.documentElement.getAttribute("windowtype");
- return winType === "navigator:browser";
- }
-};
-
-
-
-/**
- * Keeps track of a single browser window.
- *
- * This is where the core of how a widget's content is added to a window lives.
- */
-function BrowserWindow(window) {
- this.window = window;
- this.doc = window.document;
-}
-
-BrowserWindow.prototype = {
-
- // Adds an array of items to the window.
- addItems: function BW_addItems(items) {
- items.forEach(this._addItemToWindow, this);
- },
-
- _addItemToWindow: function BW__addItemToWindow(baseWidget) {
- // Create a WidgetView instance
- let widget = baseWidget._createView();
-
- // Create a WidgetChrome instance
- let item = new WidgetChrome({
- widget: widget,
- doc: this.doc,
- window: this.window
- });
-
- widget._chrome = item;
-
- this._insertNodeInToolbar(item.node);
-
- // We need to insert Widget DOM Node before finishing widget view creation
- // (because fill creates an iframe and tries to access its docShell)
- item.fill();
- },
-
- _insertNodeInToolbar: function BW__insertNodeInToolbar(node) {
- // Add to the customization palette
- let toolbox = this.doc.getElementById("navigator-toolbox");
- let palette = toolbox.palette;
- palette.appendChild(node);
-
- // Search for widget toolbar by reading toolbar's currentset attribute
- let container = null;
- let toolbars = this.doc.getElementsByTagName("toolbar");
- let id = node.getAttribute("id");
- for (let i = 0, l = toolbars.length; i < l; i++) {
- let toolbar = toolbars[i];
- if (toolbar.getAttribute("currentset").indexOf(id) == -1)
- continue;
- container = toolbar;
- }
-
- // if widget isn't in any toolbar, add it to the addon-bar
- // TODO: we may want some "first-launch" module to do this only on very
- // first execution
- if (!container) {
- container = this.doc.getElementById("addon-bar");
- // TODO: find a way to make the following code work when we use "cfx run":
- // http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#8586
- // until then, force display of addon bar directly from sdk code
- // https://bugzilla.mozilla.org/show_bug.cgi?id=627484
- if (container.collapsed)
- this.window.toggleAddonBar();
- }
-
- // Now retrieve a reference to the next toolbar item
- // by reading currentset attribute on the toolbar
- let nextNode = null;
- let currentSet = container.getAttribute("currentset");
- let ids = (currentSet == "__empty") ? [] : currentSet.split(",");
- let idx = ids.indexOf(id);
- if (idx != -1) {
- for (let i = idx; i < ids.length; i++) {
- nextNode = this.doc.getElementById(ids[i]);
- if (nextNode)
- break;
- }
- }
-
- // Finally insert our widget in the right toolbar and in the right position
- container.insertItem(id, nextNode, null, false);
-
- // Update DOM in order to save position if we remove/readd the widget
- container.setAttribute("currentset", container.currentSet);
- // Save DOM attribute in order to save position on new window opened
- this.window.document.persist(container.id, "currentset");
- }
-}
-
-
-/**
- * Final Widget class that handles chrome DOM Node:
- * - create initial DOM nodes
- * - receive instruction from WidgetView through update method and update DOM
- * - watch for DOM events and forward them to WidgetView
- */
-function WidgetChrome(options) {
- this.window = options.window;
- this._doc = options.doc;
- this._widget = options.widget;
- this._symbiont = null; // set later
- this.node = null; // set later
-
- this._createNode();
-}
-
-// Update a property of a widget.
-WidgetChrome.prototype.update = function WC_update(updatedItem, property, value) {
- switch(property) {
- case "contentURL":
- case "content":
- this.setContent();
- break;
- case "width":
- this.node.style.minWidth = value + "px";
- this.node.querySelector("iframe").style.width = value + "px";
- break;
- case "tooltip":
- this.node.setAttribute("tooltiptext", value);
- break;
- case "postMessage":
- this._symbiont.postMessage(value);
- break;
- case "emit":
- let port = this._symbiont.port;
- port.emit.apply(port, value);
- break;
- }
-}
-
-// Add a widget to this window.
-WidgetChrome.prototype._createNode = function WC__createNode() {
- // XUL element container for widget
- let node = this._doc.createElement("toolbaritem");
- let guid = require("api-utils/xpcom").makeUuid().toString();
-
- // Temporary work around require("self") failing on unit-test execution ...
- let jetpackID = "testID";
- try {
- jetpackID = require("self").id;
- } catch(e) {}
-
- // Compute an unique and stable widget id with jetpack id and widget.id
- let id = "widget:" + jetpackID + "-" + this._widget.id;
- node.setAttribute("id", id);
- node.setAttribute("label", this._widget.label);
- node.setAttribute("tooltiptext", this._widget.tooltip);
- node.setAttribute("align", "center");
-
- // TODO move into a stylesheet, configurable by consumers.
- // Either widget.style, exposing the style object, or a URL
- // (eg, can load local stylesheet file).
- node.setAttribute("style", [
- "overflow: hidden; margin: 1px 2px 1px 2px; padding: 0px;",
- "min-height: 16px;",
- ].join(""));
-
- node.style.minWidth = this._widget.width + "px";
-
- this.node = node;
-}
-
-// Initial population of a widget's content.
-WidgetChrome.prototype.fill = function WC_fill() {
- // Create element
- var iframe = this._doc.createElement("iframe");
- iframe.setAttribute("type", "content");
- iframe.setAttribute("transparent", "transparent");
- iframe.style.overflow = "hidden";
- iframe.style.height = "16px";
- iframe.style.maxHeight = "16px";
- iframe.style.width = this._widget.width + "px";
- iframe.setAttribute("flex", "1");
- iframe.style.border = "none";
- iframe.style.padding = "0px";
-
- // Do this early, because things like contentWindow are null
- // until the node is attached to a document.
- this.node.appendChild(iframe);
-
- // add event handlers
- this.addEventHandlers();
-
- // set content
- this.setContent();
-}
-
-// Get widget content type.
-WidgetChrome.prototype.getContentType = function WC_getContentType() {
- if (this._widget.content)
- return CONTENT_TYPE_HTML;
- return (this._widget.contentURL && /\.(jpg|gif|png|ico)$/.test(this._widget.contentURL))
- ? CONTENT_TYPE_IMAGE : CONTENT_TYPE_URI;
-}
-
-// Set widget content.
-WidgetChrome.prototype.setContent = function WC_setContent() {
- let type = this.getContentType();
- let contentURL = null;
-
- switch (type) {
- case CONTENT_TYPE_HTML:
- contentURL = "data:text/html," + encodeURIComponent(this._widget.content);
- break;
- case CONTENT_TYPE_URI:
- contentURL = this._widget.contentURL;
- break;
- case CONTENT_TYPE_IMAGE:
- let imageURL = this._widget.contentURL;
- contentURL = "data:text/html,<html><body><img src='" +
- encodeURI(imageURL) + "'></body></html>";
- break;
- default:
- throw new Error("The widget's type cannot be determined.");
- }
-
- let iframe = this.node.firstElementChild;
-
- let self = this;
- // Cleanup previously created symbiont (in case we are update content)
- if (this._symbiont)
- this._symbiont.destroy();
-
- this._symbiont = Trait.compose(Symbiont.resolve({
- _onContentScriptEvent: "_onContentScriptEvent-not-used"
- }), {
- _onContentScriptEvent: function () {
- // Redirect events to WidgetView
- self._widget._onPortEvent(arguments);
- }
- })({
- frame: iframe,
- contentURL: contentURL,
- contentScriptFile: this._widget.contentScriptFile,
- contentScript: this._widget.contentScript,
- contentScriptWhen: this._widget.contentScriptWhen,
- allow: this._widget.allow,
- onMessage: function(message) {
- timer.setTimeout(function() {
- self._widget._onEvent("message", message);
- }, 0);
- }
- });
-}
-
-// Detect if document consists of a single image.
-WidgetChrome._isImageDoc = function WC__isImageDoc(doc) {
- return doc.body.childNodes.length == 1 &&
- doc.body.firstElementChild &&
- doc.body.firstElementChild.tagName == "IMG";
-}
-
-// Set up all supported events for a widget.
-WidgetChrome.prototype.addEventHandlers = function WC_addEventHandlers() {
- let contentType = this.getContentType();
-
- let self = this;
- let listener = function(e) {
- // Ignore event firings that target the iframe.
- if (e.target == self.node.firstElementChild)
- return;
-
- // The widget only supports left-click for now,
- // so ignore right-clicks.
- if (e.type == "click" && e.button == 2)
- return;
-
- // Proxy event to the widget
- timer.setTimeout(function() {
- self._widget._onEvent(EVENTS[e.type], null, self.node);
- }, 0);
- };
-
- this.eventListeners = {};
- let iframe = this.node.firstElementChild;
- for (let [type, method] in Iterator(EVENTS)) {
- iframe.addEventListener(type, listener, true, true);
-
- // Store listeners for later removal
- this.eventListeners[type] = listener;
- }
-
- // On document load, make modifications required for nice default
- // presentation.
- let self = this;
- function loadListener(e) {
- // Ignore event firings that target the iframe
- if (e.target == iframe)
- return;
- // Ignore about:blank loads
- if (e.type == "load" && e.target.location == "about:blank")
- return;
-
- // We may have had an unload event before that cleaned up the symbiont
- if (!self._symbiont)
- self.setContent();
-
- let doc = e.target;
- if (contentType == CONTENT_TYPE_IMAGE || WidgetChrome._isImageDoc(doc)) {
- // Force image content to size.
- // Add-on authors must size their images correctly.
- doc.body.firstElementChild.style.width = self._widget.width + "px";
- doc.body.firstElementChild.style.height = "16px";
- }
-
- // Allow all content to fill the box by default.
- doc.body.style.margin = "0";
- }
- iframe.addEventListener("load", loadListener, true);
- this.eventListeners["load"] = loadListener;
-
- // Register a listener to unload symbiont if the toolbaritem is moved
- // on user toolbars customization
- function unloadListener(e) {
- if (e.target.location == "about:blank")
- return;
- self._symbiont.destroy();
- self._symbiont = null;
- // This may fail but not always, it depends on how the node is
- // moved or removed
- try {
- self.setContent();
- } catch(e) {}
-
- }
-
- iframe.addEventListener("unload", unloadListener, true);
- this.eventListeners["unload"] = unloadListener;
-}
-
-// Remove and unregister the widget from everything
-WidgetChrome.prototype.destroy = function WC_destroy(removedItems) {
- // remove event listeners
- for (let [type, listener] in Iterator(this.eventListeners))
- this.node.firstElementChild.removeEventListener(type, listener, true);
- // remove dom node
- this.node.parentNode.removeChild(this.node);
- // cleanup symbiont
- this._symbiont.destroy();
- // cleanup itself
- this.eventListeners = null;
- this._widget = null;
- this._symbiont = null;
-}
-
-// Init the browserManager only after setting prototypes and such above, because
-// it will cause browserManager.onTrack to be called immediately if there are
-// open windows.
-browserManager.init();
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/lib/windows.js b/tools/addon-sdk-1.4/packages/addon-kit/lib/windows.js
deleted file mode 100644
index e9e097b..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/lib/windows.js
+++ /dev/null
@@ -1,238 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Felipe Gomes <felipc@gmail.com> (Original author)
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-"use strict";
-
-if (!require("api-utils/xul-app").is("Firefox")) {
- throw new Error([
- "The windows module currently supports only Firefox. In the future",
- " we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=571449 for more information."
- ].join(""));
-}
-
-const { Cc, Ci } = require('chrome'),
- { Trait } = require('api-utils/traits'),
- { List } = require('api-utils/list'),
- { EventEmitter } = require('api-utils/events'),
- { WindowTabs, WindowTabTracker } = require('api-utils/windows/tabs'),
- { WindowDom } = require('api-utils/windows/dom'),
- { WindowLoader } = require('api-utils/windows/loader'),
- { WindowTrackerTrait } = require('api-utils/window-utils'),
- { Options } = require('api-utils/tabs/tab'),
- { utils } = require('api-utils/xpcom'),
- apiUtils = require('api-utils/api-utils'),
- unload = require('api-utils/unload'),
-
- WM = Cc['@mozilla.org/appshell/window-mediator;1'].
- getService(Ci.nsIWindowMediator),
-
- BROWSER = 'navigator:browser';
-
-/**
- * Window trait composes safe wrappers for browser window that are E10S
- * compatible.
- */
-const BrowserWindowTrait = Trait.compose(
- EventEmitter,
- WindowDom.resolve({ close: '_close' }),
- WindowTabs,
- WindowTabTracker,
- WindowLoader,
- /* WindowSidebars, */
- Trait.compose({
- _emit: Trait.required,
- _close: Trait.required,
- _load: Trait.required,
- /**
- * Constructor returns wrapper of the specified chrome window.
- * @param {nsIWindow} window
- */
- constructor: function BrowserWindow(options) {
- // Register this window ASAP, in order to avoid loop that would try
- // to create this window instance over and over (see bug 648244)
- windows.push(this);
-
- // make sure we don't have unhandled errors
- this.on('error', console.exception.bind(console));
-
- if ('onOpen' in options)
- this.on('open', options.onOpen);
- if ('onClose' in options)
- this.on('close', options.onClose);
- if ('window' in options)
- this._window = options.window;
- if ('tabs' in options) {
- this._tabOptions = Array.isArray(options.tabs) ?
- options.tabs.map(Options) :
- [ Options(options.tabs) ];
- }
- else if ('url' in options) {
- this._tabOptions = [ Options(options.url) ];
- }
- this._load();
- return this;
- },
- _tabOptions: [],
- _onLoad: function() {
- try {
- this._initWindowTabTracker();
- } catch(e) {
- this._emit('error', e)
- }
- this._emitOnObject(browserWindows, 'open', this._public);
- },
- _onUnload: function() {
- this._destroyWindowTabTracker();
- this._emitOnObject(browserWindows, 'close', this._public);
- this._window = null;
- // Removing reference from the windows array.
- windows.splice(windows.indexOf(this), 1);
- this._removeAllListeners('close');
- this._removeAllListeners('open');
- this._removeAllListeners('ready');
- },
- close: function close(callback) {
- // maybe we should deprecate this with message ?
- if (callback) this.on('close', callback);
- return this._close();
- }
- })
-);
-/**
- * Wrapper for `BrowserWindowTrait`. Creates new instance if wrapper for
- * window doesn't exists yet. If wrapper already exists then returns it
- * instead.
- * @params {Object} options
- * Options that are passed to the the `BrowserWindowTrait`
- * @returns {BrowserWindow}
- * @see BrowserWindowTrait
- */
-function BrowserWindow(options) {
- let chromeWindow = options.window;
- for each (let window in windows) {
- if (chromeWindow == window._window)
- return window._public
- }
- let window = BrowserWindowTrait(options);
- return window._public;
-}
-// to have proper `instanceof` behavior will go away when #596248 is fixed.
-BrowserWindow.prototype = BrowserWindowTrait.prototype;
-exports.BrowserWindow = BrowserWindow
-const windows = [];
-/**
- * `BrowserWindows` trait is composed out of `List` trait and it represents
- * "live" list of currently open browser windows. Instance mutates itself
- * whenever new browser window gets opened / closed.
- */
-// Very stupid to resolve all `toStrings` but this will be fixed by #596248
-const browserWindows = Trait.resolve({ toString: null }).compose(
- List.resolve({ constructor: '_initList' }),
- EventEmitter.resolve({ toString: null }),
- WindowTrackerTrait.resolve({ constructor: '_initTracker', toString: null }),
- Trait.compose({
- _emit: Trait.required,
- _add: Trait.required,
- _remove: Trait.required,
-
- // public API
-
- /**
- * Constructor creates instance of `Windows` that represents live list of open
- * windows.
- */
- constructor: function BrowserWindows() {
- this._trackedWindows = [];
- this._initList();
- this._initTracker();
- unload.ensure(this, "_destructor");
- },
- _destructor: function _destructor() {
- this._removeAllListeners('open');
- this._removeAllListeners('close');
- },
- /**
- * This property represents currently active window.
- * Property is non-enumerable, in order to preserve array like enumeration.
- * @type {Window|null}
- */
- get activeWindow() {
- let window = WM.getMostRecentWindow(BROWSER);
- return this._isBrowser(window) ? BrowserWindow({ window: window }) : null;
- },
- open: function open(options) {
- if (typeof options === "string")
- // `tabs` option is under review and may be removed.
- options = { tabs: [Options(options)] };
- return BrowserWindow(options);
- },
- /**
- * Returns true if specified window is a browser window.
- * @param {nsIWindow} window
- * @returns {Boolean}
- */
- _isBrowser: function _isBrowser(window)
- BROWSER === window.document.documentElement.getAttribute("windowtype")
- ,
- /**
- * Internal listener which is called whenever new window gets open.
- * Creates wrapper and adds to this list.
- * @param {nsIWindow} chromeWindow
- */
- _onTrack: function _onTrack(chromeWindow) {
- if (!this._isBrowser(chromeWindow)) return;
- let window = BrowserWindow({ window: chromeWindow });
- this._add(window);
- this._emit('open', window);
- },
- /**
- * Internal listener which is called whenever window gets closed.
- * Cleans up references and removes wrapper from this list.
- * @param {nsIWindow} window
- */
- _onUntrack: function _onUntrack(chromeWindow) {
- if (!this._isBrowser(chromeWindow)) return;
- let window = BrowserWindow({ window: chromeWindow });
- // `_onUnload` method of the `BrowserWindow` will remove `chromeWindow`
- // from the `windows` array.
- this._remove(window);
- this._emit('close', window);
- }
- }).resolve({ toString: null })
-)();
-exports.browserWindows = browserWindows;
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/package.json b/tools/addon-sdk-1.4/packages/addon-kit/package.json
deleted file mode 100644
index 9c62ae8..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "addon-kit",
- "description": "Add-on development made easy.",
- "keywords": ["javascript", "engine", "platform", "xulrunner"],
- "author": "Atul Varma (http://toolness.com/) <atul@mozilla.com>",
- "contributors": [
- "Myk Melez (http://melez.com/) <myk@mozilla.org>",
- "Daniel Aquino <mr.danielaquino@gmail.com>"
- ],
- "license": "MPL 1.1/GPL 2.0/LGPL 2.1",
- "dependencies": ["api-utils"]
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/helpers.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/helpers.js
deleted file mode 100644
index bbfe911..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/helpers.js
+++ /dev/null
@@ -1,19 +0,0 @@
-"use strict";
-
-const { Loader } = require("@loader");
-
-exports.Loader = function(module, globals) {
- var options = JSON.parse(JSON.stringify(require("@packaging")));
- options.globals = globals;
- let loader = Loader.new(options);
- return Object.create(loader, {
- require: { value: Loader.require.bind(loader, module.path) },
- sandbox: { value: function sandbox(id) {
- let path = options.manifest[module.path].requirements[id].path;
- return loader.sandboxes[path].sandbox;
- }},
- unload: { value: function unload(reason, callback) {
- loader.unload(reason, callback);
- }}
- })
-};
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/pagemod-test-helpers.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/pagemod-test-helpers.js
deleted file mode 100644
index 7e87a85..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/pagemod-test-helpers.js
+++ /dev/null
@@ -1,63 +0,0 @@
-"use strict";
-
-const {Cc,Ci} = require("chrome");
-const timer = require("timer");
-const xulApp = require("xul-app");
-const { Loader } = require('./helpers');
-
-/**
- * A helper function that creates a PageMod, then opens the specified URL
- * and checks the effect of the page mod on 'onload' event via testCallback.
- */
-exports.testPageMod = function testPageMod(test, testURL, pageModOptions,
- testCallback, timeout) {
- if (!xulApp.versionInRange(xulApp.platformVersion, "1.9.3a3", "*") &&
- !xulApp.versionInRange(xulApp.platformVersion, "1.9.2.7", "1.9.2.*")) {
- test.pass("Note: not testing PageMod, as it doesn't work on this platform version");
- return null;
- }
-
- var wm = Cc['@mozilla.org/appshell/window-mediator;1']
- .getService(Ci.nsIWindowMediator);
- var browserWindow = wm.getMostRecentWindow("navigator:browser");
- if (!browserWindow) {
- test.pass("page-mod tests: could not find the browser window, so " +
- "will not run. Use -a firefox to run the pagemod tests.")
- return null;
- }
-
- if (timeout !== undefined)
- test.waitUntilDone(timeout);
- else
- test.waitUntilDone();
-
- let loader = Loader(module);
- let pageMod = loader.require("page-mod");
-
- var pageMods = [new pageMod.PageMod(opts) for each(opts in pageModOptions)];
-
- var tabBrowser = browserWindow.gBrowser;
- var newTab = tabBrowser.addTab(testURL);
- tabBrowser.selectedTab = newTab;
- var b = tabBrowser.getBrowserForTab(newTab);
-
- function onPageLoad() {
- b.removeEventListener("load", onPageLoad, true);
- // Delay callback execute as page-mod content scripts may be executed on
- // load event. So page-mod actions may not be already done.
- // If we delay even more contentScriptWhen:'end', we may want to modify
- // this code again.
- timer.setTimeout(testCallback, 0,
- b.contentWindow.wrappedJSObject,
- function done() {
- pageMods.forEach(function(mod) mod.destroy());
- // XXX leaks reported if we don't close the tab?
- tabBrowser.removeTab(newTab);
- loader.unload();
- test.done();
- });
- }
- b.addEventListener("load", onPageLoad, true);
-
- return pageMods;
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-clipboard.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-clipboard.js
deleted file mode 100644
index 5f61d48..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-clipboard.js
+++ /dev/null
@@ -1,60 +0,0 @@
-
-// Test the typical use case, setting & getting with no flavors specified
-exports.testWithNoFlavor = function(test) {
- var contents = "hello there";
- var flavor = "text";
- var fullFlavor = "text/unicode";
- var clip = require("clipboard");
- // Confirm we set the clipboard
- test.assert(clip.set(contents));
- // Confirm flavor is set
- test.assertEqual(clip.currentFlavors[0], flavor);
- // Confirm we set the clipboard
- test.assertEqual(clip.get(), contents);
- // Confirm we can get the clipboard using the flavor
- test.assertEqual(clip.get(flavor), contents);
- // Confirm we can still get the clipboard using the full flavor
- test.assertEqual(clip.get(fullFlavor), contents);
-};
-
-// Test the slightly less common case where we specify the flavor
-exports.testWithFlavor = function(test) {
- var contents = "<b>hello there</b>";
- var contentsText = "hello there";
- var flavor = "html";
- var fullFlavor = "text/html";
- var unicodeFlavor = "text";
- var unicodeFullFlavor = "text/unicode";
- var clip = require("clipboard");
- test.assert(clip.set(contents, flavor));
- test.assertEqual(clip.currentFlavors[0], unicodeFlavor);
- test.assertEqual(clip.currentFlavors[1], flavor);
- test.assertEqual(clip.get(), contentsText);
- test.assertEqual(clip.get(flavor), contents);
- test.assertEqual(clip.get(fullFlavor), contents);
- test.assertEqual(clip.get(unicodeFlavor), contentsText);
- test.assertEqual(clip.get(unicodeFullFlavor), contentsText);
-};
-
-// Test that the typical case still works when we specify the flavor to set
-exports.testWithRedundantFlavor = function(test) {
- var contents = "<b>hello there</b>";
- var flavor = "text";
- var fullFlavor = "text/unicode";
- var clip = require("clipboard");
- test.assert(clip.set(contents, flavor));
- test.assertEqual(clip.currentFlavors[0], flavor);
- test.assertEqual(clip.get(), contents);
- test.assertEqual(clip.get(flavor), contents);
- test.assertEqual(clip.get(fullFlavor), contents);
-};
-
-exports.testNotInFlavor = function(test) {
- var contents = "hello there";
- var flavor = "html";
- var clip = require("clipboard");
- test.assert(clip.set(contents));
- // If there's nothing on the clipboard with this flavor, should return null
- test.assertEqual(clip.get(flavor), null);
-};
-// TODO: Test error cases.
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.html b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.html
deleted file mode 100644
index a0fb5cb..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1/GPL 2.0/LGPL 2.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Jetpack.
- -
- - The Initial Developer of the Original Code is
- - the Mozilla Foundation.
- - Portions created by the Initial Developer are Copyright (C) 2010
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- - Drew Willcoxon <adw@mozilla.com> (Original Author)
- -
- - Alternatively, the contents of this file may be used under the terms of
- - either the GNU General Public License Version 2 or later (the "GPL"), or
- - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- - in which case the provisions of the GPL or the LGPL are applicable instead
- - of those above. If you wish to allow use of your version of this file only
- - under the terms of either the GPL or the LGPL, and not to allow others to
- - use your version of this file under the terms of the MPL, indicate your
- - decision by deleting the provisions above and replace them with the notice
- - and other provisions required by the LGPL or the GPL. If you do not delete
- - the provisions above, a recipient may use your version of this file under
- - the terms of any one of the MPL, the GPL or the LGPL.
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<html>
- <head>
- <title>Context menu test</title>
- </head>
- <body>
- <p>
- <img id="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==">
- </p>
-
- <p>
- <a id="link" href="">
- A simple link.
- </a>
- </p>
-
- <p>
- <a href="">
- <span id="span-link">
- A span inside a link.
- </span>
- </a>
- </p>
-
- <p id="text">
- Some text.
- </p>
-
- <p>
- <textarea id="textfield">
- A text field,
- with some text.
- </textarea>
- </p>
-
- <p>
- <iframe id="iframe" src="data:text/html,An iframe."
- width="200" height="100">
- </iframe>
- </p>
- </body>
-</html>
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.js
deleted file mode 100644
index 157edf1..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-context-menu.js
+++ /dev/null
@@ -1,2075 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Drew Willcoxon <adw@mozilla.com> (Original Author)
- * Matteo Ferretti <zer0@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-let {Cc,Ci} = require("chrome");
-const { Loader } = require('./helpers');
-
-// These should match the same constants in the module.
-const ITEM_CLASS = "jetpack-context-menu-item";
-const SEPARATOR_ID = "jetpack-context-menu-separator";
-const OVERFLOW_THRESH_DEFAULT = 10;
-const OVERFLOW_THRESH_PREF =
- "extensions.addon-sdk.context-menu.overflowThreshold";
-const OVERFLOW_MENU_ID = "jetpack-content-menu-overflow-menu";
-const OVERFLOW_POPUP_ID = "jetpack-content-menu-overflow-popup";
-
-const TEST_DOC_URL = module.uri.replace(/\.js$/, ".html");
-
-
-// Destroying items that were previously created should cause them to be absent
-// from the menu.
-exports.testConstructDestroy = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- // Create an item.
- let item = new loader.cm.Item({ label: "item" });
- test.assertEqual(item.parentMenu, null, "item's parent menu should be null");
-
- test.showMenu(null, function (popup) {
-
- // It should be present when the menu is shown.
- test.checkMenu([item], [], []);
- popup.hidePopup();
-
- // Destroy the item. Multiple destroys should be harmless.
- item.destroy();
- item.destroy();
- test.showMenu(null, function (popup) {
-
- // It should be removed from the menu.
- test.checkMenu([], [], [item]);
- test.done();
- });
- });
-};
-
-
-// Destroying an item twice should not cause an error.
-exports.testDestroyTwice = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({ label: "item" });
- item.destroy();
- item.destroy();
-
- test.pass("Destroying an item twice should not cause an error.");
- test.done();
-};
-
-
-// CSS selector contexts should cause their items to be present in the menu
-// when the menu is invoked on nodes that match the selectors.
-exports.testSelectorContextMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- data: "item",
- context: loader.cm.SelectorContext("img")
- });
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(doc.getElementById("image"), function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
- });
-};
-
-
-// CSS selector contexts should cause their items to be present in the menu
-// when the menu is invoked on nodes that have ancestors that match the
-// selectors.
-exports.testSelectorAncestorContextMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- data: "item",
- context: loader.cm.SelectorContext("a[href]")
- });
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(doc.getElementById("span-link"), function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
- });
-};
-
-
-// CSS selector contexts should cause their items to be absent from the menu
-// when the menu is not invoked on nodes that match or have ancestors that
-// match the selectors.
-exports.testSelectorContextNoMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- data: "item",
- context: loader.cm.SelectorContext("img")
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([], [item], []);
- test.done();
- });
-};
-
-
-// Page contexts should cause their items to be present in the menu when the
-// menu is not invoked on an active element.
-exports.testPageContextMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [
- new loader.cm.Item({
- label: "item 0"
- }),
- new loader.cm.Item({
- label: "item 1",
- context: undefined
- }),
- new loader.cm.Item({
- label: "item 2",
- context: loader.cm.PageContext()
- }),
- new loader.cm.Item({
- label: "item 3",
- context: [loader.cm.PageContext()]
- })
- ];
-
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- test.done();
- });
-};
-
-
-// Page contexts should cause their items to be absent from the menu when the
-// menu is invoked on an active element.
-exports.testPageContextNoMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [
- new loader.cm.Item({
- label: "item 0"
- }),
- new loader.cm.Item({
- label: "item 1",
- context: undefined
- }),
- new loader.cm.Item({
- label: "item 2",
- context: loader.cm.PageContext()
- }),
- new loader.cm.Item({
- label: "item 3",
- context: [loader.cm.PageContext()]
- })
- ];
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(doc.getElementById("image"), function (popup) {
- test.checkMenu([], items, []);
- test.done();
- });
- });
-};
-
-
-// Selection contexts should cause items to appear when a selection exists.
-exports.testSelectionContextMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = loader.cm.Item({
- label: "item",
- context: loader.cm.SelectionContext()
- });
-
- test.withTestDoc(function (window, doc) {
- window.getSelection().selectAllChildren(doc.body);
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
- });
-};
-
-
-// Selection contexts should cause items to appear when a selection exists in
-// a text field.
-exports.testSelectionContextMatchInTextField = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = loader.cm.Item({
- label: "item",
- context: loader.cm.SelectionContext()
- });
-
- test.withTestDoc(function (window, doc) {
- let textfield = doc.getElementById("textfield");
- textfield.setSelectionRange(0, textfield.value.length);
- test.showMenu(textfield, function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
- });
-};
-
-
-// Selection contexts should not cause items to appear when a selection does
-// not exist in a text field.
-exports.testSelectionContextNoMatchInTextField = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = loader.cm.Item({
- label: "item",
- context: loader.cm.SelectionContext()
- });
-
- test.withTestDoc(function (window, doc) {
- let textfield = doc.getElementById("textfield");
- textfield.setSelectionRange(0, 0);
- test.showMenu(textfield, function (popup) {
- test.checkMenu([], [item], []);
- test.done();
- });
- });
-};
-
-
-// Selection contexts should not cause items to appear when a selection does
-// not exist.
-exports.testSelectionContextNoMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = loader.cm.Item({
- label: "item",
- context: loader.cm.SelectionContext()
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([], [item], []);
- test.done();
- });
-};
-
-
-// URL contexts should cause items to appear on pages that match.
-exports.testURLContextMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [
- loader.cm.Item({
- label: "item 0",
- context: loader.cm.URLContext(TEST_DOC_URL)
- }),
- loader.cm.Item({
- label: "item 1",
- context: loader.cm.URLContext([TEST_DOC_URL, "*.bogus.com"])
- })
- ];
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- test.done();
- });
- });
-};
-
-
-// URL contexts should not cause items to appear on pages that do not match.
-exports.testURLContextNoMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [
- loader.cm.Item({
- label: "item 0",
- context: loader.cm.URLContext("*.bogus.com")
- }),
- loader.cm.Item({
- label: "item 1",
- context: loader.cm.URLContext(["*.bogus.com", "*.gnarly.com"])
- })
- ];
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(null, function (popup) {
- test.checkMenu([], items, []);
- test.done();
- });
- });
-};
-
-
-// Removing a non-matching URL context after its item is created and the page is
-// loaded should cause the item's content script to be evaluated.
-exports.testURLContextRemove = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let shouldBeEvaled = false;
- let context = loader.cm.URLContext("*.bogus.com");
- let item = loader.cm.Item({
- label: "item",
- context: context,
- contentScript: 'self.postMessage("ok");',
- onMessage: function (msg) {
- test.assert(shouldBeEvaled,
- "content script should be evaluated when expected");
- shouldBeEvaled = false;
- test.done();
- }
- });
-
- test.withTestDoc(function (window, doc) {
- shouldBeEvaled = true;
- item.context.remove(context);
- });
-};
-
-
-// Adding a non-matching URL context after its item is created and the page is
-// loaded should cause the item's worker to be destroyed.
-exports.testURLContextAdd = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = loader.cm.Item({ label: "item" });
-
- test.withTestDoc(function (window, doc) {
- let privatePropsKey = loader.globalScope.PRIVATE_PROPS_KEY;
- let workerReg = item.valueOf(privatePropsKey)._workerReg;
-
- let found = false;
- for each (let winWorker in workerReg.winWorkers) {
- if (winWorker.win === window) {
- found = true;
- break;
- }
- }
- this.test.assert(found, "window should be present in worker registry");
-
- item.context.add(loader.cm.URLContext("*.bogus.com"));
-
- for each (let winWorker in workerReg.winWorkers)
- this.test.assertNotEqual(winWorker.win, window,
- "window should not be present in worker registry");
-
- test.done();
- });
-};
-
-
-// Content contexts that return true should cause their items to be present
-// in the menu.
-exports.testContentContextMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- contentScript: 'self.on("context", function () true);'
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
-};
-
-
-// Content contexts that return false should cause their items to be absent
-// from the menu.
-exports.testContentContextNoMatch = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- contentScript: 'self.on("context", function () false);'
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([], [item], []);
- test.done();
- });
-};
-
-
-// Content contexts that return a string should cause their items to be present
-// in the menu and the items' labels to be updated.
-exports.testContentContextMatchString = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "first label",
- contentScript: 'self.on("context", function () "second label");'
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- test.assertEqual(item.label, "second label",
- "item's label should be updated");
- test.done();
- });
-};
-
-
-// The args passed to context listeners should be correct.
-exports.testContentContextArgs = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
- let callbacks = 0;
-
- let item = new loader.cm.Item({
- label: "item",
- contentScript: 'self.on("context", function (node) {' +
- ' let Ci = Components.interfaces;' +
- ' self.postMessage(node instanceof Ci.nsIDOMHTMLElement);' +
- ' return false;' +
- '});',
- onMessage: function (isElt) {
- test.assert(isElt, "node should be an HTML element");
- if (++callbacks == 2) test.done();
- }
- });
-
- test.showMenu(null, function () {
- if (++callbacks == 2) test.done();
- });
-};
-
-// Multiple contexts imply intersection, not union, and content context
-// listeners should not be called if all declarative contexts are not current.
-exports.testMultipleContexts = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- context: [loader.cm.SelectorContext("a[href]"), loader.cm.PageContext()],
- contentScript: 'self.on("context", function () self.postMessage());',
- onMessage: function () {
- test.fail("Context listener should not be called");
- }
- });
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(doc.getElementById("span-link"), function (popup) {
- test.checkMenu([], [item], []);
- test.done();
- });
- });
-};
-
-
-// Once a context is removed, it should no longer cause its item to appear.
-exports.testRemoveContext = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let ctxt = loader.cm.SelectorContext("img");
- let item = new loader.cm.Item({
- label: "item",
- context: ctxt
- });
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(doc.getElementById("image"), function (popup) {
-
- // The item should be present at first.
- test.checkMenu([item], [], []);
- popup.hidePopup();
-
- // Remove the img context and check again.
- item.context.remove(ctxt);
- test.showMenu(doc.getElementById("image"), function (popup) {
- test.checkMenu([], [item], []);
- test.done();
- });
- });
- });
-};
-
-
-// Lots of items should overflow into the overflow submenu.
-exports.testOverflow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [];
- for (let i = 0; i < OVERFLOW_THRESH_DEFAULT + 1; i++) {
- let item = new loader.cm.Item({ label: "item " + i });
- items.push(item);
- }
-
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- test.done();
- });
-};
-
-
-// Module unload should cause all items to be removed.
-exports.testUnload = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({ label: "item" });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain the item.
- test.checkMenu([item], [], []);
- popup.hidePopup();
-
- // Unload the module.
- loader.unload();
- test.showMenu(null, function (popup) {
-
- // The item should be removed from the menu.
- test.checkMenu([], [], [item]);
- test.done();
- });
- });
-};
-
-
-// Using multiple module instances to add items without causing overflow should
-// work OK. Assumes OVERFLOW_THRESH_DEFAULT <= 2.
-exports.testMultipleModulesAdd = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- // Use each module to add an item, then unload each module in turn.
- let item0 = new loader0.cm.Item({ label: "item 0" });
- let item1 = new loader1.cm.Item({ label: "item 1" });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain both items.
- test.checkMenu([item0, item1], [], []);
- popup.hidePopup();
-
- // Unload the first module.
- loader0.unload();
- test.showMenu(null, function (popup) {
-
- // The first item should be removed from the menu.
- test.checkMenu([item1], [], [item0]);
- popup.hidePopup();
-
- // Unload the second module.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // Both items should be removed from the menu.
- test.checkMenu([], [], [item0, item1]);
- test.done();
- });
- });
- });
-};
-
-
-// Using multiple module instances to add items causing overflow should work OK.
-exports.testMultipleModulesAddOverflow = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- // Use module 0 to add OVERFLOW_THRESH_DEFAULT items.
- let items0 = [];
- for (let i = 0; i < OVERFLOW_THRESH_DEFAULT; i++) {
- let item = new loader0.cm.Item({ label: "item 0 " + i });
- items0.push(item);
- }
-
- // Use module 1 to add one item.
- let item1 = new loader1.cm.Item({ label: "item 1" });
-
- let allItems = items0.concat(item1);
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain all items in overflow.
- test.checkMenu(allItems, [], []);
- popup.hidePopup();
-
- // Unload the first module.
- loader0.unload();
- test.showMenu(null, function (popup) {
-
- // The first items should be removed from the menu, which should not
- // overflow.
- test.checkMenu([item1], [], items0);
- popup.hidePopup();
-
- // Unload the second module.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // All items should be removed from the menu.
- test.checkMenu([], [], allItems);
- test.done();
- });
- });
- });
-};
-
-
-// Using multiple module instances to modify the menu without causing overflow
-// should work OK. This test creates two loaders and:
-// loader0 create item -> loader1 create item -> loader0.unload ->
-// loader1.unload
-exports.testMultipleModulesDiffContexts1 = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let item0 = new loader0.cm.Item({
- label: "item 0",
- context: loader0.cm.SelectorContext("img")
- });
-
- let item1 = new loader1.cm.Item({ label: "item 1" });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain item1.
- test.checkMenu([item1], [item0], []);
- popup.hidePopup();
-
- // Unload module 0.
- loader0.unload();
- test.showMenu(null, function (popup) {
-
- // item0 should be removed from the menu.
- test.checkMenu([item1], [], [item0]);
- popup.hidePopup();
-
- // Unload module 1.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // Both items should be removed from the menu.
- test.checkMenu([], [], [item0, item1]);
- test.done();
- });
- });
- });
-};
-
-
-// Using multiple module instances to modify the menu without causing overflow
-// should work OK. This test creates two loaders and:
-// loader1 create item -> loader0 create item -> loader0.unload ->
-// loader1.unload
-exports.testMultipleModulesDiffContexts2 = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let item1 = new loader1.cm.Item({ label: "item 1" });
-
- let item0 = new loader0.cm.Item({
- label: "item 0",
- context: loader0.cm.SelectorContext("img")
- });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain item1.
- test.checkMenu([item1], [item0], []);
- popup.hidePopup();
-
- // Unload module 0.
- loader0.unload();
- test.showMenu(null, function (popup) {
-
- // item0 should be removed from the menu.
- test.checkMenu([item1], [], [item0]);
- popup.hidePopup();
-
- // Unload module 1.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // Both items should be removed from the menu.
- test.checkMenu([], [], [item0, item1]);
- test.done();
- });
- });
- });
-};
-
-
-// Using multiple module instances to modify the menu without causing overflow
-// should work OK. This test creates two loaders and:
-// loader0 create item -> loader1 create item -> loader1.unload ->
-// loader0.unload
-exports.testMultipleModulesDiffContexts3 = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let item0 = new loader0.cm.Item({
- label: "item 0",
- context: loader0.cm.SelectorContext("img")
- });
-
- let item1 = new loader1.cm.Item({ label: "item 1" });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain item1.
- test.checkMenu([item1], [item0], []);
- popup.hidePopup();
-
- // Unload module 1.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // item1 should be removed from the menu.
- test.checkMenu([], [item0], [item1]);
- popup.hidePopup();
-
- // Unload module 0.
- loader0.unload();
- test.showMenu(null, function (popup) {
-
- // Both items should be removed from the menu.
- test.checkMenu([], [], [item0, item1]);
- test.done();
- });
- });
- });
-};
-
-
-// Using multiple module instances to modify the menu without causing overflow
-// should work OK. This test creates two loaders and:
-// loader1 create item -> loader0 create item -> loader1.unload ->
-// loader0.unload
-exports.testMultipleModulesDiffContexts4 = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let item1 = new loader1.cm.Item({ label: "item 1" });
-
- let item0 = new loader0.cm.Item({
- label: "item 0",
- context: loader0.cm.SelectorContext("img")
- });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain item1.
- test.checkMenu([item1], [item0], []);
- popup.hidePopup();
-
- // Unload module 1.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // item1 should be removed from the menu.
- test.checkMenu([], [item0], [item1]);
- popup.hidePopup();
-
- // Unload module 0.
- loader0.unload();
- test.showMenu(null, function (popup) {
-
- // Both items should be removed from the menu.
- test.checkMenu([], [], [item0, item1]);
- test.done();
- });
- });
- });
-};
-
-
-// Test interactions between a loaded module, unloading another module, and the
-// menu separator and overflow submenu.
-exports.testMultipleModulesAddRemove = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let item = new loader0.cm.Item({ label: "item" });
-
- test.showMenu(null, function (popup) {
-
- // The menu should contain the item.
- test.checkMenu([item], [], []);
- popup.hidePopup();
-
- // Remove the item.
- item.destroy();
- test.showMenu(null, function (popup) {
-
- // The item should be removed from the menu.
- test.checkMenu([], [], [item]);
- popup.hidePopup();
-
- // Unload module 1.
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // There shouldn't be any errors involving the menu separator or
- // overflow submenu.
- test.checkMenu([], [], [item]);
- test.done();
- });
- });
- });
-};
-
-
-// An item's click listener should work.
-exports.testItemClick = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- data: "item data",
- contentScript: 'self.on("click", function (node, data) {' +
- ' let Ci = Components.interfaces;' +
- ' self.postMessage({' +
- ' isElt: node instanceof Ci.nsIDOMHTMLElement,' +
- ' data: data' +
- ' });' +
- '});',
- onMessage: function (data) {
- test.assertEqual(this, item, "`this` inside onMessage should be item");
- test.assert(data.isElt, "node should be an HTML element");
- test.assertEqual(data.data, item.data, "data should be item data");
- test.done();
- }
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- let elt = test.getItemElt(popup, item);
- elt.click();
- });
-};
-
-
-// A menu's click listener should work and receive bubbling clicks from
-// sub-items appropriately. This also tests menus and ensures that when a CSS
-// selector context matches the clicked node's ancestor, the matching ancestor
-// is passed to listeners as the clicked node.
-exports.testMenuClick = function (test) {
- // Create a top-level menu, submenu, and item, like this:
- // topMenu -> submenu -> item
- // Click the item and make sure the click bubbles.
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "submenu item",
- data: "submenu item data"
- });
-
- let submenu = new loader.cm.Menu({
- label: "submenu",
- items: [item]
- });
-
- let topMenu = new loader.cm.Menu({
- label: "top menu",
- contentScript: 'self.on("click", function (node, data) {' +
- ' let Ci = Components.interfaces;' +
- ' self.postMessage({' +
- ' isAnchor: node instanceof Ci.nsIDOMHTMLAnchorElement,' +
- ' data: data' +
- ' });' +
- '});',
- onMessage: function (data) {
- test.assertEqual(this, topMenu, "`this` inside top menu should be menu");
- test.assert(data.isAnchor, "Clicked node should be anchor");
- test.assertEqual(data.data, item.data,
- "Clicked item data should be correct");
- test.done();
- },
- items: [submenu],
- context: loader.cm.SelectorContext("a")
- });
-
- test.withTestDoc(function (window, doc) {
- test.showMenu(doc.getElementById("span-link"), function (popup) {
- test.checkMenu([topMenu], [], []);
- let topMenuElt = test.getItemElt(popup, topMenu);
- let topMenuPopup = topMenuElt.firstChild;
- let submenuElt = test.getItemElt(topMenuPopup, submenu);
- let submenuPopup = submenuElt.firstChild;
- let itemElt = test.getItemElt(submenuPopup, item);
- itemElt.click();
- });
- });
-};
-
-
-// Click listeners should work when multiple modules are loaded.
-exports.testItemClickMultipleModules = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let item0 = loader0.cm.Item({
- label: "loader 0 item",
- contentScript: 'self.on("click", self.postMessage);',
- onMessage: function () {
- test.fail("loader 0 item should not emit click event");
- }
- });
- let item1 = loader1.cm.Item({
- label: "loader 1 item",
- contentScript: 'self.on("click", self.postMessage);',
- onMessage: function () {
- test.pass("loader 1 item clicked as expected");
- test.done();
- }
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item0, item1], [], []);
- let item1Elt = test.getItemElt(popup, item1);
- item1Elt.click();
- });
-};
-
-
-// Adding a separator to a submenu should work OK.
-exports.testSeparator = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let menu = new loader.cm.Menu({
- label: "submenu",
- items: [new loader.cm.Separator()]
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Existing context menu modifications should apply to new windows.
-exports.testNewWindow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({ label: "item" });
-
- test.withNewWindow(function () {
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
- });
-};
-
-
-// When a new window is opened, items added by an unloaded module should not
-// be present in the menu.
-exports.testNewWindowMultipleModules = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
- let item = new loader.cm.Item({ label: "item" });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- popup.hidePopup();
- loader.unload();
- test.withNewWindow(function () {
- test.showMenu(null, function (popup) {
- test.checkMenu([], [], []);
- test.done();
- });
- });
- });
-};
-
-
-// Items in the context menu should be sorted according to locale.
-exports.testSorting = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- // Make an unsorted items list. It'll look like this:
- // item 1, item 0, item 3, item 2, item 5, item 4, ...
- let items = [];
- for (let i = 0; i < OVERFLOW_THRESH_DEFAULT; i += 2) {
- items.push(new loader.cm.Item({ label: "item " + (i + 1) }));
- items.push(new loader.cm.Item({ label: "item " + i }));
- }
-
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- test.done();
- });
-};
-
-
-// Items in the overflow menu should be sorted according to locale.
-exports.testSortingOverflow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- // Make an unsorted items list. It'll look like this:
- // item 1, item 0, item 3, item 2, item 5, item 4, ...
- let items = [];
- for (let i = 0; i < OVERFLOW_THRESH_DEFAULT * 2; i += 2) {
- items.push(new loader.cm.Item({ label: "item " + (i + 1) }));
- items.push(new loader.cm.Item({ label: "item " + i }));
- }
-
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- test.done();
- });
-};
-
-
-// Multiple modules shouldn't interfere with sorting.
-exports.testSortingMultipleModules = function (test) {
- test = new TestHelper(test);
- let loader0 = test.newLoader();
- let loader1 = test.newLoader();
-
- let items0 = [];
- let items1 = [];
- for (let i = 0; i < OVERFLOW_THRESH_DEFAULT; i++) {
- if (i % 2) {
- let item = new loader0.cm.Item({ label: "item " + i });
- items0.push(item);
- }
- else {
- let item = new loader1.cm.Item({ label: "item " + i });
- items1.push(item);
- }
- }
- let allItems = items0.concat(items1);
-
- test.showMenu(null, function (popup) {
-
- // All items should be present and sorted.
- test.checkMenu(allItems, [], []);
- popup.hidePopup();
- loader0.unload();
- loader1.unload();
- test.showMenu(null, function (popup) {
-
- // All items should be removed.
- test.checkMenu([], [], allItems);
- test.done();
- });
- });
-};
-
-
-// The binary search of insertionPoint should work OK.
-exports.testInsertionPoint = function (test) {
- function mockElts(labels) {
- return labels.map(function (label) {
- return { label: label, getAttribute: function (l) label };
- });
- }
-
- test = new TestHelper(test);
- let loader = test.newLoader();
- let insertionPoint = loader.globalScope.insertionPoint;
-
- let ip = insertionPoint("a", []);
- test.assertStrictEqual(ip, null, "Insertion point should be null");
-
- ip = insertionPoint("a", mockElts(["b"]));
- test.assertEqual(ip.label, "b", "Insertion point should be 'b'");
-
- ip = insertionPoint("c", mockElts(["b"]));
- test.assertStrictEqual(ip, null, "Insertion point should be null");
-
- ip = insertionPoint("b", mockElts(["a", "c"]));
- test.assertEqual(ip.label, "c", "Insertion point should be 'c'");
-
- ip = insertionPoint("c", mockElts(["a", "b", "d"]));
- test.assertEqual(ip.label, "d", "Insertion point should be 'd'");
-
- ip = insertionPoint("a", mockElts(["b", "c", "d"]));
- test.assertEqual(ip.label, "b", "Insertion point should be 'b'");
-
- ip = insertionPoint("d", mockElts(["a", "b", "c"]));
- test.assertStrictEqual(ip, null, "Insertion point should be null");
-
- test.done();
-};
-
-
-// Content click handlers and context handlers should be able to communicate,
-// i.e., they're eval'ed in the same worker and sandbox.
-exports.testContentCommunication = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = new loader.cm.Item({
- label: "item",
- contentScript: 'var potato;' +
- 'self.on("context", function () {' +
- ' potato = "potato";' +
- ' return true;' +
- '});' +
- 'self.on("click", function () {' +
- ' self.postMessage(potato);' +
- '});',
- });
-
- item.on("message", function (data) {
- test.assertEqual(data, "potato", "That's a lot of potatoes!");
- test.done();
- });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- let elt = test.getItemElt(popup, item);
- elt.click();
- });
-};
-
-
-// When the context menu is invoked on a tab that was already open when the
-// module was loaded, it should contain the expected items and content workers
-// should function as expected.
-exports.testLoadWithOpenTab = function (test) {
- test = new TestHelper(test);
- test.withTestDoc(function (window, doc) {
- let loader = test.newLoader();
- let item = new loader.cm.Item({
- label: "item",
- contentScript:
- 'self.on("click", function () self.postMessage("click"));',
- onMessage: function (msg) {
- if (msg === "click")
- test.done();
- }
- });
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- test.getItemElt(popup, item).click();
- });
- });
-};
-
-
-// Setting an item's label before the menu is ever shown should correctly change
-// its label and, if necessary, its order within the menu.
-exports.testSetLabelBeforeShow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [
- new loader.cm.Item({ label: "a" }),
- new loader.cm.Item({ label: "b" })
- ]
- items[0].label = "z";
- test.assertEqual(items[0].label, "z");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([items[1], items[0]], [], []);
- test.done();
- });
-};
-
-
-// Setting an item's label after the menu is shown should correctly change its
-// label and, if necessary, its order within the menu.
-exports.testSetLabelAfterShow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let items = [
- new loader.cm.Item({ label: "a" }),
- new loader.cm.Item({ label: "b" })
- ];
-
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- popup.hidePopup();
-
- items[0].label = "z";
- test.assertEqual(items[0].label, "z");
- test.showMenu(null, function (popup) {
- test.checkMenu([items[1], items[0]], [], []);
- test.done();
- });
- });
-};
-
-
-// Setting an item's label before the menu is ever shown should correctly change
-// its label and, if necessary, its order within the menu if the item is in the
-// overflow submenu.
-exports.testSetLabelBeforeShowOverflow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let prefs = loader.loader.require("preferences-service");
- prefs.set(OVERFLOW_THRESH_PREF, 0);
-
- let items = [
- new loader.cm.Item({ label: "a" }),
- new loader.cm.Item({ label: "b" })
- ]
- items[0].label = "z";
- test.assertEqual(items[0].label, "z");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([items[1], items[0]], [], []);
- prefs.set(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
- test.done();
- });
-};
-
-
-// Setting an item's label after the menu is shown should correctly change its
-// label and, if necessary, its order within the menu if the item is in the
-// overflow submenu.
-exports.testSetLabelAfterShowOverflow = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let prefs = loader.loader.require("preferences-service");
- prefs.set(OVERFLOW_THRESH_PREF, 0);
-
- let items = [
- new loader.cm.Item({ label: "a" }),
- new loader.cm.Item({ label: "b" })
- ];
-
- test.showMenu(null, function (popup) {
- test.checkMenu(items, [], []);
- popup.hidePopup();
-
- items[0].label = "z";
- test.assertEqual(items[0].label, "z");
- test.showMenu(null, function (popup) {
- test.checkMenu([items[1], items[0]], [], []);
- prefs.set(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
- test.done();
- });
- });
-};
-
-
-// Setting the label of an item in a Menu should work.
-exports.testSetLabelMenuItem = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let menu = loader.cm.Menu({
- label: "menu",
- items: [loader.cm.Item({ label: "a" })]
- });
- menu.items[0].label = "z";
-
- test.assertEqual(menu.items[0].label, "z");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Menu.addItem() should work.
-exports.testMenuAddItem = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let menu = loader.cm.Menu({
- label: "menu",
- items: [
- loader.cm.Item({ label: "item 0" })
- ]
- });
- menu.addItem(loader.cm.Item({ label: "item 1" }));
- menu.addItem(loader.cm.Item({ label: "item 2" }));
-
- test.assertEqual(menu.items.length, 3,
- "menu should have correct number of items");
- for (let i = 0; i < 3; i++) {
- test.assertEqual(menu.items[i].label, "item " + i,
- "item label should be correct");
- test.assertEqual(menu.items[i].parentMenu, menu,
- "item's parent menu should be correct");
- }
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Adding the same item twice to a menu should work as expected.
-exports.testMenuAddItemTwice = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let menu = loader.cm.Menu({
- label: "menu",
- items: []
- });
- let subitem = loader.cm.Item({ label: "item 1" })
- menu.addItem(subitem);
- menu.addItem(loader.cm.Item({ label: "item 0" }));
- menu.addItem(subitem);
-
- test.assertEqual(menu.items.length, 2,
- "menu should have correct number of items");
- for (let i = 0; i < 2; i++) {
- test.assertEqual(menu.items[i].label, "item " + i,
- "item label should be correct");
- }
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Menu.removeItem() should work.
-exports.testMenuRemoveItem = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let subitem = loader.cm.Item({ label: "item 1" });
- let menu = loader.cm.Menu({
- label: "menu",
- items: [
- loader.cm.Item({ label: "item 0" }),
- subitem,
- loader.cm.Item({ label: "item 2" })
- ]
- });
-
- // Removing twice should be harmless.
- menu.removeItem(subitem);
- menu.removeItem(subitem);
-
- test.assertEqual(subitem.parentMenu, null,
- "item's parent menu should be correct");
-
- test.assertEqual(menu.items.length, 2,
- "menu should have correct number of items");
- test.assertEqual(menu.items[0].label, "item 0",
- "item label should be correct");
- test.assertEqual(menu.items[1].label, "item 2",
- "item label should be correct");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Adding an item currently contained in one menu to another menu should work.
-exports.testMenuItemSwap = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let subitem = loader.cm.Item({ label: "item" });
- let menu0 = loader.cm.Menu({
- label: "menu 0",
- items: [subitem]
- });
- let menu1 = loader.cm.Menu({
- label: "menu 1",
- items: []
- });
- menu1.addItem(subitem);
-
- test.assertEqual(menu0.items.length, 0,
- "menu should have correct number of items");
-
- test.assertEqual(menu1.items.length, 1,
- "menu should have correct number of items");
- test.assertEqual(menu1.items[0].label, "item",
- "item label should be correct");
-
- test.assertEqual(subitem.parentMenu, menu1,
- "item's parent menu should be correct");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu0, menu1], [], []);
- test.done();
- });
-};
-
-
-// Destroying an item should remove it from its parent menu.
-exports.testMenuItemDestroy = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let subitem = loader.cm.Item({ label: "item" });
- let menu = loader.cm.Menu({
- label: "menu",
- items: [subitem]
- });
- subitem.destroy();
-
- test.assertEqual(menu.items.length, 0,
- "menu should have correct number of items");
- test.assertEqual(subitem.parentMenu, null,
- "item's parent menu should be correct");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Setting Menu.items should work.
-exports.testMenuItemsSetter = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let menu = loader.cm.Menu({
- label: "menu",
- items: [
- loader.cm.Item({ label: "old item 0" }),
- loader.cm.Item({ label: "old item 1" })
- ]
- });
- menu.items = [
- loader.cm.Item({ label: "new item 0" }),
- loader.cm.Item({ label: "new item 1" }),
- loader.cm.Item({ label: "new item 2" })
- ];
-
- test.assertEqual(menu.items.length, 3,
- "menu should have correct number of items");
- for (let i = 0; i < 3; i++) {
- test.assertEqual(menu.items[i].label, "new item " + i,
- "item label should be correct");
- test.assertEqual(menu.items[i].parentMenu, menu,
- "item's parent menu should be correct");
- }
-
- test.showMenu(null, function (popup) {
- test.checkMenu([menu], [], []);
- test.done();
- });
-};
-
-
-// Setting Item.data should work.
-exports.testItemDataSetter = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let item = loader.cm.Item({ label: "old item 0", data: "old" });
- item.data = "new";
-
- test.assertEqual(item.data, "new", "item should have correct data");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
-};
-
-
-// Open the test doc, load the module, make sure items appear when context-
-// clicking the iframe.
-exports.testAlreadyOpenIframe = function (test) {
- test = new TestHelper(test);
- test.withTestDoc(function (window, doc) {
- let loader = test.newLoader();
- let item = new loader.cm.Item({
- label: "item"
- });
- test.showMenu(doc.getElementById("iframe"), function (popup) {
- test.checkMenu([item], [], []);
- test.done();
- });
- });
-};
-
-
-// Test image support.
-exports.testItemImage = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let imageURL = require("self").data.url("moz_favicon.ico");
- let item = new loader.cm.Item({ label: "item", image: imageURL });
- let menu = new loader.cm.Menu({ label: "menu", image: imageURL, items: [] });
-
- test.showMenu(null, function (popup) {
- test.checkMenu([item, menu], [], []);
-
- let imageURL2 = require("self").data.url("dummy.ico");
- item.image = imageURL2;
- menu.image = imageURL2;
- test.checkMenu([item, menu], [], []);
-
- item.image = null;
- menu.image = null;
- test.checkMenu([item, menu], [], []);
-
- test.done();
- });
-};
-
-
-// Menu.destroy should destroy the item tree rooted at that menu.
-exports.testMenuDestroy = function (test) {
- test = new TestHelper(test);
- let loader = test.newLoader();
-
- let menu = loader.cm.Menu({
- label: "menu",
- items: [
- loader.cm.Item({ label: "item 0" }),
- loader.cm.Menu({
- label: "item 1",
- items: [
- loader.cm.Item({ label: "subitem 0" }),
- loader.cm.Item({ label: "subitem 1" }),
- loader.cm.Item({ label: "subitem 2" })
- ]
- }),
- loader.cm.Item({ label: "item 2" })
- ]
- });
- menu.destroy();
-
- let numRegistryEntries = 0;
- loader.globalScope.browserManager.browserWins.forEach(function (bwin) {
- for (let itemID in bwin.items)
- numRegistryEntries++;
- });
- test.assertEqual(numRegistryEntries, 0, "All items should be unregistered.");
-
- test.showMenu(null, function (popup) {
- test.checkMenu([], [], [menu]);
- test.done();
- });
-};
-
-
-// NO TESTS BELOW THIS LINE! ///////////////////////////////////////////////////
-
-// Run only a dummy test if context-menu doesn't support the host app.
-if (!require("xul-app").is("Firefox")) {
- for (let [prop, val] in Iterator(exports))
- if (/^test/.test(prop) && typeof(val) === "function")
- delete exports[prop];
- exports.testAppNotSupported = function (test) {
- test.pass("context-menu does not support this application.");
- };
-}
-
-
-// This makes it easier to run tests by handling things like opening the menu,
-// opening new windows, making assertions, etc. Methods on |test| can be called
-// on instances of this class. Don't forget to call done() to end the test!
-// WARNING: This looks up items in popups by comparing labels, so don't give two
-// items the same label.
-function TestHelper(test) {
- // default waitUntilDone timeout is 10s, which is too short on the win7
- // buildslave
- test.waitUntilDone(30*1000);
- this.test = test;
- this.loaders = [];
- this.browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator).
- getMostRecentWindow("navigator:browser");
-}
-
-TestHelper.prototype = {
- get contextMenuPopup() {
- return this.browserWindow.document.getElementById("contentAreaContextMenu");
- },
-
- get contextMenuSeparator() {
- return this.browserWindow.document.getElementById(SEPARATOR_ID);
- },
-
- get overflowPopup() {
- return this.browserWindow.document.getElementById(OVERFLOW_POPUP_ID);
- },
-
- get overflowSubmenu() {
- return this.browserWindow.document.getElementById(OVERFLOW_MENU_ID);
- },
-
- get tabBrowser() {
- return this.browserWindow.gBrowser;
- },
-
- // Methods on the wrapped test can be called on this object.
- __noSuchMethod__: function (methodName, args) {
- this.test[methodName].apply(this.test, args);
- },
-
- // Asserts that absentItems -- an array of items that should not match the
- // current context -- aren't present in the menu.
- checkAbsentItems: function (presentItems, absentItems) {
- for (let i = 0; i < absentItems.length; i++) {
- let item = absentItems[i];
- let elt = this.getItemElt(this.contextMenuPopup, item);
-
- // The implementation actually hides items rather than removing or not
- // adding them in the first place, but that's an implementation detail.
- this.test.assert(!elt || elt.hidden,
- "Item should not be present in top-level menu");
-
- if (this.shouldOverflow(presentItems)) {
- elt = getItemElt(this.overflowPopup, item);
- this.test.assert(!elt || elt.hidden,
- "Item should not be present in overflow submenu");
- }
- }
- },
-
- // Asserts that elt, a DOM element representing item, looks OK.
- checkItemElt: function (elt, item) {
- let itemType = this.getItemType(item);
-
- switch (itemType) {
- case "Item":
- this.test.assertEqual(elt.localName, "menuitem",
- "Item DOM element should be a xul:menuitem");
- if (typeof(item.data) === "string") {
- this.test.assertEqual(elt.getAttribute("value"), item.data,
- "Item should have correct data");
- }
- break
- case "Menu":
- this.test.assertEqual(elt.localName, "menu",
- "Menu DOM element should be a xul:menu");
- let subPopup = elt.firstChild;
- this.test.assert(subPopup, "xul:menu should have a child");
- this.test.assertEqual(subPopup.localName, "menupopup",
- "xul:menu's first child should be a menupopup");
- break;
- case "Separator":
- this.test.assertEqual(elt.localName, "menuseparator",
- "Separator DOM element should be a xul:menuseparator");
- break;
- }
-
- if (itemType === "Item" || itemType === "Menu") {
- this.test.assertEqual(elt.getAttribute("label"), item.label,
- "Item should have correct title");
- if (typeof(item.image) === "string")
- this.test.assertEqual(elt.getAttribute("image"), item.image,
- "Item should have correct image");
- else
- this.test.assert(!elt.hasAttribute("image"),
- "Item should not have image");
- }
- },
-
- // Asserts that the context menu looks OK given the arguments. presentItems
- // are items that should match the current context. absentItems are items
- // that shouldn't. removedItems are items that have been removed from the
- // menu.
- checkMenu: function (presentItems, absentItems, removedItems) {
- this.checkSeparator(presentItems);
- this.checkOverflow(presentItems);
- this.checkPresentItems(presentItems);
- this.checkAbsentItems(presentItems, absentItems);
- this.checkRemovedItems(removedItems);
- this.checkSort(presentItems);
- },
-
- // Asserts that the overflow submenu is present or absent as appropriate for
- // presentItems.
- checkOverflow: function (presentItems) {
- let submenu = this.overflowSubmenu;
- if (this.shouldOverflow(presentItems)) {
- this.test.assert(submenu && !submenu.hidden,
- "Overflow submenu should be present");
- this.test.assert(submenu.localName, "menu",
- "Overflow submenu should be a <menu>");
- let overflowPopup = this.overflowPopup;
- this.test.assert(overflowPopup,
- "Overflow submenu popup should be present");
- this.test.assert(overflowPopup.localName, "menupopup",
- "Overflow submenu popup should be a <menupopup>");
- }
- else {
- this.test.assert(!submenu || submenu.hidden,
- "Overflow submenu should be absent");
- }
- },
-
- // Asserts that the items that are present in the menu because they match the
- // current context look OK.
- checkPresentItems: function (presentItems) {
- function recurse(popup, items, isTopLevel) {
- items.forEach(function (item) {
- let elt = this.getItemElt(popup, item);
-
- if (isTopLevel) {
- if (this.shouldOverflow(items)) {
- this.test.assert(!elt || elt.hidden,
- "Item should not be present in top-level menu");
-
- let overflowPopup = this.overflowPopup;
- this.test.assert(overflowPopup,
- "Overflow submenu should be present");
-
- elt = this.getItemElt(overflowPopup, item);
- this.test.assert(elt && !elt.hidden,
- "Item should be present in overflow submenu");
- }
- else {
- this.test.assert(elt && !elt.hidden,
- "Item should be present in top-level menu");
- }
- }
- else {
- this.test.assert(elt && !elt.hidden,
- "Item should be present in menu");
- }
-
- this.checkItemElt(elt, item);
- if (this.getItemType(item) === "Menu")
- recurse.call(this, elt.firstChild, item.items, false);
- }, this);
- }
-
- recurse.call(this, this.contextMenuPopup, presentItems, true);
- },
-
- // Asserts that items that have been removed from the menu are really removed.
- checkRemovedItems: function (removedItems) {
- for (let i = 0; i < removedItems.length; i++) {
- let item = removedItems[i];
-
- let elt = this.getItemElt(this.contextMenuPopup, item);
- this.test.assert(!elt, "Item should be removed from top-level menu");
-
- let overflowPopup = this.overflowPopup;
- if (overflowPopup) {
- elt = this.getItemElt(overflowPopup, item);
- this.test.assert(!elt, "Item should be removed from overflow submenu");
- }
- }
- },
-
- // Asserts that the menu separator separating standard items from our items
- // looks OK.
- checkSeparator: function (presentItems) {
- let sep = this.contextMenuSeparator;
- if (presentItems.length) {
- this.test.assert(sep && !sep.hidden, "Menu separator should be present");
- this.test.assertEqual(sep.localName, "menuseparator",
- "Menu separator should be a <menuseparator>");
- }
- else {
- this.test.assert(!sep || sep.hidden, "Menu separator should be absent");
- }
- },
-
- // Asserts that our items are sorted.
- checkSort: function (presentItems) {
- // Get the first item in sorted order, get its elt, walk the nextSibling
- // chain, making sure each is greater than the previous.
- if (presentItems.length) {
- let sorted = presentItems.slice(0).
- sort(function (a, b) a.label.localeCompare(b.label));
- let elt = this.shouldOverflow(presentItems) ?
- this.getItemElt(this.overflowPopup, sorted[0]) :
- this.getItemElt(this.contextMenuPopup, sorted[0]);
- let numElts = 1;
- while (elt.nextSibling &&
- elt.nextSibling.className.split(/\s+/).indexOf(ITEM_CLASS) >= 0) {
- let eltLabel = elt.getAttribute("label");
- let nextLabel = elt.nextSibling.getAttribute("label");
- this.test.assert(eltLabel.localeCompare(nextLabel) < 0,
- "Item label should be < next item's label");
- elt = elt.nextSibling;
- numElts++;
- }
- this.test.assertEqual(numElts, presentItems.length,
- "The first item in sorted order should have the " +
- "first element in sorted order");
- }
- },
-
- // Attaches an event listener to node. The listener is automatically removed
- // when it's fired (so it's assumed it will fire), and callback is called
- // after a short delay. Since the module we're testing relies on the same
- // event listeners to do its work, this is to give them a little breathing
- // room before callback runs. Inside callback |this| is this object.
- delayedEventListener: function (node, event, callback, useCapture) {
- const self = this;
- node.addEventListener(event, function handler(evt) {
- node.removeEventListener(event, handler, useCapture);
- require("timer").setTimeout(function () {
- try {
- callback.call(self, evt);
- }
- catch (err) {
- self.test.exception(err);
- self.test.done();
- }
- }, 20);
- }, useCapture);
- },
-
- // Call to finish the test.
- done: function () {
- function commonDone() {
- if (this.tab) {
- this.tabBrowser.removeTab(this.tab);
- this.tabBrowser.selectedTab = this.oldSelectedTab;
- }
- while (this.loaders.length) {
- let browserManager = this.loaders[0].globalScope.browserManager;
- let topLevelItems = browserManager.topLevelItems.slice();
- let privatePropsKey = this.loaders[0].globalScope.PRIVATE_PROPS_KEY;
- let workerRegs = topLevelItems.map(function (item) {
- return item.valueOf(privatePropsKey)._workerReg;
- });
-
- this.loaders[0].unload();
-
- // Make sure the browser manager is cleaned up.
- this.test.assertEqual(browserManager.browserWins.length, 0,
- "browserManager should have no windows left");
- this.test.assertEqual(browserManager.topLevelItems.length, 0,
- "browserManager should have no items left");
- this.test.assert(!("contentWins" in browserManager),
- "browserManager should have no content windows left");
-
- // Make sure the items' worker registries are cleaned up.
- topLevelItems.forEach(function (item) {
- this.test.assert(!("_workerReg" in item.valueOf(privatePropsKey)),
- "item's worker registry should be removed");
- }, this);
- workerRegs.forEach(function (workerReg) {
- this.test.assertEqual(Object.keys(workerReg.winWorkers).length, 0,
- "worker registry should be empty");
- this.test.assertEqual(
- Object.keys(workerReg.winsWithoutWorkers).length, 0,
- "worker registry list of windows without workers should be empty");
- }, this);
- }
- this.test.done();
- }
-
- function closeBrowserWindow() {
- if (this.oldBrowserWindow) {
- this.delayedEventListener(this.browserWindow, "unload", commonDone,
- false);
- this.browserWindow.close();
- this.browserWindow = this.oldBrowserWindow;
- delete this.oldBrowserWindow;
- }
- else {
- commonDone.call(this);
- }
- };
-
- if (this.contextMenuPopup.state == "closed") {
- closeBrowserWindow.call(this);
- }
- else {
- this.delayedEventListener(this.contextMenuPopup, "popuphidden",
- function () closeBrowserWindow.call(this),
- false);
- this.contextMenuPopup.hidePopup();
- }
- },
-
- // Returns the DOM element in popup corresponding to item.
- // WARNING: The element is found by comparing labels, so don't give two items
- // the same label.
- getItemElt: function (popup, item) {
- let nodes = popup.childNodes;
- for (let i = nodes.length - 1; i >= 0; i--) {
- if (this.getItemType(item) === "Separator") {
- if (nodes[i].localName === "menuseparator")
- return nodes[i];
- }
- else if (nodes[i].getAttribute("label") === item.label)
- return nodes[i];
- }
- return null;
- },
-
- // Returns "Item", "Menu", or "Separator".
- getItemType: function (item) {
- // Could use instanceof here, but that would require accessing the loader
- // that created the item, and I don't want to A) somehow search through the
- // this.loaders list to find it, and B) assume there are any live loaders at
- // all.
- return /^\[object (Item|Menu|Separator)/.exec(item.toString())[1];
- },
-
- // Returns a wrapper around a new loader: { loader, cm, unload, globalScope }.
- // loader is a Cuddlefish sandboxed loader, cm is the context menu module,
- // globalScope is the context menu module's global scope, and unload is a
- // function that unloads the loader and associated resources.
- newLoader: function () {
- const self = this;
- let loader = Loader(module);
- let wrapper = {
- loader: loader,
- cm: loader.require("context-menu"),
- globalScope: loader.sandbox("context-menu"),
- unload: function () {
- loader.unload();
- let idx = self.loaders.indexOf(wrapper);
- if (idx < 0)
- throw new Error("Test error: tried to unload nonexistent loader");
- self.loaders.splice(idx, 1);
- }
- };
- this.loaders.push(wrapper);
- return wrapper;
- },
-
- // Returns true if the number of presentItems crosses the overflow threshold.
- shouldOverflow: function (presentItems) {
- return presentItems.length >
- (this.loaders.length ?
- this.loaders[0].loader.require("preferences-service").
- get(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT) :
- OVERFLOW_THRESH_DEFAULT);
- },
-
- // Opens the context menu on the current page. If targetNode is null, the
- // menu is opened in the top-left corner. onShowncallback is passed the
- // popup.
- showMenu: function(targetNode, onshownCallback) {
- function sendEvent() {
- this.delayedEventListener(this.browserWindow, "popupshowing",
- function (e) {
- let popup = e.target;
- onshownCallback.call(this, popup);
- }, false);
-
- let rect = targetNode ?
- targetNode.getBoundingClientRect() :
- { left: 0, top: 0, width: 0, height: 0 };
- let contentWin = this.browserWindow.content;
- contentWin.
- QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils).
- sendMouseEvent("contextmenu",
- rect.left + (rect.width / 2),
- rect.top + (rect.height / 2),
- 2, 1, 0);
- }
-
- // If a new tab or window has not yet been opened, open a new tab now. For
- // some reason using the tab already opened when the test starts causes
- // leaks. See bug 566351 for details.
- if (!targetNode && !this.oldSelectedTab && !this.oldBrowserWindow) {
- this.oldSelectedTab = this.tabBrowser.selectedTab;
- this.tab = this.tabBrowser.addTab("about:blank");
- let browser = this.tabBrowser.getBrowserForTab(this.tab);
-
- this.delayedEventListener(browser, "load", function () {
- this.tabBrowser.selectedTab = this.tab;
- sendEvent.call(this);
- }, true);
- }
- else
- sendEvent.call(this);
- },
-
- // Opens a new browser window. The window will be closed automatically when
- // done() is called.
- withNewWindow: function (onloadCallback) {
- let win = this.browserWindow.OpenBrowserWindow();
- this.delayedEventListener(win, "load", onloadCallback, true);
- this.oldBrowserWindow = this.browserWindow;
- this.browserWindow = win;
- },
-
- // Opens a new tab with our test page in the current window. The tab will
- // be closed automatically when done() is called.
- withTestDoc: function (onloadCallback) {
- this.oldSelectedTab = this.tabBrowser.selectedTab;
- this.tab = this.tabBrowser.addTab(TEST_DOC_URL);
- let browser = this.tabBrowser.getBrowserForTab(this.tab);
-
- this.delayedEventListener(browser, "load", function () {
- this.tabBrowser.selectedTab = this.tab;
- onloadCallback.call(this, browser.contentWindow, browser.contentDocument);
- }, true);
- }
-};
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-hotkeys.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-hotkeys.js
deleted file mode 100644
index 3b69a28..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-hotkeys.js
+++ /dev/null
@@ -1,156 +0,0 @@
-"use strict";
-
-const { Hotkey } = require("hotkeys");
-const { keyDown } = require("dom/events/keys");
-const { Loader } = require('./helpers');
-
-exports["test hotkey: function key"] = function(assert, done) {
- var element = require("window-utils").activeBrowserWindow.document.documentElement;
- var showHotKey = Hotkey({
- combo: "f1",
- onPress: function() {
- assert.pass("first callback is called");
- keyDown(element, "f2");
- showHotKey.destroy();
- }
- });
-
- var hideHotKey = Hotkey({
- combo: "f2",
- onPress: function() {
- assert.pass("second callback is called");
- hideHotKey.destroy();
- done();
- }
- });
-
- keyDown(element, "f1");
-};
-
-exports["test hotkey: accel alt shift"] = function(assert, done) {
- var element = require("window-utils").activeBrowserWindow.document.documentElement;
- var showHotKey = Hotkey({
- combo: "accel-shift-6",
- onPress: function() {
- assert.pass("first callback is called");
- keyDown(element, "accel-alt-shift-6");
- showHotKey.destroy();
- }
- });
-
- var hideHotKey = Hotkey({
- combo: "accel-alt-shift-6",
- onPress: function() {
- assert.pass("second callback is called");
- hideHotKey.destroy();
- done();
- }
- });
-
- keyDown(element, "accel-shift-6");
-};
-
-exports["test hotkey meta & control"] = function(assert, done) {
- var element = require("window-utils").activeBrowserWindow.document.documentElement;
- var showHotKey = Hotkey({
- combo: "meta-3",
- onPress: function() {
- assert.pass("first callback is called");
- keyDown(element, "alt-control-shift-b");
- showHotKey.destroy();
- }
- });
-
- var hideHotKey = Hotkey({
- combo: "Ctrl-Alt-Shift-B",
- onPress: function() {
- assert.pass("second callback is called");
- hideHotKey.destroy();
- done();
- }
- });
-
- keyDown(element, "meta-3");
-};
-
-exports["test hotkey: control-1 / meta--"] = function(assert, done) {
- var element = require("window-utils").activeBrowserWindow.document.documentElement;
- var showHotKey = Hotkey({
- combo: "control-1",
- onPress: function() {
- assert.pass("first callback is called");
- keyDown(element, "meta--");
- showHotKey.destroy();
- }
- });
-
- var hideHotKey = Hotkey({
- combo: "meta--",
- onPress: function() {
- assert.pass("second callback is called");
- hideHotKey.destroy();
- done();
- }
- });
-
- keyDown(element, "control-1");
-};
-
-exports["test invalid combos"] = function(assert) {
- assert.throws(function() {
- Hotkey({
- combo: "d",
- onPress: function() {}
- });
- }, "throws if no modifier is present");
- assert.throws(function() {
- Hotkey({
- combo: "alt",
- onPress: function() {}
- });
- }, "throws if no key is present");
- assert.throws(function() {
- Hotkey({
- combo: "alt p b",
- onPress: function() {}
- });
- }, "throws if more then one key is present");
-};
-
-exports["test no exception on unmodified keypress"] = function(assert) {
- var element = require("window-utils").activeBrowserWindow.document.documentElement;
- var someHotkey = Hotkey({
- combo: "control-alt-1",
- onPress: function() {
- }
- });
- keyDown(element, "a");
- assert.pass("No exception throw, unmodified keypress passed");
-};
-
-exports["test hotkey: automatic destroy"] = function(assert, done) {
- // Hacky way to be able to create unloadable modules via makeSandboxedLoader.
- let loader = Loader(module);
-
- var called = false;
- var element = loader.require("window-utils").activeBrowserWindow.document.documentElement;
- var hotkey = loader.require("hotkeys").Hotkey({
- combo: "accel-shift-x",
- onPress: function() {
- called = true;
- }
- });
-
- // Unload the module so that previous hotkey is automatically destroyed
- loader.unload();
-
- // Ensure that the hotkey is really destroyed
- keyDown(element, "accel-shift-x");
-
- require("timer").setTimeout(function () {
- assert.ok(!called, "Hotkey is destroyed and not called.");
- done();
- }, 0);
-};
-
-require("test").run(exports);
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-module.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-module.js
deleted file mode 100644
index c62f923..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-module.js
+++ /dev/null
@@ -1,33 +0,0 @@
-"use strict";
-
-/** Disabled because of Bug 672199
-exports["test module exports are frozen"] = function(assert) {
- assert.ok(Object.isFrozen(require("addon-kit/hotkeys")),
- "module exports are frozen");
-};
-
-exports["test redefine exported property"] = function(assert) {
- let hotkeys = require("addon-kit/hotkeys");
- let { Hotkey } = hotkeys;
- try { Object.defineProperty(hotkeys, 'Hotkey', { value: {} }); } catch(e) {}
- assert.equal(hotkeys.Hotkey, Hotkey, "exports can't be redefined");
-};
-*/
-
-exports["test can't delete exported property"] = function(assert) {
- let hotkeys = require("addon-kit/hotkeys");
- let { Hotkey } = hotkeys;
-
- try { delete hotkeys.Hotkey; } catch(e) {}
- assert.equal(hotkeys.Hotkey, Hotkey, "exports can't be deleted");
-};
-
-exports["test can't override exported property"] = function(assert) {
- let hotkeys = require("addon-kit/hotkeys");
- let { Hotkey } = hotkeys;
-
- try { hotkeys.Hotkey = Object } catch(e) {}
- assert.equal(hotkeys.Hotkey, Hotkey, "exports can't be overriden");
-};
-
-require("test").run(exports);
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-notifications.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-notifications.js
deleted file mode 100644
index 1eb6190..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-notifications.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Drew Willcoxon <adw@mozilla.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const { Loader } = require('./helpers');
-
-exports.testOnClick = function (test) {
- let [loader, mockAlertServ] = makeLoader(module);
- let notifs = loader.require("notifications");
- let data = "test data";
- let opts = {
- onClick: function (clickedData) {
- test.assertEqual(this, notifs, "|this| should be notifications module");
- test.assertEqual(clickedData, data,
- "data passed to onClick should be correct");
- },
- data: data,
- title: "test title",
- text: "test text",
- iconURL: "test icon URL"
- };
- notifs.notify(opts);
- mockAlertServ.click();
- loader.unload();
-};
-
-// Returns [loader, mockAlertService].
-function makeLoader(test) {
- let loader = Loader(module);
- let mockAlertServ = {
- showAlertNotification: function (imageUrl, title, text, textClickable,
- cookie, alertListener, name) {
- this._cookie = cookie;
- this._alertListener = alertListener;
- },
- click: function () {
- this._alertListener.observe(null, "alertclickcallback", this._cookie);
- }
- };
- loader.require("notifications");
- let scope = loader.sandbox("notifications");
- scope.notify = mockAlertServ.showAlertNotification.bind(mockAlertServ);
- return [loader, mockAlertServ];
-};
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-mod.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-mod.js
deleted file mode 100644
index 2b38946..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-mod.js
+++ /dev/null
@@ -1,416 +0,0 @@
-"use strict";
-
-var pageMod = require("page-mod");
-var testPageMod = require("pagemod-test-helpers").testPageMod;
-const { Loader } = require('./helpers');
-const tabs = require("tabs");
-
-/* XXX This can be used to delay closing the test Firefox instance for interactive
- * testing or visual inspection. This test is registered first so that it runs
- * the last. */
-exports.delay = function(test) {
- if (false) {
- test.waitUntilDone(60000);
- require("timer").setTimeout(function() {test.done();}, 4000);
- } else
- test.pass();
-}
-
-/* Tests for the PageMod APIs */
-
-exports.testPageMod1 = function(test) {
- let mods = testPageMod(test, "about:", [{
- include: /about:/,
- contentScriptWhen: 'end',
- contentScript: 'new ' + function WorkerScope() {
- window.document.body.setAttribute("JEP-107", "worked");
- },
- onAttach: function() {
- test.assertEqual(this, mods[0], "The 'this' object is the page mod.");
- }
- }],
- function(win, done) {
- test.assertEqual(
- win.document.body.getAttribute("JEP-107"),
- "worked",
- "PageMod.onReady test"
- );
- done();
- }
- );
-};
-
-exports.testPageMod2 = function(test) {
- testPageMod(test, "about:", [{
- include: "about:*",
- contentScript: [
- 'new ' + function contentScript() {
- window.AUQLUE = function() { return 42; }
- try {
- window.AUQLUE()
- }
- catch(e) {
- throw new Error("PageMod scripts executed in order");
- }
- document.documentElement.setAttribute("first", "true");
- },
- 'new ' + function contentScript() {
- document.documentElement.setAttribute("second", "true");
- }
- ]
- }], function(win, done) {
- test.assertEqual(win.document.documentElement.getAttribute("first"),
- "true",
- "PageMod test #2: first script has run");
- test.assertEqual(win.document.documentElement.getAttribute("second"),
- "true",
- "PageMod test #2: second script has run");
- test.assertEqual("AUQLUE" in win, false,
- "PageMod test #2: scripts get a wrapped window");
- done();
- });
-};
-
-exports.testPageModIncludes = function(test) {
- var asserts = [];
- function createPageModTest(include, expectedMatch) {
- // Create an 'onload' test function...
- asserts.push(function(test, win) {
- var matches = include in win.localStorage;
- test.assert(expectedMatch ? matches : !matches,
- "'" + include + "' match test, expected: " + expectedMatch);
- });
- // ...and corresponding PageMod options
- return {
- include: include,
- contentScript: 'new ' + function() {
- self.on("message", function(msg) {
- window.localStorage[msg] = true;
- });
- },
- // The testPageMod callback with test assertions is called on 'end',
- // and we want this page mod to be attached before it gets called,
- // so we attach it on 'start'.
- contentScriptWhen: 'start',
- onAttach: function(worker) {
- worker.postMessage(this.include[0]);
- }
- };
- }
-
- testPageMod(test, "about:buildconfig", [
- createPageModTest("*", false),
- createPageModTest("*.google.com", false),
- createPageModTest("about:*", true),
- createPageModTest("about:", false),
- createPageModTest("about:buildconfig", true)
- ],
- function (win, done) {
- test.waitUntil(function () win.localStorage["about:buildconfig"],
- "about:buildconfig page-mod to be executed")
- .then(function () {
- asserts.forEach(function(fn) {
- fn(test, win);
- });
- done();
- });
- }
- );
-};
-
-exports.testPageModErrorHandling = function(test) {
- test.assertRaises(function() {
- new pageMod.PageMod();
- },
- 'pattern is undefined',
- "PageMod() throws when 'include' option is not specified.");
-};
-
-/* Tests for internal functions. */
-exports.testCommunication1 = function(test) {
- let workerDone = false,
- callbackDone = null;
-
- testPageMod(test, "about:", [{
- include: "about:*",
- contentScriptWhen: 'end',
- contentScript: 'new ' + function WorkerScope() {
- self.on('message', function(msg) {
- document.body.setAttribute('JEP-107', 'worked');
- self.postMessage(document.body.getAttribute('JEP-107'));
- })
- },
- onAttach: function(worker) {
- worker.on('error', function(e) {
- test.fail('Errors where reported');
- });
- worker.on('message', function(value) {
- test.assertEqual(
- "worked",
- value,
- "test comunication"
- );
- workerDone = true;
- if (callbackDone)
- callbackDone();
- });
- worker.postMessage('do it!')
- }
- }],
- function(win, done) {
- (callbackDone = function() {
- if (workerDone) {
- test.assertEqual(
- 'worked',
- win.document.body.getAttribute('JEP-107'),
- 'attribute should be modified'
- );
- done();
- }
- })();
- }
- );
-};
-
-exports.testCommunication2 = function(test) {
- let callbackDone = null,
- window;
-
- testPageMod(test, "about:", [{
- include: "about:*",
- contentScriptWhen: 'start',
- contentScript: 'new ' + function WorkerScope() {
- document.documentElement.setAttribute('AUQLUE', 42);
- window.addEventListener('load', function listener() {
- self.postMessage('onload');
- }, false);
- self.on("message", function() {
- self.postMessage(document.documentElement.getAttribute("test"))
- });
- },
- onAttach: function(worker) {
- worker.on('error', function(e) {
- test.fail('Errors where reported');
- });
- worker.on('message', function(msg) {
- if ('onload' == msg) {
- test.assertEqual(
- '42',
- window.document.documentElement.getAttribute('AUQLUE'),
- 'PageMod scripts executed in order'
- );
- window.document.documentElement.setAttribute('test', 'changes in window');
- worker.postMessage('get window.test')
- } else {
- test.assertEqual(
- 'changes in window',
- msg,
- 'PageMod test #2: second script has run'
- )
- callbackDone();
- }
- });
- }
- }],
- function(win, done) {
- window = win;
- callbackDone = done;
- }
- );
-};
-
-exports.testEventEmitter = function(test) {
- let workerDone = false,
- callbackDone = null;
-
- testPageMod(test, "about:", [{
- include: "about:*",
- contentScript: 'new ' + function WorkerScope() {
- self.port.on('addon-to-content', function(data) {
- self.port.emit('content-to-addon', data);
- });
- },
- onAttach: function(worker) {
- worker.on('error', function(e) {
- test.fail('Errors were reported : '+e);
- });
- worker.port.on('content-to-addon', function(value) {
- test.assertEqual(
- "worked",
- value,
- "EventEmitter API works!"
- );
- if (callbackDone)
- callbackDone();
- else
- workerDone = true;
- });
- worker.port.emit('addon-to-content', 'worked');
- }
- }],
- function(win, done) {
- if (workerDone)
- done();
- else
- callbackDone = done;
- }
- );
-};
-
-// Execute two concurrent page mods on same document to ensure that their
-// JS contexts are different
-exports.testMixedContext = function(test) {
- let doneCallback = null;
- let messages = 0;
- let modObject = {
- include: "data:text/html,",
- contentScript: 'new ' + function WorkerScope() {
- // Both scripts will execute this,
- // context is shared if one script see the other one modification.
- let isContextShared = "sharedAttribute" in document;
- self.postMessage(isContextShared);
- document.sharedAttribute = true;
- },
- onAttach: function(w) {
- w.on("message", function (isContextShared) {
- if (isContextShared) {
- test.fail("Page mod contexts are mixed.");
- doneCallback();
- }
- else if (++messages == 2) {
- test.pass("Page mod contexts are different.");
- doneCallback();
- }
- });
- }
- };
- testPageMod(test, "data:text/html,", [modObject, modObject],
- function(win, done) {
- doneCallback = done;
- }
- );
-};
-
-exports.testHistory = function(test) {
- // We need a valid url in order to have a working History API.
- // (i.e do not work on data: or about: pages)
- // Test bug 679054.
- let url = require("self").data.url("test-page-mod.html");
- let callbackDone = null;
- testPageMod(test, url, [{
- include: url,
- contentScriptWhen: 'end',
- contentScript: 'new ' + function WorkerScope() {
- history.pushState({}, "", "#");
- history.replaceState({foo: "bar"}, "", "#");
- self.postMessage(history.state);
- },
- onAttach: function(worker) {
- worker.on('message', function (data) {
- test.assertEqual(JSON.stringify(data), JSON.stringify({foo: "bar"}),
- "History API works!");
- callbackDone();
- });
- }
- }],
- function(win, done) {
- callbackDone = done;
- }
- );
-};
-
-exports.testRelatedTab = function(test) {
- test.waitUntilDone();
-
- let tab;
- let { PageMod } = require("page-mod");
- let pageMod = new PageMod({
- include: "about:*",
- onAttach: function(worker) {
- test.assertEqual(tab, worker.tab, "Worker.tab is valid");
- pageMod.destroy();
- tab.close();
- test.done();
- }
- });
-
- tabs.open({
- url: "about:",
- onOpen: function onOpen(t) {
- tab = t;
- }
- });
-
-};
-
-exports['test tab worker on message'] = function(test) {
- test.waitUntilDone();
-
- let { browserWindows } = require("windows");
- let tabs = require("tabs");
- let { PageMod } = require("page-mod");
-
- let url1 = "data:text/html,<title>tab1</title><h1>worker1.tab</h1>";
- let url2 = "data:text/html,<title>tab2</title><h1>worker2.tab</h1>";
- let worker1 = null;
-
- let mod = PageMod({
- include: "data:text/html,*",
- contentScriptWhen: "ready",
- contentScript: "self.postMessage('#1');",
- onAttach: function onAttach(worker) {
- worker.on("message", function onMessage() {
- this.tab.attach({
- contentScriptWhen: "ready",
- contentScript: "self.postMessage({ url: window.location.href, title: document.title });",
- onMessage: function onMessage(data) {
- test.assertEqual(this.tab.url, data.url, "location is correct");
- test.assertEqual(this.tab.title, data.title, "title is correct");
- if (this.tab.url === url1) {
- worker1 = this;
- tabs.open({ url: url2, inBackground: true });
- }
- else if (this.tab.url === url2) {
- mod.destroy();
- worker1.tab.close();
- worker1.destroy();
- worker.tab.close();
- worker.destroy();
- test.done();
- }
- }
- });
- });
- }
- });
-
- tabs.open(url1);
-};
-
-exports.testAutomaticDestroy = function(test) {
- test.waitUntilDone();
- let loader = Loader(module);
-
- let pageMod = loader.require("page-mod").PageMod({
- include: "about:*",
- contentScriptWhen: "start",
- onAttach: function(w) {
- test.fail("Page-mod should have been detroyed during module unload");
- }
- });
-
- // Unload the page-mod module so that our page mod is destroyed
- loader.unload();
-
- // Then create a second tab to ensure that it is correctly destroyed
- let tabs = require("tabs");
- tabs.open({
- url: "about:",
- onReady: function onReady(tab) {
- test.pass("check automatic destroy");
- tab.close();
- test.done();
- }
- });
-
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-worker.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-worker.js
deleted file mode 100644
index 89cdf45..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-page-worker.js
+++ /dev/null
@@ -1,362 +0,0 @@
-let tests = {}, Pages, Page;
-const { Loader } = require('./helpers');
-
-const ERR_DESTROYED =
- "The page has been destroyed and can no longer be used.";
-
-tests.testSimplePageCreation = function(test) {
- test.waitUntilDone();
-
- let page = new Page({
- contentScript: "self.postMessage(window.location.href)",
- contentScriptWhen: "end",
- onMessage: function (message) {
- test.assertEqual(message, "about:blank",
- "Page Worker should start with a blank page by default");
- test.assertEqual(this, page, "The 'this' object is the page itself.");
- test.done();
- }
- });
-}
-
-/*
- * Tests that we can't be tricked by document overloads as we have access
- * to wrapped nodes
- */
-tests.testWrappedDOM = function(test) {
- test.waitUntilDone();
-
- let page = Page({
- allow: { script: true },
- contentURL: "data:text/html,<script>document.getElementById=3;window.scrollTo=3;</script>",
- contentScript: "window.addEventListener('load', function () " +
- "self.postMessage([typeof(document.getElementById), " +
- "typeof(window.scrollTo)]), true)",
- onMessage: function (message) {
- test.assertEqual(message[0],
- "function",
- "getElementById from content script is the native one");
-
- test.assertEqual(message[1],
- "function",
- "scrollTo from content script is the native one");
-
- test.done();
- }
- });
-}
-
-/*
-// We do not offer unwrapped access to DOM since bug 601295 landed
-// See 660780 to track progress of unwrap feature
-tests.testUnwrappedDOM = function(test) {
- test.waitUntilDone();
-
- let page = Page({
- allow: { script: true },
- contentURL: "data:text/html,<script>document.getElementById=3;window.scrollTo=3;</script>",
- contentScript: "window.addEventListener('load', function () " +
- "self.postMessage([typeof(unsafeWindow.document.getElementById), " +
- "typeof(unsafeWindow.scrollTo)]), true)",
- onMessage: function (message) {
- test.assertEqual(message[0],
- "number",
- "document inside page is free to be changed");
-
- test.assertEqual(message[1],
- "number",
- "window inside page is free to be changed");
-
- test.done();
- }
- });
-}
-*/
-
-tests.testPageProperties = function(test) {
- let page = new Page();
-
- for each (let prop in ['contentURL', 'allow', 'contentScriptFile',
- 'contentScript', 'contentScriptWhen', 'on',
- 'postMessage', 'removeListener']) {
- test.assert(prop in page, prop + " property is defined on page.");
- }
-
- test.assert(function () page.postMessage("foo") || true,
- "postMessage doesn't throw exception on page.");
-}
-
-tests.testConstructorAndDestructor = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let Pages = loader.require("page-worker");
- let global = loader.sandbox("page-worker");
-
- let pagesReady = 0;
-
- let page1 = Pages.Page({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- onMessage: pageReady
- });
- let page2 = Pages.Page({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- onMessage: pageReady
- });
-
- test.assertNotEqual(page1, page2,
- "Page 1 and page 2 should be different objects.");
-
- function pageReady() {
- if (++pagesReady == 2) {
- page1.destroy();
- page2.destroy();
-
- test.assert(isDestroyed(page1), "page1 correctly unloaded.");
- test.assert(isDestroyed(page2), "page2 correctly unloaded.");
-
- loader.unload();
- test.done();
- }
- }
-}
-
-tests.testAutoDestructor = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let Pages = loader.require("page-worker");
-
- let page = Pages.Page({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- onMessage: function() {
- loader.unload();
- test.assert(isDestroyed(page), "Page correctly unloaded.");
- test.done();
- }
- });
-}
-
-tests.testValidateOptions = function(test) {
- test.assertRaises(
- function () Page({ contentURL: 'home' }),
- "The `contentURL` option must be a valid URL.",
- "Validation correctly denied a non-URL contentURL"
- );
-
- test.assertRaises(
- function () Page({ onMessage: "This is not a function."}),
- "The event listener must be a function.",
- "Validation correctly denied a non-function onMessage."
- );
-
- test.pass("Options validation is working.");
-}
-
-tests.testContentAndAllowGettersAndSetters = function(test) {
- test.waitUntilDone();
- let content = "data:text/html,<script>window.localStorage.allowScript=3;</script>";
- let page = Page({
- contentURL: content,
- contentScript: "self.postMessage(window.localStorage.allowScript)",
- contentScriptWhen: "end",
- onMessage: step0
- });
-
- function step0(message) {
- test.assertEqual(message, "3",
- "Correct value expected for allowScript - 3");
- test.assertEqual(page.contentURL, content,
- "Correct content expected");
- page.removeListener('message', step0);
- page.on('message', step1);
- page.allow = { script: false };
- page.contentURL = content =
- "data:text/html,<script>window.localStorage.allowScript='f'</script>";
- }
-
- function step1(message) {
- test.assertEqual(message, "3",
- "Correct value expected for allowScript - 3");
- test.assertEqual(page.contentURL, content, "Correct content expected");
- page.removeListener('message', step1);
- page.on('message', step2);
- page.allow = { script: true };
- page.contentURL = content =
- "data:text/html,<script>window.localStorage.allowScript='g'</script>";
- }
-
- function step2(message) {
- test.assertEqual(message, "g",
- "Correct value expected for allowScript - g");
- test.assertEqual(page.contentURL, content, "Correct content expected");
- page.removeListener('message', step2);
- page.on('message', step3);
- page.allow.script = false;
- page.contentURL = content =
- "data:text/html,<script>window.localStorage.allowScript=3</script>";
- }
-
- function step3(message) {
- test.assertEqual(message, "g",
- "Correct value expected for allowScript - g");
- test.assertEqual(page.contentURL, content, "Correct content expected");
- page.removeListener('message', step3);
- page.on('message', step4);
- page.allow.script = true;
- page.contentURL = content =
- "data:text/html,<script>window.localStorage.allowScript=4</script>";
- }
-
- function step4(message) {
- test.assertEqual(message, "4",
- "Correct value expected for allowScript - 4");
- test.assertEqual(page.contentURL, content, "Correct content expected");
- test.done();
- }
-
-}
-
-tests.testOnMessageCallback = function(test) {
- test.waitUntilDone();
-
- Page({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- onMessage: function() {
- test.pass("onMessage callback called");
- test.done();
- }
- });
-}
-
-tests.testMultipleOnMessageCallbacks = function(test) {
- test.waitUntilDone();
-
- let count = 0;
- let page = Page({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- onMessage: function() count += 1
- });
- page.on('message', function() count += 2);
- page.on('message', function() count *= 3);
- page.on('message', function()
- test.assertEqual(count, 9, "All callbacks were called, in order."));
- page.on('message', function() test.done());
-
-}
-
-tests.testLoadContentPage = function(test) {
-
- test.waitUntilDone();
-
- let page = Page({
- onMessage: function(message) {
- // The message is an array whose first item is the test method to call
- // and the rest of whose items are arguments to pass it.
- test[message.shift()].apply(test, message);
- },
- contentURL: require("self").data.url("test-page-worker.html"),
- contentScriptFile: require("self").data.url("test-page-worker.js"),
- contentScriptWhen: "ready"
- });
-
-}
-
-tests.testAllowScriptDefault = function(test) {
-
- test.waitUntilDone();
-
- let page = Page({
- onMessage: function(message) {
- test.assert(message, "Script is allowed to run by default.");
- test.done();
- },
- contentURL: "data:text/html,<script>document.documentElement.setAttribute('foo', 3);</script>",
- contentScript: "self.postMessage(document.documentElement.getAttribute('foo'))",
- contentScriptWhen: "ready"
- });
-}
-
-tests.testAllowScript = function(test) {
-
- test.waitUntilDone();
-
- let page = Page({
- onMessage: function(message) {
- test.assert(message, "Script runs when allowed to do so.");
- test.done();
- },
- allow: { script: true },
- contentURL: "data:text/html,<script>document.documentElement.setAttribute('foo', 3);</script>",
- contentScript: "self.postMessage(document.documentElement.hasAttribute('foo') && " +
- " document.documentElement.getAttribute('foo') == 3)",
- contentScriptWhen: "ready"
- });
-}
-
-tests.testPingPong = function(test) {
- test.waitUntilDone();
- let page = Page({
- contentURL: 'data:text/html,ping-pong',
- contentScript: 'self.on("message", function(message) self.postMessage("pong"));'
- + 'self.postMessage("ready");',
- onMessage: function(message) {
- if ('ready' == message) {
- page.postMessage('ping');
- }
- else {
- test.assert(message, 'pong', 'Callback from contentScript');
- test.done();
- }
- }
- });
-};
-
-tests.testMultipleDestroys = function(test) {
- let page = Page();
- page.destroy();
- page.destroy();
- test.pass("Multiple destroys should not cause an error");
-};
-
-
-function isDestroyed(page) {
- try {
- page.postMessage("foo");
- }
- catch (err if err.message == ERR_DESTROYED) {
- return true;
- }
- return false;
-}
-
-
-let pageWorkerSupported = true;
-
-try {
- Pages = require("page-worker");
- Page = Pages.Page;
-}
-catch (ex if ex.message == [
- "The page-worker module currently supports only Firefox and Thunderbird. ",
- "In the future, we would like it to support other applications, however. ",
- "Please see https://bugzilla.mozilla.org/show_bug.cgi?id=546740 for more ",
- "information."
- ].join("")) {
- pageWorkerSupported = false;
-}
-
-if (pageWorkerSupported) {
- for (let test in tests) {
- exports[test] = tests[test];
- }
-} else {
- exports.testPageWorkerNotSupported = function(test) {
- test.pass("The page-worker module is not supported on this app.");
- }
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-panel.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-panel.js
deleted file mode 100644
index 3e240db..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-panel.js
+++ /dev/null
@@ -1,437 +0,0 @@
-let { Cc, Ci } = require("chrome");
-let panels = require('panel');
-let tests = {}, panels, Panel;
-const { Loader } = require('./helpers');
-
-tests.testPanel = function(test) {
- test.waitUntilDone();
- let panel = Panel({
- contentURL: "about:buildconfig",
- contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));",
- onMessage: function (message) {
- test.assertEqual(this, panel, "The 'this' object is the panel.");
- switch(message) {
- case 1:
- test.pass("The panel was loaded.");
- panel.postMessage('');
- break;
- case 2:
- test.pass("The panel posted a message and received a response.");
- panel.destroy();
- test.done();
- break;
- }
- }
- });
-};
-
-tests.testPanelEmit = function(test) {
- test.waitUntilDone();
- let panel = Panel({
- contentURL: "about:buildconfig",
- contentScript: "self.port.emit('loaded');" +
- "self.port.on('addon-to-content', " +
- " function() self.port.emit('received'));",
- });
- panel.port.on("loaded", function () {
- test.pass("The panel was loaded and sent a first event.");
- panel.port.emit("addon-to-content");
- });
- panel.port.on("received", function () {
- test.pass("The panel posted a message and received a response.");
- panel.destroy();
- test.done();
- });
-};
-
-tests.testPanelEmitEarly = function(test) {
- test.waitUntilDone();
- let panel = Panel({
- contentURL: "about:buildconfig",
- contentScript: "self.port.on('addon-to-content', " +
- " function() self.port.emit('received'));",
- });
- panel.port.on("received", function () {
- test.pass("The panel posted a message early and received a response.");
- panel.destroy();
- test.done();
- });
- panel.port.emit("addon-to-content");
-};
-
-tests.testShowHidePanel = function(test) {
- test.waitUntilDone();
- let panel = Panel({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- onMessage: function (message) {
- panel.show();
- },
- onShow: function () {
- test.pass("The panel was shown.");
- test.assertEqual(this, panel, "The 'this' object is the panel.");
- test.assertEqual(this.isShowing, true, "panel.isShowing == true.");
- panel.hide();
- },
- onHide: function () {
- test.pass("The panel was hidden.");
- test.assertEqual(this, panel, "The 'this' object is the panel.");
- test.assertEqual(this.isShowing, false, "panel.isShowing == false.");
- panel.destroy();
- test.done();
- }
- });
-};
-
-tests.testDocumentReload = function(test) {
- test.waitUntilDone();
- let content =
- "<script>" +
- "setTimeout(function () {" +
- " window.location = 'about:blank';" +
- "}, 250);" +
- "</script>";
- let messageCount = 0;
- let panel = Panel({
- contentURL: "data:text/html," + encodeURIComponent(content),
- contentScript: "self.postMessage(window.location.href)",
- onMessage: function (message) {
- messageCount++;
- if (messageCount == 1) {
- test.assertMatches(message, /data:text\/html,/, "First document had a content script");
- }
- else if (messageCount == 2) {
- test.assertEqual(message, "about:blank", "Second document too");
- panel.destroy();
- test.done();
- }
- }
- });
-};
-
-tests.testParentResizeHack = function(test) {
- let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator).
- getMostRecentWindow("navigator:browser");
- let docShell = browserWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
- if (!("allowWindowControl" in docShell)) {
- // bug 635673 is not fixed in this firefox build
- test.pass("allowWindowControl attribute that allow to fix browser window " +
- "resize is not available on this build.");
- return;
- }
-
- test.waitUntilDone(30000);
-
- let previousWidth = browserWindow.outerWidth, previousHeight = browserWindow.outerHeight;
-
- let content = "<script>" +
- "function contentResize() {" +
- " resizeTo(200,200);" +
- " resizeBy(200,200);" +
- "}" +
- "</script>" +
- "Try to resize browser window";
- let panel = Panel({
- contentURL: "data:text/html," + encodeURIComponent(content),
- contentScript: "self.on('message', function(message){" +
- " if (message=='resize') " +
- " unsafeWindow.contentResize();" +
- "});",
- contentScriptWhen: "ready",
- onMessage: function (message) {
-
- },
- onShow: function () {
- panel.postMessage('resize');
- require("timer").setTimeout(function () {
- test.assertEqual(previousWidth,browserWindow.outerWidth,"Size doesn't change by calling resizeTo/By/...");
- test.assertEqual(previousHeight,browserWindow.outerHeight,"Size doesn't change by calling resizeTo/By/...");
- panel.destroy();
- test.done();
- },0);
- }
- });
- panel.show();
-}
-
-tests.testResizePanel = function(test) {
- test.waitUntilDone();
-
- // These tests fail on Linux if the browser window in which the panel
- // is displayed is not active. And depending on what other tests have run
- // before this one, it might not be (the untitled window in which the test
- // runner executes is often active). So we make sure the browser window
- // is focused by focusing it before running the tests. Then, to be the best
- // possible test citizen, we refocus whatever window was focused before we
- // started running these tests.
-
- let activeWindow = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIWindowWatcher).
- activeWindow;
- let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator).
- getMostRecentWindow("navigator:browser");
-
-
- function onFocus() {
- browserWindow.removeEventListener("focus", onFocus, true);
-
- let panel = Panel({
- contentScript: "self.postMessage('')",
- contentScriptWhen: "end",
- height: 10,
- width: 10,
- onMessage: function (message) {
- panel.show();
- },
- onShow: function () {
- panel.resize(100,100);
- panel.hide();
- },
- onHide: function () {
- test.assert((panel.width == 100) && (panel.height == 100),
- "The panel was resized.");
- if (activeWindow)
- activeWindow.focus();
- test.done();
- }
- });
- }
-
- if (browserWindow === activeWindow) {
- onFocus();
- }
- else {
- browserWindow.addEventListener("focus", onFocus, true);
- browserWindow.focus();
- }
-};
-
-tests.testHideBeforeShow = function(test) {
- test.waitUntilDone();
- let showCalled = false;
- let panel = Panel({
- onShow: function () {
- showCalled = true;
- },
- onHide: function () {
- test.assert(!showCalled, 'must not emit show if was hidden before');
- test.done();
- }
- });
- panel.show();
- panel.hide();
-};
-
-tests.testSeveralShowHides = function(test) {
- test.waitUntilDone();
- let hideCalled = 0;
- let panel = panels.Panel({
- contentURL: "about:buildconfig",
- onShow: function () {
- panel.hide();
- },
- onHide: function () {
- hideCalled++;
- if (hideCalled < 3)
- panel.show();
- else {
- test.pass("onHide called three times as expected");
- test.done();
- }
- }
- });
- panel.on('error', function(e) {
- test.fail('error was emitted:' + e.message + '\n' + e.stack);
- });
- panel.show();
-};
-
-tests.testAnchorAndArrow = function(test) {
- test.waitUntilDone(20000);
- let count = 0;
- function newPanel(tab, anchor) {
- let panel = panels.Panel({
- contentURL: "data:text/html,<html><body style='padding: 0; margin: 0; " +
- "background: gray; text-align: center;'>Anchor: " +
- anchor.id + "</body></html>",
- width: 200,
- height: 100,
- onShow: function () {
- count++;
- panel.destroy();
- if (count==5) {
- test.pass("All anchored panel test displayed");
- tab.close(function () {
- test.done();
- });
- }
- }
- });
- panel.show(anchor);
- }
-
- let tabs= require("tabs");
- let url = 'data:text/html,' +
- '<html><head><title>foo</title></head><body>' +
- '<style>div {background: gray; position: absolute; width: 300px; ' +
- 'border: 2px solid black;}</style>' +
- '<div id="tl" style="top: 0px; left: 0px;">Top Left</div>' +
- '<div id="tr" style="top: 0px; right: 0px;">Top Right</div>' +
- '<div id="bl" style="bottom: 0px; left: 0px;">Bottom Left</div>' +
- '<div id="br" style="bottom: 0px; right: 0px;">Bottom right</div>' +
- '</body></html>';
-
- tabs.open({
- url: url,
- onReady: function(tab) {
- let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator).
- getMostRecentWindow("navigator:browser");
- let window = browserWindow.content;
- newPanel(tab, window.document.getElementById('tl'));
- newPanel(tab, window.document.getElementById('tr'));
- newPanel(tab, window.document.getElementById('bl'));
- newPanel(tab, window.document.getElementById('br'));
- let anchor = browserWindow.document.getElementById("identity-box");
- newPanel(tab, anchor);
- }
- });
-
-
-
-};
-
-tests.testPanelTextColor = function(test) {
- test.waitUntilDone();
- let html = "<html><head><style>body {color: yellow}</style></head>" +
- "<body><p>Foo</p></body></html>";
- let panel = Panel({
- contentURL: "data:text/html," + encodeURI(html),
- contentScript: "self.port.emit('color', " +
- "window.getComputedStyle(document.body.firstChild, null). " +
- " getPropertyValue('color'));"
- });
- panel.port.on("color", function (color) {
- test.assertEqual(color, "rgb(255, 255, 0)",
- "The panel text color style is preserved when a style exists.");
- panel.destroy();
- test.done();
- });
-};
-
-function makeEventOrderTest(options) {
- let expectedEvents = [];
-
- return function(test) {
- let panel = panels.Panel({ contentURL: "about:buildconfig" });
-
- function expect(event, cb) {
- expectedEvents.push(event);
- panel.on(event, function() {
- test.assertEqual(event, expectedEvents.shift());
- if (cb)
- require("timer").setTimeout(cb, 1);
- });
- return {then: expect};
- }
-
- test.waitUntilDone();
- options.test(test, expect, panel);
- }
-}
-
-tests.testAutomaticDestroy = function(test) {
- let loader = Loader(module);
- let panel = loader.require("panel").Panel({
- contentURL: "about:buildconfig",
- contentScript:
- "self.port.on('event', function() self.port.emit('event-back'));"
- });
-
- loader.unload();
-
- panel.port.on("event-back", function () {
- test.fail("Panel should have been destroyed on module unload");
- });
- panel.port.emit("event");
- test.pass("check automatic destroy");
-};
-
-tests.testWaitForInitThenShowThenDestroy = makeEventOrderTest({
- test: function(test, expect, panel) {
- expect('inited', function() { panel.show(); }).
- then('show', function() { panel.destroy(); }).
- then('hide', function() { test.done(); });
- }
-});
-
-tests.testShowThenWaitForInitThenDestroy = makeEventOrderTest({
- test: function(test, expect, panel) {
- panel.show();
- expect('inited').
- then('show', function() { panel.destroy(); }).
- then('hide', function() { test.done(); });
- }
-});
-
-tests.testShowThenHideThenDestroy = makeEventOrderTest({
- test: function(test, expect, panel) {
- panel.show();
- expect('show', function() { panel.hide(); }).
- then('hide', function() { panel.destroy(); test.done(); });
- }
-});
-
-tests.testContentURLOption = function(test) {
- const URL_STRING = "about:buildconfig";
- const HTML_CONTENT = "<html><title>Test</title><p>This is a test.</p></html>";
-
- let (panel = Panel({ contentURL: URL_STRING })) {
- test.pass("contentURL accepts a string URL.");
- test.assertEqual(panel.contentURL, URL_STRING,
- "contentURL is the string to which it was set.");
- }
-
- let dataURL = "data:text/html," + encodeURIComponent(HTML_CONTENT);
- let (panel = Panel({ contentURL: dataURL })) {
- test.pass("contentURL accepts a data: URL.");
- }
-
- let (panel = Panel({})) {
- test.assert(panel.contentURL == null,
- "contentURL is undefined.");
- }
-
- test.assertRaises(function () Panel({ contentURL: "foo" }),
- "The `contentURL` option must be a valid URL.",
- "Panel throws an exception if contentURL is not a URL.");
-};
-
-let panelSupported = true;
-
-try {
- panels = require("panel");
- Panel = panels.Panel;
-}
-catch(ex if ex.message == [
- "The panel module currently supports only Firefox. In the future ",
- "we would like it to support other applications, however. Please see ",
- "https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps ",
- "for more information."
- ].join("")) {
- panelSupported = false;
-}
-
-if (panelSupported) {
- for (let test in tests)
- exports[test] = tests[test];
-}
-else {
- exports.testPanelNotSupported = function(test) {
- test.pass("The panel module is not supported on this app.");
- }
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-passwords.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-passwords.js
deleted file mode 100644
index e799b48..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-passwords.js
+++ /dev/null
@@ -1,277 +0,0 @@
-"use strict";
-
-const { store, search, remove } = require("passwords");
-
-exports["test store requires `password` field"] = function(assert, done) {
- store({
- username: "foo",
- realm: "bar",
- onComplete: function onComplete() {
- assert.fail("onComplete should not be called");
- },
- onError: function onError() {
- assert.pass("'`password` is required");
- done();
- }
- });
-};
-
-exports["test store requires `username` field"] = function(assert, done) {
- store({
- password: "foo",
- realm: "bar",
- onComplete: function onComplete() {
- assert.fail("onComplete should not be called");
- },
- onError: function onError() {
- assert.pass("'`username` is required");
- done();
- }
- });
-};
-
-exports["test onComplete is optional"] = function(assert, done) {
- store({
- realm: "bla",
- username: "bla",
- password: "bla",
- onError: function onError() {
- assert.fail("onError was called");
- }
- });
- assert.pass("exception is not thrown if `onComplete is missing")
- done();
-};
-
-exports["test exceptions in onComplete are reported"] = function(assert, done) {
- store({
- realm: "throws",
- username: "error",
- password: "boom!",
- onComplete: function onComplete(error) {
- throw new Error("Boom!")
- },
- onError: function onError(error) {
- assert.equal(error.message, "Boom!", "Error thrown is reported");
- done();
- }
- });
-};
-
-exports["test store requires `realm` field"] = function(assert, done) {
- store({
- username: "foo",
- password: "bar",
- onComplete: function onComplete() {
- assert.fail("onComplete should not be called");
- },
- onError: function onError() {
- assert.pass("'`realm` is required");
- done();
- }
- });
-};
-
-exports["test can't store same login twice"] = function(assert, done) {
- store({
- username: "user",
- password: "pass",
- realm: "realm",
- onComplete: function onComplete() {
- assert.pass("credential saved");
-
- store({
- username: "user",
- password: "pass",
- realm: "realm",
- onComplete: function onComplete() {
- assert.fail("onComplete should not be called");
- },
- onError: function onError() {
- assert.pass("re-saving credential failed");
-
- remove({
- username: "user",
- password: "pass",
- realm: "realm",
- onComplete: function onComplete() {
- assert.pass("credential was removed");
- done();
- },
- onError: function onError() {
- assert.fail("remove should not fail");
- }
- });
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
-};
-
-exports["test remove fails if no login found"] = function(assert, done) {
- remove({
- username: "foo",
- password: "bar",
- realm: "baz",
- onComplete: function onComplete() {
- assert.fail("should not be able to remove unstored credentials");
- },
- onError: function onError() {
- assert.pass("can't remove unstored credentials");
- done();
- }
- });
-};
-
-exports["test addon associated credentials"] = function(assert, done) {
- store({
- username: "foo",
- password: "bar",
- realm: "baz",
- onComplete: function onComplete() {
- search({
- username: "foo",
- password: "bar",
- realm: "baz",
- onComplete: function onComplete([credential]) {
- assert.equal(credential.url.indexOf("addon:"), 0,
- "`addon:` uri is used for add-on credentials");
- assert.equal(credential.username, "foo",
- "username matches");
- assert.equal(credential.password, "bar",
- "password matches");
- assert.equal(credential.realm, "baz", "realm matches");
- assert.equal(credential.formSubmitURL, null,
- "`formSubmitURL` is `null` for add-on credentials");
- assert.equal(credential.usernameField, "", "usernameField is empty");
- assert.equal(credential.passwordField, "", "passwordField is empty");
-
- remove({
- username: credential.username,
- password: credential.password,
- realm: credential.realm,
- onComplete: function onComplete() {
- assert.pass("credential is removed");
- done();
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
-};
-
-exports["test web page associated credentials"] = function(assert, done) {
- store({
- url: "http://bar.foo.com/authentication/?login",
- formSubmitURL: "http://login.foo.com/authenticate.cgi",
- username: "user",
- password: "pass",
- usernameField: "user-f",
- passwordField: "pass-f",
- onComplete: function onComplete() {
- search({
- username: "user",
- password: "pass",
- url: "http://bar.foo.com",
- formSubmitURL: "http://login.foo.com",
- onComplete: function onComplete([credential]) {
- assert.equal(credential.url, "http://bar.foo.com", "url matches");
- assert.equal(credential.username, "user", "username matches");
- assert.equal(credential.password, "pass", "password matches");
- assert.equal(credential.realm, null, "realm is null");
- assert.equal(credential.formSubmitURL, "http://login.foo.com",
- "formSubmitURL matches");
- assert.equal(credential.usernameField, "user-f",
- "usernameField is matches");
- assert.equal(credential.passwordField, "pass-f",
- "passwordField matches");
-
- remove({
- url: credential.url,
- formSubmitURL: credential.formSubmitURL,
- username: credential.username,
- password: credential.password,
- usernameField: credential.usernameField,
- passwordField: credential.passwordField,
-
- onComplete: function onComplete() {
- assert.pass("credential is removed");
- done();
- },
- onError: function onError(e) {
- assert.fail("onError should not be called");
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
-};
-
-exports["test site authentication credentials"] = function(assert, done) {
- store({
- url: "http://authentication.com",
- username: "U",
- password: "P",
- realm: "R",
- onComplete: function onComplete() {
- search({
- url: "http://authentication.com",
- username: "U",
- password: "P",
- realm: "R",
- onComplete: function onComplete([credential]) {
- assert.equal(credential.url,"http://authentication.com",
- "url matches");
- assert.equal(credential.username, "U", "username matches");
- assert.equal(credential.password, "P", "password matches");
- assert.equal(credential.realm, "R", "realm matches");
- assert.equal(credential.formSubmitURL, null, "formSubmitURL is null");
- assert.equal(credential.usernameField, "", "usernameField is empty");
- assert.equal(credential.passwordField, "", "passwordField is empty");
-
- remove({
- url: credential.url,
- username: credential.username,
- password: credential.password,
- realm: credential.realm,
- onComplete: function onComplete() {
- assert.pass("credential is removed");
- done();
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
- },
- onError: function onError() {
- assert.fail("onError should not be called");
- }
- });
-};
-
-require("test").run(exports);
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-private-browsing.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-private-browsing.js
deleted file mode 100644
index a3c1519..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-private-browsing.js
+++ /dev/null
@@ -1,238 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Paul O’Shannessy <paul@oshannessy.com>
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-let pb = require("private-browsing");
-let {Cc,Ci} = require("chrome");
-const { Loader } = require('./helpers');
-
-let pbService;
-// Currently, only Firefox implements the private browsing service.
-if (require("xul-app").is("Firefox")) {
- pbService = Cc["@mozilla.org/privatebrowsing;1"].
- getService(Ci.nsIPrivateBrowsingService);
-}
-
-if (pbService) {
-
- // tests that isActive has the same value as the private browsing service
- // expects
- exports.testGetIsActive = function (test) {
- test.assertEqual(pb.isActive, false,
- "private-browsing.isActive is correct without modifying PB service");
-
- pbService.privateBrowsingEnabled = true;
- test.assert(pb.isActive,
- "private-browsing.isActive is correct after modifying PB service");
-
- // Switch back to normal mode.
- pbService.privateBrowsingEnabled = false;
- };
-
- // tests that activating does put the browser into private browsing mode
- exports.testActivateDeactivate = function (test) {
- test.waitUntilDone();
- pb.once("start", function onStart() {
- test.assertEqual(pbService.privateBrowsingEnabled, true,
- "private browsing mode was activated");
- pb.deactivate();
- });
- pb.once("stop", function onStop() {
- test.assertEqual(pbService.privateBrowsingEnabled, false,
- "private browsing mode was deactivate");
- test.done();
- });
- pb.activate();
- };
-
- exports.testStart = function(test) {
- test.waitUntilDone();
- pb.on("start", function onStart() {
- test.assertEqual(this, pb, "`this` should be private-browsing module");
- test.assert(pbService.privateBrowsingEnabled,
- 'private mode is active when "start" event is emitted');
- test.assert(pb.isActive,
- '`isActive` is `true` when "start" event is emitted');
- pb.removeListener("start", onStart);
- test.done();
- });
- pb.activate();
- };
-
- exports.testStop = function(test) {
- test.waitUntilDone();
- pb.on("stop", function onStop() {
- test.assertEqual(this, pb, "`this` should be private-browsing module");
- test.assertEqual(pbService.privateBrowsingEnabled, false,
- "private mode is disabled when stop event is emitted");
- test.assertEqual(pb.isActive, false,
- "`isActive` is `false` when stop event is emitted");
- pb.removeListener("stop", onStop);
- test.done();
- });
- pb.activate();
- pb.deactivate();
- };
-
- exports.testAutomaticUnload = function(test) {
- test.waitUntilDone();
- // Create another private browsing instance and unload it
- let loader = Loader(module);
- let pb2 = loader.require("private-browsing");
- let called = false;
- pb2.on("start", function onStart() {
- called = true;
- test.fail("should not be called:x");
- });
- loader.unload();
-
- // Then switch to private mode in order to check that the previous instance
- // is correctly destroyed
- pb.activate();
- pb.once("start", function onStart() {
- require("timer").setTimeout(function () {
- test.assert(!called,
- "First private browsing instance is destroyed and inactive");
-
- // Must reset to normal mode, so that next test starts with it.
- pb.deactivate();
- test.done();
- }, 0);
- });
- };
-
- exports.testBothListeners = function(test) {
- test.waitUntilDone();
- let stop = false;
- let start = false;
-
- function onStop() {
- test.assertEqual(stop, false,
- "stop callback must be called only once");
- test.assertEqual(pbService.privateBrowsingEnabled, false,
- "private mode is disabled when stop event is emitted");
- test.assertEqual(pb.isActive, false,
- "`isActive` is `false` when stop event is emitted");
-
- pb.on("start", finish);
- pb.removeListener("start", onStart);
- pb.removeListener("start", onStart2);
- pb.activate();
- stop = true;
- }
-
- function onStart() {
- test.assertEqual(false, start,
- "stop callback must be called only once");
- test.assert(pbService.privateBrowsingEnabled,
- "private mode is active when start event is emitted");
- test.assert(pb.isActive,
- "`isActive` is `true` when start event is emitted");
-
- pb.on("stop", onStop);
- pb.deactivate();
- start = true;
- }
-
- function onStart2() {
- test.assert(start, "start listener must be called already");
- test.assertEqual(false, stop, "stop callback must not be called yet");
- }
-
- function finish() {
- test.assert(pbService.privateBrowsingEnabled, true,
- "private mode is active when start event is emitted");
- test.assert(pb.isActive,
- "`isActive` is `true` when start event is emitted");
-
- pb.removeListener("start", finish);
- pb.removeListener("stop", onStop);
-
- pb.deactivate();
- pb.once("stop", function () {
- test.assertEqual(pbService.privateBrowsingEnabled, false);
- test.assertEqual(pb.isActive, false);
-
- test.done();
- });
- }
-
- pb.on("start", onStart);
- pb.on("start", onStart2);
- pbService.privateBrowsingEnabled = true;
- };
-
- exports["test activate private mode via handler"] = function(test) {
- const tabs = require("tabs");
-
- test.waitUntilDone();
- function onReady(tab) {
- if (tab.url == "about:robots")
- tab.close(function() pb.activate());
- }
- function cleanup(tab) {
- if (tab.url == "about:") {
- tabs.removeListener("ready", cleanup);
- tab.close(function onClose() {
- test.done();
- });
- }
- }
-
- tabs.on("ready", onReady);
- pb.once("start", function onStart() {
- test.pass("private mode was activated");
- pb.deactivate();
- });
- pb.once("stop", function onStop() {
- test.pass("private mode was deactivated");
- tabs.removeListener("ready", onReady);
- tabs.on("ready", cleanup);
- });
- tabs.once("open", function onOpen() {
- tabs.open("about:robots");
- });
- tabs.open("about:");
- };
-}
-else {
- // tests for the case where private browsing doesn't exist
- exports.testNoImpl = function (test) {
- test.assertEqual(pb.isActive, false,
- "pb.isActive returns false when private browsing isn't supported");
- };
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-request.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-request.js
deleted file mode 100644
index 8b8300e..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-request.js
+++ /dev/null
@@ -1,358 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Paul O’Shannessy <paul@oshannessy.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const Request = require("request").Request;
-
-var port = 8080;
-var data = require("self").data;
-var testFilePath = require("url").toFilename(data.url("test-request.txt"));
-var basePath = require("file").dirname(testFilePath);
-
-var {startServerAsync} = require("httpd");
-
-exports.testOptionsValidator = function(test) {
- // First, a simple test to make sure we didn't break normal functionality.
- test.assertRaises(function () {
- Request({
- url: null
- });
- }, 'The option "url" must be one of the following types: string');
-
- // Next we'll have a Request that doesn't throw from c'tor, but from a setter.
- let req = Request({
- url: "http://playground.zpao.com/jetpack/request/text.php",
- onComplete: function () {}
- });
- test.assertRaises(function () {
- req.url = null;
- }, 'The option "url" must be one of the following types: string');
- // The url shouldn't have changed, so check that
- test.assertEqual(req.url, "http://playground.zpao.com/jetpack/request/text.php");
-}
-
-exports.testContentValidator = function(test) {
- test.waitUntilDone();
- Request({
- url: "data:text/html,response",
- content: { 'key1' : null, 'key2' : 'some value' },
- onComplete: function(response) {
- test.assertEqual(response.text, "response?key1=null&key2=some+value");
- test.done();
- }
- }).get();
-};
-
-// All tests below here require a network connection. They will be commented out
-// when checked in. If you'd like to run them, simply uncomment them.
-//
-// When we have the means, these tests will be converted so that they don't
-// require an external server nor a network connection.
-
-// This is a request to a file that exists.
-exports.testStatus200 = function (test) {
- var srv = startServerAsync(port, basePath);
-
- test.waitUntilDone();
- var req = Request({
- url: "http://localhost:" + port + "/test-request.txt",
- onComplete: function (response) {
- test.assertEqual(this, req, "`this` should be request");
- test.assertEqual(response.status, 200);
- test.assertEqual(response.statusText, "OK");
- test.assertEqual(response.headers["Content-Type"], "text/plain");
- test.assertEqual(response.text, "Look ma, no hands!\n");
- srv.stop(function() test.done());
- }
- }).get();
-}
-
-// This tries to get a file that doesn't exist
-exports.testStatus404 = function (test) {
- var srv = startServerAsync(port, basePath);
-
- test.waitUntilDone();
- Request({
- // the following URL doesn't exist
- url: "http://localhost:" + port + "/test-request-404.txt",
- onComplete: function (response) {
- test.assertEqual(response.status, 404);
- test.assertEqual(response.statusText, "Not Found");
- srv.stop(function() test.done());
- }
- }).get();
-}
-
-/*
-// a simple file with a known header
-exports.testKnownHeader = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/headers.php",
- onComplete: function (response) {
- test.assertEqual(response.headers["x-zpao-header"], "Jamba Juice");
- test.done();
- }
- }).get();
-}
-
-// complex headers
-exports.testKnownHeader = function (test) {
- let headers = {
- "x-zpao-header": "Jamba Juice is: delicious",
- "x-zpao-header-2": "foo, bar",
- "Set-Cookie": "foo=bar\nbaz=foo"
- }
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/complex_headers.php",
- onComplete: function (response) {
- for (k in headers) {
- test.assertEqual(response.headers[k], headers[k]);
- }
- test.done();
- }
- }).get();
-}
-*/
-
-exports.testSimpleJSON = function (test) {
- var srv = startServerAsync(port, basePath);
-
- test.waitUntilDone();
- Request({
- url: "http://localhost:" + port + "/test-request.json",
- onComplete: function (response) {
- assertDeepEqual(test, response.json, { foo: "bar" });
- srv.stop(function() test.done());
- }
- }).get();
-}
-
-exports.testInvalidJSON = function (test) {
- var srv = startServerAsync(port, basePath);
-
- test.waitUntilDone();
- Request({
- url: "http://localhost:" + port + "/test-request-invalid.json",
- onComplete: function (response) {
- test.assertEqual(response.json, null);
- srv.stop(function() test.done());
- }
- }).get();
-}
-
-/*
-exports.testGetWithParamsNotContent = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar",
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : { foo: "bar" }
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testGetWithContent = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: { foo: "bar" },
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : { foo: "bar" }
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testGetWithParamsAndContent = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar",
- content: { baz: "foo" },
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : { foo: "bar", baz: "foo" }
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testSimplePost = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: { foo: "bar" },
- onComplete: function (response) {
- let expected = {
- "POST": { foo: "bar" },
- "GET" : []
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).post();
-}
-
-exports.testEncodedContent = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: "foo=bar&baz=foo",
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : { foo: "bar", baz: "foo" }
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testEncodedContentWithSpaces = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: "foo=bar+hop!&baz=foo",
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : { foo: "bar hop!", baz: "foo" }
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testGetWithArray = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: { foo: [1, 2], baz: "foo" },
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : { foo: [1, 2], baz: "foo" }
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testGetWithNestedArray = function (test) {
- test.waitUntilDone();
- Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: { foo: [1, 2, [3, 4]], bar: "baz" },
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : this.content
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-
-exports.testGetWithNestedArray = function (test) {
- test.waitUntilDone();
- let request = Request({
- url: "http://playground.zpao.com/jetpack/request/getpost.php",
- content: {
- foo: [1, 2, {
- omg: "bbq",
- "all your base!": "are belong to us"
- }],
- bar: "baz"
- },
- onComplete: function (response) {
- let expected = {
- "POST": [],
- "GET" : request.content
- };
- assertDeepEqual(test, response.json, expected);
- test.done();
- }
- }).get();
-}
-*/
-
-// This is not a proper testing for deep equal, but it's good enough for my uses
-// here. It will do type coercion to check equality, but that's good here. Data
-// coming from the server will be stringified and so "0" should be equal to 0.
-function assertDeepEqual(test, obj1, obj2, msg) {
- function equal(o1, o2) {
- // cover our non-object cases well enough
- if (o1 == o2)
- return true;
- if (typeof(o1) != typeof(o2))
- return false;
- if (typeof(o1) != "object")
- return o1 == o2;
-
- let e = true;
- for (let [key, val] in Iterator(o1)) {
- e = e && key in o2 && equal(o2[key], val);
- if (!e)
- break;
- }
- for (let [key, val] in Iterator(o2)) {
- e = e && key in o1 && equal(o1[key], val);
- if (!e)
- break;
- }
- return e;
- }
- msg = msg || "objects not equal - " + JSON.stringify(obj1) + " != " +
- JSON.stringify(obj2);
- test.assert(equal(obj1, obj2), msg);
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-selection.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-selection.js
deleted file mode 100644
index cd96072..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-selection.js
+++ /dev/null
@@ -1,490 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Eric H. Jung <eric.jung@yahoo.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-let timer = require("timer");
-let {Cc,Ci} = require("chrome");
-
-// Arbitrary delay needed to avoid weird behavior.
-// TODO: We need to find all uses of this and replace them
-// with more deterministic solutions.
-const ARB_DELAY = 100;
-
-// Select all divs elements in an HTML document
-function selectAllDivs(window) {
- let divs = window.document.getElementsByTagName("div");
- let s = window.getSelection();
- if (s.rangeCount > 0)
- s.removeAllRanges();
- for (let i = 0; i < divs.length; i++) {
- let range = window.document.createRange();
- range.selectNode(divs[i]);
- s.addRange(range);
- }
-}
-
-function selectTextarea(window, from, to) {
- let textarea = window.document.getElementsByTagName("textarea")[0];
-
- from = from || 0;
- to = to || textarea.value.length;
-
- textarea.setSelectionRange(from, to);
- textarea.focus();
-}
-
-function primeTestCase(html, test, callback) {
- let tabBrowser = require("tab-browser");
- let dataURL = "data:text/html," + encodeURI(html);
- let tracker = tabBrowser.whenContentLoaded(
- function(window) {
- if (window.document.location.href != dataURL)
- return;
- callback(window, test);
- timer.setTimeout(function() {
- tracker.unload();
- test.done();
- window.close();
- },
- ARB_DELAY);
- }
- );
- tabBrowser.addTab(dataURL);
-}
-
-const DIV1 = '<div id="foo">bar</div>';
-const DIV2 = '<div>noodles</div>';
-const HTML_MULTIPLE = '<html><body>' + DIV1 + DIV2 + '</body></html>';
-const HTML_SINGLE = '<html><body>' + DIV1 + '</body></html>';
-
-// Tests of contiguous
-
-exports.testContiguousMultiple = function testContiguousMultiple(test) {
- let selection = require("selection");
- primeTestCase(HTML_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- test.assertEqual(selection.isContiguous, false,
- "selection.isContiguous multiple works.");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testContiguousSingle = function testContiguousSingle(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- selectAllDivs(window);
- test.assertEqual(selection.isContiguous, true,
- "selection.isContiguous single works.");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testContiguousWithoutSelection =
- function testContiguousWithoutSelection(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- test.assertEqual(selection.isContiguous, false,
- "selection.isContiguous without selection works.");
- });
-
- test.waitUntilDone(5000);
-};
-
-/**
- * Test that setting the contiguous property has no effect.
- */
-/*exports.testSetContiguous = function testSetContiguous(test) {
- let selection = require("selection");
- primeTestCase(HTML_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- try {
- selection.isContiguous = true;
- test.assertEqual(selection.isContiguous, false,
- "setting selection.isContiguous doesn't work (as expected).");
- }
- catch (e) {
- test.pass("setting selection.isContiguous doesn't work (as expected).");
- }
- });
-
- test.waitUntilDone(5000);
-};*/
-
-
-// HTML tests
-
-exports.testGetHTMLSingleSelection = function testGetHTMLSingleSelection(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- selectAllDivs(window);
- test.assertEqual(selection.html, DIV1, "get html selection works");
- });
-
- test.waitUntilDone(5000);
-};
-
-/* Myk's comments: This is fine. However, it reminds me to figure out and
- specify whether iteration is ordered. If so, we'll want to change this
- test in the future to test that the discontiguous selections are returned in
- the appropriate order. In the meantime, add a comment to that effect here */
-exports.testGetHTMLMultipleSelection =
- function testGetHTMLMultipleSelection(test) {
- let selection = require("selection");
- primeTestCase(HTML_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- let assertions = false;
- for each (let i in selection) {
- test.assertEqual(true, [DIV1, DIV2].some(function(t) t == i.html),
- "get multiple selection html works");
- assertions = true;
- }
- // Ensure we ran at least one assertEqual()
- test.assert(assertions, "No assertions were called");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetHTMLNull = function testGetHTMLNull(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- test.assertEqual(selection.html, null, "get html null works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetHTMLWeird = function testGetHTMLWeird(test) {
- let selection = require("selection");
- // If the getter is used when there are contiguous selections, the first
- // selection should be returned
- primeTestCase(HTML_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- test.assertEqual(selection.html, DIV1, "get html weird works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetHTMLNullInTextareaSelection =
- function testGetHTMLNullInTextareaSelection(test) {
- let selection = require("selection");
-
- primeTestCase(TEXT_FIELD, test, function(window, test) {
- selectTextarea(window);
-
- test.assertEqual(selection.html, null, "get html null in textarea works")
- });
-
- test.waitUntilDone(5000);
-};
-
-const REPLACEMENT_HTML = "<b>Lorem ipsum dolor sit amet</b>";
-
-exports.testSetHTMLSelection = function testSetHTMLSelection(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- selectAllDivs(window);
- selection.html = REPLACEMENT_HTML;
- test.assertEqual(selection.html, "<span>" + REPLACEMENT_HTML +
- "</span>", "selection html works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testSetHTMLException = function testSetHTMLException(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- try {
- selection.html = REPLACEMENT_HTML;
- test.fail("set HTML throws when there's no selection.");
- }
- catch (e) {
- test.pass("set HTML throws when there's no selection.");
- }
- });
-
- test.waitUntilDone(5000);
-};
-
-const TEXT1 = "foo";
-const TEXT2 = "noodles";
-const TEXT_MULTIPLE = "<html><body><div>" + TEXT1 + "</div><div>" + TEXT2 +
- "</div></body></html>";
-const TEXT_SINGLE = "<html><body><div>" + TEXT1 + "</div></body></html>";
-const TEXT_FIELD = "<html><body><textarea>" + TEXT1 + "</textarea></body></html>";
-
-// Text tests
-
-exports.testSetHTMLinTextareaSelection =
- function testSetHTMLinTextareaSelection(test) {
- let selection = require("selection");
-
- primeTestCase(TEXT_FIELD, test, function(window, test) {
- selectTextarea(window);
-
- // HTML string is set as plain text in textareas, that's because
- // `selection.html` and `selection.text` are basically aliases when a
- // value is set. See bug 677269
- selection.html = REPLACEMENT_HTML;
-
- test.assertEqual(selection.text, REPLACEMENT_HTML,
- "set selection html in textarea works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetTextSingleSelection =
- function testGetTextSingleSelection(test) {
- let selection = require("selection");
- primeTestCase(TEXT_SINGLE, test, function(window, test) {
- selectAllDivs(window);
- test.assertEqual(selection.text, TEXT1, "get text selection works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetTextMultipleSelection =
- function testGetTextMultipleSelection(test) {
- let selection = require("selection");
- primeTestCase(TEXT_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- let assertions = false;
- for each (let i in selection) {
- test.assertEqual(true, [TEXT1, TEXT2].some(function(t) t == i.text),
- "get multiple selection text works");
- assertions = true;
- }
- // Ensure we ran at least one assertEqual()
- test.assert(assertions, "No assertions were called");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetTextNull = function testGetTextNull(test) {
- let selection = require("selection");
- primeTestCase(TEXT_SINGLE, test, function(window, test) {
- test.assertEqual(selection.text, null, "get text null works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetTextWeird = function testGetTextWeird(test) {
- let selection = require("selection");
- // If the getter is used when there are contiguous selections, the first
- // selection should be returned
- primeTestCase(TEXT_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- test.assertEqual(selection.text, TEXT1, "get text weird works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetTextNullInTextareaSelection =
- function testGetTextInTextareaSelection(test) {
- let selection = require("selection");
-
- primeTestCase(TEXT_FIELD, test, function(window, test) {
- test.assertEqual(selection.text, null, "get text null in textarea works")
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testGetTextInTextareaSelection =
- function testGetTextInTextareaSelection(test) {
- let selection = require("selection");
-
- primeTestCase(TEXT_FIELD, test, function(window, test) {
- selectTextarea(window);
-
- test.assertEqual(selection.text, TEXT1, "get text null in textarea works")
- });
-
- test.waitUntilDone(5000);
-};
-
-const REPLACEMENT_TEXT = "Lorem ipsum dolor sit amet";
-
-exports.testSetTextSelection = function testSetTextSelection(test) {
- let selection = require("selection");
- primeTestCase(TEXT_SINGLE, test, function(window, test) {
- selectAllDivs(window);
- selection.text = REPLACEMENT_TEXT;
- test.assertEqual(selection.text, REPLACEMENT_TEXT, "selection text works");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testSetHTMLException = function testSetHTMLException(test) {
- let selection = require("selection");
- primeTestCase(TEXT_SINGLE, test, function(window, test) {
- try {
- selection.text = REPLACEMENT_TEXT;
- test.fail("set HTML throws when there's no selection.");
- }
- catch (e) {
- test.pass("set HTML throws when there's no selection.");
- }
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testSetTextInTextareaSelection =
- function testSetTextInTextareaSelection(test) {
- let selection = require("selection");
-
- primeTestCase(TEXT_FIELD, test, function(window, test) {
- selectTextarea(window);
-
- selection.text = REPLACEMENT_TEXT;
-
- test.assertEqual(selection.text, REPLACEMENT_TEXT,
- "set selection text in textarea works");
- });
-
- test.waitUntilDone(5000);
-};
-
-// Iterator tests
-
-exports.testIterator = function testIterator(test) {
- let selection = require("selection");
- let selectionCount = 0;
- primeTestCase(TEXT_MULTIPLE, test, function(window, test) {
- selectAllDivs(window);
- for each (let i in selection)
- selectionCount++;
- test.assertEqual(2, selectionCount, "iterator works.");
- });
-
- test.waitUntilDone(5000);
-};
-
-exports.testIteratorWithTextareaSelection =
- function testIteratorWithTextareaSelection(test) {
- let selection = require("selection");
- let selectionCount = 0;
-
- primeTestCase(TEXT_FIELD, test, function(window, test) {
- selectTextarea(window);
-
- for each (let i in selection)
- selectionCount++;
-
- test.assertEqual(1, selectionCount, "iterator works in textarea.");
- });
-
- test.waitUntilDone(5000);
-};
-
-/* onSelect tests */
-
-/*
-function sendSelectionSetEvent(window) {
- const Ci = Components.interfaces;
- let utils = window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils);
- if (!utils.sendSelectionSetEvent(0, 1, false))
- dump("**** sendSelectionSetEvent did not select anything\n");
- else
- dump("**** sendSelectionSetEvent succeeded\n");
-}
-
-// testOnSelect() requires nsIDOMWindowUtils, which is only available in
-// Firefox 3.7+.
-exports.testOnSelect = function testOnSelect(test) {
- let selection = require("selection");
- let callbackCount = 0;
- primeTestCase(TEXT_SINGLE, test, function(window, test) {
- selection.onSelect = function() {callbackCount++};
- // Now simulate the user selecting stuff
- sendSelectionSetEvent(window);
- selection.text = REPLACEMENT_TEXT;
- test.assertEqual(1, callbackCount, "onSelect text listener works.");
- //test.pass();
- //test.done();
- });
-
- test.waitUntilDone(5000);
-};
-
-// testOnSelectExceptionNoBubble() requires nsIDOMWindowUtils, which is only
-// available in Firefox 3.7+.
-exports.testOnSelectExceptionNoBubble =
- function testOnSelectTextSelection(test) {
- let selection = require("selection");
- primeTestCase(HTML_SINGLE, test, function(window, test) {
- selection.onSelect = function() {
- throw new Error("Exception thrown in testOnSelectExceptionNoBubble");
- };
- // Now simulate the user selecting stuff
- sendSelectionSetEvent(window);
- test.pass("onSelect catches exceptions.");
- });
-
- test.waitUntilDone(5000);
-};
-*/
-
-// If the module doesn't support the app we're being run in, require() will
-// throw. In that case, remove all tests above from exports, and add one dummy
-// test that passes.
-try {
- require("selection");
-}
-catch (err) {
- // This bug should be mentioned in the error message.
- let bug = "https://bugzilla.mozilla.org/show_bug.cgi?id=560716";
- if (err.message.indexOf(bug) < 0)
- throw err;
- for (let [prop, val] in Iterator(exports)) {
- if (/^test/.test(prop) && typeof(val) === "function")
- delete exports[prop];
- }
- exports.testAppNotSupported = function (test) {
- test.pass("The selection module does not support this application.");
- };
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-prefs.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-prefs.js
deleted file mode 100644
index 581eca1..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-prefs.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Erik Vold <erikvvold@gmail.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-const { Loader } = require("./helpers");
-const setTimeout = require("timers").setTimeout;
-const notify = require("observer-service").notify;
-const { jetpackID } = require("@packaging");
-
-exports.testSetGetBool = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs").prefs;
-
- test.assertEqual(sp.test, undefined, "Value should not exist");
- sp.test = true;
- test.assert(sp.test, "Value read should be the value previously set");
-
- loader.unload();
- test.done();
-};
-
-exports.testSetGetInt = function(test) {
- test.waitUntilDone();
-
- // Load the module once, set a value.
- let loader = Loader(module);
- let sp = loader.require("simple-prefs").prefs;
-
- test.assertEqual(sp["test-int"], undefined, "Value should not exist");
- sp["test-int"] = 1;
- test.assertEqual(sp["test-int"], 1, "Value read should be the value previously set");
-
- loader.unload();
- test.done();
-};
-
-exports.testSetComplex = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs").prefs;
-
- try {
- sp["test-complex"] = {test: true};
- test.fail("Complex values are not allowed");
- }
- catch (e) {
- test.pass("Complex values are not allowed");
- }
-
- loader.unload();
- test.done();
-};
-
-exports.testSetGetString = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs").prefs;
-
- test.assertEqual(sp["test-string"], undefined, "Value should not exist");
- sp["test-string"] = "test";
- test.assertEqual(sp["test-string"], "test", "Value read should be the value previously set");
-
- loader.unload();
- test.done();
-};
-
-exports.testHasAndRemove = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs").prefs;
-
- sp.test = true;
- test.assert(("test" in sp), "Value exists");
- delete sp.test;
- test.assertEqual(sp.test, undefined, "Value should be undefined");
-
- loader.unload();
- test.done();
-
-};
-
-exports.testPrefListener = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs");
-
- let listener = function(prefName) {
- test.assertEqual(prefName, "test-listen", "The prefs listener heard the right event");
- test.done();
- };
-
- sp.on("test-listen", listener);
-
- sp.prefs["test-listen"] = true;
- loader.unload();
-};
-
-exports.testBtnListener = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs");
-
- sp.on("test-btn-listen", function() {
- test.pass("Button press event was heard");
- test.done();
- });
- notify((jetpackID + "-cmdPressed"), "", "test-btn-listen");
-
- loader.unload();
-};
-
-exports.testPrefRemoveListener = function(test) {
- test.waitUntilDone();
-
- let loader = Loader(module);
- let sp = loader.require("simple-prefs");
- let counter = 0;
-
- let listener = function() {
- test.pass("The prefs listener was not removed yet");
-
- if (++counter > 1)
- test.fail("The prefs listener was not removed");
-
- sp.removeListener("test-listen2", listener);
-
- sp.prefs["test-listen2"] = false;
-
- setTimeout(function() {
- test.pass("The prefs listener was removed");
- loader.unload();
- test.done();
- }, 250);
- };
-
- sp.on("test-listen2", listener);
-
- sp.prefs["test-listen2"] = true;
-};
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-storage.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-storage.js
deleted file mode 100644
index 95e4689..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-simple-storage.js
+++ /dev/null
@@ -1,346 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim:set ts=2 sw=2 sts=2 et filetype=javascript
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Drew Willcoxon <adw@mozilla.com> (Original Author)
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const file = require("file");
-const prefs = require("preferences-service");
-
-const QUOTA_PREF = "extensions.addon-sdk.simple-storage.quota";
-
-let {Cc,Ci} = require("chrome");
-
-const { Loader } = require("./helpers");
-const options = require("@packaging");
-
-let storeFile = Cc["@mozilla.org/file/directory_service;1"].
- getService(Ci.nsIProperties).
- get("ProfD", Ci.nsIFile);
-storeFile.append("jetpack");
-storeFile.append(options.jetpackID);
-storeFile.append("simple-storage");
-storeFile.append("store.json");
-let storeFilename = storeFile.path;
-
-exports.testSetGet = function (test) {
- test.waitUntilDone();
-
- // Load the module once, set a value.
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function (storage) {
- test.assert(file.exists(storeFilename), "Store file should exist");
-
- // Load the module again and make sure the value stuck.
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function (storage) {
- file.remove(storeFilename);
- test.done();
- };
- test.assertEqual(ss.storage.foo, val, "Value should persist");
- loader.unload();
- };
- let val = "foo";
- ss.storage.foo = val;
- test.assertEqual(ss.storage.foo, val, "Value read should be value set");
- loader.unload();
-};
-
-exports.testSetGetRootArray = function (test) {
- setGetRoot(test, [1, 2, 3], function (arr1, arr2) {
- if (arr1.length !== arr2.length)
- return false;
- for (let i = 0; i < arr1.length; i++) {
- if (arr1[i] !== arr2[i])
- return false;
- }
- return true;
- });
-};
-
-exports.testSetGetRootBool = function (test) {
- setGetRoot(test, true);
-};
-
-exports.testSetGetRootFunction = function (test) {
- setGetRootError(test, function () {},
- "Setting storage to a function should fail");
-};
-
-exports.testSetGetRootNull = function (test) {
- setGetRoot(test, null);
-};
-
-exports.testSetGetRootNumber = function (test) {
- setGetRoot(test, 3.14);
-};
-
-exports.testSetGetRootObject = function (test) {
- setGetRoot(test, { foo: 1, bar: 2 }, function (obj1, obj2) {
- for (let [prop, val] in Iterator(obj1)) {
- if (!(prop in obj2) || obj2[prop] !== val)
- return false;
- }
- for (let [prop, val] in Iterator(obj2)) {
- if (!(prop in obj1) || obj1[prop] !== val)
- return false;
- }
- return true;
- });
-};
-
-exports.testSetGetRootString = function (test) {
- setGetRoot(test, "sho' 'nuff");
-};
-
-exports.testSetGetRootUndefined = function (test) {
- setGetRootError(test, undefined, "Setting storage to undefined should fail");
-};
-
-exports.testEmpty = function (test) {
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- loader.unload();
- test.assert(!file.exists(storeFilename), "Store file should not exist");
-};
-
-exports.testMalformed = function (test) {
- let stream = file.open(storeFilename, "w");
- stream.write("i'm not json");
- stream.close();
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- let empty = true;
- for (let key in ss.storage) {
- empty = false;
- break;
- }
- test.assert(empty, "Malformed storage should cause root to be empty");
- loader.unload();
-};
-
-// Go over quota and handle it by listener.
-exports.testQuotaExceededHandle = function (test) {
- test.waitUntilDone();
- prefs.set(QUOTA_PREF, 18);
-
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- ss.on("OverQuota", function () {
- test.pass("OverQuota was emitted as expected");
- test.assertEqual(this, ss, "`this` should be simple storage");
- ss.storage = { x: 4, y: 5 };
-
- manager(loader).jsonStore.onWrite = function () {
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- let numProps = 0;
- for (let prop in ss.storage)
- numProps++;
- test.assert(numProps, 2,
- "Store should contain 2 values: " + ss.storage.toSource());
- test.assertEqual(ss.storage.x, 4, "x value should be correct");
- test.assertEqual(ss.storage.y, 5, "y value should be correct");
- manager(loader).jsonStore.onWrite = function (storage) {
- prefs.reset(QUOTA_PREF);
- test.done();
- };
- loader.unload();
- };
- loader.unload();
- });
- // This will be JSON.stringify()ed to: {"a":1,"b":2,"c":3} (19 bytes)
- ss.storage = { a: 1, b: 2, c: 3 };
- manager(loader).jsonStore.write();
-};
-
-// Go over quota but don't handle it. The last good state should still persist.
-exports.testQuotaExceededNoHandle = function (test) {
- test.waitUntilDone();
- prefs.set(QUOTA_PREF, 5);
-
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
-
- manager(loader).jsonStore.onWrite = function (storage) {
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- test.assertEqual(ss.storage, val,
- "Value should have persisted: " + ss.storage);
- ss.storage = "some very long string that is very long";
- ss.on("OverQuota", function () {
- test.pass("OverQuota emitted as expected");
- manager(loader).jsonStore.onWrite = function () {
- test.fail("Over-quota value should not have been written");
- };
- loader.unload();
-
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- test.assertEqual(ss.storage, val,
- "Over-quota value should not have been written, " +
- "old value should have persisted: " + ss.storage);
- loader.unload();
- prefs.reset(QUOTA_PREF);
- test.done();
- });
- manager(loader).jsonStore.write();
- };
-
- let val = "foo";
- ss.storage = val;
- loader.unload();
-};
-
-exports.testQuotaUsage = function (test) {
- test.waitUntilDone();
-
- let quota = 21;
- prefs.set(QUOTA_PREF, quota);
-
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
-
- // {"a":1} (7 bytes)
- ss.storage = { a: 1 };
- test.assertEqual(ss.quotaUsage, 7 / quota, "quotaUsage should be correct");
-
- // {"a":1,"bb":2} (14 bytes)
- ss.storage = { a: 1, bb: 2 };
- test.assertEqual(ss.quotaUsage, 14 / quota, "quotaUsage should be correct");
-
- // {"a":1,"bb":2,"cc":3} (21 bytes)
- ss.storage = { a: 1, bb: 2, cc: 3 };
- test.assertEqual(ss.quotaUsage, 21 / quota, "quotaUsage should be correct");
-
- manager(loader).jsonStore.onWrite = function () {
- prefs.reset(QUOTA_PREF);
- test.done();
- };
- loader.unload();
-};
-
-exports.testUninstall = function (test) {
- test.waitUntilDone();
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function () {
- test.assert(file.exists(storeFilename), "Store file should exist");
-
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- loader.unload("uninstall");
- test.assert(!file.exists(storeFilename), "Store file should be removed");
- test.done();
- };
- ss.storage.foo = "foo";
- loader.unload();
-};
-
-exports.testSetNoSetRead = function (test) {
- test.waitUntilDone();
-
- // Load the module, set a value.
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function (storage) {
- test.assert(file.exists(storeFilename), "Store file should exist");
-
- // Load the module again but don't access ss.storage.
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function (storage) {
- test.fail("Nothing should be written since `storage` was not accessed.");
- };
- loader.unload();
-
- // Load the module a third time and make sure the value stuck.
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function (storage) {
- file.remove(storeFilename);
- test.done();
- };
- test.assertEqual(ss.storage.foo, val, "Value should persist");
- loader.unload();
- };
- let val = "foo";
- ss.storage.foo = val;
- test.assertEqual(ss.storage.foo, val, "Value read should be value set");
- loader.unload();
-};
-
-function manager(loader) loader.sandbox("simple-storage").manager;
-
-function newLoader() Loader(module);
-
-function setGetRoot(test, val, compare) {
- test.waitUntilDone();
-
- compare = compare || function (a, b) a === b;
-
- // Load the module once, set a value.
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function () {
- test.assert(file.exists(storeFilename), "Store file should exist");
-
- // Load the module again and make sure the value stuck.
- loader = newLoader(test);
- ss = loader.require("simple-storage");
- manager(loader).jsonStore.onWrite = function () {
- file.remove(storeFilename);
- test.done();
- };
- test.assert(compare(ss.storage, val), "Value should persist");
- loader.unload();
- };
- ss.storage = val;
- test.assert(compare(ss.storage, val), "Value read should be value set");
- loader.unload();
-}
-
-function setGetRootError(test, val, msg) {
- let pred = "storage must be one of the following types: " +
- "array, boolean, null, number, object, string";
- let loader = newLoader(test);
- let ss = loader.require("simple-storage");
- test.assertRaises(function () ss.storage = val, pred, msg);
- loader.unload();
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-tabs.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-tabs.js
deleted file mode 100644
index ae98312..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-tabs.js
+++ /dev/null
@@ -1,905 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Dietrich Ayala <dietrich@mozilla.com> (Original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-"use strict";
-
-var {Cc,Ci} = require("chrome");
-const { Loader } = require("./helpers");
-
-// test tab.activeTab getter
-exports.testActiveTab_getter = function(test) {
- test.waitUntilDone();
-
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
-
- let url = "data:text/html,<html><head><title>foo</title></head></html>";
- require("tab-browser").addTab(
- url,
- {
- onLoad: function(e) {
- test.assert(tabs.activeTab);
- test.assertEqual(tabs.activeTab.url, url);
- test.assertEqual(tabs.activeTab.title, "foo");
- closeBrowserWindow(window, function() test.done());
- }
- }
- );
- });
-};
-
-// test 'BrowserWindow' instance creation on tab 'activate' event
-// See bug 648244: there was a infinite loop.
-exports.testBrowserWindowCreationOnActivate = function(test) {
- test.waitUntilDone();
-
- let windows = require("windows").browserWindows;
- let tabs = require("tabs");
-
- let gotActivate = false;
-
- tabs.once('activate', function onActivate(eventTab) {
- test.assert(windows.activeWindow, "Is able to fetch activeWindow");
- gotActivate = true;
- });
-
- openBrowserWindow(function(window, browser) {
- test.assert(gotActivate, "Received activate event before openBrowserWindow's callback is called");
- closeBrowserWindow(window, function () test.done());
- });
-}
-
-// test tab.activeTab setter
-exports.testActiveTab_setter = function(test) {
- test.waitUntilDone();
-
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,<html><head><title>foo</title></head></html>";
-
- tabs.on('ready', function onReady(tab) {
- tabs.removeListener('ready', onReady);
- test.assertEqual(tabs.activeTab.url, "about:blank", "activeTab url has not changed");
- test.assertEqual(tab.url, url, "url of new background tab matches");
- tabs.on('activate', function onActivate(eventTab) {
- tabs.removeListener('activate', onActivate);
- test.assertEqual(tabs.activeTab.url, url, "url after activeTab setter matches");
- test.assertEqual(eventTab, tab, "event argument is the activated tab");
- test.assertEqual(eventTab, tabs.activeTab, "the tab is the active one");
- closeBrowserWindow(window, function() test.done());
- });
- tab.activate();
- })
-
- tabs.open({
- url: url,
- inBackground: true
- });
- });
-};
-
-exports.testAutomaticDestroy = function(test) {
- test.waitUntilDone();
-
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
-
- // Create a second tab instance that we will destroy
- let called = false;
-
- let loader = Loader(module);
- let tabs2 = loader.require("tabs");
- tabs2.on('open', function onOpen(tab) {
- called = true;
- });
-
- loader.unload();
-
- // Fire a tab event an ensure that this destroyed tab is inactive
- tabs.once('open', function () {
- require("timer").setTimeout(function () {
- test.assert(!called, "Unloaded tab module is destroyed and inactive");
- closeBrowserWindow(window, function() test.done());
- }, 0);
- });
-
- tabs.open("data:text/html,foo");
-
- });
-};
-
-// test tab properties
-exports.testTabProperties = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs= require("tabs");
- let url = "data:text/html,<html><head><title>foo</title></head><body>foo</body></html>";
- tabs.open({
- url: url,
- onReady: function(tab) {
- test.assertEqual(tab.title, "foo", "title of the new tab matches");
- test.assertEqual(tab.url, url, "URL of the new tab matches");
- test.assert(tab.favicon, "favicon of the new tab is not empty");
- test.assertEqual(tab.style, null, "style of the new tab matches");
- test.assertEqual(tab.index, 1, "index of the new tab matches");
- test.assertNotEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
- closeBrowserWindow(window, function() test.done());
- }
- });
- });
-};
-
-// test tabs iterator and length property
-exports.testTabsIteratorAndLength = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let startCount = 0;
- for each (let t in tabs) startCount++;
- test.assertEqual(startCount, tabs.length, "length property is correct");
- let url = "data:text/html,default";
- tabs.open(url);
- tabs.open(url);
- tabs.open({
- url: url,
- onOpen: function(tab) {
- let count = 0;
- for each (let t in tabs) count++;
- test.assertEqual(count, startCount + 3, "iterated tab count matches");
- test.assertEqual(startCount + 3, tabs.length, "iterated tab count matches length property");
- closeBrowserWindow(window, function() test.done());
- }
- });
- });
-};
-
-// test tab.url setter
-exports.testTabLocation = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url1 = "data:text/html,foo";
- let url2 = "data:text/html,bar";
-
- tabs.on('ready', function onReady(tab) {
- if (tab.url != url2)
- return;
- tabs.removeListener('ready', onReady);
- test.pass("tab.load() loaded the correct url");
- closeBrowserWindow(window, function() test.done());
- });
-
- tabs.open({
- url: url1,
- onOpen: function(tab) {
- tab.url = url2
- }
- });
- });
-};
-
-// test tab.close()
-exports.testTabClose = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,foo";
-
- test.assertNotEqual(tabs.activeTab.url, url, "tab is now the active tab");
- tabs.on('ready', function onReady(tab) {
- tabs.removeListener('ready', onReady);
- test.assertEqual(tabs.activeTab.url, tab.url, "tab is now the active tab");
- tab.close(function() {
- closeBrowserWindow(window, function() test.done());
- });
- test.assertNotEqual(tabs.activeTab.url, url, "tab is no longer the active tab");
- });
-
- tabs.open(url);
- });
-};
-
-// test tab.reload()
-exports.testTabReload = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,<!doctype%20html><title></title>";
-
- tabs.open({ url: url, onReady: function onReady(tab) {
- tab.removeListener("ready", onReady);
-
- browser.addEventListener(
- "load",
- function onLoad() {
- browser.removeEventListener("load", onLoad, true);
-
- browser.addEventListener(
- "load",
- function onReload() {
- browser.removeEventListener("load", onReload, true);
- test.pass("the tab was loaded again");
- test.assertEqual(tab.url, url, "the tab has the same URL");
- closeBrowserWindow(window, function() test.done());
- },
- true
- );
- tab.reload();
- },
- true
- );
- }});
- });
-};
-
-// test tab.move()
-exports.testTabMove = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,foo";
-
- tabs.open({
- url: url,
- onOpen: function(tab) {
- test.assertEqual(tab.index, 1, "tab index before move matches");
- tab.index = 0;
- test.assertEqual(tab.index, 0, "tab index after move matches");
- closeBrowserWindow(window, function() test.done());
- }
- });
- });
-};
-
-// open tab with default options
-exports.testOpen = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,default";
- tabs.open({
- url: url,
- onReady: function(tab) {
- test.assertEqual(tab.url, url, "URL of the new tab matches");
- test.assertEqual(window.content.location, url, "URL of active tab in the current window matches");
- closeBrowserWindow(window, function() test.done());
- }
- });
- });
-};
-
-// open pinned tab
-exports.testOpenPinned = function(test) {
- const xulApp = require("xul-app");
- if (xulApp.versionInRange(xulApp.platformVersion, "2.0b2", "*")) {
- // test tab pinning
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,default";
- tabs.open({
- url: url,
- isPinned: true,
- onOpen: function(tab) {
- test.assertEqual(tab.isPinned, true, "The new tab is pinned");
- closeBrowserWindow(window, function() test.done());
- }
- });
- });
- }
- else {
- test.pass("Pinned tabs are not supported in this application.");
- }
-};
-
-// pin/unpin opened tab
-exports.testPinUnpin = function(test) {
- const xulApp = require("xul-app");
- if (xulApp.versionInRange(xulApp.platformVersion, "2.0b2", "*")) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let url = "data:text/html,default";
- tabs.open({
- url: url,
- onOpen: function(tab) {
- tab.pin();
- test.assertEqual(tab.isPinned, true, "The tab was pinned correctly");
- tab.unpin();
- test.assertEqual(tab.isPinned, false, "The tab was unpinned correctly");
- closeBrowserWindow(window, function() test.done());
- }
- });
- });
- }
- else {
- test.pass("Pinned tabs are not supported in this application.");
- }
-};
-
-// open tab in background
-exports.testInBackground = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let activeUrl = tabs.activeTab.url;
- let url = "data:text/html,background";
- test.assertEqual(activeWindow, window, "activeWindow matches this window");
- tabs.on('ready', function onReady(tab) {
- tabs.removeListener('ready', onReady);
- test.assertEqual(tabs.activeTab.url, activeUrl, "URL of active tab has not changed");
- test.assertEqual(tab.url, url, "URL of the new background tab matches");
- test.assertEqual(activeWindow, window, "a new window was not opened");
- test.assertNotEqual(tabs.activeTab.url, url, "URL of active tab is not the new URL");
- closeBrowserWindow(window, function() test.done());
- });
- tabs.open({
- url: url,
- inBackground: true
- });
- });
-};
-
-// open tab in new window
-exports.testOpenInNewWindow = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
-
- let cache = [];
- let windowUtils = require("window-utils");
- let wt = new windowUtils.WindowTracker({
- onTrack: function(win) {
- cache.push(win);
- },
- onUntrack: function(win) {
- cache.splice(cache.indexOf(win), 1)
- }
- });
- let startWindowCount = cache.length;
-
- let url = "data:text/html,newwindow";
- tabs.open({
- url: url,
- inNewWindow: true,
- onReady: function(tab) {
- let newWindow = cache[cache.length - 1];
- test.assertEqual(cache.length, startWindowCount + 1, "a new window was opened");
- test.assertEqual(activeWindow, newWindow, "new window is active");
- test.assertEqual(tab.url, url, "URL of the new tab matches");
- test.assertEqual(newWindow.content.location, url, "URL of new tab in new window matches");
- test.assertEqual(tabs.activeTab.url, url, "URL of activeTab matches");
- for (var i in cache) cache[i] = null;
- wt.unload();
- closeBrowserWindow(newWindow, function() {
- closeBrowserWindow(window, function() test.done());
- });
- }
- });
- });
-};
-
-// onOpen event handler
-exports.testTabsEvent_onOpen = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
- let url = "data:text/html,1";
- let eventCount = 0;
-
- // add listener via property assignment
- function listener1(tab) {
- eventCount++;
- };
- tabs.on('open', listener1);
-
- // add listener via collection add
- tabs.on('open', function listener2(tab) {
- test.assertEqual(++eventCount, 2, "both listeners notified");
- tabs.removeListener('open', listener1);
- tabs.removeListener('open', listener2);
- closeBrowserWindow(window, function() test.done());
- });
-
- tabs.open(url);
- });
-};
-
-// onClose event handler
-exports.testTabsEvent_onClose = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
- let url = "data:text/html,onclose";
- let eventCount = 0;
-
- // add listener via property assignment
- function listener1(tab) {
- eventCount++;
- }
- tabs.on('close', listener1);
-
- // add listener via collection add
- tabs.on('close', function listener2(tab) {
- test.assertEqual(++eventCount, 2, "both listeners notified");
- tabs.removeListener('close', listener1);
- tabs.removeListener('close', listener2);
- closeBrowserWindow(window, function() test.done());
- });
-
- tabs.on('ready', function onReady(tab) {
- tabs.removeListener('ready', onReady);
- tab.close();
- });
-
- tabs.open(url);
- });
-};
-
-// onClose event handler when a window is closed
-exports.testTabsEvent_onCloseWindow = function(test) {
- test.waitUntilDone();
-
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
-
- let closeCount = 0, individualCloseCount = 0;
- function listener() {
- closeCount++;
- }
- tabs.on('close', listener);
-
- // One tab is already open with the window
- let openTabs = 1;
- function testCasePossiblyLoaded() {
- if (++openTabs == 4) {
- beginCloseWindow();
- }
- }
-
- tabs.open({
- url: "data:text/html,tab2",
- onOpen: function() testCasePossiblyLoaded(),
- onClose: function() individualCloseCount++
- });
-
- tabs.open({
- url: "data:text/html,tab3",
- onOpen: function() testCasePossiblyLoaded(),
- onClose: function() individualCloseCount++
- });
-
- tabs.open({
- url: "data:text/html,tab4",
- onOpen: function() testCasePossiblyLoaded(),
- onClose: function() individualCloseCount++
- });
-
- function beginCloseWindow() {
- closeBrowserWindow(window, function testFinished() {
- tabs.removeListener("close", listener);
-
- test.assertEqual(closeCount, 4, "Correct number of close events received");
- test.assertEqual(individualCloseCount, 3,
- "Each tab with an attached onClose listener received a close " +
- "event when the window was closed");
-
- test.done();
- });
- }
-
- });
-}
-
-// onReady event handler
-exports.testTabsEvent_onReady = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
- let url = "data:text/html,onready";
- let eventCount = 0;
-
- // add listener via property assignment
- function listener1(tab) {
- eventCount++;
- };
- tabs.on('ready', listener1);
-
- // add listener via collection add
- tabs.on('ready', function listener2(tab) {
- test.assertEqual(++eventCount, 2, "both listeners notified");
- tabs.removeListener('ready', listener1);
- tabs.removeListener('ready', listener2);
- closeBrowserWindow(window, function() test.done());
- });
-
- tabs.open(url);
- });
-};
-
-// onActivate event handler
-exports.testTabsEvent_onActivate = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
- let url = "data:text/html,onactivate";
- let eventCount = 0;
-
- // add listener via property assignment
- function listener1(tab) {
- eventCount++;
- };
- tabs.on('activate', listener1);
-
- // add listener via collection add
- tabs.on('activate', function listener2(tab) {
- test.assertEqual(++eventCount, 2, "both listeners notified");
- tabs.removeListener('activate', listener1);
- tabs.removeListener('activate', listener2);
- closeBrowserWindow(window, function() test.done());
- });
-
- tabs.open(url);
- });
-};
-
-// onDeactivate event handler
-exports.testTabsEvent_onDeactivate = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
- let url = "data:text/html,ondeactivate";
- let eventCount = 0;
-
- // add listener via property assignment
- function listener1(tab) {
- eventCount++;
- };
- tabs.on('deactivate', listener1);
-
- // add listener via collection add
- tabs.on('deactivate', function listener2(tab) {
- test.assertEqual(++eventCount, 2, "both listeners notified");
- tabs.removeListener('deactivate', listener1);
- tabs.removeListener('deactivate', listener2);
- closeBrowserWindow(window, function() test.done());
- });
-
- tabs.on('open', function onOpen(tab) {
- tabs.removeListener('open', onOpen);
- tabs.open("data:text/html,foo");
- });
-
- tabs.open(url);
- });
-};
-
-// per-tab event handlers
-exports.testPerTabEvents = function(test) {
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- var tabs = require("tabs");
- let eventCount = 0;
-
- tabs.open({
- url: "data:text/html,foo",
- onOpen: function(tab) {
- // add listener via property assignment
- function listener1() {
- eventCount++;
- };
- tab.on('ready', listener1);
-
- // add listener via collection add
- tab.on('ready', function listener2() {
- test.assertEqual(eventCount, 1, "both listeners notified");
- tab.removeListener('ready', listener1);
- tab.removeListener('ready', listener2);
- closeBrowserWindow(window, function() test.done());
- });
- }
- });
- });
-};
-
-exports.testAttachOnOpen = function (test) {
- // Take care that attach has to be called on tab ready and not on tab open.
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
-
- tabs.open({
- url: "data:text/html,foobar",
- onOpen: function (tab) {
- let worker = tab.attach({
- contentScript: 'self.postMessage(document.location.href); ',
- onMessage: function (msg) {
- test.assertEqual(msg, "about:blank",
- "Worker document url is about:blank on open");
- worker.destroy();
- closeBrowserWindow(window, function() test.done());
- }
- });
- }
- });
-
- });
-}
-
-exports.testAttachOnMultipleDocuments = function (test) {
- // Example of attach that process multiple tab documents
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let firstLocation = "data:text/html,foobar";
- let secondLocation = "data:text/html,bar";
- let thirdLocation = "data:text/html,fox";
- let onReadyCount = 0;
- let worker1 = null;
- let worker2 = null;
- let detachEventCount = 0;
- tabs.open({
- url: firstLocation,
- onReady: function (tab) {
- onReadyCount++;
- if (onReadyCount == 1) {
- worker1 = tab.attach({
- contentScript: 'self.on("message", ' +
- ' function () self.postMessage(document.location.href)' +
- ');',
- onMessage: function (msg) {
- test.assertEqual(msg, firstLocation,
- "Worker url is equal to the 1st document");
- tab.url = secondLocation;
- },
- onDetach: function () {
- detachEventCount++;
- test.pass("Got worker1 detach event");
- test.assertRaises(function () {
- worker1.postMessage("ex-1");
- },
- /The page has been destroyed/,
- "postMessage throw because worker1 is destroyed");
- checkEnd();
- }
- });
- worker1.postMessage("new-doc-1");
- }
- else if (onReadyCount == 2) {
-
- worker2 = tab.attach({
- contentScript: 'self.on("message", ' +
- ' function () self.postMessage(document.location.href)' +
- ');',
- onMessage: function (msg) {
- test.assertEqual(msg, secondLocation,
- "Worker url is equal to the 2nd document");
- tab.url = thirdLocation;
- },
- onDetach: function () {
- detachEventCount++;
- test.pass("Got worker2 detach event");
- test.assertRaises(function () {
- worker2.postMessage("ex-2");
- },
- /The page has been destroyed/,
- "postMessage throw because worker2 is destroyed");
- checkEnd();
- }
- });
- worker2.postMessage("new-doc-2");
- }
- else if (onReadyCount == 3) {
-
- tab.close();
-
- }
-
- }
- });
-
- function checkEnd() {
- if (detachEventCount != 2)
- return;
-
- test.pass("Got all detach events");
-
- closeBrowserWindow(window, function() test.done());
- }
-
- });
-}
-
-
-exports.testAttachWrappers = function (test) {
- // Check that content script has access to wrapped values by default
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let document = "data:text/html,<script>var globalJSVar = true; " +
- " document.getElementById = 3;</script>";
- let count = 0;
-
- tabs.open({
- url: document,
- onReady: function (tab) {
- let worker = tab.attach({
- contentScript: 'try {' +
- ' self.postMessage(!("globalJSVar" in window));' +
- ' self.postMessage(typeof window.globalJSVar == "undefined");' +
- '} catch(e) {' +
- ' self.postMessage(e.message);' +
- '}',
- onMessage: function (msg) {
- test.assertEqual(msg, true, "Worker has wrapped objects ("+count+")");
- if (count++ == 1)
- closeBrowserWindow(window, function() test.done());
- }
- });
- }
- });
-
- });
-}
-
-/*
-// We do not offer unwrapped access to DOM since bug 601295 landed
-// See 660780 to track progress of unwrap feature
-exports.testAttachUnwrapped = function (test) {
- // Check that content script has access to unwrapped values through unsafeWindow
- test.waitUntilDone();
- openBrowserWindow(function(window, browser) {
- let tabs = require("tabs");
- let document = "data:text/html,<script>var globalJSVar=true;</script>";
- let count = 0;
-
- tabs.open({
- url: document,
- onReady: function (tab) {
- let worker = tab.attach({
- contentScript: 'try {' +
- ' self.postMessage(unsafeWindow.globalJSVar);' +
- '} catch(e) {' +
- ' self.postMessage(e.message);' +
- '}',
- onMessage: function (msg) {
- test.assertEqual(msg, true, "Worker has access to javascript content globals ("+count+")");
- closeBrowserWindow(window, function() test.done());
- }
- });
- }
- });
-
- });
-}
-*/
-
-exports['test window focus changes active tab'] = function(test) {
- test.waitUntilDone();
- let win1 = openBrowserWindow(function() {
- let win2 = openBrowserWindow(function() {
- let tabs = require("tabs");
- tabs.on("activate", function onActivate() {
- tabs.removeListener("activate", onActivate);
- test.pass("activate was called on windows focus change.");
- closeBrowserWindow(win1, function() {
- closeBrowserWindow(win2, function() { test.done(); });
- });
- });
- win1.focus();
- }, "data:text/html,test window focus changes active tab</br><h1>Window #2");
- }, "data:text/html,test window focus changes active tab</br><h1>Window #1");
-};
-
-exports['test ready event on new window tab'] = function(test) {
- test.waitUntilDone();
- let uri = encodeURI("data:text/html,Waiting for ready event!");
-
- require("tabs").on("ready", function onReady(tab) {
- if (tab.url === uri) {
- require("tabs").removeListener("ready", onReady);
- test.pass("ready event was emitted");
- closeBrowserWindow(window, function() {
- test.done();
- });
- }
- });
-
- let window = openBrowserWindow(function(){}, uri);
-};
-/******************* helpers *********************/
-
-// Helper for getting the active window
-this.__defineGetter__("activeWindow", function activeWindow() {
- return Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator).
- getMostRecentWindow("navigator:browser");
-});
-
-// Utility function to open a new browser window.
-function openBrowserWindow(callback, url) {
- let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIWindowWatcher);
- let urlString = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- urlString.data = url;
- let window = ww.openWindow(null, "chrome://browser/content/browser.xul",
- "_blank", "chrome,all,dialog=no", urlString);
-
- if (callback) {
- window.addEventListener("load", function onLoad(event) {
- if (event.target && event.target.defaultView == window) {
- window.removeEventListener("load", onLoad, true);
- let browsers = window.document.getElementsByTagName("tabbrowser");
- try {
- require("timer").setTimeout(function () {
- callback(window, browsers[0]);
- }, 10);
- } catch (e) { console.exception(e); }
- }
- }, true);
- }
-
- return window;
-}
-
-// Helper for calling code at window close
-function closeBrowserWindow(window, callback) {
- window.addEventListener("unload", function unload() {
- window.removeEventListener("unload", unload, false);
- callback();
- }, false);
- window.close();
-}
-
-// If the module doesn't support the app we're being run in, require() will
-// throw. In that case, remove all tests above from exports, and add one dummy
-// test that passes.
-try {
- require("tabs");
-}
-catch (err) {
- // This bug should be mentioned in the error message.
- let bug = "https://bugzilla.mozilla.org/show_bug.cgi?id=560716";
- if (err.message.indexOf(bug) < 0)
- throw err;
- for (let [prop, val] in Iterator(exports)) {
- if (/^test/.test(prop) && typeof(val) === "function")
- delete exports[prop];
- }
- exports.testAppNotSupported = function (test) {
- test.pass("the tabs module does not support this application.");
- };
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-timers.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-timers.js
deleted file mode 100644
index 98ea613..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-timers.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shane Tomlinson <stomlinson@mozilla.com> (Original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-const timers = require("timers");
-
-exports.testTimeout = function (test) {
- test.waitUntilDone();
- timers.setTimeout(function () {
- test.pass("timers.setTimeout works");
- test.done();
- }, 0);
-}
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-widget.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-widget.js
deleted file mode 100644
index a5ab83c..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-widget.js
+++ /dev/null
@@ -1,950 +0,0 @@
-const {Cc,Ci} = require("chrome");
-const { Loader } = require('./helpers');
-
-exports.testConstructor = function(test) {
-
- const tabBrowser = require("tab-browser");
-
- test.waitUntilDone(30000);
-
- const widgets = require("widget");
- const url = require("url");
- const windowUtils = require("window-utils");
-
- let browserWindow = windowUtils.activeBrowserWindow;
- let doc = browserWindow.document;
- let AddonsMgrListener = browserWindow.AddonsMgrListener;
-
- function container() doc.getElementById("addon-bar");
- function widgetCount() container() ? container().getElementsByTagName("toolbaritem").length : 0;
- let widgetStartCount = widgetCount();
- function widgetNode(index) container() ? container().getElementsByTagName("toolbaritem")[index] : null;
-
- // Test basic construct/destroy
- AddonsMgrListener.onInstalling();
- let w = widgets.Widget({ id: "fooID", label: "foo", content: "bar" });
- AddonsMgrListener.onInstalled();
- test.assertEqual(widgetCount(), widgetStartCount + 1, "panel has correct number of child elements after widget construction");
-
- // test widget height
- test.assertEqual(widgetNode(0).firstChild.boxObject.height, 16, "widget has correct default height");
-
- AddonsMgrListener.onUninstalling();
- w.destroy();
- AddonsMgrListener.onUninstalled();
- w.destroy();
- test.pass("Multiple destroys do not cause an error");
- test.assertEqual(widgetCount(), widgetStartCount, "panel has correct number of child elements after destroy");
-
- // Test automatic widget destroy on unload
- let loader = Loader(module);
- let widgetsFromLoader = loader.require("widget");
- let widgetStartCount = widgetCount();
- let w = widgetsFromLoader.Widget({ id: "fooID", label: "foo", content: "bar" });
- test.assertEqual(widgetCount(), widgetStartCount + 1, "widget has been correctly added");
- loader.unload();
- test.assertEqual(widgetCount(), widgetStartCount, "widget has been destroyed on module unload");
-
- // Test nothing
- test.assertRaises(
- function() widgets.Widget({}),
- "The widget must have a non-empty label property.",
- "throws on no properties");
-
- // Test no label
- test.assertRaises(
- function() widgets.Widget({content: "foo"}),
- "The widget must have a non-empty label property.",
- "throws on no label");
-
- // Test empty label
- test.assertRaises(
- function() widgets.Widget({label: "", content: "foo"}),
- "The widget must have a non-empty label property.",
- "throws on empty label");
-
- // Test no content or image
- test.assertRaises(
- function() widgets.Widget({id: "fooID", label: "foo"}),
- "No content or contentURL property found. Widgets must have one or the other.",
- "throws on no content");
-
- // Test empty content, no image
- test.assertRaises(
- function() widgets.Widget({id:"fooID", label: "foo", content: ""}),
- "No content or contentURL property found. Widgets must have one or the other.",
- "throws on empty content");
-
- // Test empty image, no content
- test.assertRaises(
- function() widgets.Widget({id:"fooID", label: "foo", image: ""}),
- "No content or contentURL property found. Widgets must have one or the other.",
- "throws on empty content");
-
- // Test empty content, empty image
- test.assertRaises(
- function() widgets.Widget({id:"fooID", label: "foo", content: "", image: ""}),
- "No content or contentURL property found. Widgets must have one or the other.",
- "throws on empty content");
-
- // Test duplicated ID
- let duplicateID = widgets.Widget({id: "foo", label: "foo", content: "bar"});
- test.assertRaises(
- function() widgets.Widget({id: "foo", label: "bar", content: "bar"}),
- /This widget ID is already used:/,
- "throws on duplicated id");
- duplicateID.destroy();
-
- // Test duplicate label, different ID
- let w1 = widgets.Widget({id: "id1", label: "foo", content: "bar"});
- let w2 = widgets.Widget({id: "id2", label: "foo", content: "bar"});
- w1.destroy();
- w2.destroy();
-
- // Test position restore on create/destroy/create
- // Create 3 ordered widgets
- let w1 = widgets.Widget({id: "first", label:"first", content: "bar"});
- let w2 = widgets.Widget({id: "second", label:"second", content: "bar"});
- let w3 = widgets.Widget({id: "third", label:"third", content: "bar"});
- // Remove the middle widget
- test.assertEqual(widgetNode(1).getAttribute("label"), "second", "second widget is the second widget inserted");
- w2.destroy();
- test.assertEqual(widgetNode(1).getAttribute("label"), "third", "second widget is removed, so second widget is now the third one");
- w2 = widgets.Widget({id: "second", label:"second", content: "bar"});
- test.assertEqual(widgetNode(1).getAttribute("label"), "second", "second widget is created again, at the same location");
- // Cleanup this testcase
- AddonsMgrListener.onUninstalling();
- w1.destroy();
- w2.destroy();
- w3.destroy();
- AddonsMgrListener.onUninstalled();
-
- // Test concurrent widget module instances on addon-bar hiding
- let loader = Loader(module);
- let anotherWidgetsInstance = loader.require("widget");
- test.assert(container().collapsed, "UI is hidden when no widgets");
- AddonsMgrListener.onInstalling();
- let w1 = widgets.Widget({id: "foo", label: "foo", content: "bar"});
- // Ideally we would let AddonsMgrListener display the addon bar
- // But, for now, addon bar is immediatly displayed by sdk code
- // https://bugzilla.mozilla.org/show_bug.cgi?id=627484
- test.assert(!container().collapsed, "UI is already visible when we just added the widget");
- AddonsMgrListener.onInstalled();
- test.assert(!container().collapsed, "UI become visible when we notify AddonsMgrListener about end of addon installation");
- let w2 = anotherWidgetsInstance.Widget({id: "bar", label: "bar", content: "foo"});
- test.assert(!container().collapsed, "UI still visible when we add a second widget");
- AddonsMgrListener.onUninstalling();
- w1.destroy();
- AddonsMgrListener.onUninstalled();
- test.assert(!container().collapsed, "UI still visible when we remove one of two widgets");
- AddonsMgrListener.onUninstalling();
- w2.destroy();
- test.assert(!container().collapsed, "UI is still visible when we have removed all widget but still not called onUninstalled");
- AddonsMgrListener.onUninstalled();
- test.assert(container().collapsed, "UI is hidden when we have removed all widget and called onUninstalled");
-
- // Helper for testing a single widget.
- // Confirms proper addition and content setup.
- function testSingleWidget(widgetOptions) {
- // We have to display which test is being run, because here we do not
- // use the regular test framework but rather a custom one that iterates
- // the `tests` array.
- console.info("executing: " + widgetOptions.id);
-
- let startCount = widgetCount();
- let widget = widgets.Widget(widgetOptions);
- let node = widgetNode(startCount);
- test.assert(node, "widget node at index");
- test.assertEqual(node.tagName, "toolbaritem", "widget element is correct");
- test.assertEqual(widget.width + "px", node.style.minWidth, "widget width is correct");
- test.assertEqual(widgetCount(), startCount + 1, "container has correct number of child elements");
- let content = node.firstElementChild;
- test.assert(content, "found content");
- test.assertMatches(content.tagName, /iframe|image/, "content is iframe or image");
- return widget;
- }
-
- // Array of widgets to test
- // and a function to test them.
- let tests = [];
- function nextTest() {
- test.assertEqual(widgetCount(), 0, "widget in last test property cleaned itself up");
- if (!tests.length)
- test.done();
- else
- require("timer").setTimeout(tests.shift(), 0);
- }
- function doneTest() nextTest();
-
- // text widget
- tests.push(function testTextWidget() testSingleWidget({
- id: "text",
- label: "text widget",
- content: "oh yeah",
- contentScript: "self.postMessage(document.body.innerHTML);",
- contentScriptWhen: "end",
- onMessage: function (message) {
- test.assertEqual(this.content, message, "content matches");
- this.destroy();
- doneTest();
- }
- }));
-
- // html widget
- tests.push(function testHTMLWidget() testSingleWidget({
- id: "html",
- label: "html widget",
- content: "<div>oh yeah</div>",
- contentScript: "self.postMessage(document.body.innerHTML);",
- contentScriptWhen: "end",
- onMessage: function (message) {
- test.assertEqual(this.content, message, "content matches");
- this.destroy();
- doneTest();
- }
- }));
-
- // image url widget
- tests.push(function testImageURLWidget() testSingleWidget({
- id: "image",
- label: "image url widget",
- contentURL: require("self").data.url("test.html"),
- contentScript: "self.postMessage({title: document.title, " +
- "tag: document.body.firstElementChild.tagName, " +
- "content: document.body.firstElementChild.innerHTML});",
- contentScriptWhen: "end",
- onMessage: function (message) {
- test.assertEqual(message.title, "foo", "title matches");
- test.assertEqual(message.tag, "P", "element matches");
- test.assertEqual(message.content, "bar", "element content matches");
- this.destroy();
- doneTest();
- }
- }));
-
- // web uri widget
- tests.push(function testWebURIWidget() testSingleWidget({
- id: "web",
- label: "web uri widget",
- contentURL: require("self").data.url("test.html"),
- contentScript: "self.postMessage({title: document.title, " +
- "tag: document.body.firstElementChild.tagName, " +
- "content: document.body.firstElementChild.innerHTML});",
- contentScriptWhen: "end",
- onMessage: function (message) {
- test.assertEqual(message.title, "foo", "title matches");
- test.assertEqual(message.tag, "P", "element matches");
- test.assertEqual(message.content, "bar", "element content matches");
- this.destroy();
- doneTest();
- }
- }));
-
- // event: onclick + content
- tests.push(function testOnclickEventContent() testSingleWidget({
- id: "click",
- label: "click test widget - content",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('click', true, true ); " +
- "document.getElementById('me').dispatchEvent(evt);",
- contentScriptWhen: "end",
- onClick: function() {
- test.pass("onClick called");
- this.destroy();
- doneTest();
- }
- }));
-
- // event: onmouseover + content
- tests.push(function testOnmouseoverEventContent() testSingleWidget({
- id: "mouseover",
- label: "mouseover test widget - content",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('mouseover', true, true ); " +
- "document.getElementById('me').dispatchEvent(evt);",
- contentScriptWhen: "end",
- onMouseover: function() {
- test.pass("onMouseover called");
- this.destroy();
- doneTest();
- }
- }));
-
- // event: onmouseout + content
- tests.push(function testOnmouseoutEventContent() testSingleWidget({
- id: "mouseout",
- label: "mouseout test widget - content",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('mouseout', true, true ); " +
- "document.getElementById('me').dispatchEvent(evt);",
- contentScriptWhen: "end",
- onMouseout: function() {
- test.pass("onMouseout called");
- this.destroy();
- doneTest();
- }
- }));
-
- // event: onclick + image
- tests.push(function testOnclickEventImage() testSingleWidget({
- id: "click",
- label: "click test widget - image",
- contentURL: require("self").data.url("moz_favicon.ico"),
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('click', true, true ); " +
- "document.body.firstElementChild.dispatchEvent(evt);",
- contentScriptWhen: "end",
- onClick: function() {
- test.pass("onClick called");
- this.destroy();
- doneTest();
- }
- }));
-
- // event: onmouseover + image
- tests.push(function testOnmouseoverEventImage() testSingleWidget({
- id: "mouseover",
- label: "mouseover test widget - image",
- contentURL: require("self").data.url("moz_favicon.ico"),
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('mouseover', true, true ); " +
- "document.body.firstElementChild.dispatchEvent(evt);",
- contentScriptWhen: "end",
- onMouseover: function() {
- test.pass("onMouseover called");
- this.destroy();
- doneTest();
- }
- }));
-
- // event: onmouseout + image
- tests.push(function testOnmouseoutEventImage() testSingleWidget({
- id: "mouseout",
- label: "mouseout test widget - image",
- contentURL: require("self").data.url("moz_favicon.ico"),
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('mouseout', true, true ); " +
- "document.body.firstElementChild.dispatchEvent(evt);",
- contentScriptWhen: "end",
- onMouseout: function() {
- test.pass("onMouseout called");
- this.destroy();
- doneTest();
- }
- }));
-
- // test multiple widgets
- tests.push(function testMultipleWidgets() {
- let w1 = widgets.Widget({id: "first", label: "first widget", content: "first content"});
- let w2 = widgets.Widget({id: "second", label: "second widget", content: "second content"});
-
- w1.destroy();
- w2.destroy();
-
- doneTest();
- });
-
- // test updating widget content
- let loads = 0;
- tests.push(function testUpdatingWidgetContent() testSingleWidget({
- id: "content",
- label: "content update test widget",
- content: "<div id='me'>foo</div>",
- contentScript: "self.postMessage(1)",
- contentScriptWhen: "ready",
- onMessage: function(message) {
- if (!this.flag) {
- this.content = "<div id='me'>bar</div>";
- this.flag = 1;
- }
- else {
- test.assertEqual(this.content, "<div id='me'>bar</div>");
- this.destroy();
- doneTest();
- }
- }
- }));
-
- // test updating widget contentURL
- let url1 = "data:text/html,<body>foodle</body>";
- let url2 = "data:text/html,<body>nistel</body>";
-
- tests.push(function testUpdatingContentURL() testSingleWidget({
- id: "content",
- label: "content update test widget",
- contentURL: url1,
- contentScript: "self.postMessage(document.location.href);",
- contentScriptWhen: "end",
- onMessage: function(message) {
- if (!this.flag) {
- test.assertEqual(this.contentURL.toString(), url1);
- test.assertEqual(message, url1);
- this.contentURL = url2;
- this.flag = 1;
- }
- else {
- test.assertEqual(this.contentURL.toString(), url2);
- test.assertEqual(message, url2);
- this.destroy();
- doneTest();
- }
- }
- }));
-
- // test tooltip
- tests.push(function testTooltip() testSingleWidget({
- id: "text",
- label: "text widget",
- content: "oh yeah",
- tooltip: "foo",
- contentScript: "self.postMessage(1)",
- contentScriptWhen: "ready",
- onMessage: function(message) {
- test.assertEqual(this.tooltip, "foo", "tooltip matches");
- this.destroy();
- doneTest();
- }
- }));
-
- // test tooltip fallback to label
- tests.push(function testTooltipFallback() testSingleWidget({
- id: "fallback",
- label: "fallback",
- content: "oh yeah",
- contentScript: "self.postMessage(1)",
- contentScriptWhen: "ready",
- onMessage: function(message) {
- test.assertEqual(this.tooltip, this.label, "tooltip fallbacks to label");
- this.destroy();
- doneTest();
- }
- }));
-
- // test updating widget tooltip
- let updated = false;
- tests.push(function testUpdatingTooltip() testSingleWidget({
- id: "tooltip",
- label: "tooltip update test widget",
- tooltip: "foo",
- content: "<div id='me'>foo</div>",
- contentScript: "self.postMessage(1)",
- contentScriptWhen: "ready",
- onMessage: function(message) {
- this.tooltip = "bar";
- test.assertEqual(this.tooltip, "bar", "tooltip gets updated");
- this.destroy();
- doneTest();
- }
- }));
-
- // test allow attribute
- tests.push(function testDefaultAllow() testSingleWidget({
- id: "allow",
- label: "allow.script attribute",
- content: "<script>document.title = 'ok';</script>",
- contentScript: "self.postMessage(document.title)",
- onMessage: function(message) {
- test.assertEqual(message, "ok", "scripts are evaluated by default");
- this.destroy();
- doneTest();
- }
- }));
-
- tests.push(function testExplicitAllow() testSingleWidget({
- id: "allow",
- label: "allow.script attribute",
- allow: {script: true},
- content: "<script>document.title = 'ok';</script>",
- contentScript: "self.postMessage(document.title)",
- onMessage: function(message) {
- test.assertEqual(message, "ok", "scripts are evaluated when we want to");
- this.destroy();
- doneTest();
- }
- }));
-
- tests.push(function testExplicitDisallow() testSingleWidget({
- id: "allow",
- label: "allow.script attribute",
- content: "<script>document.title = 'ok';</script>",
- allow: {script: false},
- contentScript: "self.postMessage(document.title)",
- onMessage: function(message) {
- test.assertNotEqual(message, "ok", "scripts aren't evaluated when " +
- "explicitly blocked it");
- this.destroy();
- doneTest();
- }
- }));
-
- // test multiple windows
- tests.push(function testMultipleWindows() {
- tabBrowser.addTab("about:blank", { inNewWindow: true, onLoad: function(e) {
- let browserWindow = e.target.defaultView;
- let doc = browserWindow.document;
- function container() doc.getElementById("addon-bar");
- function widgetCount2() container() ? container().childNodes.length : 0;
- let widgetStartCount2 = widgetCount2();
-
- let w1Opts = {id:"first", label: "first widget", content: "first content"};
- let w1 = testSingleWidget(w1Opts);
- test.assertEqual(widgetCount2(), widgetStartCount2 + 1, "2nd window has correct number of child elements after first widget");
-
- let w2Opts = {id:"second", label: "second widget", content: "second content"};
- let w2 = testSingleWidget(w2Opts);
- test.assertEqual(widgetCount2(), widgetStartCount2 + 2, "2nd window has correct number of child elements after second widget");
-
- w1.destroy();
- test.assertEqual(widgetCount2(), widgetStartCount2 + 1, "2nd window has correct number of child elements after first destroy");
- w2.destroy();
- test.assertEqual(widgetCount2(), widgetStartCount2, "2nd window has correct number of child elements after second destroy");
-
- closeBrowserWindow(browserWindow, function() {
- doneTest();
- });
- }});
- });
-
- // test window closing
- tests.push(function testWindowClosing() {
- // 1/ Create a new widget
- let w1Opts = {
- id:"first",
- label: "first widget",
- content: "first content",
- contentScript: "self.port.on('event', function () self.port.emit('event'))"
- };
- let widget = testSingleWidget(w1Opts);
- let windows = require("windows").browserWindows;
-
- // 2/ Retrieve a WidgetView for the initial browser window
- let acceptDetach = false;
- let mainView = widget.getView(windows.activeWindow);
- test.assert(mainView, "Got first widget view");
- mainView.on("detach", function () {
- // 8/ End of our test. Accept detach event only when it occurs after
- // widget.destroy()
- if (acceptDetach)
- doneTest();
- else
- test.fail("View on initial window should not be destroyed");
- });
- mainView.port.on("event", function () {
- // 7/ Receive event sent during 6/ and cleanup our test
- acceptDetach = true;
- widget.destroy();
- });
-
- // 3/ First: open a new browser window
- windows.open({
- url: "about:blank",
- onOpen: function(window) {
- // 4/ Retrieve a WidgetView for this new window
- let view = widget.getView(window);
- test.assert(view, "Got second widget view");
- view.port.on("event", function () {
- test.fail("We should not receive event on the detach view");
- });
- view.on("detach", function () {
- // The related view is destroyed
- // 6/ Send a custom event
- test.assertRaises(function () {
- view.port.emit("event");
- },
- /The widget has been destroyed and can no longer be used./,
- "emit on a destroyed view should throw");
- widget.port.emit("event");
- });
-
- // 5/ Destroy this window
- window.close();
- }
- });
- });
-
- tests.push(function testAddonBarHide() {
- // Hide the addon-bar
- browserWindow.setToolbarVisibility(container(), false);
-
- // Then open a browser window and verify that the addon-bar remains hidden
- tabBrowser.addTab("about:blank", { inNewWindow: true, onLoad: function(e) {
- let browserWindow = e.target.defaultView;
- let doc = browserWindow.document;
- function container2() doc.getElementById("addon-bar");
- function widgetCount2() container2() ? container2().childNodes.length : 0;
- let widgetStartCount2 = widgetCount2();
-
- let w1Opts = {id:"first", label: "first widget", content: "first content"};
- let w1 = testSingleWidget(w1Opts);
- test.assertEqual(widgetCount2(), widgetStartCount2 + 1, "2nd window has correct number of child elements after widget creation");
-
- w1.destroy();
- test.assertEqual(widgetCount2(), widgetStartCount2, "2nd window has correct number of child elements after widget destroy");
-
- test.assert(container().collapsed, "1st window has an hidden addon-bar");
- test.assert(container2().collapsed, "2nd window has an hidden addon-bar");
-
- browserWindow.setToolbarVisibility(container(), true);
-
- closeBrowserWindow(browserWindow, function() {
- doneTest();
- });
- }});
- });
-
- // test widget.width
- tests.push(function testWidgetWidth() testSingleWidget({
- id: "text",
- label: "test widget.width",
- content: "test width",
- width: 200,
- contentScript: "self.postMessage(1)",
- contentScriptWhen: "ready",
- onMessage: function(message) {
- test.assertEqual(this.width, 200);
-
- let node = widgetNode(0);
- test.assertEqual(this.width, node.style.minWidth.replace("px", ""));
- test.assertEqual(this.width, node.firstElementChild.style.width.replace("px", ""));
- this.width = 300;
- test.assertEqual(this.width, node.style.minWidth.replace("px", ""));
- test.assertEqual(this.width, node.firstElementChild.style.width.replace("px", ""));
-
- this.destroy();
- doneTest();
- }
- }));
-
- // test click handler not respond to right-click
- let clickCount = 0;
- tests.push(function testNoRightClick() testSingleWidget({
- id: "click-content",
- label: "click test widget - content",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('MouseEvents'); " +
- "evt.initMouseEvent('click', true, true, window, " +
- " 0, 0, 0, 0, 0, false, false, false, false, 2, null); " +
- "document.getElementById('me').dispatchEvent(evt); " +
- "evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('click', true, true ); " +
- "document.getElementById('me').dispatchEvent(evt); " +
- "evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('mouseover', true, true ); " +
- "document.getElementById('me').dispatchEvent(evt);",
- contentScriptWhen: "end",
- onClick: function() clickCount++,
- onMouseover: function() {
- test.assertEqual(clickCount, 1, "right click wasn't sent to click handler");
- this.destroy();
- doneTest();
- }
- }));
-
- // kick off test execution
- doneTest();
-};
-
-exports.testPanelWidget1 = function testPanelWidget1(test) {
- const widgets = require("widget");
-
- let widget1 = widgets.Widget({
- id: "panel1",
- label: "panel widget 1",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('click', true, true ); " +
- "document.body.dispatchEvent(evt);",
- contentScriptWhen: "end",
- panel: require("panel").Panel({
- contentURL: "data:text/html,<body>Look ma, a panel!</body>",
- onShow: function() {
- widget1.destroy();
- test.pass("panel displayed on click");
- test.done();
- }
- })
- });
- test.waitUntilDone();
-};
-
-exports.testPanelWidget2 = function testPanelWidget2(test) {
- const widgets = require("widget");
- test.assertRaises(
- function() {
- widgets.Widget({
- id: "panel2",
- label: "panel widget 2",
- panel: {}
- });
- },
- "The option \"panel\" must be one of the following types: null, undefined, object",
- "widget.panel must be a Panel object"
- );
-};
-
-exports.testPanelWidget3 = function testPanelWidget3(test) {
- const widgets = require("widget");
- let onClickCalled = false;
- let widget3 = widgets.Widget({
- id: "panel3",
- label: "panel widget 3",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('click', true, true ); " +
- "document.body.firstElementChild.dispatchEvent(evt);",
- contentScriptWhen: "end",
- onClick: function() {
- onClickCalled = true;
- this.panel.show();
- },
- panel: require("panel").Panel({
- contentURL: "data:text/html,<body>Look ma, a panel!</body>",
- onShow: function() {
- test.assert(
- onClickCalled,
- "onClick called on click for widget with both panel and onClick"
- );
- widget3.destroy();
- test.done();
- }
- })
- });
- test.waitUntilDone();
-};
-
-exports.testWidgetMessaging = function testWidgetMessaging(test) {
- test.waitUntilDone();
- let origMessage = "foo";
- const widgets = require("widget");
- let widget = widgets.Widget({
- id: "foo",
- label: "foo",
- content: "<bar>baz</bar>",
- contentScriptWhen: "end",
- contentScript: "self.on('message', function(data) { self.postMessage(data); }); self.postMessage('ready');",
- onMessage: function(message) {
- if (message == "ready")
- widget.postMessage(origMessage);
- else {
- test.assertEqual(origMessage, message);
- widget.destroy();
- test.done();
- }
- }
- });
-};
-
-exports.testWidgetViews = function testWidgetViews(test) {
- test.waitUntilDone();
- const widgets = require("widget");
- let widget = widgets.Widget({
- id: "foo",
- label: "foo",
- content: "<bar>baz</bar>",
- contentScriptWhen: "ready",
- contentScript: "self.on('message', function(data) self.postMessage(data)); self.postMessage('ready')",
- onAttach: function(view) {
- test.pass("WidgetView created");
- view.on("message", function () {
- test.pass("Got message in WidgetView");
- widget.destroy();
- });
- view.on("detach", function () {
- test.pass("WidgetView destroyed");
- test.done();
- });
- }
- });
-
-};
-
-exports.testWidgetViewsUIEvents = function testWidgetViewsUIEvents(test) {
- test.waitUntilDone();
- const widgets = require("widget");
- let view = null;
- let widget = widgets.Widget({
- id: "foo",
- label: "foo",
- content: "<div id='me'>foo</div>",
- contentScript: "var evt = document.createEvent('HTMLEvents'); " +
- "evt.initEvent('click', true, true ); " +
- "document.getElementById('me').dispatchEvent(evt);",
- contentScriptWhen: "ready",
- onAttach: function(attachView) {
- view = attachView;
- test.pass("Got attach event");
- },
- onClick: function (eventView) {
- test.assertEqual(view, eventView,
- "event first argument is equal to the WidgetView");
- let view2 = widget.getView(require("windows").browserWindows.activeWindow);
- test.assertEqual(view, view2,
- "widget.getView return the same WidgetView");
- widget.destroy();
- test.done();
- }
- });
-};
-
-exports.testWidgetViewsCustomEvents = function testWidgetViewsCustomEvents(test) {
- test.waitUntilDone();
- const widgets = require("widget");
- let widget = widgets.Widget({
- id: "foo",
- label: "foo",
- content: "<div id='me'>foo</div>",
- contentScript: "self.port.emit('event', 'ok');",
- contentScriptWhen: "ready",
- onAttach: function(view) {
- view.port.on("event", function (data) {
- test.assertEqual(data, "ok",
- "event argument is valid on WidgetView");
- });
- },
- });
- widget.port.on("event", function (data) {
- test.assertEqual(data, "ok",
- "event argument is valid on Widget");
- widget.destroy();
- test.done();
- });
-};
-
-exports.testWidgetViewsTooltip = function testWidgetViewsTooltip(test) {
- test.waitUntilDone();
- const widgets = require("widget");
-
- let widget = new widgets.Widget({
- id: "foo",
- label: "foo",
- content: "foo"
- });
- let view = widget.getView(require("windows").browserWindows.activeWindow);
- widget.tooltip = null;
- test.assertEqual(view.tooltip, "foo",
- "view tooltip defaults to base widget label");
- test.assertEqual(widget.tooltip, "foo",
- "tooltip defaults to base widget label");
- widget.destroy();
- test.done();
-};
-
-exports.testWidgetMove = function testWidgetMove(test) {
- test.waitUntilDone();
-
- let windowUtils = require("window-utils");
- let widgets = require("widget");
-
- let browserWindow = windowUtils.activeBrowserWindow;
- let doc = browserWindow.document;
-
- let label = "unique-widget-label";
- let origMessage = "message after node move";
- let gotFirstReady = false;
-
- let widget = widgets.Widget({
- id: "foo",
- label: label,
- content: "<bar>baz</bar>",
- contentScriptWhen: "ready",
- contentScript: "self.on('message', function(data) { self.postMessage(data); }); self.postMessage('ready');",
- onMessage: function(message) {
- if (message == "ready") {
- if (!gotFirstReady) {
- test.pass("Got first ready event");
- let widgetNode = doc.querySelector('toolbaritem[label="' + label + '"]');
- let parent = widgetNode.parentNode;
- parent.insertBefore(widgetNode, parent.firstChild);
- gotFirstReady = true;
- } else {
- test.pass("Got second ready event");
- widget.postMessage(origMessage);
- }
- }
- else {
- test.assertEqual(origMessage, message, "Got message after node move");
- widget.destroy();
- test.done();
- }
- }
- });
-};
-
-/*
-The bug is exhibited when a widget with HTML content has it's content
-changed to new HTML content with a pound in it. Because the src of HTML
-content is converted to a data URI, the underlying iframe doesn't
-consider the content change a navigation change, so doesn't load
-the new content.
-*/
-exports.testWidgetWithPound = function testWidgetWithPound(test) {
- test.waitUntilDone();
-
- function getWidgetContent(widget) {
- let windowUtils = require("window-utils");
- let browserWindow = windowUtils.activeBrowserWindow;
- let doc = browserWindow.document;
- let widgetNode = doc.querySelector('toolbaritem[label="' + widget.label + '"]');
- test.assert(widgetNode, 'found widget node in the front-end');
- return widgetNode.firstChild.contentDocument.body.innerHTML;
- }
-
- let widgets = require("widget");
- let count = 0;
- let widget = widgets.Widget({
- id: "1",
- label: "foo",
- content: "foo",
- contentScript: "window.addEventListener('load', self.postMessage, false);",
- onMessage: function() {
- count++;
- if (count == 1) {
- widget.content = "foo#";
- }
- else {
- test.assertEqual(getWidgetContent(widget), "foo#", "content updated to pound?");
- widget.destroy();
- test.done();
- }
- }
- });
-};
-
-/******************* helpers *********************/
-
-// Helper for calling code at window close
-function closeBrowserWindow(window, callback) {
- require("timer").setTimeout(function() {
- window.addEventListener("unload", function onUnload() {
- window.removeEventListener("unload", onUnload, false);
- callback();
- }, false);
- window.close();
- }, 0);
-}
-
-// ADD NO TESTS BELOW THIS LINE! ///////////////////////////////////////////////
-
-// If the module doesn't support the app we're being run in, require() will
-// throw. In that case, remove all tests above from exports, and add one dummy
-// test that passes.
-try {
- require("widget");
-}
-catch (err) {
- // This bug should be mentioned in the error message.
- let bug = "https://bugzilla.mozilla.org/show_bug.cgi?id=560716";
- if (err.message.indexOf(bug) < 0)
- throw err;
- for (let [prop, val] in Iterator(exports)) {
- if (/^test/.test(prop) && typeof(val) === "function")
- delete exports[prop];
- }
- exports.testAppNotSupported = function (test) {
- test.pass("context-menu does not support this application.");
- };
-}
-
diff --git a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-windows.js b/tools/addon-sdk-1.4/packages/addon-kit/tests/test-windows.js
deleted file mode 100644
index e2824f8..0000000
--- a/tools/addon-sdk-1.4/packages/addon-kit/tests/test-windows.js
+++ /dev/null
@@ -1,342 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Jetpack.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Felipe Gomes <felipc@gmail.com> (Original author)
- * Irakli Gozalishvili <gozala@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const {Cc, Ci} = require("chrome");
-const { setTimeout } = require("timer");
-const { Loader } = require('./helpers');
-const wm = Cc["@mozilla.org/appshell/window-mediator;1"].
- getService(Ci.nsIWindowMediator);
-let browserWindows;
-
-function getTestRunnerWindow() wm.getMostRecentWindow("test:runner")
-
-exports.testOpenAndCloseWindow = function(test) {
- test.waitUntilDone();
-
- test.assertEqual(browserWindows.length, 1, "Only one window open");
-
- browserWindows.open({
- url: "data:text/html,<title>windows API test</title>",
- onOpen: function(window) {
- test.assertEqual(this, browserWindows,
- "The 'this' object is the windows object.");
- test.assertEqual(window.tabs.length, 1, "Only one tab open");
- test.assertEqual(browserWindows.length, 2, "Two windows open");
- window.tabs.activeTab.on('ready', function onReady(tab) {
- tab.removeListener('ready', onReady);
- test.assert(window.title.indexOf("windows API test") != -1,
- "URL correctly loaded");
- window.close();
- });
- },
- onClose: function(window) {
- test.assertEqual(window.tabs.length, 0, "Tabs were cleared");
- test.assertEqual(browserWindows.length, 1, "Only one window open");
- test.done();
- }
- });
-};
-
-exports.testAutomaticDestroy = function(test) {
-
- test.waitUntilDone();
- let windows = browserWindows;
-
- // Create a second windows instance that we will unload
- let called = false;
- let loader = Loader(module);
- let windows2 = loader.require("windows").browserWindows;
- windows2.on("open", function() {
- called = true;
- });
-
- loader.unload();
-
- // Fire a windows event and check that this unloaded instance is inactive
- windows.open({
- url: "data:text/html,foo",
- onOpen: function(window) {
- setTimeout(function () {
- test.assert(!called,
- "Unloaded windows instance is destroyed and inactive");
- window.close(function () {
- test.done();
- });
- });
- }
- });
-
-};
-
-exports.testOnOpenOnCloseListeners = function(test) {
- test.waitUntilDone();
- let windows = browserWindows;
-
- test.assertEqual(browserWindows.length, 1, "Only one window open");
-
- let received = {
- listener1: false,
- listener2: false,
- listener3: false,
- listener4: false
- }
-
- function listener1() {
- test.assertEqual(this, windows, "The 'this' object is the windows object.");
- if (received.listener1)
- test.fail("Event received twice");
- received.listener1 = true;
- }
-
- function listener2() {
- if (received.listener2)
- test.fail("Event received twice");
- received.listener2 = true;
- }
-
- function listener3() {
- test.assertEqual(this, windows, "The 'this' object is the windows object.");
- if (received.listener3)
- test.fail("Event received twice");
- received.listener3 = true;
- }
-
- function listener4() {
- if (received.listener4)
- test.fail("Event received twice");
- received.listener4 = true;
- }
-
- windows.on('open', listener1);
- windows.on('open', listener2);
- windows.on('close', listener3);
- windows.on('close', listener4);
-
- function verify() {
- test.assert(received.listener1, "onOpen handler called");
- test.assert(received.listener2, "onOpen handler called");
- test.assert(received.listener3, "onClose handler called");
- test.assert(received.listener4, "onClose handler called");
-
- windows.removeListener('open', listener1);
- windows.removeListener('open', listener2);
- windows.removeListener('close', listener3);
- windows.removeListener('close', listener4);
- test.done();
- }
-
-
- windows.open({
- url: "data:text/html,foo",
- onOpen: function(window) {
- window.close(verify);
- }
- });
-};
-
-exports.testWindowTabsObject = function(test) {
- test.waitUntilDone();
-
- browserWindows.open({
- url: "data:text/html,<title>tab 1</title>",
- onOpen: function onOpen(window) {
- test.assertEqual(window.tabs.length, 1, "Only 1 tab open");
-
- window.tabs.open({
- url: "data:text/html,<title>tab 2</title>",
- inBackground: true,
- onReady: function onReady(newTab) {
- test.assertEqual(window.tabs.length, 2, "New tab open");
- test.assertEqual(newTab.title, "tab 2", "Correct new tab title");
- test.assertEqual(window.tabs.activeTab.title, "tab 1", "Correct active tab");
-
- let i = 1;
- for each (let tab in window.tabs)
- test.assertEqual(tab.title, "tab " + i++, "Correct title");
-
- window.close();
- }
- });
- },
- onClose: function onClose(window) {
- test.assertEqual(window.tabs.length, 0, "No more tabs on closed window");
- test.done();
- }
- });
-};
-
-exports.testActiveWindow = function(test) {
- const xulApp = require("xul-app");
- if (xulApp.versionInRange(xulApp.platformVersion, "1.9.2", "1.9.2.*")) {
- test.pass("This test is disabled on 3.6. For more information, see bug 598525");
- return;
- }
-
- let windows = browserWindows;
-
- // API window objects
- let window2, window3;
-
- // Raw window objects
- let nonBrowserWindow = getTestRunnerWindow(), rawWindow2, rawWindow3;
-
- test.waitUntilDone();
-
- let testSteps = [
- function() {
- test.assertEqual(windows.length, 3, "Correct number of browser windows");
- let count = 0;
- for (let window in windows)
- count++;
- test.assertEqual(count, 3, "Correct number of windows returned by iterator");
-
- rawWindow2.focus();
- continueAfterFocus(rawWindow2);
- },
- function() {
- nonBrowserWindow.focus();
- continueAfterFocus(nonBrowserWindow);
- },
- function() {
- /**
- * Bug 614079: This test fails intermittently on some specific linux
- * environnements, without being able to reproduce it in same
- * distribution with same window manager.
- * Disable it until being able to reproduce it easily.
-
- // On linux, focus is not consistent, so we can't be sure
- // what window will be on top.
- // Here when we focus "non-browser" window,
- // Any Browser window may be selected as "active".
- test.assert(windows.activeWindow == window2 || windows.activeWindow == window3,
- "Non-browser windows aren't handled by this module");
- */
- window2.activate();
- continueAfterFocus(rawWindow2);
- },
- function() {
- test.assertEqual(windows.activeWindow.title, window2.title, "Correct active window - 2");
- window3.activate();
- continueAfterFocus(rawWindow3);
- },
- function() {
- test.assertEqual(windows.activeWindow.title, window3.title, "Correct active window - 3");
- nonBrowserWindow.focus();
- finishTest();
- }
- ];
-
- windows.open({
- url: "data:text/html,<title>window 2</title>",
- onOpen: function(window) {
- window2 = window;
- rawWindow2 = wm.getMostRecentWindow("navigator:browser");
-
- windows.open({
- url: "data:text/html,<title>window 3</title>",
- onOpen: function(window) {
- window.tabs.activeTab.on('ready', function onReady() {
- window3 = window;
- rawWindow3 = wm.getMostRecentWindow("navigator:browser");
- nextStep()
- });
- }
- });
- }
- });
-
- function nextStep() {
- if (testSteps.length > 0)
- testSteps.shift()();
- }
-
- function continueAfterFocus(targetWindow) {
-
- // Based on SimpleTest.waitForFocus
- var fm = Cc["@mozilla.org/focus-manager;1"].
- getService(Ci.nsIFocusManager);
-
- var childTargetWindow = {};
- fm.getFocusedElementForWindow(targetWindow, true, childTargetWindow);
- childTargetWindow = childTargetWindow.value;
-
- var focusedChildWindow = {};
- if (fm.activeWindow) {
- fm.getFocusedElementForWindow(fm.activeWindow, true, focusedChildWindow);
- focusedChildWindow = focusedChildWindow.value;
- }
-
- var focused = (focusedChildWindow == childTargetWindow);
- if (focused) {
- nextStep();
- } else {
- childTargetWindow.addEventListener("focus", function focusListener() {
- childTargetWindow.removeEventListener("focus", focusListener, true);
- nextStep();
- }, true);
- }
-
- }
-
- function finishTest() {
- window3.close(function() {
- window2.close(function() {
- test.done();
- });
- });
- }
-};
-
-// If the module doesn't support the app we're being run in, require() will
-// throw. In that case, remove all tests above from exports, and add one dummy
-// test that passes.
-try {
- browserWindows = require("windows").browserWindows;
-}
-catch (err) {
- // This bug should be mentioned in the error message.
- let bug = "https://bugzilla.mozilla.org/show_bug.cgi?id=571449";
- if (err.message.indexOf(bug) < 0)
- throw err;
- for (let [prop, val] in Iterator(exports)) {
- if (/^test/.test(prop) && typeof(val) === "function")
- delete exports[prop];
- }
- exports.testAppNotSupported = function (test) {
- test.pass("the windows module does not support this application.");
- };
-}