merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-11-06 14:55:48 +01:00
commit 59bcf9294a
242 changed files with 8378 additions and 10597 deletions

View File

@ -13,7 +13,6 @@ include $(topsrcdir)/config/rules.mk
TEST_FILES = \
source/app-extension \
source/bin \
source/data \
source/python-lib \
source/test \
source/package.json \

View File

@ -35,7 +35,7 @@ such, will only return favicon URLs for visited sites.
console.log(url); // http://mozorg.cdn.mozilla.net/media/img/favicon.ico
});
@param object {string, tab}
@param object {string|tab}
A value that represents the URL of the page to get the favicon URL from.
Can be a URL `String` or a [`Tab`](modules/sdk/tabs.html#Tab).

View File

@ -126,6 +126,10 @@ content (see the
});
});
Note that `tab.attach` is tab-centric: if the user navigates to a new
page in the same tab, then the worker and content scripts will be
reattached to the new page.
## Private Windows ##
If your add-on has not opted into private browsing, then you won't see any
@ -346,7 +350,10 @@ Returns thumbnail data URI of the page currently loaded in this tab.
<api name="attach">
@method
Create a page mod and attach it to the document in the tab.
Create a [Worker](modules/sdk/content/worker.html) and attach it to
every document loaded in the tab. Note that this is tab-centric: if
the user navigates to a new page in the same tab, then the worker and
content scripts will be reattached to the new page.
**Example**
@ -360,20 +367,22 @@ Returns thumbnail data URI of the page currently loaded in this tab.
});
@param options {object}
Options for the page mod, with the following keys:
Options for the worker, with the following keys:
@prop [contentScriptFile] {string,array}
The local file URLs of content scripts to load. Content scripts specified
by this option are loaded *before* those specified by the `contentScript`
option. Optional.
@prop [contentScript] {string,array}
The texts of content scripts to load. Content scripts specified by this
option are loaded *after* those specified by the `contentScriptFile` option.
A string or an array of strings of code to be evaluated in the context.
Content scripts specified by this option are loaded *after*
those specified by the `contentScriptFile` option.
Optional.
@prop [onMessage] {function}
A function called when the page mod receives a message from content scripts.
Listeners are passed a single argument, the message posted from the
content script. Optional.
A function called when the content worker receives a message from
content scripts. Listeners are passed a single argument, the
message posted from the content script.
Optional.
@returns {Worker}
The [Worker](modules/sdk/content/worker.html#Worker) object can be used to

View File

@ -1,214 +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/. -->
<!-- contributed by Erik Vold [evold@mozilla.com] -->
This module exports a two constructor functions `Button` which constructs a
new toolbar button, and `Sidebar` which constructs a sidebar (with a button).
Sidebars are displayed on the left side of your browser. Its content is specified as
local HTML, so the appearance and behaviour of the sidebar
is limited only by what you can do using HTML, CSS and JavaScript.
The screenshot below shows a sidebar whose content is built from tweets:
<!-- add screen shot here -->
Sidebars are useful for presenting temporary interfaces to users in a way that is
easier for users to ignore and dismiss than a modal dialog
and easier for users to keep around than a Panel, since sidebars are
displayed at the side of the browser until the user decides to close it.
A sidebar's content is loaded anew as soon as it is opened, and unloads
when the user closes the sidebar.
Your add-on can receive notifications when a sidebar is shown or hidden by
listening to its `show` and `hide` events.
Opening a sidebar in a window will close an already opened sidebar in that window.
## Sidebar Content ##
The sidebar's content is specified as HTML, which is loaded from the URL
supplied in the `url` option to the sidebar's constructor.
You can load remote HTML into the sidebar:
var sidebar = require("sdk/ui").Sidebar({
id: 'a-new-sidebar',
title: 'A New Sidebar',
icon: './icon.png',
url: './index.html'
});
sidebar.show();
This will load HTML that's been packaged with your add-on, and this is
most probably how you will create sidebars. To do this, save
the `index.html` HTML file in your add-on's `data` directory.
## Sidebar Positioning ##
By default the sidebars appears on the left side of the currently active browser window.
## Updating Sidebar Content ##
You can update the sidebar's content simply by setting the sidebar's `url`
property. Note this will change the sidebar's url for all windows.
## Scripting Sidebar Content ##
You can't directly access your sidebar's content from your main add-on code.
To access the sidebar's content, you need to add a `<script>` into the sidebar.
The sidebar's scripts will have access to a `addon` global, with you can
communicate with your main add-on code, like so:
`lib/main.js`:
let sidebar = Sidebar({
id: 'a-new-sidebar',
title: 'A New Sidebar',
icon: './icon.png',
url: './index.html',
onAttach: function (worker) {
worker.port.on('message', function() { // part 2
// do things...
worker.port.emit('message', 'I have information for you!'); // part 3
});
}
});
`data/index.html`
<pre class="brush: html">
&lt;html&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
...
&lt;script&gt;
addon.port.on('message', function(msg) { // part 4
// msg will == 'I have information for you!'
});
// starting communication here..
addon.port.emit('message'); // part 1
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<api name="Sidebar">
@class
The Sidebar object.
Once a sidebar object has been created it can be shown and hidden,
in the active window, using its
`show()` and `hide()` methods. Once a sidebar is no longer needed it can be
removed/destructed using `destroy()`.
<api name="Sidebar">
@constructor
Creates a sidebar.
@param options {object}
Options for the sidebar, with the following keys:
@prop id {string}
The `id` of the sidebar.
@prop title {string}
A title for the sidebar.
@prop icon {string, object}
The icon used for the sidebar's button.
@prop url {string, URL}
The URL of the content to load in the sidebar.
@prop [onAttach] {function}
Include this to listen to the sidebar's `attach` event.
@prop [onShow] {function}
Include this to listen to the sidebar's `show` event.
@prop [onHide] {function}
Include this to listen to the sidebar's `hide` event.
</api>
<api name="id">
@property {string}
The `id` for the sidebar.
</api>
<api name="title">
@property {string}
The `title` of the sidebar.
</api>
<api name="icon">
@property {string, object}
The global icon for the sidebar.
</api>
<api name="url">
@property {string}
The URL of content loaded into the sidebar.
</api>
<api name="destroy">
@method
Destroys the sidebar, once destroyed, the sidebar can no longer be used.
</api>
<api name="show">
@method
Displays the sidebar in the active window.
</api>
<api name="hide">
@method
Hides the sidebar in the active window.
</api>
<api name="on">
@method
Registers an event listener with the sidebar.
@param type {string}
The type of event to listen for.
@param listener {function}
The listener function that handles the event.
</api>
<api name="once">
@method
Registers an event listener with the sidebar.
The difference between `on` and `once` is that
`on` will continue listening until it is
removed, whereas `once` is removed automatically
upon the first event it catches.
@param type {string}
The type of event to listen for.
@param listener {function}
The listener function that handles the event.
</api>
<api name="removeListener">
@method
Unregisters/removes an event listener from the sidebar.
@param type {string}
The type of event for which `listener` was registered.
@param listener {function}
The listener function that was registered.
</api>
<api name="attach">
@event
This event is emitted when the sidebar's window
is created and the `addon` global was added.
</api>
<api name="show">
@event
This event is emitted when the sidebar is shown.
</api>
<api name="hide">
@event
This event is emitted when the sidebar is hidden.
</api>
</api>

View File

@ -0,0 +1,378 @@
<!-- 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/. -->
The `sidebar` module enables you to create sidebars. A sidebar is a a strip
of user interface real estate for your add-on that's attached to the
left-hand side of the browser window. A sidebar is a bit like a widget,
in that it's a persistent user interface element belonging to your add-on
that's attached to the browser window. However, it's much bigger than a
widget and is suitable for more presenting more complex interfaces.
## Creating, showing, and hiding sidebars
You construct a `Sidebar` object using the [`Sidebar()`](modules/sdk/ui/sidebar.html#Sidebar(options)) constructor.
Once you've done that, you can show the sidebar in the currently active window
by calling the Sidebar's [`show()`](modules/sdk/ui/sidebar.html#show()) method. If a new window is opened from a
window that has a sidebar visible, the new window gets a sidebar, too.
You can hide the sidebar in the currently active window by calling its
[`hide()`](modules/sdk/ui/sidebar.html#hide()) method.
Alternatively, the View->Sidebar submenu in Firefox will contain a new item
which the user can use to show or hide the sidebar:
<img class="image-center" src="static-files/media/screenshots/sidebar-menu.png" alt="Opening sidebar from a menu">
The sidebar generates a [`show`](modules/sdk/ui/sidebar.html#show) event when it is shown and a [`hide`](modules/sdk/ui/sidebar.html#hide) event when
it is hidden.
Once you've finished using the sidebar you can destroy it by calling its
[`dispose()`](file:///Users/Work/mozilla/jetpack-sdk/doc/modules/sdk/ui/sidebar.html#dispose()) method.
To show what a sidebar looks like, here's a sidebar that displays the results
of running the [W3C Validator](http://validator.w3.org/) on the current page:
<img class="image-center" src="static-files/media/screenshots/sidebar.png" alt="Simple sidebar example">
## Specifying sidebar content
The content of a sidebar is specified using HTML, which is loaded from the URL
supplied in the `url` option to the sidebar's constructor. Unlike modules
such as [`panel`](modules/sdk/panel.html), the content must be local,
typically loaded from the add-on's `data` directory via a URL constructed
using [`self.data.url()`](modules/sdk/self.html#data):
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: require("sdk/self").data.url("sidebar.html")
});
You can include JavaScript and CSS from the HTML as you would with any web
page, for example using `<script>` and `<link>` tags containing a path
relative to the HTML file itself.
<pre class="brush: html">
&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
&lt;head&gt;
&lt;link href="stuff.css" type="text/css" rel="stylesheet"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type="text/javascript" src="stuff.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
You can update the sidebar's content by setting the sidebar's `url`
property. This will change the sidebar's content across all windows.
## Communicating with sidebar scripts ##
You can't directly access your sidebar's content from your main add-on code,
but you can send messages between your main add-on code and scripts loaded
into your sidebar.
On the sidebar end of the conversation, sidebar scripts get a global
variable `addon` that contains a `port` for sending and receiving
messages.
On the add-on side, you must listen for the sidebar's `attach` event,
which is triggered whenever the DOM for a new sidebar instance is loaded
and its scripts are attached. This message passes a `worker` object into
the listener function, and you can use that worker to communicate with the
script loaded into the new sidebar instance.
Here's a simple but complete add-on that shows how to set up communication
between main.js and a script in a sidebar:
The HTML file includes just a script, "sidebar.js":
<pre class="brush: html">
&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
&lt;body&gt;
Content for my sidebar
&lt;script type="text/javascript" src="sidebar.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
The "sidebar.js" file sends a `ready` message to main.js using `port.emit()`,
and adds a listener to the `init` message that logs the message payload.
addon.port.emit("ready");
addon.port.on("init", sayStuff);
function sayStuff(message) {
console.log("got the message '" + message + "'" );
}
The "main.js" file creates a sidebar object and adds a listener to its
`attach` event. The listener listens for the `ready` message from the
sidebar script, and responds with an `init` message:
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: require("sdk/self").data.url("sidebar.html"),
onAttach: function (worker) {
worker.port.on("ready", function() {
worker.port.emit("init", "message from main.js");
});
}
});
Try running the add-on, and showing the sidebar using the
"View->Sidebar->My sidebar" menu item. You should see console output like:
<pre>
example-add-on: got the message 'message from main.js'
</pre>
You *can't* send the sidebar script
messages in the `attach` event listener, because the script may not be
initialized yet. It's safer, as in this example, to have the script
message "main.js" as soon as it is loaded, and have "main.js" listen
for that message before responding.
<api name="Sidebar">
@class
The Sidebar object. Once a sidebar has been created it can be shown and hidden
in the active window using its
[`show()`](modules/sdk/ui/sidebar.html#show()) and
[`hide()`](modules/sdk/ui/sidebar.html#hide()) methods.
Once a sidebar is no longer needed it can be
destroyed using [`dispose()`](modules/sdk/ui/sidebar.html#dispose()).
<api name="Sidebar">
@constructor
Creates a sidebar.
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: require("sdk/self").data.url("sidebar.html"),
onAttach: function (worker) {
console.log("attaching");
},
onShow: function () {
console.log("showing");
},
onHide: function () {
console.log("hiding");
},
onDetach: function () {
console.log("detaching");
}
});
@param options {object}
Options for the sidebar, with the following keys:
@prop id {string}
The `id` of the sidebar. This used to identify this sidebar in its chrome window. It must be unique.
@prop title {string}
A title for the sidebar. This will be used for the label for your sidebar
in the "Sidebar" submenu in Firefox, and will be shown at the top of your
sidebar when it is open.
@prop url {string}
The URL of the content to load in the sidebar. This must be a local URL (typically, loaded from the "data" folder using `self.data.url()`).
@prop [onAttach] {function}
Listener for the sidebar's `attach` event.
@prop [onDetach] {function}
Listener for the sidebar's `detach` event.
@prop [onShow] {function}
Listener for the sidebar's `show` event.
@prop [onHide] {function}
Listener for the sidebar's `hide` event.
</api>
<api name="id">
@property {string}
The id of the sidebar. This used to identify this sidebar in its chrome window. It must be unique.
</api>
<api name="title">
@property {string}
The title of the sidebar. This will be used for the label for your sidebar
in the "Sidebar" submenu in Firefox, and will be shown at the top of your
sidebar when it is open.
</api>
<api name="url">
@property {string}
The URL of the content to load in the sidebar. This must be a local URL (typically, loaded from the "data" folder using `self.data.url()`).
</api>
<api name="dispose">
@method
Destroys the sidebar. Once destroyed, the sidebar can no longer be used.
</api>
<api name="show">
@method
Displays the sidebar in the active window.
</api>
<api name="hide">
@method
Hides the sidebar in the active window.
</api>
<api name="on">
@method
Registers an event listener with the sidebar.
@param type {string}
The type of event to listen for.
@param listener {function}
The listener function that handles the event.
</api>
<api name="once">
@method
Registers an event listener with the sidebar.
The difference between `on` and `once` is that
`on` will continue listening until it is
removed, whereas `once` is removed automatically
upon the first event it catches.
@param type {string}
The type of event to listen for.
@param listener {function}
The listener function that handles the event.
</api>
<api name="removeListener">
@method
Unregisters/removes an event listener from the sidebar.
@param type {string}
The type of event for which `listener` was registered.
@param listener {function}
The listener function that was registered.
</api>
<api name="attach">
@event
This event is emitted when a worker is attached to a sidebar, as a result of any of the following:
* calling the sidebar's [`show()`](modules/sdk/ui/sidebar.html#show()) method,
when the sidebar is not shown in the currently active window
* changing the sidebar's [`url`](modules/sdk/ui/sidebar.html#url) property
* the user switching the sidebar on using the "Sidebar" submenu in Firefox,
when the sidebar is not shown in the currently active window
* the user opening a new window from a window that has the sidebar showing
This is the event you should listen to if you need to communicate with the
scripts loaded into the sidebar. It is passed a [`worker`](modules/sdk/content/worker.html)
as an argument, which defines `port.emit()` and `port.on()` methods that you can use
to send messages to, and receive messages from, scripts loaded into the sidebar.
This code listens to `attach` and in the listener, starts listening to a message called "ready"
from the script. When the listener receives the "ready" message it sends an "init" message to
the script:
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My Sidebar',
url: require("sdk/self").data.url("sidebar.html"),
onAttach: function (worker) {
// listen for a "ready" message from the script
worker.port.on("ready", function() {
// send an "init" message to the script
worker.port.emit("init", "message from main.js");
});
}
});
Here's the corresponding script, that sends "ready" as soon as it runs, and listens for
the "init" message from main.js:
addon.port.emit("ready");
addon.port.on("init", sayStuff);
function sayStuff(message) {
console.log("got the message '" + message + "'" );
}
You should not try to send messages to the script in your `attach` handler, because it's not
guaranteed that the script is listening to them yet. It's safer to start by listening for a
message from the script, as in this example.
</api>
<api name="detach">
@event
This event is emitted when a worker is detached from a sidebar, as a result of either of the following:
* calling the sidebar's [`hide()`](modules/sdk/ui/sidebar.html#hide()) method,
when the sidebar is being shown in the currently active window
* the user switching the sidebar off using the "Sidebar" submenu in Firefox,
when the sidebar is being shown in the currently active window
The `detach` listener receives a [`worker`](modules/sdk/content/worker.html) object as a parameter.
This object is the same as the worker passed into the corresponding `attach` event. After
`detach`, this worker can no longer be used to communicate with the scripts in that sidebar
instance, because it has been unloaded.
If you listen to `attach`, and in the listener take a reference to the worker object that's
passed into it, so you can send it messages later on, then you should probably listen to `detach`,
and in its handler, remove your reference to the worker.
Here's an add-on that adds each worker to an array in the `attach` handler, and makes sure
that its references are cleaned up by listening to `detach` and removing workers as they are
detached:
var workerArray = [];
function attachWorker(worker) {
workerArray.push(worker);
}
function detachWorker(worker) {
var index = workerArray.indexOf(worker);
if(index != -1) {
workerArray.splice(index, 1);
}
}
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My Sidebar',
url: require("sdk/self").data.url("sidebar.html"),
onAttach: attachWorker,
onDetach: detachWorker
});
</api>
<api name="show">
@event
This event is emitted when the sidebar is shown, as a result of any of the following:
* calling the sidebar's [`show()`](modules/sdk/ui/sidebar.html#show()) method,
when the sidebar is not shown in the currently active window
* changing the sidebar's [`url`](modules/sdk/ui/sidebar.html#url) property
* the user switching the sidebar on using the "Sidebar" submenu in Firefox,
when the sidebar is not shown in the currently active window
* the user opening a new window from a window that has the sidebar showing
</api>
<api name="hide">
@event
This event is emitted when the sidebar is hidden, as a result of either of the following:
* calling the sidebar's [`hide()`](modules/sdk/ui/sidebar.html#hide()) method,
when the sidebar is being shown in the currently active window
* the user switching the sidebar off using the "Sidebar" submenu in Firefox,
when the sidebar is being shown in the currently active window
</api>
</api>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -3,7 +3,7 @@
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"fullName": "library-detector-sdk",
"title": "library-detector-sdk",
"id": "jid1-R4rSVNkBANnvGQ",
"description": "a basic add-on"
}

View File

