mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out a104642698a0 (bug 842762) for b2g test bustage
CLOSED TREE
This commit is contained in:
parent
e27a914398
commit
93af72da81
@ -38,8 +38,8 @@ Bugs
|
||||
|
||||
* file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
|
||||
|
||||
|
||||
Style Guidelines
|
||||
--------------------
|
||||
|
||||
* https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide
|
||||
* https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide
|
||||
|
||||
|
57
addon-sdk/source/app-extension/bootstrap.js
vendored
57
addon-sdk/source/app-extension/bootstrap.js
vendored
@ -55,6 +55,29 @@ function readURI(uri) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Utility function that converts cfx-py generated paths to a
|
||||
// module ids.
|
||||
function path2id(path) {
|
||||
// Strips out `/lib` and `.js` from package/lib/path.js
|
||||
return path.replace(/([^\/]*)\/lib/, '$1').replace(/.js$/, '');
|
||||
}
|
||||
// Utility function that takes old manifest format and creates a manifest
|
||||
// in a new format: https://github.com/mozilla/addon-sdk/wiki/JEP-Linker
|
||||
function manifestV2(manifest) {
|
||||
return Object.keys(manifest).reduce(function(result, path) {
|
||||
let entry = manifest[path];
|
||||
let id = path2id(path);
|
||||
let requirements = entry.requirements || {};
|
||||
result[id] = {
|
||||
requirements: Object.keys(requirements).reduce(function(result, path) {
|
||||
result[path] = path2id(requirements[path].path);
|
||||
return result;
|
||||
}, {})
|
||||
};
|
||||
return result
|
||||
}, {});
|
||||
}
|
||||
|
||||
// We don't do anything on install & uninstall yet, but in a future
|
||||
// we should allow add-ons to cleanup after uninstall.
|
||||
function install(data, reason) {}
|
||||
@ -92,31 +115,19 @@ function startup(data, reasonCode) {
|
||||
resourceHandler.setSubstitution(domain, resourcesURI);
|
||||
|
||||
// Create path to URLs mapping supported by loader.
|
||||
let paths = {
|
||||
let paths = Object.keys(options.metadata).reduce(function(result, name) {
|
||||
result[name + '/'] = prefixURI + name + '/lib/'
|
||||
result[name + '/tests/'] = prefixURI + name + '/tests/'
|
||||
return result
|
||||
}, {
|
||||
// Relative modules resolve to add-on package lib
|
||||
'./': prefixURI + name + '/lib/',
|
||||
'./tests/': prefixURI + name + '/tests/',
|
||||
'': 'resource://gre/modules/commonjs/'
|
||||
};
|
||||
|
||||
// Maps addon lib and tests ressource folders
|
||||
paths[name + '/'] = prefixURI + name + '/lib/';
|
||||
paths[name + '/tests/'] = prefixURI + name + '/tests/';
|
||||
// We need to map tests folder when we run sdk tests whose package name
|
||||
// is stripped
|
||||
if (name == 'addon-sdk')
|
||||
paths['tests/'] = prefixURI + name + '/tests/';
|
||||
|
||||
// Maps sdk module folders to their resource folder
|
||||
paths['sdk/'] = prefixURI + 'addon-sdk/lib/sdk/';
|
||||
paths['toolkit/'] = prefixURI + 'addon-sdk/lib/toolkit/';
|
||||
// test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
|
||||
// so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
|
||||
// until we no longer support SDK modules in XPI:
|
||||
paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
|
||||
'toolkit/': 'resource://gre/modules/toolkit/',
|
||||
'': 'resources:///modules/'
|
||||
});
|
||||
|
||||
// Make version 2 of the manifest
|
||||
let manifest = options.manifest;
|
||||
let manifest = manifestV2(options.manifest);
|
||||
|
||||
// Import `cuddlefish.js` module using a Sandbox and bootstrap loader.
|
||||
let cuddlefishURI = prefixURI + options.loader;
|
||||
@ -125,7 +136,7 @@ function startup(data, reasonCode) {
|
||||
|
||||
// Normalize `options.mainPath` so that it looks like one that will come
|
||||
// in a new version of linker.
|
||||
let main = options.mainPath;
|
||||
let main = path2id(options.mainPath);
|
||||
|
||||
unload = cuddlefish.unload;
|
||||
loader = cuddlefish.Loader({
|
||||
@ -169,7 +180,7 @@ function startup(data, reasonCode) {
|
||||
}
|
||||
});
|
||||
|
||||
let module = cuddlefish.Module('sdk/loader/cuddlefish', cuddlefishURI);
|
||||
let module = cuddlefish.Module('addon-sdk/sdk/loader/cuddlefish', cuddlefishURI);
|
||||
let require = cuddlefish.Require(loader, module);
|
||||
|
||||
require('sdk/addon/runner').startup(reason, {
|
||||
|
@ -18,7 +18,7 @@
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>18.0</em:minVersion>
|
||||
<em:maxVersion>21.0a1</em:maxVersion>
|
||||
<em:maxVersion>20.*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -10,11 +10,9 @@
|
||||
<body>
|
||||
<p id="paragraph">Lorem ipsum dolor sit amet.</p>
|
||||
<script>
|
||||
if ("addon" in window) {
|
||||
addon.port.on('addon-to-document', function (arg) {
|
||||
addon.port.emit('document-to-addon', arg);
|
||||
});
|
||||
}
|
||||
addon.port.on('addon-to-document', function (arg) {
|
||||
addon.port.emit('document-to-addon', arg);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -11,144 +11,58 @@ We'd like to thank our many Jetpack project contributors! They include:
|
||||
* arky
|
||||
* [Heather Arthur](https://github.com/harthur)
|
||||
* Dietrich Ayala
|
||||
|
||||
<!--end-->
|
||||
|
||||
* [Romain B](https://github.com/Niamor)
|
||||
* [Louis-Rémi Babé](https://github.com/louisremi)
|
||||
* Will Bamberg
|
||||
* Thomas Bassetto
|
||||
* Tomaz Bevec
|
||||
* Zbigniew Braniecki
|
||||
* Daniel Buchner
|
||||
* James Burke
|
||||
|
||||
<!--end-->
|
||||
|
||||
* [Shane Caraveo](https://github.com/mixedpuppy)
|
||||
* [Matěj Cepl](https://github.com/mcepl)
|
||||
* Marc Chevrier
|
||||
* Hernán Rodriguez Colmeiro
|
||||
* [David Creswick](https://github.com/dcrewi)
|
||||
|
||||
<!--end-->
|
||||
|
||||
* dexter
|
||||
* Christopher Dorn
|
||||
* Connor Dunn
|
||||
* dynamis
|
||||
|
||||
<!--end-->
|
||||
|
||||
* [Matteo Ferretti (ZER0)](https://github.com/ZER0)
|
||||
* fuzzykiller
|
||||
|
||||
<!--end-->
|
||||
|
||||
* [Marcio Galli](https://github.com/taboca)
|
||||
* [Ben Gillbanks](http://www.iconfinder.com/browse/iconset/circular_icons/)
|
||||
* Felipe Gomes
|
||||
* Irakli Gozalishvili
|
||||
* Luca Greco
|
||||
* Jeff Griffiths
|
||||
* [David Guo](https://github.com/dglol)
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Mark Hammond
|
||||
* Mark A. Hershberger
|
||||
* Lloyd Hilaiel
|
||||
* Bobby Holley
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Shun Ikejima
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Eric H. Jung
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Hrishikesh Kale
|
||||
* Wes Kocher
|
||||
* Lajos Koszti
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Edward Lee
|
||||
* Gregg Lind
|
||||
|
||||
<!--end-->
|
||||
|
||||
* [Nils Maier](https://github.com/nmaier)
|
||||
* Gervase Markham
|
||||
* Dave Mason
|
||||
* Myk Melez
|
||||
* Zandr Milewski
|
||||
* Noelle Murata
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Siavash Askari Nasr
|
||||
* Joe R. Nassimian ([placidrage](https://github.com/placidrage))
|
||||
* Dương H. Nguyễn
|
||||
* Nick Nguyen
|
||||
|
||||
<!--end-->
|
||||
|
||||
* [ongaeshi](https://github.com/ongaeshi)
|
||||
* Paul O’Shannessy
|
||||
* Les Orchard
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Robert Pankowecki
|
||||
* l.m.orchard
|
||||
* Alexandre Poirot
|
||||
* Nickolay Ponomarev
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Aza Raskin
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Till Schneidereit
|
||||
* Justin Scott
|
||||
* Ayan Shah
|
||||
* [skratchdot](https://github.com/skratchdot)
|
||||
* Henrik Skupin
|
||||
* slash
|
||||
* Markus Stange
|
||||
* Dan Stevens
|
||||
* [Mihai Sucan](https://github.com/mihaisucan)
|
||||
|
||||
<!--end-->
|
||||
|
||||
* taku0
|
||||
* Clint Talbert
|
||||
* Tim Taubert
|
||||
* Shane Tomlinson
|
||||
* Thomas
|
||||
* Dave Townsend
|
||||
* [Matthias Tylkowski](https://github.com/tylkomat)
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Peter Van der Beken
|
||||
* Sander van Veen
|
||||
* Atul Varma
|
||||
* [Erik Vold](https://github.com/erikvold)
|
||||
* Vladimir Vukicevic
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Brian Warner
|
||||
* [Henri Wiechers](https://github.com/hwiechers)
|
||||
* Drew Willcoxon
|
||||
* Blake Winton
|
||||
* Michal Wojciechowski
|
||||
|
||||
<!--end-->
|
||||
|
||||
* Piotr Zalewa
|
||||
* Brett Zamir
|
||||
* [David Guo](https://github.com/dglol)
|
||||
* [Nils Maier](https://github.com/nmaier)
|
||||
* [Louis-Rémi Babé](https://github.com/louisremi)
|
||||
* [Matthias Tylkowski](https://github.com/tylkomat)
|
||||
|
@ -6,18 +6,23 @@
|
||||
# Communicating using "port" #
|
||||
|
||||
To enable add-on scripts and content scripts to communicate with each other,
|
||||
each end of the conversation has access to a `port` object.
|
||||
each end of the conversation has access to a `port` object which defines two
|
||||
functions:
|
||||
|
||||
* to send messages from one side to the other, use `port.emit()`
|
||||
* to receive messages sent from the other side, use `port.on()`
|
||||
**`emit()`** is used to emit an event. It may be called with any number of
|
||||
parameters, but is most likely to be called with a name for the event and
|
||||
an optional payload. The payload can be any value that is
|
||||
<a href = "dev-guide/guides/content-scripts/using-port.html#json_serializable">serializable to JSON</a>
|
||||
|
||||
<img class="image-center" src="static-files/media/content-scripting-events.png"
|
||||
alt="Content script events">
|
||||
port.emit("myEvent", myEventPayload);
|
||||
|
||||
Messages are asynchronous: that is, the sender does not wait for a reply from
|
||||
the recipient but just emits the message and continues processing.
|
||||
**`on()`** takes two parameters: the name of the event and a function to handle it:
|
||||
|
||||
Here's a simple add-on that sends a message to a content script using `port`:
|
||||
port.on("myEvent", function handleMyEvent(myEventPayload) {
|
||||
// Handle the event
|
||||
});
|
||||
|
||||
Here's simple add-on that sends a message to a content script using `port`:
|
||||
|
||||
var tabs = require("sdk/tabs");
|
||||
|
||||
@ -34,49 +39,45 @@ Here's a simple add-on that sends a message to a content script using `port`:
|
||||
|
||||
tabs.open("http://www.mozilla.org");
|
||||
|
||||
In total, the `port` object defines four functions:
|
||||
We could depict the interface between add-on code and content script code like
|
||||
this:
|
||||
|
||||
* [`emit()`](dev-guide/guides/content-scripts/using-port.html#port.emit()):
|
||||
emit a message.
|
||||
* [`on()`](dev-guide/guides/content-scripts/using-port.html#port.on()):
|
||||
listen to a message.
|
||||
* [`removeListener()`](dev-guide/guides/content-scripts/using-port.html#port.removeListener()):
|
||||
stop listening to a message.
|
||||
* [`once()`](dev-guide/guides/content-scripts/using-port.html#port.once()):
|
||||
listen to only the first occurrence of a message.
|
||||
<img class="image-center" src="static-files/media/content-scripting-events.png"
|
||||
alt="Content script events">
|
||||
|
||||
## Accessing `port` ##
|
||||
Events are asynchronous: that is, the sender does not wait for a reply from
|
||||
the recipient but just emits the event and continues processing.
|
||||
|
||||
### Accessing `port` in the Content Script ###
|
||||
## Accessing `port` in the Content Script ##
|
||||
|
||||
<span class="aside">Note that the global `self` object is completely
|
||||
different from the [`self` module](modules/sdk/self.html), which
|
||||
provides an API for an add-on to access its data files and ID.</span>
|
||||
|
||||
In the content script the `port` object is available as a property of the
|
||||
global `self` object. Thus, to emit a message from a content script:
|
||||
global `self` object. Thus, to emit an event from a content script:
|
||||
|
||||
self.port.emit("myContentScriptMessage", myContentScriptMessagePayload);
|
||||
self.port.emit("myContentScriptEvent", myContentScriptEventPayload);
|
||||
|
||||
To receive a message from the add-on code:
|
||||
To receive an event from the add-on code:
|
||||
|
||||
self.port.on("myAddonMessage", function(myAddonMessagePayload) {
|
||||
// Handle the message
|
||||
self.port.on("myAddonEvent", function(myAddonEventPayload) {
|
||||
// Handle the event
|
||||
});
|
||||
|
||||
Compare this to the technique used to receive _built-in_ messages in the
|
||||
content script. For example, to receive the `context` message in a content script
|
||||
Compare this to the technique used to receive _built-in_ events in the
|
||||
content script. For example, to receive the `context` event in a content script
|
||||
associated with a [context menu](modules/sdk/context-menu.html)
|
||||
object, you would call the `on` function attached to the global `self` object:
|
||||
|
||||
self.on("context", function() {
|
||||
// Handle the message
|
||||
// Handle the event
|
||||
});
|
||||
|
||||
So the `port` property is essentially used here as a namespace for
|
||||
user-defined messages.
|
||||
user-defined events.
|
||||
|
||||
### Accessing `port` in the Add-on Script ###
|
||||
## Accessing `port` in the Add-on Script ##
|
||||
|
||||
In the add-on code, the channel of communication between the add-on and a
|
||||
particular content script context is encapsulated by the `worker` object. Thus
|
||||
@ -85,7 +86,7 @@ corresponding `worker` object.
|
||||
|
||||
However, the worker is not exposed to add-on code in quite the same way
|
||||
in all modules. The `panel` and `page-worker` objects integrate the
|
||||
worker API directly. So to receive messages from a content script associated
|
||||
worker API directly. So to receive events from a content script associated
|
||||
with a panel you use `panel.port.on()`:
|
||||
|
||||
var panel = require("sdk/panel").Panel({
|
||||
@ -98,7 +99,7 @@ with a panel you use `panel.port.on()`:
|
||||
|
||||
panel.show();
|
||||
|
||||
Conversely, to emit user-defined messages from your add-on you can just call
|
||||
Conversely, to emit user-defined events from your add-on you can just call
|
||||
`panel.port.emit()`:
|
||||
|
||||
var panel = require("sdk/panel").Panel({
|
||||
@ -120,8 +121,8 @@ So `page-mod` does not integrate the worker API directly: instead, each time a
|
||||
content script is attached to a page, the worker associated with the page is
|
||||
supplied to the page-mod in its `onAttach` function. By supplying a target for
|
||||
this function in the page-mod's constructor you can register to receive
|
||||
messages from the content script, and take a reference to the worker so as to
|
||||
emit messages to the content script.
|
||||
events from the content script, and take a reference to the worker so as to
|
||||
emit events to it.
|
||||
|
||||
var pageModScript = "window.addEventListener('click', function(event) {" +
|
||||
" self.port.emit('click', event.target.toString());" +
|
||||
@ -142,126 +143,18 @@ emit messages to the content script.
|
||||
}
|
||||
});
|
||||
|
||||
In the add-on above there are two user-defined messages:
|
||||
In the add-on above there are two user-defined events:
|
||||
|
||||
* `click` is sent from the page-mod to the add-on, when the user clicks an
|
||||
element in the page
|
||||
* `warning` sends a silly string back to the page-mod
|
||||
|
||||
## port.emit() ##
|
||||
|
||||
The `port.emit()` function sends a message from the "main.js", or another
|
||||
add-on module, to a content script, or vice versa.
|
||||
|
||||
It may be called with any number of parameters, but is most likely to be
|
||||
called with a name for the message and an optional payload.
|
||||
The payload can be any value that is
|
||||
<a href = "dev-guide/guides/content-scripts/using-port.html#json_serializable">serializable to JSON</a>.
|
||||
|
||||
From the content script to the main add-on code:
|
||||
|
||||
var myMessagePayload = "some data";
|
||||
self.port.emit("myMessage", myMessagePayload);
|
||||
|
||||
From the main add-on code (in this case a panel instance)
|
||||
to the content script:
|
||||
|
||||
var myMessagePayload = "some data";
|
||||
panel.port.emit("myMessage", myMessagePayload);
|
||||
|
||||
## port.on() ##
|
||||
|
||||
The `port.on()` function registers a function as a listener for a specific
|
||||
named message sent from the other side using `port.emit()`.
|
||||
|
||||
It takes two parameters: the name of the message and a function to handle it.
|
||||
|
||||
In a content script, to listen for "myMessage" sent from the main
|
||||
add-on code:
|
||||
|
||||
self.port.on("myMessage", function handleMyMessage(myMessagePayload) {
|
||||
// Handle the message
|
||||
});
|
||||
|
||||
In the main add-on code (in this case a panel instance), to listen for
|
||||
"myMessage" sent from a a content script:
|
||||
|
||||
panel.port.on("myMessage", function handleMyMessage(myMessagePayload) {
|
||||
// Handle the message
|
||||
});
|
||||
|
||||
## port.removeListener() ##
|
||||
|
||||
You can uses `port.on()` to listen for messages. To stop listening for a
|
||||
particular message, use `port.removeListener()`. This takes the
|
||||
same two parameters as `port.on()`: the name of the message, and the name
|
||||
of the listener function.
|
||||
|
||||
For example, here's an add-on that creates a page-worker and a widget.
|
||||
The page-worker loads
|
||||
[http://en.wikipedia.org/wiki/Chalk](http://en.wikipedia.org/wiki/Chalk)
|
||||
alongside a content script "listener.js". The widget sends the content script
|
||||
a message called "get-first-para" when it is clicked:
|
||||
|
||||
pageWorker = require("sdk/page-worker").Page({
|
||||
contentScriptFile: require("sdk/self").data.url("listener.js"),
|
||||
contentURL: "http://en.wikipedia.org/wiki/Chalk"
|
||||
});
|
||||
|
||||
require("sdk/widget").Widget({
|
||||
id: "mozilla-icon",
|
||||
label: "My Mozilla Widget",
|
||||
contentURL: "http://www.mozilla.org/favicon.ico",
|
||||
onClick: function() {
|
||||
console.log("sending 'get-first-para'");
|
||||
pageWorker.port.emit("get-first-para");
|
||||
}
|
||||
});
|
||||
|
||||
The content script "listener.js" listens for "get-first-para". When it
|
||||
receives this message, the script logs the first paragraph of the document
|
||||
and then calls `removeListener()` to stop listening.
|
||||
|
||||
function getFirstParagraph() {
|
||||
var paras = document.getElementsByTagName('p');
|
||||
console.log(paras[0].textContent);
|
||||
self.port.removeListener("get-first-para", getFirstParagraph);
|
||||
}
|
||||
|
||||
self.port.on("get-first-para", getFirstParagraph);
|
||||
|
||||
The result is that the paragraph is only logged the first time the widget
|
||||
is clicked.
|
||||
|
||||
Due to [bug 816272](https://bugzilla.mozilla.org/show_bug.cgi?id=816272)
|
||||
the [`page-mod`](modules/sdk/page-mod.html)'s `removeListener()` function
|
||||
does not prevent the listener from receiving messages that are already queued.
|
||||
This means that if "main.js" sends the message twice in successive lines, and
|
||||
the listener stops listening as soon as it receives the first message, then
|
||||
the listener will still receive the second message.
|
||||
|
||||
## port.once() ##
|
||||
|
||||
Often you'll want to receive a message just once, then stop listening. The
|
||||
`port` object offers a shortcut to do this: the `once()` method.
|
||||
|
||||
This example rewrites the "listener.js" content script in the
|
||||
[`port.removeListener()` example](dev-guide/guides/content-scripts/using-port.html#port.removeListener())
|
||||
so that it uses `once()`:
|
||||
|
||||
function getFirstParagraph() {
|
||||
var paras = document.getElementsByTagName('p');
|
||||
console.log(paras[0].textContent);
|
||||
}
|
||||
|
||||
self.port.once("get-first-para", getFirstParagraph);
|
||||
|
||||
## <a name="json_serializable">JSON-Serializable Values</a> ##
|
||||
|
||||
The payload for an message can be any JSON-serializable value. When messages
|
||||
are sent their payloads are automatically serialized, and when messages are
|
||||
received their payloads are automatically deserialized, so you don't need to
|
||||
worry about serialization.
|
||||
The payload for an event can be any JSON-serializable value. When events are
|
||||
sent their payloads are automatically serialized, and when events are received
|
||||
their payloads are automatically deserialized, so you don't need to worry
|
||||
about serialization.
|
||||
|
||||
However, you _do_ have to ensure that the payload can be serialized to JSON.
|
||||
This means that it needs to be a string, number, boolean, null, array of
|
||||
|
@ -24,7 +24,7 @@ their code.
|
||||
|
||||
The stability index is adopted from
|
||||
[node.js](http://nodejs.org/api/documentation.html#documentation_stability_index).
|
||||
The SDK uses only four of the six values defined by node.js:
|
||||
The SDK uses only three of the six values defined by node.js:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@ -33,14 +33,6 @@ The SDK uses only four of the six values defined by node.js:
|
||||
You can try it out and provide feedback, but we may change or remove
|
||||
it in future versions without having to pass through a formal
|
||||
deprecation process.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unstable</td>
|
||||
<td>The API is in the process of settling, but has not yet had sufficient
|
||||
real-world testing to be considered stable.
|
||||
Backwards-compatibility will be maintained if reasonable.
|
||||
If we do have to make backwards-incompatible changes, we will not guarantee
|
||||
to go through the formal deprecation process.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stable</td>
|
||||
|
@ -240,96 +240,111 @@ rm my-addon.xpi
|
||||
<a name="modules-compatibility"></a>
|
||||
## Module Compatibility
|
||||
|
||||
Modules not yet supported in Firefox Mobile are
|
||||
<span class="unsupported-on-mobile">**marked**</span> in the tables below.
|
||||
Modules not yet supported in Firefox Mobile are <span class="unsupported-on-mobile">highlighted</span> in the tables below.
|
||||
|
||||
### High-Level APIs ###
|
||||
|
||||
- [**addon-page**](modules/sdk/addon-page.html)
|
||||
- [base64](modules/sdk/clipboard.html)
|
||||
- [**clipboard**](modules/sdk/clipboard.html)
|
||||
- [**context-menu**](modules/sdk/context-menu.html)
|
||||
- [hotkeys](modules/sdk/hotkeys.html)
|
||||
- [indexed-db](modules/sdk/indexed-db.html)
|
||||
- [l10n](modules/sdk/l10n.html)
|
||||
- [notifications](modules/sdk/notifications.html)
|
||||
- [page-mod](modules/sdk/notifications.html)
|
||||
- [page-worker](modules/sdk/page-worker.html)
|
||||
- [**panel**](modules/sdk/panel.html)
|
||||
- [passwords](modules/sdk/passwords.html)
|
||||
- [**private-browsing**](modules/sdk/private-browsing.html)
|
||||
- [querystring](modules/sdk/querystring.html)
|
||||
- [request](modules/sdk/request.html)
|
||||
- [**selection**](modules/sdk/selection.html)
|
||||
- [self](modules/sdk/self.html)
|
||||
- [simple-prefs](modules/sdk/simple-prefs.html)
|
||||
- [simple-storage](modules/sdk/simple-storage.html)
|
||||
- [system](modules/sdk/system.html)
|
||||
- [tabs](modules/sdk/tabs.html)
|
||||
- [timers](modules/sdk/timers.html)
|
||||
- [url](modules/sdk/url.html)
|
||||
- [**widget**](modules/sdk/widget.html)
|
||||
- [windows](modules/sdk/windows.html)
|
||||
<ul class="module-list">
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/addon-page.html">addon-page</a></li>
|
||||
<li><a href="modules/sdk/base64.html">base64</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/clipboard.html">clipboard</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/context-menu.html">context-menu</a></li>
|
||||
<li><a href="modules/sdk/hotkeys.html">hotkeys</a></li>
|
||||
<!-- test-l10n-locale, test-l10n-plural-rules -->
|
||||
<li><a href="modules/sdk/l10n.html">l10n</a></li>
|
||||
<li><a href="modules/sdk/notifications.html">notifications</a></li>
|
||||
<!-- test-page-mod fails, but we know the module works -->
|
||||
<li><a href="modules/sdk/page-mod.html">page-mod</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/panel.html">panel</a></li>
|
||||
<!-- test-passwords, test-passwords-utils (with exceptions / warning from js console) -->
|
||||
<li><a href="modules/sdk/passwords.html">passwords</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/private-browsing.html">private-browsing</a></li>
|
||||
<li><a href="modules/sdk/querystring.html">querystring</a></li>
|
||||
<li><a href="modules/sdk/request.html">request</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/selection.html">selection</a></li>
|
||||
<li><a href="modules/sdk/self.html">self</a></li>
|
||||
<li><a href="modules/sdk/simple-prefs.html">simple-prefs</a></li>
|
||||
<li><a href="modules/sdk/simple-storage.html">simple-storage</a></li>
|
||||
<!-- test-tabs, test-tabs-common -->
|
||||
<li><a href="modules/sdk/tabs.html">tabs</a></li>
|
||||
<!-- test-timer -->
|
||||
<li><a href="modules/sdk/timers.html">timers</a></li>
|
||||
<li><a href="modules/sdk/url.html">url</a></li>
|
||||
<li><a href="modules/sdk/widget.html">widget</a></li>
|
||||
<!-- test-windows-common, test-windows -->
|
||||
<li><a href="modules/sdk/windows.html">windows</a></li>
|
||||
</ul>
|
||||
|
||||
### Low-Level APIs ###
|
||||
|
||||
- [/loader](modules/toolkit/loader.html)
|
||||
- [chrome](dev-guide/tutorials/chrome.html)
|
||||
- [console/plain-text](modules/sdk/console/plain-text.html)
|
||||
- [console/traceback](modules/sdk/console/traceback.html)
|
||||
- [**content/content**](modules/sdk/content/content.html)
|
||||
- [content/loader](modules/sdk/content/loader.html)
|
||||
- [**content/symbiont**](modules/sdk/content/symbiont.html)
|
||||
- [**content/worker**](modules/sdk/content/worker.html)
|
||||
- core/disposable
|
||||
- [core/heritage](modules/sdk/core/heritage.html)
|
||||
- [core/namespace](modules/sdk/core/namespace.html)
|
||||
- [core/promise](modules/sdk/core/promise.html)
|
||||
- [deprecated/api-utils](modules/sdk/deprecated/api-utils.html)
|
||||
- [deprecated/app-strings](modules/sdk/deprecated/app-strings.html)
|
||||
- [deprecated/cortex](modules/sdk/deprecated/cortex.html)
|
||||
- [deprecated/errors](modules/sdk/deprecated/errors.html)
|
||||
- [deprecated/events](modules/sdk/deprecated/events.html)
|
||||
- [deprecated/light-traits](modules/sdk/deprecated/light-traits.html)
|
||||
- deprecated/list
|
||||
- [deprecated/observer-service](modules/sdk/deprecated/observer-service.html)
|
||||
- [**deprecated/tab-browser**](modules/sdk/deprecated/tab-browser.html)
|
||||
- [deprecated/traits](modules/sdk/deprecated/traits.html)
|
||||
- [**deprecated/window-utils**](modules/sdk/deprecated/window-utils.html)
|
||||
- dom/events
|
||||
- [event/core](modules/sdk/event/core.html)
|
||||
- [event/target](modules/sdk/event/target.html)
|
||||
- [frame/hidden-frame](modules/sdk/frame/hidden-frame.html)
|
||||
- [frame/utils](modules/sdk/frame/utils.html)
|
||||
- [io/byte-streams](modules/sdk/io/byte-streams.html)
|
||||
- [io/file](modules/sdk/io/file.html)
|
||||
- [io/text-streams](modules/sdk/io/text-streams.html)
|
||||
- keyboard/observer
|
||||
- keyboard/utils
|
||||
- lang/functional
|
||||
- lang/type
|
||||
- [loader/cuddlefish](modules/sdk/loader/cuddlefish.html)
|
||||
- [loader/sandbox](modules/sdk/loader/sandbox.html)
|
||||
- [net/url](modules/sdk/net/url.html)
|
||||
- [net/xhr](modules/sdk/net/xhr.html)
|
||||
- [page-mod/match-pattern](modules/sdk/page-mod/match-pattern.html)
|
||||
- [platform/xpcom](modules/sdk/platform/xpcom.html)
|
||||
- [preferences/service](modules/sdk/preferences/service.html)
|
||||
- [system/environment](modules/sdk/system/environment.html)
|
||||
- [system/events](modules/sdk/system/events.html)
|
||||
- system/globals
|
||||
- [system/runtime](modules/sdk/system/runtime.html)
|
||||
- [system/unload](modules/sdk/system/unload.html)
|
||||
- [system/xul-app](modules/sdk/system/xul-app.html)
|
||||
- [test/assert](modules/sdk/test/assert.html)
|
||||
- [test/harness](modules/sdk/test/harness.html)
|
||||
- [test/httpd](modules/sdk/test/httpd.html)
|
||||
- [test/runner](modules/sdk/test/runner.html)
|
||||
- test/tmp-file
|
||||
- util/array
|
||||
- [util/collection](modules/sdk/util/collection.html)
|
||||
- [util/deprecate](modules/sdk/util/deprecate.html)
|
||||
- [util/list](modules/sdk/util/list.html)
|
||||
- util/registry
|
||||
- [util/uuid](modules/sdk/util/uuid.html)
|
||||
- [window/utils](modules/sdk/window/utils.html)
|
||||
<ul class="module-list">
|
||||
<li><a href="modules/toolkit/loader.html">/loader</a></li>
|
||||
<li><a href="dev-guide/tutorials/chrome.html">chrome</a></li>
|
||||
<li><a href="modules/sdk/console/plain-text.html">console/plain-text</a></li>
|
||||
<li><a href="modules/sdk/console/traceback.html">console/traceback</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/content/content.html">content/content</a></li>
|
||||
<li><a href="modules/sdk/content/loader.html">content/loader</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/content/symbiont.html">content/symbiont</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/content/worker.html">content/worker</a></li>
|
||||
<li>core/disposable</li>
|
||||
<li><a href="modules/sdk/core/heritage.html">core/heritage</a></li>
|
||||
<li><a href="modules/sdk/core/namespace.html">core/namespace</a></li>
|
||||
<li><a href="modules/sdk/core/promise.html">core/promise</a></li>
|
||||
<li><a href="modules/sdk/deprecated/api-utils.html">deprecated/api-utils</a></li>
|
||||
<li><a href="modules/sdk/deprecated/app-strings.html">deprecated/app-strings</a></li>
|
||||
<li><a href="modules/sdk/deprecated/cortex.html">deprecated/cortex</a></li>
|
||||
<li><a href="modules/sdk/deprecated/errors.html">deprecated/errors</a></li>
|
||||
<li><a href="modules/sdk/deprecated/events.html">deprecated/events</a></li>
|
||||
<li><a href="modules/sdk/deprecated/light-traits.html">deprecated/light-traits</a></li>
|
||||
<li>deprecated/list</li>
|
||||
<li><a href="modules/sdk/deprecated/observer-service.html">deprecated/observer-service</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/deprecated/tab-browser.html">deprecated/tab-browser</a></li>
|
||||
<!-- test-traits-core, test-traits -->
|
||||
<li><a href="modules/sdk/deprecated/traits.html">deprecated/traits</a></li>
|
||||
<li class="unsupported-on-mobile"><a href="modules/sdk/deprecated/window-utils.html">deprecated/window-utils</a></li>
|
||||
<!-- test-dom -->
|
||||
<li>dom/events</li>
|
||||
<li><a href="modules/sdk/event/core.html">event/core</a></li>
|
||||
<li><a href="modules/sdk/event/target.html">event/target</a></li>
|
||||
<li><a href="modules/sdk/frame/hidden-frame.html">frame/hidden-frame</a></li>
|
||||
<li><a href="modules/sdk/frame/utils.html">frame/utils</a></li>
|
||||
<li><a href="modules/sdk/io/byte-streams.html">io/byte-streams</a></li>
|
||||
<li><a href="modules/sdk/io/file.html">io/file</a></li>
|
||||
<li><a href="modules/sdk/io/text-streams.html">io/text-streams</a></li>
|
||||
<li>keyboard/observer</li>
|
||||
<li>keyboard/utils</li>
|
||||
<li>lang/functional</li>
|
||||
<li>lang/type</li>
|
||||
<li><a href="modules/sdk/loader/cuddlefish.html">loader/cuddlefish</a></li>
|
||||
<li><a href="modules/sdk/loader/sandbox.html">loader/sandbox</a></li>
|
||||
<li><a href="modules/sdk/net/url.html">net/url</a></li>
|
||||
<li><a href="modules/sdk/net/xhr.html">net/xhr</a></li>
|
||||
<li><a href="modules/sdk/page-mod/match-pattern.html">page-mod/match-pattern</a></li>
|
||||
<li><a href="modules/sdk/platform/xpcom.html">platform/xpcom</a></li>
|
||||
<!-- test-preferences-service, test-preferences-target -->
|
||||
<li><a href="modules/sdk/preferences/service.html">preferences/service</a></li>
|
||||
<li><a href="modules/sdk/system/environment.html">system/environment</a></li>
|
||||
<!-- No test for `system/events`, assuming it works because other compatible modules are using it -->
|
||||
<li><a href="modules/sdk/system/events.html">system/events</a></li>
|
||||
<li>system/globals</li>
|
||||
<!-- No test for `system/events`, assuming it works because other compatible modules are using it -->
|
||||
<li><a href="modules/sdk/system/runtime.html">system/runtime</a></li>
|
||||
<li><a href="modules/sdk/system/unload.html">system/unload</a></li>
|
||||
<li><a href="modules/sdk/system/xul-app.html">system/xul-app</a></li>
|
||||
<!-- No test for `assert`, assuming it works because the test are using it -->
|
||||
<li><a href="modules/sdk/test/assert.html">test/assert</a></li>
|
||||
<!-- No test for `harness`, assuming it works because the test are using it -->
|
||||
<li><a href="modules/sdk/test/harness.html">test/harness</a></li>
|
||||
<li><a href="modules/sdk/test/httpd.html">test/httpd</a></li>
|
||||
<!-- No test for `runner`, assuming it works because the test are using it -->
|
||||
<li><a href="modules/sdk/test/runner.html">test/runner</a></li>
|
||||
<li>test/tmp-file</li>
|
||||
<li>util/array</li>
|
||||
<li><a href="modules/sdk/util/collection.html">util/collection</a></li>
|
||||
<li><a href="modules/sdk/util/deprecate.html">util/deprecate</a></li>
|
||||
<li><a href="modules/sdk/util/list.html">util/list</a></li>
|
||||
<li>util/registry</li>
|
||||
<li><a href="modules/sdk/util/uuid.html">util/uuid</a></li>
|
||||
<!-- test-window-utils2 -->
|
||||
<li><a href="modules/sdk/window/utils.html">window/utils</a></li>
|
||||
</ul>
|
||||
|
@ -12,23 +12,23 @@ 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,
|
||||
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
|
||||
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.
|
||||
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
|
||||
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
|
||||
don't remove it when the page unloads. Rather, create your item only once and
|
||||
supply a context that matches the target URL.
|
||||
|
||||
Context menu items are displayed in the order created or in the case of sub
|
||||
@ -43,27 +43,27 @@ 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,
|
||||
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
|
||||
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 a top-level
|
||||
item does not specify a context, the page context applies. An item that is in a
|
||||
First of all, you may not need to specify a context at all. When a top-level
|
||||
item does not specify a context, the page context applies. An item that is in a
|
||||
submenu is visible unless you specify a context.
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
@ -79,7 +79,7 @@ like this:
|
||||
context: cm.URLContext("*.mozilla.org")
|
||||
});
|
||||
|
||||
These contexts may be specified by calling the following constructors. Each is
|
||||
These contexts may be specified by calling the following constructors. Each is
|
||||
exported by the `context-menu` module.
|
||||
|
||||
<table>
|
||||
@ -121,10 +121,10 @@ exported by the `context-menu` module.
|
||||
</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
|
||||
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 patterns. These are the same match pattern strings that you use with
|
||||
the <a href="modules/sdk/page-mod.html"><code>page-mod</code></a>
|
||||
<code>include</code> property.
|
||||
<a href="modules/sdk/page-mod/match-pattern.html">Read more about patterns</a>.
|
||||
@ -135,14 +135,14 @@ exported by the `context-menu` module.
|
||||
array
|
||||
</td>
|
||||
<td>
|
||||
An array of any of the other types. This context occurs when all contexts
|
||||
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:
|
||||
declarative contexts after construction. For example:
|
||||
|
||||
var context = require("sdk/context-menu").SelectorContext("img");
|
||||
myMenuItem.context.add(context);
|
||||
@ -153,19 +153,19 @@ all of those contexts occur.
|
||||
|
||||
### In Content Scripts
|
||||
|
||||
The declarative contexts are handy but not very powerful. For instance, you
|
||||
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 over the context in which your menu items are
|
||||
shown, you can use content scripts. Like other APIs in the SDK, the
|
||||
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/guides/content-scripts/index.html) to let your
|
||||
add-on interact with pages in the browser. Each menu item you create in the
|
||||
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
|
||||
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.
|
||||
|
||||
@ -179,18 +179,16 @@ that contains at least one image:
|
||||
'});'
|
||||
});
|
||||
|
||||
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
|
||||
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, and your
|
||||
item is shown only when all declarative contexts are current and your
|
||||
context listener returns true.
|
||||
script. In that case, the declarative contexts are evaluated first. If they
|
||||
are not current, then your context listener is never called.
|
||||
|
||||
If any declarative contexts 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:
|
||||
This example takes advantage of that fact. The listener can be assured that
|
||||
`node` will always be an image:
|
||||
|
||||
var cm = require("sdk/context-menu");
|
||||
cm.Item({
|
||||
@ -201,26 +199,8 @@ can be assured that `node` will always be an image:
|
||||
'});'
|
||||
});
|
||||
|
||||
However, if you do combine `SelectorContext` and the `"context"` event,
|
||||
be aware that the `node` argument passed to the `"context"` event will
|
||||
not always match the type specified in `SelectorContext`.
|
||||
|
||||
`SelectorContext` will match if the menu is invoked on the node specified
|
||||
*or any descendant of that node*, but the `"context"` event handler is
|
||||
passed *the actual node* on which the menu was invoked. The example above
|
||||
works because `<IMG>` elements can't contain other elements, but in the
|
||||
example below, `node.nodeName` is not guaranteed to be "P" - for example,
|
||||
it won't be "P" if the user context-clicked a link inside a paragraph:
|
||||
|
||||
var cm = require("sdk/context-menu");
|
||||
cm.Item({
|
||||
label: "A Paragraph",
|
||||
context: cm.SelectorContext("p"),
|
||||
contentScript: 'self.on("context", function (node) {' +
|
||||
' console.log(node.nodeName);' +
|
||||
' return true;' +
|
||||
'});'
|
||||
});
|
||||
Your item is shown only when all declarative contexts are current and your
|
||||
context listener returns true.
|
||||
|
||||
The content script is executed for every page that a context menu is shown for.
|
||||
It will be executed the first time it is needed (i.e. when the context menu is
|
||||
@ -232,7 +212,7 @@ 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
|
||||
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.
|
||||
|
||||
@ -246,68 +226,10 @@ item's content script like so:
|
||||
'});'
|
||||
});
|
||||
|
||||
Note that the listener function has parameters called `node` and `data`.
|
||||
|
||||
### The "node" Argument ###
|
||||
|
||||
`node` is the node that the user context-clicked to invoke the menu.
|
||||
|
||||
* If you did not use `SelectorContext` to decide whether to show the menu item,
|
||||
then this is the actual node clicked.
|
||||
* If you did use `SelectorContext`, then this is the node that matched your
|
||||
selector.
|
||||
|
||||
For example, suppose your add-on looks like this:
|
||||
|
||||
var script = "self.on('click', function (node, data) {" +
|
||||
" console.log('clicked: ' + node.nodeName);" +
|
||||
"});";
|
||||
|
||||
var cm = require("sdk/context-menu");
|
||||
|
||||
cm.Item({
|
||||
label: "body context",
|
||||
context: cm.SelectorContext("body"),
|
||||
contentScript: script
|
||||
});
|
||||
|
||||
This add-on creates a context-menu item that uses `SelectorContext` to display
|
||||
the item whenever the context menu is activated on any descendant of the
|
||||
`<BODY>` element. When clicked, the item just logs the
|
||||
[`nodeName`](https://developer.mozilla.org/en-US/docs/DOM/Node.nodeName)
|
||||
property for the node passed to the click handler.
|
||||
|
||||
If you run this add-on you'll see that it always logs "BODY", even if you
|
||||
click on a paragraph element inside the page:
|
||||
|
||||
<pre>
|
||||
info: contextmenu-example: clicked: BODY
|
||||
</pre>
|
||||
|
||||
By contrast, this add-on uses the `PageContext`:
|
||||
|
||||
var script = "self.on('click', function (node, data) {" +
|
||||
" console.log('clicked: ' + node.nodeName);" +
|
||||
"});";
|
||||
|
||||
var cm = require("sdk/context-menu");
|
||||
|
||||
cm.Item({
|
||||
label: "body context",
|
||||
context: cm.PageContext(),
|
||||
contentScript: script
|
||||
});
|
||||
|
||||
It will log the name of the actual node clicked:
|
||||
|
||||
<pre>
|
||||
info: contextmenu-example: clicked: P
|
||||
</pre>
|
||||
|
||||
### The "data" Argument ###
|
||||
|
||||
`data` is the `data` property of the menu item
|
||||
that was clicked. Note that when you have a hierarchy of menu items the click
|
||||
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. Note that when you have a hierarchy of menu items the click
|
||||
event will be sent to the content script of the item clicked and all ancestors
|
||||
so be sure to verify that the `data` value passed matches the item you expect.
|
||||
You can use this to simplify click handling by providing just a single click
|
||||
@ -326,13 +248,11 @@ listener on a `Menu` that reacts to clicks for any child items.:
|
||||
]
|
||||
});
|
||||
|
||||
### Communicating With the Add-on ###
|
||||
|
||||
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
|
||||
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
|
||||
JSON-able data. The menu item's `"message"` event listener will be called with
|
||||
that data.
|
||||
|
||||
var cm = require("sdk/context-menu");
|
||||
@ -354,7 +274,7 @@ 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
|
||||
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;
|
||||
@ -368,13 +288,13 @@ updates the item's label based on the number of times it's been clicked:
|
||||
}
|
||||
});
|
||||
|
||||
Sometimes you might want to update the label based on the context. For
|
||||
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
|
||||
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
|
||||
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:
|
||||
@ -392,7 +312,7 @@ This item implements the aforementioned search example:
|
||||
});
|
||||
|
||||
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,
|
||||
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.
|
||||
|
||||
@ -401,9 +321,9 @@ 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
|
||||
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
|
||||
`contentScriptFile` property. See
|
||||
[Working with Content Scripts](dev-guide/guides/content-scripts/index.html)
|
||||
for more information.
|
||||
|
||||
@ -516,14 +436,14 @@ 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
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -539,43 +459,43 @@ A labeled menu item that can perform an action when clicked.
|
||||
use to interact with the page.
|
||||
@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
|
||||
be called when the content script calls `self.postMessage`. It will be
|
||||
passed the data that was passed to `postMessage`.
|
||||
</api>
|
||||
|
||||
<api name="label">
|
||||
@property {string}
|
||||
The menu item's label. You can set this after creating the item to update its
|
||||
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
|
||||
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
|
||||
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
|
||||
context menu. Contexts can be added by calling `context.add()` and removed by
|
||||
called `context.remove()`.
|
||||
</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,
|
||||
context menu. This property is read-only. To add the item to a new menu,
|
||||
call that menu's `addItem()` method.
|
||||
</api>
|
||||
|
||||
@ -594,7 +514,7 @@ A labeled menu item that can perform an action when clicked.
|
||||
<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
|
||||
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>
|
||||
@ -624,13 +544,13 @@ 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
|
||||
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`,
|
||||
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
|
||||
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
|
||||
@ -646,43 +566,43 @@ A labeled menu item that expands into a submenu.
|
||||
use to interact with the page.
|
||||
@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
|
||||
be called when the content script calls `self.postMessage`. It will be
|
||||
passed the data that was passed to `postMessage`.
|
||||
</api>
|
||||
|
||||
<api name="label">
|
||||
@property {string}
|
||||
The menu's label. You can set this after creating the menu to update its
|
||||
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
|
||||
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
|
||||
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
|
||||
menu. Contexts can be added by calling `context.add()` and removed by called
|
||||
`context.remove()`.
|
||||
</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,
|
||||
context menu. This property is read-only. To add the menu to a new menu,
|
||||
call that menu's `addItem()` method.
|
||||
</api>
|
||||
|
||||
@ -700,9 +620,9 @@ A labeled menu item that expands into a submenu.
|
||||
|
||||
<api name="addItem">
|
||||
@method
|
||||
Appends a menu item to the end of the menu. If the item is already contained
|
||||
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. If the item is already contained in this menu it will just be moved
|
||||
first. If the item is already contained in this menu it will just be moved
|
||||
to the end of the menu.
|
||||
@param item {Item,Menu,Separator}
|
||||
The `Item`, `Menu`, or `Separator` to add to the menu.
|
||||
@ -710,7 +630,7 @@ A labeled menu item that expands into a submenu.
|
||||
|
||||
<api name="removeItem">
|
||||
@method
|
||||
Removes the given menu item from the menu. If the menu does not contain the
|
||||
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.
|
||||
@ -719,7 +639,7 @@ A labeled menu item that expands into a submenu.
|
||||
<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
|
||||
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>
|
||||
@ -741,7 +661,7 @@ from the content script. The message can be any
|
||||
|
||||
<api name="Separator">
|
||||
@class
|
||||
A menu separator. Separators can be contained only in `Menu`s, not in the
|
||||
A menu separator. Separators can be contained only in `Menu`s, not in the
|
||||
top-level context menu.
|
||||
|
||||
<api name="Separator">
|
||||
@ -751,14 +671,14 @@ top-level context menu.
|
||||
|
||||
<api name="parentMenu">
|
||||
@property {Menu}
|
||||
The separator's parent `Menu`. This property is read-only. To add the
|
||||
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
|
||||
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>
|
||||
@ -769,7 +689,7 @@ top-level context menu.
|
||||
@class
|
||||
<api name="PageContext">
|
||||
@constructor
|
||||
Creates a page context. See Specifying Contexts above.
|
||||
Creates a page context. See Specifying Contexts above.
|
||||
</api>
|
||||
</api>
|
||||
|
||||
@ -777,7 +697,7 @@ top-level context menu.
|
||||
@class
|
||||
<api name="SelectionContext">
|
||||
@constructor
|
||||
Creates a context that occurs when a page contains a selection. See
|
||||
Creates a context that occurs when a page contains a selection. See
|
||||
Specifying Contexts above.
|
||||
</api>
|
||||
</api>
|
||||
@ -786,7 +706,7 @@ top-level context menu.
|
||||
@class
|
||||
<api name="SelectorContext">
|
||||
@constructor
|
||||
Creates a context that matches a given CSS selector. See Specifying Contexts
|
||||
Creates a context that matches a given CSS selector. See Specifying Contexts
|
||||
above.
|
||||
@param selector {string}
|
||||
A CSS selector.
|
||||
@ -797,7 +717,7 @@ top-level context menu.
|
||||
@class
|
||||
<api name="URLContext">
|
||||
@constructor
|
||||
Creates a context that matches pages with particular URLs. See Specifying
|
||||
Creates a context that matches pages with particular URLs. See Specifying
|
||||
Contexts above.
|
||||
@param matchPattern {string,array}
|
||||
A [match pattern](modules/sdk/page-mod/match-pattern.html) string, regexp or an
|
||||
|
@ -201,11 +201,11 @@ functions to asynchronous by making it aware of promises. Module exports
|
||||
`promised` function to do exactly that:
|
||||
|
||||
const { promised } = require('sdk/core/promise');
|
||||
function sum(x, y) { return x + y };
|
||||
var asyncSum = promised(sum);
|
||||
function sum(x, y) { return x + y }
|
||||
var sumAsync = promised(sum);
|
||||
|
||||
var c = sum(a, b);
|
||||
var cAsync = asyncSum(aAsync(), bAsync());
|
||||
var cAsync = asyncSum(aAsync(), bAsinc());
|
||||
|
||||
`promised` takes normal function and composes new promise aware version of it
|
||||
that may take both normal values and promises as arguments and returns promise
|
||||
|
@ -7,7 +7,7 @@
|
||||
<!-- contributed by Atul Varma [atul@mozilla.com] -->
|
||||
<!-- edited by Noelle Murata [fiveinchpixie@gmail.com] -->
|
||||
|
||||
The `preferences/service` module provides access to the
|
||||
The `preferences-service` module provides access to the
|
||||
application-wide preferences service singleton.
|
||||
|
||||
|
||||
|
@ -27,23 +27,14 @@ but will have no effect when called.
|
||||
|
||||
<api name="isActive">
|
||||
@property {boolean}
|
||||
This read-only boolean is `true` if global private browsing mode is turned on.
|
||||
This read-only boolean is true if global private browsing mode is turned on.
|
||||
|
||||
<div class="warning">
|
||||
This property is deprecated. It will continue to work until version 1.13 of the SDK.
|
||||
From version 1.13 onwards it will always return `false`.
|
||||
From version 1.13 onwards it will always return false.
|
||||
</div>
|
||||
</api>
|
||||
|
||||
<api name="isPrivate">
|
||||
@function
|
||||
Returns `true` if the argument is a private window or tab.
|
||||
@param [thing] {any}
|
||||
The thing to check if it is private, only handles windows and tabs at the moment.
|
||||
Everything else returns `false` automatically.
|
||||
In global private browsing mode, this method returns the same value as `isActive`.
|
||||
</api>
|
||||
|
||||
<api name="activate">
|
||||
@function
|
||||
Turns on global private browsing mode.
|
||||
|
@ -45,6 +45,7 @@
|
||||
<input type="text" name="q" size="31" id="search-box" />
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript" src="https://www.google.com/cse/brand?form=cse-search-box&lang=en"></script>
|
||||
<!-- Google CSE Search Box Ends -->
|
||||
</div>
|
||||
</div>
|
||||
@ -162,8 +163,6 @@
|
||||
|
||||
<script type="text/javascript" src="static-files/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="static-files/js/main.js"></script>
|
||||
<!-- load the google JS last, in case we're offline ( bug 836955 ) -->
|
||||
<script type="text/javascript" src="https://www.google.com/cse/brand?form=cse-search-box&lang=en"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -441,8 +441,8 @@ ul.tree ul li:last-child {
|
||||
background: #fff url("../media/icons/lastnode.png") no-repeat;
|
||||
}
|
||||
|
||||
ul#module-index,
|
||||
h2[id="Module Compatibility"] ~ ul {
|
||||
ul.module-list,
|
||||
ul#module-index {
|
||||
border-color: #a0d0fb;
|
||||
border: solid 1px #a0d0fb;
|
||||
padding: 1em;
|
||||
@ -455,8 +455,8 @@ h2[id="Module Compatibility"] ~ ul {
|
||||
column-gap: 1em;
|
||||
}
|
||||
|
||||
span.unsupported-on-mobile strong,
|
||||
h2[id="Module Compatibility"] ~ ul strong {
|
||||
font-weight: normal;
|
||||
text-decoration: line-through;
|
||||
span.unsupported-on-mobile,
|
||||
ul.module-list li.unsupported-on-mobile,
|
||||
ul.module-list li.unsupported-on-mobile > a {
|
||||
color: maroon;
|
||||
}
|
||||
|
@ -86,7 +86,8 @@ function startup(reason, options) {
|
||||
then(function onLocalizationReady(data) {
|
||||
// Exports data to a pseudo module so that api-utils/l10n/core
|
||||
// can get access to it
|
||||
definePseudo(options.loader, '@l10n/data', data ? data : null);
|
||||
if (data)
|
||||
definePseudo(options.loader, '@l10n/data', data);
|
||||
run(options);
|
||||
});
|
||||
}
|
||||
|
@ -9,11 +9,10 @@
|
||||
factory.call(this, require, exports, module);
|
||||
} else if (~String(this).indexOf('BackstagePass')) { // JSM
|
||||
this[factory.name] = {};
|
||||
var Cu = this.Components["utils"];
|
||||
this.console = Cu.import("resource://gre/modules/devtools/Console.jsm", {})
|
||||
.console;
|
||||
factory(function require(uri) {
|
||||
return Cu.import(uri, {});
|
||||
var imports = {};
|
||||
this['Components'].utils.import(uri, imports);
|
||||
return imports;
|
||||
}, this[factory.name], { uri: __URI__, id: id });
|
||||
this.EXPORTED_SYMBOLS = [factory.name];
|
||||
} else { // Browser or alike
|
||||
@ -54,12 +53,7 @@ function attempt(f) {
|
||||
**/
|
||||
return function effort(options) {
|
||||
try { return f(options) }
|
||||
catch(error) {
|
||||
if (exports._reportErrors && typeof(console) == 'object') {
|
||||
console.error(error)
|
||||
}
|
||||
return rejection(error)
|
||||
}
|
||||
catch(error) { return rejection(error) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,7 @@ module.metadata = {
|
||||
const file = require("../io/file");
|
||||
const memory = require('./memory');
|
||||
const suites = require('@test/options').allTestModules;
|
||||
const { Loader } = require("sdk/test/loader");
|
||||
const cuddlefish = require("sdk/loader/cuddlefish");
|
||||
|
||||
|
||||
const NOT_TESTS = ['setup', 'teardown'];
|
||||
|
||||
@ -53,11 +52,7 @@ TestFinder.prototype = {
|
||||
|
||||
suites.forEach(
|
||||
function(suite) {
|
||||
// Load each test file as a main module in its own loader instance
|
||||
// `suite` is defined by cuddlefish/manifest.py:ManifestBuilder.build
|
||||
var loader = Loader(module);
|
||||
var module = cuddlefish.main(loader, suite);
|
||||
|
||||
var module = require(suite);
|
||||
if (self.testInProcess)
|
||||
for each (let name in Object.keys(module).sort()) {
|
||||
if(NOT_TESTS.indexOf(name) === -1 && filter(suite, name)) {
|
||||
|
@ -10,7 +10,7 @@ module.metadata = {
|
||||
|
||||
const { Cc, Ci } = require("chrome");
|
||||
const { extend } = require("./core/heritage");
|
||||
const { id } = require("./self");
|
||||
const { id } = require("self");
|
||||
|
||||
// placeholder, copied from bootstrap.js
|
||||
let sanitizeId = function(id){
|
||||
|
@ -8,15 +8,11 @@ module.metadata = {
|
||||
"stability": "unstable"
|
||||
};
|
||||
|
||||
const { Ci, Cu } = require("chrome");
|
||||
const { Ci } = require("chrome");
|
||||
const events = require("../system/events");
|
||||
const core = require("./core");
|
||||
|
||||
const assetsURI = require('../self').data.url();
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const hideContentStyle = "data:text/css,:root {visibility: hidden !important;}";
|
||||
const hideSheetUri = Services.io.newURI(hideContentStyle, null, null);
|
||||
|
||||
// Taken from Gaia:
|
||||
// https://github.com/andreasgal/gaia/blob/04fde2640a7f40314643016a5a6c98bf3755f5fd/webapi.js#L1470
|
||||
@ -45,15 +41,8 @@ function onDocumentReady2Translate(event) {
|
||||
|
||||
translateElement(document);
|
||||
|
||||
try {
|
||||
// Finally display document when we finished replacing all text content
|
||||
let winUtils = document.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
winUtils.removeSheet(hideSheetUri, winUtils.USER_SHEET);
|
||||
}
|
||||
catch(e) {
|
||||
console.exception(e);
|
||||
}
|
||||
// Finally display document when we finished replacing all text content
|
||||
document.documentElement.style.visibility = "visible";
|
||||
}
|
||||
|
||||
function onContentWindow(event) {
|
||||
@ -72,16 +61,12 @@ function onContentWindow(event) {
|
||||
if (document.location.href.indexOf(assetsURI) !== 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
// First hide content of the document in order to have content blinking
|
||||
// between untranslated and translated states
|
||||
let winUtils = document.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
winUtils.loadSheet(hideSheetUri, winUtils.USER_SHEET);
|
||||
}
|
||||
catch(e) {
|
||||
console.exception(e);
|
||||
}
|
||||
// First hide content of the document in order to have content blinking
|
||||
// between untranslated and translated states
|
||||
// TODO: use result of bug 737003 discussion in order to avoid any conflict
|
||||
// with document CSS
|
||||
document.documentElement.style.visibility = "hidden";
|
||||
|
||||
// Wait for DOM tree to be built before applying localization
|
||||
document.addEventListener("DOMContentLoaded", onDocumentReady2Translate,
|
||||
false);
|
||||
@ -107,4 +92,4 @@ function disable() {
|
||||
}
|
||||
exports.disable = disable;
|
||||
|
||||
require("sdk/system/unload").when(disable);
|
||||
require("api-utils/unload").when(disable);
|
||||
|
@ -88,8 +88,8 @@ function CuddlefishLoader(options) {
|
||||
// cache to avoid subsequent loads via `require`.
|
||||
modules: override({
|
||||
'toolkit/loader': loaderModule,
|
||||
'sdk/loader/cuddlefish': exports,
|
||||
'sdk/system/xul-app': xulappModule
|
||||
'addon-sdk/sdk/loader/cuddlefish': exports,
|
||||
'addon-sdk/sdk/system/xul-app': xulappModule
|
||||
}, options.modules),
|
||||
resolve: function resolve(id, requirer) {
|
||||
let entry = requirer && requirer in manifest && manifest[requirer];
|
||||
@ -103,14 +103,15 @@ function CuddlefishLoader(options) {
|
||||
// If requirer entry is in manifest and it's requirement is not, than
|
||||
// it has no authority to load since linker was not able to find it.
|
||||
if (!requirement)
|
||||
throw Error('Module: ' + requirer + ' has no authority to load: '
|
||||
+ id, requirer);
|
||||
throw Error('Module: ' + requirer.id + ' located at ' + requirer.uri
|
||||
+ ' has no authority to load: ' + id, requirer.uri);
|
||||
|
||||
uri = requirement;
|
||||
} else {
|
||||
// If requirer is off manifest than it's a system module and we allow it
|
||||
// to go off manifest by resolving a relative path.
|
||||
uri = loaderModule.resolve(id, requirer);
|
||||
}
|
||||
// If requirer is off manifest than it's a system module and we allow it
|
||||
// to go off manifest.
|
||||
else {
|
||||
uri = id;
|
||||
}
|
||||
return uri;
|
||||
},
|
||||
|
@ -114,10 +114,6 @@ XMLHttpRequest.prototype = {
|
||||
set upload(newValue) {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
forceAllowThirdPartyCookie: function forceAllowThirdPartyCookie() {
|
||||
if (this._req.channel instanceof Ci.nsIHttpChannelInternal)
|
||||
this._req.channel.forceAllowThirdPartyCookie = true;
|
||||
},
|
||||
get onreadystatechange() {
|
||||
return this._orsc;
|
||||
},
|
||||
|
@ -7,11 +7,10 @@ module.metadata = {
|
||||
"stability": "stable"
|
||||
};
|
||||
|
||||
const { setMode, getMode, on: onStateChange, isWindowPrivate } = require('./private-browsing/utils');
|
||||
const { setMode, getMode, on: onStateChange } = require('./private-browsing/utils');
|
||||
const { emit, on, once, off } = require('./event/core');
|
||||
const { when: unload } = require('./system/unload');
|
||||
const { deprecateUsage, deprecateFunction, deprecateEvent } = require('./util/deprecate');
|
||||
const { getOwnerWindow } = require('./private-browsing/window/utils');
|
||||
|
||||
onStateChange('start', function onStart() {
|
||||
emit(exports, 'start');
|
||||
@ -37,19 +36,6 @@ exports.removeListener = deprecateEvents(function removeListener(type, listener)
|
||||
off(exports, type, listener);
|
||||
});
|
||||
|
||||
exports.isPrivate = function(thing) {
|
||||
if (!!thing) {
|
||||
if (isWindowPrivate(thing)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let window = getOwnerWindow(thing);
|
||||
if (window)
|
||||
return isWindowPrivate(window);
|
||||
}
|
||||
return getMode();
|
||||
};
|
||||
|
||||
function deprecateEvents(func) deprecateEvent(
|
||||
func,
|
||||
'The require("private-browsing") module\'s "start" and "stop" events are deprecated.',
|
||||
|
@ -15,14 +15,13 @@ const { getWindowLoadingContext, windows } = require('../window/utils');
|
||||
const { WindowTracker } = require("../deprecated/window-utils");
|
||||
const events = require('../system/events');
|
||||
const { deprecateFunction } = require('../util/deprecate');
|
||||
const { isOneOf, is, satisfiesVersion, version } = require('../system/xul-app');
|
||||
|
||||
let deferredEmit = defer(emit);
|
||||
let pbService;
|
||||
let PrivateBrowsingUtils;
|
||||
|
||||
// Private browsing is only supported in Fx
|
||||
if (isOneOf(['Firefox', 'Fennec'])) {
|
||||
if (require("../system/xul-app").is("Firefox")) {
|
||||
// get the nsIPrivateBrowsingService if it exists
|
||||
try {
|
||||
pbService = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
@ -42,36 +41,20 @@ if (isOneOf(['Firefox', 'Fennec'])) {
|
||||
}
|
||||
|
||||
function isWindowPrivate(win) {
|
||||
if (!PrivateBrowsingUtils || !win)
|
||||
return false;
|
||||
|
||||
// if the pbService is undefined, the PrivateBrowsingUtils.jsm is available,
|
||||
// and the app is Firefox, then assume per-window private browsing is
|
||||
// enabled.
|
||||
if (win instanceof Ci.nsIDOMWindow) {
|
||||
return PrivateBrowsingUtils.isWindowPrivate(win);
|
||||
}
|
||||
|
||||
// Sometimes the input is not a nsIDOMWindow.. but it is still a winodw.
|
||||
try {
|
||||
return !!win.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing;
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
return false;
|
||||
return win instanceof Ci.nsIDOMWindow &&
|
||||
isWindowPBSupported &&
|
||||
PrivateBrowsingUtils.isWindowPrivate(win);
|
||||
}
|
||||
exports.isWindowPrivate = isWindowPrivate;
|
||||
|
||||
// checks that global private browsing is implemented
|
||||
let isGlobalPBSupported = exports.isGlobalPBSupported = !!pbService && is('Firefox');
|
||||
let isGlobalPBSupported = exports.isGlobalPBSupported = !!pbService;
|
||||
|
||||
// checks that per-window private browsing is implemented
|
||||
let isWindowPBSupported = exports.isWindowPBSupported =
|
||||
!pbService && !!PrivateBrowsingUtils && is('Firefox');
|
||||
|
||||
// checks that per-tab private browsing is implemented
|
||||
let isTabPBSupported = exports.isTabPBSupported =
|
||||
!pbService && !!PrivateBrowsingUtils && is('Fennec') && satisfiesVersion(version, '>=20.0*');
|
||||
let isWindowPBSupported = exports.isWindowPBSupported = !isGlobalPBSupported && !!PrivateBrowsingUtils;
|
||||
|
||||
function onChange() {
|
||||
// Emit event with in next turn of event loop.
|
||||
|
@ -1,32 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
'use strict';
|
||||
|
||||
module.metadata = {
|
||||
'stability': 'unstable'
|
||||
};
|
||||
|
||||
const privateNS = require('../../core/namespace').ns();
|
||||
|
||||
function getOwnerWindow(thing) {
|
||||
try {
|
||||
// check for and return associated window
|
||||
let fn = (privateNS(thing.prototype) || privateNS(thing) || {}).getOwnerWindow;
|
||||
if (fn)
|
||||
return fn.apply(fn, [thing].concat(arguments));
|
||||
}
|
||||
// stuff like numbers and strings throw errors with namespaces
|
||||
catch(e) {}
|
||||
// default
|
||||
return undefined;
|
||||
}
|
||||
getOwnerWindow.define = function(Type, fn) {
|
||||
privateNS(Type.prototype).getOwnerWindow = fn;
|
||||
}
|
||||
|
||||
getOwnerWindow.implement = function(instance, fn) {
|
||||
privateNS(instance).getOwnerWindow = fn;
|
||||
}
|
||||
|
||||
exports.getOwnerWindow = getOwnerWindow;
|
@ -71,8 +71,6 @@ function runRequest(mode, target) {
|
||||
// open the request
|
||||
xhr.open(mode, url);
|
||||
|
||||
xhr.forceAllowThirdPartyCookie();
|
||||
|
||||
// request header must be set after open, but before send
|
||||
xhr.setRequestHeader("Content-Type", contentType);
|
||||
|
||||
|
@ -20,7 +20,7 @@ const { Ci, Cc } = require("chrome"),
|
||||
{ when: unload } = require("./system/unload"),
|
||||
{ getTabs, getTabContentWindow, getTabForContentWindow,
|
||||
getAllTabContentWindows } = require('./tabs/utils'),
|
||||
{ getMostRecentBrowserWindow,
|
||||
{ getInnerId, getMostRecentBrowserWindow,
|
||||
windows, getFocusedWindow, getFocusedElement } = require("./window/utils"),
|
||||
events = require("./system/events");
|
||||
|
||||
@ -321,6 +321,17 @@ function addSelectionListener(window) {
|
||||
window.addEventListener("select", selectionListener.onSelect, true);
|
||||
|
||||
selections(window).selection = selection;
|
||||
|
||||
let innerId = getInnerId(window);
|
||||
|
||||
events.on("inner-window-destroyed", function destroyed (event) {
|
||||
let destroyedId = event.subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
|
||||
if (destroyedId === innerId) {
|
||||
removeSelectionListener(window);
|
||||
events.off("inner-window-destroyed", destroyed);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -371,7 +382,7 @@ getAllTabContentWindows().forEach(addSelectionListener);
|
||||
//
|
||||
// See bug 665386 for further details.
|
||||
|
||||
function onShown(event) {
|
||||
events.on("document-shown", function (event) {
|
||||
let window = event.subject.defaultView;
|
||||
|
||||
// We are not interested in documents without valid defaultView.
|
||||
@ -397,21 +408,17 @@ function onShown(event) {
|
||||
if (currentSelection instanceof Ci.nsISelectionPrivate &&
|
||||
currentSelection !== selection) {
|
||||
|
||||
window.addEventListener("select", selectionListener.onSelect, true);
|
||||
currentSelection.addSelectionListener(selectionListener);
|
||||
selections(window).selection = currentSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.on("document-shown", onShown, true);
|
||||
});
|
||||
|
||||
// Removes Selection listeners when the add-on is unloaded
|
||||
unload(function(){
|
||||
getAllTabContentWindows().forEach(removeSelectionListener);
|
||||
|
||||
events.off("document-element-inserted", onContent);
|
||||
events.off("document-shown", onShown);
|
||||
|
||||
off(exports);
|
||||
});
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
module.metadata = {
|
||||
@ -102,6 +103,7 @@ function normalizeRange(range) {
|
||||
* A version to compare
|
||||
*/
|
||||
function compareVersion(version, comparison, compareVersion) {
|
||||
|
||||
let hasWildcard = compareVersion.indexOf("*") !== -1;
|
||||
|
||||
comparison = comparison || "=";
|
||||
@ -179,4 +181,5 @@ function satisfiesVersion(version, versionRange) {
|
||||
: true);
|
||||
});
|
||||
}
|
||||
|
||||
exports.satisfiesVersion = satisfiesVersion;
|
||||
|
@ -7,10 +7,9 @@ const { Cc, Ci } = require('chrome');
|
||||
const { Class } = require('../core/heritage');
|
||||
const { tabNS } = require('./namespace');
|
||||
const { EventTarget } = require('../event/target');
|
||||
const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL, getContentWindowForTab,
|
||||
const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL,
|
||||
setTabURL, getOwnerWindow, getTabContentType, getTabId } = require('./utils');
|
||||
const { emit } = require('../event/core');
|
||||
const { getOwnerWindow: getPBOwnerWindow } = require('../private-browsing/window/utils');
|
||||
const { when: unload } = require('../system/unload');
|
||||
|
||||
const { EVENTS } = require('./events');
|
||||
@ -144,7 +143,3 @@ const Tab = Class({
|
||||
}
|
||||
});
|
||||
exports.Tab = Tab;
|
||||
|
||||
getPBOwnerWindow.define(Tab, function(tab) {
|
||||
return getContentWindowForTab(tabNS(tab).tab);
|
||||
});
|
||||
|
@ -11,8 +11,6 @@ const { getThumbnailURIForWindow } = require("../content/thumbnail");
|
||||
const { getFaviconURIForLocation } = require("../io/data");
|
||||
const { activateTab, getOwnerWindow, getBrowserForTab, getTabTitle, setTabTitle,
|
||||
getTabURL, setTabURL, getTabContentType, getTabId } = require('./utils');
|
||||
const { getOwnerWindow: getPBOwnerWindow } = require('../private-browsing/window/utils');
|
||||
const viewNS = require('sdk/core/namespace').ns();
|
||||
|
||||
// Array of the inner instances of all the wrapped tabs.
|
||||
const TABS = [];
|
||||
@ -52,9 +50,6 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
if (options.isPinned)
|
||||
this.pin();
|
||||
|
||||
viewNS(this._public).tab = this._tab;
|
||||
getPBOwnerWindow.implement(this._public, getChromeTab);
|
||||
|
||||
// Since we will have to identify tabs by a DOM elements facade function
|
||||
// is used as constructor that collects all the instances and makes sure
|
||||
// that they more then one wrapper is not created per tab.
|
||||
@ -217,10 +212,6 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
}
|
||||
});
|
||||
|
||||
function getChromeTab(tab) {
|
||||
return getOwnerWindow(viewNS(tab).tab);
|
||||
}
|
||||
|
||||
function Tab(options) {
|
||||
let chromeTab = options.tab;
|
||||
for each (let tab in TABS) {
|
||||
|
@ -80,8 +80,7 @@ exports.getOwnerWindow = getOwnerWindow;
|
||||
// fennec
|
||||
function getWindowHoldingTab(rawTab) {
|
||||
for each (let window in windows()) {
|
||||
// this function may be called when not using fennec,
|
||||
// but BrowserApp is only defined on Fennec
|
||||
// this function may be called when not using fennec
|
||||
if (!window.BrowserApp)
|
||||
continue;
|
||||
|
||||
@ -101,8 +100,7 @@ function openTab(window, url, options) {
|
||||
if (window.BrowserApp) {
|
||||
return window.BrowserApp.addTab(url, {
|
||||
selected: options.inBackground ? false : true,
|
||||
pinned: options.isPinned || false,
|
||||
isPrivate: options.private || false
|
||||
pinned: options.isPinned || false
|
||||
});
|
||||
}
|
||||
return window.gBrowser.addTab(url);
|
||||
@ -152,12 +150,6 @@ function getBrowserForTab(tab) {
|
||||
}
|
||||
exports.getBrowserForTab = getBrowserForTab;
|
||||
|
||||
|
||||
function getContentWindowForTab(tab) {
|
||||
return getBrowserForTab(tab).contentWindow;
|
||||
}
|
||||
exports.getContentWindowForTab = getContentWindowForTab;
|
||||
|
||||
function getTabId(tab) {
|
||||
if (tab.browser) // fennec
|
||||
return tab.id
|
||||
@ -166,6 +158,7 @@ function getTabId(tab) {
|
||||
}
|
||||
exports.getTabId = getTabId;
|
||||
|
||||
|
||||
function getTabTitle(tab) {
|
||||
return getBrowserForTab(tab).contentDocument.title || tab.label || "";
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ module.metadata = {
|
||||
"stability": "unstable"
|
||||
};
|
||||
|
||||
const BaseAssert = require("sdk/test/assert").Assert;
|
||||
const { isFunction, isObject } = require("sdk/lang/type");
|
||||
const BaseAssert = require("./test/assert").Assert;
|
||||
const { isFunction, isObject } = require("./lang/type");
|
||||
|
||||
function extend(target) {
|
||||
let descriptor = {}
|
||||
|
@ -20,7 +20,7 @@ const system = require("../system");
|
||||
|
||||
// Trick manifest builder to make it think we need these modules ?
|
||||
const unit = require("../deprecated/unit-test");
|
||||
const test = require("../../test");
|
||||
const test = require("../test");
|
||||
const url = require("../url");
|
||||
|
||||
var cService = Cc['@mozilla.org/consoleservice;1'].getService()
|
||||
|
@ -105,7 +105,7 @@ exports.runTestsFromModule = function runTestsFromModule(module) {
|
||||
|
||||
runTests(function findAndRunTests(loader, nextIteration) {
|
||||
// Consider that all these tests are CommonJS ones
|
||||
loader.require('../../test').run(exports);
|
||||
loader.require('../test').run(exports);
|
||||
|
||||
// Reproduce what is done in unit-test-finder.findTests()
|
||||
let tests = [];
|
||||
|
@ -11,7 +11,6 @@ const { getWindowTitle } = require('./utils');
|
||||
const unload = require('../system/unload');
|
||||
const { getMode } = require('../private-browsing/utils');
|
||||
const { EventTarget } = require('../event/target');
|
||||
const { getOwnerWindow: getPBOwnerWindow } = require('../private-browsing/window/utils');
|
||||
|
||||
const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec, consider using require("tabs") instead';
|
||||
|
||||
@ -40,7 +39,3 @@ const BrowserWindow = Class({
|
||||
get isPrivateBrowsing() getMode(windowNS(this).window),
|
||||
});
|
||||
exports.BrowserWindow = BrowserWindow;
|
||||
|
||||
getPBOwnerWindow.define(BrowserWindow, function(window) {
|
||||
return windowNS(window).window;
|
||||
});
|
||||
|
@ -17,9 +17,7 @@ const { Cc, Ci, Cr } = require('chrome'),
|
||||
windowUtils = require('../deprecated/window-utils'),
|
||||
{ WindowTrackerTrait } = windowUtils,
|
||||
{ ns } = require('../core/namespace'),
|
||||
{ observer: windowObserver } = require('./observer'),
|
||||
{ getOwnerWindow } = require('../private-browsing/window/utils'),
|
||||
viewNS = require('sdk/core/namespace').ns();
|
||||
{ observer: windowObserver } = require('./observer');
|
||||
|
||||
/**
|
||||
* Window trait composes safe wrappers for browser window that are E10S
|
||||
@ -71,10 +69,6 @@ const BrowserWindowTrait = Trait.compose(
|
||||
this._private = !!options.private;
|
||||
|
||||
this._load();
|
||||
|
||||
viewNS(this._public).window = this._window;
|
||||
getOwnerWindow.implement(this._public, getChromeWindow);
|
||||
|
||||
return this;
|
||||
},
|
||||
destroy: function () this._onUnload(),
|
||||
@ -245,8 +239,4 @@ const browserWindows = Trait.resolve({ toString: null }).compose(
|
||||
}).resolve({ toString: null })
|
||||
)();
|
||||
|
||||
function getChromeWindow(window) {
|
||||
return viewNS(window).window;
|
||||
}
|
||||
|
||||
exports.browserWindows = browserWindows;
|
||||
|
@ -1,112 +0,0 @@
|
||||
/* vim:ts=2:sts=2:sw=2:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
module.metadata = {
|
||||
"stability": "unstable"
|
||||
};
|
||||
|
||||
const BaseAssert = require("sdk/test/assert").Assert;
|
||||
const { isFunction, isObject } = require("sdk/lang/type");
|
||||
|
||||
function extend(target) {
|
||||
let descriptor = {}
|
||||
Array.slice(arguments, 1).forEach(function(source) {
|
||||
Object.getOwnPropertyNames(source).forEach(function onEach(name) {
|
||||
descriptor[name] = Object.getOwnPropertyDescriptor(source, name);
|
||||
});
|
||||
});
|
||||
return Object.create(target, descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function takes test `suite` object in CommonJS format and defines all of the
|
||||
* tests from that suite and nested suites in a jetpack format on a given
|
||||
* `target` object. Optionally third argument `prefix` can be passed to prefix
|
||||
* all the test names.
|
||||
*/
|
||||
function defineTestSuite(target, suite, prefix) {
|
||||
prefix = prefix || "";
|
||||
// If suite defines `Assert` that's what `assert` object have to be created
|
||||
// from and passed to a test function (This allows custom assertion functions)
|
||||
// See for details: http://wiki.commonjs.org/wiki/Unit_Testing/1.1
|
||||
let Assert = suite.Assert || BaseAssert;
|
||||
// Going through each item in the test suite and wrapping it into a
|
||||
// Jetpack test format.
|
||||
Object.keys(suite).forEach(function(key) {
|
||||
// If name starts with test then it's a test function or suite.
|
||||
if (key.indexOf("test") === 0) {
|
||||
let test = suite[key];
|
||||
|
||||
// For each test function so we create a wrapper test function in a
|
||||
// jetpack format and copy that to a `target` exports.
|
||||
if (isFunction(test)) {
|
||||
|
||||
// Since names of the test may match across suites we use full object
|
||||
// path as a name to avoid overriding same function.
|
||||
target[prefix + key] = function(options) {
|
||||
|
||||
// Creating `assert` functions for this test.
|
||||
let assert = Assert(options);
|
||||
|
||||
// If CommonJS test function expects more than one argument
|
||||
// it means that test is async and second argument is a callback
|
||||
// to notify that test is finished.
|
||||
if (1 < test.length) {
|
||||
|
||||
// Letting test runner know that test is executed async and
|
||||
// creating a callback function that CommonJS tests will call
|
||||
// once it's done.
|
||||
options.waitUntilDone();
|
||||
test(assert, function() {
|
||||
options.done();
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise CommonJS test is synchronous so we call it only with
|
||||
// one argument.
|
||||
else {
|
||||
test(assert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If it's an object then it's a test suite containing test function
|
||||
// and / or nested test suites. In that case we just extend prefix used
|
||||
// and call this function to copy and wrap tests from nested suite.
|
||||
else if (isObject(test)) {
|
||||
// We need to clone `tests` instead of modifying it, since it's very
|
||||
// likely that it is frozen (usually test suites imported modules).
|
||||
test = extend(Object.prototype, test, {
|
||||
Assert: test.Assert || Assert
|
||||
});
|
||||
defineTestSuite(target, test, prefix + key + ".");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is a CommonJS test runner function, but since Jetpack test
|
||||
* runner and test format is different from CommonJS this function shims given
|
||||
* `exports` with all its tests into a Jetpack test format so that the built-in
|
||||
* test runner will be able to run CommonJS test without manual changes.
|
||||
*/
|
||||
exports.run = function run(exports) {
|
||||
|
||||
// We can't leave old properties on exports since those are test in a CommonJS
|
||||
// format that why we move everything to a new `suite` object.
|
||||
let suite = {};
|
||||
Object.keys(exports).forEach(function(key) {
|
||||
suite[key] = exports[key];
|
||||
delete exports[key];
|
||||
});
|
||||
|
||||
// Now we wrap all the CommonJS tests to a Jetpack format and define
|
||||
// those to a given `exports` object since that where jetpack test runner
|
||||
// will look for them.
|
||||
defineTestSuite(exports, suite);
|
||||
};
|
@ -206,6 +206,7 @@ const evaluate = iced(function evaluate(sandbox, uri, options) {
|
||||
source: null
|
||||
}, options);
|
||||
|
||||
|
||||
return source ? Cu.evalInSandbox(source, sandbox, version, uri, line)
|
||||
: loadSubScript(uri, sandbox, encoding);
|
||||
});
|
||||
@ -280,7 +281,6 @@ function normalize(uri) { return uri.substr(-3) === '.js' ? uri : uri + '.js'; }
|
||||
// `requirer.uri` but in some cases it may be `baseURI`. In order to
|
||||
// avoid complexity we require `baseURI` with a trailing `/`.
|
||||
const resolve = iced(function resolve(id, base) {
|
||||
if (!isRelative(id)) return id;
|
||||
let paths = id.split('/');
|
||||
let result = base.split('/');
|
||||
result.pop();
|
||||
@ -320,6 +320,7 @@ const Require = iced(function Require(loader, requirer) {
|
||||
// Resolve `id` to its requirer if it's relative.
|
||||
let requirement = requirer ? resolve(id, requirer.id) : id;
|
||||
|
||||
|
||||
// Resolves `uri` of module using loaders resolve function.
|
||||
let uri = resolveURI(requirement, mapping);
|
||||
|
||||
|
@ -769,7 +769,7 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
|
||||
# This should be contained in the test runner package.
|
||||
# maybe just do: target_cfg.main = 'test-harness/run-tests'
|
||||
harness_options['main'] = 'sdk/test/runner'
|
||||
harness_options['mainPath'] = 'sdk/test/runner'
|
||||
harness_options['mainPath'] = manifest.get_manifest_entry("addon-sdk", "lib", "sdk/test/runner").get_path()
|
||||
else:
|
||||
harness_options['main'] = target_cfg.get('main')
|
||||
harness_options['mainPath'] = manifest.top_path
|
||||
|
@ -196,3 +196,4 @@ def replace_file(env_root, dest_path, file_contents, must_rewrite_links):
|
||||
if must_rewrite_links and dest_path.endswith(".html"):
|
||||
file_contents = rewrite_links(env_root, get_sdk_docs_path(env_root), file_contents, dest_path)
|
||||
open(dest_path, "w").write(file_contents)
|
||||
|
||||
|
@ -58,22 +58,11 @@ class ManifestEntry:
|
||||
self.datamap = None
|
||||
|
||||
def get_path(self):
|
||||
name = self.moduleName
|
||||
|
||||
if name.endswith(".js"):
|
||||
name = name[:-3]
|
||||
items = []
|
||||
# Only add package name for addons, so that system module paths match
|
||||
# the path from the commonjs root directory and also match the loader
|
||||
# mappings.
|
||||
if self.packageName != "addon-sdk":
|
||||
items.append(self.packageName)
|
||||
# And for the same reason, do not append `lib/`.
|
||||
if self.sectionName == "tests":
|
||||
items.append(self.sectionName)
|
||||
items.append(name)
|
||||
|
||||
return "/".join(items)
|
||||
path = "%s/%s/%s" % \
|
||||
(self.packageName, self.sectionName, self.moduleName)
|
||||
if not path.endswith(".js"):
|
||||
path += ".js"
|
||||
return path
|
||||
|
||||
def get_entry_for_manifest(self):
|
||||
entry = { "packageName": self.packageName,
|
||||
@ -86,13 +75,13 @@ class ManifestEntry:
|
||||
for req in self.requirements:
|
||||
if isinstance(self.requirements[req], ManifestEntry):
|
||||
them = self.requirements[req] # this is another ManifestEntry
|
||||
entry["requirements"][req] = them.get_path()
|
||||
them_path = them.get_path()
|
||||
entry["requirements"][req] = {"path": them_path}
|
||||
else:
|
||||
# something magic. The manifest entry indicates that they're
|
||||
# allowed to require() it
|
||||
entry["requirements"][req] = self.requirements[req]
|
||||
assert isinstance(entry["requirements"][req], unicode) or \
|
||||
isinstance(entry["requirements"][req], str)
|
||||
assert isinstance(entry["requirements"][req], dict)
|
||||
return entry
|
||||
|
||||
def add_js(self, js_filename):
|
||||
@ -237,8 +226,7 @@ class ManifestBuilder:
|
||||
# search for all tests. self.test_modules will be passed
|
||||
# through the harness-options.json file in the
|
||||
# .allTestModules property.
|
||||
# Pass the absolute module path.
|
||||
self.test_modules.append(tme.get_path())
|
||||
self.test_modules.append(testname)
|
||||
|
||||
# include files used by the loader
|
||||
for em in self.extra_modules:
|
||||
@ -390,7 +378,7 @@ class ManifestBuilder:
|
||||
# If requirement is chrome or a pseudo-module (starts with @) make
|
||||
# path a requirement name.
|
||||
if reqname == "chrome" or reqname.startswith("@"):
|
||||
me.add_requirement(reqname, reqname)
|
||||
me.add_requirement(reqname, {"path": reqname})
|
||||
else:
|
||||
# when two modules require() the same name, do they get a
|
||||
# shared instance? This is a deep question. For now say yes.
|
||||
|
@ -169,7 +169,7 @@ def gen_manifest(template_root_dir, target_cfg, jid,
|
||||
ta_desc.appendChild(elem)
|
||||
|
||||
elem = dom.createElement("em:maxVersion")
|
||||
elem.appendChild(dom.createTextNode("21.0a1"))
|
||||
elem.appendChild(dom.createTextNode("20.*"))
|
||||
ta_desc.appendChild(elem)
|
||||
|
||||
if target_cfg.get("homepage"):
|
||||
|
@ -46,15 +46,15 @@ class Basic(unittest.TestCase):
|
||||
m = m.get_harness_options_manifest()
|
||||
|
||||
def assertReqIs(modname, reqname, path):
|
||||
reqs = m["one/%s" % modname]["requirements"]
|
||||
self.failUnlessEqual(reqs[reqname], path)
|
||||
assertReqIs("main", "panel", "sdk/panel")
|
||||
assertReqIs("main", "two.js", "one/two")
|
||||
assertReqIs("main", "./two", "one/two")
|
||||
assertReqIs("main", "sdk/tabs.js", "sdk/tabs")
|
||||
assertReqIs("main", "./subdir/three", "one/subdir/three")
|
||||
assertReqIs("two", "main", "one/main")
|
||||
assertReqIs("subdir/three", "../main", "one/main")
|
||||
reqs = m["one/lib/%s.js" % modname]["requirements"]
|
||||
self.failUnlessEqual(reqs[reqname]["path"], path)
|
||||
assertReqIs("main", "panel", "addon-sdk/lib/sdk/panel.js")
|
||||
assertReqIs("main", "two.js", "one/lib/two.js")
|
||||
assertReqIs("main", "./two", "one/lib/two.js")
|
||||
assertReqIs("main", "sdk/tabs.js", "addon-sdk/lib/sdk/tabs.js")
|
||||
assertReqIs("main", "./subdir/three", "one/lib/subdir/three.js")
|
||||
assertReqIs("two", "main", "one/lib/main.js")
|
||||
assertReqIs("subdir/three", "../main", "one/lib/main.js")
|
||||
|
||||
target_cfg.dependencies = []
|
||||
# now, because .dependencies *is* provided, we won't search 'deps',
|
||||
@ -74,11 +74,11 @@ class Basic(unittest.TestCase):
|
||||
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
|
||||
m = m.get_harness_options_manifest()
|
||||
def assertReqIs(modname, reqname, path):
|
||||
reqs = m["three/%s" % modname]["requirements"]
|
||||
self.failUnlessEqual(reqs[reqname], path)
|
||||
assertReqIs("main", "three-a", "three-a/main")
|
||||
assertReqIs("main", "three-b", "three-b/main")
|
||||
assertReqIs("main", "three-c", "three-c/main")
|
||||
reqs = m["three/lib/%s.js" % modname]["requirements"]
|
||||
self.failUnlessEqual(reqs[reqname]["path"], path)
|
||||
assertReqIs("main", "three-a", "three-a/lib/main.js")
|
||||
assertReqIs("main", "three-b", "three-b/lib/main.js")
|
||||
assertReqIs("main", "three-c", "three-c/lib/main.js")
|
||||
|
||||
def test_relative_main_in_top(self):
|
||||
target_cfg = self.get_pkg("five")
|
||||
@ -91,7 +91,7 @@ class Basic(unittest.TestCase):
|
||||
# all we care about is that this next call doesn't raise an exception
|
||||
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False)
|
||||
m = m.get_harness_options_manifest()
|
||||
reqs = m["five/main"]["requirements"]
|
||||
reqs = m["five/lib/main.js"]["requirements"]
|
||||
self.failUnlessEqual(reqs, {});
|
||||
|
||||
def test_unreachable_relative_main_in_top(self):
|
||||
|
@ -328,7 +328,7 @@ class SmallXPI(unittest.TestCase):
|
||||
[target_cfg.name, "addon-sdk"])
|
||||
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True)
|
||||
self.failUnlessEqual(sorted(m.get_all_test_modules()),
|
||||
sorted(["three/tests/test-one", "three/tests/test-two"]))
|
||||
sorted(["test-one", "test-two"]))
|
||||
# the current __init__.py code omits limit_to=used_files for 'cfx
|
||||
# test', so all test files are included in the XPI. But the test
|
||||
# runner will only execute the tests that m.get_all_test_modules()
|
||||
@ -371,7 +371,7 @@ class SmallXPI(unittest.TestCase):
|
||||
m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=True,
|
||||
test_filter_re=FILTER)
|
||||
self.failUnlessEqual(sorted(m.get_all_test_modules()),
|
||||
sorted(["three/tests/test-one"]))
|
||||
sorted(["test-one"]))
|
||||
# the current __init__.py code omits limit_to=used_files for 'cfx
|
||||
# test', so all test files are included in the XPI. But the test
|
||||
# runner will only execute the tests that m.get_all_test_modules()
|
||||
|
@ -182,7 +182,7 @@ class Markdown:
|
||||
def __init__(self,
|
||||
extensions=[],
|
||||
extension_configs={},
|
||||
safe_mode = False,
|
||||
safe_mode = False,
|
||||
output_format=DEFAULT_OUTPUT_FORMAT):
|
||||
"""
|
||||
Creates a new Markdown instance.
|
||||
@ -200,12 +200,12 @@ class Markdown:
|
||||
* "xhtml": Outputs latest supported version of XHTML (currently XHTML 1.1).
|
||||
* "html4": Outputs HTML 4
|
||||
* "html": Outputs latest supported version of HTML (currently HTML 4).
|
||||
Note that it is suggested that the more specific formats ("xhtml1"
|
||||
Note that it is suggested that the more specific formats ("xhtml1"
|
||||
and "html4") be used as "xhtml" or "html" may change in the future
|
||||
if it makes sense at that time.
|
||||
if it makes sense at that time.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
self.safeMode = safe_mode
|
||||
self.registeredExtensions = []
|
||||
self.docType = ""
|
||||
@ -300,9 +300,9 @@ class Markdown:
|
||||
|
||||
# Map format keys to serializers
|
||||
self.output_formats = {
|
||||
'html' : html4.to_html_string,
|
||||
'html' : html4.to_html_string,
|
||||
'html4' : html4.to_html_string,
|
||||
'xhtml' : etree.tostring,
|
||||
'xhtml' : etree.tostring,
|
||||
'xhtml1': etree.tostring,
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ class Markdown:
|
||||
except AttributeError:
|
||||
message(ERROR, "Incorrect type! Extension '%s' is "
|
||||
"neither a string or an Extension." %(repr(ext)))
|
||||
|
||||
|
||||
|
||||
def registerExtension(self, extension):
|
||||
""" This gets called by the extension """
|
||||
@ -574,15 +574,15 @@ def markdown(text,
|
||||
* "xhtml": Outputs latest supported version of XHTML (currently XHTML 1.1).
|
||||
* "html4": Outputs HTML 4
|
||||
* "html": Outputs latest supported version of HTML (currently HTML 4).
|
||||
Note that it is suggested that the more specific formats ("xhtml1"
|
||||
Note that it is suggested that the more specific formats ("xhtml1"
|
||||
and "html4") be used as "xhtml" or "html" may change in the future
|
||||
if it makes sense at that time.
|
||||
if it makes sense at that time.
|
||||
|
||||
Returns: An HTML document as a string.
|
||||
|
||||
"""
|
||||
md = Markdown(extensions=load_extensions(extensions),
|
||||
safe_mode=safe_mode,
|
||||
safe_mode=safe_mode,
|
||||
output_format=output_format)
|
||||
return md.convert(text)
|
||||
|
||||
@ -594,7 +594,7 @@ def markdownFromFile(input = None,
|
||||
safe_mode = False,
|
||||
output_format = DEFAULT_OUTPUT_FORMAT):
|
||||
"""Read markdown code from a file and write it to a file or a stream."""
|
||||
md = Markdown(extensions=load_extensions(extensions),
|
||||
md = Markdown(extensions=load_extensions(extensions),
|
||||
safe_mode=safe_mode,
|
||||
output_format=output_format)
|
||||
md.convertFile(input, output, encoding)
|
||||
|
@ -453,10 +453,8 @@ class Runner(object):
|
||||
if binary is None:
|
||||
for bin in [(program_files, 'Mozilla Firefox', 'firefox.exe'),
|
||||
(os.environ.get("ProgramFiles(x86)"),'Mozilla Firefox', 'firefox.exe'),
|
||||
(program_files, 'Nightly', 'firefox.exe'),
|
||||
(os.environ.get("ProgramFiles(x86)"),'Nightly', 'firefox.exe'),
|
||||
(program_files, 'Aurora', 'firefox.exe'),
|
||||
(os.environ.get("ProgramFiles(x86)"),'Aurora', 'firefox.exe')
|
||||
(program_files,'Nightly', 'firefox.exe'),
|
||||
(os.environ.get("ProgramFiles(x86)"),'Nightly', 'firefox.exe')
|
||||
]:
|
||||
path = os.path.join(*bin)
|
||||
if os.path.isfile(path):
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"id": "test-layout-change"
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { packed } = require("sdk/self");
|
||||
const url = require("sdk/url");
|
||||
|
||||
exports["test self.packed"] = function (assert) {
|
||||
assert.ok(packed, "require('sdk/self').packed is correct");
|
||||
}
|
||||
|
||||
exports["test url.toFilename"] = function (assert) {
|
||||
assert.throws(
|
||||
function() { url.toFilename(module.uri); },
|
||||
/cannot map to filename: /,
|
||||
"url.toFilename() can fail for packed XPIs");
|
||||
}
|
||||
|
||||
require("sdk/test/runner").runTestsFromModule(module);
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"id": "test-url",
|
||||
"unpack": false
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { packed } = require("sdk/self");
|
||||
const url = require("sdk/url");
|
||||
|
||||
exports["test self.packed"] = function (assert) {
|
||||
assert.ok(!packed, "require('sdk/self').packed is correct");
|
||||
}
|
||||
|
||||
exports["test url.toFilename"] = function (assert) {
|
||||
assert.ok(/.*main\.js$/.test(url.toFilename(module.uri)),
|
||||
"url.toFilename() on resource: URIs should work");
|
||||
}
|
||||
|
||||
require("sdk/test/runner").runTestsFromModule(module);
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"id": "test-url",
|
||||
"unpack": true
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const AssertBase = require("sdk/test/assert").Assert;
|
||||
const AssertBase = require("test/assert").Assert;
|
||||
|
||||
/**
|
||||
* Generates custom assertion constructors that may be bundled with a test
|
||||
|
@ -4,5 +4,5 @@
|
||||
|
||||
define(function (require, exports) {
|
||||
exports.name = 'tiger';
|
||||
exports.type = require('./types/cat').type;
|
||||
exports.type = require('modules/types/cat').type;
|
||||
});
|
||||
|
@ -47,14 +47,10 @@ exports.testGetIsActive = function (test) {
|
||||
|
||||
test.assertEqual(pb.isActive, false,
|
||||
"private-browsing.isActive is correct without modifying PB service");
|
||||
test.assertEqual(pb.isPrivate(), false,
|
||||
"private-browsing.sPrivate() is correct without modifying PB service");
|
||||
|
||||
pb.once("start", function() {
|
||||
test.assert(pb.isActive,
|
||||
"private-browsing.isActive is correct after modifying PB service");
|
||||
test.assert(pb.isPrivate(),
|
||||
"private-browsing.sPrivate() is correct after modifying PB service");
|
||||
// Switch back to normal mode.
|
||||
pb.deactivate();
|
||||
});
|
||||
@ -63,8 +59,6 @@ exports.testGetIsActive = function (test) {
|
||||
pb.once("stop", function() {
|
||||
test.assert(!pb.isActive,
|
||||
"private-browsing.isActive is correct after modifying PB service");
|
||||
test.assert(!pb.isPrivate(),
|
||||
"private-browsing.sPrivate() is correct after modifying PB service");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
@ -78,8 +72,6 @@ exports.testStart = function(test) {
|
||||
'private mode is active when "start" event is emitted');
|
||||
test.assert(pb.isActive,
|
||||
'`isActive` is `true` when "start" event is emitted');
|
||||
test.assert(pb.isPrivate(),
|
||||
'`isPrivate` is `true` when "start" event is emitted');
|
||||
pb.removeListener("start", onStart);
|
||||
deactivate(function() test.done());
|
||||
});
|
||||
@ -94,8 +86,6 @@ exports.testStop = function(test) {
|
||||
"private mode is disabled when stop event is emitted");
|
||||
test.assertEqual(pb.isActive, false,
|
||||
"`isActive` is `false` when stop event is emitted");
|
||||
test.assertEqual(pb.isPrivate(), false,
|
||||
"`isPrivate()` is `false` when stop event is emitted");
|
||||
test.done();
|
||||
});
|
||||
pb.activate();
|
||||
@ -116,8 +106,6 @@ exports.testBothListeners = function(test) {
|
||||
"private mode is disabled when stop event is emitted");
|
||||
test.assertEqual(pb.isActive, false,
|
||||
"`isActive` is `false` when stop event is emitted");
|
||||
test.assertEqual(pb.isPrivate(), false,
|
||||
"`isPrivate()` is `false` when stop event is emitted");
|
||||
|
||||
pb.on("start", finish);
|
||||
pb.removeListener("start", onStart);
|
||||
@ -133,8 +121,6 @@ exports.testBothListeners = function(test) {
|
||||
"private mode is active when start event is emitted");
|
||||
test.assert(pb.isActive,
|
||||
"`isActive` is `true` when start event is emitted");
|
||||
test.assert(pb.isPrivate(),
|
||||
"`isPrivate()` is `true` when start event is emitted");
|
||||
|
||||
pb.on("stop", onStop);
|
||||
pb.deactivate();
|
||||
@ -151,8 +137,6 @@ exports.testBothListeners = function(test) {
|
||||
"private mode is active when start event is emitted");
|
||||
test.assert(pb.isActive,
|
||||
"`isActive` is `true` when start event is emitted");
|
||||
test.assert(pb.isPrivate(),
|
||||
"`isPrivate()` is `true` when start event is emitted");
|
||||
|
||||
pb.removeListener("start", finish);
|
||||
pb.removeListener("stop", onStop);
|
||||
@ -161,7 +145,6 @@ exports.testBothListeners = function(test) {
|
||||
pb.once("stop", function () {
|
||||
test.assertEqual(pbUtils.getMode(), false);
|
||||
test.assertEqual(pb.isActive, false);
|
||||
test.assertEqual(pb.isPrivate(), false);
|
||||
|
||||
test.done();
|
||||
});
|
||||
|
@ -7,15 +7,11 @@ let { Cc,Ci } = require('chrome');
|
||||
const unload = require("sdk/system/unload");
|
||||
const { Loader } = require('sdk/test/loader');
|
||||
const { windows: windowsIterator } = require("sdk/window/utils");
|
||||
const windows = require("sdk/windows").browserWindows;
|
||||
const windows = require("windows").browserWindows;
|
||||
|
||||
let { loader } = LoaderWithHookedConsole();
|
||||
const pb = loader.require('sdk/private-browsing');
|
||||
const pbUtils = loader.require('sdk/private-browsing/utils');
|
||||
const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
|
||||
|
||||
require('sdk/tabs/utils');
|
||||
require('sdk/windows');
|
||||
|
||||
function LoaderWithHookedConsole() {
|
||||
let errors = [];
|
||||
@ -44,8 +40,6 @@ function deactivate(callback) {
|
||||
}
|
||||
exports.deactivate = deactivate;
|
||||
|
||||
exports.loader = loader;
|
||||
exports.pb = pb;
|
||||
exports.pbUtils = pbUtils;
|
||||
exports.getOwnerWindow = getOwnerWindow;
|
||||
exports.LoaderWithHookedConsole = LoaderWithHookedConsole;
|
||||
|
@ -1,24 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { Ci } = require('chrome');
|
||||
const { pb, pbUtils, loader: pbLoader, getOwnerWindow } = require('./helper');
|
||||
|
||||
exports.testIsPrivateOnTab = function(test) {
|
||||
const { openTab, closeTab } = pbLoader.require('sdk/tabs/utils');
|
||||
|
||||
let window = pbLoader.require('sdk/windows').browserWindows.activeWindow;
|
||||
let chromeWindow = pbLoader.require('sdk/private-browsing/window/utils').getOwnerWindow(window);
|
||||
test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
|
||||
test.assert(!pb.isPrivate(chromeWindow), 'the top level window is not private');
|
||||
|
||||
let rawTab = openTab(chromeWindow, 'data:text/html,<h1>Hi!</h1>', {
|
||||
private: true
|
||||
});
|
||||
|
||||
// test that the tab is private
|
||||
test.assert(rawTab.browser.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing);
|
||||
test.assert(pb.isPrivate(rawTab.browser.contentWindow));
|
||||
test.assert(pb.isPrivate(rawTab.browser));
|
||||
|
||||
closeTab(rawTab);
|
||||
}
|
@ -4,11 +4,9 @@
|
||||
'use strict';
|
||||
|
||||
const { pb, pbUtils } = require('./helper');
|
||||
const { openDialog } = require('sdk/window/utils');
|
||||
const { isPrivate } = require('sdk/private-browsing');
|
||||
const { browserWindows: windows } = require('sdk/windows');
|
||||
const { openDialog } = require('window/utils');
|
||||
|
||||
exports.testPerWindowPrivateBrowsingGetter = function(assert, done) {
|
||||
exports["test Per Window Private Browsing getter"] = function(assert, done) {
|
||||
let win = openDialog({
|
||||
private: true
|
||||
});
|
||||
@ -25,30 +23,8 @@ exports.testPerWindowPrivateBrowsingGetter = function(assert, done) {
|
||||
assert.equal(pb.isActive, false, 'PB mode is not active');
|
||||
done();
|
||||
}, false);
|
||||
|
||||
win.close();
|
||||
}, false);
|
||||
}
|
||||
|
||||
exports.testIsPrivateOnWindowOn = function(assert, done) {
|
||||
windows.open({
|
||||
private: true,
|
||||
onOpen: function(window) {
|
||||
assert.equal(isPrivate(window), true, 'isPrivate for a window is true when it should be');
|
||||
assert.equal(isPrivate(window.tabs[0]), true, 'isPrivate for a tab is false when it should be');
|
||||
window.close(done);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.testIsPrivateOnWindowOff = function(assert, done) {
|
||||
windows.open({
|
||||
onOpen: function(window) {
|
||||
assert.equal(isPrivate(window), false, 'isPrivate for a window is false when it should be');
|
||||
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
|
||||
window.close(done);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
require("test").run(exports);
|
||||
|
@ -918,7 +918,7 @@ exports['test ready event on new window tab'] = function(test) {
|
||||
exports['test unique tab ids'] = function(test) {
|
||||
test.waitUntilDone();
|
||||
|
||||
var windows = require('sdk/windows').browserWindows,
|
||||
var windows = require('windows').browserWindows,
|
||||
tabIds = {}, win1, win2;
|
||||
|
||||
let steps = [
|
||||
|
@ -21,7 +21,7 @@ function isChromeVisible(window) {
|
||||
|
||||
exports['test that add-on page has no chrome'] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
loader.require('sdk/addon-page');
|
||||
loader.require('addon-kit/addon-page');
|
||||
|
||||
let window = windows.activeBrowserWindow;
|
||||
let tab = openTab(window, uri);
|
||||
@ -44,7 +44,7 @@ exports['test that add-on page has no chrome'] = function(assert, done) {
|
||||
|
||||
exports['test that add-on page with hash has no chrome'] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
loader.require('sdk/addon-page');
|
||||
loader.require('addon-kit/addon-page');
|
||||
|
||||
let window = windows.activeBrowserWindow;
|
||||
let tab = openTab(window, uri + "#foo");
|
||||
@ -67,7 +67,7 @@ exports['test that add-on page with hash has no chrome'] = function(assert, done
|
||||
|
||||
exports['test that add-on page with querystring has no chrome'] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
loader.require('sdk/addon-page');
|
||||
loader.require('addon-kit/addon-page');
|
||||
|
||||
let window = windows.activeBrowserWindow;
|
||||
let tab = openTab(window, uri + '?foo=bar');
|
||||
@ -90,7 +90,7 @@ exports['test that add-on page with querystring has no chrome'] = function(asser
|
||||
|
||||
exports['test that add-on page with hash and querystring has no chrome'] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
loader.require('sdk/addon-page');
|
||||
loader.require('addon-kit/addon-page');
|
||||
|
||||
let window = windows.activeBrowserWindow;
|
||||
let tab = openTab(window, uri + '#foo?foo=bar');
|
||||
@ -113,7 +113,7 @@ exports['test that add-on page with hash and querystring has no chrome'] = funct
|
||||
|
||||
exports['test that malformed uri is not an addon-page'] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
loader.require('sdk/addon-page');
|
||||
loader.require('addon-kit/addon-page');
|
||||
|
||||
let window = windows.activeBrowserWindow;
|
||||
let tab = openTab(window, uri + 'anguage');
|
||||
@ -146,4 +146,4 @@ exports['test that add-on pages are closed on unload'] = function(assert, done)
|
||||
});
|
||||
};
|
||||
|
||||
require('test').run(exports);
|
||||
require('sdk/test').run(exports);
|
||||
|
@ -1360,7 +1360,7 @@ exports.testMultipleModulesOrderOverflow = function (test) {
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("sdk/preferences/service");
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 0);
|
||||
|
||||
// Use each module to add an item, then unload each module in turn.
|
||||
@ -1401,7 +1401,7 @@ exports.testMultipleModulesOverflowHidden = function (test) {
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("sdk/preferences/service");
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 0);
|
||||
|
||||
// Use each module to add an item, then unload each module in turn.
|
||||
@ -1426,7 +1426,7 @@ exports.testMultipleModulesOverflowHidden2 = function (test) {
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("sdk/preferences/service");
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 0);
|
||||
|
||||
// Use each module to add an item, then unload each module in turn.
|
||||
@ -1450,7 +1450,7 @@ exports.testOverflowIgnoresHidden = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let prefs = loader.loader.require("sdk/preferences/service");
|
||||
let prefs = loader.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
@ -1481,7 +1481,7 @@ exports.testOverflowIgnoresHiddenMultipleModules1 = function (test) {
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("sdk/preferences/service");
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
@ -1516,7 +1516,7 @@ exports.testOverflowIgnoresHiddenMultipleModules2 = function (test) {
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("sdk/preferences/service");
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
@ -1551,7 +1551,7 @@ exports.testOverflowIgnoresHiddenMultipleModules3 = function (test) {
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("sdk/preferences/service");
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
@ -1585,7 +1585,7 @@ exports.testOverflowTransition = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let prefs = loader.loader.require("sdk/preferences/service");
|
||||
let prefs = loader.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let pItems = [
|
||||
@ -1718,6 +1718,7 @@ exports.testMenuCommand = function (test) {
|
||||
let topMenu = new loader.cm.Menu({
|
||||
label: "top menu",
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' let Ci = Components["interfaces"];' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
@ -1797,6 +1798,7 @@ exports.testItemClick = function (test) {
|
||||
label: "item",
|
||||
data: "item data",
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' let Ci = Components["interfaces"];' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
@ -1844,6 +1846,7 @@ exports.testMenuClick = function (test) {
|
||||
let topMenu = new loader.cm.Menu({
|
||||
label: "top menu",
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' let Ci = Components["interfaces"];' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
|
@ -5,13 +5,6 @@
|
||||
const port = 8099;
|
||||
const file = require("sdk/io/file");
|
||||
const { pathFor } = require("sdk/system");
|
||||
const { Loader } = require("sdk/test/loader");
|
||||
const options = require("@test/options");
|
||||
|
||||
const loader = Loader(module);
|
||||
const httpd = loader.require("sdk/test/httpd");
|
||||
if (options.parseable || options.verbose)
|
||||
loader.sandbox("sdk/test/httpd").DEBUG = true;
|
||||
|
||||
exports.testBasicHTTPServer = function(test) {
|
||||
// Use the profile directory for the temporary file as that will be deleted
|
||||
@ -23,7 +16,8 @@ exports.testBasicHTTPServer = function(test) {
|
||||
fileStream.write(content);
|
||||
fileStream.close();
|
||||
|
||||
let srv = httpd.startServerAsync(port, basePath);
|
||||
let { startServerAsync } = require("sdk/test/httpd");
|
||||
let srv = startServerAsync(port, basePath);
|
||||
|
||||
test.waitUntilDone();
|
||||
|
||||
@ -47,7 +41,8 @@ exports.testBasicHTTPServer = function(test) {
|
||||
exports.testDynamicServer = function (test) {
|
||||
let content = "This is the HTTPD test file.\n";
|
||||
|
||||
let srv = httpd.startServerAsync(port);
|
||||
let { startServerAsync } = require("sdk/test/httpd");
|
||||
let srv = startServerAsync(port);
|
||||
|
||||
// See documentation here:
|
||||
//http://doxygen.db48x.net/mozilla/html/interfacensIHttpServer.html#a81fc7e7e29d82aac5ce7d56d0bedfb3a
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let xulApp = require("sdk/system/xul-app");
|
||||
let xulApp = require("api-utils/xul-app");
|
||||
if (xulApp.versionInRange(xulApp.platformVersion, "16.0a1", "*")) {
|
||||
new function tests() {
|
||||
|
||||
const { indexedDB, IDBKeyRange, DOMException, IDBCursor, IDBTransaction,
|
||||
IDBOpenDBRequest, IDBVersionChangeEvent, IDBDatabase, IDBFactory,
|
||||
IDBIndex, IDBObjectStore, IDBRequest
|
||||
} = require("sdk/indexed-db");
|
||||
} = require("indexed-db");
|
||||
|
||||
exports["test indexedDB is frozen"] = function(assert){
|
||||
let original = indexedDB.open;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@ -184,4 +184,4 @@ if (require("sdk/system/xul-app").is("Fennec")) {
|
||||
}
|
||||
}
|
||||
|
||||
require("sdk/test/runner").runTestsFromModule(module);
|
||||
require("test").run(exports);
|
@ -6,10 +6,10 @@
|
||||
|
||||
let { Loader, main, unload, parseStack } = require('toolkit/loader');
|
||||
|
||||
let root = module.uri.substr(0, module.uri.lastIndexOf('/'))
|
||||
|
||||
exports['test dependency cycles'] = function(assert) {
|
||||
let uri = root + '/fixtures/loader/cycles/';
|
||||
let uri = module.uri.substr(0, module.uri.lastIndexOf('/')) +
|
||||
'/fixtures/loader/cycles/'
|
||||
|
||||
let loader = Loader({ paths: { '': uri } });
|
||||
|
||||
let program = main(loader, 'main');
|
||||
@ -19,10 +19,12 @@ exports['test dependency cycles'] = function(assert) {
|
||||
assert.equal(program.c.main, program, 'module `c` gets correct `main`');
|
||||
|
||||
unload(loader);
|
||||
}
|
||||
};
|
||||
|
||||
exports['test syntax errors'] = function(assert) {
|
||||
let uri = root + '/fixtures/loader/syntax-error/';
|
||||
let uri = module.uri.substr(0, module.uri.lastIndexOf('/')) +
|
||||
'/fixtures/loader/syntax-error/';
|
||||
|
||||
let loader = Loader({ paths: { '': uri } });
|
||||
|
||||
try {
|
||||
@ -41,10 +43,12 @@ exports['test syntax errors'] = function(assert) {
|
||||
} finally {
|
||||
unload(loader);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports['test missing module'] = function(assert) {
|
||||
let uri = root + '/fixtures/loader/missing/'
|
||||
let uri = module.uri.substr(0, module.uri.lastIndexOf('/')) +
|
||||
'/fixtures/loader/missing/'
|
||||
|
||||
let loader = Loader({ paths: { '': uri } });
|
||||
|
||||
try {
|
||||
@ -71,7 +75,8 @@ exports['test missing module'] = function(assert) {
|
||||
}
|
||||
|
||||
exports['test exceptions in modules'] = function(assert) {
|
||||
let uri = root + '/fixtures/loader/exceptions/'
|
||||
let uri = module.uri.substr(0, module.uri.lastIndexOf('/')) +
|
||||
'/fixtures/loader/exceptions/'
|
||||
|
||||
let loader = Loader({ paths: { '': uri } });
|
||||
|
||||
@ -107,7 +112,9 @@ exports['test exceptions in modules'] = function(assert) {
|
||||
}
|
||||
|
||||
exports['test early errors in module'] = function(assert) {
|
||||
let uri = root + '/fixtures/loader/errors/';
|
||||
let uri = module.uri.substr(0, module.uri.lastIndexOf('/')) +
|
||||
'/fixtures/loader/errors/'
|
||||
|
||||
let loader = Loader({ paths: { '': uri } });
|
||||
|
||||
try {
|
||||
|
@ -5,7 +5,7 @@
|
||||
"use strict";
|
||||
|
||||
const { readURI, readURISync } = require("sdk/net/url");
|
||||
const { data } = require("sdk/self");
|
||||
const { data } = require("self");
|
||||
|
||||
const utf8text = "Hello, ゼロ!";
|
||||
const latin1text = "Hello, ゼãƒ!";
|
||||
|
@ -12,7 +12,7 @@ const { Cc, Ci } = require("chrome");
|
||||
const { open, getFrames, getMostRecentBrowserWindow } = require('sdk/window/utils');
|
||||
const windowUtils = require('sdk/deprecated/window-utils');
|
||||
const { getTabContentWindow, getActiveTab, openTab, closeTab } = require('sdk/tabs/utils');
|
||||
const { data } = require('sdk/self');
|
||||
const { data } = require('self');
|
||||
|
||||
/* 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
|
||||
@ -357,27 +357,6 @@ exports.testRelatedTab = function(test) {
|
||||
});
|
||||
};
|
||||
|
||||
exports.testRelatedTabNoRequireTab = function(test) {
|
||||
test.waitUntilDone();
|
||||
|
||||
let loader = Loader(module);
|
||||
let tab;
|
||||
let url = "data:text/html;charset=utf-8," + encodeURI("Test related worker tab 2");
|
||||
let { PageMod } = loader.require("sdk/page-mod");
|
||||
let pageMod = new PageMod({
|
||||
include: url,
|
||||
onAttach: function(worker) {
|
||||
test.assertEqual(worker.tab.url, url, "Worker.tab.url is valid");
|
||||
worker.tab.close();
|
||||
pageMod.destroy();
|
||||
loader.unload();
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
|
||||
tabs.open(url);
|
||||
};
|
||||
|
||||
exports.testRelatedTabNoOtherReqs = function(test) {
|
||||
test.waitUntilDone();
|
||||
|
||||
@ -654,7 +633,7 @@ exports['test111 attachTo [frame]'] = function(test) {
|
||||
this.destroy();
|
||||
if (++messageCount == 2) {
|
||||
mod.destroy();
|
||||
require('sdk/tabs').activeTab.close(function() {
|
||||
require('tabs').activeTab.close(function() {
|
||||
test.done();
|
||||
});
|
||||
}
|
||||
@ -813,7 +792,7 @@ exports.testPageModCssAutomaticDestroy = function(test) {
|
||||
test.waitUntilDone();
|
||||
let loader = Loader(module);
|
||||
|
||||
let pageMod = loader.require("sdk/page-mod").PageMod({
|
||||
let pageMod = loader.require("page-mod").PageMod({
|
||||
include: "data:*",
|
||||
contentStyle: "div { width: 100px!important; }"
|
||||
});
|
||||
@ -853,7 +832,7 @@ exports.testPageModTimeout = function(test) {
|
||||
test.waitUntilDone();
|
||||
let tab = null
|
||||
let loader = Loader(module);
|
||||
let { PageMod } = loader.require("sdk/page-mod");
|
||||
let { PageMod } = loader.require("page-mod");
|
||||
|
||||
let mod = PageMod({
|
||||
include: "data:*",
|
||||
@ -888,7 +867,7 @@ exports.testPageModcancelTimeout = function(test) {
|
||||
test.waitUntilDone();
|
||||
let tab = null
|
||||
let loader = Loader(module);
|
||||
let { PageMod } = loader.require("sdk/page-mod");
|
||||
let { PageMod } = loader.require("page-mod");
|
||||
|
||||
let mod = PageMod({
|
||||
include: "data:*",
|
||||
@ -1050,3 +1029,4 @@ if (require("sdk/system/xul-app").is("Fennec")) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
let { Cc, Ci } = require("chrome");
|
||||
const { Loader } = require('sdk/test/loader');
|
||||
const timer = require("sdk/timers");
|
||||
const self = require('sdk/self');
|
||||
const self = require('self');
|
||||
|
||||
exports["test Panel"] = function(assert, done) {
|
||||
const { Panel } = require('sdk/panel');
|
||||
|
@ -3,46 +3,18 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
'use strict';
|
||||
|
||||
const { Ci } = require('chrome');
|
||||
const { pb, pbUtils, getOwnerWindow } = require('./private-browsing/helper');
|
||||
const { pb, pbUtils } = require('./private-browsing/helper');
|
||||
const { merge } = require('sdk/util/object');
|
||||
const windows = require('sdk/windows').browserWindows;
|
||||
const winUtils = require('sdk/window/utils');
|
||||
const { is } = require('sdk/system/xul-app');
|
||||
const { isPrivate } = require('sdk/private-browsing');
|
||||
|
||||
// is global pb is enabled?
|
||||
if (pbUtils.isGlobalPBSupported) {
|
||||
merge(module.exports, require('./private-browsing/global'));
|
||||
|
||||
exports.testGlobalOnlyOnFirefox = function(test) {
|
||||
test.assert(is("Firefox"), "isGlobalPBSupported is only true on Firefox");
|
||||
}
|
||||
}
|
||||
else if (pbUtils.isWindowPBSupported) {
|
||||
merge(module.exports, require('./private-browsing/windows'));
|
||||
|
||||
exports.testPWOnlyOnFirefox = function(test) {
|
||||
test.assert(is("Firefox"), "isWindowPBSupported is only true on Firefox");
|
||||
}
|
||||
}
|
||||
// only on Fennec
|
||||
else if (pbUtils.isTabPBSupported) {
|
||||
merge(module.exports, require('./private-browsing/tabs'));
|
||||
|
||||
exports.testPTOnlyOnFennec = function(test) {
|
||||
test.assert(is("Fennec"), "isTabPBSupported is only true on Fennec");
|
||||
}
|
||||
}
|
||||
|
||||
exports.testIsPrivateDefaults = function(test) {
|
||||
test.assertEqual(pb.isPrivate(), false, 'undefined is not private');
|
||||
test.assertEqual(pb.isPrivate('test'), false, 'strings are not private');
|
||||
test.assertEqual(pb.isPrivate({}), false, 'random objects are not private');
|
||||
test.assertEqual(pb.isPrivate(4), false, 'numbers are not private');
|
||||
test.assertEqual(pb.isPrivate(/abc/), false, 'regex are not private');
|
||||
test.assertEqual(pb.isPrivate(function() {}), false, 'functions are not private');
|
||||
};
|
||||
|
||||
exports.testWindowDefaults = function(test) {
|
||||
test.assertEqual(windows.activeWindow.isPrivateBrowsing, false, 'window is not private browsing by default');
|
||||
@ -57,31 +29,3 @@ exports.testIsActiveDefault = function(test) {
|
||||
'pb.isActive returns false when private browsing isn\'t supported');
|
||||
};
|
||||
|
||||
exports.testGetOwnerWindow = function(test) {
|
||||
test.waitUntilDone();
|
||||
|
||||
let window = windows.activeWindow;
|
||||
let chromeWindow = getOwnerWindow(window);
|
||||
test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
|
||||
|
||||
window.tabs.open({
|
||||
url: 'about:blank',
|
||||
private: true, // should be ignored in this case
|
||||
onOpen: function(tab) {
|
||||
// test that getOwnerWindow works as expected
|
||||
if (is('Fennec')) {
|
||||
test.assertNotStrictEqual(chromeWindow, getOwnerWindow(tab));
|
||||
test.assert(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow);
|
||||
}
|
||||
else {
|
||||
test.assertStrictEqual(chromeWindow, getOwnerWindow(tab), 'associated window is the same for window and window\'s tab');
|
||||
}
|
||||
|
||||
// test that the tab is not private
|
||||
// private flag should be ignored by default
|
||||
test.assert(!isPrivate(tab));
|
||||
|
||||
tab.close(function() test.done());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -15,9 +15,6 @@ if (options.parseable || options.verbose)
|
||||
loader.sandbox("sdk/test/httpd").DEBUG = true;
|
||||
const { startServerAsync } = httpd;
|
||||
|
||||
const { Cc, Ci, Cu } = require("chrome");
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Use the profile directory for the temporary files as that will be deleted
|
||||
// when tests are complete
|
||||
const basePath = pathFor("ProfD")
|
||||
@ -143,55 +140,6 @@ exports.testComplexHeader = function (test) {
|
||||
}).get();
|
||||
}
|
||||
|
||||
// Force Allow Third Party cookies
|
||||
exports.test3rdPartyCookies = function (test) {
|
||||
let srv = startServerAsync(port, basePath);
|
||||
|
||||
let basename = "test-request-3rd-party-cookies.sjs";
|
||||
|
||||
// Function to handle the requests in the server
|
||||
let content = function handleRequest(request, response) {
|
||||
var cookiePresent = request.hasHeader("Cookie");
|
||||
// If no cookie, set it
|
||||
if(!cookiePresent) {
|
||||
response.setHeader("Set-Cookie", "cookie=monster;", "true");
|
||||
response.setHeader("x-jetpack-3rd-party", "false", "true");
|
||||
} else {
|
||||
// We got the cookie, say so
|
||||
response.setHeader("x-jetpack-3rd-party", "true", "true");
|
||||
}
|
||||
|
||||
response.write("<html><body>This tests 3rd party cookies.</body></html>");
|
||||
}.toString()
|
||||
|
||||
prepareFile(basename, content);
|
||||
|
||||
// Disable the 3rd party cookies
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 1);
|
||||
|
||||
test.waitUntilDone();
|
||||
Request({
|
||||
url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs",
|
||||
onComplete: function (response) {
|
||||
// Check that the server created the cookie
|
||||
test.assertEqual(response.headers['Set-Cookie'], 'cookie=monster;');
|
||||
|
||||
// Check it wasn't there before
|
||||
test.assertEqual(response.headers['x-jetpack-3rd-party'], 'false');
|
||||
|
||||
// Make a second request, and check that the server this time
|
||||
// got the cookie
|
||||
Request({
|
||||
url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs",
|
||||
onComplete: function (response) {
|
||||
test.assertEqual(response.headers['x-jetpack-3rd-party'], 'true');
|
||||
srv.stop(function() test.done());
|
||||
}
|
||||
}).get();
|
||||
}
|
||||
}).get();
|
||||
}
|
||||
|
||||
exports.testSimpleJSON = function (test) {
|
||||
let srv = startServerAsync(port, basePath);
|
||||
let json = { foo: "bar" };
|
||||
|
@ -14,16 +14,12 @@ const HTML = "<html>\
|
||||
|
||||
const URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
|
||||
|
||||
const FRAME_HTML = "<iframe src='" + URL + "'><iframe>";
|
||||
const FRAME_URL = "data:text/html;charset=utf-8," + encodeURIComponent(FRAME_HTML);
|
||||
|
||||
const { defer } = require("sdk/core/promise");
|
||||
const tabs = require("sdk/tabs");
|
||||
const { getActiveTab, getTabContentWindow, closeTab } = require("sdk/tabs/utils")
|
||||
const { getMostRecentBrowserWindow } = require("sdk/window/utils");
|
||||
const { Loader } = require("sdk/test/loader");
|
||||
const { setTimeout } = require("sdk/timers");
|
||||
const { Cu } = require("chrome");
|
||||
|
||||
// General purpose utility functions
|
||||
|
||||
@ -86,55 +82,6 @@ function reload(window) {
|
||||
|
||||
// Selection's unit test utility function
|
||||
|
||||
/**
|
||||
* Returns the frame's window once the document is loaded
|
||||
*/
|
||||
function getFrameWindow(window) {
|
||||
let { promise, resolve } = defer();
|
||||
|
||||
let frame = window.frames[0];
|
||||
let { document } = frame;
|
||||
|
||||
frame.focus();
|
||||
|
||||
if (document.readyState === "complete")
|
||||
return frame;
|
||||
|
||||
document.addEventListener("readystatechange", function readystate() {
|
||||
if (this.readyState === "complete") {
|
||||
this.removeEventListener("readystatechange", readystate);
|
||||
frame.focus();
|
||||
resolve(frame);
|
||||
}
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the frame in order to destroy the selection object, and show it again
|
||||
* after ~500 msec, to give time to attach the code on `document-shown`
|
||||
* notification.
|
||||
* In the process, call `Cu.forgeGC` to ensure that the `document-shown` code
|
||||
* is not garbaged.
|
||||
*/
|
||||
function hideAndShowFrame(window) {
|
||||
let { promise, resolve } = defer();
|
||||
let iframe = window.document.querySelector("iframe");
|
||||
|
||||
iframe.style.display = "none";
|
||||
|
||||
Cu.forceGC();
|
||||
|
||||
setTimeout(function(){
|
||||
iframe.style.display = "";
|
||||
|
||||
setTimeout(resolve, 500, window);
|
||||
}, 0)
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the first div in the page, adding the range to the selection.
|
||||
*/
|
||||
@ -227,7 +174,7 @@ function dispatchOnSelectEvent(window) {
|
||||
|
||||
event.initUIEvent("select", true, true, window, 1);
|
||||
|
||||
textarea.dispatchEvent(event);
|
||||
textarea.dispatchEvent(event)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -783,42 +730,6 @@ exports["test Textarea OnSelect Listener on document reload"] = function(assert,
|
||||
then(loader.unload);
|
||||
};
|
||||
|
||||
exports["test Selection Listener on frame"] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
let selection = loader.require("sdk/selection");
|
||||
|
||||
selection.once("select", function() {
|
||||
assert.equal(selection.text, "fo");
|
||||
done();
|
||||
});
|
||||
|
||||
open(FRAME_URL).
|
||||
then(hideAndShowFrame).
|
||||
then(getFrameWindow).
|
||||
then(selectContentFirstDiv).
|
||||
then(dispatchSelectionEvent).
|
||||
then(close).
|
||||
then(loader.unload)
|
||||
};
|
||||
|
||||
exports["test Textarea onSelect Listener on frame"] = function(assert, done) {
|
||||
let loader = Loader(module);
|
||||
let selection = loader.require("sdk/selection");
|
||||
|
||||
selection.once("select", function() {
|
||||
assert.equal(selection.text, "noodles");
|
||||
done();
|
||||
});
|
||||
|
||||
open(FRAME_URL).
|
||||
then(hideAndShowFrame).
|
||||
then(getFrameWindow).
|
||||
then(selectTextarea).
|
||||
then(dispatchOnSelectEvent).
|
||||
then(close).
|
||||
then(loader.unload)
|
||||
};
|
||||
|
||||
// TODO: test Selection Listener on long-held connection (Bug 661884)
|
||||
//
|
||||
// I didn't find a way to do so with httpd, using `processAsync` I'm able to
|
||||
|
@ -199,7 +199,7 @@ exports.testPrefUnloadWildcardListener = function(test) {
|
||||
test.waitUntilDone();
|
||||
let testpref = "test-wildcard-unload-listener";
|
||||
let loader = Loader(module);
|
||||
let sp = loader.require("sdk/simple-prefs");
|
||||
let sp = loader.require("simple-prefs");
|
||||
let counter = 0;
|
||||
|
||||
let listener = function() {
|
||||
@ -210,7 +210,7 @@ exports.testPrefUnloadWildcardListener = function(test) {
|
||||
// this may not execute after unload, but definitely shouldn't fire listener
|
||||
sp.prefs[testpref] = false;
|
||||
// this should execute, but also definitely shouldn't fire listener
|
||||
require("sdk/simple-prefs").prefs[testpref] = false;
|
||||
require("simple-prefs").prefs[testpref] = false;
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
@ -115,8 +115,7 @@ exports["test behavior on close"] = function(assert, done) {
|
||||
url: "about:mozilla",
|
||||
onReady: function(tab) {
|
||||
assert.equal(tab.url, "about:mozilla", "Tab has the expected url");
|
||||
// if another test ends before closing a tab then index != 1 here
|
||||
assert.ok(tab.index >= 1, "Tab has the expected index, a value greater than 0");
|
||||
assert.equal(tab.index, 1, "Tab has the expected index");
|
||||
tab.close(function () {
|
||||
assert.equal(tab.url, undefined,
|
||||
"After being closed, tab attributes are undefined (url)");
|
||||
|
@ -3,6 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var url = require("sdk/url");
|
||||
var { packed } = require("sdk/self");
|
||||
|
||||
exports.testResolve = function(test) {
|
||||
test.assertEqual(url.URL("bar", "http://www.foo.com/").toString(),
|
||||
@ -85,6 +86,16 @@ exports.testToFilename = function(test) {
|
||||
"url.toFilename() on nonexistent resources should throw"
|
||||
);
|
||||
|
||||
if (!packed)
|
||||
test.assertMatches(url.toFilename(module.uri),
|
||||
/.*test-url\.js$/,
|
||||
"url.toFilename() on resource: URIs should work");
|
||||
else
|
||||
test.assertRaises(
|
||||
function() { url.toFilename(module.uri); },
|
||||
"cannot map to filename: "+module.uri,
|
||||
"url.toFilename() can fail for packed XPIs");
|
||||
|
||||
test.assertRaises(
|
||||
function() { url.toFilename("http://foo.com/"); },
|
||||
"cannot map to filename: http://foo.com/",
|
||||
|
@ -8,7 +8,7 @@ const { Cc, Ci } = require("chrome");
|
||||
const { Loader } = require('sdk/test/loader');
|
||||
const url = require("sdk/url");
|
||||
const timer = require("sdk/timers");
|
||||
const self = require("sdk/self");
|
||||
const self = require("self");
|
||||
const windowUtils = require("sdk/deprecated/window-utils");
|
||||
|
||||
exports.testConstructor = function(test) {
|
||||
@ -1029,7 +1029,7 @@ exports.testSVGWidget = function(test) {
|
||||
// use of capital SVG here is intended, that was failing..
|
||||
let SVG_URL = self.data.url("mofo_logo.SVG");
|
||||
|
||||
let widget = require("sdk/widget").Widget({
|
||||
let widget = require("widget").Widget({
|
||||
id: "mozilla-svg-logo",
|
||||
label: "moz foundation logo",
|
||||
contentURL: SVG_URL,
|
||||
|
@ -10,8 +10,7 @@ const wm = Cc['@mozilla.org/appshell/window-mediator;1'].
|
||||
getService(Ci.nsIWindowMediator);
|
||||
|
||||
const { browserWindows } = require("sdk/windows");
|
||||
const tabs = require("sdk/tabs");
|
||||
const { WindowTracker } = require("sdk/deprecated/window-utils");
|
||||
const tabs = require("tabs");
|
||||
|
||||
// TEST: open & close window
|
||||
exports.testOpenAndCloseWindow = function(test) {
|
||||
@ -204,24 +203,33 @@ exports.testActiveWindow = function(test) {
|
||||
count++;
|
||||
test.assertEqual(count, 3, "Correct number of windows returned by iterator");
|
||||
|
||||
test.assertEqual(windows.activeWindow.title, window3.title, "Correct active window - 3");
|
||||
|
||||
continueAfterFocus(rawWindow2);
|
||||
rawWindow2.focus();
|
||||
continueAfterFocus(rawWindow2);
|
||||
},
|
||||
function() {
|
||||
nextStep();
|
||||
},
|
||||
function() {
|
||||
test.assertEqual(windows.activeWindow.title, window2.title, "Correct active window - 2");
|
||||
/**
|
||||
* 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.
|
||||
|
||||
continueAfterFocus(rawWindow2);
|
||||
// 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");
|
||||
continueAfterFocus(rawWindow3);
|
||||
window3.activate();
|
||||
continueAfterFocus(rawWindow3);
|
||||
},
|
||||
function() {
|
||||
test.assertEqual(windows.activeWindow.title, window3.title, "Correct active window - 3");
|
||||
@ -229,39 +237,21 @@ exports.testActiveWindow = function(test) {
|
||||
}
|
||||
];
|
||||
|
||||
let newWindow = null;
|
||||
let tracker = new WindowTracker({
|
||||
onTrack: function(window) {
|
||||
newWindow = window;
|
||||
}
|
||||
});
|
||||
|
||||
windows.open({
|
||||
url: "data:text/html;charset=utf-8,<title>window 2</title>",
|
||||
onOpen: function(window) {
|
||||
window.tabs.activeTab.on('ready', function() {
|
||||
window2 = window;
|
||||
test.assert(newWindow, "A new window was opened");
|
||||
rawWindow2 = newWindow;
|
||||
newWindow = null;
|
||||
test.assertEqual(rawWindow2.content.document.title, "window 2", "Got correct raw window 2");
|
||||
test.assertEqual(rawWindow2.document.title, window2.title, "Saw correct title on window 2");
|
||||
window2 = window;
|
||||
rawWindow2 = wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
windows.open({
|
||||
url: "data:text/html;charset=utf-8,<title>window 3</title>",
|
||||
onOpen: function(window) {
|
||||
window.tabs.activeTab.on('ready', function onReady() {
|
||||
window3 = window;
|
||||
test.assert(newWindow, "A new window was opened");
|
||||
rawWindow3 = newWindow;
|
||||
tracker.unload();
|
||||
test.assertEqual(rawWindow3.content.document.title, "window 3", "Got correct raw window 3");
|
||||
test.assertEqual(rawWindow3.document.title, window3.title, "Saw correct title on window 3");
|
||||
continueAfterFocus(rawWindow3);
|
||||
rawWindow3.focus();
|
||||
});
|
||||
}
|
||||
});
|
||||
windows.open({
|
||||
url: "data:text/html;charset=utf-8,<title>window 3</title>",
|
||||
onOpen: function(window) {
|
||||
window.tabs.activeTab.on('ready', function onReady() {
|
||||
window3 = window;
|
||||
rawWindow3 = wm.getMostRecentWindow("navigator:browser");
|
||||
nextStep()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -288,11 +278,11 @@ exports.testActiveWindow = function(test) {
|
||||
|
||||
var focused = (focusedChildWindow == childTargetWindow);
|
||||
if (focused) {
|
||||
setTimeout(nextStep, 0);
|
||||
nextStep();
|
||||
} else {
|
||||
childTargetWindow.addEventListener("focus", function focusListener() {
|
||||
childTargetWindow.removeEventListener("focus", focusListener, true);
|
||||
setTimeout(nextStep, 0);
|
||||
nextStep();
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user