Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #411 from ochameau/fix688127
Browse files Browse the repository at this point in the history
Bug 688127: Add property to provide JSON set of global variables for initial state of content scripts r=@ochameau
  • Loading branch information
ochameau committed Apr 24, 2012
2 parents 677a214 + 3df59ea commit 0006f26
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 23 deletions.
1 change: 1 addition & 0 deletions doc/dev-guide-source/credits.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ We'd like to thank our many Jetpack project contributors! They include:
* Piotr Zalewa
* [David Guo](https://github.com/dglol)
* [Nils Maier](https://github.com/nmaier)
* [Louis-Rémi Babé](https://github.com/louisremi)
12 changes: 9 additions & 3 deletions doc/dev-guide-source/guides/content-scripts/loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ The constructors for content-script-using objects such as panel and page-mod
define a group of options for loading content scripts:

<pre>
contentScript string, array
contentScriptFile string, array
contentScriptWhen string
contentScript string, array
contentScriptFile string, array
contentScriptWhen string
contentScriptOptions object
</pre>

We have already seen the `contentScript` option, which enables you to pass
Expand Down Expand Up @@ -71,3 +72,8 @@ has been loaded, at the time the
fires.

The default value is "end".

The `contentScriptOptions` is a json that is exposed to content scripts as a read
only value under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
5 changes: 5 additions & 0 deletions packages/addon-kit/docs/page-mod.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,11 @@ Creates a PageMod.
fires

This property is optional and defaults to "end".
@prop [contentScriptOptions] {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.

@prop [contentStyleFile] {string,array}
The local file URLs of stylesheet to load. Content style specified by this
Expand Down
13 changes: 13 additions & 0 deletions packages/addon-kit/docs/page-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ loaded until its `destroy` method is called or the add-on is unloaded.
fires

This property is optional and defaults to "end".
@prop [contentScriptOptions] {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.

@prop [onMessage] {function}
Use this to add a listener to the page worker's `message` event.
Expand Down Expand Up @@ -246,6 +251,14 @@ load.

</api>

<api name="contentScriptOptions">
@property {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.
</api>

<api name="destroy">
@method
Unloads the page worker. After you destroy a page worker, its memory is freed
Expand Down
13 changes: 13 additions & 0 deletions packages/addon-kit/docs/panel.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,11 @@ Creates a panel.
fires

This property is optional and defaults to "end".
@prop [contentScriptOptions] {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.

@prop [onMessage] {function}
Include this to listen to the panel's `message` event.
Expand Down Expand Up @@ -480,6 +485,14 @@ fires

</api>

<api name="contentScriptOptions">
@property {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.
</api>

<api name="destroy">
@method
Destroys the panel, unloading any content that was loaded in it. Once
Expand Down
49 changes: 35 additions & 14 deletions packages/addon-kit/docs/widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,22 +527,27 @@ Represents a widget object.
specified by the `contentScriptFile` property.

@prop [contentScriptWhen="end"] {string}
When to load the content scripts. This may take one of the following
values:
When to load the content scripts. This may take one of the following
values:

* "start": load content scripts immediately after the document
element for the widget is inserted into the DOM, but before the DOM content
itself has been loaded
* "ready": load content scripts once DOM content has been loaded,
corresponding to the
[DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events)
event
* "end": load content scripts once all the content (DOM, JS, CSS,
images) for the widget has been loaded, at the time the
[window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
fires
* "start": load content scripts immediately after the document
element for the widget is inserted into the DOM, but before the DOM content
itself has been loaded
* "ready": load content scripts once DOM content has been loaded,
corresponding to the
[DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events)
event
* "end": load content scripts once all the content (DOM, JS, CSS,
images) for the widget has been loaded, at the time the
[window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
fires

This property is optional and defaults to "end".
@prop [contentScriptOptions] {object}
Read-only value exposed to content scripts under `self.options` property.

This property is optional and defaults to "end".
Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.

</api>

Expand Down Expand Up @@ -665,6 +670,14 @@ Represents a widget object.

</api>

<api name="contentScriptOptions">
@property {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.
</api>

<api name="port">
@property {EventEmitter}
[EventEmitter](packages/api-utils/events.html) object that allows you to:
Expand Down Expand Up @@ -858,6 +871,14 @@ In this example `WidgetView` is used to display different content for

</api>

<api name="contentScriptOptions">
@property {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.
</api>

<api name="port">
@property {EventEmitter}
[EventEmitter](packages/api-utils/events.html) object that allows you to:
Expand Down
6 changes: 5 additions & 1 deletion packages/addon-kit/lib/page-mod.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const PageMod = Loader.compose(EventEmitter, {
contentScript: Loader.required,
contentScriptFile: Loader.required,
contentScriptWhen: Loader.required,
contentScriptOptions: Loader.required,
include: null,
constructor: function PageMod(options) {
this._onContent = this._onContent.bind(this);
Expand All @@ -112,6 +113,8 @@ const PageMod = Loader.compose(EventEmitter, {
this.contentScript = options.contentScript;
if ('contentScriptFile' in options)
this.contentScriptFile = options.contentScriptFile;
if ('contentScriptOptions' in options)
this.contentScriptOptions = options.contentScriptOptions;
if ('contentScriptWhen' in options)
this.contentScriptWhen = options.contentScriptWhen;
if ('onAttach' in options)
Expand Down Expand Up @@ -200,6 +203,7 @@ const PageMod = Loader.compose(EventEmitter, {
window: window,
contentScript: this.contentScript,
contentScriptFile: this.contentScriptFile,
contentScriptOptions: this.contentScriptOptions,
onError: this._onUncaughtError
});
this._emit('attach', worker);
Expand Down Expand Up @@ -316,4 +320,4 @@ const PageModManager = Registry.resolve({
delete RULES[topic];
}
});
const pageModManager = PageModManager();
const pageModManager = PageModManager();
2 changes: 2 additions & 0 deletions packages/addon-kit/lib/page-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const Page = Trait.compose(
this.contentScriptWhen = options.contentScriptWhen;
if ('contentScriptFile' in options)
this.contentScriptFile = options.contentScriptFile;
if ('contentScriptOptions' in options)
this.contentScriptOptions = options.contentScriptOptions;
if ('contentScript' in options)
this.contentScript = options.contentScript;
if ('allow' in options)
Expand Down
1 change: 1 addition & 0 deletions packages/addon-kit/lib/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@ WidgetChrome.prototype.setContent = function WC_setContent() {
contentScriptFile: this._widget.contentScriptFile,
contentScript: this._widget.contentScript,
contentScriptWhen: this._widget.contentScriptWhen,
contentScriptOptions: this._widget.contentScriptOptions,
allow: this._widget.allow,
onMessage: function(message) {
setTimeout(function() {
Expand Down
3 changes: 2 additions & 1 deletion packages/addon-kit/tests/pagemod-test-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ exports.testPageMod = function testPageMod(test, testURL, pageModOptions,
tabBrowser.removeTab(newTab);
loader.unload();
test.done();
});
}
);
}
b.addEventListener("load", onPageLoad, true);

Expand Down
26 changes: 26 additions & 0 deletions packages/addon-kit/tests/test-page-mod.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,32 @@ exports.testAutomaticDestroy = function(test) {

}

exports.testContentScriptOptionsOption = function(test) {
test.waitUntilDone();

let callbackDone = null;
testPageMod(test, "about:", [{
include: "about:*",
contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
contentScriptWhen: "end",
contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
onAttach: function(worker) {
worker.on('message', function(msg) {
test.assertEqual( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
test.assertEqual( typeof msg[1], 'object', 'object as contentScriptOptions' );
test.assertEqual( msg[1].a, true, 'boolean in contentScriptOptions' );
test.assertEqual( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
test.assertEqual( msg[1].c, 'string', 'string in contentScriptOptions' );
callbackDone();
});
}
}],
function(win, done) {
callbackDone = done;
}
);
};

exports.testPageModCss = function(test) {
let [pageMod] = testPageMod(test,
'data:text/html,<div style="background: silver">css test</div>', [{
Expand Down
17 changes: 17 additions & 0 deletions packages/addon-kit/tests/test-page-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,23 @@ tests.testMultipleDestroys = function(test) {
test.pass("Multiple destroys should not cause an error");
};

exports.testContentScriptOptionsOption = function(test) {
test.waitUntilDone();

let page = new Page({
contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
contentScriptWhen: "end",
contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
onMessage: function(msg) {
test.assertEqual( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
test.assertEqual( typeof msg[1], 'object', 'object as contentScriptOptions' );
test.assertEqual( msg[1].a, true, 'boolean in contentScriptOptions' );
test.assertEqual( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
test.assertEqual( msg[1].c, 'string', 'string in contentScriptOptions' );
test.done();
}
});
};

function isDestroyed(page) {
try {
Expand Down
19 changes: 19 additions & 0 deletions packages/addon-kit/tests/test-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,25 @@ tests.testContentURLOption = function(test) {
"Panel throws an exception if contentURL is not a URL.");
};

exports.testContentScriptOptionsOption = function(test) {
test.waitUntilDone();

let loader = Loader(module);
let panel = loader.require("panel").Panel({
contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
contentScriptWhen: "end",
contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
onMessage: function(msg) {
test.assertEqual( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
test.assertEqual( typeof msg[1], 'object', 'object as contentScriptOptions' );
test.assertEqual( msg[1].a, true, 'boolean in contentScriptOptions' );
test.assertEqual( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
test.assertEqual( msg[1].c, 'string', 'string in contentScriptOptions' );
test.done();
}
});
};

let panelSupported = true;

try {
Expand Down
22 changes: 22 additions & 0 deletions packages/addon-kit/tests/test-widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,28 @@ exports.testWidgetWithPound = function testWidgetWithPound(test) {
});
};

exports.testContentScriptOptionsOption = function(test) {
test.waitUntilDone();

let widget = require("widget").Widget({
id: "fooz",
label: "fooz",
content: "fooz",
contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
contentScriptWhen: "end",
contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
onMessage: function(msg) {
test.assertEqual( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
test.assertEqual( typeof msg[1], 'object', 'object as contentScriptOptions' );
test.assertEqual( msg[1].a, true, 'boolean in contentScriptOptions' );
test.assertEqual( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
test.assertEqual( msg[1].c, 'string', 'string in contentScriptOptions' );
widget.destroy();
test.done();
}
});
};

exports.testNavigationBarWidgets = function testNavigationBarWidgets(test) {
test.waitUntilDone();

Expand Down
17 changes: 14 additions & 3 deletions packages/api-utils/data/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,13 @@ const ContentWorker = Object.freeze({
ContentWorker.createEventEmitter(pipe.emit.bind(null, "event"));
pipe.on("event", portEmit);

let self = Object.freeze({
let self = {
port: port,
postMessage: pipe.emit.bind(null, "message"),
on: pipe.on.bind(null),
once: pipe.once.bind(null),
removeListener: pipe.removeListener.bind(null),
});
};
Object.defineProperty(exports, "self", {
value: self
});
Expand Down Expand Up @@ -233,12 +233,23 @@ const ContentWorker = Object.freeze({
});
},

inject: function (exports, chromeAPI, emitToChrome) {
injectOptions: function (exports, options) {
Object.defineProperty( exports.self, "options", { value: JSON.parse( options ) });
},

inject: function (exports, chromeAPI, emitToChrome, options) {
let { pipe, onChromeEvent, hasListenerFor } =
ContentWorker.createPipe(emitToChrome);

ContentWorker.injectConsole(exports, pipe);
ContentWorker.injectTimers(exports, chromeAPI, pipe, exports.console);
ContentWorker.injectMessageAPI(exports, pipe);
if ( options !== undefined ) {
ContentWorker.injectOptions(exports, options);
}

Object.freeze( exports.self );

return {
emitToContent: onChromeEvent,
hasListenerFor: hasListenerFor
Expand Down
8 changes: 8 additions & 0 deletions packages/api-utils/docs/content/loader.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ fires

</api>

<api name="contentScriptOptions">
@property {object}
Read-only value exposed to content scripts under `self.options` property.

Any kind of jsonable value (object, array, string, etc.) can be used here.
Optional.
</api>

<api name="contentURL">
@property {string}
The URL of the content loaded.
Expand Down
Loading

0 comments on commit 0006f26

Please sign in to comment.