Bug 1197437 - [webext] Fix content script run_at parameter (r=gabor)

This commit is contained in:
Bill McCloskey 2015-08-22 16:48:15 -07:00
parent e815396b58
commit f4456ed493
12 changed files with 154 additions and 9 deletions

View File

@ -342,8 +342,11 @@ let DocumentManager = {
}
// TODO: Somehow make sure we have the right permissions for this origin!
// FIXME: Need to keep this around so that I will execute it later if we're not in the right state.
context.execute(script, scheduled => scheduled == state);
// FIXME: Script should be executed only if current state has
// already reached its run_at state, or we have to keep it around
// somewhere to execute later.
context.execute(script, scheduled => true);
},
enumerateWindows: function*(docShell) {
@ -415,7 +418,7 @@ let DocumentManager = {
for (let script of extension.scripts) {
if (script.matches(window)) {
let context = this.getContext(extensionId, window);
context.execute(script, scheduled => isWhenBeforeOrSame(scheduled, state));
context.execute(script, scheduled => scheduled == state);
}
}
}

View File

@ -0,0 +1,5 @@
browser.runtime.onMessage.addListener(([msg, expectedState, readyState], sender) => {
browser.test.assertEq(msg, "script-run", "message type is correct");
browser.test.assertEq(readyState, expectedState, "readyState is correct");
browser.test.sendMessage("script-run-" + expectedState);
});

View File

@ -0,0 +1 @@
browser.runtime.sendMessage(["script-run", "interactive", document.readyState]);

View File

@ -0,0 +1 @@
browser.runtime.sendMessage(["script-run", "complete", document.readyState]);

View File

@ -0,0 +1 @@
browser.runtime.sendMessage(["script-run", "loading", document.readyState]);

View File

@ -0,0 +1,28 @@
{
"name": "Content script extension test",
"version": "1.0",
"manifest_version": 2,
"description": "",
"content_scripts": [
{
"matches": ["http://mochi.test/tests/toolkit/components/extensions/test/mochitest/file_contentscript_*.html"],
"js": ["content_script_start.js"],
"run_at": "document_start"
},
{
"matches": ["http://mochi.test/tests/toolkit/components/extensions/test/mochitest/file_contentscript_*.html"],
"js": ["content_script_end.js"],
"run_at": "document_end"
},
{
"matches": ["http://mochi.test/tests/toolkit/components/extensions/test/mochitest/file_contentscript_*.html"],
"js": ["content_script_idle.js"],
"run_at": "document_idle"
}
],
"background": {
"scripts": ["background.js"]
}
}

View File

@ -0,0 +1,13 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
TESTING_JS_MODULES.extensions.content_script += [
'background.js',
'content_script_end.js',
'content_script_idle.js',
'content_script_start.js',
'manifest.json',
]

View File

@ -6,6 +6,7 @@
DIRS += [
'background',
'content_script',
'simple',
'webrequest',
]

View File

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="test">Sample text</div>
</body>
</html>

View File

@ -14,7 +14,7 @@ function loadExtension(name)
let testResolve;
let testDone = new Promise(resolve => { testResolve = resolve; });
let messageResolve = new Map();
let messageHandler = new Map();
let handler = {
testResult(kind, pass, msg, ...args) {
@ -26,13 +26,12 @@ function loadExtension(name)
},
testMessage(msg, ...args) {
let resolve = messageResolve.get(msg);
if (!resolve) {
let handler = messageHandler.get(msg);
if (!handler) {
return;
}
messageResolve.delete(msg);
resolve(...args);
handler(...args);
},
};
@ -46,10 +45,24 @@ function loadExtension(name)
extension.awaitMessage = (msg) => {
return new Promise(resolve => {
messageResolve.set(msg, resolve);
if (messageHandler.has(msg)) {
throw new Error("only one message handler allowed");
}
messageHandler.set(msg, (...args) => {
messageHandler.delete(msg);
resolve(...args);
});
});
};
extension.onMessage = (msg, callback) => {
if (messageHandler.has(msg)) {
throw new Error("only one message handler allowed");
}
messageHandler.set(msg, callback);
};
extension.awaitFinish = () => {
return testDone;
};

View File

@ -15,6 +15,8 @@ support-files =
file_script_bad.js
file_script_redirect.js
file_script_xhr.js
file_contentscript_page1.html
[test_simple_extensions.html]
[test_extension_contentscript.html]
[test_extension_webrequest.html]

View File

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for content script</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript;version=1.8" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8">
"use strict";
const BASE = "http://mochi.test:8888/tests/toolkit/components/extensions/test/mochitest";
add_task(function* test_contentscript()
{
let extension = loadExtension("content_script");
yield extension.startup();
info("extension loaded");
let loadingCount = 0;
let interactiveCount = 0;
let completeCount = 0;
extension.onMessage("script-run-loading", () => { loadingCount++; });
extension.onMessage("script-run-interactive", () => { interactiveCount++; });
let completePromise = new Promise(resolve => {
extension.onMessage("script-run-complete", () => { completeCount++; resolve(); });
});
yield new Promise(resolve => { setTimeout(resolve, 0); });
let win = window.open();
win.location = "file_contentscript_page1.html";
ok(true, "page loaded");
yield Promise.all([waitForLoad(win), completePromise]);
info("test page loaded");
win.close();
is(loadingCount, 1, "document_start script ran exactly once");
is(interactiveCount, 1, "document_end script ran exactly once");
is(completeCount, 1, "document_idle script ran exactly once");
yield extension.unload();
info("extension unloaded");
});
function waitForLoad(win) {
return new Promise(resolve => {
win.addEventListener("load", function listener() {
win.removeEventListener("load", listener, true);
resolve();
}, true);
});
}
</script>
</body>
</html>