Backed out 2 changesets (bug 1481021) for bc failures on security/sandbox/test/browser_bug1393259.js.

Backed out changeset c53c7b0249ad (bug 1481021)
Backed out changeset 41bedc526dd6 (bug 1481021)
This commit is contained in:
Brindusan Cristian 2018-08-08 03:22:16 +03:00
Родитель a8579f90d1
Коммит 16ec846afc
20 изменённых файлов: 80 добавлений и 124 удалений

Просмотреть файл

@ -18,8 +18,6 @@ registerCleanupFunction(function() {
// offline cache events.
//
function contentTask() {
ChromeUtils.import("resource://gre/modules/Timer.jsm");
let resolve;
let promise = new Promise(r => { resolve = r; });

Просмотреть файл

@ -24,8 +24,6 @@ const whitelist = {
]),
modules: new Set([
"chrome://mochikit/content/ShutdownLeaksCollector.jsm",
"resource://specialpowers/specialpowers.js",
"resource://specialpowers/specialpowersAPI.js",
// General utilities
"resource://gre/modules/AppConstants.jsm",

Просмотреть файл

@ -92,7 +92,6 @@ add_task(async function test_displayURI_camera() {
add_task(async function test_displayURI_geo_blob() {
await check(async function() {
Cu.importGlobalProperties(["Blob"]);
let text = "<script>navigator.geolocation.getCurrentPosition(() => {})</script>";
let blob = new Blob([text], {type: "text/html"});
let url = content.URL.createObjectURL(blob);
@ -102,7 +101,6 @@ add_task(async function test_displayURI_geo_blob() {
add_task(async function test_displayURI_camera_blob() {
await check(async function() {
Cu.importGlobalProperties(["Blob"]);
let text = "<script>navigator.mediaDevices.getUserMedia({video: true, fake: true})</script>";
let blob = new Blob([text], {type: "text/html"});
let url = content.URL.createObjectURL(blob);

Просмотреть файл

@ -3,7 +3,6 @@
/* eslint-env mozilla/frame-script */
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
"@mozilla.org/mediaManagerService;1",

Просмотреть файл

@ -65,7 +65,7 @@ test_newtab({
// it should be able to click the topsites edit button to reveal the edit topsites modal and overlay.
test: async function topsites_add() {
let nativeInputValueSetter = Object.getOwnPropertyDescriptor(content.window.HTMLInputElement.prototype, "value").set;
let event = new content.Event("input", {bubbles: true});
let event = new Event("input", {bubbles: true});
// Find the add topsites button
content.document.querySelector(".top-sites .section-top-bar .context-menu-button").click();

Просмотреть файл

@ -90,12 +90,12 @@ let PaymentFrameScript = {
},
getDefaultPreferences() {
let prefValues = Cu.cloneInto({
let prefValues = {
saveCreditCardDefaultChecked:
Services.prefs.getBoolPref(SAVE_CREDITCARD_DEFAULT_PREF, false),
saveAddressDefaultChecked:
Services.prefs.getBoolPref(SAVE_ADDRESS_DEFAULT_PREF, false),
}, waivedContent);
};
return prefValues;
},
};

Просмотреть файл

@ -323,7 +323,7 @@ function loadUITourTestPage(callback, host = "https://example.org/") {
let callbacksCalled = 0;
let resolveCallbackPromise;
let allCallbacksCalledPromise = new Promise(resolve => resolveCallbackPromise = resolve);
let argumentsWithFunctions = Cu.cloneInto(contentArgs.args.map((arg, index) => {
let argumentsWithFunctions = contentArgs.args.map((arg, index) => {
if (arg === "" && contentArgs.fnIndices.includes(index)) {
return function() {
callbacksCalled++;
@ -334,9 +334,9 @@ function loadUITourTestPage(callback, host = "https://example.org/") {
};
}
return arg;
}), content, {cloneFunctions: true});
});
let rv = contentWin.Mozilla.UITour[contentArgs.methodName].apply(contentWin.Mozilla.UITour,
argumentsWithFunctions);
argumentsWithFunctions);
if (contentArgs.fnIndices.length) {
await allCallbacksCalledPromise;
}

Просмотреть файл

@ -23,7 +23,7 @@ this.call = function (name, args) {
dump("Calling function with name " + name + ".\n");
dump("args " + JSON.stringify(args) + "\n");
return XPCNativeWrapper.unwrap(content)[name].apply(undefined, Cu.cloneInto(args, content));
return XPCNativeWrapper.unwrap(content)[name].apply(undefined, args);
};
this._eval = function (string) {

Просмотреть файл

@ -9,6 +9,8 @@
title="bug 89419 test">
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
<script type="text/javascript"
src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/>
<script type="text/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
<script type="text/javascript"

Просмотреть файл

@ -72,8 +72,6 @@ function testKeys(browser) {
function testOpen_worker(browser) {
return ContentTask.spawn(browser, {}, function() {
Cu.importGlobalProperties(["Blob"]);
let workerFunctionString = function () {
caches.open("pb-worker-cache").then(function(cacheObject) {
postMessage(cacheObject.toString());

Просмотреть файл

@ -11,7 +11,6 @@ add_task(async function test_CtoPtoC_big() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blob = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
let blob = new Blob([new Array(1024*1024).join('123456789ABCDEF')]);
return blob;
});
@ -44,7 +43,6 @@ add_task(async function test_CtoPtoC_small() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blob = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
let blob = new Blob(["hello world!"]);
return blob;
});
@ -77,7 +75,6 @@ add_task(async function test_CtoPtoC_bc_big() {
let browser1 = gBrowser.getBrowserForTab(tab1);
await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
var bc = new content.BroadcastChannel('test');
bc.onmessage = function() {
bc.postMessage(new Blob([new Array(1024*1024).join('123456789ABCDEF')]));
@ -114,7 +111,6 @@ add_task(async function test_CtoPtoC_bc_small() {
let browser1 = gBrowser.getBrowserForTab(tab1);
await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
var bc = new content.BroadcastChannel('test');
bc.onmessage = function() {
bc.postMessage(new Blob(["hello world!"]));
@ -151,7 +147,6 @@ add_task(async function test_CtoPtoC_bc_small() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blobURL = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
return content.URL.createObjectURL(new content.Blob(["hello world!"]));
});
@ -182,7 +177,6 @@ add_task(async function test_CtoPtoC_multipart() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blob = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
return new Blob(["!"]);
});
@ -195,7 +189,6 @@ add_task(async function test_CtoPtoC_multipart() {
let browser2 = gBrowser.getBrowserForTab(tab2);
let status = await ContentTask.spawn(browser2, newBlob, function(blob) {
Cu.importGlobalProperties(["Blob"]);
return new Promise(resolve => {
let fr = new content.FileReader();
fr.readAsText(new Blob(["hello ", blob]));

Просмотреть файл

@ -18,7 +18,7 @@ function frameScript() {
});
addMessageListener("Test:DispatchUntrustedKeyEvents", msg => {
var evt = new content.CustomEvent("Test:DispatchKeyEvents", {
detail: Cu.cloneInto({ code: msg.data }, content),
detail: { code: msg.data }
});
content.dispatchEvent(evt);
});

Просмотреть файл

@ -160,7 +160,7 @@ async function mutateTabStorage(knownTab, mutations, sentinelValue) {
knownTab.tab.linkedBrowser,
{ mutations, sentinelValue },
function(args) {
return content.wrappedJSObject.mutateStorage(Cu.cloneInto(args, content));
return content.wrappedJSObject.mutateStorage(args);
});
}

Просмотреть файл

@ -19,17 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=628410
<script type="application/javascript">
/** Test for Bug 628410 **/
{
// window.toSource() will throw if SpecialPowers is defined on the window and
// permissive COWs are not enabled for the global that owns its frame message
// manager.
let sp = window.SpecialPowers;
window.SpecialPowers = null;
window.toSource();
window.SpecialPowers = sp;
}
window.toSource();
window.toString();
InstallTrigger + "";
console + "";

Просмотреть файл

@ -105,7 +105,7 @@ if (params.runUntilFailure) {
// closeWhenDone tells us to close the browser when complete
if (params.closeWhenDone) {
TestRunner.onComplete = SpecialPowers.quit.bind(SpecialPowers);
TestRunner.onComplete = SpecialPowers.quit;
}
if (params.failureFile) {

Просмотреть файл

@ -16,7 +16,8 @@ var EXPORTED_SYMBOLS = ["SpecialPowersObserver"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
Cu.importGlobalProperties(["File"]);
const CHILD_SCRIPT_API = "resource://specialpowers/specialpowersFrameScript.js";
const CHILD_SCRIPT = "resource://specialpowers/specialpowers.js";
const CHILD_SCRIPT_API = "resource://specialpowers/specialpowersAPI.js";
const CHILD_LOGGER_SCRIPT = "resource://specialpowers/MozillaLogger.js";
@ -81,6 +82,7 @@ SpecialPowersObserver.prototype._loadFrameScript = function() {
this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true);
this._messageManager.loadFrameScript(CHILD_SCRIPT, true);
this._isFrameScriptLoaded = true;
this._createdFiles = null;
}
@ -147,6 +149,7 @@ SpecialPowersObserver.prototype.uninit = function() {
this._messageManager.removeDelayedFrameScript(CHILD_LOGGER_SCRIPT);
this._messageManager.removeDelayedFrameScript(CHILD_SCRIPT_API);
this._messageManager.removeDelayedFrameScript(CHILD_SCRIPT);
this._isFrameScriptLoaded = false;
}
};

Просмотреть файл

@ -5,21 +5,12 @@
* order to be used as a replacement for UniversalXPConnect
*/
/* globals bindDOMWindowUtils, SpecialPowersAPI */
/* import-globals-from specialpowersAPI.js */
/* globals addMessageListener, removeMessageListener, sendSyncMessage, sendAsyncMessage */
ChromeUtils.import("resource://gre/modules/Services.jsm");
Services.scriptloader.loadSubScript("resource://specialpowers/MozillaLogger.js", this);
var EXPORTED_SYMBOLS = ["SpecialPowers", "attachSpecialPowersToWindow"];
ChromeUtils.import("resource://specialpowers/specialpowersAPI.js", this);
Cu.forcePermissiveCOWs();
function SpecialPowers(window, mm) {
this.mm = mm;
function SpecialPowers(window) {
this.window = Cu.getWeakReference(window);
this._windowID = window.windowUtils.currentInnerWindowID;
this._encounteredCrashDumpFiles = [];
@ -56,18 +47,18 @@ function SpecialPowers(window, mm) {
"SPExtensionMessage",
"SPRequestDumpCoverageCounters",
"SPRequestResetCoverageCounters"];
mm.addMessageListener("SPPingService", this._messageListener);
mm.addMessageListener("SpecialPowers.FilesCreated", this._messageListener);
mm.addMessageListener("SpecialPowers.FilesError", this._messageListener);
addMessageListener("SPPingService", this._messageListener);
addMessageListener("SpecialPowers.FilesCreated", this._messageListener);
addMessageListener("SpecialPowers.FilesError", this._messageListener);
let self = this;
Services.obs.addObserver(function onInnerWindowDestroyed(subject, topic, data) {
var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (self._windowID === id) {
Services.obs.removeObserver(onInnerWindowDestroyed, "inner-window-destroyed");
try {
mm.removeMessageListener("SPPingService", self._messageListener);
mm.removeMessageListener("SpecialPowers.FilesCreated", self._messageListener);
mm.removeMessageListener("SpecialPowers.FilesError", self._messageListener);
removeMessageListener("SPPingService", self._messageListener);
removeMessageListener("SpecialPowers.FilesCreated", self._messageListener);
removeMessageListener("SpecialPowers.FilesError", self._messageListener);
} catch (e) {
// Ignore the exception which the message manager has been destroyed.
if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE) {
@ -92,34 +83,33 @@ SpecialPowers.prototype._sendSyncMessage = function(msgname, msg) {
if (!this.SP_SYNC_MESSAGES.includes(msgname)) {
dump("TEST-INFO | specialpowers.js | Unexpected SP message: " + msgname + "\n");
}
let result = this.mm.sendSyncMessage(msgname, msg);
return Cu.cloneInto(result, this);
return sendSyncMessage(msgname, msg);
};
SpecialPowers.prototype._sendAsyncMessage = function(msgname, msg) {
if (!this.SP_ASYNC_MESSAGES.includes(msgname)) {
dump("TEST-INFO | specialpowers.js | Unexpected SP message: " + msgname + "\n");
}
this.mm.sendAsyncMessage(msgname, msg);
sendAsyncMessage(msgname, msg);
};
SpecialPowers.prototype._addMessageListener = function(msgname, listener) {
this.mm.addMessageListener(msgname, listener);
this.mm.sendAsyncMessage("SPPAddNestedMessageListener", { name: msgname });
addMessageListener(msgname, listener);
sendAsyncMessage("SPPAddNestedMessageListener", { name: msgname });
};
SpecialPowers.prototype._removeMessageListener = function(msgname, listener) {
this.mm.removeMessageListener(msgname, listener);
removeMessageListener(msgname, listener);
};
SpecialPowers.prototype.registerProcessCrashObservers = function() {
this.mm.addMessageListener("SPProcessCrashService", this._messageListener);
this.mm.sendSyncMessage("SPProcessCrashService", { op: "register-observer" });
addMessageListener("SPProcessCrashService", this._messageListener);
sendSyncMessage("SPProcessCrashService", { op: "register-observer" });
};
SpecialPowers.prototype.unregisterProcessCrashObservers = function() {
this.mm.removeMessageListener("SPProcessCrashService", this._messageListener);
this.mm.sendSyncMessage("SPProcessCrashService", { op: "unregister-observer" });
removeMessageListener("SPProcessCrashService", this._messageListener);
sendSyncMessage("SPProcessCrashService", { op: "unregister-observer" });
};
SpecialPowers.prototype._messageReceived = function(aMessage) {
@ -149,7 +139,7 @@ SpecialPowers.prototype._messageReceived = function(aMessage) {
this._createFilesOnSuccess = null;
this._createFilesOnError = null;
if (createdHandler) {
createdHandler(Cu.cloneInto(aMessage.data, this.mm.content));
createdHandler(aMessage.data);
}
break;
@ -167,7 +157,7 @@ SpecialPowers.prototype._messageReceived = function(aMessage) {
};
SpecialPowers.prototype.quit = function() {
this.mm.sendAsyncMessage("SpecialPowers.Quit", {});
sendAsyncMessage("SpecialPowers.Quit", {});
};
// fileRequests is an array of file requests. Each file request is an object.
@ -182,18 +172,18 @@ SpecialPowers.prototype.createFiles = function(fileRequests, onCreation, onError
this._createFilesOnSuccess = onCreation;
this._createFilesOnError = onError;
this.mm.sendAsyncMessage("SpecialPowers.CreateFiles", fileRequests);
sendAsyncMessage("SpecialPowers.CreateFiles", fileRequests);
};
// Remove the files that were created using |SpecialPowers.createFiles()|.
// This will be automatically called by |SimpleTest.finish()|.
SpecialPowers.prototype.removeFiles = function() {
this.mm.sendAsyncMessage("SpecialPowers.RemoveFiles", {});
sendAsyncMessage("SpecialPowers.RemoveFiles", {});
};
SpecialPowers.prototype.executeAfterFlushingMessageQueue = function(aCallback) {
this._pongHandlers.push(aCallback);
this.mm.sendAsyncMessage("SPPingService", { op: "ping" });
sendAsyncMessage("SPPingService", { op: "ping" });
};
SpecialPowers.prototype.nestedFrameSetup = function() {
@ -225,7 +215,9 @@ SpecialPowers.prototype.nestedFrameSetup = function() {
});
});
mm.loadFrameScript("resource://specialpowers/specialpowersFrameScript.js", false);
mm.loadFrameScript("resource://specialpowers/MozillaLogger.js", false);
mm.loadFrameScript("resource://specialpowers/specialpowersAPI.js", false);
mm.loadFrameScript("resource://specialpowers/specialpowers.js", false);
let frameScript = "SpecialPowers.prototype.IsInNestedFrame=true;";
mm.loadFrameScript("data:," + frameScript, false);
@ -240,13 +232,13 @@ SpecialPowers.prototype.isServiceWorkerRegistered = function() {
};
// Attach our API to the window.
function attachSpecialPowersToWindow(aWindow, mm) {
function attachSpecialPowersToWindow(aWindow) {
try {
if ((aWindow !== null) &&
(aWindow !== undefined) &&
(aWindow.wrappedJSObject) &&
!(aWindow.wrappedJSObject.SpecialPowers)) {
let sp = new SpecialPowers(aWindow, mm);
let sp = new SpecialPowers(aWindow);
aWindow.wrappedJSObject.SpecialPowers = sp;
if (sp.IsInNestedFrame) {
sp.addPermission("allowXULXBL", true, aWindow.document);
@ -257,6 +249,25 @@ function attachSpecialPowersToWindow(aWindow, mm) {
}
}
// This is a frame script, so it may be running in a content process.
// In any event, it is targeted at a specific "tab", so we listen for
// the DOMWindowCreated event to be notified about content windows
// being created in this context.
function SpecialPowersManager() {
addEventListener("DOMWindowCreated", this, false);
}
SpecialPowersManager.prototype = {
handleEvent: function handleEvent(aEvent) {
var window = aEvent.target.defaultView;
attachSpecialPowersToWindow(window);
}
};
var specialpowersmanager = new SpecialPowersManager();
this.SpecialPowers = SpecialPowers;
this.attachSpecialPowersToWindow = attachSpecialPowersToWindow;
@ -265,5 +276,5 @@ this.attachSpecialPowersToWindow = attachSpecialPowersToWindow;
if (typeof window != "undefined") {
window.addMessageListener = function() {};
window.removeMessageListener = function() {};
window.wrappedJSObject.SpecialPowers = new SpecialPowers(window, window);
window.wrappedJSObject.SpecialPowers = new SpecialPowers(window);
}

Просмотреть файл

@ -8,17 +8,13 @@
"use strict";
/* import-globals-from MozillaLogger.js */
/* globals XPCNativeWrapper */
/* globals XPCNativeWrapper, content */
var EXPORTED_SYMBOLS = ["SpecialPowersAPI", "bindDOMWindowUtils"];
var global = this;
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
Services.scriptloader.loadSubScript("resource://specialpowers/MozillaLogger.js", this);
ChromeUtils.defineModuleGetter(this, "setTimeout",
"resource://gre/modules/Timer.jsm");
ChromeUtils.defineModuleGetter(this, "MockFilePicker",
"resource://specialpowers/MockFilePicker.jsm");
ChromeUtils.defineModuleGetter(this, "MockColorPicker",
@ -586,9 +582,6 @@ SpecialPowersAPI.prototype = {
let messageId = aMessage.json.id;
let name = aMessage.json.name;
let message = aMessage.json.message;
if (this.mm) {
message = new StructuredCloneHolder(message).deserialize(this.mm.content);
}
// Ignore message from other chrome script
if (messageId != id)
return;
@ -761,12 +754,12 @@ SpecialPowersAPI.prototype = {
setTimeout(callback, 0);
// for mochitest-plain
else
this.mm.content.setTimeout(callback, 0);
content.window.setTimeout(callback, 0);
},
_delayCallbackTwice(callback) {
let delayedCallback = () => {
let delayAgain = (aCallback) => {
function delayedCallback() {
function delayAgain(aCallback) {
// Using this._setTimeout doesn't work here
// It causes failures in mochtests that use
// multiple pushPrefEnv calls
@ -775,10 +768,10 @@ SpecialPowersAPI.prototype = {
setTimeout(aCallback, 0);
// For mochitest-plain
else
this.mm.content.setTimeout(aCallback, 0);
};
delayAgain(delayAgain.bind(this, callback));
};
content.window.setTimeout(aCallback, 0);
}
delayAgain(delayAgain(callback));
}
return delayedCallback;
},
@ -1468,10 +1461,10 @@ SpecialPowersAPI.prototype = {
// XXX end of problematic APIs
addChromeEventListener(type, listener, capture, allowUntrusted) {
this.mm.addEventListener(type, listener, capture, allowUntrusted);
addEventListener(type, listener, capture, allowUntrusted);
},
removeChromeEventListener(type, listener, capture) {
this.mm.removeEventListener(type, listener, capture);
removeEventListener(type, listener, capture);
},
// Note: each call to registerConsoleListener MUST be paired with a
@ -1759,7 +1752,7 @@ SpecialPowersAPI.prototype = {
// With aWindow, it is called in SimpleTest.waitForFocus to allow popup window opener focus switching
if (aWindow)
aWindow.focus();
var mm = this.mm;
var mm = global;
if (aWindow) {
let windowMM = aWindow.docShell.messageManager;
if (windowMM) {
@ -1782,7 +1775,7 @@ SpecialPowersAPI.prototype = {
// in e10s b-c tests |content.window| is a CPOW whereas |window| works fine.
// for some non-e10s mochi tests, |window| is null whereas |content.window|
// works fine. So we take whatever is non-null!
xferable.init(this._getDocShell(typeof(window) == "undefined" ? this.mm.content.window : window)
xferable.init(this._getDocShell(typeof(window) == "undefined" ? content.window : window)
.QueryInterface(Ci.nsILoadContext));
xferable.addDataFlavor(flavor);
Services.clipboard.getData(xferable, whichClipboard);
@ -2102,7 +2095,7 @@ SpecialPowersAPI.prototype = {
state = "unloaded";
resolveUnload();
} else if (msg.data.type in handler) {
handler[msg.data.type](...Cu.cloneInto(msg.data.args, this.window));
handler[msg.data.type](...msg.data.args);
} else {
dump(`Unexpected: ${msg.data.type}\n`);
}
@ -2123,7 +2116,7 @@ SpecialPowersAPI.prototype = {
createChromeCache(name, url) {
let principal = this._getPrincipalFromArg(url);
return wrapIfUnwrapped(new this.mm.content.CacheStorage(name, principal));
return wrapIfUnwrapped(new content.window.CacheStorage(name, principal));
},
loadChannelAndReturnStatus(url, loadUsingSystemPrincipal) {

Просмотреть файл

@ -1,26 +0,0 @@
"use strict";
/* globals attachSpecialPowersToWindow */
let mm = this;
ChromeUtils.import("resource://specialpowers/specialpowersAPI.js", this);
ChromeUtils.import("resource://specialpowers/specialpowers.js", this);
// This is a frame script, so it may be running in a content process.
// In any event, it is targeted at a specific "tab", so we listen for
// the DOMWindowCreated event to be notified about content windows
// being created in this context.
function SpecialPowersManager() {
addEventListener("DOMWindowCreated", this, false);
}
SpecialPowersManager.prototype = {
handleEvent: function handleEvent(aEvent) {
var window = aEvent.target.defaultView;
attachSpecialPowersToWindow(window, mm);
}
};
var specialpowersmanager = new SpecialPowersManager();

Просмотреть файл

@ -23,7 +23,6 @@ FINAL_TARGET_FILES.content += [
'content/MozillaLogger.js',
'content/specialpowers.js',
'content/specialpowersAPI.js',
'content/specialpowersFrameScript.js',
'content/SpecialPowersObserver.jsm',
'content/SpecialPowersObserverAPI.js',
]