@ -15,7 +15,8 @@ const unload = require('../system/unload');
const { getDocShell } = require("../frame/utils");
const { ignoreWindow } = require('../private-browsing/utils');
const assetsURI = require('../self').data.url();
// Everything coming from add-on's xpi considered an asset.
const assetsURI = require('../self').data.url().replace(/data\/$/, "");
/**
* This trait is layered on top of `Worker` and in contrast to symbiont

View File

@ -1,37 +1,79 @@
/* 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";
'use strict';
module.metadata = {
"stability": "experimental"
'stability': 'experimental'
};
/*
* Encodings supported by TextEncoder/Decoder:
* utf-8, utf-16le, utf-16be
* http://encoding.spec.whatwg.org/#interface-textencoder
*
* Node however supports the following encodings:
* ascii, utf-8, utf-16le, usc2, base64, hex
*/
const { Cu } = require("chrome");
const { TextEncoder, TextDecoder } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
const { Cu } = require('chrome');
const { isNumber } = require('sdk/lang/type');
const { TextEncoder, TextDecoder } = Cu.import('resource://gre/modules/commonjs/toolkit/loader.js', {});
exports.TextEncoder = TextEncoder;
exports.TextDecoder = TextDecoder;
/**
* Use WeakMaps to work around Bug 929146, which prevents us from adding
* getters or values to typed arrays
* https://bugzilla.mozilla.org/show_bug.cgi?id=929146
*/
const parents = new WeakMap();
const views = new WeakMap();
function Buffer(subject, encoding) {
var type = typeof(subject);
switch (type) {
case "number":
// Create typed array of the given size if number.
return Uint8Array(subject > 0 ? Math.floor(subject) : 0);
case "string":
// If string encode it and use buffer for the returned Uint8Array
// to create a local patched version that acts like node buffer.
encoding = encoding || "utf8";
return Uint8Array(TextEncoder(encoding).encode(subject).buffer);
case "object":
// If array or alike just make a copy with a local patched prototype.
function Buffer(subject, encoding /*, bufferLength */) {
// Allow invocation without `new` constructor
if (!(this instanceof Buffer))
return new Buffer(subject, encoding, arguments[2]);
var type = typeof(subject);
switch (type) {
case 'number':
// Create typed array of the given size if number.
try {
let buffer = Uint8Array(subject > 0 ? Math.floor(subject) : 0);
return buffer;
} catch (e) {
if (/size and count too large/.test(e.message) ||
/invalid arguments/.test(e.message))
throw new RangeError('Could not instantiate buffer: size of buffer may be too large');
else
throw new Error('Could not instantiate buffer');
}
break;
case 'string':
// If string encode it and use buffer for the returned Uint8Array
// to create a local patched version that acts like node buffer.
encoding = encoding || 'utf8';
return Uint8Array(TextEncoder(encoding).encode(subject).buffer);
case 'object':
// This form of the constructor uses the form of
// Uint8Array(buffer, offset, length);
// So we can instantiate a typed array within the constructor
// to inherit the appropriate properties, where both the
// `subject` and newly instantiated buffer share the same underlying
// data structure.
if (arguments.length === 3)
return Uint8Array(subject, encoding, arguments[2]);
// If array or alike just make a copy with a local patched prototype.
else
return Uint8Array(subject);
default:
throw new TypeError("must start with number, buffer, array or string");
}
default:
throw new TypeError('must start with number, buffer, array or string');
}
}
exports.Buffer = Buffer;
@ -39,12 +81,20 @@ exports.Buffer = Buffer;
Buffer.isBuffer = value => value instanceof Buffer
// Returns true if the encoding is a valid encoding argument & false otherwise
Buffer.isEncoding = encoding => !!ENCODINGS[String(encoding).toLowerCase()]
Buffer.isEncoding = function (encoding) {
if (!encoding) return false;
try {
TextDecoder(encoding);
} catch(e) {
return false;
}
return true;
}
// Gives the actual byte length of a string. encoding defaults to 'utf8'.
// This is not the same as String.prototype.length since that returns the
// number of characters in a string.
Buffer.byteLength = (value, encoding = "utf8") =>
Buffer.byteLength = (value, encoding = 'utf8') =>
TextEncoder(encoding).encode(value).byteLength
// Direct copy of the nodejs's buffer implementation:
@ -85,78 +135,167 @@ Buffer.concat = function(list, length) {
// Node buffer is very much like Uint8Array although it has bunch of methods
// that typically can be used in combination with `DataView` while preserving
// access by index. Since in SDK echo module has it's own set of bult-ins it
// access by index. Since in SDK each module has it's own set of bult-ins it
// ok to patch ours to make it nodejs Buffer compatible.
Buffer.prototype = Uint8Array.prototype;
Object.defineProperties(Buffer.prototype, {
parent: {
get: function() { return parents.get(this, undefined); }
},
view: {
get: function() this._view || (this._view = DataView(this.buffer))
get: function () {
let view = views.get(this, undefined);
if (view) return view;
view = DataView(this.buffer);
views.set(this, view);
return view;
}
},
toString: {
value: function(encoding, start, end) {
encoding = !!encoding ? (encoding + '').toLowerCase() : "utf8";
encoding = !!encoding ? (encoding + '').toLowerCase() : 'utf8';
start = Math.max(0, ~~start);
end = Math.min(this.length, end === void(0) ? this.length : ~~end);
return TextDecoder(encoding).decode(this.subarray(start, end));
}
},
toJSON: {
value: function() ({ type: "Buffer", data: Array.slice(this, 0) })
value: function() {
return { type: 'Buffer', data: Array.slice(this, 0) };
}
},
get: {
value: function(offset) this[offset]
value: function(offset) {
return this[offset];
}
},
set: {
value: function(offset, value) this[offset] = value
value: function(offset, value) { this[offset] = value; }
},
copy: {
value: function(target, offset, start, end)
Uint8Array.set(target, this.subarray(start, end), offset)
value: function(target, offset, start, end) {
let length = this.length;
let targetLength = target.length;
offset = isNumber(offset) ? offset : 0;
start = isNumber(start) ? start : 0;
if (start < 0)
throw new RangeError('sourceStart is outside of valid range');
if (end < 0)
throw new RangeError('sourceEnd is outside of valid range');
// If sourceStart > sourceEnd, or targetStart > targetLength,
// zero bytes copied
if (start > end ||
offset > targetLength
)
return 0;
// If `end` is not defined, or if it is defined
// but would overflow `target`, redefine `end`
// so we can copy as much as we can
if (end - start > targetLength - offset ||
end == null) {
let remainingTarget = targetLength - offset;
let remainingSource = length - start;
if (remainingSource <= remainingTarget)
end = length;
else
end = start + remainingTarget;
}
Uint8Array.set(target, this.subarray(start, end), offset);
return end - start;
}
},
slice: {
value: Buffer.prototype.subarray
value: function(start, end) {
let length = this.length;
start = ~~start;
end = end != null ? end : length;
if (start < 0) {
start += length;
if (start < 0) start = 0;
} else if (start > length)
start = length;
if (end < 0) {
end += length;
if (end < 0) end = 0;
} else if (end > length)
end = length;
if (end < start)
end = start;
// This instantiation uses the Uint8Array(buffer, offset, length) version
// of construction to share the same underling data structure
let buffer = new Buffer(this.buffer, start, end - start);
// If buffer has a value, assign its parent value to the
// buffer it shares its underlying structure with. If a slice of
// a slice, then use the root structure
if (buffer.length > 0)
parents.set(buffer, this.parent || this);
return buffer;
}
},
write: {
value: function(string, offset, length, encoding = "utf8") {
if (typeof(offset) === "string")
value: function(string, offset, length, encoding = 'utf8') {
// write(string, encoding);
if (typeof(offset) === 'string' && Number.isNaN(parseInt(offset))) {
([offset, length, encoding]) = [0, null, offset];
else if (typeof(length) === "string")
}
// write(string, offset, encoding);
else if (typeof(length) === 'string')
([length, encoding]) = [null, length];
if (offset < 0 || offset > this.length)
throw new RangeError('offset is outside of valid range');
offset = ~~offset;
length = length || this.length - offset;
// Clamp length if it would overflow buffer, or if its
// undefined
if (length == null || length + offset > this.length)
length = this.length - offset;
let buffer = TextEncoder(encoding).encode(string);
let result = Math.min(buffer.length, length);
if (buffer.length !== length)
buffer = buffer.subarray(0, length);
Uint8Array.set(this, buffer, offset);
return result;
}
},
fill: {
value: function fill(value, start, end) {
let length = this.length;
value = value || 0;
start = start || 0;
end = end || this.length;
end = end || length;
if (typeof(value) === "string")
if (typeof(value) === 'string')
value = value.charCodeAt(0);
if (typeof(value) !== "number" || isNaN(value))
throw TypeError("value is not a number");
if (typeof(value) !== 'number' || isNaN(value))
throw TypeError('value is not a number');
if (end < start)
throw new RangeError("end < start");
throw new RangeError('end < start');
// Fill 0 bytes; we're done
if (end === start)
return 0;
if (this.length == 0)
if (length == 0)
return 0;
if (start < 0 || start >= this.length)
throw RangeError("start out of bounds");
if (start < 0 || start >= length)
throw RangeError('start out of bounds');
if (end < 0 || end > this.length)
throw RangeError("end out of bounds");
if (end < 0 || end > length)
throw RangeError('end out of bounds');
let index = start;
while (index < end) this[index++] = value;
@ -166,94 +305,42 @@ Object.defineProperties(Buffer.prototype, {
// Define nodejs Buffer's getter and setter functions that just proxy
// to internal DataView's equivalent methods.
[["readUInt16LE", "getUint16", true],
["readUInt16BE", "getUint16", false],
["readInt16LE", "getInt16", true],
["readInt16BE", "getInt16", false],
["readUInt32LE", "getInt32", true],
["readUInt32BE", "getInt32", false],
["readInt32LE", "getInt32", true],
["readInt32BE", "getInt32", false],
["readFloatLE", "getFloat32", true],
["readFloatBE", "getFloat32", false],
["readDoubleLE", "getFloat64", true],
["readDoubleBE", "getFloat64", false],
["readUInt8", "getUint8"],
["readInt8", "getInt8"]].forEach(([alias, name, littleEndian]) => {
// TODO do we need to check architecture to see if it's default big/little endian?
[['readUInt16LE', 'getUint16', true],
['readUInt16BE', 'getUint16', false],
['readInt16LE', 'getInt16', true],
['readInt16BE', 'getInt16', false],
['readUInt32LE', 'getUint32', true],
['readUInt32BE', 'getUint32', false],
['readInt32LE', 'getInt32', true],
['readInt32BE', 'getInt32', false],
['readFloatLE', 'getFloat32', true],
['readFloatBE', 'getFloat32', false],
['readDoubleLE', 'getFloat64', true],
['readDoubleBE', 'getFloat64', false],
['readUInt8', 'getUint8'],
['readInt8', 'getInt8']].forEach(([alias, name, littleEndian]) => {
Object.defineProperty(Buffer.prototype, alias, {
value: function(offset) this.view[name](offset, littleEndian)
});
});
[["writeUInt16LE", "setUint16", true],
["writeUInt16BE", "setUint16", false],
["writeInt16LE", "setInt16", true],
["writeInt16BE", "setInt16", false],
["writeUInt32LE", "setUint32", true],
["writeUInt32BE", "setUint32", false],
["writeInt32LE", "setInt32", true],
["writeInt32BE", "setInt32", false],
["writeFloatLE", "setFloat32", true],
["writeFloatBE", "setFloat32", false],
["writeDoubleLE", "setFloat64", true],
["writeDoubleBE", "setFloat64", false],
["writeUInt8", "setUint8"],
["writeInt8", "setInt8"]].forEach(([alias, name, littleEndian]) => {
[['writeUInt16LE', 'setUint16', true],
['writeUInt16BE', 'setUint16', false],
['writeInt16LE', 'setInt16', true],
['writeInt16BE', 'setInt16', false],
['writeUInt32LE', 'setUint32', true],
['writeUInt32BE', 'setUint32', false],
['writeInt32LE', 'setInt32', true],
['writeInt32BE', 'setInt32', false],
['writeFloatLE', 'setFloat32', true],
['writeFloatBE', 'setFloat32', false],
['writeDoubleLE', 'setFloat64', true],
['writeDoubleBE', 'setFloat64', false],
['writeUInt8', 'setUint8'],
['writeInt8', 'setInt8']].forEach(([alias, name, littleEndian]) => {
Object.defineProperty(Buffer.prototype, alias, {
value: function(value, offset) this.view[name](offset, value, littleEndian)
});
});
// List of supported encodings taken from:
// http://mxr.mozilla.org/mozilla-central/source/dom/encoding/labelsencodings.properties
const ENCODINGS = { "unicode-1-1-utf-8": 1, "utf-8": 1, "utf8": 1,
"866": 1, "cp866": 1, "csibm866": 1, "ibm866": 1, "csisolatin2": 1,
"iso-8859-2": 1, "iso-ir-101": 1, "iso8859-2": 1, "iso88592": 1,
"iso_8859-2": 1, "iso_8859-2:1987": 1, "l2": 1, "latin2": 1, "csisolatin3": 1,
"iso-8859-3": 1, "iso-ir-109": 1, "iso8859-3": 1, "iso88593": 1,
"iso_8859-3": 1, "iso_8859-3:1988": 1, "l3": 1, "latin3": 1, "csisolatin4": 1,
"iso-8859-4": 1, "iso-ir-110": 1, "iso8859-4": 1, "iso88594": 1,
"iso_8859-4": 1, "iso_8859-4:1988": 1, "l4": 1, "latin4": 1,
"csisolatincyrillic": 1, "cyrillic": 1, "iso-8859-5": 1, "iso-ir-144": 1,
"iso8859-5": 1, "iso88595": 1, "iso_8859-5": 1, "iso_8859-5:1988": 1,
"arabic": 1, "asmo-708": 1, "csiso88596e": 1, "csiso88596i": 1,
"csisolatinarabic": 1, "ecma-114": 1, "iso-8859-6": 1, "iso-8859-6-e": 1,
"iso-8859-6-i": 1, "iso-ir-127": 1, "iso8859-6": 1, "iso88596": 1,
"iso_8859-6": 1, "iso_8859-6:1987": 1, "csisolatingreek": 1, "ecma-118": 1,
"elot_928": 1, "greek": 1, "greek8": 1, "iso-8859-7": 1, "iso-ir-126": 1,
"iso8859-7": 1, "iso88597": 1, "iso_8859-7": 1, "iso_8859-7:1987": 1,
"sun_eu_greek": 1, "csiso88598e": 1, "csisolatinhebrew": 1, "hebrew": 1,
"iso-8859-8": 1, "iso-8859-8-e": 1, "iso-ir-138": 1, "iso8859-8": 1,
"iso88598": 1, "iso_8859-8": 1, "iso_8859-8:1988": 1, "visual": 1,
"csiso88598i": 1, "iso-8859-8-i": 1, "logical": 1, "csisolatin6": 1,
"iso-8859-10": 1, "iso-ir-157": 1, "iso8859-10": 1, "iso885910": 1,
"l6": 1, "latin6": 1, "iso-8859-13": 1, "iso8859-13": 1, "iso885913": 1,
"iso-8859-14": 1, "iso8859-14": 1, "iso885914": 1, "csisolatin9": 1,
"iso-8859-15": 1, "iso8859-15": 1, "iso885915": 1, "iso_8859-15": 1,
"l9": 1, "iso-8859-16": 1, "cskoi8r": 1, "koi": 1, "koi8": 1, "koi8-r": 1,
"koi8_r": 1, "koi8-u": 1, "csmacintosh": 1, "mac": 1, "macintosh": 1,
"x-mac-roman": 1, "dos-874": 1, "iso-8859-11": 1, "iso8859-11": 1,
"iso885911": 1, "tis-620": 1, "windows-874": 1, "cp1250": 1,
"windows-1250": 1, "x-cp1250": 1, "cp1251": 1, "windows-1251": 1,
"x-cp1251": 1, "ansi_x3.4-1968": 1, "ascii": 1, "cp1252": 1, "cp819": 1,
"csisolatin1": 1, "ibm819": 1, "iso-8859-1": 1, "iso-ir-100": 1,
"iso8859-1": 1, "iso88591": 1, "iso_8859-1": 1, "iso_8859-1:1987": 1,
"l1": 1, "latin1": 1, "us-ascii": 1, "windows-1252": 1, "x-cp1252": 1,
"cp1253": 1, "windows-1253": 1, "x-cp1253": 1, "cp1254": 1, "csisolatin5": 1,
"iso-8859-9": 1, "iso-ir-148": 1, "iso8859-9": 1, "iso88599": 1,
"iso_8859-9": 1, "iso_8859-9:1989": 1, "l5": 1, "latin5": 1,
"windows-1254": 1, "x-cp1254": 1, "cp1255": 1, "windows-1255": 1,
"x-cp1255": 1, "cp1256": 1, "windows-1256": 1, "x-cp1256": 1, "cp1257": 1,
"windows-1257": 1, "x-cp1257": 1, "cp1258": 1, "windows-1258": 1,
"x-cp1258": 1, "x-mac-cyrillic": 1, "x-mac-ukrainian": 1, "chinese": 1,
"csgb2312": 1, "csiso58gb231280": 1, "gb2312": 1, "gb_2312": 1,
"gb_2312-80": 1, "gbk": 1, "iso-ir-58": 1, "x-gbk": 1, "gb18030": 1,
"hz-gb-2312": 1, "big5": 1, "big5-hkscs": 1, "cn-big5": 1, "csbig5": 1,
"x-x-big5": 1, "cseucpkdfmtjapanese": 1, "euc-jp": 1, "x-euc-jp": 1,
"csiso2022jp": 1, "iso-2022-jp": 1, "csshiftjis": 1, "ms_kanji": 1,
"shift-jis": 1, "shift_jis": 1, "sjis": 1, "windows-31j": 1, "x-sjis": 1,
"cseuckr": 1, "csksc56011987": 1, "euc-kr": 1, "iso-ir-149": 1, "korean": 1,
"ks_c_5601-1987": 1, "ks_c_5601-1989": 1, "ksc5601": 1, "ksc_5601": 1,
"windows-949": 1, "csiso2022kr": 1, "iso-2022-kr": 1, "utf-16": 1,
"utf-16le": 1, "utf-16be": 1, "x-user-defined": 1 };

View File

@ -811,12 +811,7 @@ function readFile(path, encoding, callback) {
let readStream = new ReadStream(path);
readStream.on("data", function(data) {
if (!buffer) buffer = data;
else {
let bufferred = buffer
buffer = new Buffer(buffer.length + data.length);
bufferred.copy(buffer, 0);
data.copy(buffer, bufferred.length);
}
else buffer = Buffer.concat([buffer, data], 2);
});
readStream.on("error", function onError(error) {
callback(error);

View File

@ -139,7 +139,7 @@ const StreamListener = Class({
let stream = this.stream;
let buffer = new ArrayBuffer(count);
nsIBinaryInputStream(stream).readArrayBuffer(count, buffer);
emit(stream, "data", new Buffer(buffer, stream.encoding));
emit(stream, "data", new Buffer(buffer));
},
// Next two methods implement `nsIRequestObserver` interface and are invoked

View File

@ -33,8 +33,20 @@ const Subject = Class({
});
function emit(type, event) {
let subject = 'subject' in event ? Subject(event.subject) : null;
let data = 'data' in event ? event.data : null;
// From bug 910599
// We must test to see if 'subject' or 'data' is a defined property
// of the event object, but also allow primitives to be passed in,
// which the `in` operator breaks, yet `null` is an object, hence
// the long conditional
let subject = event && typeof event === 'object' && 'subject' in event ?
Subject(event.subject) :
null;
let data = event && typeof event === 'object' ?
// An object either returns its `data` property or null
('data' in event ? event.data : null) :
// All other types return themselves (and cast to strings/null
// via observer service)
event;
notifyObservers(subject, type, data);
}
exports.emit = emit;

View File

@ -17,6 +17,7 @@ const { off, emit, setListeners } = require('../event/core');
const { EventTarget } = require('../event/target');
const { URL } = require('../url');
const { add, remove, has, clear, iterator } = require('../lang/weak-set');
const { id: addonID } = require('../self');
const { WindowTracker } = require('../deprecated/window-utils');
const { isShowing } = require('./sidebar/utils');
const { isBrowser, getMostRecentBrowserWindow, windows, isWindowPrivate } = require('../window/utils');
@ -30,6 +31,8 @@ const { defer } = require('../core/promise');
const { models, views, viewsFor, modelFor } = require('./sidebar/namespace');
const { isLocalURL } = require('../url');
const { ensure } = require('../system/unload');
const { identify } = require('./id');
const { uuid } = require('../util/uuid');
const Worker = WorkerTrait.resolve({
_injectInDocument: '__injectInDocument'
@ -47,9 +50,16 @@ const Sidebar = Class({
implements: [ Disposable ],
extends: EventTarget,
setup: function(options) {
// inital validation for the model information
let model = sidebarContract(options);
// save the model information
models.set(this, model);
// generate an id if one was not provided
model.id = model.id || addonID + '-' + uuid();
// further validation for the title and url
validateTitleAndURLCombo({}, this.title, this.url);
const self = this;
@ -119,6 +129,7 @@ const Sidebar = Class({
emit(self, 'hide', {});
emit(self, 'detach', worker);
windowNS(window).worker = null;
}
windowNS(window).onWebPanelSidebarUnload = onWebPanelSidebarUnload;
panelBrowser.contentWindow.addEventListener('unload', onWebPanelSidebarUnload, true);
@ -126,6 +137,15 @@ const Sidebar = Class({
// check the associated menuitem
bar.setAttribute('checked', 'true');
function onWebPanelSidebarReady() {
panelBrowser.contentWindow.removeEventListener('DOMContentLoaded', onWebPanelSidebarReady, false);
windowNS(window).onWebPanelSidebarReady = null;
emit(self, 'ready', worker);
}
windowNS(window).onWebPanelSidebarReady = onWebPanelSidebarReady;
panelBrowser.contentWindow.addEventListener('DOMContentLoaded', onWebPanelSidebarReady, false);
function onWebPanelSidebarLoad() {
panelBrowser.contentWindow.removeEventListener('load', onWebPanelSidebarLoad, true);
windowNS(window).onWebPanelSidebarLoad = null;
@ -173,6 +193,11 @@ const Sidebar = Class({
windowNS(window).onWebPanelSidebarCreated = null;
}
if (windowNS(window).onWebPanelSidebarReady) {
panelBrowser && panelBrowser.contentWindow.removeEventListener('DOMContentLoaded', windowNS(window).onWebPanelSidebarReady, false);
windowNS(window).onWebPanelSidebarReady = null;
}
if (windowNS(window).onWebPanelSidebarLoad) {
panelBrowser && panelBrowser.contentWindow.removeEventListener('load', windowNS(window).onWebPanelSidebarLoad, true);
windowNS(window).onWebPanelSidebarLoad = null;
@ -180,7 +205,7 @@ const Sidebar = Class({
if (windowNS(window).onWebPanelSidebarUnload) {
panelBrowser && panelBrowser.contentWindow.removeEventListener('unload', windowNS(window).onWebPanelSidebarUnload, true);
windowNS(window).onWebPanelSidebarUnload = null;
windowNS(window).onWebPanelSidebarUnload();
}
}
});
@ -208,10 +233,13 @@ const Sidebar = Class({
// destroyed?
if (!modelFor(this))
return;
// validation
if (!isLocalURL(v))
throw Error('the url must be a valid local url');
validateTitleAndURLCombo(this, this.title, v);
// do update
updateURL(this, v);
modelFor(this).url = v;
@ -260,6 +288,10 @@ isShowing.define(Sidebar, isSidebarShowing.bind(null, null));
show.define(Sidebar, showSidebar.bind(null, null));
hide.define(Sidebar, hideSidebar.bind(null, null));
identify.define(Sidebar, function(sidebar) {
return sidebar.id;
});
function toggleSidebar(window, sidebar) {
// TODO: make sure this is not private
window = window || getMostRecentBrowserWindow();

View File

@ -9,7 +9,7 @@ const { isNil, isObject, isString } = require('../../lang/type');
exports.contract = contract({
id: {
is: [ 'string' ],
is: [ 'string', 'undefined' ],
ok: v => /^[a-z0-9-_]+$/i.test(v),
msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' +
'underscores are allowed).'
@ -22,6 +22,6 @@ exports.contract = contract({
is: [ 'string' ],
ok: v => isLocalURL(v),
map: function(v) v.toString(),
msg: 'The option "url" must be a valid URI.'
msg: 'The option "url" must be a valid local URI.'
}
});

View File

@ -72,7 +72,15 @@ function updateTitle(sidebar, title) {
exports.updateTitle = updateTitle;
function updateURL(sidebar, url) {
let eleID = makeID(sidebar.id);
for (let window of windows(null, { includePrivate: true })) {
// update the menuitem
let mi = window.document.getElementById(eleID);
if (mi) {
mi.setAttribute('sidebarurl', url)
}
// update sidebar, if showing
if (isSidebarShowing(window, sidebar)) {
showSidebar(window, sidebar, url);
@ -134,7 +142,10 @@ function showSidebar(window, sidebar, newURL) {
let { promise, resolve, reject } = defer();
let model = modelFor(sidebar);
if (!isPrivateBrowsingSupported && isWindowPrivate(window)) {
if (!newURL && isSidebarShowing(window, sidebar)) {
resolve({});
}
else if (!isPrivateBrowsingSupported && isWindowPrivate(window)) {
reject(Error('You cannot show a sidebar on private windows'));
}
else {

View File

@ -5,9 +5,9 @@
const { defer } = require('../core/promise');
const events = require('../system/events');
const { setImmediate } = require('../timers');
const { open: openWindow, onFocus, getToplevelWindow,
isInteractive } = require('./utils');
isInteractive, getOuterId } = require('./utils');
const { Ci } = require("chrome");
function open(uri, options) {
return promise(openWindow.apply(null, arguments), 'load');
@ -15,19 +15,14 @@ function open(uri, options) {
exports.open = open;
function close(window) {
// We shouldn't wait for unload, as it is dispatched
// before the window is actually closed. 'domwindowclosed' isn't great either,
// because it's fired midway through window teardown (see bug 874502
// comment 15). We could go with xul-window-destroyed, but _that_ doesn't
// provide us with a subject by which to disambiguate notifications. So we
// end up just doing the dumb thing and round-tripping through the event loop
// with setImmediate.
let deferred = defer();
let toplevelWindow = getToplevelWindow(window);
events.on("domwindowclosed", function onclose({subject}) {
if (subject == toplevelWindow) {
events.off("domwindowclosed", onclose);
setImmediate(function() deferred.resolve(window));
let outerId = getOuterId(toplevelWindow);
events.on("outer-window-destroyed", function onclose({subject}) {
let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (id == outerId) {
events.off("outer-window-destroyed", onclose);
deferred.resolve();
}
}, true);
window.close();

View File

@ -297,8 +297,7 @@ function windows(type, options) {
let window = winEnum.getNext().QueryInterface(Ci.nsIDOMWindow);
// Only add non-private windows when pb permission isn't set,
// unless an option forces the addition of them.
// XXXbz should this be checking window.closed?
if (options.includePrivate || !isWindowPrivate(window)) {
if (!window.closed && (options.includePrivate || !isWindowPrivate(window))) {
list.push(window);
}
}

View File

@ -38,6 +38,7 @@ const { loadSubScript } = Cc['@mozilla.org/moz/jssubscript-loader;1'].
getService(Ci.mozIJSSubScriptLoader);
const { notifyObservers } = Cc['@mozilla.org/observer-service;1'].
getService(Ci.nsIObserverService);
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
// Define some shortcuts.
const bind = Function.call.bind(Function.bind);
@ -157,6 +158,18 @@ var serializeStack = iced(function serializeStack(frames) {
})
exports.serializeStack = serializeStack
function readURI(uri) {
let stream = NetUtil.newChannel(uri, 'UTF-8', null).open();
let count = stream.available();
let data = NetUtil.readInputStreamToString(stream, count, {
charset: 'UTF-8'
});
stream.close();
return data;
}
// Function takes set of options and returns a JS sandbox. Function may be
// passed set of options:
// - `name`: A string value which identifies the sandbox in about:memory. Will
@ -313,7 +326,11 @@ exports.load = load;
// Utility function to check if id is relative.
function isRelative(id) { return id[0] === '.'; }
// Utility function to normalize module `uri`s so they have `.js` extension.
function normalize(uri) { return uri.substr(-3) === '.js' ? uri : uri + '.js'; }
function normalize(uri) {
return isJSURI(uri) ? uri :
isJSONURI(uri) ? uri :
uri + '.js';
}
// Utility function to join paths. In common case `base` is a
// `requirer.uri` but in some cases it may be `baseURI`. In order to
// avoid complexity we require `baseURI` with a trailing `/`.
@ -371,9 +388,31 @@ const Require = iced(function Require(loader, requirer) {
if (uri in modules) {
module = modules[uri];
}
// Otherwise load and cache it. We also freeze module to prevent it from
// further changes at runtime.
else {
else if (isJSONURI(uri)) {
let data;
// First attempt to load and parse json uri
// ex: `test.json`
// If that doesn't exist, check for `test.json.js`
// for node parity
try {
data = JSON.parse(readURI(uri));
module = modules[uri] = Module(requirement, uri);
module.exports = data;
freeze(module);
}
catch (err) {
// If error thrown from JSON parsing, throw that, do not
// attempt to find .json.js file
if (err && /JSON\.parse/.test(err.message))
throw err;
uri = uri + '.js';
}
}
// If not yet cached, load and cache it.
// We also freeze module to prevent it from further changes
// at runtime.
if (!(uri in modules)) {
module = modules[uri] = Module(requirement, uri);
freeze(load(loader, module));
}
@ -504,5 +543,8 @@ const Loader = iced(function Loader(options) {
});
exports.Loader = Loader;
let isJSONURI = uri => uri.substr(-5) === '.json';
let isJSURI = uri => uri.substr(-3) === '.js';
});

View File

@ -172,7 +172,7 @@ parser_groups = (
(("", "--strip-sdk",), dict(dest="bundle_sdk",
help=("Do not ship SDK modules in the xpi"),
action="store_false",
default=True,
default=False,
cmds=['run', 'test', 'testex', 'testpkgs',
'testall', 'xpi'])),
(("", "--force-use-bundled-sdk",), dict(dest="force_use_bundled_sdk",
@ -554,7 +554,7 @@ def initializer(env_root, args, out=sys.stdout, err=sys.stderr):
jid = create_jid()
print >>out, '* generated jID automatically:', jid
open(os.path.join(path,'package.json'),'w').write(PACKAGE_JSON % {'name':addon.lower(),
'fullName':addon,
'title':addon,
'id':jid })
print >>out, '* package.json written'
open(os.path.join(path,'test','test-main.js'),'w').write(TEST_MAIN_JS)
@ -568,7 +568,7 @@ def initializer(env_root, args, out=sys.stdout, err=sys.stderr):
print >>out, 'Do "cfx test" to test it and "cfx run" to try it. Have fun!'
else:
print >>out, '\nYour sample add-on is now ready in the \'' + args[1] + '\' directory.'
print >>out, 'Change to that directory, then do "cfx test" to test it, \nand "cfx run" to try it. Have fun!'
print >>out, 'Change to that directory, then do "cfx test" to test it, \nand "cfx run" to try it. Have fun!'
return {"result":0, "jid":jid}
def buildJID(target_cfg):
@ -597,7 +597,7 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
(options, args) = parse_args(**parser_kwargs)
config_args = get_config_args(options.config, env_root);
# reparse configs with arguments from local.json
if config_args:
parser_kwargs['arguments'] += config_args

View File

@ -606,9 +606,13 @@ class ManifestBuilder:
filename = os.sep.join(name.split("/"))
# normalize filename, make sure that we do not add .js if it already has
# it.
if not filename.endswith(".js"):
if not filename.endswith(".js") and not filename.endswith(".json"):
filename += ".js"
basename = filename[:-3]
if filename.endswith(".js"):
basename = filename[:-3]
if filename.endswith(".json"):
basename = filename[:-5]
pkg = self.pkg_cfg.packages[pkgname]
if isinstance(sections, basestring):

View File

@ -122,7 +122,7 @@ def gen_manifest(template_root_dir, target_cfg, jid,
manifest.set("em:version",
target_cfg.get('version', '1.0'))
manifest.set("em:name",
target_cfg.get('fullName', target_cfg['name']))
target_cfg.get('title', target_cfg.get('fullName', target_cfg['name'])))
manifest.set("em:description",
target_cfg.get("description", ""))
manifest.set("em:creator",

View File

@ -22,7 +22,7 @@ require("sdk/test").run(exports);
PACKAGE_JSON = '''\
{
"name": "%(name)s",
"fullName": "%(fullName)s",
"title": "%(title)s",
"id": "%(id)s",
"description": "a basic add-on",
"author": "",

View File

@ -3,7 +3,7 @@
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"fullName": "empty",
"title": "empty",
"id": "jid1-80fr8b6qeRlQSQ",
"unpack": false,
"description": "test unpack= support"

View File

@ -3,7 +3,7 @@
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"fullName": "empty",
"title": "empty",
"id": "jid1-80fr8b6qeRlQSQ",
"unpack": true,
"description": "test unpack= support"

View File

@ -3,7 +3,7 @@
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"fullName": "empty",
"title": "empty",
"id": "jid1-80fr8b6qeRlQSQ",
"description": "test unpack= support"
}

View File

@ -0,0 +1,9 @@
{
"name": "empty",
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"fullName": "a long fullName",
"id": "jid1-80123",
"description": "test addon name fallback to 'fullName' key"
}

View File

@ -0,0 +1,9 @@
{
"name": "a long none",
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"id": "jid1-80123",
"description": "test addon name falls back all the way to the 'name' key"
}

View File

@ -0,0 +1,9 @@
{
"name": "empty",
"license": "MPL 2.0",
"author": "",
"version": "0.1",
"title": "a long title",
"id": "jid1-80123",
"description": "test addon name comes from the 'title' key"
}

View File

@ -1,6 +1,6 @@
{
"id": "jid1-fZHqN9JfrDBa8A",
"fullName": "No Prefs Test",
"title": "No Prefs Test",
"author": "Erik Vold",
"loader": "lib/main.js"
}

View File

@ -1,6 +1,6 @@
{
"id": "jid1-fZHqN9JfrDBa8A",
"fullName": "Simple Prefs Test",
"title": "Simple Prefs Test",
"author": "Erik Vold",
"preferences": [{
"name": "test",

View File

@ -48,7 +48,7 @@ class TestInit(unittest.TestCase):
self.assertEqual(open(main_js,"r").read(),"")
self.assertEqual(open(package_json,"r").read() % {"id":"tmp_addon_id" },
PACKAGE_JSON % {"name":"tmp_addon_sample",
"fullName": "tmp_addon_SAMPLE",
"title": "tmp_addon_SAMPLE",
"id":init_run["jid"] })
self.assertEqual(open(test_main_js,"r").read(),TEST_MAIN_JS)

View File

@ -188,16 +188,13 @@ class Contents(unittest.TestCase):
self.failUnlessEqual(e.args[0], 0)
zf = zipfile.ZipFile("seven.xpi", "r")
names = zf.namelist()
# the first problem found in bug 664840 was that cuddlefish.js
# (the loader) was stripped out on windows, due to a /-vs-\ bug
self.assertIn("resources/addon-sdk/lib/sdk/loader/cuddlefish.js", names)
# the second problem found in bug 664840 was that an addon
# problem found in bug 664840 was that an addon
# without an explicit tests/ directory would copy all files from
# the package into a bogus JID-PKGNAME-tests/ directory, so check
# for that
testfiles = [fn for fn in names if "seven/tests" in fn]
self.failUnlessEqual([], testfiles)
# the third problem was that data files were being stripped from
# another problem was that data files were being stripped from
# the XPI. Note that data/ is only supposed to be included if a
# module that actually gets used does a require("self") .
self.assertIn("resources/seven/data/text.data",

View File

@ -41,5 +41,14 @@ class RDFTests(unittest.TestCase):
self.failUnlessEqual(m.get("em:unpack"), "true")
self.failUnlessIn("<em:unpack>true</em:unpack>", str(m), n)
def testTitle(self):
basedir = os.path.join(test_dir, 'bug-906359-files')
for n in ['title', 'fullName', 'none']:
cfg = packaging.get_config_in_dir(os.path.join(basedir, n))
m = rdf.gen_manifest(template_dir, cfg, jid='JID')
self.failUnlessEqual(m.get('em:name'), 'a long ' + n)
self.failUnlessIn('<em:name>a long ' + n + '</em:name>', str(m), n)
if __name__ == '__main__':
unittest.main()

View File

@ -49,7 +49,7 @@ class PrefsTests(unittest.TestCase):
xulNamespacePrefix = \
"{http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul}"
settings = root.findall(xulNamespacePrefix + 'setting')
def assertPref(setting, name, prefType, title):
@ -74,7 +74,7 @@ class PrefsTests(unittest.TestCase):
def assertOption(option, value, label):
self.failUnlessEqual(option.get('value'), value)
self.failUnlessEqual(option.get('label'), label)
assertOption(menuItems[0], "0", "label1")
assertOption(menuItems[1], "1", "label2")
assertOption(radios[0], "red", "rouge")
@ -257,7 +257,6 @@ class SmallXPI(unittest.TestCase):
"defaults/preferences/prefs.js",
"resources/",
"resources/addon-sdk/",
"resources/addon-sdk/data/",
"resources/addon-sdk/lib/",
"resources/addon-sdk/lib/sdk/",
"resources/addon-sdk/lib/sdk/self.js",

View File

@ -164,4 +164,4 @@ exports['test that malformed uri is not an addon-page'] = function(assert, done)
});
};
require('test').run(exports);
require('sdk/test/runner').runTestsFromModule(module);

View File

@ -0,0 +1,3 @@
{
"id": "test-addon-page"
}

View File

@ -0,0 +1,24 @@
/* 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 = {
'engines': {
'Firefox': '*'
}
};
const { safeMerge: merge } = require('sdk/util/object');
merge(module.exports,
require('./tests/test-places-bookmarks'),
require('./tests/test-places-events'),
require('./tests/test-places-favicon'),
require('./tests/test-places-history'),
require('./tests/test-places-host'),
require('./tests/test-places-utils')
);
require('sdk/test/runner').runTestsFromModule(module);

View File

@ -0,0 +1,3 @@
{
"id": "test-places"
}

View File

@ -28,7 +28,7 @@ const {
invalidResolve, invalidReject, createTree,
compareWithHost, createBookmark, createBookmarkItem,
createBookmarkTree, addVisits, resetPlaces
} = require('./places-helper');
} = require('../places-helper');
const { promisedEmitter } = require('sdk/places/utils');
const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1'].
getService(Ci.nsINavBookmarksService);
@ -963,5 +963,3 @@ function delayed (value, ms) {
setTimeout(() => resolve(value), ms || 10);
return promise;
}
require('test').run(exports);

View File

@ -23,7 +23,7 @@ const {
invalidResolve, invalidReject, createTree, createBookmark,
compareWithHost, addVisits, resetPlaces, createBookmarkItem,
removeVisits
} = require('./places-helper');
} = require('../places-helper');
const { save, MENU, UNSORTED } = require('sdk/places/bookmarks');
const { promisedEmitter } = require('sdk/places/utils');
@ -289,4 +289,3 @@ function makeCompleted (done, countTo) {
if (++count === countTo) done();
};
}
require('sdk/test').run(exports);

View File

@ -16,10 +16,10 @@ const tabs = require('sdk/tabs');
const open = tabs.open;
const port = 8099;
const host = 'http://localhost:' + port;
const { onFaviconChange, serve, binFavicon } = require('./favicon-helpers');
const { onFaviconChange, serve, binFavicon } = require('../favicon-helpers');
const { once } = require('sdk/system/events');
const { defer } = require('sdk/core/promise');
const { resetPlaces } = require('./places-helper');
const { resetPlaces } = require('../places-helper');
const faviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
@ -186,5 +186,3 @@ function complete(tab, srv, done) {
});
});
}
require("test").run(exports);

View File

@ -21,7 +21,7 @@ const {
const {
invalidResolve, invalidReject, createTree,
compareWithHost, addVisits, resetPlaces
} = require('./places-helper');
} = require('../places-helper');
const { promisedEmitter } = require('sdk/places/utils');
exports.testEmptyQuery = function (assert, done) {
@ -247,5 +247,3 @@ function searchP () {
before(exports, (name, assert, done) => resetPlaces(done));
after(exports, (name, assert, done) => resetPlaces(done));
require('test').run(exports);

View File

@ -23,7 +23,7 @@ require('sdk/places/host/host-query');
const {
invalidResolve, invalidReject, createTree,
compareWithHost, createBookmark, createBookmarkTree, resetPlaces
} = require('./places-helper');
} = require('../places-helper');
const bmsrv = Cc['@mozilla.org/browser/nav-bookmarks-service;1'].
getService(Ci.nsINavBookmarksService);
@ -301,5 +301,3 @@ exports.testGetAllChildren = function (assert, done) {
before(exports, (name, assert, done) => resetPlaces(done));
after(exports, (name, assert, done) => resetPlaces(done));
require('test').run(exports);

View File

@ -77,5 +77,3 @@ exports['test async walk'] = function (assert, done) {
done();
});
};
require('test').run(exports);

View File

@ -0,0 +1 @@
# hello world

View File

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const self = require("sdk/self");
exports["test self.data.load"] = assert => {
assert.equal(self.data.load("data.md"),
"# hello world\n",
"paths work");
assert.equal(self.data.load("./data.md"),
"# hello world\n",
"relative paths work");
};
require("sdk/test/runner").runTestsFromModule(module);

View File

@ -0,0 +1,3 @@
{
"id": "test-self"
}

View File

@ -0,0 +1,39 @@
/* 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 { data } = require("sdk/self");
const { Symbiont } = require("sdk/content/symbiont");
exports["test:direct communication with trusted document"] = function(assert, done) {
let worker = Symbiont({
contentURL: data.url("test-trusted-document.html")
});
worker.port.on('document-to-addon', function (arg) {
assert.equal(arg, "ok", "Received an event from the document");
worker.destroy();
done();
});
worker.port.emit('addon-to-document', 'ok');
};
exports["test:`addon` is not available when a content script is set"] = function(assert, done) {
let worker = Symbiont({
contentURL: data.url("test-trusted-document.html"),
contentScript: "new " + function ContentScriptScope() {
self.port.emit("cs-to-addon", "addon" in unsafeWindow);
}
});
worker.port.on('cs-to-addon', function (hasAddon) {
assert.equal(hasAddon, false,
"`addon` is not available");
worker.destroy();
done();
});
};
require("sdk/test/runner").runTestsFromModule(module);

View File

@ -0,0 +1,3 @@
{
"id": "test-symbiont"
}

View File

@ -0,0 +1,368 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
const { Buffer } = require('sdk/io/buffer');
exports.testReadDouble = helper('readDoubleLE/readDoubleBE', function (assert) {
var buffer = new Buffer(8);
buffer[0] = 0x55;
buffer[1] = 0x55;
buffer[2] = 0x55;
buffer[3] = 0x55;
buffer[4] = 0x55;
buffer[5] = 0x55;
buffer[6] = 0xd5;
buffer[7] = 0x3f;
assert.equal(1.1945305291680097e+103, buffer.readDoubleBE(0));
assert.equal(0.3333333333333333, buffer.readDoubleLE(0));
buffer[0] = 1;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
buffer[4] = 0;
buffer[5] = 0;
buffer[6] = 0xf0;
buffer[7] = 0x3f;
assert.equal(7.291122019655968e-304, buffer.readDoubleBE(0));
assert.equal(1.0000000000000002, buffer.readDoubleLE(0));
buffer[0] = 2;
assert.equal(4.778309726801735e-299, buffer.readDoubleBE(0));
assert.equal(1.0000000000000004, buffer.readDoubleLE(0));
buffer[0] = 1;
buffer[6] = 0;
buffer[7] = 0;
assert.equal(7.291122019556398e-304, buffer.readDoubleBE(0));
assert.equal(5e-324, buffer.readDoubleLE(0));
buffer[0] = 0xff;
buffer[1] = 0xff;
buffer[2] = 0xff;
buffer[3] = 0xff;
buffer[4] = 0xff;
buffer[5] = 0xff;
buffer[6] = 0x0f;
buffer[7] = 0x00;
assert.ok(isNaN(buffer.readDoubleBE(0)));
assert.equal(2.225073858507201e-308, buffer.readDoubleLE(0));
buffer[6] = 0xef;
buffer[7] = 0x7f;
assert.ok(isNaN(buffer.readDoubleBE(0)));
assert.equal(1.7976931348623157e+308, buffer.readDoubleLE(0));
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
buffer[4] = 0;
buffer[5] = 0;
buffer[6] = 0xf0;
buffer[7] = 0x3f;
assert.equal(3.03865e-319, buffer.readDoubleBE(0));
assert.equal(1, buffer.readDoubleLE(0));
buffer[6] = 0;
buffer[7] = 0x40;
assert.equal(3.16e-322, buffer.readDoubleBE(0));
assert.equal(2, buffer.readDoubleLE(0));
buffer[7] = 0xc0;
assert.equal(9.5e-322, buffer.readDoubleBE(0));
assert.equal(-2, buffer.readDoubleLE(0));
buffer[6] = 0x10;
buffer[7] = 0;
assert.equal(2.0237e-320, buffer.readDoubleBE(0));
assert.equal(2.2250738585072014e-308, buffer.readDoubleLE(0));
buffer[6] = 0;
assert.equal(0, buffer.readDoubleBE(0));
assert.equal(0, buffer.readDoubleLE(0));
assert.equal(false, 1 / buffer.readDoubleLE(0) < 0);
buffer[7] = 0x80;
assert.equal(6.3e-322, buffer.readDoubleBE(0));
assert.equal(0, buffer.readDoubleLE(0));
assert.equal(true, 1 / buffer.readDoubleLE(0) < 0);
buffer[6] = 0xf0;
buffer[7] = 0x7f;
assert.equal(3.0418e-319, buffer.readDoubleBE(0));
assert.equal(Infinity, buffer.readDoubleLE(0));
buffer[6] = 0xf0;
buffer[7] = 0xff;
assert.equal(3.04814e-319, buffer.readDoubleBE(0));
assert.equal(-Infinity, buffer.readDoubleLE(0));
});
exports.testReadFloat = helper('readFloatLE/readFloatBE', function (assert) {
var buffer = new Buffer(4);
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0x80;
buffer[3] = 0x3f;
assert.equal(4.600602988224807e-41, buffer.readFloatBE(0));
assert.equal(1, buffer.readFloatLE(0));
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0xc0;
assert.equal(2.6904930515036488e-43, buffer.readFloatBE(0));
assert.equal(-2, buffer.readFloatLE(0));
buffer[0] = 0xff;
buffer[1] = 0xff;
buffer[2] = 0x7f;
buffer[3] = 0x7f;
assert.ok(isNaN(buffer.readFloatBE(0)));
assert.equal(3.4028234663852886e+38, buffer.readFloatLE(0));
buffer[0] = 0xab;
buffer[1] = 0xaa;
buffer[2] = 0xaa;
buffer[3] = 0x3e;
assert.equal(-1.2126478207002966e-12, buffer.readFloatBE(0));
assert.equal(0.3333333432674408, buffer.readFloatLE(0));
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
assert.equal(0, buffer.readFloatBE(0));
assert.equal(0, buffer.readFloatLE(0));
assert.equal(false, 1 / buffer.readFloatLE(0) < 0);
buffer[3] = 0x80;
assert.equal(1.793662034335766e-43, buffer.readFloatBE(0));
assert.equal(0, buffer.readFloatLE(0));
assert.equal(true, 1 / buffer.readFloatLE(0) < 0);
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0x80;
buffer[3] = 0x7f;
assert.equal(4.609571298396486e-41, buffer.readFloatBE(0));
assert.equal(Infinity, buffer.readFloatLE(0));
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0x80;
buffer[3] = 0xff;
assert.equal(4.627507918739843e-41, buffer.readFloatBE(0));
assert.equal(-Infinity, buffer.readFloatLE(0));
});
exports.testReadInt8 = helper('readInt8', function (assert) {
var data = new Buffer(4);
data[0] = 0x23;
assert.equal(0x23, data.readInt8(0));
data[0] = 0xff;
assert.equal(-1, data.readInt8(0));
data[0] = 0x87;
data[1] = 0xab;
data[2] = 0x7c;
data[3] = 0xef;
assert.equal(-121, data.readInt8(0));
assert.equal(-85, data.readInt8(1));
assert.equal(124, data.readInt8(2));
assert.equal(-17, data.readInt8(3));
});
exports.testReadInt16 = helper('readInt16BE/readInt16LE', function (assert) {
var buffer = new Buffer(6);
buffer[0] = 0x16;
buffer[1] = 0x79;
assert.equal(0x1679, buffer.readInt16BE(0));
assert.equal(0x7916, buffer.readInt16LE(0));
buffer[0] = 0xff;
buffer[1] = 0x80;
assert.equal(-128, buffer.readInt16BE(0));
assert.equal(-32513, buffer.readInt16LE(0));
/* test offset with weenix */
buffer[0] = 0x77;
buffer[1] = 0x65;
buffer[2] = 0x65;
buffer[3] = 0x6e;
buffer[4] = 0x69;
buffer[5] = 0x78;
assert.equal(0x7765, buffer.readInt16BE(0));
assert.equal(0x6565, buffer.readInt16BE(1));
assert.equal(0x656e, buffer.readInt16BE(2));
assert.equal(0x6e69, buffer.readInt16BE(3));
assert.equal(0x6978, buffer.readInt16BE(4));
assert.equal(0x6577, buffer.readInt16LE(0));
assert.equal(0x6565, buffer.readInt16LE(1));
assert.equal(0x6e65, buffer.readInt16LE(2));
assert.equal(0x696e, buffer.readInt16LE(3));
assert.equal(0x7869, buffer.readInt16LE(4));
});
exports.testReadInt32 = helper('readInt32BE/readInt32LE', function (assert) {
var buffer = new Buffer(6);
buffer[0] = 0x43;
buffer[1] = 0x53;
buffer[2] = 0x16;
buffer[3] = 0x79;
assert.equal(0x43531679, buffer.readInt32BE(0));
assert.equal(0x79165343, buffer.readInt32LE(0));
buffer[0] = 0xff;
buffer[1] = 0xfe;
buffer[2] = 0xef;
buffer[3] = 0xfa;
assert.equal(-69638, buffer.readInt32BE(0));
assert.equal(-84934913, buffer.readInt32LE(0));
buffer[0] = 0x42;
buffer[1] = 0xc3;
buffer[2] = 0x95;
buffer[3] = 0xa9;
buffer[4] = 0x36;
buffer[5] = 0x17;
assert.equal(0x42c395a9, buffer.readInt32BE(0));
assert.equal(-1013601994, buffer.readInt32BE(1));
assert.equal(-1784072681, buffer.readInt32BE(2));
assert.equal(-1449802942, buffer.readInt32LE(0));
assert.equal(917083587, buffer.readInt32LE(1));
assert.equal(389458325, buffer.readInt32LE(2));
});
/*
* We need to check the following things:
* - We are correctly resolving big endian (doesn't mean anything for 8 bit)
* - Correctly resolving little endian (doesn't mean anything for 8 bit)
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
exports.testReadUInt8 = helper('readUInt8', function (assert) {
var data = new Buffer(4);
data[0] = 23;
data[1] = 23;
data[2] = 23;
data[3] = 23;
assert.equal(23, data.readUInt8(0));
assert.equal(23, data.readUInt8(1));
assert.equal(23, data.readUInt8(2));
assert.equal(23, data.readUInt8(3));
data[0] = 255; /* If it became a signed int, would be -1 */
assert.equal(255, data.readUInt8(0));
});
/*
* Test 16 bit unsigned integers. We need to verify the same set as 8 bit, only
* now some of the issues actually matter:
* - We are correctly resolving big endian
* - Correctly resolving little endian
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
exports.testReadUInt16 = helper('readUInt16LE/readUInt16BE', function (assert) {
var data = new Buffer(4);
data[0] = 0;
data[1] = 0x23;
data[2] = 0x42;
data[3] = 0x3f;
assert.equal(0x23, data.readUInt16BE(0));
assert.equal(0x2342, data.readUInt16BE(1));
assert.equal(0x423f, data.readUInt16BE(2));
assert.equal(0x2300, data.readUInt16LE(0));
assert.equal(0x4223, data.readUInt16LE(1));
assert.equal(0x3f42, data.readUInt16LE(2));
data[0] = 0xfe;
data[1] = 0xfe;
assert.equal(0xfefe, data.readUInt16BE(0));
assert.equal(0xfefe, data.readUInt16LE(0));
});
/*
* Test 32 bit unsigned integers. We need to verify the same set as 8 bit, only
* now some of the issues actually matter:
* - We are correctly resolving big endian
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
exports.testReadUInt32 = helper('readUInt32LE/readUInt32BE', function (assert) {
var data = new Buffer(8);
data[0] = 0x32;
data[1] = 0x65;
data[2] = 0x42;
data[3] = 0x56;
data[4] = 0x23;
data[5] = 0xff;
assert.equal(0x32654256, data.readUInt32BE(0));
assert.equal(0x65425623, data.readUInt32BE(1));
assert.equal(0x425623ff, data.readUInt32BE(2));
assert.equal(0x56426532, data.readUInt32LE(0));
assert.equal(0x23564265, data.readUInt32LE(1));
assert.equal(0xff235642, data.readUInt32LE(2));
});
function helper (description, fn) {
let bulkAssert = {
equal: function (a, b) {
if (a !== b) throw new Error('Error found in ' + description);
},
ok: function (value) {
if (!value) throw new Error('Error found in ' + description);
},
throws: function (shouldThrow) {
let didItThrow = false;
try {
shouldThrow();
} catch (e) {
didItThrow = e;
}
if (!didItThrow)
throw new Error('Error found in ' + description + ': ' + shouldThrow + ' should have thrown');
}
};
return function (assert) {
fn(bulkAssert);
// If we get here, no errors thrown
assert.pass('All tests passed for ' + description);
};
}

View File

@ -0,0 +1,602 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
const { Buffer } = require('sdk/io/buffer');
exports.testWriteDouble = helper('writeDoubleBE/writeDoubleLE', function (assert) {
var buffer = new Buffer(16);
buffer.writeDoubleBE(2.225073858507201e-308, 0);
buffer.writeDoubleLE(2.225073858507201e-308, 8);
assert.equal(0x00, buffer[0]);
assert.equal(0x0f, buffer[1]);
assert.equal(0xff, buffer[2]);
assert.equal(0xff, buffer[3]);
assert.equal(0xff, buffer[4]);
assert.equal(0xff, buffer[5]);
assert.equal(0xff, buffer[6]);
assert.equal(0xff, buffer[7]);
assert.equal(0xff, buffer[8]);
assert.equal(0xff, buffer[9]);
assert.equal(0xff, buffer[10]);
assert.equal(0xff, buffer[11]);
assert.equal(0xff, buffer[12]);
assert.equal(0xff, buffer[13]);
assert.equal(0x0f, buffer[14]);
assert.equal(0x00, buffer[15]);
buffer.writeDoubleBE(1.0000000000000004, 0);
buffer.writeDoubleLE(1.0000000000000004, 8);
assert.equal(0x3f, buffer[0]);
assert.equal(0xf0, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x02, buffer[7]);
assert.equal(0x02, buffer[8]);
assert.equal(0x00, buffer[9]);
assert.equal(0x00, buffer[10]);
assert.equal(0x00, buffer[11]);
assert.equal(0x00, buffer[12]);
assert.equal(0x00, buffer[13]);
assert.equal(0xf0, buffer[14]);
assert.equal(0x3f, buffer[15]);
buffer.writeDoubleBE(-2, 0);
buffer.writeDoubleLE(-2, 8);
assert.equal(0xc0, buffer[0]);
assert.equal(0x00, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
assert.equal(0x00, buffer[8]);
assert.equal(0x00, buffer[9]);
assert.equal(0x00, buffer[10]);
assert.equal(0x00, buffer[11]);
assert.equal(0x00, buffer[12]);
assert.equal(0x00, buffer[13]);
assert.equal(0x00, buffer[14]);
assert.equal(0xc0, buffer[15]);
buffer.writeDoubleBE(1.7976931348623157e+308, 0);
buffer.writeDoubleLE(1.7976931348623157e+308, 8);
assert.equal(0x7f, buffer[0]);
assert.equal(0xef, buffer[1]);
assert.equal(0xff, buffer[2]);
assert.equal(0xff, buffer[3]);
assert.equal(0xff, buffer[4]);
assert.equal(0xff, buffer[5]);
assert.equal(0xff, buffer[6]);
assert.equal(0xff, buffer[7]);
assert.equal(0xff, buffer[8]);
assert.equal(0xff, buffer[9]);
assert.equal(0xff, buffer[10]);
assert.equal(0xff, buffer[11]);
assert.equal(0xff, buffer[12]);
assert.equal(0xff, buffer[13]);
assert.equal(0xef, buffer[14]);
assert.equal(0x7f, buffer[15]);
buffer.writeDoubleBE(0 * -1, 0);
buffer.writeDoubleLE(0 * -1, 8);
assert.equal(0x80, buffer[0]);
assert.equal(0x00, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
assert.equal(0x00, buffer[8]);
assert.equal(0x00, buffer[9]);
assert.equal(0x00, buffer[10]);
assert.equal(0x00, buffer[11]);
assert.equal(0x00, buffer[12]);
assert.equal(0x00, buffer[13]);
assert.equal(0x00, buffer[14]);
assert.equal(0x80, buffer[15]);
buffer.writeDoubleBE(Infinity, 0);
buffer.writeDoubleLE(Infinity, 8);
assert.equal(0x7F, buffer[0]);
assert.equal(0xF0, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
assert.equal(0x00, buffer[8]);
assert.equal(0x00, buffer[9]);
assert.equal(0x00, buffer[10]);
assert.equal(0x00, buffer[11]);
assert.equal(0x00, buffer[12]);
assert.equal(0x00, buffer[13]);
assert.equal(0xF0, buffer[14]);
assert.equal(0x7F, buffer[15]);
assert.equal(Infinity, buffer.readDoubleBE(0));
assert.equal(Infinity, buffer.readDoubleLE(8));
buffer.writeDoubleBE(-Infinity, 0);
buffer.writeDoubleLE(-Infinity, 8);
assert.equal(0xFF, buffer[0]);
assert.equal(0xF0, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
assert.equal(0x00, buffer[8]);
assert.equal(0x00, buffer[9]);
assert.equal(0x00, buffer[10]);
assert.equal(0x00, buffer[11]);
assert.equal(0x00, buffer[12]);
assert.equal(0x00, buffer[13]);
assert.equal(0xF0, buffer[14]);
assert.equal(0xFF, buffer[15]);
assert.equal(-Infinity, buffer.readDoubleBE(0));
assert.equal(-Infinity, buffer.readDoubleLE(8));
buffer.writeDoubleBE(NaN, 0);
buffer.writeDoubleLE(NaN, 8);
// Darwin ia32 does the other kind of NaN.
// Compiler bug. No one really cares.
assert.ok(0x7F === buffer[0] || 0xFF === buffer[0]);
assert.equal(0xF8, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
assert.equal(0x00, buffer[8]);
assert.equal(0x00, buffer[9]);
assert.equal(0x00, buffer[10]);
assert.equal(0x00, buffer[11]);
assert.equal(0x00, buffer[12]);
assert.equal(0x00, buffer[13]);
assert.equal(0xF8, buffer[14]);
// Darwin ia32 does the other kind of NaN.
// Compiler bug. No one really cares.
assert.ok(0x7F === buffer[15] || 0xFF === buffer[15]);
assert.ok(isNaN(buffer.readDoubleBE(0)));
assert.ok(isNaN(buffer.readDoubleLE(8)));
});
exports.testWriteFloat = helper('writeFloatBE/writeFloatLE', function (assert) {
var buffer = new Buffer(8);
buffer.writeFloatBE(1, 0);
buffer.writeFloatLE(1, 4);
assert.equal(0x3f, buffer[0]);
assert.equal(0x80, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x80, buffer[6]);
assert.equal(0x3f, buffer[7]);
buffer.writeFloatBE(1 / 3, 0);
buffer.writeFloatLE(1 / 3, 4);
assert.equal(0x3e, buffer[0]);
assert.equal(0xaa, buffer[1]);
assert.equal(0xaa, buffer[2]);
assert.equal(0xab, buffer[3]);
assert.equal(0xab, buffer[4]);
assert.equal(0xaa, buffer[5]);
assert.equal(0xaa, buffer[6]);
assert.equal(0x3e, buffer[7]);
buffer.writeFloatBE(3.4028234663852886e+38, 0);
buffer.writeFloatLE(3.4028234663852886e+38, 4);
assert.equal(0x7f, buffer[0]);
assert.equal(0x7f, buffer[1]);
assert.equal(0xff, buffer[2]);
assert.equal(0xff, buffer[3]);
assert.equal(0xff, buffer[4]);
assert.equal(0xff, buffer[5]);
assert.equal(0x7f, buffer[6]);
assert.equal(0x7f, buffer[7]);
buffer.writeFloatLE(1.1754943508222875e-38, 0);
buffer.writeFloatBE(1.1754943508222875e-38, 4);
assert.equal(0x00, buffer[0]);
assert.equal(0x00, buffer[1]);
assert.equal(0x80, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x80, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
buffer.writeFloatBE(0 * -1, 0);
buffer.writeFloatLE(0 * -1, 4);
assert.equal(0x80, buffer[0]);
assert.equal(0x00, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x80, buffer[7]);
buffer.writeFloatBE(Infinity, 0);
buffer.writeFloatLE(Infinity, 4);
assert.equal(0x7F, buffer[0]);
assert.equal(0x80, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x80, buffer[6]);
assert.equal(0x7F, buffer[7]);
assert.equal(Infinity, buffer.readFloatBE(0));
assert.equal(Infinity, buffer.readFloatLE(4));
buffer.writeFloatBE(-Infinity, 0);
buffer.writeFloatLE(-Infinity, 4);
// Darwin ia32 does the other kind of NaN.
// Compiler bug. No one really cares.
assert.ok(0xFF === buffer[0] || 0x7F === buffer[0]);
assert.equal(0x80, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x80, buffer[6]);
assert.equal(0xFF, buffer[7]);
assert.equal(-Infinity, buffer.readFloatBE(0));
assert.equal(-Infinity, buffer.readFloatLE(4));
buffer.writeFloatBE(NaN, 0);
buffer.writeFloatLE(NaN, 4);
// Darwin ia32 does the other kind of NaN.
// Compiler bug. No one really cares.
assert.ok(0x7F === buffer[0] || 0xFF === buffer[0]);
assert.equal(0xc0, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0xc0, buffer[6]);
// Darwin ia32 does the other kind of NaN.
// Compiler bug. No one really cares.
assert.ok(0x7F === buffer[7] || 0xFF === buffer[7]);
assert.ok(isNaN(buffer.readFloatBE(0)));
assert.ok(isNaN(buffer.readFloatLE(4)));
});
exports.testWriteInt8 = helper('writeInt8', function (assert) {
var buffer = new Buffer(2);
buffer.writeInt8(0x23, 0);
buffer.writeInt8(-5, 1);
assert.equal(0x23, buffer[0]);
assert.equal(0xfb, buffer[1]);
/* Make sure we handle truncation correctly */
assert.throws(function() {
buffer.writeInt8(0xabc, 0);
});
assert.throws(function() {
buffer.writeInt8(0xabc, 0);
});
/* Make sure we handle min/max correctly */
buffer.writeInt8(0x7f, 0);
buffer.writeInt8(-0x80, 1);
assert.equal(0x7f, buffer[0]);
assert.equal(0x80, buffer[1]);
assert.throws(function() {
buffer.writeInt8(0x7f + 1, 0);
});
assert.throws(function() {
buffer.writeInt8(-0x80 - 1, 0);
});
});
exports.testWriteInt16 = helper('writeInt16LE/writeInt16BE', function (assert) {
var buffer = new Buffer(6);
buffer.writeInt16BE(0x0023, 0);
buffer.writeInt16LE(0x0023, 2);
assert.equal(0x00, buffer[0]);
assert.equal(0x23, buffer[1]);
assert.equal(0x23, buffer[2]);
assert.equal(0x00, buffer[3]);
buffer.writeInt16BE(-5, 0);
buffer.writeInt16LE(-5, 2);
assert.equal(0xff, buffer[0]);
assert.equal(0xfb, buffer[1]);
assert.equal(0xfb, buffer[2]);
assert.equal(0xff, buffer[3]);
buffer.writeInt16BE(-1679, 1);
buffer.writeInt16LE(-1679, 3);
assert.equal(0xf9, buffer[1]);
assert.equal(0x71, buffer[2]);
assert.equal(0x71, buffer[3]);
assert.equal(0xf9, buffer[4]);
/* Make sure we handle min/max correctly */
buffer.writeInt16BE(0x7fff, 0);
buffer.writeInt16BE(-0x8000, 2);
assert.equal(0x7f, buffer[0]);
assert.equal(0xff, buffer[1]);
assert.equal(0x80, buffer[2]);
assert.equal(0x00, buffer[3]);
assert.throws(function() {
buffer.writeInt16BE(0x7fff + 1, 0);
});
assert.throws(function() {
buffer.writeInt16BE(-0x8000 - 1, 0);
});
buffer.writeInt16LE(0x7fff, 0);
buffer.writeInt16LE(-0x8000, 2);
assert.equal(0xff, buffer[0]);
assert.equal(0x7f, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x80, buffer[3]);
assert.throws(function() {
buffer.writeInt16LE(0x7fff + 1, 0);
});
assert.throws(function() {
buffer.writeInt16LE(-0x8000 - 1, 0);
});
});
exports.testWriteInt32 = helper('writeInt32BE/writeInt32LE', function (assert) {
var buffer = new Buffer(8);
buffer.writeInt32BE(0x23, 0);
buffer.writeInt32LE(0x23, 4);
assert.equal(0x00, buffer[0]);
assert.equal(0x00, buffer[1]);
assert.equal(0x00, buffer[2]);
assert.equal(0x23, buffer[3]);
assert.equal(0x23, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
buffer.writeInt32BE(-5, 0);
buffer.writeInt32LE(-5, 4);
assert.equal(0xff, buffer[0]);
assert.equal(0xff, buffer[1]);
assert.equal(0xff, buffer[2]);
assert.equal(0xfb, buffer[3]);
assert.equal(0xfb, buffer[4]);
assert.equal(0xff, buffer[5]);
assert.equal(0xff, buffer[6]);
assert.equal(0xff, buffer[7]);
buffer.writeInt32BE(-805306713, 0);
buffer.writeInt32LE(-805306713, 4);
assert.equal(0xcf, buffer[0]);
assert.equal(0xff, buffer[1]);
assert.equal(0xfe, buffer[2]);
assert.equal(0xa7, buffer[3]);
assert.equal(0xa7, buffer[4]);
assert.equal(0xfe, buffer[5]);
assert.equal(0xff, buffer[6]);
assert.equal(0xcf, buffer[7]);
/* Make sure we handle min/max correctly */
buffer.writeInt32BE(0x7fffffff, 0);
buffer.writeInt32BE(-0x80000000, 4);
assert.equal(0x7f, buffer[0]);
assert.equal(0xff, buffer[1]);
assert.equal(0xff, buffer[2]);
assert.equal(0xff, buffer[3]);
assert.equal(0x80, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x00, buffer[7]);
assert.throws(function() {
buffer.writeInt32BE(0x7fffffff + 1, 0);
});
assert.throws(function() {
buffer.writeInt32BE(-0x80000000 - 1, 0);
});
buffer.writeInt32LE(0x7fffffff, 0);
buffer.writeInt32LE(-0x80000000, 4);
assert.equal(0xff, buffer[0]);
assert.equal(0xff, buffer[1]);
assert.equal(0xff, buffer[2]);
assert.equal(0x7f, buffer[3]);
assert.equal(0x00, buffer[4]);
assert.equal(0x00, buffer[5]);
assert.equal(0x00, buffer[6]);
assert.equal(0x80, buffer[7]);
assert.throws(function() {
buffer.writeInt32LE(0x7fffffff + 1, 0);
});
assert.throws(function() {
buffer.writeInt32LE(-0x80000000 - 1, 0);
});
});
/*
* We need to check the following things:
* - We are correctly resolving big endian (doesn't mean anything for 8 bit)
* - Correctly resolving little endian (doesn't mean anything for 8 bit)
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
exports.testWriteUInt8 = helper('writeUInt8', function (assert) {
var data = new Buffer(4);
data.writeUInt8(23, 0);
data.writeUInt8(23, 1);
data.writeUInt8(23, 2);
data.writeUInt8(23, 3);
assert.equal(23, data[0]);
assert.equal(23, data[1]);
assert.equal(23, data[2]);
assert.equal(23, data[3]);
data.writeUInt8(23, 0);
data.writeUInt8(23, 1);
data.writeUInt8(23, 2);
data.writeUInt8(23, 3);
assert.equal(23, data[0]);
assert.equal(23, data[1]);
assert.equal(23, data[2]);
assert.equal(23, data[3]);
data.writeUInt8(255, 0);
assert.equal(255, data[0]);
data.writeUInt8(255, 0);
assert.equal(255, data[0]);
});
exports.testWriteUInt16 = helper('writeUInt16BE/writeUInt16LE', function (assert) {
var value = 0x2343;
var data = new Buffer(4);
data.writeUInt16BE(value, 0);
assert.equal(0x23, data[0]);
assert.equal(0x43, data[1]);
data.writeUInt16BE(value, 1);
assert.equal(0x23, data[1]);
assert.equal(0x43, data[2]);
data.writeUInt16BE(value, 2);
assert.equal(0x23, data[2]);
assert.equal(0x43, data[3]);
data.writeUInt16LE(value, 0);
assert.equal(0x23, data[1]);
assert.equal(0x43, data[0]);
data.writeUInt16LE(value, 1);
assert.equal(0x23, data[2]);
assert.equal(0x43, data[1]);
data.writeUInt16LE(value, 2);
assert.equal(0x23, data[3]);
assert.equal(0x43, data[2]);
value = 0xff80;
data.writeUInt16LE(value, 0);
assert.equal(0xff, data[1]);
assert.equal(0x80, data[0]);
data.writeUInt16BE(value, 0);
assert.equal(0xff, data[0]);
assert.equal(0x80, data[1]);
});
exports.testWriteUInt32 = helper('writeUInt32BE/writeUInt32LE', function (assert) {
var data = new Buffer(6);
var value = 0xe7f90a6d;
data.writeUInt32BE(value, 0);
assert.equal(0xe7, data[0]);
assert.equal(0xf9, data[1]);
assert.equal(0x0a, data[2]);
assert.equal(0x6d, data[3]);
data.writeUInt32BE(value, 1);
assert.equal(0xe7, data[1]);
assert.equal(0xf9, data[2]);
assert.equal(0x0a, data[3]);
assert.equal(0x6d, data[4]);
data.writeUInt32BE(value, 2);
assert.equal(0xe7, data[2]);
assert.equal(0xf9, data[3]);
assert.equal(0x0a, data[4]);
assert.equal(0x6d, data[5]);
data.writeUInt32LE(value, 0);
assert.equal(0xe7, data[3]);
assert.equal(0xf9, data[2]);
assert.equal(0x0a, data[1]);
assert.equal(0x6d, data[0]);
data.writeUInt32LE(value, 1);
assert.equal(0xe7, data[4]);
assert.equal(0xf9, data[3]);
assert.equal(0x0a, data[2]);
assert.equal(0x6d, data[1]);
data.writeUInt32LE(value, 2);
assert.equal(0xe7, data[5]);
assert.equal(0xf9, data[4]);
assert.equal(0x0a, data[3]);
assert.equal(0x6d, data[2]);
});
function helper (description, fn) {
return function (assert) {
let bulkAssert = {
equal: function (a, b) {
if (a !== b) throw new Error('Error found in ' + description);
},
ok: function (value) {
if (!value) throw new Error('Error found in ' + description);
},
/*
* TODO
* There should be errors when setting outside of the value range
* of the data type (like writeInt8 with value of 1000), but DataView
* does not throw; seems to just grab the appropriate max bits.
* So ignoring this test for now
*/
throws: function (shouldThrow) {
assert.pass(description + ': Need to implement error handling for setting buffer values ' +
'outside of the data types\' range.');
/*
let didItThrow = false;
try {
shouldThrow();
} catch (e) {
didItThrow = e;
}
if (!didItThrow)
throw new Error('Error found in ' + description + ': ' + shouldThrow + ' should have thrown');
*/
}
};
fn(bulkAssert);
// If we get here, no errors thrown
assert.pass('All tests passed for ' + description);
};
}

View File

@ -2,13 +2,5 @@
* 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/. */
namespace mozilla {
namespace dom {
struct PermissionRequest {
nsCString type;
nsCString access;
};
} // namespace dom
} // namespace mozilla
exports.url = path =>
module.uri.substr(0, module.uri.lastIndexOf("/") + 1) + "fixtures/" + path

View File

@ -0,0 +1,13 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<meta charset="UTF-8">
<title>Add-on Page</title>
</head>
<body>
<p>This is an add-on page test!</p>
</body>
</html>

View File

@ -0,0 +1,3 @@
{
invalidjson
}

View File

@ -0,0 +1,14 @@
{
"name": "Jetpack Loader Test",
"version": "1.0.1",
"dependencies": {
"async": "*",
"underscore": "*"
},
"contributors": [
"ash nazg durbatulûk",
"ash nazg gimbatul",
"ash nazg thrakatulûk",
"agh burzum-ishi krimpatul"
]
}

View File

@ -0,0 +1,4 @@
module.exports = {
"filename": "nodotjson.json.js",
"data": {}
};

View File

@ -0,0 +1,3 @@
{
"filename": "test.json"
}

View File

@ -0,0 +1,3 @@
module.exports = {
"filename": "test.json.js"
};

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,20 @@
<!-- 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/. -->
<html>
<head>
<meta charset="UTF-8">
<title>Worker test</title>
</head>
<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);
});
}
</script>
</body>
</html>

View File

@ -10,6 +10,7 @@ const observers = require("sdk/deprecated/observer-service");
const { setTimeout } = require("sdk/timers");
const tmp = require("sdk/test/tmp-file");
const system = require("sdk/system");
const fixtures = require("./fixtures");
const testFolderURL = module.uri.split('test-addon-installer.js')[0];
const ADDON_URL = testFolderURL + "fixtures/addon-install-unit-test@mozilla.com.xpi";

View File

@ -2,31 +2,486 @@
* 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/. */
/*
* Many of these tests taken from Joyent's Node
* https://github.com/joyent/node/blob/master/test/simple/test-buffer.js
*/
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
const { Buffer, TextEncoder, TextDecoder } = require('sdk/io/buffer');
const { safeMerge } = require('sdk/util/object');
const ENCODINGS = ['utf-8', 'utf-16le', 'utf-16be'];
exports.testBufferMain = function (assert) {
let b = Buffer('abcdef');
// try to create 0-length buffers
new Buffer('');
new Buffer(0);
// test encodings supported by node;
// this is different than what node supports, details
// in buffer.js
ENCODINGS.forEach(enc => {
new Buffer('', enc);
assert.pass('Creating a buffer with ' + enc + ' does not throw');
});
ENCODINGS.forEach(function(encoding) {
// Does not work with utf8
if (encoding === 'utf-8') return;
var b = new Buffer(10);
b.write('あいうえお', encoding);
assert.equal(b.toString(encoding), 'あいうえお',
'encode and decodes buffer with ' + encoding);
});
// invalid encoding for Buffer.toString
assert.throws(() => {
b.toString('invalid');
}, TypeError, 'invalid encoding for Buffer.toString');
// try to toString() a 0-length slice of a buffer, both within and without the
// valid buffer range
assert.equal(new Buffer('abc').toString('utf8', 0, 0), '',
'toString 0-length buffer, valid range');
assert.equal(new Buffer('abc').toString('utf8', -100, -100), '',
'toString 0-length buffer, invalid range');
assert.equal(new Buffer('abc').toString('utf8', 100, 100), '',
'toString 0-length buffer, invalid range');
// try toString() with a object as a encoding
assert.equal(new Buffer('abc').toString({toString: function() {
return 'utf8';
}}), 'abc', 'toString with object as an encoding');
// test for buffer overrun
var buf = new Buffer([0, 0, 0, 0, 0]); // length: 5
var sub = buf.slice(0, 4); // length: 4
var written = sub.write('12345', 'utf8');
assert.equal(written, 4, 'correct bytes written in slice');
assert.equal(buf[4], 0, 'correct origin buffer value');
// Check for fractional length args, junk length args, etc.
// https://github.com/joyent/node/issues/1758
Buffer(3.3).toString(); // throws bad argument error in commit 43cb4ec
assert.equal(Buffer(-1).length, 0);
assert.equal(Buffer(NaN).length, 0);
assert.equal(Buffer(3.3).length, 3);
assert.equal(Buffer({length: 3.3}).length, 3);
assert.equal(Buffer({length: 'BAM'}).length, 0);
// Make sure that strings are not coerced to numbers.
assert.equal(Buffer('99').length, 2);
assert.equal(Buffer('13.37').length, 5);
};
exports.testIsEncoding = function (assert) {
Object.keys(ENCODINGS).forEach(encoding => {
ENCODINGS.map(encoding => {
assert.ok(Buffer.isEncoding(encoding),
'Buffer.isEncoding ' + encoding + ' truthy');
});
['not-encoding', undefined, null, 100, {}].forEach(encoding => {
['not-encoding', undefined, null, 100, {}].map(encoding => {
assert.ok(!Buffer.isEncoding(encoding),
'Buffer.isEncoding ' + encoding + ' falsy');
});
};
exports.testBufferCopy = function (assert) {
// counter to ensure unique value is always copied
var cntr = 0;
var b = Buffer(1024); // safe constructor
assert.strictEqual(1024, b.length);
b[0] = -1;
assert.strictEqual(b[0], 255);
var shimArray = [];
for (var i = 0; i < 1024; i++) {
b[i] = i % 256;
shimArray[i] = i % 256;
}
compareBuffers(assert, b, shimArray, 'array notation');
var c = new Buffer(512);
assert.strictEqual(512, c.length);
// copy 512 bytes, from 0 to 512.
b.fill(++cntr);
c.fill(++cntr);
var copied = b.copy(c, 0, 0, 512);
assert.strictEqual(512, copied,
'copied ' + copied + ' bytes from b into c');
compareBuffers(assert, b, c, 'copied to other buffer');
// copy c into b, without specifying sourceEnd
b.fill(++cntr);
c.fill(++cntr);
var copied = c.copy(b, 0, 0);
assert.strictEqual(c.length, copied,
'copied ' + copied + ' bytes from c into b w/o sourceEnd');
compareBuffers(assert, b, c,
'copied to other buffer without specifying sourceEnd');
// copy c into b, without specifying sourceStart
b.fill(++cntr);
c.fill(++cntr);
var copied = c.copy(b, 0);
assert.strictEqual(c.length, copied,
'copied ' + copied + ' bytes from c into b w/o sourceStart');
compareBuffers(assert, b, c,
'copied to other buffer without specifying sourceStart');
// copy longer buffer b to shorter c without targetStart
b.fill(++cntr);
c.fill(++cntr);
var copied = b.copy(c);
assert.strictEqual(c.length, copied,
'copied ' + copied + ' bytes from b into c w/o targetStart');
compareBuffers(assert, b, c,
'copy long buffer to shorter buffer without targetStart');
// copy starting near end of b to c
b.fill(++cntr);
c.fill(++cntr);
var copied = b.copy(c, 0, b.length - Math.floor(c.length / 2));
assert.strictEqual(Math.floor(c.length / 2), copied,
'copied ' + copied + ' bytes from end of b into beg. of c');
let successStatus = true;
for (var i = 0; i < Math.floor(c.length / 2); i++) {
if (b[b.length - Math.floor(c.length / 2) + i] !== c[i])
successStatus = false;
}
for (var i = Math.floor(c.length /2) + 1; i < c.length; i++) {
if (c[c.length-1] !== c[i])
successStatus = false;
}
assert.ok(successStatus,
'Copied bytes from end of large buffer into beginning of small buffer');
// try to copy 513 bytes, and check we don't overrun c
b.fill(++cntr);
c.fill(++cntr);
var copied = b.copy(c, 0, 0, 513);
assert.strictEqual(c.length, copied,
'copied ' + copied + ' bytes from b trying to overrun c');
compareBuffers(assert, b, c,
'copying to buffer that would overflow');
// copy 768 bytes from b into b
b.fill(++cntr);
b.fill(++cntr, 256);
var copied = b.copy(b, 0, 256, 1024);
assert.strictEqual(768, copied,
'copied ' + copied + ' bytes from b into b');
compareBuffers(assert, b, shimArray.map(()=>cntr),
'copy partial buffer to itself');
// copy string longer than buffer length (failure will segfault)
var bb = new Buffer(10);
bb.fill('hello crazy world');
// copy throws at negative sourceStart
assert.throws(function() {
Buffer(5).copy(Buffer(5), 0, -1);
}, RangeError, 'buffer copy throws at negative sourceStart');
// check sourceEnd resets to targetEnd if former is greater than the latter
b.fill(++cntr);
c.fill(++cntr);
var copied = b.copy(c, 0, 0, 1025);
assert.strictEqual(copied, c.length,
'copied ' + copied + ' bytes from b into c');
compareBuffers(assert, b, c, 'copying should reset sourceEnd if targetEnd if sourceEnd > targetEnd');
// throw with negative sourceEnd
assert.throws(function() {
b.copy(c, 0, 0, -1);
}, RangeError, 'buffer copy throws at negative sourceEnd');
// when sourceStart is greater than sourceEnd, zero copied
assert.equal(b.copy(c, 0, 100, 10), 0);
// when targetStart > targetLength, zero copied
assert.equal(b.copy(c, 512, 0, 10), 0);
// try to copy 0 bytes worth of data into an empty buffer
b.copy(new Buffer(0), 0, 0, 0);
// try to copy 0 bytes past the end of the target buffer
b.copy(new Buffer(0), 1, 1, 1);
b.copy(new Buffer(1), 1, 1, 1);
// try to copy 0 bytes from past the end of the source buffer
b.copy(new Buffer(1), 0, 2048, 2048);
};
exports.testBufferWrite = function (assert) {
let b = Buffer(1024);
b.fill(0);
assert.throws(() => {
b.write('test string', 0, 5, 'invalid');
}, TypeError, 'invalid encoding with buffer write throws');
// try to write a 0-length string beyond the end of b
assert.throws(function() {
b.write('', 2048);
}, RangeError, 'writing a 0-length string beyond buffer throws');
// throw when writing to negative offset
assert.throws(function() {
b.write('a', -1);
}, RangeError, 'writing negative offset on buffer throws');
// throw when writing past bounds from the pool
assert.throws(function() {
b.write('a', 2048);
}, RangeError, 'writing past buffer bounds from pool throws');
// testing for smart defaults and ability to pass string values as offset
// previous write API was the following:
// write(string, encoding, offset, length)
// this is planned on being removed in node v0.13,
// we will not support it
var writeTest = new Buffer('abcdes');
writeTest.write('n', 'utf8');
// writeTest.write('o', 'utf8', '1');
writeTest.write('d', '2', 'utf8');
writeTest.write('e', 3, 'utf8');
// writeTest.write('j', 'utf8', 4);
assert.equal(writeTest.toString(), 'nbdees',
'buffer write API alternative syntax works');
};
exports.testBufferWriteEncoding = function (assert) {
// Node #1210 Test UTF-8 string includes null character
var buf = new Buffer('\0');
assert.equal(buf.length, 1);
buf = new Buffer('\0\0');
assert.equal(buf.length, 2);
buf = new Buffer(2);
var written = buf.write(''); // 0byte
assert.equal(written, 0);
written = buf.write('\0'); // 1byte (v8 adds null terminator)
assert.equal(written, 1);
written = buf.write('a\0'); // 1byte * 2
assert.equal(written, 2);
// TODO, these tests write 0, possibly due to character encoding
/*
written = buf.write('あ'); // 3bytes
assert.equal(written, 0);
written = buf.write('\0あ'); // 1byte + 3bytes
assert.equal(written, 1);
*/
written = buf.write('\0\0あ'); // 1byte * 2 + 3bytes
buf = new Buffer(10);
written = buf.write('あいう'); // 3bytes * 3 (v8 adds null terminator)
assert.equal(written, 9);
written = buf.write('あいう\0'); // 3bytes * 3 + 1byte
assert.equal(written, 10);
};
exports.testBufferWriteWithMaxLength = function (assert) {
// Node #243 Test write() with maxLength
var buf = new Buffer(4);
buf.fill(0xFF);
var written = buf.write('abcd', 1, 2, 'utf8');
assert.equal(written, 2);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0x61);
assert.equal(buf[2], 0x62);
assert.equal(buf[3], 0xFF);
buf.fill(0xFF);
written = buf.write('abcd', 1, 4);
assert.equal(written, 3);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0x61);
assert.equal(buf[2], 0x62);
assert.equal(buf[3], 0x63);
buf.fill(0xFF);
// Ignore legacy API
/*
written = buf.write('abcd', 'utf8', 1, 2); // legacy style
console.log(buf);
assert.equal(written, 2);
assert.equal(buf[0], 0xFF);
assert.equal(buf[1], 0x61);
assert.equal(buf[2], 0x62);
assert.equal(buf[3], 0xFF);
*/
};
exports.testBufferSlice = function (assert) {
var asciiString = 'hello world';
var offset = 100;
var b = Buffer(1024);
b.fill(0);
for (var i = 0; i < asciiString.length; i++) {
b[i] = asciiString.charCodeAt(i);
}
var asciiSlice = b.toString('utf8', 0, asciiString.length);
assert.equal(asciiString, asciiSlice);
var written = b.write(asciiString, offset, 'utf8');
assert.equal(asciiString.length, written);
asciiSlice = b.toString('utf8', offset, offset + asciiString.length);
assert.equal(asciiString, asciiSlice);
var sliceA = b.slice(offset, offset + asciiString.length);
var sliceB = b.slice(offset, offset + asciiString.length);
compareBuffers(assert, sliceA, sliceB,
'slicing is idempotent');
let sliceTest = true;
for (var j = 0; j < 100; j++) {
var slice = b.slice(100, 150);
if (50 !== slice.length)
sliceTest = false;
for (var i = 0; i < 50; i++) {
if (b[100 + i] !== slice[i])
sliceTest = false;
}
}
assert.ok(sliceTest, 'massive slice runs do not affect buffer');
// Single argument slice
let testBuf = new Buffer('abcde');
assert.equal('bcde', testBuf.slice(1).toString(), 'single argument slice');
// slice(0,0).length === 0
assert.equal(0, Buffer('hello').slice(0, 0).length, 'slice(0,0) === 0');
var buf = new Buffer('0123456789');
assert.equal(buf.slice(-10, 10), '0123456789', 'buffer slice range correct');
assert.equal(buf.slice(-20, 10), '0123456789', 'buffer slice range correct');
assert.equal(buf.slice(-20, -10), '', 'buffer slice range correct');
assert.equal(buf.slice(0, -1), '012345678', 'buffer slice range correct');
assert.equal(buf.slice(2, -2), '234567', 'buffer slice range correct');
assert.equal(buf.slice(0, 65536), '0123456789', 'buffer slice range correct');
assert.equal(buf.slice(65536, 0), '', 'buffer slice range correct');
let sliceTest = true;
for (var i = 0, s = buf.toString(); i < buf.length; ++i) {
if (buf.slice(-i) != s.slice(-i)) sliceTest = false;
if (buf.slice(0, -i) != s.slice(0, -i)) sliceTest = false;
}
assert.ok(sliceTest, 'buffer.slice should be consistent');
// Make sure modifying a sliced buffer, affects original and vice versa
b.fill(0);
let sliced = b.slice(0, 10);
let babyslice = sliced.slice(0, 5);
for (let i = 0; i < sliced.length; i++)
sliced[i] = 'jetpack'.charAt(i);
compareBuffers(assert, b, sliced,
'modifying sliced buffer affects original');
compareBuffers(assert, b, babyslice,
'modifying sliced buffer affects child-sliced buffer');
for (let i = 0; i < sliced.length; i++)
b[i] = 'odinmonkey'.charAt(i);
compareBuffers(assert, b, sliced,
'modifying original buffer affects sliced');
compareBuffers(assert, b, babyslice,
'modifying original buffer affects grandchild sliced buffer');
};
exports.testSlicingParents = function (assert) {
let root = Buffer(5);
let child = root.slice(0, 4);
let grandchild = child.slice(0, 3);
assert.equal(root.parent, undefined, 'a new buffer should not have a parent');
// make sure a zero length slice doesn't set the .parent attribute
assert.equal(root.slice(0,0).parent, undefined,
'0-length slice should not have a parent');
assert.equal(child.parent, root,
'a valid slice\'s parent should be the original buffer (child)');
assert.equal(grandchild.parent, root,
'a valid slice\'s parent should be the original buffer (grandchild)');
};
exports.testIsBuffer = function (assert) {
let buffer = new Buffer('content', 'utf8');
assert.ok(Buffer.isBuffer(buffer), 'isBuffer truthy on buffers');
assert.ok(!Buffer.isBuffer({}), 'isBuffer falsy on objects');
assert.ok(!Buffer.isBuffer(new Uint8Array()),
'isBuffer falsy on Uint8Array');
assert.ok(Buffer.isBuffer(buffer.slice(0)), 'Buffer#slice should be a new buffer');
};
exports.testBufferConcat = function (assert) {
let zero = [];
let one = [ new Buffer('asdf') ];
let long = [];
for (let i = 0; i < 10; i++) long.push(new Buffer('asdf'));
let flatZero = Buffer.concat(zero);
let flatOne = Buffer.concat(one);
let flatLong = Buffer.concat(long);
let flatLongLen = Buffer.concat(long, 40);
assert.equal(flatZero.length, 0);
assert.equal(flatOne.toString(), 'asdf');
assert.equal(flatOne, one[0]);
assert.ok(flatLong.toString(), (new Array(10+1).join('asdf')));
assert.equal(flatLongLen.toString(), (new Array(10+1).join('asdf')));
};
exports.testBufferByteLength = function (assert) {
let str = '\u00bd + \u00bc = \u00be';
assert.equal(Buffer.byteLength(str), 12,
'correct byteLength of string');
assert.equal(14, Buffer.byteLength('Il était tué'));
assert.equal(14, Buffer.byteLength('Il était tué', 'utf8'));
// We do not currently support these encodings
/*
['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
assert.equal(24, Buffer.byteLength('Il était tué', encoding));
});
assert.equal(12, Buffer.byteLength('Il était tué', 'ascii'));
assert.equal(12, Buffer.byteLength('Il était tué', 'binary'));
*/
};
exports.testTextEncoderDecoder = function (assert) {
@ -34,57 +489,78 @@ exports.testTextEncoderDecoder = function (assert) {
assert.ok(TextDecoder, 'TextDecoder exists');
};
// List of supported encodings taken from:
// http://mxr.mozilla.org/mozilla-central/source/dom/encoding/labelsencodings.properties
const ENCODINGS = { "unicode-1-1-utf-8": 1, "utf-8": 1, "utf8": 1,
"866": 1, "cp866": 1, "csibm866": 1, "ibm866": 1, "csisolatin2": 1,
"iso-8859-2": 1, "iso-ir-101": 1, "iso8859-2": 1, "iso88592": 1,
"iso_8859-2": 1, "iso_8859-2:1987": 1, "l2": 1, "latin2": 1, "csisolatin3": 1,
"iso-8859-3": 1, "iso-ir-109": 1, "iso8859-3": 1, "iso88593": 1,
"iso_8859-3": 1, "iso_8859-3:1988": 1, "l3": 1, "latin3": 1, "csisolatin4": 1,
"iso-8859-4": 1, "iso-ir-110": 1, "iso8859-4": 1, "iso88594": 1,
"iso_8859-4": 1, "iso_8859-4:1988": 1, "l4": 1, "latin4": 1,
"csisolatincyrillic": 1, "cyrillic": 1, "iso-8859-5": 1, "iso-ir-144": 1,
"iso8859-5": 1, "iso88595": 1, "iso_8859-5": 1, "iso_8859-5:1988": 1,
"arabic": 1, "asmo-708": 1, "csiso88596e": 1, "csiso88596i": 1,
"csisolatinarabic": 1, "ecma-114": 1, "iso-8859-6": 1, "iso-8859-6-e": 1,
"iso-8859-6-i": 1, "iso-ir-127": 1, "iso8859-6": 1, "iso88596": 1,
"iso_8859-6": 1, "iso_8859-6:1987": 1, "csisolatingreek": 1, "ecma-118": 1,
"elot_928": 1, "greek": 1, "greek8": 1, "iso-8859-7": 1, "iso-ir-126": 1,
"iso8859-7": 1, "iso88597": 1, "iso_8859-7": 1, "iso_8859-7:1987": 1,
"sun_eu_greek": 1, "csiso88598e": 1, "csisolatinhebrew": 1, "hebrew": 1,
"iso-8859-8": 1, "iso-8859-8-e": 1, "iso-ir-138": 1, "iso8859-8": 1,
"iso88598": 1, "iso_8859-8": 1, "iso_8859-8:1988": 1, "visual": 1,
"csiso88598i": 1, "iso-8859-8-i": 1, "logical": 1, "csisolatin6": 1,
"iso-8859-10": 1, "iso-ir-157": 1, "iso8859-10": 1, "iso885910": 1,
"l6": 1, "latin6": 1, "iso-8859-13": 1, "iso8859-13": 1, "iso885913": 1,
"iso-8859-14": 1, "iso8859-14": 1, "iso885914": 1, "csisolatin9": 1,
"iso-8859-15": 1, "iso8859-15": 1, "iso885915": 1, "iso_8859-15": 1,
"l9": 1, "iso-8859-16": 1, "cskoi8r": 1, "koi": 1, "koi8": 1, "koi8-r": 1,
"koi8_r": 1, "koi8-u": 1, "csmacintosh": 1, "mac": 1, "macintosh": 1,
"x-mac-roman": 1, "dos-874": 1, "iso-8859-11": 1, "iso8859-11": 1,
"iso885911": 1, "tis-620": 1, "windows-874": 1, "cp1250": 1,
"windows-1250": 1, "x-cp1250": 1, "cp1251": 1, "windows-1251": 1,
"x-cp1251": 1, "ansi_x3.4-1968": 1, "ascii": 1, "cp1252": 1, "cp819": 1,
"csisolatin1": 1, "ibm819": 1, "iso-8859-1": 1, "iso-ir-100": 1,
"iso8859-1": 1, "iso88591": 1, "iso_8859-1": 1, "iso_8859-1:1987": 1,
"l1": 1, "latin1": 1, "us-ascii": 1, "windows-1252": 1, "x-cp1252": 1,
"cp1253": 1, "windows-1253": 1, "x-cp1253": 1, "cp1254": 1, "csisolatin5": 1,
"iso-8859-9": 1, "iso-ir-148": 1, "iso8859-9": 1, "iso88599": 1,
"iso_8859-9": 1, "iso_8859-9:1989": 1, "l5": 1, "latin5": 1,
"windows-1254": 1, "x-cp1254": 1, "cp1255": 1, "windows-1255": 1,
"x-cp1255": 1, "cp1256": 1, "windows-1256": 1, "x-cp1256": 1, "cp1257": 1,
"windows-1257": 1, "x-cp1257": 1, "cp1258": 1, "windows-1258": 1,
"x-cp1258": 1, "x-mac-cyrillic": 1, "x-mac-ukrainian": 1, "chinese": 1,
"csgb2312": 1, "csiso58gb231280": 1, "gb2312": 1, "gb_2312": 1,
"gb_2312-80": 1, "gbk": 1, "iso-ir-58": 1, "x-gbk": 1, "gb18030": 1,
"hz-gb-2312": 1, "big5": 1, "big5-hkscs": 1, "cn-big5": 1, "csbig5": 1,
"x-x-big5": 1, "cseucpkdfmtjapanese": 1, "euc-jp": 1, "x-euc-jp": 1,
"csiso2022jp": 1, "iso-2022-jp": 1, "csshiftjis": 1, "ms_kanji": 1,
"shift-jis": 1, "shift_jis": 1, "sjis": 1, "windows-31j": 1, "x-sjis": 1,
"cseuckr": 1, "csksc56011987": 1, "euc-kr": 1, "iso-ir-149": 1, "korean": 1,
"ks_c_5601-1987": 1, "ks_c_5601-1989": 1, "ksc5601": 1, "ksc_5601": 1,
"windows-949": 1, "csiso2022kr": 1, "iso-2022-kr": 1, "utf-16": 1,
"utf-16le": 1, "utf-16be": 1, "x-user-defined": 1 };
exports.testOverflowedBuffers = function (assert) {
assert.throws(function() {
new Buffer(0xFFFFFFFF);
}, RangeError, 'correctly throws buffer overflow');
assert.throws(function() {
new Buffer(0xFFFFFFFFF);
}, RangeError, 'correctly throws buffer overflow');
assert.throws(function() {
var buf = new Buffer(8);
buf.readFloatLE(0xffffffff);
}, RangeError, 'correctly throws buffer overflow with readFloatLE');
assert.throws(function() {
var buf = new Buffer(8);
buf.writeFloatLE(0.0, 0xffffffff);
}, RangeError, 'correctly throws buffer overflow with writeFloatLE');
//ensure negative values can't get past offset
assert.throws(function() {
var buf = new Buffer(8);
buf.readFloatLE(-1);
}, RangeError, 'correctly throws with readFloatLE negative values');
assert.throws(function() {
var buf = new Buffer(8);
buf.writeFloatLE(0.0, -1);
}, RangeError, 'correctly throws with writeFloatLE with negative values');
assert.throws(function() {
var buf = new Buffer(8);
buf.readFloatLE(-1);
}, RangeError, 'correctly throws with readFloatLE with negative values');
};
exports.testReadWriteDataTypeErrors = function (assert) {
var buf = new Buffer(0);
assert.throws(function() { buf.readUInt8(0); }, RangeError,
'readUInt8(0) throws');
assert.throws(function() { buf.readInt8(0); }, RangeError,
'readInt8(0) throws');
[16, 32].forEach(function(bits) {
var buf = new Buffer(bits / 8 - 1);
assert.throws(function() { buf['readUInt' + bits + 'BE'](0); },
RangeError,
'readUInt' + bits + 'BE');
assert.throws(function() { buf['readUInt' + bits + 'LE'](0); },
RangeError,
'readUInt' + bits + 'LE');
assert.throws(function() { buf['readInt' + bits + 'BE'](0); },
RangeError,
'readInt' + bits + 'BE()');
assert.throws(function() { buf['readInt' + bits + 'LE'](0); },
RangeError,
'readInt' + bits + 'LE()');
});
};
safeMerge(exports, require('./buffers/test-write-types'));
safeMerge(exports, require('./buffers/test-read-types'));
function compareBuffers (assert, buf1, buf2, message) {
let status = true;
for (let i = 0; i < Math.min(buf1.length, buf2.length); i++) {
if (buf1[i] !== buf2[i])
status = false;
}
assert.ok(status, 'buffer successfully copied: ' + message);
}
require('sdk/test').run(exports);

View File

@ -5,6 +5,7 @@
"use strict";
const { Loader } = require('sdk/content/loader');
const self = require("sdk/self");
const fixtures = require("./fixtures");
exports['test:contentURL'] = function(assert) {
let loader = Loader(),
@ -172,7 +173,7 @@ exports['test:contentScript'] = function(assert) {
};
exports['test:contentScriptFile'] = function(assert) {
let loader = Loader(), value, uri = self.data.url("test-content-loader.js");
let loader = Loader(), value, uri = fixtures.url("test-content-loader.js");
assert.equal(
null,
loader.contentScriptFile,

View File

@ -7,7 +7,7 @@ const { create: makeFrame } = require("sdk/frame/utils");
const { window } = require("sdk/addon/window");
const { Loader } = require('sdk/test/loader');
const { URL } = require("sdk/url");
const testURI = require("sdk/self").data.url("test.html");
const testURI = require("./fixtures").url("test.html");
const testHost = URL(testURI).scheme + '://' + URL(testURI).host;
/*

View File

@ -6,6 +6,7 @@
const { Cc, Ci } = require('chrome');
const { Symbiont } = require('sdk/content/symbiont');
const self = require('sdk/self');
const fixtures = require("./fixtures");
const { close } = require('sdk/window/helpers');
const app = require("sdk/system/xul-app");
@ -27,7 +28,7 @@ function makeWindow() {
exports['test:constructing symbiont && validating API'] = function(assert) {
let contentScript = ["1;", "2;"];
let contentScriptFile = self.data.url("test-content-symbiont.js");
let contentScriptFile = fixtures.url("test-content-symbiont.js");
// We can avoid passing a `frame` argument. Symbiont will create one
// by using HiddenFrame module
@ -75,6 +76,8 @@ exports["test:communication with worker global scope"] = function(assert, done)
let window = makeWindow();
let contentSymbiont;
console.log(window)
function onMessage1(message) {
assert.equal(message, 1, "Program gets message via onMessage.");
contentSymbiont.removeListener('message', onMessage1);
@ -154,33 +157,4 @@ exports["test:document element present on 'start'"] = function(assert, done) {
});
};
exports["test:direct communication with trusted document"] = function(assert, done) {
let worker = Symbiont({
contentURL: require("sdk/self").data.url("test-trusted-document.html")
});
worker.port.on('document-to-addon', function (arg) {
assert.equal(arg, "ok", "Received an event from the document");
worker.destroy();
done();
});
worker.port.emit('addon-to-document', 'ok');
};
exports["test:`addon` is not available when a content script is set"] = function(assert, done) {
let worker = Symbiont({
contentURL: require("sdk/self").data.url("test-trusted-document.html"),
contentScript: "new " + function ContentScriptScope() {
self.port.emit("cs-to-addon", "addon" in unsafeWindow);
}
});
worker.port.on('cs-to-addon', function (hasAddon) {
assert.equal(hasAddon, false,
"`addon` is not available");
worker.destroy();
done();
});
};
require("test").run(exports);

View File

@ -21,6 +21,7 @@ const OVERFLOW_MENU_CLASS = "addon-content-menu-overflow-menu";
const OVERFLOW_POPUP_CLASS = "addon-content-menu-overflow-popup";
const TEST_DOC_URL = module.uri.replace(/\.js$/, ".html");
const data = require("./fixtures");
// Tests that when present the separator is placed before the separator from
// the old context-menu module
@ -894,7 +895,7 @@ exports.testContentScriptFile = function (assert, done) {
// But accept files from data folder
let item = new loader.cm.Item({
label: "item",
contentScriptFile: require("sdk/self").data.url("test-context-menu.js")
contentScriptFile: data.url("test-context-menu.js")
});
test.showMenu(null, function (popup) {
@ -2669,7 +2670,7 @@ exports.testItemImage = function (assert, done) {
let test = new TestHelper(assert, done);
let loader = test.newLoader();
let imageURL = require("sdk/self").data.url("moz_favicon.ico");
let imageURL = data.url("moz_favicon.ico");
let item = new loader.cm.Item({ label: "item", image: imageURL });
let menu = new loader.cm.Menu({ label: "menu", image: imageURL, items: [
loader.cm.Item({ label: "subitem" })
@ -2680,7 +2681,7 @@ exports.testItemImage = function (assert, done) {
test.showMenu(null, function (popup) {
test.checkMenu([item, menu], [], []);
let imageURL2 = require("sdk/self").data.url("dummy.ico");
let imageURL2 = data.url("dummy.ico");
item.image = imageURL2;
menu.image = imageURL2;
assert.equal(item.image, imageURL2, "Should have set the image correctly");
@ -2701,7 +2702,7 @@ exports.testItemImage = function (assert, done) {
exports.testItemImageValidURL = function (assert, done) {
let test = new TestHelper(assert, done);
let loader = test.newLoader();
assert.throws(function(){
new loader.cm.Item({
label: "item 1",
@ -2725,8 +2726,8 @@ exports.testItemImageValidURL = function (assert, done) {
})
}, /Image URL validation failed/
);
let imageURL = require("sdk/self").data.url("moz_favicon.ico");
let imageURL = data.url("moz_favicon.ico");
let item4 = new loader.cm.Item({ label: "item 4", image: imageURL });
let item5 = new loader.cm.Item({ label: "item 5", image: null });
let item6 = new loader.cm.Item({ label: "item 6", image: undefined });
@ -3228,7 +3229,7 @@ TestHelper.prototype = {
},
// Asserts that the context menu looks OK given the arguments. presentItems
// are items that have been added to the menu. absentItems are items that
// are items that have been added to the menu. absentItems are items that
// shouldn't match the current context. removedItems are items that have been
// removed from the menu.
checkMenu: function (presentItems, absentItems, removedItems) {

View File

@ -36,7 +36,7 @@ exports['test syntax errors'] = function(assert) {
assert.equal(error.name, "SyntaxError", "throws syntax error");
assert.equal(error.fileName.split("/").pop(), "error.js",
"Error contains filename");
assert.equal(error.lineNumber, 11, "error is on line 11")
assert.equal(error.lineNumber, 11, "error is on line 11");
let stack = parseStack(error.stack);
assert.equal(stack.pop().fileName, uri + "error.js",
@ -147,7 +147,41 @@ exports['test early errors in module'] = function(assert) {
} finally {
unload(loader);
}
}
};
exports['test require json'] = function (assert) {
let data = require('./fixtures/loader/json/manifest.json');
assert.equal(data.name, 'Jetpack Loader Test', 'loads json with strings');
assert.equal(data.version, '1.0.1', 'loads json with strings');
assert.equal(data.dependencies.async, '*', 'loads json with objects');
assert.equal(data.dependencies.underscore, '*', 'loads json with objects');
assert.equal(data.contributors.length, 4, 'loads json with arrays');
assert.ok(Array.isArray(data.contributors), 'loads json with arrays');
data.version = '2.0.0';
let newdata = require('./fixtures/loader/json/manifest.json');
assert.equal(newdata.version, '2.0.0',
'JSON objects returned should be cached and the same instance');
try {
require('./fixtures/loader/json/invalid.json');
assert.fail('Error not thrown when loading invalid json');
} catch (err) {
assert.ok(err, 'error thrown when loading invalid json');
assert.ok(/JSON\.parse/.test(err.message),
'should thrown an error from JSON.parse, not attempt to load .json.js');
}
// Try again to ensure an empty module isn't loaded from cache
try {
require('./fixtures/loader/json/invalid.json');
assert.fail('Error not thrown when loading invalid json a second time');
} catch (err) {
assert.ok(err,
'error thrown when loading invalid json a second time');
assert.ok(/JSON\.parse/.test(err.message),
'should thrown an error from JSON.parse a second time, not attempt to load .json.js');
}
};
exports['test setting metadata for newly created sandboxes'] = function(assert) {
let addonID = 'random-addon-id';
@ -165,6 +199,23 @@ exports['test setting metadata for newly created sandboxes'] = function(assert)
}
let program = main(loader, 'main');
}
};
exports['test require .json, .json.js'] = function (assert) {
let testjson = require('./fixtures/loader/json/test.json');
assert.equal(testjson.filename, 'test.json',
'require("./x.json") should load x.json, not x.json.js');
let nodotjson = require('./fixtures/loader/json/nodotjson.json');
assert.equal(nodotjson.filename, 'nodotjson.json.js',
'require("./x.json") should load x.json.js when x.json does not exist');
nodotjson.data.prop = 'hydralisk';
// require('nodotjson.json') and require('nodotjson.json.js')
// should resolve to the same file
let nodotjsonjs = require('./fixtures/loader/json/nodotjson.json.js');
assert.equal(nodotjsonjs.data.prop, 'hydralisk',
'js modules are cached whether access via .json.js or .json');
};
require('test').run(exports);

View File

@ -5,7 +5,7 @@
"use strict";
const { readURI, readURISync } = require("sdk/net/url");
const { data } = require("sdk/self");
const data = require("./fixtures");
const utf8text = "Hello, ゼロ!";
const latin1text = "Hello, ゼロ!";

View File

@ -13,15 +13,18 @@ const { open, getFrames, getMostRecentBrowserWindow } = require('sdk/window/util
const windowUtils = require('sdk/deprecated/window-utils');
const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils');
const xulApp = require("sdk/system/xul-app");
const { data, isPrivateBrowsingSupported } = require('sdk/self');
const { isPrivateBrowsingSupported } = require('sdk/self');
const { isPrivate } = require('sdk/private-browsing');
const { openWebpage } = require('./private-browsing/helper');
const { isTabPBSupported, isWindowPBSupported, isGlobalPBSupported } = require('sdk/private-browsing/utils');
const promise = require("sdk/core/promise");
const { pb } = require('./private-browsing/helper');
const { URL } = require("sdk/url");
const testPageURI = require("sdk/self").data.url("test.html");
const { waitUntil } = require("sdk/test/utils");
const data = require("./fixtures");
const testPageURI = data.url("test.html");
// The following adds Debugger constructor to the global namespace.
const { addDebuggerToGlobal } =
@ -311,7 +314,7 @@ exports.testHistory = function(assert, done) {
// We need a valid url in order to have a working History API.
// (i.e do not work on data: or about: pages)
// Test bug 679054.
let url = require("sdk/self").data.url("test-page-mod.html");
let url = data.url("test-page-mod.html");
let callbackDone = null;
testPageMod(assert, done, url, [{
include: url,
@ -691,8 +694,7 @@ exports.testPageModCss = function(assert, done) {
'data:text/html;charset=utf-8,<div style="background: silver">css test</div>', [{
include: ["*", "data:*"],
contentStyle: "div { height: 100px; }",
contentStyleFile:
require("sdk/self").data.url("pagemod-css-include-file.css")
contentStyleFile: data.url("pagemod-css-include-file.css")
}],
function(win, done) {
let div = win.document.querySelector("div");

View File

@ -8,7 +8,8 @@ const { Loader } = require('sdk/test/loader');
const Pages = require("sdk/page-worker");
const Page = Pages.Page;
const { URL } = require("sdk/url");
const testURI = require("sdk/self").data.url("test.html");
const fixtures = require("./fixtures");
const testURI = fixtures.url("test.html");
const ERR_DESTROYED =
"Couldn't find the worker to receive this message. " +
@ -264,8 +265,8 @@ exports.testLoadContentPage = function(assert, done) {
return done();
assert[msg].apply(assert, message);
},
contentURL: require("sdk/self").data.url("test-page-worker.html"),
contentScriptFile: require("sdk/self").data.url("test-page-worker.js"),
contentURL: fixtures.url("test-page-worker.html"),
contentScriptFile: fixtures.url("test-page-worker.js"),
contentScriptWhen: "ready"
});
}

View File

@ -22,8 +22,9 @@ const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { getWindow } = require('sdk/panel/window');
const { pb } = require('./private-browsing/helper');
const { URL } = require('sdk/url');
const fixtures = require('./fixtures')
const SVG_URL = self.data.url('mofo_logo.SVG');
const SVG_URL = fixtures.url('mofo_logo.SVG');
const Isolate = fn => '(' + fn + ')()';
function ignorePassingDOMNodeWarning(type, message) {

View File

@ -276,6 +276,21 @@ exports['test promised error handleing'] = function(assert, done) {
})
}
exports['test errors in promise resolution handlers are propagated'] = function(assert, done) {
var expected = Error('Boom');
var { promise, resolve } = defer();
promise.then(function() {
throw expected;
}).then(function() {
return undefined;
}).then(null, function(actual) {
assert.equal(actual, expected, 'rejected as expected');
}).then(done, assert.fail);
resolve({});
}
exports['test return promise form promised'] = function(assert, done) {
var f = promised(function() {
return resolve(17)

View File

@ -10,9 +10,6 @@ const self = require("sdk/self");
const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
exports.testSelf = function(assert) {
var source = self.data.load("test-content-symbiont.js");
assert.ok(source.match(/test-content-symbiont/), "self.data.load() works");
// Likewise, we can't assert anything about the full URL, because that
// depends on self.id . We can only assert that it ends in the right
// thing.

View File

@ -17,7 +17,7 @@ exports["test basic"] = function(assert) {
let type = Date.now().toString(32);
let timesCalled = 0;
function handler(subject, data) { timesCalled++; };
function handler({subject, data}) { timesCalled++; };
events.on(type, handler);
events.emit(type, { data: "yo yo" });
@ -36,6 +36,32 @@ exports["test basic"] = function(assert) {
assert.equal(timesCalled, 2, "handlers added via once are triggered once");
}
exports["test simple argument passing"] = function (assert) {
let type = Date.now().toString(32);
let lastArg;
function handler({data}) { lastArg = data; }
events.on(type, handler);
[true, false, 100, 0, 'a string', ''].forEach(arg => {
events.emit(type, arg);
assert.strictEqual(lastArg, arg + '',
'event emitted for ' + arg + ' has correct data value');
events.emit(type, { data: arg });
assert.strictEqual(lastArg, arg + '',
'event emitted for ' + arg + ' has correct data value when a property on an object');
});
[null, undefined, {}].forEach(arg => {
events.emit(type, arg);
assert.strictEqual(lastArg, null,
'emitting ' + arg + ' gets null data');
});
events.off(type, handler);
};
exports["test error reporting"] = function(assert) {
let { loader, messages } = LoaderWithHookedConsole2(module);
@ -220,7 +246,7 @@ exports["test emit to nsIObserverService observers"] = function(assert) {
assert.equal(lastData, "data again", "event.data is notification data");
nsIObserverService.removeObserver(nsIObserver, "*");
events.emit(topic, { data: "last data" });
assert.equal(timesCalled, 3, "removed observers no longer invoked");
}

View File

@ -11,7 +11,7 @@ module.metadata = {
const { Cu } = require('chrome');
const { Loader } = require('sdk/test/loader');
const { data } = require('sdk/self');
const data = require('./fixtures');
const { open, focus, close } = require('sdk/window/helpers');
const { setTimeout } = require('sdk/timers');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');

View File

@ -15,9 +15,9 @@ const { show, hide } = require('sdk/ui/sidebar/actions');
const { isShowing } = require('sdk/ui/sidebar/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { open, close, focus, promise: windowPromise } = require('sdk/window/helpers');
const { setTimeout } = require('sdk/timers');
const { setTimeout, setImmediate } = require('sdk/timers');
const { isPrivate } = require('sdk/private-browsing');
const { data } = require('sdk/self');
const data = require('./fixtures');
const { URL } = require('sdk/url');
const { once, off, emit } = require('sdk/event/core');
const { defer, all } = require('sdk/core/promise');
@ -251,6 +251,32 @@ exports.testAddonGlobalComplex = function(assert, done) {
show(sidebar);
}
exports.testAddonReady = function(assert, done) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testAddonReady';
let sidebar = Sidebar({
id: testName,
title: testName,
url: data.url('test-sidebar-addon-global.html'),
onReady: function(worker) {
assert.pass('sidebar was attached');
assert.ok(!!worker, 'attach event has worker');
worker.port.on('X', function(msg) {
assert.equal(msg, '123', 'the final message is correct');
sidebar.destroy();
done();
});
worker.port.emit('X', '12');
}
});
show(sidebar);
}
exports.testShowingOneSidebarAfterAnother = function(assert, done) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testShowingOneSidebarAfterAnother';
@ -356,7 +382,7 @@ exports.testRemoteContent = function(assert) {
sidebar.destroy();
}
catch(e) {
assert.ok(/The option "url" must be a valid URI./.test(e), 'remote content is not acceptable');
assert.ok(/The option "url" must be a valid local URI\./.test(e), 'remote content is not acceptable');
}
}
@ -373,7 +399,7 @@ exports.testInvalidURL = function(assert) {
sidebar.destroy();
}
catch(e) {
assert.ok(/The option "url" must be a valid URI./.test(e), 'invalid URIs are not acceptable');
assert.ok(/The option "url" must be a valid local URI\./.test(e), 'invalid URIs are not acceptable');
}
}
@ -389,7 +415,7 @@ exports.testInvalidURLType = function(assert) {
sidebar.destroy();
}
catch(e) {
assert.ok(/The option "url" must be a valid URI./.test(e), 'invalid URIs are not acceptable');
assert.ok(/The option "url" must be a valid local URI\./.test(e), 'invalid URIs are not acceptable');
}
}
@ -461,19 +487,24 @@ exports.testInvalidNullID = function(assert) {
}
}
exports.testInvalidUndefinedID = function(assert) {
exports.testUndefinedID = function(assert) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testInvalidBlankID';
let testName = 'testInvalidUndefinedID';
try {
let sidebar = Sidebar({
title: testName,
url: 'data:text/html;charset=utf-8,'+testName
url: 'data:text/html;charset=utf-8,' + testName
});
assert.fail('a bad sidebar was created..');
assert.ok(sidebar.id, 'an undefined id was accepted, id was creawted: ' + sidebar.id);
assert.ok(getMostRecentBrowserWindow().document.getElementById(makeID(sidebar.id)), 'the sidebar element was found');
sidebar.destroy();
}
catch(e) {
assert.ok(/The option "id" must be a valid alphanumeric id/.test(e), 'invalid ids are not acceptable');
assert.fail('undefined ids are acceptable');
assert.fail(e.message);
}
}
@ -892,6 +923,64 @@ exports.testGCdShowingSidebarsOnUnload = function(assert, done) {
sidebar.show();
}
exports.testDetachEventOnWindowClose = function(assert, done) {
const loader = Loader(module);
const { Sidebar } = loader.require('sdk/ui/sidebar');
const window = getMostRecentBrowserWindow();
let testName = 'testDetachEventOnWindowClose';
let url = 'data:text/html;charset=utf-8,' + testName;
windowPromise(window.OpenBrowserWindow(), 'load').then(focus).then(function(window) {
let sidebar = Sidebar({
id: testName,
title: testName,
url: url,
onAttach: function() {
assert.pass('the attach event is fired');
window.close();
},
onDetach: function() {
assert.pass('the detach event is fired when the window showing it closes');
loader.unload();
done();
}
});
sidebar.show();
}).then(null, assert.fail);
}
exports.testHideEventOnWindowClose = function(assert, done) {
const loader = Loader(module);
const { Sidebar } = loader.require('sdk/ui/sidebar');
const window = getMostRecentBrowserWindow();
let testName = 'testDetachEventOnWindowClose';
let url = 'data:text/html;charset=utf-8,' + testName;
windowPromise(window.OpenBrowserWindow(), 'load').then(focus).then(function(window) {
let sidebar = Sidebar({
id: testName,
title: testName,
url: url,
onAttach: function() {
assert.pass('the attach event is fired');
window.close();
},
onHide: function() {
assert.pass('the hide event is fired when the window showing it closes');
loader.unload();
done();
}
});
sidebar.show();
}).then(null, assert.fail);
}
exports.testGCdHiddenSidebarsOnUnload = function(assert, done) {
const loader = Loader(module);
const { Sidebar } = loader.require('sdk/ui/sidebar');
@ -1078,6 +1167,35 @@ exports.testTwoSidebarsWithSameTitleAndURL = function(assert) {
sidebar2.destroy();
}
exports.testChangingURLBackToOriginalValue = function(assert) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testChangingURLBackToOriginalValue';
let title = testName;
let url = 'data:text/html;charset=utf-8,' + testName;
let count = 0;
let sidebar = Sidebar({
id: testName,
title: title,
url: url
});
sidebar.url = url + 2;
assert.equal(sidebar.url, url + 2, 'the sidebar.url is correct');
sidebar.url = url;
assert.equal(sidebar.url, url, 'the sidebar.url is correct');
sidebar.title = 'foo';
assert.equal(sidebar.title, 'foo', 'the sidebar.title is correct');
sidebar.title = title;
assert.equal(sidebar.title, title, 'the sidebar.title is correct');
sidebar.destroy();
assert.pass('Changing values back to originals works');
}
exports.testShowToOpenXToClose = function(assert, done) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testShowToOpenXToClose';
@ -1181,14 +1299,17 @@ exports.testEventListeners = function(assert, done) {
let constructorOnShow = defer();
let constructorOnHide = defer();
let constructorOnAttach = defer();
let constructorOnReady = defer();
let onShow = defer();
let onHide = defer();
let onAttach = defer();
let onReady = defer();
let onceShow = defer();
let onceHide = defer();
let onceAttach = defer();
let onceReady = defer();
function testThis() {
assert(this, sidebar, '`this` is correct');
@ -1208,6 +1329,11 @@ exports.testEventListeners = function(assert, done) {
eventListenerOrder.push('onAttach');
constructorOnAttach.resolve();
},
onReady: function() {
assert.equal(this, sidebar, '`this` is correct in onReady');
eventListenerOrder.push('onReady');
constructorOnReady.resolve();
},
onHide: function() {
assert.equal(this, sidebar, '`this` is correct in onHide');
eventListenerOrder.push('onHide');
@ -1225,6 +1351,11 @@ exports.testEventListeners = function(assert, done) {
eventListenerOrder.push('once attach');
onceAttach.resolve();
});
sidebar.once('ready', function() {
assert.equal(this, sidebar, '`this` is correct in once ready');
eventListenerOrder.push('once ready');
onceReady.resolve();
});
sidebar.once('hide', function() {
assert.equal(this, sidebar, '`this` is correct in once hide');
eventListenerOrder.push('once hide');
@ -1243,6 +1374,11 @@ exports.testEventListeners = function(assert, done) {
eventListenerOrder.push('on attach');
onAttach.resolve();
});
sidebar.on('ready', function() {
assert.equal(this, sidebar, '`this` is correct in on ready');
eventListenerOrder.push('on ready');
onReady.resolve();
});
sidebar.on('hide', function() {
assert.equal(this, sidebar, '`this` is correct in on hide');
eventListenerOrder.push('on hide');
@ -1251,17 +1387,23 @@ exports.testEventListeners = function(assert, done) {
all(constructorOnShow.promise,
constructorOnAttach.promise,
constructorOnReady.promise,
constructorOnHide.promise,
onceShow.promise,
onceAttach.promise,
onceReady.promise,
onceHide.promise,
onShow.promise,
onAttach.promise,
onReady.promise,
onHide.promise).then(function() {
assert.equal(eventListenerOrder.join(), [
'onAttach',
'once attach',
'on attach',
'onReady',
'once ready',
'on ready',
'onShow',
'once show',
'on show',
@ -1275,6 +1417,58 @@ exports.testEventListeners = function(assert, done) {
sidebar.show();
}
// For more information see Bug 920780
exports.testAttachDoesNotEmitWhenShown = function(assert, done) {
const { Sidebar } = require('sdk/ui/sidebar');
let testName = 'testSidebarLeakCheckUnloadAfterAttach';
let count = 0;
let sidebar = Sidebar({
id: testName,
title: testName,
url: 'data:text/html;charset=utf-8,'+testName,
onAttach: function() {
if (count > 2) {
assert.fail('sidebar was attached again..');
}
else {
assert.pass('sidebar was attached ' + count + ' time(s)');
}
if (++count == 1) {
setTimeout(function() {
let shown = false;
let endShownTest = false;
sidebar.once('show', function() {
assert.pass('shown was emitted');
shown = !endShownTest && true;
});
sidebar.show().then(function() {
assert.pass('calling hide');
sidebar.hide();
}).then(function() {
endShownTest = true;
setTimeout(function() {
sidebar.show().then(function() {
assert.ok(!shown, 'show did not emit');
sidebar.hide().then(function() {
sidebar.destroy();
done();
}).then(null, assert.fail);
})
})
}).then(null, assert.fail);
});
}
}
});
sidebar.show();
}
// If the module doesn't support the app we're being run in, require() will
// throw. In that case, remove all tests above from exports, and add one dummy
// test that passes.

View File

@ -18,6 +18,7 @@ const self = require("sdk/self");
const windowUtils = require("sdk/deprecated/window-utils");
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { close } = require("sdk/window/helpers");
const fixtures = require("./fixtures");
let jetpackID = "testID";
try {
@ -243,7 +244,7 @@ exports.testConstructor = function(assert, done) {
tests.push(function testImageURLWidget() testSingleWidget({
id: "image",
label: "image url widget",
contentURL: require("sdk/self").data.url("test.html"),
contentURL: fixtures.url("test.html"),
contentScript: "self.postMessage({title: document.title, " +
"tag: document.body.firstElementChild.tagName, " +
"content: document.body.firstElementChild.innerHTML});",
@ -261,7 +262,7 @@ exports.testConstructor = function(assert, done) {
tests.push(function testWebURIWidget() testSingleWidget({
id: "web",
label: "web uri widget",
contentURL: require("sdk/self").data.url("test.html"),
contentURL: fixtures.url("test.html"),
contentScript: "self.postMessage({title: document.title, " +
"tag: document.body.firstElementChild.tagName, " +
"content: document.body.firstElementChild.innerHTML});",
@ -324,7 +325,7 @@ exports.testConstructor = function(assert, done) {
tests.push(function testOnclickEventImage() testSingleWidget({
id: "click",
label: "click test widget - image",
contentURL: require("sdk/self").data.url("moz_favicon.ico"),
contentURL: fixtures.url("moz_favicon.ico"),
contentScript: "var evt = new MouseEvent('click'); " +
"document.body.firstElementChild.dispatchEvent(evt);",
contentScriptWhen: "end",
@ -339,7 +340,7 @@ exports.testConstructor = function(assert, done) {
tests.push(function testOnmouseoverEventImage() testSingleWidget({
id: "mouseover",
label: "mouseover test widget - image",
contentURL: require("sdk/self").data.url("moz_favicon.ico"),
contentURL: fixtures.url("moz_favicon.ico"),
contentScript: "var evt = new MouseEvent('mouseover');" +
"document.body.firstElementChild.dispatchEvent(evt);",
contentScriptWhen: "end",
@ -354,7 +355,7 @@ exports.testConstructor = function(assert, done) {
tests.push(function testOnmouseoutEventImage() testSingleWidget({
id: "mouseout",
label: "mouseout test widget - image",
contentURL: require("sdk/self").data.url("moz_favicon.ico"),
contentURL: fixtures.url("moz_favicon.ico"),
contentScript: "var evt = new MouseEvent('mouseout'); " +
"document.body.firstElementChild.dispatchEvent(evt);",
contentScriptWhen: "end",
@ -1034,7 +1035,7 @@ exports.testPostMessageOnLocationChange = function(assert, done) {
exports.testSVGWidget = function(assert, done) {
// use of capital SVG here is intended, that was failing..
let SVG_URL = self.data.url("mofo_logo.SVG");
let SVG_URL = fixtures.url("mofo_logo.SVG");
let widget = require("sdk/widget").Widget({
id: "mozilla-svg-logo",

View File

@ -13,7 +13,7 @@ const windowUtils = require("sdk/deprecated/window-utils");
const timer = require("sdk/timers");
const { Cc, Ci } = require("chrome");
const { Loader } = require("sdk/test/loader");
const { open, getFrames, getWindowTitle, onFocus } = require('sdk/window/utils');
const { open, getFrames, getWindowTitle, onFocus, windows } = require('sdk/window/utils');
const { close } = require('sdk/window/helpers');
const { fromIterator: toArray } = require('sdk/util/array');
@ -297,4 +297,29 @@ exports.testWindowIterator = function(assert, done) {
}, false);
};
exports.testIgnoreClosingWindow = function(assert, done) {
assert.equal(windows().length, 1, "Only one window open");
// make a new window
let window = makeEmptyWindow();
assert.equal(windows().length, 2, "Two windows open");
window.addEventListener("load", function onload() {
window.addEventListener("load", onload, false);
assert.equal(windows().length, 2, "Two windows open");
// Wait for the window unload before ending test
let checked = false;
close(window).then(function() {
assert.ok(checked, 'the test is finished');
}).then(done, assert.fail)
assert.equal(windows().length, 1, "Only one window open");
checked = true;
}, false);
};
require("test").run(exports);

View File

@ -5,8 +5,9 @@
const { XMLHttpRequest } = require('sdk/net/xhr');
const { LoaderWithHookedConsole } = require('sdk/test/loader');
const { data } = require('sdk/self');
const { set: setPref } = require("sdk/preferences/service");
const data = require("./fixtures");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
exports.testAPIExtension = function(assert) {

View File

@ -5,7 +5,7 @@
"use strict"
function debug(str) {
//dump("-*- ContentPermissionPrompt: " + str + "\n");
//dump("-*- ContentPermissionPrompt: " + s + "\n");
}
const Ci = Components.interfaces;
@ -13,14 +13,11 @@ const Cr = Components.results;
const Cu = Components.utils;
const Cc = Components.classes;
const PROMPT_FOR_UNKNOWN = ["audio-capture",
"desktop-notification",
"geolocation",
"video-capture"];
const PROMPT_FOR_UNKNOWN = ["geolocation", "desktop-notification",
"audio-capture"];
// Due to privary issue, permission requests like GetUserMedia should prompt
// every time instead of providing session persistence.
const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"];
const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
const PERMISSION_NO_SESSION = ["audio-capture"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -44,21 +41,7 @@ XPCOMUtils.defineLazyServiceGetter(this,
"@mozilla.org/telephony/audiomanager;1",
"nsIAudioManager");
/**
* aTypesInfo is an array of {permission, access, action, deny} which keeps
* the information of each permission. This arrary is initialized in
* ContentPermissionPrompt.prompt and used among functions.
*
* aTypesInfo[].permission : permission name
* aTypesInfo[].access : permission name + request.access
* aTypesInfo[].action : the default action of this permission
* aTypesInfo[].deny : true if security manager denied this app's origin
* principal.
* Note:
* aTypesInfo[].permission will be sent to prompt only when
* aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
*/
function rememberPermission(aTypesInfo, aPrincipal, aSession)
function rememberPermission(aPermission, aPrincipal, aSession)
{
function convertPermToAllow(aPerm, aPrincipal)
{
@ -66,13 +49,12 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
if (type == Ci.nsIPermissionManager.PROMPT_ACTION ||
(type == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0)) {
debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
PROMPT_FOR_UNKNOWN.indexOf(aPermission) >= 0)) {
if (!aSession) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION);
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
} else if (PERMISSION_NO_SESSION.indexOf(aPermission) < 0) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION,
@ -81,18 +63,14 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
}
}
for (let i in aTypesInfo) {
// Expand the permission to see if we have multiple access properties
// to convert
let perm = aTypesInfo[i].permission;
let access = PermissionsTable[perm].access;
if (access) {
for (let idx in access) {
convertPermToAllow(perm + "-" + access[idx], aPrincipal);
}
} else {
convertPermToAllow(perm, aPrincipal);
// Expand the permission to see if we have multiple access properties to convert
let access = PermissionsTable[aPermission].access;
if (access) {
for (let idx in access) {
convertPermToAllow(aPermission + "-" + access[idx], aPrincipal);
}
} else {
convertPermToAllow(aPermission, aPrincipal);
}
}
@ -100,63 +78,23 @@ function ContentPermissionPrompt() {}
ContentPermissionPrompt.prototype = {
handleExistingPermission: function handleExistingPermission(request,
typesInfo) {
typesInfo.forEach(function(type) {
type.action =
Services.perms.testExactPermissionFromPrincipal(request.principal,
type.access);
});
// If all permissions are allowed already, call allow() without prompting.
let checkAllowPermission = function(type) {
if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION) {
return true;
}
return false;
}
if (typesInfo.every(checkAllowPermission)) {
debug("all permission requests are allowed");
handleExistingPermission: function handleExistingPermission(request) {
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
request.type;
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, access);
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
request.allow();
return true;
}
// If all permissions are DENY_ACTION or UNKNOWN_ACTION, call cancel()
// without prompting.
let checkDenyPermission = function(type) {
if (type.action == Ci.nsIPermissionManager.DENY_ACTION ||
type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
PROMPT_FOR_UNKNOWN.indexOf(type.access) < 0) {
return true;
}
return false;
}
if (typesInfo.every(checkDenyPermission)) {
debug("all permission requests are denied");
if (result == Ci.nsIPermissionManager.DENY_ACTION ||
result == Ci.nsIPermissionManager.UNKNOWN_ACTION && PROMPT_FOR_UNKNOWN.indexOf(access) < 0) {
request.cancel();
return true;
}
return false;
},
// multiple requests should be audio and video
checkMultipleRequest: function checkMultipleRequest(typesInfo) {
if (typesInfo.length == 1) {
return true;
} else if (typesInfo.length > 1) {
let checkIfAllowMultiRequest = function(type) {
return (ALLOW_MULTIPLE_REQUESTS.indexOf(type.access) !== -1);
}
if (typesInfo.every(checkIfAllowMultiRequest)) {
debug("legal multiple requests");
return true;
}
}
return false;
},
handledByApp: function handledByApp(request, typesInfo) {
handledByApp: function handledByApp(request) {
if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
// This should not really happen
@ -168,94 +106,49 @@ ContentPermissionPrompt.prototype = {
.getService(Ci.nsIAppsService);
let app = appsService.getAppByLocalId(request.principal.appId);
// Check each permission if it's denied by permission manager with app's
// URL.
let checkIfDenyAppPrincipal = function(type) {
let url = Services.io.newURI(app.origin, null, null);
let principal = secMan.getAppCodebasePrincipal(url,
request.principal.appId,
/*mozbrowser*/false);
let result = Services.perms.testExactPermissionFromPrincipal(principal,
type.access);
let url = Services.io.newURI(app.origin, null, null);
let principal = secMan.getAppCodebasePrincipal(url, request.principal.appId,
/*mozbrowser*/false);
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
request.type;
let result = Services.perms.testExactPermissionFromPrincipal(principal, access);
if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
result == Ci.nsIPermissionManager.PROMPT_ACTION) {
type.deny = false;
}
return type.deny;
}
if (typesInfo.every(checkIfDenyAppPrincipal)) {
request.cancel();
return true;
if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
result == Ci.nsIPermissionManager.PROMPT_ACTION) {
return false;
}
return false;
request.cancel();
return true;
},
handledByPermissionType: function handledByPermissionType(request, typesInfo) {
for (let i in typesInfo) {
if (permissionSpecificChecker.hasOwnProperty(typesInfo[i].permission) &&
permissionSpecificChecker[typesInfo[i].permission](request)) {
return true;
}
}
return false;
handledByPermissionType: function handledByPermissionType(request) {
return permissionSpecificChecker.hasOwnProperty(request.type)
? permissionSpecificChecker[request.type](request)
: false;
},
_id: 0,
prompt: function(request) {
if (secMan.isSystemPrincipal(request.principal)) {
request.allow();
return;
return true;
}
// Initialize the typesInfo and set the default value.
let typesInfo = [];
let perms = request.types.QueryInterface(Ci.nsIArray);
for (let idx = 0; idx < perms.length; idx++) {
let perm = perms.queryElementAt(idx, Ci.nsIContentPermissionType);
let tmp = {
permission: perm.type,
access: (perm.access && perm.access !== "unused") ?
perm.type + "-" + perm.access : perm.type,
deny: true,
action: Ci.nsIPermissionManager.UNKNOWN_ACTION
};
typesInfo.push(tmp);
}
if (typesInfo.length == 0) {
request.cancel();
return;
}
if(!this.checkMultipleRequest(typesInfo)) {
request.cancel();
return;
}
if (this.handledByApp(request, typesInfo) ||
this.handledByPermissionType(request, typesInfo)) {
if (this.handledByApp(request) ||
this.handledByPermissionType(request)) {
return;
}
// returns true if the request was handled
if (this.handleExistingPermission(request, typesInfo)) {
if (this.handleExistingPermission(request))
return;
}
// prompt PROMPT_ACTION request only.
typesInfo.forEach(function(aType, aIndex) {
if (aType.action != Ci.nsIPermissionManager.PROMPT_ACTION || aType.deny) {
typesInfo.splice(aIndex);
}
});
let frame = request.element;
let requestId = this._id++;
if (!frame) {
this.delegatePrompt(request, requestId, typesInfo);
this.delegatePrompt(request, requestId);
return;
}
@ -270,7 +163,7 @@ ContentPermissionPrompt.prototype = {
if (evt.detail.visible === true)
return;
self.cancelPrompt(request, requestId, typesInfo);
self.cancelPrompt(request, requestId);
cancelRequest();
}
@ -287,7 +180,7 @@ ContentPermissionPrompt.prototype = {
// away but the request is still here.
frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange);
self.delegatePrompt(request, requestId, typesInfo, function onCallback() {
self.delegatePrompt(request, requestId, function onCallback() {
frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange);
});
};
@ -298,17 +191,22 @@ ContentPermissionPrompt.prototype = {
}
},
cancelPrompt: function(request, requestId, typesInfo) {
this.sendToBrowserWindow("cancel-permission-prompt", request, requestId,
typesInfo);
cancelPrompt: function(request, requestId) {
this.sendToBrowserWindow("cancel-permission-prompt", request, requestId);
},
delegatePrompt: function(request, requestId, typesInfo, callback) {
delegatePrompt: function(request, requestId, callback) {
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
request.type;
let principal = request.principal;
this.sendToBrowserWindow("permission-prompt", request, requestId, typesInfo,
function(type, remember) {
this._permission = access;
this._uri = principal.URI.spec;
this._origin = principal.origin;
this.sendToBrowserWindow("permission-prompt", request, requestId, function(type, remember) {
if (type == "permission-allow") {
rememberPermission(typesInfo, request.principal, !remember);
rememberPermission(request.type, principal, !remember);
if (callback) {
callback();
}
@ -316,20 +214,14 @@ ContentPermissionPrompt.prototype = {
return;
}
let addDenyPermission = function(type) {
debug("add " + type.permission +
" to permission manager with DENY_ACTION");
if (remember) {
Services.perms.addFromPrincipal(request.principal, type.access,
Ci.nsIPermissionManager.DENY_ACTION);
} else {
Services.perms.addFromPrincipal(request.principal, type.access,
Ci.nsIPermissionManager.DENY_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION,
0);
}
if (remember) {
Services.perms.addFromPrincipal(principal, access,
Ci.nsIPermissionManager.DENY_ACTION);
} else {
Services.perms.addFromPrincipal(principal, access,
Ci.nsIPermissionManager.DENY_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
}
typesInfo.forEach(addDenyPermission);
if (callback) {
callback();
@ -338,7 +230,7 @@ ContentPermissionPrompt.prototype = {
});
},
sendToBrowserWindow: function(type, request, requestId, typesInfo, callback) {
sendToBrowserWindow: function(type, request, requestId, callback) {
let browser = Services.wm.getMostRecentWindow("navigator:browser");
let content = browser.getContentWindow();
if (!content)
@ -361,15 +253,10 @@ ContentPermissionPrompt.prototype = {
principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
? true
: request.remember;
let permissions = [];
for (let i in typesInfo) {
debug("prompt " + typesInfo[i].permission);
permissions.push(typesInfo[i].permission);
}
let details = {
type: type,
permissions: permissions,
permission: request.type,
id: requestId,
origin: principal.origin,
isApp: isApp,
@ -402,5 +289,6 @@ ContentPermissionPrompt.prototype = {
};
})();
//module initialization
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);

Some files were not shown because too many files have changed in this diff Show More