Bug 1247455 - Add a .removeCSS method to complement .insertCSS. r=kmag
This commit is contained in:
@@ -707,6 +707,7 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
{}, {recipient});
|
||||
},
|
||||
|
||||
// Used to executeScript, insertCSS and removeCSS.
|
||||
_execute: function(tabId, details, kind, method) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let mm = tab.linkedBrowser.messageManager;
|
||||
@@ -714,6 +715,7 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
let options = {
|
||||
js: [],
|
||||
css: [],
|
||||
remove_css: method == "removeCSS",
|
||||
};
|
||||
|
||||
// We require a `code` or a `file` property, but we can't accept both.
|
||||
@@ -773,6 +775,10 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
return self.tabs._execute(tabId, details, "css", "insertCSS");
|
||||
},
|
||||
|
||||
removeCSS: function(tabId, details) {
|
||||
return self.tabs._execute(tabId, details, "css", "removeCSS");
|
||||
},
|
||||
|
||||
connect: function(tabId, connectInfo) {
|
||||
let tab = TabManager.getTab(tabId);
|
||||
let mm = tab.linkedBrowser.messageManager;
|
||||
|
||||
@@ -866,6 +866,33 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "removeCSS",
|
||||
"type": "function",
|
||||
"description": "Removes injected CSS from a page. For details, see the $(topic:content_scripts)[programmatic injection] section of the content scripts doc.",
|
||||
"async": "callback",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"minimum": 0,
|
||||
"optional": true,
|
||||
"description": "The ID of the tab from which to remove the injected CSS; defaults to the active tab of the current window."
|
||||
},
|
||||
{
|
||||
"$ref": "extensionTypes.InjectDetails",
|
||||
"name": "details",
|
||||
"description": "Details of the CSS text to remove."
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"optional": true,
|
||||
"description": "Called when all the CSS has been removed.",
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "setZoom",
|
||||
"type": "function",
|
||||
|
||||
@@ -53,6 +53,7 @@ support-files =
|
||||
[browser_ext_tabs_executeScript_runAt.js]
|
||||
[browser_ext_tabs_getCurrent.js]
|
||||
[browser_ext_tabs_insertCSS.js]
|
||||
[browser_ext_tabs_removeCSS.js]
|
||||
[browser_ext_tabs_move.js]
|
||||
[browser_ext_tabs_move_window.js]
|
||||
[browser_ext_tabs_move_window_multiple.js]
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(function* testExecuteScript() {
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/", true);
|
||||
|
||||
function background() {
|
||||
let promises = [
|
||||
// Insert CSS file.
|
||||
{
|
||||
background: "transparent",
|
||||
foreground: "rgb(0, 113, 4)",
|
||||
promise: () => {
|
||||
return browser.tabs.insertCSS({
|
||||
file: "file2.css",
|
||||
});
|
||||
},
|
||||
},
|
||||
// Insert CSS code.
|
||||
{
|
||||
background: "rgb(42, 42, 42)",
|
||||
foreground: "rgb(0, 113, 4)",
|
||||
promise: () => {
|
||||
return browser.tabs.insertCSS({
|
||||
code: "* { background: rgb(42, 42, 42) }",
|
||||
});
|
||||
},
|
||||
},
|
||||
// Remove CSS code again.
|
||||
{
|
||||
background: "transparent",
|
||||
foreground: "rgb(0, 113, 4)",
|
||||
promise: () => {
|
||||
return browser.tabs.removeCSS({
|
||||
code: "* { background: rgb(42, 42, 42) }",
|
||||
});
|
||||
},
|
||||
},
|
||||
// Remove CSS file again.
|
||||
{
|
||||
background: "transparent",
|
||||
foreground: "rgb(0, 0, 0)",
|
||||
promise: () => {
|
||||
return browser.tabs.removeCSS({
|
||||
file: "file2.css",
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
function checkCSS() {
|
||||
let computedStyle = window.getComputedStyle(document.body);
|
||||
return [computedStyle.backgroundColor, computedStyle.color];
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (!promises.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let {promise, background, foreground} = promises.shift();
|
||||
return promise().then(result => {
|
||||
browser.test.assertEq(undefined, result, "Expected callback result");
|
||||
|
||||
return browser.tabs.executeScript({
|
||||
code: `(${checkCSS})()`,
|
||||
});
|
||||
}).then(result => {
|
||||
browser.test.assertEq(background, result[0], "Expected background color");
|
||||
browser.test.assertEq(foreground, result[1], "Expected foreground color");
|
||||
return next();
|
||||
});
|
||||
}
|
||||
|
||||
next().then(() => {
|
||||
browser.test.notifyPass("removeCSS");
|
||||
}).catch(e => {
|
||||
browser.test.fail(`Error: ${e} :: ${e.stack}`);
|
||||
browser.test.notifyFailure("removeCSS");
|
||||
});
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["http://mochi.test/"],
|
||||
},
|
||||
|
||||
background,
|
||||
|
||||
files: {
|
||||
"file2.css": "* { color: rgb(0, 113, 4) }",
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
yield extension.awaitFinish("removeCSS");
|
||||
|
||||
yield extension.unload();
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
@@ -155,6 +155,7 @@ function Script(options, deferred = PromiseUtils.defer()) {
|
||||
this.run_at = this.options.run_at;
|
||||
this.js = this.options.js || [];
|
||||
this.css = this.options.css || [];
|
||||
this.remove_css = this.options.remove_css;
|
||||
|
||||
this.deferred = deferred;
|
||||
|
||||
@@ -211,15 +212,25 @@ Script.prototype = {
|
||||
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
for (let url of this.css) {
|
||||
url = extension.baseURI.resolve(url);
|
||||
runSafeSyncWithoutClone(winUtils.loadSheetUsingURIString, url, winUtils.AUTHOR_SHEET);
|
||||
this.deferred.resolve();
|
||||
// We can handle CSS urls (css) and CSS code (cssCode).
|
||||
let cssUrls = [];
|
||||
for (let cssUrl of this.css) {
|
||||
cssUrl = extension.baseURI.resolve(cssUrl);
|
||||
cssUrls.push(cssUrl);
|
||||
}
|
||||
|
||||
if (this.options.cssCode) {
|
||||
let url = "data:text/css;charset=utf-8," + encodeURIComponent(this.options.cssCode);
|
||||
runSafeSyncWithoutClone(winUtils.loadSheetUsingURIString, url, winUtils.AUTHOR_SHEET);
|
||||
let cssUrl = "data:text/css;charset=utf-8," + encodeURIComponent(this.options.cssCode);
|
||||
cssUrls.push(cssUrl);
|
||||
}
|
||||
|
||||
// We can insertCSS and removeCSS.
|
||||
let method = this.remove_css ? winUtils.removeSheetUsingURIString : winUtils.loadSheetUsingURIString;
|
||||
for (let cssUrl of cssUrls) {
|
||||
runSafeSyncWithoutClone(method, cssUrl, winUtils.AUTHOR_SHEET);
|
||||
}
|
||||
|
||||
if (cssUrls.length > 0) {
|
||||
this.deferred.resolve();
|
||||
}
|
||||
}
|
||||
@@ -548,6 +559,7 @@ DocumentManager = {
|
||||
}
|
||||
},
|
||||
|
||||
// Used to executeScript, insertCSS and removeCSS.
|
||||
executeScript(global, extensionId, options) {
|
||||
let executeInWin = (window) => {
|
||||
let deferred = PromiseUtils.defer();
|
||||
@@ -881,6 +893,7 @@ class ExtensionGlobal {
|
||||
});
|
||||
}
|
||||
|
||||
// Used to executeScript, insertCSS and removeCSS.
|
||||
handleExtensionExecute(target, extensionId, options) {
|
||||
return DocumentManager.executeScript(target, extensionId, options).then(result => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user