Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Razvan Maries 2019-07-05 00:43:53 +03:00
commit 960e4c47d4
206 changed files with 4454 additions and 3727 deletions

View file

@ -161,15 +161,11 @@ function setTestPluginEnabledState(newEnabledState, pluginName) {
} }
function pushPrefs(...aPrefs) { function pushPrefs(...aPrefs) {
return new Promise(resolve => { return SpecialPowers.pushPrefEnv({"set": aPrefs});
SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
});
} }
function popPrefs() { function popPrefs() {
return new Promise(resolve => { return SpecialPowers.popPrefEnv();
SpecialPowers.popPrefEnv(resolve);
});
} }
function updateBlocklist(aCallback) { function updateBlocklist(aCallback) {

View file

@ -20,8 +20,9 @@ const kDumpAllStacks = false;
const whitelist = { const whitelist = {
modules: new Set([ modules: new Set([
"chrome://mochikit/content/ShutdownLeaksCollector.jsm", "chrome://mochikit/content/ShutdownLeaksCollector.jsm",
"resource://specialpowers/specialpowers.js", "resource://specialpowers/SpecialPowersChild.jsm",
"resource://specialpowers/specialpowersAPI.js", "resource://specialpowers/SpecialPowersAPI.jsm",
"resource://specialpowers/WrapPrivileged.jsm",
"resource://gre/modules/ContentProcessSingleton.jsm", "resource://gre/modules/ContentProcessSingleton.jsm",
@ -64,8 +65,6 @@ const whitelist = {
]), ]),
frameScripts: new Set([ frameScripts: new Set([
// Test related // Test related
"resource://specialpowers/MozillaLogger.js",
"resource://specialpowers/specialpowersFrameScript.js",
"chrome://mochikit/content/shutdown-leaks-collector.js", "chrome://mochikit/content/shutdown-leaks-collector.js",
"chrome://mochikit/content/tests/SimpleTest/AsyncUtilsContent.js", "chrome://mochikit/content/tests/SimpleTest/AsyncUtilsContent.js",
"chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js", "chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js",

View file

@ -129,9 +129,9 @@
const permission = "geolocation"; const permission = "geolocation";
const promiseGranted = this.promiseStateChanged(permission, "granted"); const promiseGranted = this.promiseStateChanged(permission, "granted");
this.setPermissions(ALLOW_ACTION); this.setPermissions(ALLOW_ACTION);
promiseGranted.then(() => { promiseGranted.then(async () => {
const promisePrompt = this.promiseStateChanged(permission, "prompt"); const promisePrompt = this.promiseStateChanged(permission, "prompt");
SpecialPowers.popPermissions(); await SpecialPowers.popPermissions();
return promisePrompt; return promisePrompt;
}).then(resolve); }).then(resolve);
}); });

View file

@ -174,54 +174,47 @@ function checkMenuEntries(expectedValues, isFormAutofillResult = true) {
} }
} }
function invokeAsyncChromeTask(message, response, payload = {}) { function invokeAsyncChromeTask(message, payload = {}) {
info(`expecting the chrome task finished: ${message}`); info(`expecting the chrome task finished: ${message}`);
return new Promise(resolve => { return formFillChromeScript.sendQuery(message, payload);
formFillChromeScript.sendAsyncMessage(message, payload);
formFillChromeScript.addMessageListener(response, function onReceived(data) {
formFillChromeScript.removeMessageListener(response, onReceived);
resolve(data);
});
});
} }
async function addAddress(address) { async function addAddress(address) {
await invokeAsyncChromeTask("FormAutofillTest:AddAddress", "FormAutofillTest:AddressAdded", {address}); await invokeAsyncChromeTask("FormAutofillTest:AddAddress", {address});
await sleep(); await sleep();
} }
async function removeAddress(guid) { async function removeAddress(guid) {
return invokeAsyncChromeTask("FormAutofillTest:RemoveAddress", "FormAutofillTest:AddressRemoved", {guid}); return invokeAsyncChromeTask("FormAutofillTest:RemoveAddress", {guid});
} }
async function updateAddress(guid, address) { async function updateAddress(guid, address) {
return invokeAsyncChromeTask("FormAutofillTest:UpdateAddress", "FormAutofillTest:AddressUpdated", {address, guid}); return invokeAsyncChromeTask("FormAutofillTest:UpdateAddress", {address, guid});
} }
async function checkAddresses(expectedAddresses) { async function checkAddresses(expectedAddresses) {
return invokeAsyncChromeTask("FormAutofillTest:CheckAddresses", "FormAutofillTest:areAddressesMatching", {expectedAddresses}); return invokeAsyncChromeTask("FormAutofillTest:CheckAddresses", {expectedAddresses});
} }
async function cleanUpAddresses() { async function cleanUpAddresses() {
return invokeAsyncChromeTask("FormAutofillTest:CleanUpAddresses", "FormAutofillTest:AddressesCleanedUp"); return invokeAsyncChromeTask("FormAutofillTest:CleanUpAddresses");
} }
async function addCreditCard(creditcard) { async function addCreditCard(creditcard) {
await invokeAsyncChromeTask("FormAutofillTest:AddCreditCard", "FormAutofillTest:CreditCardAdded", {creditcard}); await invokeAsyncChromeTask("FormAutofillTest:AddCreditCard", {creditcard});
await sleep(); await sleep();
} }
async function removeCreditCard(guid) { async function removeCreditCard(guid) {
return invokeAsyncChromeTask("FormAutofillTest:RemoveCreditCard", "FormAutofillTest:CreditCardRemoved", {guid}); return invokeAsyncChromeTask("FormAutofillTest:RemoveCreditCard", {guid});
} }
async function checkCreditCards(expectedCreditCards) { async function checkCreditCards(expectedCreditCards) {
return invokeAsyncChromeTask("FormAutofillTest:CheckCreditCards", "FormAutofillTest:areCreditCardsMatching", {expectedCreditCards}); return invokeAsyncChromeTask("FormAutofillTest:CheckCreditCards", {expectedCreditCards});
} }
async function cleanUpCreditCards() { async function cleanUpCreditCards() {
return invokeAsyncChromeTask("FormAutofillTest:CleanUpCreditCards", "FormAutofillTest:CreditCardsCleanedUp"); return invokeAsyncChromeTask("FormAutofillTest:CleanUpCreditCards");
} }
async function cleanUpStorage() { async function cleanUpStorage() {
@ -230,12 +223,12 @@ async function cleanUpStorage() {
} }
async function canTestOSKeyStoreLogin() { async function canTestOSKeyStoreLogin() {
let {canTest} = await invokeAsyncChromeTask("FormAutofillTest:CanTestOSKeyStoreLogin", "FormAutofillTest:CanTestOSKeyStoreLoginResult"); let {canTest} = await invokeAsyncChromeTask("FormAutofillTest:CanTestOSKeyStoreLogin");
return canTest; return canTest;
} }
async function waitForOSKeyStoreLogin(login = false) { async function waitForOSKeyStoreLogin(login = false) {
await invokeAsyncChromeTask("FormAutofillTest:OSKeyStoreLogin", "FormAutofillTest:OSKeyStoreLoggedIn", {login}); await invokeAsyncChromeTask("FormAutofillTest:OSKeyStoreLogin", {login});
} }
function patchRecordCCNumber(record) { function patchRecordCCNumber(record) {
@ -302,15 +295,13 @@ function formAutoFillCommonSetup() {
}); });
add_task(async function setup() { add_task(async function setup() {
formFillChromeScript.sendAsyncMessage("setup");
info(`expecting the storage setup`); info(`expecting the storage setup`);
await formFillChromeScript.promiseOneMessage("setup-finished"); await formFillChromeScript.sendQuery("setup");
}); });
SimpleTest.registerCleanupFunction(async () => { SimpleTest.registerCleanupFunction(async () => {
formFillChromeScript.sendAsyncMessage("cleanup");
info(`expecting the storage cleanup`); info(`expecting the storage cleanup`);
await formFillChromeScript.promiseOneMessage("cleanup-finished"); await formFillChromeScript.sendQuery("cleanup");
formFillChromeScript.destroy(); formFillChromeScript.destroy();
expectingPopup = null; expectingPopup = null;

View file

@ -13,6 +13,8 @@ let {formAutofillStorage} = ChromeUtils.import("resource://formautofill/FormAuto
const {ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME} = FormAutofillUtils; const {ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME} = FormAutofillUtils;
let destroyed = false;
var ParentUtils = { var ParentUtils = {
async _getRecords(collectionName) { async _getRecords(collectionName) {
return new Promise(resolve => { return new Promise(resolve => {
@ -34,12 +36,16 @@ var ParentUtils = {
} }
// every notification type should have the collection name. // every notification type should have the collection name.
let allowedNames = [ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME]; // We're not allowed to trigger assertions during mochitest
assert.ok(allowedNames.includes(subject.wrappedJSObject.collectionName), // cleanup functions.
"should include the collection name"); if (!destroyed) {
// every notification except removeAll should have a guid. let allowedNames = [ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME];
if (data != "removeAll") { assert.ok(allowedNames.includes(subject.wrappedJSObject.collectionName),
assert.ok(subject.wrappedJSObject.guid, "should have a guid"); "should include the collection name");
// every notification except removeAll should have a guid.
if (data != "removeAll") {
assert.ok(subject.wrappedJSObject.guid, "should have a guid");
}
} }
Services.obs.removeObserver(observer, obsTopic); Services.obs.removeObserver(observer, obsTopic);
resolve(); resolve();
@ -47,7 +53,7 @@ var ParentUtils = {
}); });
}, },
async _operateRecord(collectionName, type, msgData, contentMsg) { async _operateRecord(collectionName, type, msgData) {
let times, topic; let times, topic;
if (collectionName == ADDRESSES_COLLECTION_NAME) { if (collectionName == ADDRESSES_COLLECTION_NAME) {
@ -83,14 +89,13 @@ var ParentUtils = {
} }
await this._storageChangeObserved({type, times, topic}); await this._storageChangeObserved({type, times, topic});
sendAsyncMessage(contentMsg);
}, },
async operateAddress(type, msgData, contentMsg) { async operateAddress(type, msgData) {
await this._operateRecord(ADDRESSES_COLLECTION_NAME, ...arguments); await this._operateRecord(ADDRESSES_COLLECTION_NAME, ...arguments);
}, },
async operateCreditCard(type, msgData, contentMsg) { async operateCreditCard(type, msgData) {
await this._operateRecord(CREDITCARDS_COLLECTION_NAME, ...arguments); await this._operateRecord(CREDITCARDS_COLLECTION_NAME, ...arguments);
}, },
@ -98,7 +103,6 @@ var ParentUtils = {
const guids = (await this._getRecords(ADDRESSES_COLLECTION_NAME)).map(record => record.guid); const guids = (await this._getRecords(ADDRESSES_COLLECTION_NAME)).map(record => record.guid);
if (guids.length == 0) { if (guids.length == 0) {
sendAsyncMessage("FormAutofillTest:AddressesCleanedUp");
return; return;
} }
@ -112,7 +116,6 @@ var ParentUtils = {
const guids = (await this._getRecords(CREDITCARDS_COLLECTION_NAME)).map(record => record.guid); const guids = (await this._getRecords(CREDITCARDS_COLLECTION_NAME)).map(record => record.guid);
if (guids.length == 0) { if (guids.length == 0) {
sendAsyncMessage("FormAutofillTest:CreditCardsCleanedUp");
return; return;
} }
@ -167,19 +170,17 @@ var ParentUtils = {
}, },
async checkAddresses({expectedAddresses}) { async checkAddresses({expectedAddresses}) {
const areMatched = await this._checkRecords(ADDRESSES_COLLECTION_NAME, expectedAddresses); return this._checkRecords(ADDRESSES_COLLECTION_NAME, expectedAddresses);
sendAsyncMessage("FormAutofillTest:areAddressesMatching", areMatched);
}, },
async checkCreditCards({expectedCreditCards}) { async checkCreditCards({expectedCreditCards}) {
const areMatched = await this._checkRecords(CREDITCARDS_COLLECTION_NAME, expectedCreditCards); return this._checkRecords(CREDITCARDS_COLLECTION_NAME, expectedCreditCards);
sendAsyncMessage("FormAutofillTest:areCreditCardsMatching", areMatched);
}, },
observe(subject, topic, data) { observe(subject, topic, data) {
assert.ok(topic === "formautofill-storage-changed"); if (!destroyed) {
assert.ok(topic === "formautofill-storage-changed");
}
sendAsyncMessage("formautofill-storage-changed", {subject: null, topic, data}); sendAsyncMessage("formautofill-storage-changed", {subject: null, topic, data});
}, },
}; };
@ -187,62 +188,58 @@ var ParentUtils = {
Services.obs.addObserver(ParentUtils, "formautofill-storage-changed"); Services.obs.addObserver(ParentUtils, "formautofill-storage-changed");
Services.mm.addMessageListener("FormAutofill:FieldsIdentified", () => { Services.mm.addMessageListener("FormAutofill:FieldsIdentified", () => {
sendAsyncMessage("FormAutofillTest:FieldsIdentified"); return null;
}); });
addMessageListener("FormAutofillTest:AddAddress", (msg) => { addMessageListener("FormAutofillTest:AddAddress", (msg) => {
ParentUtils.operateAddress("add", msg, "FormAutofillTest:AddressAdded"); return ParentUtils.operateAddress("add", msg);
}); });
addMessageListener("FormAutofillTest:RemoveAddress", (msg) => { addMessageListener("FormAutofillTest:RemoveAddress", (msg) => {
ParentUtils.operateAddress("remove", msg, "FormAutofillTest:AddressRemoved"); return ParentUtils.operateAddress("remove", msg);
}); });
addMessageListener("FormAutofillTest:UpdateAddress", (msg) => { addMessageListener("FormAutofillTest:UpdateAddress", (msg) => {
ParentUtils.operateAddress("update", msg, "FormAutofillTest:AddressUpdated"); return ParentUtils.operateAddress("update", msg);
}); });
addMessageListener("FormAutofillTest:CheckAddresses", (msg) => { addMessageListener("FormAutofillTest:CheckAddresses", (msg) => {
ParentUtils.checkAddresses(msg); return ParentUtils.checkAddresses(msg);
}); });
addMessageListener("FormAutofillTest:CleanUpAddresses", (msg) => { addMessageListener("FormAutofillTest:CleanUpAddresses", (msg) => {
ParentUtils.cleanUpAddresses(); return ParentUtils.cleanUpAddresses();
}); });
addMessageListener("FormAutofillTest:AddCreditCard", (msg) => { addMessageListener("FormAutofillTest:AddCreditCard", (msg) => {
ParentUtils.operateCreditCard("add", msg, "FormAutofillTest:CreditCardAdded"); return ParentUtils.operateCreditCard("add", msg);
}); });
addMessageListener("FormAutofillTest:RemoveCreditCard", (msg) => { addMessageListener("FormAutofillTest:RemoveCreditCard", (msg) => {
ParentUtils.operateCreditCard("remove", msg, "FormAutofillTest:CreditCardRemoved"); return ParentUtils.operateCreditCard("remove", msg);
}); });
addMessageListener("FormAutofillTest:CheckCreditCards", (msg) => { addMessageListener("FormAutofillTest:CheckCreditCards", (msg) => {
ParentUtils.checkCreditCards(msg); return ParentUtils.checkCreditCards(msg);
}); });
addMessageListener("FormAutofillTest:CleanUpCreditCards", (msg) => { addMessageListener("FormAutofillTest:CleanUpCreditCards", (msg) => {
ParentUtils.cleanUpCreditCards(); return ParentUtils.cleanUpCreditCards();
}); });
addMessageListener("FormAutofillTest:CanTestOSKeyStoreLogin", (msg) => { addMessageListener("FormAutofillTest:CanTestOSKeyStoreLogin", (msg) => {
sendAsyncMessage("FormAutofillTest:CanTestOSKeyStoreLoginResult", return {canTest: OSKeyStoreTestUtils.canTestOSKeyStoreLogin()};
{canTest: OSKeyStoreTestUtils.canTestOSKeyStoreLogin()});
}); });
addMessageListener("FormAutofillTest:OSKeyStoreLogin", async (msg) => { addMessageListener("FormAutofillTest:OSKeyStoreLogin", async (msg) => {
await OSKeyStoreTestUtils.waitForOSKeyStoreLogin(msg.login); await OSKeyStoreTestUtils.waitForOSKeyStoreLogin(msg.login);
sendAsyncMessage("FormAutofillTest:OSKeyStoreLoggedIn");
}); });
addMessageListener("setup", async () => { addMessageListener("setup", async () => {
ParentUtils.setup(); ParentUtils.setup();
sendAsyncMessage("setup-finished", {});
}); });
addMessageListener("cleanup", async () => { addMessageListener("cleanup", async () => {
destroyed = true;
await ParentUtils.cleanup(); await ParentUtils.cleanup();
sendAsyncMessage("cleanup-finished", {});
}); });

View file

@ -44,8 +44,8 @@ add_task(async function test_DE_is_valid_testcase() {
chromeScript.destroy(); chromeScript.destroy();
}); });
let result = chromeScript.sendSyncMessage("CheckSubKeys"); let result = await chromeScript.sendQuery("CheckSubKeys");
ok(result[0][0], "Check that there are no sub_keys for the test country"); ok(result, "Check that there are no sub_keys for the test country");
}); });
add_task(async function test_form_will_submit_without_sub_keys() { add_task(async function test_form_will_submit_without_sub_keys() {

View file

@ -16,7 +16,6 @@
#include "nsQueryObject.h" #include "nsQueryObject.h"
#include "mozilla/dom/URL.h" #include "mozilla/dom/URL.h"
#include "nsDOMWindowList.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"

View file

@ -273,7 +273,7 @@ add_task(async function testActiveTabOnNonExistingSidebar() {
// to simulate the scenario where an extension has installed a sidebar // to simulate the scenario where an extension has installed a sidebar
// which has been saved in the preference but it doesn't exist anymore. // which has been saved in the preference but it doesn't exist anymore.
await SpecialPowers.pushPrefEnv({ await SpecialPowers.pushPrefEnv({
set: [["devtools.inspector.activeSidebar"], "unexisting-sidebar-id"], set: [["devtools.inspector.activeSidebar", "unexisting-sidebar-id"]],
}); });
const res = await openInspectorForURL("about:blank"); const res = await openInspectorForURL("about:blank");

View file

@ -34,7 +34,7 @@ const HTML_VOID_ELEMENTS = [
// element markup and their respective title tooltip text. // element markup and their respective title tooltip text.
const DISPLAY_TYPES = { const DISPLAY_TYPES = {
"flex": INSPECTOR_L10N.getStr("markupView.display.flex.tooltiptext"), "flex": INSPECTOR_L10N.getStr("markupView.display.flex.tooltiptext"),
"inline-flex": INSPECTOR_L10N.getStr("markupView.display.flex.tooltiptext"), "inline-flex": INSPECTOR_L10N.getStr("markupView.display.inlineFlex.tooltiptext"),
"grid": INSPECTOR_L10N.getStr("markupView.display.grid.tooltiptext"), "grid": INSPECTOR_L10N.getStr("markupView.display.grid.tooltiptext"),
"inline-grid": INSPECTOR_L10N.getStr("markupView.display.inlineGrid.tooltiptext"), "inline-grid": INSPECTOR_L10N.getStr("markupView.display.inlineGrid.tooltiptext"),
"subgrid": INSPECTOR_L10N.getStr("markupView.display.subgrid.tooltiptiptext"), "subgrid": INSPECTOR_L10N.getStr("markupView.display.subgrid.tooltiptiptext"),

View file

@ -456,6 +456,8 @@ var closeTabAndToolbox = async function(tab = gBrowser.selectedTab) {
} }
await removeTab(tab); await removeTab(tab);
await new Promise(resolve => setTimeout(resolve, 0));
}; };
/** /**
@ -596,10 +598,8 @@ function waitForClipboardPromise(setup, expected) {
* @return {Promise} resolves when the preferences have been updated * @return {Promise} resolves when the preferences have been updated
*/ */
function pushPref(preferenceName, value) { function pushPref(preferenceName, value) {
return new Promise(resolve => { const options = {"set": [[preferenceName, value]]};
const options = {"set": [[preferenceName, value]]}; return SpecialPowers.pushPrefEnv(options);
SpecialPowers.pushPrefEnv(options, resolve);
});
} }
/** /**

View file

@ -92,7 +92,7 @@ addEventListener("load", startTest);
// This test needs to add tabs that are controlled by a service worker // This test needs to add tabs that are controlled by a service worker
// so use some special powers to dig around and find gBrowser // so use some special powers to dig around and find gBrowser
let {gBrowser} = SpecialPowers._getTopChromeWindow(SpecialPowers.window.get()); let {gBrowser} = SpecialPowers._getTopChromeWindow(SpecialPowers.window);
SimpleTest.registerCleanupFunction(() => { SimpleTest.registerCleanupFunction(() => {
while (gBrowser.tabs.length > 1) { while (gBrowser.tabs.length > 1) {

View file

@ -16,6 +16,7 @@
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/Location.h" #include "mozilla/dom/Location.h"
#include "mozilla/dom/LocationBinding.h" #include "mozilla/dom/LocationBinding.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/WindowBinding.h" #include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/WindowGlobalChild.h" #include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/dom/WindowGlobalParent.h"
@ -90,6 +91,12 @@ already_AddRefed<BrowsingContext> BrowsingContext::Get(uint64_t aId) {
return do_AddRef(sBrowsingContexts->Get(aId)); return do_AddRef(sBrowsingContexts->Get(aId));
} }
/* static */
already_AddRefed<BrowsingContext> BrowsingContext::GetFromWindow(
WindowProxyHolder& aProxy) {
return do_AddRef(aProxy.get());
}
CanonicalBrowsingContext* BrowsingContext::Canonical() { CanonicalBrowsingContext* BrowsingContext::Canonical() {
return CanonicalBrowsingContext::Cast(this); return CanonicalBrowsingContext::Cast(this);
} }
@ -551,6 +558,45 @@ JSObject* BrowsingContext::WrapObject(JSContext* aCx,
return BrowsingContext_Binding::Wrap(aCx, this, aGivenProto); return BrowsingContext_Binding::Wrap(aCx, this, aGivenProto);
} }
bool BrowsingContext::WriteStructuredClone(JSContext* aCx,
JSStructuredCloneWriter* aWriter,
StructuredCloneHolder* aHolder) {
return (JS_WriteUint32Pair(aWriter, SCTAG_DOM_BROWSING_CONTEXT, 0) &&
JS_WriteUint32Pair(aWriter, uint32_t(Id()), uint32_t(Id() >> 32)));
}
/* static */
JSObject* BrowsingContext::ReadStructuredClone(JSContext* aCx,
JSStructuredCloneReader* aReader,
StructuredCloneHolder* aHolder) {
uint32_t idLow = 0;
uint32_t idHigh = 0;
if (!JS_ReadUint32Pair(aReader, &idLow, &idHigh)) {
return nullptr;
}
uint64_t id = uint64_t(idHigh) << 32 | idLow;
// Note: Do this check after reading our ID data. Returning null will abort
// the decode operation anyway, but we should at least be as safe as possible.
if (NS_WARN_IF(!NS_IsMainThread())) {
MOZ_DIAGNOSTIC_ASSERT(false,
"We shouldn't be trying to decode a BrowsingContext "
"on a background thread.");
return nullptr;
}
JS::RootedValue val(aCx, JS::NullValue());
// We'll get rooting hazard errors from the RefPtr destructor if it isn't
// destroyed before we try to return a raw JSObject*, so create it in its own
// scope.
if (RefPtr<BrowsingContext> context = Get(id)) {
if (!GetOrCreateDOMReflector(aCx, context, &val) || !val.isObject()) {
return nullptr;
}
}
return val.toObjectOrNull();
}
void BrowsingContext::NotifyUserGestureActivation() { void BrowsingContext::NotifyUserGestureActivation() {
// We would set the user gesture activation flag on the top level browsing // We would set the user gesture activation flag on the top level browsing
// context, which would automatically be sync to other top level browsing // context, which would automatically be sync to other top level browsing

View file

@ -51,6 +51,7 @@ template <typename>
struct Nullable; struct Nullable;
template <typename T> template <typename T>
class Sequence; class Sequence;
class StructuredCloneHolder;
struct WindowPostMessageOptions; struct WindowPostMessageOptions;
class WindowProxyHolder; class WindowProxyHolder;
@ -104,6 +105,13 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
return Get(aId); return Get(aId);
} }
static already_AddRefed<BrowsingContext> GetFromWindow(
WindowProxyHolder& aProxy);
static already_AddRefed<BrowsingContext> GetFromWindow(
GlobalObject&, WindowProxyHolder& aProxy) {
return GetFromWindow(aProxy);
}
// Create a brand-new BrowsingContext object. // Create a brand-new BrowsingContext object.
static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent, static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent,
BrowsingContext* aOpener, BrowsingContext* aOpener,
@ -266,6 +274,12 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
JSObject* WrapObject(JSContext* aCx); JSObject* WrapObject(JSContext* aCx);
static JSObject* ReadStructuredClone(JSContext* aCx,
JSStructuredCloneReader* aReader,
StructuredCloneHolder* aHolder);
bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter,
StructuredCloneHolder* aHolder);
void StartDelayedAutoplayMediaComponents(); void StartDelayedAutoplayMediaComponents();
/** /**

View file

@ -8,15 +8,13 @@
onload="setTimeout(nextTest, 0);" onload="setTimeout(nextTest, 0);"
title="bug 293235 test"> title="bug 293235 test">
<script src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/> <script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
<script type="application/javascript" src="docshell_helpers.js" /> <script type="application/javascript" src="docshell_helpers.js" />
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<script type="application/javascript"><![CDATA[ <script type="application/javascript"><![CDATA[
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); var {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
// Define the generator-iterator for the tests. // Define the generator-iterator for the tests.
var tests = testIterator(); var tests = testIterator();

View file

@ -8,8 +8,6 @@
onload="setTimeout(nextTest, 0);" onload="setTimeout(nextTest, 0);"
title="bug 396649 test"> title="bug 396649 test">
<script src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/> <script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
<script type="application/javascript" src="docshell_helpers.js" /> <script type="application/javascript" src="docshell_helpers.js" />

View file

@ -9,8 +9,7 @@
title="bug 89419 test"> title="bug 89419 test">
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" /> <script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
<script src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/> <script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
<script src="chrome://mochikit/content/tests/SimpleTest/specialpowers.js"/>
<script type="application/javascript" src="docshell_helpers.js" /> <script type="application/javascript" src="docshell_helpers.js" />
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>

View file

@ -44,18 +44,20 @@ function checkLoadFrame1() {
myFrame1.src = CROSS_ORIGIN_URI; myFrame1.src = CROSS_ORIGIN_URI;
} }
function checkNavFrame1() { async function checkNavFrame1() {
myFrame1.removeEventListener("load", checkNavFrame1); myFrame1.removeEventListener("load", checkNavFrame1);
is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, CROSS_ORIGIN_URI, is(await SpecialPowers.spawn(myFrame1, [], () => this.content.location.href),
CROSS_ORIGIN_URI,
"cross origin dummy loaded into frame1"); "cross origin dummy loaded into frame1");
myFrame1.addEventListener("load", checkBackNavFrame1); myFrame1.addEventListener("load", checkBackNavFrame1);
myFrame1.src = SAME_ORIGIN_URI + "#bar"; myFrame1.src = SAME_ORIGIN_URI + "#bar";
} }
function checkBackNavFrame1() { async function checkBackNavFrame1() {
myFrame1.removeEventListener("load", checkBackNavFrame1); myFrame1.removeEventListener("load", checkBackNavFrame1);
is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI + "#bar", is(await SpecialPowers.spawn(myFrame1, [], () => this.content.location.href),
SAME_ORIGIN_URI + "#bar",
"navagiating back to same origin dummy for frame1"); "navagiating back to same origin dummy for frame1");
checkFinish(); checkFinish();
} }

View file

@ -55,10 +55,11 @@ function navigateByHyperlink(name) {
// Functions that call into Mochitest framework // Functions that call into Mochitest framework
// ///////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
function isNavigated(wnd, message) { async function isNavigated(wnd, message) {
var result = null; var result = null;
try { try {
result = SpecialPowers.wrap(wnd).document.body.innerHTML.trim(); result = await SpecialPowers.spawn(
wnd, [], () => this.content.document.body.innerHTML.trim());
} catch (ex) { } catch (ex) {
result = ex; result = ex;
} }

View file

@ -61,11 +61,11 @@ function testChild3() {
} }
} }
xpcWaitForFinishedFrames(function() { xpcWaitForFinishedFrames(async function() {
isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location."); await isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open."); await isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form."); await isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink."); await isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
window0.close(); window0.close();
window1.close(); window1.close();

View file

@ -19,11 +19,11 @@ window.onload = function() {
navigateByForm("child2"); navigateByForm("child2");
navigateByHyperlink("child3"); navigateByHyperlink("child3");
xpcWaitForFinishedFrames(function() { xpcWaitForFinishedFrames(async function() {
isNavigated(frames[0], "Should be able to navigate off-domain child by setting location."); await isNavigated(frames[0], "Should be able to navigate off-domain child by setting location.");
isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open."); await isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open.");
isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form."); await isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form.");
isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink."); await isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink.");
xpcCleanupWindows(); xpcCleanupWindows();
SimpleTest.finish(); SimpleTest.finish();

View file

@ -19,11 +19,11 @@ window.onload = function() {
navigateByForm("child2_child0"); navigateByForm("child2_child0");
navigateByHyperlink("child3_child0"); navigateByHyperlink("child3_child0");
xpcWaitForFinishedFrames(function() { xpcWaitForFinishedFrames(async function() {
isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location."); await isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location.");
isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open."); await isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open.");
isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form."); await isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form.");
isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink."); await isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink.");
xpcCleanupWindows(); xpcCleanupWindows();
SimpleTest.finish(); SimpleTest.finish();

View file

@ -19,11 +19,11 @@ window.onload = function() {
navigateByForm("window2"); navigateByForm("window2");
navigateByHyperlink("window3"); navigateByHyperlink("window3");
xpcWaitForFinishedFrames(function() { xpcWaitForFinishedFrames(async function() {
isNavigated(window0, "Should be able to navigate popup by setting location."); await isNavigated(window0, "Should be able to navigate popup by setting location.");
isNavigated(window1, "Should be able to navigate popup by calling window.open."); await isNavigated(window1, "Should be able to navigate popup by calling window.open.");
isNavigated(window2, "Should be able to navigate popup by submitting form."); await isNavigated(window2, "Should be able to navigate popup by submitting form.");
isNavigated(window3, "Should be able to navigate popup by targeted hyperlink."); await isNavigated(window3, "Should be able to navigate popup by targeted hyperlink.");
window0.close(); window0.close();
window1.close(); window1.close();

View file

@ -35,11 +35,11 @@ function testChild3() {
window3 = window.open("navigate.html#child3,hyperlink", "window3", "width=10,height=10"); window3 = window.open("navigate.html#child3,hyperlink", "window3", "width=10,height=10");
} }
xpcWaitForFinishedFrames(function() { xpcWaitForFinishedFrames(async function() {
isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location."); await isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open."); await isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form."); await isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink."); await isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
window0.close(); window0.close();
window1.close(); window1.close();

View file

@ -16,11 +16,11 @@ window.onload = function() {
'<iframe src="navigate.html#child2,form"></iframe>' + '<iframe src="navigate.html#child2,form"></iframe>' +
'<iframe src="navigate.html#child3,hyperlink"></iframe>'; '<iframe src="navigate.html#child3,hyperlink"></iframe>';
xpcWaitForFinishedFrames(function() { xpcWaitForFinishedFrames(async function() {
isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location."); await isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location.");
isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open."); await isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open.");
isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form."); await isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form.");
isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink."); await isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink.");
xpcCleanupWindows(); xpcCleanupWindows();
SimpleTest.finish(); SimpleTest.finish();

View file

@ -0,0 +1,62 @@
"use strict";
add_task(async function test_BrowsingContext_structured_clone() {
let browser = Services.appShell.createWindowlessBrowser(false);
let frame = browser.document.createElement("iframe");
browser.document.body.appendChild(frame);
let {browsingContext} = frame;
let sch = new StructuredCloneHolder({browsingContext});
let deserialize = () => sch.deserialize({}, true);
// Check that decoding a live browsing context produces the correct
// object.
equal(deserialize().browsingContext, browsingContext,
"Got correct browsing context from StructuredClone deserialize");
// Check that decoding a second time still succeeds.
equal(deserialize().browsingContext, browsingContext,
"Got correct browsing context from second StructuredClone deserialize");
// Destroy the browsing context and make sure that the decode fails
// with a DataCloneError.
//
// Making sure the BrowsingContext is actually destroyed by the time
// we do the second decode is a bit tricky. We obviously have clear
// our local references to it, and give the GC a chance to reap them.
// And we also, of course, have to destroy the frame that it belongs
// to, or its frame loader and window global would hold it alive.
//
// Beyond that, we don't *have* to reload or destroy the parent
// document, but we do anyway just to be safe.
//
// Then comes the tricky bit: The WindowGlobal actors (which keep
// references to their BrowsingContexts) require an IPC round trip to
// be completely destroyed, even though they're in-process, so we make
// a quick trip through the event loop, and then run the CC in order
// to allow their (now snow-white) references to be collected.
frame.remove();
frame = null;
browsingContext = null;
browser.document.location.reload();
browser.close();
Cu.forceGC();
// Give the IPC messages that destroy the actors a chance to be
// processed.
await new Promise(executeSoon);
Cu.forceCC();
// OK. We can be fairly confident that the BrowsingContext object
// stored in our structured clone data has been destroyed. Make sure
// that attempting to decode it again leads to the appropriate error.
Assert.throws(deserialize, e => e.name === "DataCloneError",
"Should get a DataCloneError when trying to decode a dead BrowsingContext");
});

View file

@ -2,6 +2,7 @@
head = head_docshell.js head = head_docshell.js
[test_bug442584.js] [test_bug442584.js]
[test_browsing_context_structured_clone.js]
[test_nsDefaultURIFixup.js] [test_nsDefaultURIFixup.js]
[test_nsDefaultURIFixup_search.js] [test_nsDefaultURIFixup_search.js]
skip-if = os == 'android' skip-if = os == 'android'

View file

@ -584,7 +584,7 @@ nsresult Selection::AddTableCellRange(nsRange* aRange, bool* aDidAddRange,
mFrameSelection->mSelectingTableCellMode = tableMode; mFrameSelection->mSelectingTableCellMode = tableMode;
*aDidAddRange = true; *aDidAddRange = true;
return AddItem(aRange, aOutIndex); return AddRangesForSelectableNodes(aRange, aOutIndex);
} }
// TODO: Figure out TableSelection::Column and TableSelection::AllCells // TODO: Figure out TableSelection::Column and TableSelection::AllCells
@ -927,8 +927,9 @@ void Selection::UserSelectRangesToAdd(nsRange* aItem,
} }
} }
nsresult Selection::AddItem(nsRange* aItem, int32_t* aOutIndex, nsresult Selection::AddRangesForSelectableNodes(nsRange* aItem,
bool aNoStartSelect) { int32_t* aOutIndex,
bool aNoStartSelect) {
if (!aItem) return NS_ERROR_NULL_POINTER; if (!aItem) return NS_ERROR_NULL_POINTER;
if (!aItem->IsPositioned()) return NS_ERROR_UNEXPECTED; if (!aItem->IsPositioned()) return NS_ERROR_UNEXPECTED;
@ -1010,7 +1011,7 @@ nsresult Selection::AddItem(nsRange* aItem, int32_t* aOutIndex,
GetDirection() == eDirPrevious ? 0 : rangesToAdd.Length() - 1; GetDirection() == eDirPrevious ? 0 : rangesToAdd.Length() - 1;
for (size_t i = 0; i < rangesToAdd.Length(); ++i) { for (size_t i = 0; i < rangesToAdd.Length(); ++i) {
int32_t index; int32_t index;
nsresult rv = AddItemInternal(rangesToAdd[i], &index); nsresult rv = MaybeAddRangeAndTruncateOverlaps(rangesToAdd[i], &index);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (i == newAnchorFocusIndex) { if (i == newAnchorFocusIndex) {
*aOutIndex = index; *aOutIndex = index;
@ -1021,20 +1022,23 @@ nsresult Selection::AddItem(nsRange* aItem, int32_t* aOutIndex,
} }
return NS_OK; return NS_OK;
} }
return AddItemInternal(aItem, aOutIndex); return MaybeAddRangeAndTruncateOverlaps(aItem, aOutIndex);
} }
nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) { nsresult Selection::MaybeAddRangeAndTruncateOverlaps(nsRange* aRange,
MOZ_ASSERT(aItem); int32_t* aOutIndex) {
MOZ_ASSERT(aItem->IsPositioned()); MOZ_ASSERT(aRange);
MOZ_ASSERT(aRange->IsPositioned());
MOZ_ASSERT(aOutIndex); MOZ_ASSERT(aOutIndex);
*aOutIndex = -1; *aOutIndex = -1;
// a common case is that we have no ranges yet // a common case is that we have no ranges yet
if (mRanges.Length() == 0) { if (mRanges.Length() == 0) {
if (!mRanges.AppendElement(RangeData(aItem))) return NS_ERROR_OUT_OF_MEMORY; if (!mRanges.AppendElement(RangeData(aRange))) {
aItem->SetSelection(this); return NS_ERROR_OUT_OF_MEMORY;
}
aRange->SetSelection(this);
*aOutIndex = 0; *aOutIndex = 0;
return NS_OK; return NS_OK;
@ -1042,9 +1046,9 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
int32_t startIndex, endIndex; int32_t startIndex, endIndex;
nsresult rv = nsresult rv =
GetIndicesForInterval(aItem->GetStartContainer(), aItem->StartOffset(), GetIndicesForInterval(aRange->GetStartContainer(), aRange->StartOffset(),
aItem->GetEndContainer(), aItem->EndOffset(), false, aRange->GetEndContainer(), aRange->EndOffset(),
&startIndex, &endIndex); false, &startIndex, &endIndex);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (endIndex == -1) { if (endIndex == -1) {
@ -1061,8 +1065,8 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
// If the range is already contained in mRanges, silently succeed // If the range is already contained in mRanges, silently succeed
bool sameRange = EqualsRangeAtPoint( bool sameRange = EqualsRangeAtPoint(
aItem->GetStartContainer(), aItem->StartOffset(), aRange->GetStartContainer(), aRange->StartOffset(),
aItem->GetEndContainer(), aItem->EndOffset(), startIndex); aRange->GetEndContainer(), aRange->EndOffset(), startIndex);
if (sameRange) { if (sameRange) {
*aOutIndex = startIndex; *aOutIndex = startIndex;
return NS_OK; return NS_OK;
@ -1070,9 +1074,10 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
if (startIndex == endIndex) { if (startIndex == endIndex) {
// The new range doesn't overlap any existing ranges // The new range doesn't overlap any existing ranges
if (!mRanges.InsertElementAt(startIndex, RangeData(aItem))) if (!mRanges.InsertElementAt(startIndex, RangeData(aRange))) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
aItem->SetSelection(this); }
aRange->SetSelection(this);
*aOutIndex = startIndex; *aOutIndex = startIndex;
return NS_OK; return NS_OK;
} }
@ -1100,19 +1105,20 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
nsTArray<RangeData> temp; nsTArray<RangeData> temp;
for (int32_t i = overlaps.Length() - 1; i >= 0; i--) { for (int32_t i = overlaps.Length() - 1; i >= 0; i--) {
nsresult rv = SubtractRange(&overlaps[i], aItem, &temp); nsresult rv = SubtractRange(&overlaps[i], aRange, &temp);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
// Insert the new element into our "leftovers" array // Insert the new element into our "leftovers" array
int32_t insertionPoint; int32_t insertionPoint;
rv = FindInsertionPoint(&temp, aItem->GetStartContainer(), rv = FindInsertionPoint(&temp, aRange->GetStartContainer(),
aItem->StartOffset(), CompareToRangeStart, aRange->StartOffset(), CompareToRangeStart,
&insertionPoint); &insertionPoint);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!temp.InsertElementAt(insertionPoint, RangeData(aItem))) if (!temp.InsertElementAt(insertionPoint, RangeData(aRange))) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
}
// Merge the leftovers back in to mRanges // Merge the leftovers back in to mRanges
if (!mRanges.InsertElementsAt(startIndex, temp)) if (!mRanges.InsertElementsAt(startIndex, temp))
@ -1126,9 +1132,7 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
return NS_OK; return NS_OK;
} }
nsresult Selection::RemoveItem(nsRange* aItem) { nsresult Selection::RemoveRangeInternal(nsRange& aRange) {
if (!aItem) return NS_ERROR_NULL_POINTER;
// Find the range's index & remove it. We could use FindInsertionPoint to // Find the range's index & remove it. We could use FindInsertionPoint to
// get O(log n) time, but that requires many expensive DOM comparisons. // get O(log n) time, but that requires many expensive DOM comparisons.
// For even several thousand items, this is probably faster because the // For even several thousand items, this is probably faster because the
@ -1136,7 +1140,7 @@ nsresult Selection::RemoveItem(nsRange* aItem) {
int32_t idx = -1; int32_t idx = -1;
uint32_t i; uint32_t i;
for (i = 0; i < mRanges.Length(); i++) { for (i = 0; i < mRanges.Length(); i++) {
if (mRanges[i].mRange == aItem) { if (mRanges[i].mRange == &aRange) {
idx = (int32_t)i; idx = (int32_t)i;
break; break;
} }
@ -1144,7 +1148,7 @@ nsresult Selection::RemoveItem(nsRange* aItem) {
if (idx < 0) return NS_ERROR_DOM_NOT_FOUND_ERR; if (idx < 0) return NS_ERROR_DOM_NOT_FOUND_ERR;
mRanges.RemoveElementAt(idx); mRanges.RemoveElementAt(idx);
aItem->SetSelection(nullptr); aRange.SetSelection(nullptr);
return NS_OK; return NS_OK;
} }
@ -1152,7 +1156,7 @@ nsresult Selection::RemoveCollapsedRanges() {
uint32_t i = 0; uint32_t i = 0;
while (i < mRanges.Length()) { while (i < mRanges.Length()) {
if (mRanges[i].mRange->Collapsed()) { if (mRanges[i].mRange->Collapsed()) {
nsresult rv = RemoveItem(mRanges[i].mRange); nsresult rv = RemoveRangeInternal(*mRanges[i].mRange);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} else { } else {
++i; ++i;
@ -2037,7 +2041,7 @@ void Selection::AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
} }
if (!didAddRange) { if (!didAddRange) {
result = AddItem(range, &rangeIndex); result = AddRangesForSelectableNodes(range, &rangeIndex);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
aRv.Throw(result); aRv.Throw(result);
return; return;
@ -2083,7 +2087,7 @@ void Selection::AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
void Selection::RemoveRangeAndUnselectFramesAndNotifyListeners( void Selection::RemoveRangeAndUnselectFramesAndNotifyListeners(
nsRange& aRange, ErrorResult& aRv) { nsRange& aRange, ErrorResult& aRv) {
nsresult rv = RemoveItem(&aRange); nsresult rv = RemoveRangeInternal(aRange);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
aRv.Throw(rv); aRv.Throw(rv);
return; return;
@ -2267,7 +2271,7 @@ void Selection::Collapse(const RawRangeBoundary& aPoint, ErrorResult& aRv) {
#endif #endif
int32_t rangeIndex = -1; int32_t rangeIndex = -1;
result = AddItem(range, &rangeIndex); result = AddRangesForSelectableNodes(range, &rangeIndex);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
aRv.Throw(result); aRv.Throw(result);
return; return;
@ -2389,11 +2393,11 @@ nsresult Selection::SetAnchorFocusToRange(nsRange* aRange) {
bool collapsed = IsCollapsed(); bool collapsed = IsCollapsed();
nsresult res = RemoveItem(mAnchorFocusRange); nsresult res = RemoveRangeInternal(*mAnchorFocusRange);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
int32_t aOutIndex = -1; int32_t aOutIndex = -1;
res = AddItem(aRange, &aOutIndex, !collapsed); res = AddRangesForSelectableNodes(aRange, &aOutIndex, !collapsed);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
SetAnchorFocusRange(aOutIndex); SetAnchorFocusRange(aOutIndex);

View file

@ -161,17 +161,21 @@ class Selection final : public nsSupportsWeakReference,
ScrollAxis aVertical = ScrollAxis(), ScrollAxis aVertical = ScrollAxis(),
ScrollAxis aHorizontal = ScrollAxis(), ScrollAxis aHorizontal = ScrollAxis(),
int32_t aFlags = 0); int32_t aFlags = 0);
nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract, static nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract,
nsTArray<RangeData>* aOutput); nsTArray<RangeData>* aOutput);
private:
/** /**
* AddItem adds aRange to this Selection. If mUserInitiated is true, * Adds aRange to this Selection. If mUserInitiated is true,
* then aRange is first scanned for -moz-user-select:none nodes and split up * then aRange is first scanned for -moz-user-select:none nodes and split up
* into multiple ranges to exclude those before adding the resulting ranges * into multiple ranges to exclude those before adding the resulting ranges
* to this Selection. * to this Selection.
*/ */
nsresult AddItem(nsRange* aRange, int32_t* aOutIndex, nsresult AddRangesForSelectableNodes(nsRange* aRange, int32_t* aOutIndex,
bool aNoStartSelect = false); bool aNoStartSelect = false);
nsresult RemoveItem(nsRange* aRange); nsresult RemoveRangeInternal(nsRange& aRange);
public:
nsresult RemoveCollapsedRanges(); nsresult RemoveCollapsedRanges();
nsresult Clear(nsPresContext* aPresContext); nsresult Clear(nsPresContext* aPresContext);
nsresult Collapse(nsINode* aContainer, int32_t aOffset) { nsresult Collapse(nsINode* aContainer, int32_t aOffset) {
@ -737,13 +741,14 @@ class Selection final : public nsSupportsWeakReference,
int32_t* aEndIndex); int32_t* aEndIndex);
RangeData* FindRangeData(nsRange* aRange); RangeData* FindRangeData(nsRange* aRange);
void UserSelectRangesToAdd(nsRange* aItem, static void UserSelectRangesToAdd(nsRange* aItem,
nsTArray<RefPtr<nsRange>>& rangesToAdd); nsTArray<RefPtr<nsRange>>& rangesToAdd);
/** /**
* Helper method for AddItem. * Preserves the sorting of mRanges.
*/ */
nsresult AddItemInternal(nsRange* aRange, int32_t* aOutIndex); nsresult MaybeAddRangeAndTruncateOverlaps(nsRange* aRange,
int32_t* aOutIndex);
Document* GetDocument() const; Document* GetDocument() const;
nsPIDOMWindowOuter* GetWindow() const; nsPIDOMWindowOuter* GetWindow() const;

View file

@ -10,6 +10,8 @@
#include "mozilla/AutoRestore.h" #include "mozilla/AutoRestore.h"
#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h" #include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/BrowsingContextBinding.h"
#include "mozilla/dom/StructuredCloneBlob.h" #include "mozilla/dom/StructuredCloneBlob.h"
#include "mozilla/dom/Directory.h" #include "mozilla/dom/Directory.h"
#include "mozilla/dom/DirectoryBinding.h" #include "mozilla/dom/DirectoryBinding.h"
@ -910,6 +912,10 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
return ReadInputStream(aCx, aIndex, this); return ReadInputStream(aCx, aIndex, this);
} }
if (aTag == SCTAG_DOM_BROWSING_CONTEXT) {
return BrowsingContext::ReadStructuredClone(aCx, aReader, this);
}
return ReadFullySerializableObjects(aCx, aReader, aTag); return ReadFullySerializableObjects(aCx, aReader, aTag);
} }
@ -973,6 +979,15 @@ bool StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
} }
} }
// See if this is a BrowsingContext object.
if (mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
mStructuredCloneScope == StructuredCloneScope::DifferentProcess) {
BrowsingContext* holder = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(BrowsingContext, &obj, holder))) {
return holder->WriteStructuredClone(aCx, aWriter, this);
}
}
// See if this is a WasmModule. // See if this is a WasmModule.
if ((mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread || if ((mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
mStructuredCloneScope == mStructuredCloneScope ==

View file

@ -137,6 +137,8 @@ enum StructuredCloneTags {
SCTAG_DOM_STRUCTURED_CLONE_HOLDER, SCTAG_DOM_STRUCTURED_CLONE_HOLDER,
SCTAG_DOM_BROWSING_CONTEXT,
// IMPORTANT: If you plan to add an new IDB tag, it _must_ be add before the // IMPORTANT: If you plan to add an new IDB tag, it _must_ be add before the
// "less stable" tags! // "less stable" tags!
}; };

View file

@ -9,7 +9,6 @@
#include "mozilla/dom/WindowBinding.h" #include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/WindowProxyHolder.h" #include "mozilla/dom/WindowProxyHolder.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsDOMWindowList.h"
#include "nsGlobalWindow.h" #include "nsGlobalWindow.h"
#include "nsHTMLDocument.h" #include "nsHTMLDocument.h"
#include "nsJSUtils.h" #include "nsJSUtils.h"
@ -18,18 +17,17 @@
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
static bool ShouldExposeChildWindow(nsString& aNameBeingResolved, static bool ShouldExposeChildWindow(const nsString& aNameBeingResolved,
BrowsingContext* aChild) { BrowsingContext* aChild) {
nsPIDOMWindowOuter* child = aChild->GetDOMWindow(); Element* e = aChild->GetEmbedderElement();
Element* e = child->GetFrameElementInternal();
if (e && e->IsInShadowTree()) { if (e && e->IsInShadowTree()) {
return false; return false;
} }
// If we're same-origin with the child, go ahead and expose it. // If we're same-origin with the child, go ahead and expose it.
nsPIDOMWindowOuter* child = aChild->GetDOMWindow();
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(child); nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(child);
NS_ENSURE_TRUE(sop, false); if (sop && nsContentUtils::SubjectPrincipal()->Equals(sop->GetPrincipal())) {
if (nsContentUtils::SubjectPrincipal()->Equals(sop->GetPrincipal())) {
return true; return true;
} }
@ -169,23 +167,12 @@ bool WindowNamedPropertiesHandler::ownPropNames(
// The names live on the outer window, which might be null // The names live on the outer window, which might be null
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal(); nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();
if (outer) { if (outer) {
nsDOMWindowList* childWindows = outer->GetFrames(); if (BrowsingContext* bc = outer->GetBrowsingContext()) {
if (childWindows) { for (const auto& child : bc->GetChildren()) {
uint32_t length = childWindows->GetLength(); const nsString& name = child->Name();
for (uint32_t i = 0; i < length; ++i) { if (!name.IsEmpty() && !names.Contains(name)) {
nsCOMPtr<nsIDocShellTreeItem> item =
childWindows->GetDocShellTreeItemAt(i);
// This is a bit silly, since we could presumably just do
// item->GetWindow(). But it's not obvious whether this does the same
// thing as GetChildWindow() with the item's name (due to the complexity
// of FindChildWithName). Since GetChildWindow is what we use in
// getOwnPropDescriptor, let's try to be consistent.
nsString name;
item->GetName(name);
if (!names.Contains(name)) {
// Make sure we really would expose it from getOwnPropDescriptor. // Make sure we really would expose it from getOwnPropDescriptor.
RefPtr<BrowsingContext> child = win->GetChildWindow(name); if (ShouldExposeChildWindow(name, child)) {
if (child && ShouldExposeChildWindow(name, child)) {
names.AppendElement(name); names.AppendElement(name);
} }
} }

View file

@ -336,7 +336,6 @@ UNIFIED_SOURCES += [
'nsDOMNavigationTiming.cpp', 'nsDOMNavigationTiming.cpp',
'nsDOMSerializer.cpp', 'nsDOMSerializer.cpp',
'nsDOMTokenList.cpp', 'nsDOMTokenList.cpp',
'nsDOMWindowList.cpp',
'nsFocusManager.cpp', 'nsFocusManager.cpp',
'nsFrameLoader.cpp', 'nsFrameLoader.cpp',
'nsFrameLoaderOwner.cpp', 'nsFrameLoaderOwner.cpp',

View file

@ -1,82 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "nsDOMWindowList.h"
#include "FlushType.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/Document.h"
#include "nsIDOMWindow.h"
#include "nsIDocShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIScriptGlobalObject.h"
#include "nsIWebNavigation.h"
using namespace mozilla;
nsDOMWindowList::nsDOMWindowList(nsIDocShell* aDocShell) {
SetDocShell(aDocShell);
}
nsDOMWindowList::~nsDOMWindowList() {}
void nsDOMWindowList::SetDocShell(nsIDocShell* aDocShell) {
mDocShellNode = aDocShell; // Weak Reference
}
void nsDOMWindowList::EnsureFresh() {
nsCOMPtr<nsIWebNavigation> shellAsNav = do_QueryInterface(mDocShellNode);
if (shellAsNav) {
nsCOMPtr<dom::Document> doc;
shellAsNav->GetDocument(getter_AddRefs(doc));
if (doc) {
doc->FlushPendingNotifications(FlushType::ContentAndNotify);
}
}
}
uint32_t nsDOMWindowList::GetLength() {
EnsureFresh();
NS_ENSURE_TRUE(mDocShellNode, 0);
int32_t length;
nsresult rv = mDocShellNode->GetChildCount(&length);
NS_ENSURE_SUCCESS(rv, 0);
return uint32_t(length);
}
already_AddRefed<nsPIDOMWindowOuter> nsDOMWindowList::IndexedGetter(
uint32_t aIndex) {
nsCOMPtr<nsIDocShellTreeItem> item = GetDocShellTreeItemAt(aIndex);
if (!item) {
return nullptr;
}
nsCOMPtr<nsPIDOMWindowOuter> window = item->GetWindow();
MOZ_ASSERT(window);
return window.forget();
}
already_AddRefed<nsPIDOMWindowOuter> nsDOMWindowList::NamedItem(
const nsAString& aName) {
EnsureFresh();
if (!mDocShellNode) {
return nullptr;
}
nsCOMPtr<nsIDocShellTreeItem> item;
mDocShellNode->FindChildWithName(aName, false, false, nullptr, nullptr,
getter_AddRefs(item));
nsCOMPtr<nsPIDOMWindowOuter> childWindow(do_GetInterface(item));
return childWindow.forget();
}

View file

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef nsDOMWindowList_h___
#define nsDOMWindowList_h___
#include "nsCOMPtr.h"
#include <stdint.h>
#include "nsIDocShell.h"
class nsIDocShell;
class nsIDOMWindow;
class nsDOMWindowList final {
public:
explicit nsDOMWindowList(nsIDocShell* aDocShell);
NS_INLINE_DECL_REFCOUNTING(nsDOMWindowList)
uint32_t GetLength();
already_AddRefed<nsPIDOMWindowOuter> IndexedGetter(uint32_t aIndex);
already_AddRefed<nsPIDOMWindowOuter> NamedItem(const nsAString& aName);
// local methods
void SetDocShell(nsIDocShell* aDocShell);
already_AddRefed<nsIDocShellTreeItem> GetDocShellTreeItemAt(uint32_t aIndex) {
EnsureFresh();
nsCOMPtr<nsIDocShellTreeItem> item;
if (mDocShellNode) {
mDocShellNode->GetChildAt(aIndex, getter_AddRefs(item));
}
return item.forget();
}
protected:
~nsDOMWindowList();
// Note: this function may flush and cause mDocShellNode to become null.
void EnsureFresh();
nsIDocShell* mDocShellNode; // Weak Reference
};
#endif // nsDOMWindowList_h___

View file

@ -50,7 +50,6 @@
#include "nsISizeOfEventTarget.h" #include "nsISizeOfEventTarget.h"
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "nsArrayUtils.h" #include "nsArrayUtils.h"
#include "nsDOMWindowList.h"
#include "mozilla/dom/WakeLock.h" #include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h" #include "mozilla/dom/power/PowerManagerService.h"
#include "nsIContentSecurityPolicy.h" #include "nsIContentSecurityPolicy.h"
@ -2708,11 +2707,7 @@ bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
FORWARD_TO_OUTER(GetClosedOuter, (), true); FORWARD_TO_OUTER(GetClosedOuter, (), true);
} }
nsDOMWindowList* nsGlobalWindowInner::GetFrames() { Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
FORWARD_TO_OUTER(GetFrames, (), nullptr);
}
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowInner::IndexedGetter(
uint32_t aIndex) { uint32_t aIndex) {
FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr); FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
} }

View file

@ -77,7 +77,6 @@ class nsITimeoutHandler;
class nsIWebBrowserChrome; class nsIWebBrowserChrome;
class mozIDOMWindowProxy; class mozIDOMWindowProxy;
class nsDOMWindowList;
class nsScreen; class nsScreen;
class nsHistory; class nsHistory;
class nsGlobalWindowObserver; class nsGlobalWindowObserver;
@ -381,7 +380,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSIINTERFACEREQUESTOR
// WebIDL interface. // WebIDL interface.
already_AddRefed<nsPIDOMWindowOuter> IndexedGetter(uint32_t aIndex); mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetter(
uint32_t aIndex);
static bool IsPrivilegedChromeWindow(JSContext* /* unused */, JSObject* aObj); static bool IsPrivilegedChromeWindow(JSContext* /* unused */, JSObject* aObj);
@ -612,7 +612,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
void Focus(mozilla::ErrorResult& aError); void Focus(mozilla::ErrorResult& aError);
nsresult Focus() override; nsresult Focus() override;
void Blur(mozilla::ErrorResult& aError); void Blur(mozilla::ErrorResult& aError);
nsDOMWindowList* GetFrames() final;
mozilla::dom::BrowsingContext* GetFrames(mozilla::ErrorResult& aError); mozilla::dom::BrowsingContext* GetFrames(mozilla::ErrorResult& aError);
uint32_t Length(); uint32_t Length();
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTop( mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTop(

View file

@ -48,7 +48,6 @@
#include "nsISizeOfEventTarget.h" #include "nsISizeOfEventTarget.h"
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
#include "nsArrayUtils.h" #include "nsArrayUtils.h"
#include "nsDOMWindowList.h"
#include "mozilla/dom/WakeLock.h" #include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h" #include "mozilla/dom/power/PowerManagerService.h"
#include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeOwner.h"
@ -510,8 +509,9 @@ class nsOuterWindowProxy : public MaybeCrossOriginObject<js::Wrapper> {
// Returns a non-null window only if id is an index and we have a // Returns a non-null window only if id is an index and we have a
// window at that index. // window at that index.
already_AddRefed<nsPIDOMWindowOuter> GetSubframeWindow( Nullable<WindowProxyHolder> GetSubframeWindow(JSContext* cx,
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const; JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const;
bool AppendIndexedPropertyNames(JSObject* proxy, bool AppendIndexedPropertyNames(JSObject* proxy,
JS::MutableHandleVector<jsid> props) const; JS::MutableHandleVector<jsid> props) const;
@ -784,7 +784,7 @@ bool nsOuterWindowProxy::delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete")); return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete"));
} }
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) { if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
// Fail (which means throw if strict, else return false). // Fail (which means throw if strict, else return false).
return result.failCantDeleteWindowElement(); return result.failCantDeleteWindowElement();
} }
@ -818,7 +818,7 @@ bool nsOuterWindowProxy::has(JSContext* cx, JS::Handle<JSObject*> proxy,
return hasOwn(cx, proxy, id, bp); return hasOwn(cx, proxy, id, bp);
} }
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) { if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
*bp = true; *bp = true;
return true; return true;
} }
@ -851,7 +851,7 @@ bool nsOuterWindowProxy::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp); return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp);
} }
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) { if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
*bp = true; *bp = true;
return true; return true;
} }
@ -982,28 +982,17 @@ bool nsOuterWindowProxy::GetSubframeWindow(JSContext* cx,
JS::Handle<jsid> id, JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp, JS::MutableHandle<JS::Value> vp,
bool& found) const { bool& found) const {
nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id); Nullable<WindowProxyHolder> frame = GetSubframeWindow(cx, proxy, id);
if (!frame) { if (frame.IsNull()) {
found = false; found = false;
return true; return true;
} }
found = true; found = true;
// Just return the window's global return WrapObject(cx, frame.Value(), vp);
nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(frame);
frame->EnsureInnerWindow();
JSObject* obj = global->GetGlobalJSObject();
// This null check fixes a hard-to-reproduce crash that occurs when we
// get here when we're mid-call to nsDocShell::Destroy. See bug 640904
// comment 105.
if (MOZ_UNLIKELY(!obj)) {
return xpc::Throw(cx, NS_ERROR_FAILURE);
}
vp.setObject(*obj);
return JS_WrapValue(cx, vp);
} }
already_AddRefed<nsPIDOMWindowOuter> nsOuterWindowProxy::GetSubframeWindow( Nullable<WindowProxyHolder> nsOuterWindowProxy::GetSubframeWindow(
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const { JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const {
uint32_t index = GetArrayIndexFromId(id); uint32_t index = GetArrayIndexFromId(id);
if (!IsArrayIndex(index)) { if (!IsArrayIndex(index)) {
@ -1300,7 +1289,6 @@ void nsGlobalWindowOuter::CleanUp() {
StartDying(); StartDying();
mFrames = nullptr;
mWindowUtils = nullptr; mWindowUtils = nullptr;
ClearControllers(); ClearControllers();
@ -2380,10 +2368,6 @@ void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
mTopLevelOuterContentWindow = mTopLevelOuterContentWindow =
!mIsChrome && GetScriptableTopInternal() == this; !mIsChrome && GetScriptableTopInternal() == this;
if (mFrames) {
mFrames->SetDocShell(aDocShell);
}
// Get our enclosing chrome shell and retrieve its global window impl, so // Get our enclosing chrome shell and retrieve its global window impl, so
// that we can do some forwarding to the chrome document. // that we can do some forwarding to the chrome document.
RefPtr<EventTarget> chromeEventHandler; RefPtr<EventTarget> chromeEventHandler;
@ -2475,10 +2459,6 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
mDocShell = nullptr; mDocShell = nullptr;
mBrowsingContext->ClearDocShell(); mBrowsingContext->ClearDocShell();
if (mFrames) {
mFrames->SetDocShell(nullptr);
}
MaybeForgiveSpamCount(); MaybeForgiveSpamCount();
CleanUp(); CleanUp();
} }
@ -3196,20 +3176,16 @@ bool nsGlobalWindowOuter::GetClosedOuter() {
bool nsGlobalWindowOuter::Closed() { return GetClosedOuter(); } bool nsGlobalWindowOuter::Closed() { return GetClosedOuter(); }
nsDOMWindowList* nsGlobalWindowOuter::GetFrames() { Nullable<WindowProxyHolder> nsGlobalWindowOuter::IndexedGetterOuter(
if (!mFrames && mDocShell) {
mFrames = new nsDOMWindowList(mDocShell);
}
return mFrames;
}
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::IndexedGetterOuter(
uint32_t aIndex) { uint32_t aIndex) {
nsDOMWindowList* windows = GetFrames(); BrowsingContext* bc = GetBrowsingContext();
NS_ENSURE_TRUE(windows, nullptr); NS_ENSURE_TRUE(bc, nullptr);
return windows->IndexedGetter(aIndex); const BrowsingContext::Children& children = bc->GetChildren();
if (aIndex < children.Length()) {
return WindowProxyHolder(children[aIndex]);
}
return nullptr;
} }
nsIControllers* nsGlobalWindowOuter::GetControllersOuter(ErrorResult& aError) { nsIControllers* nsGlobalWindowOuter::GetControllersOuter(ErrorResult& aError) {
@ -3962,9 +3938,8 @@ double nsGlobalWindowOuter::GetScrollXOuter() { return GetScrollXY(false).x; }
double nsGlobalWindowOuter::GetScrollYOuter() { return GetScrollXY(false).y; } double nsGlobalWindowOuter::GetScrollYOuter() { return GetScrollXY(false).y; }
uint32_t nsGlobalWindowOuter::Length() { uint32_t nsGlobalWindowOuter::Length() {
nsDOMWindowList* windows = GetFrames(); BrowsingContext* bc = GetBrowsingContext();
return bc ? bc->GetChildren().Length() : 0;
return windows ? windows->GetLength() : 0;
} }
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() { Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() {

View file

@ -74,7 +74,6 @@ class nsIWebBrowserChrome;
class mozIDOMWindowProxy; class mozIDOMWindowProxy;
class nsDocShellLoadState; class nsDocShellLoadState;
class nsDOMWindowList;
class nsScreen; class nsScreen;
class nsHistory; class nsHistory;
class nsGlobalWindowObserver; class nsGlobalWindowObserver;
@ -354,7 +353,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// nsIObserver // nsIObserver
NS_DECL_NSIOBSERVER NS_DECL_NSIOBSERVER
already_AddRefed<nsPIDOMWindowOuter> IndexedGetterOuter(uint32_t aIndex); mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetterOuter(
uint32_t aIndex);
already_AddRefed<nsPIDOMWindowOuter> GetTop() override; already_AddRefed<nsPIDOMWindowOuter> GetTop() override;
// Similar to GetTop() except that it stops at content frames that an // Similar to GetTop() except that it stops at content frames that an
@ -535,7 +535,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
nsresult Focus() override; nsresult Focus() override;
void BlurOuter(); void BlurOuter();
mozilla::dom::BrowsingContext* GetFramesOuter(); mozilla::dom::BrowsingContext* GetFramesOuter();
nsDOMWindowList* GetFrames() final;
uint32_t Length(); uint32_t Length();
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter(); mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
@ -918,8 +917,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
virtual bool ShouldShowFocusRing() override; virtual bool ShouldShowFocusRing() override;
virtual void SetKeyboardIndicators(UIStateChangeType aShowFocusRings) virtual void SetKeyboardIndicators(
override; UIStateChangeType aShowFocusRings) override;
public: public:
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override; virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
@ -1099,7 +1098,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// For |window.arguments|, via |openDialog|. // For |window.arguments|, via |openDialog|.
nsCOMPtr<nsIArray> mArguments; nsCOMPtr<nsIArray> mArguments;
RefPtr<nsDOMWindowList> mFrames;
RefPtr<nsDOMWindowUtils> mWindowUtils; RefPtr<nsDOMWindowUtils> mWindowUtils;
nsString mStatus; nsString mStatus;

View file

@ -25,7 +25,6 @@
#define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed" #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
class nsDOMOfflineResourceList; class nsDOMOfflineResourceList;
class nsDOMWindowList;
class nsGlobalWindowInner; class nsGlobalWindowInner;
class nsGlobalWindowOuter; class nsGlobalWindowOuter;
class nsIArray; class nsIArray;
@ -546,8 +545,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
virtual nsresult GetControllers(nsIControllers** aControllers) = 0; virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
virtual nsDOMWindowList* GetFrames() = 0;
virtual nsresult GetInnerWidth(int32_t* aWidth) = 0; virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
virtual nsresult GetInnerHeight(int32_t* aHeight) = 0; virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
@ -1045,8 +1042,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0; virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0;
virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0; virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
virtual nsDOMWindowList* GetFrames() = 0;
// aLoadState will be passed on through to the windowwatcher. // aLoadState will be passed on through to the windowwatcher.
// aForceNoOpener will act just like a "noopener" feature in aOptions except // aForceNoOpener will act just like a "noopener" feature in aOptions except
// will not affect any other window features. // will not affect any other window features.

View file

@ -112,7 +112,7 @@ class nsRange final : public mozilla::dom::AbstractRange,
* Mark this range as being generated or not. * Mark this range as being generated or not.
* Currently it is used for marking ranges that are created when splitting up * Currently it is used for marking ranges that are created when splitting up
* a range to exclude a -moz-user-select:none region. * a range to exclude a -moz-user-select:none region.
* @see Selection::AddItem * @see Selection::AddRangesForSelectableNodes
* @see ExcludeNonSelectableNodes * @see ExcludeNonSelectableNodes
*/ */
void SetIsGenerated(bool aIsGenerated) { mIsGenerated = aIsGenerated; } void SetIsGenerated(bool aIsGenerated) { mIsGenerated = aIsGenerated; }

View file

@ -7,13 +7,14 @@
#include "nsWindowMemoryReporter.h" #include "nsWindowMemoryReporter.h"
#include "nsWindowSizes.h" #include "nsWindowSizes.h"
#include "nsGlobalWindow.h" #include "nsGlobalWindow.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
#include "nsDOMWindowList.h"
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/ResultExtensions.h"
#include "nsNetCID.h" #include "nsNetCID.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "XPCJSMemoryReporter.h" #include "XPCJSMemoryReporter.h"
@ -61,19 +62,16 @@ static nsresult AddNonJSSizeOfWindowAndItsDescendents(
windowSizes.addToTabSizes(aSizes); windowSizes.addToTabSizes(aSizes);
nsDOMWindowList* frames = aWindow->GetFrames(); BrowsingContext* bc = aWindow->GetBrowsingContext();
if (!bc) {
uint32_t length = frames->GetLength(); return NS_OK;
}
// Measure this window's descendents. // Measure this window's descendents.
for (uint32_t i = 0; i < length; i++) { for (const auto& frame : bc->GetChildren()) {
nsCOMPtr<nsPIDOMWindowOuter> child = frames->IndexedGetter(i); if (auto* childWin = nsGlobalWindowOuter::Cast(frame->GetDOMWindow())) {
NS_ENSURE_STATE(child); MOZ_TRY(AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes));
}
nsGlobalWindowOuter* childWin = nsGlobalWindowOuter::Cast(child);
nsresult rv = AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes);
NS_ENSURE_SUCCESS(rv, rv);
} }
return NS_OK; return NS_OK;
} }

View file

@ -10,6 +10,8 @@
<label value="CPOWs"/> <label value="CPOWs"/>
<script type="application/javascript"><![CDATA[ <script type="application/javascript"><![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var test_state = "remote"; var test_state = "remote";
var test_node = null; var test_node = null;
var reentered = false; var reentered = false;
@ -400,7 +402,7 @@
let failed = false; let failed = false;
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser"; const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true); Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
try { try {
msg.objects.f(); msg.objects.f();
} catch (e) { } catch (e) {
@ -416,7 +418,7 @@
function recvSafe(msg) { function recvSafe(msg) {
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser"; const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true); Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
try { try {
msg.objects.f(); msg.objects.f();
} catch (e) { } catch (e) {

View file

@ -34,7 +34,7 @@ function createFileWithData(fileData) {
/** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/ /** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/
var file = createFileWithData("Test bug 914381"); var file = createFileWithData("Test bug 914381");
SpecialPowers.pushPrefEnv({ set: [ "dom.file.createInChild" ]}) SpecialPowers.pushPrefEnv({ set: [["dom.file.createInChild", true]]})
.then(() => { .then(() => {
return File.createFromNsIFile(file); return File.createFromNsIFile(file);
}) })

View file

@ -13,12 +13,14 @@
<!-- test code goes here --> <!-- test code goes here -->
<script type="application/javascript"><![CDATA[ <script type="application/javascript"><![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser"; const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, false); Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
SimpleTest.registerCleanupFunction(() => { SimpleTest.registerCleanupFunction(() => {
SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN); Services.prefs.clearUserPref(PREF_UNSAFE_FORBIDDEN);
}); });
function done() { function done() {

View file

@ -23,7 +23,8 @@
<script class="testbody" type="application/javascript"> <script class="testbody" type="application/javascript">
<![CDATA[ <![CDATA[
var SpecialPowers = window.opener.wrappedJSObject.SpecialPowers; const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var SimpleTest = window.opener.wrappedJSObject.SimpleTest; var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
SimpleTest.waitForFocus(runTests, window); SimpleTest.waitForFocus(runTests, window);
@ -1480,7 +1481,7 @@ function runReleaseTests()
// Release the TIP // Release the TIP
TIP = null; TIP = null;
// Needs to run GC forcibly for testing this. // Needs to run GC forcibly for testing this.
SpecialPowers.gc(); Cu.forceGC();
is(input.value, "", is(input.value, "",
description + "the input should be empty because the composition should be canceled"); description + "the input should be empty because the composition should be canceled");
@ -1770,7 +1771,7 @@ function runCompositionWithKeyEventTests()
var convertKeyEvent = new KeyboardEvent("", { key: "Convert", code: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT }); var convertKeyEvent = new KeyboardEvent("", { key: "Convert", code: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT });
var backspaceKeyEvent = new KeyboardEvent("", { key: "Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE }); var backspaceKeyEvent = new KeyboardEvent("", { key: "Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE });
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false); Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
// nsITextInputProcessor.startComposition() // nsITextInputProcessor.startComposition()
reset(); reset();
@ -2004,7 +2005,7 @@ function runCompositionWithKeyEventTests()
is(input.value, "FOobarbuzzboo!", is(input.value, "FOobarbuzzboo!",
description + "committing text directly should append the committing text to the focused editor"); description + "committing text directly should append the committing text to the focused editor");
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true); Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
// Even if "dom.keyboardevent.dispatch_during_composition" is true, keypress event shouldn't be fired during composition // Even if "dom.keyboardevent.dispatch_during_composition" is true, keypress event shouldn't be fired during composition
reset(); reset();
@ -2108,7 +2109,7 @@ function runCompositionWithKeyEventTests()
is(events[1].type, "compositionend", is(events[1].type, "compositionend",
description + "TIP.cancelComposition(escKeydownEvent) should cause compositionend (keyup event shouldn't be fired)"); description + "TIP.cancelComposition(escKeydownEvent) should cause compositionend (keyup event shouldn't be fired)");
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition"); Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
window.removeEventListener("compositionstart", handler, false); window.removeEventListener("compositionstart", handler, false);
window.removeEventListener("compositionupdate", handler, false); window.removeEventListener("compositionupdate", handler, false);
@ -2155,7 +2156,7 @@ function runConsumingKeydownBeforeCompositionTests()
var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN });
var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE });
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false); Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
// If keydown before compositionstart is consumed, composition shouldn't be started. // If keydown before compositionstart is consumed, composition shouldn't be started.
reset(); reset();
@ -2205,7 +2206,7 @@ function runConsumingKeydownBeforeCompositionTests()
is(input.value, "", is(input.value, "",
description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause inserting text"); description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause inserting text");
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true); Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
// If composition is already started, TIP.flushPendingComposition(printableKeyEvent) shouldn't be canceled. // If composition is already started, TIP.flushPendingComposition(printableKeyEvent) shouldn't be canceled.
TIP.startComposition(); TIP.startComposition();
@ -2273,7 +2274,7 @@ function runConsumingKeydownBeforeCompositionTests()
is(input.value, "", is(input.value, "",
description + "TIP.cancelComposition(escKeyEvent) should cancel composition even if preceding keydown is consumed because there was a composition already"); description + "TIP.cancelComposition(escKeyEvent) should cancel composition even if preceding keydown is consumed because there was a composition already");
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition"); Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
window.removeEventListener("compositionstart", handler, false); window.removeEventListener("compositionstart", handler, false);
window.removeEventListener("compositionupdate", handler, false); window.removeEventListener("compositionupdate", handler, false);
@ -2594,7 +2595,7 @@ function runKeyTests()
// key events during composition // key events during composition
try { try {
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false); Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
ok(TIP.startComposition(), "TIP.startComposition() should start composition"); ok(TIP.startComposition(), "TIP.startComposition() should start composition");
@ -2608,7 +2609,7 @@ function runKeyTests()
is(events.length, 0, is(events.length, 0,
description + "TIP.keyup(keyA) shouldn't cause key events during composition if it's disabled by the pref"); description + "TIP.keyup(keyA) shouldn't cause key events during composition if it's disabled by the pref");
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true); Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
reset(); reset();
TIP.keydown(keyA); TIP.keydown(keyA);
is(events.length, 1, is(events.length, 1,
@ -2624,7 +2625,7 @@ function runKeyTests()
} finally { } finally {
TIP.cancelComposition(); TIP.cancelComposition();
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition"); Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
} }
// Test .location computation // Test .location computation

View file

@ -14,8 +14,8 @@ function getTestPlugin(pluginName) {
return null; return null;
} }
// Copied from /dom/plugins/test/mochitest/utils.js // Copied from /dom/plugins/test/mochitest/utils.js
function setTestPluginEnabledState(newEnabledState, pluginName) { async function setTestPluginEnabledState(newEnabledState, pluginName) {
var oldEnabledState = SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName); var oldEnabledState = await SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName);
if (!oldEnabledState) { if (!oldEnabledState) {
return; return;
} }
@ -26,7 +26,7 @@ function setTestPluginEnabledState(newEnabledState, pluginName) {
return plugin.enabledState == newEnabledState; return plugin.enabledState == newEnabledState;
}); });
SimpleTest.registerCleanupFunction(function() { SimpleTest.registerCleanupFunction(function() {
SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName); return SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName);
}); });
} }
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);

View file

@ -16,10 +16,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
function doTest() { function doTest() {
var file = location.href; var file = location.href;
var asyncFrame; var asyncFrame;
/* Async parent frames from pushPrefEnv don't show up in e10s. */ /* Async parent frames from pushPrefEnv don't show up in e10s. */
var isE10S = !SpecialPowers.isMainProcess(); if (SpecialPowers.getBoolPref("javascript.options.asyncstack")) {
if (!isE10S && SpecialPowers.getBoolPref("javascript.options.asyncstack")) {
asyncFrame = `Async*@${file}:153:17 asyncFrame = `Async*@${file}:153:17
`; `;
} else { } else {

View file

@ -37,12 +37,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
function doTest() { function doTest() {
var t = new TestInterfaceJS(); var t = new TestInterfaceJS();
/* Async parent frames from pushPrefEnv don't show up in e10s. */
var isE10S = !SpecialPowers.isMainProcess();
var asyncStack = SpecialPowers.getBoolPref("javascript.options.asyncstack"); var asyncStack = SpecialPowers.getBoolPref("javascript.options.asyncstack");
var ourFile = location.href; var ourFile = location.href;
var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper."; var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper.";
var parentFrame = (asyncStack && !isE10S) ? `Async*@${ourFile}:130:17 var parentFrame = asyncStack ? `Async*@${ourFile}:130:17
` : ""; ` : "";
Promise.all([ Promise.all([

View file

@ -16,7 +16,7 @@
</div> </div>
<pre id="test"> <pre id="test">
<script type="application/javascript"> <script type="application/javascript">
SpecialPowers.pushPrefEnv({"set": [["canvas.hitregions.enabled", true]]}, function() { SpecialPowers.pushPrefEnv({"set": [["canvas.hitregions.enabled", true]]}).then(function() {
var input = document.getElementById("input"); var input = document.getElementById("input");
var regionId = ""; var regionId = "";

View file

@ -9,6 +9,8 @@ interface nsIDocShell;
interface BrowsingContext { interface BrowsingContext {
static BrowsingContext? get(unsigned long long aId); static BrowsingContext? get(unsigned long long aId);
static BrowsingContext? getFromWindow(WindowProxy window);
BrowsingContext? findChildWithName(DOMString name); BrowsingContext? findChildWithName(DOMString name);
BrowsingContext? findWithName(DOMString name); BrowsingContext? findWithName(DOMString name);

View file

@ -23,30 +23,31 @@ let seenClick = false;
SpecialPowers.pushPrefEnv( SpecialPowers.pushPrefEnv(
{ set: [[HACK_PREF, document.domain]] }, { set: [[HACK_PREF, document.domain]] },
SimpleTest.waitForFocus(() => { () => {
// Test seeing the non-primary 'click' SimpleTest.waitForFocus(() => {
document.addEventListener("click", (e) => { // Test seeing the non-primary 'click'
ok(true, "Saw 'click' event"); document.addEventListener("click", (e) => {
seenClick = true; ok(true, "Saw 'click' event");
}, { once: true }); seenClick = true;
document.addEventListener("auxclick", (e) => { }, { once: true });
ok(true, "Saw 'auxclick' event"); document.addEventListener("auxclick", (e) => {
ok(seenClick, "Saw 'click' event before 'auxclick' event"); ok(true, "Saw 'auxclick' event");
}, { once: true }); ok(seenClick, "Saw 'click' event before 'auxclick' event");
synthesizeMouseAtCenter(testEl, { button: 1 }); }, { once: true });
synthesizeMouseAtCenter(testEl, { button: 1 });
// Test preventDefaulting on non-primary 'click' // Test preventDefaulting on non-primary 'click'
document.addEventListener("click", (e) => { document.addEventListener("click", (e) => {
is(e.target, linkEl, "Saw 'click' on link"); is(e.target, linkEl, "Saw 'click' on link");
e.preventDefault(); e.preventDefault();
SimpleTest.finish(); SimpleTest.finish();
}, { once: true, capture: true }); }, { once: true, capture: true });
document.addEventListener("auxclick", (e) => { document.addEventListener("auxclick", (e) => {
ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'"); ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'");
}, { once: true }); }, { once: true });
synthesizeMouseAtCenter(linkEl, { button: 1 }); synthesizeMouseAtCenter(linkEl, { button: 1 });
}) });
); });
</script> </script>
</body> </body>
</html> </html>

View file

@ -152,6 +152,7 @@ async function testFullscreenMouseBtn(event, button, next) {
// Restore the pref environment we changed before // Restore the pref environment we changed before
// entering testNonTrustContext. // entering testNonTrustContext.
await SpecialPowers.popPrefEnv(); await SpecialPowers.popPrefEnv();
await SpecialPowers.popPrefEnv();
finish(); finish();
} }

View file

@ -39,8 +39,8 @@ function onFileOpened(message) {
const elem = document.getElementById("file"); const elem = document.getElementById("file");
is(getGlobal(elem), window, is(getGlobal(elem), window,
"getGlobal() works as expected"); "getGlobal() works as expected");
isnot(getGlobal(file), window, is(getGlobal(file), window,
"File from MessageManager is wrapped"); "File from MessageManager is not wrapped");
SpecialPowers.wrap(elem).mozSetFileArray([file]); SpecialPowers.wrap(elem).mozSetFileArray([file]);
is(getGlobal(elem.files[0]), window, is(getGlobal(elem.files[0]), window,
"File read back from input element is not wrapped"); "File read back from input element is not wrapped");

View file

@ -12,32 +12,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1414077
/** Test for Bug 1414077 **/ /** Test for Bug 1414077 **/
SimpleTest.waitForExplicitFinish(); var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", true]]}, function() { add_task(async function() {
var testWin = document.querySelector("iframe"); await SpecialPowers.pushPrefEnv({"set": [["browser.enable_automatic_image_resizing", true]]});
testWin.height = 0;
testWin.width = 0;
testWin.src = "image.png";
testWin.onload = function() {
var testDoc = testWin.contentDocument;
// testDoc should be a image document. return new Promise(resolve => {
ok(testDoc.imageIsOverflowing, "image is overflowing"); var testWin = document.querySelector("iframe");
ok(testDoc.imageIsResized, "image is resized to fit visible area by default"); testWin.src = "image.png";
testWin.onload = function() {
var testDoc = testWin.contentDocument;
// Restore image to original size. // testDoc should be a image document.
testDoc.restoreImage(); ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsOverflowing, "image is overflowing"); ok(testDoc.imageIsResized, "image is resized to fit visible area by default");
ok(!testDoc.imageIsResized, "image is restored to original size");
// Resize the image to fit visible area // Restore image to original size.
testDoc.shrinkToFit(); testDoc.restoreImage();
ok(testDoc.imageIsOverflowing, "image is overflowing"); ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area"); ok(!testDoc.imageIsResized, "image is restored to original size");
SimpleTest.finish(); // Resize the image to fit visible area
}; testDoc.shrinkToFit();
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area");
resolve();
};
})
}); });
</script> </script>
@ -45,6 +47,6 @@ SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", tr
<body> <body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414077">Mozilla Bug 1414077</a> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414077">Mozilla Bug 1414077</a>
<iframe></iframe> <iframe width="0" height="0"></iframe>
</body> </body>
</html> </html>

View file

@ -888,12 +888,21 @@ nsresult ContentChild::ProvideWindowCommon(
// load in the current process. // load in the current process.
bool loadInDifferentProcess = aForceNoOpener && sNoopenerNewProcess; bool loadInDifferentProcess = aForceNoOpener && sNoopenerNewProcess;
if (aTabOpener && !loadInDifferentProcess && aURI) { if (aTabOpener && !loadInDifferentProcess && aURI) {
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3; nsCOMPtr<nsILoadContext> context;
rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3)); if (aParent) {
if (NS_SUCCEEDED(rv) && browserChrome3) { context = do_GetInterface(aTabOpener->WebNavigation());
bool shouldLoad; }
rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad); // Only special-case cross-process loads if Fission is disabled. With
loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad; // Fission enabled, the initial in-process load will automatically be
// retargeted to the correct process.
if (!(context && context->UseRemoteSubframes())) {
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
if (NS_SUCCEEDED(rv) && browserChrome3) {
bool shouldLoad;
rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
}
} }
} }

View file

@ -8,6 +8,8 @@
#include "mozilla/dom/JSWindowActorBinding.h" #include "mozilla/dom/JSWindowActorBinding.h"
#include "mozilla/dom/MessageManagerBinding.h" #include "mozilla/dom/MessageManagerBinding.h"
#include "mozilla/dom/PWindowGlobal.h" #include "mozilla/dom/PWindowGlobal.h"
#include "mozilla/dom/Promise.h"
#include "js/Promise.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -35,10 +37,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(JSWindowActor)
JSWindowActor::JSWindowActor() : mNextQueryId(0) {} JSWindowActor::JSWindowActor() : mNextQueryId(0) {}
nsIGlobalObject* JSWindowActor::GetParentObject() const {
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
}
void JSWindowActor::StartDestroy() { void JSWindowActor::StartDestroy() {
DestroyCallback(DestroyCallbackFunction::WillDestroy); DestroyCallback(DestroyCallbackFunction::WillDestroy);
} }
@ -48,8 +46,7 @@ void JSWindowActor::AfterDestroy() {
} }
void JSWindowActor::DestroyCallback(DestroyCallbackFunction callback) { void JSWindowActor::DestroyCallback(DestroyCallbackFunction callback) {
AutoEntryScript aes(xpc::PrivilegedJunkScope(), AutoEntryScript aes(GetParentObject(), "JSWindowActor destroy callback");
"JSWindowActor destroy callback");
JSContext* cx = aes.cx(); JSContext* cx = aes.cx();
MozActorDestroyCallbacks callbacksHolder; MozActorDestroyCallbacks callbacksHolder;
NS_ENSURE_TRUE_VOID(GetWrapper()); NS_ENSURE_TRUE_VOID(GetWrapper());
@ -91,8 +88,8 @@ void JSWindowActor::SendAsyncMessage(JSContext* aCx,
JS::Handle<JS::Value> aTransfers, JS::Handle<JS::Value> aTransfers,
ErrorResult& aRv) { ErrorResult& aRv) {
ipc::StructuredCloneData data; ipc::StructuredCloneData data;
if (!aObj.isUndefined() && !nsFrameMessageManager::GetParamsForMessage( if (!nsFrameMessageManager::GetParamsForMessage(aCx, aObj, aTransfers,
aCx, aObj, aTransfers, data)) { data)) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
return; return;
} }
@ -109,8 +106,8 @@ already_AddRefed<Promise> JSWindowActor::SendQuery(
JSContext* aCx, const nsAString& aMessageName, JS::Handle<JS::Value> aObj, JSContext* aCx, const nsAString& aMessageName, JS::Handle<JS::Value> aObj,
JS::Handle<JS::Value> aTransfers, ErrorResult& aRv) { JS::Handle<JS::Value> aTransfers, ErrorResult& aRv) {
ipc::StructuredCloneData data; ipc::StructuredCloneData data;
if (!aObj.isUndefined() && !nsFrameMessageManager::GetParamsForMessage( if (!nsFrameMessageManager::GetParamsForMessage(aCx, aObj, aTransfers,
aCx, aObj, aTransfers, data)) { data)) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
return nullptr; return nullptr;
} }
@ -140,8 +137,7 @@ already_AddRefed<Promise> JSWindowActor::SendQuery(
void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata, void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
ipc::StructuredCloneData&& aData) { ipc::StructuredCloneData&& aData) {
AutoEntryScript aes(xpc::PrivilegedJunkScope(), AutoEntryScript aes(GetParentObject(), "JSWindowActor message handler");
"JSWindowActor message handler");
JSContext* cx = aes.cx(); JSContext* cx = aes.cx();
// Read the message into a JS object from IPC. // Read the message into a JS object from IPC.
@ -149,6 +145,11 @@ void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
JS::Rooted<JS::Value> data(cx); JS::Rooted<JS::Value> data(cx);
aData.Read(cx, &data, error); aData.Read(cx, &data, error);
if (NS_WARN_IF(error.Failed())) { if (NS_WARN_IF(error.Failed())) {
if (XRE_IsParentProcess()) {
MOZ_ASSERT(false, "Should not receive non-decodable data");
} else {
MOZ_DIAGNOSTIC_ASSERT(false, "Should not receive non-decodable data");
}
MOZ_ALWAYS_TRUE(error.MaybeSetPendingException(cx)); MOZ_ALWAYS_TRUE(error.MaybeSetPendingException(cx));
return; return;
} }
@ -235,8 +236,15 @@ void JSWindowActor::ReceiveQueryReply(JSContext* aCx,
return; return;
} }
JSAutoRealm ar(aCx, promise->PromiseObj());
JS::RootedValue data(aCx, aData);
if (NS_WARN_IF(!JS_WrapValue(aCx, &data))) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (aMetadata.kind() == JSWindowActorMessageKind::QueryResolve) { if (aMetadata.kind() == JSWindowActorMessageKind::QueryResolve) {
promise->MaybeResolve(aCx, aData); promise->MaybeResolve(aCx, data);
} else { } else {
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR); promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
} }
@ -262,8 +270,9 @@ void JSWindowActor::QueryHandler::RejectedCallback(
Unused << JS::CallOriginalPromiseReject(aCx, aValue); Unused << JS::CallOriginalPromiseReject(aCx, aValue);
// The exception probably isn't cloneable, so just send down undefined. // The exception probably isn't cloneable, so just send down undefined.
SendReply(aCx, JSWindowActorMessageKind::QueryReject, ipc::StructuredCloneData data;
ipc::StructuredCloneData()); data.Write(aCx, JS::UndefinedHandleValue, IgnoredErrorResult());
SendReply(aCx, JSWindowActorMessageKind::QueryReject, std::move(data));
} }
void JSWindowActor::QueryHandler::ResolvedCallback( void JSWindowActor::QueryHandler::ResolvedCallback(
@ -289,8 +298,9 @@ void JSWindowActor::QueryHandler::ResolvedCallback(
JS_ClearPendingException(aCx); JS_ClearPendingException(aCx);
SendReply(aCx, JSWindowActorMessageKind::QueryReject, ipc::StructuredCloneData data;
ipc::StructuredCloneData()); data.Write(aCx, JS::UndefinedHandleValue, IgnoredErrorResult());
SendReply(aCx, JSWindowActorMessageKind::QueryReject, std::move(data));
return; return;
} }

View file

@ -56,7 +56,7 @@ class JSWindowActor : public nsISupports, public nsWrapperCache {
void ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata, void ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
ipc::StructuredCloneData&& aData); ipc::StructuredCloneData&& aData);
nsIGlobalObject* GetParentObject() const; virtual nsIGlobalObject* GetParentObject() const = 0;
void RejectPendingQueries(); void RejectPendingQueries();

View file

@ -17,6 +17,10 @@
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
JSWindowActorChild::JSWindowActorChild(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal ? aGlobal
: xpc::NativeGlobal(xpc::PrivilegedJunkScope())) {}
JSWindowActorChild::~JSWindowActorChild() { MOZ_ASSERT(!mManager); } JSWindowActorChild::~JSWindowActorChild() { MOZ_ASSERT(!mManager); }
JSObject* JSWindowActorChild::WrapObject(JSContext* aCx, JSObject* JSWindowActorChild::WrapObject(JSContext* aCx,

View file

@ -37,12 +37,17 @@ class JSWindowActorChild final : public JSWindowActor {
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(JSWindowActorChild, NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(JSWindowActorChild,
JSWindowActor) JSWindowActor)
explicit JSWindowActorChild(nsIGlobalObject* aGlobal = nullptr);
nsIGlobalObject* GetParentObject() const override { return mGlobal; }
JSObject* WrapObject(JSContext* aCx, JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<JSWindowActorChild> Constructor(GlobalObject& aGlobal, static already_AddRefed<JSWindowActorChild> Constructor(GlobalObject& aGlobal,
ErrorResult& aRv) { ErrorResult& aRv) {
return MakeAndAddRef<JSWindowActorChild>(); nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(aGlobal.GetAsSupports()));
return MakeAndAddRef<JSWindowActorChild>(global);
} }
WindowGlobalChild* GetManager() const; WindowGlobalChild* GetManager() const;
@ -64,6 +69,8 @@ class JSWindowActorChild final : public JSWindowActor {
bool mCanSend = true; bool mCanSend = true;
RefPtr<WindowGlobalChild> mManager; RefPtr<WindowGlobalChild> mManager;
nsCOMPtr<nsIGlobalObject> mGlobal;
}; };
} // namespace dom } // namespace dom

View file

@ -14,6 +14,10 @@ namespace dom {
JSWindowActorParent::~JSWindowActorParent() { MOZ_ASSERT(!mManager); } JSWindowActorParent::~JSWindowActorParent() { MOZ_ASSERT(!mManager); }
nsIGlobalObject* JSWindowActorParent::GetParentObject() const {
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
}
JSObject* JSWindowActorParent::WrapObject(JSContext* aCx, JSObject* JSWindowActorParent::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) { JS::Handle<JSObject*> aGivenProto) {
return JSWindowActorParent_Binding::Wrap(aCx, this, aGivenProto); return JSWindowActorParent_Binding::Wrap(aCx, this, aGivenProto);

View file

@ -40,6 +40,8 @@ class JSWindowActorParent final : public JSWindowActor {
return MakeAndAddRef<JSWindowActorParent>(); return MakeAndAddRef<JSWindowActorParent>();
} }
nsIGlobalObject* GetParentObject() const override;
WindowGlobalParent* GetManager() const; WindowGlobalParent* GetManager() const;
void Init(const nsAString& aName, WindowGlobalParent* aManager); void Init(const nsAString& aName, WindowGlobalParent* aManager);
void StartDestroy(); void StartDestroy();

View file

@ -60,7 +60,7 @@ var tests = [
{ {
keySystem: "com.widevine.alpha", keySystem: "com.widevine.alpha",
expectedStatus: 'cdm-not-installed', expectedStatus: 'cdm-not-installed',
prefs: [["media.eme.enabled", true], , ["media.gmp-widevinecdm.enabled", true]] prefs: [["media.eme.enabled", true], ["media.gmp-widevinecdm.enabled", true]]
}, },
{ {
keySystem: CLEARKEY_KEYSYSTEM, keySystem: CLEARKEY_KEYSYSTEM,

View file

@ -162,6 +162,7 @@ function startTest(test, token) {
createMedia(test.type, test.name, token); createMedia(test.type, test.name, token);
} }
SimpleTest.waitForExplicitFinish();
createTestArray().then(testArray => { createTestArray().then(testArray => {
manager.runTests(testArray, startTest); manager.runTests(testArray, startTest);
}); });

View file

@ -8,12 +8,12 @@ var NotificationTest = (function() {
function setup_testing_env() { function setup_testing_env() {
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
// turn on testing pref (used by notification.cpp, and mock the alerts // turn on testing pref (used by notification.cpp, and mock the alerts
SpecialPowers.setBoolPref("notification.prompt.testing", true); return SpecialPowers.setBoolPref("notification.prompt.testing", true);
} }
function teardown_testing_env() { async function teardown_testing_env() {
SpecialPowers.clearUserPref("notification.prompt.testing"); await SpecialPowers.clearUserPref("notification.prompt.testing");
SpecialPowers.clearUserPref("notification.prompt.testing.allow"); await SpecialPowers.clearUserPref("notification.prompt.testing.allow");
SimpleTest.finish(); SimpleTest.finish();
} }
@ -78,9 +78,10 @@ var NotificationTest = (function() {
// NotificationTest API // NotificationTest API
return { return {
run(tests, callback) { run(tests, callback) {
setup_testing_env(); let ready = setup_testing_env();
addLoadEvent(function() { addLoadEvent(async function() {
await ready;
executeTests(tests, function() { executeTests(tests, function() {
teardown_testing_env(); teardown_testing_env();
callback && callback(); callback && callback();
@ -89,11 +90,11 @@ var NotificationTest = (function() {
}, },
allowNotifications() { allowNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", true); return SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
}, },
denyNotifications() { denyNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", false); return SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
}, },
clickNotification(notification) { clickNotification(notification) {

View file

@ -32,13 +32,13 @@
Notification.requestPermission(); Notification.requestPermission();
}, },
function(done) { async function(done) {
info("Test requestPermission deny"); info("Test requestPermission deny");
function assertPermissionDenied(perm) { function assertPermissionDenied(perm) {
is(perm, "denied", "Permission should be denied."); is(perm, "denied", "Permission should be denied.");
is(Notification.permission, "denied", "Permission should be denied."); is(Notification.permission, "denied", "Permission should be denied.");
} }
NotificationTest.denyNotifications(); await NotificationTest.denyNotifications();
Notification.requestPermission() Notification.requestPermission()
.then(assertPermissionDenied) .then(assertPermissionDenied)
.then(_ => Notification.requestPermission(assertPermissionDenied)) .then(_ => Notification.requestPermission(assertPermissionDenied))
@ -48,13 +48,13 @@
.then(done); .then(done);
}, },
function(done) { async function(done) {
info("Test requestPermission grant"); info("Test requestPermission grant");
function assertPermissionGranted(perm) { function assertPermissionGranted(perm) {
is(perm, "granted", "Permission should be granted."); is(perm, "granted", "Permission should be granted.");
is(Notification.permission, "granted", "Permission should be granted"); is(Notification.permission, "granted", "Permission should be granted");
} }
NotificationTest.allowNotifications(); await NotificationTest.allowNotifications();
Notification.requestPermission() Notification.requestPermission()
.then(assertPermissionGranted) .then(assertPermissionGranted)
.then(_ => Notification.requestPermission(assertPermissionGranted)) .then(_ => Notification.requestPermission(assertPermissionGranted))

View file

@ -37,7 +37,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1429432
response = await Notification.requestPermission(); response = await Notification.requestPermission();
is(response, "granted", "Granted permission in insecure context with pref set"); is(response, "granted", "Granted permission in insecure context with pref set");
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
script.destroy(); script.destroy();
SimpleTest.finish(); SimpleTest.finish();

View file

@ -130,9 +130,9 @@
const permission = 'geolocation'; const permission = 'geolocation';
const promiseGranted = this.promiseStateChanged(permission, 'granted'); const promiseGranted = this.promiseStateChanged(permission, 'granted');
this.setPermissions(ALLOW_ACTION); this.setPermissions(ALLOW_ACTION);
promiseGranted.then(() => { promiseGranted.then(async () => {
const promisePrompt = this.promiseStateChanged(permission, 'prompt'); const promisePrompt = this.promiseStateChanged(permission, 'prompt');
SpecialPowers.popPermissions(); await SpecialPowers.popPermissions();
return promisePrompt; return promisePrompt;
}).then(resolve); }).then(resolve);
}); });

View file

@ -108,7 +108,11 @@ function waitScrollFinish(aTarget) {
*/ */
function setTestPluginEnabledState(aState, aPluginName) { function setTestPluginEnabledState(aState, aPluginName) {
let name = aPluginName || "Test Plug-in"; let name = aPluginName || "Test Plug-in";
SpecialPowers.setTestPluginEnabledState(aState, name); let resolved = false;
SpecialPowers.setTestPluginEnabledState(aState, name).then(() => {
resolved = true;
});
SpecialPowers.Services.tm.spinEventLoopUntil(() => resolved);
} }
/** /**

View file

@ -33,8 +33,8 @@ function setTestPluginEnabledState(newEnabledState, pluginName) {
SpecialPowers.Services.tm.spinEventLoopUntil(() => { SpecialPowers.Services.tm.spinEventLoopUntil(() => {
return plugin.enabledState == newEnabledState; return plugin.enabledState == newEnabledState;
}); });
SimpleTest.registerCleanupFunction(function() { SimpleTest.registerCleanupFunction(async function() {
SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName); return SpecialPowers.setTestPluginEnabledState(await oldEnabledState, pluginName);
}); });
} }

View file

@ -10,11 +10,6 @@
"use strict"; "use strict";
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
function addPerms() {
ok(SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Shockwave Flash"), "Should find allowed test flash plugin");
ok(!SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Third Test Plug-in"), "Should not find disallowed plugin");
SpecialPowers.pushPermissions([{type: "plugin:flash", allow: true, context: document}], run);
}
function findPlugin(pluginName) { function findPlugin(pluginName) {
for (var i = 0; i < navigator.plugins.length; i++) { for (var i = 0; i < navigator.plugins.length; i++) {
@ -45,7 +40,13 @@
document.body.appendChild(obj); document.body.appendChild(obj);
} }
function run() { async function run() {
ok(await SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Shockwave Flash"), "Should find allowed test flash plugin");
ok(!await SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Third Test Plug-in"), "Should not find disallowed plugin");
await new Promise(resolve => {
SpecialPowers.pushPermissions([{type: "plugin:flash", allow: true, context: document}], resolve);
});
createNode("plugin-flash", "application/x-shockwave-flash-test"); createNode("plugin-flash", "application/x-shockwave-flash-test");
createNode("disallowedPlugin", "application/x-third-test"); createNode("disallowedPlugin", "application/x-third-test");
var pluginElement = document.getElementById("plugin-flash"); var pluginElement = document.getElementById("plugin-flash");
@ -70,6 +71,6 @@
} }
</script> </script>
<body onload="addPerms()"> <body onload="run()">
</body> </body>
</html> </html>

View file

@ -19,6 +19,8 @@
</body> </body>
<script class="testbody" type="application/javascript"> <script class="testbody" type="application/javascript">
<![CDATA[ <![CDATA[
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SimpleTest.expectChildProcessCrash(); SimpleTest.expectChildProcessCrash();
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
@ -89,9 +91,9 @@ function finishTest() {
os.removeObserver(testObserver, "plugin-crashed"); os.removeObserver(testObserver, "plugin-crashed");
--obsCount; --obsCount;
} }
SpecialPowers.clearUserPref(hangUITimeoutPref); Services.prefs.clearUserPref(hangUITimeoutPref);
SpecialPowers.clearUserPref(hangUIMinDisplayPref); Services.prefs.clearUserPref(hangUIMinDisplayPref);
SpecialPowers.clearUserPref(timeoutPref); Services.prefs.clearUserPref(timeoutPref);
SimpleTest.finish(); SimpleTest.finish();
} }
@ -151,9 +153,9 @@ function test9b() {
function test9a() { function test9a() {
resetVars(); resetVars();
SpecialPowers.setIntPref(hangUITimeoutPref, 1); Services.prefs.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1); Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
SpecialPowers.setIntPref(timeoutPref, 45); Services.prefs.setIntPref(timeoutPref, 45);
hanguiContinue("test9a: Continue button works with checkbox", true, "test9b"); hanguiContinue("test9a: Continue button works with checkbox", true, "test9b");
p.stall(STALL_DURATION); p.stall(STALL_DURATION);
} }
@ -165,8 +167,8 @@ function test9() {
function test8a() { function test8a() {
resetVars(); resetVars();
SpecialPowers.setIntPref(hangUITimeoutPref, 1); Services.prefs.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 4); Services.prefs.setIntPref(hangUIMinDisplayPref, 4);
hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9"); hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9");
var exceptionThrown = false; var exceptionThrown = false;
try { try {
@ -184,7 +186,7 @@ function test8() {
function test7a() { function test7a() {
resetVars(); resetVars();
SpecialPowers.setIntPref(hangUITimeoutPref, 0); Services.prefs.setIntPref(hangUITimeoutPref, 0);
hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8"); hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8");
var exceptionThrown = false; var exceptionThrown = false;
try { try {
@ -201,9 +203,9 @@ function test7() {
} }
function test6() { function test6() {
SpecialPowers.setIntPref(hangUITimeoutPref, 1); Services.prefs.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1); Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
SpecialPowers.setIntPref(timeoutPref, 3); Services.prefs.setIntPref(timeoutPref, 3);
hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7"); hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7");
var exceptionThrown = false; var exceptionThrown = false;
try { try {
@ -250,9 +252,9 @@ function test2() {
} }
function test1() { function test1() {
SpecialPowers.setIntPref(hangUITimeoutPref, 1); Services.prefs.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1); Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
SpecialPowers.setIntPref(timeoutPref, 45); Services.prefs.setIntPref(timeoutPref, 45);
hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2"); hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2");
p.stall(STALL_DURATION); p.stall(STALL_DURATION);
} }

View file

@ -40,14 +40,14 @@ function testSetup() {
function testInitialUnavailable() { function testInitialUnavailable() {
request = new PresentationRequest("https://example.com"); request = new PresentationRequest("https://example.com");
return request.getAvailability().then(function(aAvailability) { return request.getAvailability().then(async function(aAvailability) {
is(aAvailability.value, false, "Should have no available device after setup"); is(aAvailability.value, false, "Should have no available device after setup");
aAvailability.onchange = function() { aAvailability.onchange = function() {
aAvailability.onchange = null; aAvailability.onchange = null;
ok(aAvailability.value, "Device should be available."); ok(aAvailability.value, "Device should be available.");
}; };
availability = aAvailability; availability = aAvailability;
gScript.sendAsyncMessage("trigger-device-add", testDevice); await gScript.sendQuery("trigger-device-add", testDevice);
}).catch(function(aError) { }).catch(function(aError) {
ok(false, "Error occurred when getting availability: " + aError); ok(false, "Error occurred when getting availability: " + aError);
teardown(); teardown();

View file

@ -62,7 +62,7 @@ let currentMockSocket = null;
function setupMockPushSocket(mockWebSocket) { function setupMockPushSocket(mockWebSocket) {
currentMockSocket = mockWebSocket; currentMockSocket = mockWebSocket;
currentMockSocket._isActive = true; currentMockSocket._isActive = true;
chromeScript.sendSyncMessage("socket-setup"); chromeScript.sendAsyncMessage("socket-setup");
chromeScript.addMessageListener("socket-client-msg", function(msg) { chromeScript.addMessageListener("socket-client-msg", function(msg) {
mockWebSocket.handleMessage(msg); mockWebSocket.handleMessage(msg);
}); });
@ -73,7 +73,7 @@ function teardownMockPushSocket() {
return new Promise(resolve => { return new Promise(resolve => {
currentMockSocket._isActive = false; currentMockSocket._isActive = false;
chromeScript.addMessageListener("socket-server-teardown", resolve); chromeScript.addMessageListener("socket-server-teardown", resolve);
chromeScript.sendSyncMessage("socket-teardown"); chromeScript.sendAsyncMessage("socket-teardown");
}); });
} }
return Promise.resolve(); return Promise.resolve();

View file

@ -33,7 +33,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
} }
var secureTestsStarted = false; var secureTestsStarted = false;
function checkTestsCompleted() { async function checkTestsCompleted() {
for (var prop in testsToRunInsecure) { for (var prop in testsToRunInsecure) {
// some test hasn't run yet so we're not done // some test hasn't run yet so we're not done
if (!testsToRunInsecure[prop]) if (!testsToRunInsecure[prop])
@ -60,7 +60,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
} }
//call to change the preferences //call to change the preferences
counter++; counter++;
SpecialPowers.setBoolPref("security.mixed_content.block_active_content", false); await SpecialPowers.setBoolPref("security.mixed_content.block_active_content", false);
blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content"); blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content");
log("blockActive set to "+blockActive+"."); log("blockActive set to "+blockActive+".");
secureTestsStarted = false; secureTestsStarted = false;

View file

@ -64,68 +64,65 @@
return Promise.all(unregisterArray); return Promise.all(unregisterArray);
} }
function testScopes() { async function testScopes() {
return new Promise(function(resolve, reject) { function chromeScriptSource() {
function chromeScriptSource() { let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
let swm = Cc["@mozilla.org/serviceworkers/manager;1"] .getService(Ci.nsIServiceWorkerManager);
.getService(Ci.nsIServiceWorkerManager); let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"] .getService(Ci.nsIScriptSecurityManager);
.getService(Ci.nsIScriptSecurityManager); addMessageListener("getScope", (msg) => {
addMessageListener("getScope", (msg) => { let principal = secMan.createCodebasePrincipalFromOrigin(msg.principal);
let principal = secMan.createCodebasePrincipalFromOrigin(msg.principal);
try {
return { scope: swm.getScopeForUrl(principal, msg.path) };
} catch (e) {
return { exception: e.message };
}
});
}
let getScope;
let parent_intercept_enabled =
SpecialPowers.getBoolPref("dom.serviceWorkers.parent_intercept");
if (parent_intercept_enabled) {
let chromeScript = SpecialPowers.loadChromeScript(chromeScriptSource);
let docPrincipal = SpecialPowers.wrap(document).nodePrincipal.URI.spec;
getScope = (path) => {
let rv = chromeScript.sendSyncMessage("getScope", { principal: docPrincipal, path })[0][0];
if (rv.exception)
throw rv.exception;
return rv.scope;
};
} else {
getScope = navigator.serviceWorker.getScopeForUrl.bind(navigator.serviceWorker);
}
var base = new URL(".", document.baseURI);
function p(s) {
return base + s;
}
function fail(fn) {
try { try {
getScope(p("index.html")); return { scope: swm.getScopeForUrl(principal, msg.path) };
ok(false, "No registration"); } catch (e) {
} catch(e) { return { exception: e.message };
ok(true, "No registration");
} }
} });
}
is(getScope(p("sub.html")), p("sub"), "Scope should match"); let getScope;
is(getScope(p("sub/dir.html")), p("sub/dir.html"), "Scope should match"); let parent_intercept_enabled =
is(getScope(p("sub/dir")), p("sub/dir"), "Scope should match"); SpecialPowers.getBoolPref("dom.serviceWorkers.parent_intercept");
is(getScope(p("sub/dir/foo")), p("sub/dir/"), "Scope should match");
is(getScope(p("sub/dir/afoo")), p("sub/dir/a"), "Scope should match"); if (parent_intercept_enabled) {
is(getScope(p("star*wars")), p("star*"), "Scope should match"); let chromeScript = SpecialPowers.loadChromeScript(chromeScriptSource);
is(getScope(p("scope/some_file.html")), p("scope/"), "Scope should match"); let docPrincipal = SpecialPowers.wrap(document).nodePrincipal.URI.spec;
fail("index.html");
fail("sua.html"); getScope = async (path) => {
fail("star/a.html"); let rv = await chromeScript.sendQuery("getScope", { principal: docPrincipal, path });
resolve(); if (rv.exception)
}); throw rv.exception;
return rv.scope;
};
} else {
getScope = navigator.serviceWorker.getScopeForUrl.bind(navigator.serviceWorker);
}
var base = new URL(".", document.baseURI);
function p(s) {
return base + s;
}
async function fail(fn) {
try {
await getScope(p("index.html"));
ok(false, "No registration");
} catch(e) {
ok(true, "No registration");
}
}
is(await getScope(p("sub.html")), p("sub"), "Scope should match");
is(await getScope(p("sub/dir.html")), p("sub/dir.html"), "Scope should match");
is(await getScope(p("sub/dir")), p("sub/dir"), "Scope should match");
is(await getScope(p("sub/dir/foo")), p("sub/dir/"), "Scope should match");
is(await getScope(p("sub/dir/afoo")), p("sub/dir/a"), "Scope should match");
is(await getScope(p("star*wars")), p("star*"), "Scope should match");
is(await getScope(p("scope/some_file.html")), p("scope/"), "Scope should match");
await fail("index.html");
await fail("sua.html");
await fail("star/a.html");
} }
function runTest() { function runTest() {

View file

@ -47,13 +47,13 @@ let chromeScript = SpecialPowers.loadChromeScript(() => {
}); });
}); });
let chromeBuildID = chromeScript.sendSyncMessage("test:getBuildID")[0][0]; async function onMozillaIFrameLoaded() {
chromeScript.destroy(); let chromeBuildID = await chromeScript.sendQuery("test:getBuildID");
chromeScript.destroy();
ok(+chromeBuildID > LEGACY_BUILD_ID, ok(+chromeBuildID > LEGACY_BUILD_ID,
`navigator.buildID should be exposed in chrome - got "${chromeBuildID}"`); `navigator.buildID should be exposed in chrome - got "${chromeBuildID}"`);
function onMozillaIFrameLoaded() {
// //
// Access navigator.buildID from mozilla.org. // Access navigator.buildID from mozilla.org.
// //

View file

@ -8,7 +8,7 @@
<iframe src="about:blank"></iframe> <iframe src="about:blank"></iframe>
<script type="text/javascript"> <script type="text/javascript">
function checkForFindDialog() { async function checkForFindDialog() {
let chromeScript = SpecialPowers.loadChromeScript(_ => { let chromeScript = SpecialPowers.loadChromeScript(_ => {
addMessageListener("test:check", () => { addMessageListener("test:check", () => {
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
@ -25,7 +25,7 @@
}); });
let sawFind = chromeScript.sendSyncMessage("test:check")[0][0]; let sawFind = await chromeScript.sendQuery("test:check");
chromeScript.destroy(); chromeScript.destroy();
return sawFind; return sawFind;
} }
@ -67,7 +67,7 @@
"Should return false and not show a dialog if we pass an empty string."); "Should return false and not show a dialog if we pass an empty string.");
// Double check to ensure that the parent didn't open a find dialog // Double check to ensure that the parent didn't open a find dialog
let sawWindow = checkForFindDialog(); let sawWindow = await checkForFindDialog();
ok(!sawWindow, "Should never have seen the dialog."); ok(!sawWindow, "Should never have seen the dialog.");
}); });
} }

View file

@ -11,7 +11,9 @@
var SimpleTest = opener.wrappedJSObject.SimpleTest; var SimpleTest = opener.wrappedJSObject.SimpleTest;
var ok = opener.wrappedJSObject.ok; var ok = opener.wrappedJSObject.ok;
var doc = frames[0].document; // Note: We can't use frames[0] here because the type="content" attribute
// isolates it into a separate browsing context hierarchy.
var doc = document.querySelector("iframe").contentDocument;
ok(doc.createElement("body") instanceof HTMLBodyElement, ok(doc.createElement("body") instanceof HTMLBodyElement,
"Should be instance of HTMLBodyElement"); "Should be instance of HTMLBodyElement");
ok(doc.createElement("div") instanceof HTMLDivElement, ok(doc.createElement("div") instanceof HTMLDivElement,

View file

@ -34,7 +34,7 @@ window.onload = function() {
myLoadTime = performance.now(); myLoadTime = performance.now();
} }
SpecialPowers.pushPrefEnv({"set":[["dom.background_loading_iframe", true]]}, function () { SpecialPowers.pushPrefEnv({"set":[["dom.background_loading_iframe", true]]}).then(function () {
var iframe1 = document.createElement("iframe"); var iframe1 = document.createElement("iframe");
var iframe2 = document.createElement("iframe"); var iframe2 = document.createElement("iframe");
var iframe3 = document.createElement("iframe"); var iframe3 = document.createElement("iframe");

View file

@ -3,12 +3,12 @@
var GamepadService; var GamepadService;
function setGamepadPreferenceAndCreateIframe(iframeSrc) { async function setGamepadPreferenceAndCreateIframe(iframeSrc) {
SpecialPowers.pushPrefEnv({"set" : [["dom.gamepad.test.enabled", true]]}, () => { await SpecialPowers.pushPrefEnv({"set" : [["dom.gamepad.test.enabled", true]]});
let iframe = document.createElement("iframe");
iframe.src = iframeSrc; let iframe = document.createElement("iframe");
document.body.appendChild(iframe); iframe.src = iframeSrc;
}); document.body.appendChild(iframe);
} }
function runGamepadTest (callback) { function runGamepadTest (callback) {

View file

@ -43,11 +43,11 @@ function pressButton() {
GamepadService.newButtonEvent(gamepad_index, 0, false, false); GamepadService.newButtonEvent(gamepad_index, 0, false, false);
} }
function startTest() { async function startTest() {
SpecialPowers.pushPrefEnv({ "set": [ await SpecialPowers.pushPrefEnv({ "set": [
["dom.gamepad.extensions.enabled", true], ["dom.gamepad.extensions.enabled", true],
["dom.gamepad.extensions.lightindicator", true], ["dom.gamepad.extensions.lightindicator", true],
["dom.gamepad.extensions.multitouch", true]] }); ["dom.gamepad.extensions.multitouch", true]] });
// Add a gamepad // Add a gamepad
GamepadService.addGamepad("test gamepad", // id GamepadService.addGamepad("test gamepad", // id
GamepadService.standardMapping, GamepadService.standardMapping,

View file

@ -52,13 +52,14 @@ function pressButton() {
} }
let frames_loaded = 0; let frames_loaded = 0;
function startTest() { async function startTest() {
frames_loaded++; frames_loaded++;
SpecialPowers.pushPrefEnv({ "set": [ let promise = SpecialPowers.pushPrefEnv({ "set": [
["dom.gamepad.extensions.enabled", true], ["dom.gamepad.extensions.enabled", true],
["dom.gamepad.extensions.lightindicator", true], ["dom.gamepad.extensions.lightindicator", true],
["dom.gamepad.extensions.multitouch", true]] }); ["dom.gamepad.extensions.multitouch", true]] });
if (frames_loaded == 2) { if (frames_loaded == 2) {
await promise;
// Add a gamepad // Add a gamepad
GamepadService.addGamepad("test gamepad", // id GamepadService.addGamepad("test gamepad", // id
GamepadService.standardMapping, GamepadService.standardMapping,

View file

@ -93,7 +93,7 @@ function runTest() {
prompt("summary", "text"); prompt("summary", "text");
info("prompt is closed"); info("prompt is closed");
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
SimpleTest.finish(); SimpleTest.finish();
} }

View file

@ -17,7 +17,7 @@ async function setup() {
winUtils.advanceTimeAndRefresh(100); winUtils.advanceTimeAndRefresh(100);
} }
function* runTests() { async function* runTests() {
var e = document.getElementById("edit"); var e = document.getElementById("edit");
var doc = e.contentDocument; var doc = e.contentDocument;
var win = e.contentWindow; var win = e.contentWindow;
@ -181,9 +181,9 @@ function* runTests() {
is(testPageSelectCommand("cmd_selectPageUp", 0), 22 - lineNum, "cmd_selectPageUp"); is(testPageSelectCommand("cmd_selectPageUp", 0), 22 - lineNum, "cmd_selectPageUp");
}; };
yield SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]}); await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]});
runSelectionTests(body, 1); runSelectionTests(body, 1);
yield SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]}); await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]});
runSelectionTests(node(2), 0); runSelectionTests(node(2), 0);
} }
@ -196,7 +196,7 @@ async function testRunner() {
let curTest = runTests(); let curTest = runTests();
while (true) { while (true) {
winUtils.advanceTimeAndRefresh(100); winUtils.advanceTimeAndRefresh(100);
if (curTest.next().done) { if ((await curTest.next()).done) {
break; break;
} }
winUtils.advanceTimeAndRefresh(100); winUtils.advanceTimeAndRefresh(100);

View file

@ -50,7 +50,7 @@ var tests = [
var loadCount = 0; var loadCount = 0;
var script; var script;
var loadListener = function(evt) { var loadListener = async function(evt) {
if (loadCount == 0) { if (loadCount == 0) {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
@ -86,7 +86,7 @@ var loadListener = function(evt) {
hunspell.removeDirectory(de_DE); hunspell.removeDirectory(de_DE);
}); });
}); });
var existenceChecks = script.sendSyncMessage("check-existence")[0][0]; var existenceChecks = await script.sendQuery("check-existence");
is(existenceChecks[0], true, "true expected (en-GB directory should exist)"); is(existenceChecks[0], true, "true expected (en-GB directory should exist)");
is(existenceChecks[1], true, "true expected (en-AU directory should exist)"); is(existenceChecks[1], true, "true expected (en-AU directory should exist)");
is(existenceChecks[2], true, "true expected (de-DE directory should exist)"); is(existenceChecks[2], true, "true expected (de-DE directory should exist)");
@ -124,7 +124,7 @@ function continueTest(evt) {
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1200533_subframe.html?firstload=false"; content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1200533_subframe.html?firstload=false";
} else { } else {
// Remove the fake dictionaries again, since it's otherwise picked up by later tests. // Remove the fake dictionaries again, since it's otherwise picked up by later tests.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
SimpleTest.finish(); SimpleTest.finish();
} }

View file

@ -29,7 +29,7 @@ var content = document.getElementById("content");
var firstLoad = true; var firstLoad = true;
var script; var script;
var loadListener = function(evt) { var loadListener = async function(evt) {
if (firstLoad) { if (firstLoad) {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
@ -53,7 +53,7 @@ var loadListener = function(evt) {
addMessageListener("en_GB-exists", () => en_GB.exists()); addMessageListener("en_GB-exists", () => en_GB.exists());
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB)); addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
}); });
is(script.sendSyncMessage("en_GB-exists")[0][0], true, is(await script.sendQuery("en_GB-exists"), true,
"true expected (en-GB directory should exist)"); "true expected (en-GB directory should exist)");
} }
@ -97,7 +97,7 @@ var loadListener = function(evt) {
content.removeEventListener("load", loadListener); content.removeEventListener("load", loadListener);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests. // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
// Reset the preference, so the last value we set doesn't collide with the next test. // Reset the preference, so the last value we set doesn't collide with the next test.
SimpleTest.finish(); SimpleTest.finish();

View file

@ -34,7 +34,7 @@ var onSpellCheck =
/** Test for Bug 1205983 **/ /** Test for Bug 1205983 **/
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() { SimpleTest.waitForFocus(async function() {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
// eslint-disable-next-line mozilla/use-services // eslint-disable-next-line mozilla/use-services
@ -57,7 +57,7 @@ SimpleTest.waitForFocus(function() {
addMessageListener("de_DE-exists", () => de_DE.exists()); addMessageListener("de_DE-exists", () => de_DE.exists());
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE)); addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
}); });
is(script.sendSyncMessage("de_DE-exists")[0][0], true, is(await script.sendQuery("de_DE-exists"), true,
"true expected (de_DE directory should exist)"); "true expected (de_DE directory should exist)");
document.getElementById("de-DE").focus(); document.getElementById("de-DE").focus();
@ -106,7 +106,7 @@ function enFocus() {
is(sel.toString(), "German", "one misspelled word expected: German"); is(sel.toString(), "German", "one misspelled word expected: German");
// Remove the fake de_DE dictionary again. // Remove the fake de_DE dictionary again.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
// Focus again, so the spelling gets updated, but before we need to kill the focus handler. // Focus again, so the spelling gets updated, but before we need to kill the focus handler.
elem_de.onfocus = null; elem_de.onfocus = null;

View file

@ -41,13 +41,13 @@ var onSpellCheck =
"resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck; "resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() { SimpleTest.waitForFocus(async function() {
/* global browserElement */ /* global actorParent */
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
var chromeWin = browserElement.ownerGlobal.docShell var chromeWin = actorParent.rootFrameLoader
.rootTreeItem.domWindow .ownerElement.ownerGlobal.docShell
.QueryInterface(Ci.nsIDOMChromeWindow); .rootTreeItem.domWindow;
var contextMenu = chromeWin.document.getElementById("contentAreaContextMenu"); var contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
contextMenu.addEventListener("popupshown", contextMenu.addEventListener("popupshown",
() => sendAsyncMessage("popupshown")); () => sendAsyncMessage("popupshown"));
@ -85,9 +85,9 @@ SimpleTest.waitForFocus(function() {
addMessageListener("contextMenu-not-null", () => contextMenu != null); addMessageListener("contextMenu-not-null", () => contextMenu != null);
addMessageListener("de_DE-exists", () => de_DE.exists()); addMessageListener("de_DE-exists", () => de_DE.exists());
}); });
is(script.sendSyncMessage("contextMenu-not-null")[0][0], true, is(await script.sendQuery("contextMenu-not-null"), true,
"Got context menu XUL"); "Got context menu XUL");
is(script.sendSyncMessage("de_DE-exists")[0][0], true, is(await script.sendQuery("de_DE-exists"), true,
"true expected (de_DE directory should exist)"); "true expected (de_DE directory should exist)");
script.addMessageListener("popupshown", handlePopup); script.addMessageListener("popupshown", handlePopup);
@ -117,8 +117,8 @@ SimpleTest.waitForFocus(function() {
}); });
}); });
function handlePopup() { async function handlePopup() {
var state = script.sendSyncMessage("hidepopup")[0][0]; var state = await script.sendQuery("hidepopup");
is(state, "open", "checking if popup is open"); is(state, "open", "checking if popup is open");
onSpellCheck(elem_de, function() { onSpellCheck(elem_de, function() {
@ -135,7 +135,7 @@ function handlePopup() {
is(getMisspelledWords(editor_de), "heute" + "ist" + "ein" + "guter", "some misspelled words expected: heute ist ein guter"); is(getMisspelledWords(editor_de), "heute" + "ist" + "ein" + "guter", "some misspelled words expected: heute ist ein guter");
// Remove the fake de_DE dictionary again. // Remove the fake de_DE dictionary again.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary". // This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.SetCurrentDictionary(""); spellchecker.SetCurrentDictionary("");

View file

@ -28,7 +28,7 @@ var content = document.getElementById("content");
var firstLoad = true; var firstLoad = true;
var script; var script;
var loadListener = function(evt) { var loadListener = async function(evt) {
if (firstLoad) { if (firstLoad) {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
@ -52,7 +52,7 @@ var loadListener = function(evt) {
addMessageListener("en_GB-exists", () => en_GB.exists()); addMessageListener("en_GB-exists", () => en_GB.exists());
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB)); addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
}); });
is(script.sendSyncMessage("en_GB-exists")[0][0], true, is(await script.sendQuery("en_GB-exists"), true,
"true expected (en-GB directory should exist)"); "true expected (en-GB directory should exist)");
} }
@ -89,7 +89,7 @@ var loadListener = function(evt) {
content.removeEventListener("load", loadListener); content.removeEventListener("load", loadListener);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests. // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary". // This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.SetCurrentDictionary(""); spellchecker.SetCurrentDictionary("");

View file

@ -34,7 +34,7 @@ var onSpellCheck =
/** Test for Bug 697981 **/ /** Test for Bug 697981 **/
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() { SimpleTest.waitForFocus(async function() {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
// eslint-disable-next-line mozilla/use-services // eslint-disable-next-line mozilla/use-services
@ -57,7 +57,7 @@ SimpleTest.waitForFocus(function() {
addMessageListener("de_DE-exists", () => de_DE.exists()); addMessageListener("de_DE-exists", () => de_DE.exists());
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE)); addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
}); });
is(script.sendSyncMessage("de_DE-exists")[0][0], true, is(await script.sendQuery("de_DE-exists"), true,
"true expected (de_DE directory should exist)"); "true expected (de_DE directory should exist)");
document.getElementById("de-DE").focus(); document.getElementById("de-DE").focus();
@ -107,7 +107,7 @@ function enFocus() {
is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German"); is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
// Remove the fake de_DE dictionary again. // Remove the fake de_DE dictionary again.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
// Focus again, so the spelling gets updated, but before we need to kill the focus handler. // Focus again, so the spelling gets updated, but before we need to kill the focus handler.
elem_de.onfocus = null; elem_de.onfocus = null;

View file

@ -29,7 +29,7 @@ var firstLoad = true;
var expected = ""; var expected = "";
var script; var script;
var loadListener = function(evt) { var loadListener = async function(evt) {
if (firstLoad) { if (firstLoad) {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() { script = SpecialPowers.loadChromeScript(function() {
@ -53,7 +53,7 @@ var loadListener = function(evt) {
addMessageListener("en_GB-exists", () => en_GB.exists()); addMessageListener("en_GB-exists", () => en_GB.exists());
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB)); addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
}); });
is(script.sendSyncMessage("en_GB-exists")[0][0], true, is(await script.sendQuery("en_GB-exists"), true,
"true expected (en-GB directory should exist)"); "true expected (en-GB directory should exist)");
} }
@ -90,7 +90,7 @@ var loadListener = function(evt) {
content.removeEventListener("load", loadListener); content.removeEventListener("load", loadListener);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests. // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
script.sendSyncMessage("destroy"); script.sendAsyncMessage("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary". // This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.SetCurrentDictionary(""); spellchecker.SetCurrentDictionary("");

View file

@ -123,7 +123,7 @@ are also in the UI process. Consider this outline of a Gecko display list:
If item P was a filter, for example, that would normally apply to all of items If item P was a filter, for example, that would normally apply to all of items
A, B, and C. This would mean either sharing the filter between the "chrome" renderroot A, B, and C. This would mean either sharing the filter between the "chrome" renderroot
and the "content" renderroot, or duplicating it such that it existed in both and the "content" renderroot, or duplicating it such that it existed in both
renderroots. The sharing is not possibly as it violates the independence of WR renderroots. The sharing is not possible as it violates the independence of WR
documents. The duplication is technically possible, but could result in visual documents. The duplication is technically possible, but could result in visual
glitches as the two documents would be processed and composited separately. glitches as the two documents would be processed and composited separately.
@ -135,7 +135,7 @@ properties do NOT get carried across the render root boundary. Similarly, a
scrollframe may not contain content from multiple render roots, because that scrollframe may not contain content from multiple render roots, because that
would lead to a similar problem in APZ where it would have to update the scroll would lead to a similar problem in APZ where it would have to update the scroll
position of scrollframes in multiple documents and they might get composited position of scrollframes in multiple documents and they might get composited
at separate times resulting in visual glitches. at separate times, resulting in visual glitches.
Security Concerns Security Concerns
----------------- -----------------
@ -225,7 +225,7 @@ helpers in gfxUtils that assist with this task.
The other catch is that an APZ message may be associated with multiple documents. The other catch is that an APZ message may be associated with multiple documents.
A concrete example is if a user on a touch device does a multitouch action with A concrete example is if a user on a touch device does a multitouch action with
one fingers landing on different documents, which would trigger a call to different fingers landing on different documents, which would trigger a call to
`RecvSetTargetAPZC `RecvSetTargetAPZC
<https://searchfox.org/mozilla-central/rev/06bd14ced96f25ff1dbd5352cb985fc0fa12a64e/gfx/layers/ipc/APZCTreeManagerParent.cpp#76>`_ <https://searchfox.org/mozilla-central/rev/06bd14ced96f25ff1dbd5352cb985fc0fa12a64e/gfx/layers/ipc/APZCTreeManagerParent.cpp#76>`_
with multiple targets, each potentially belonging to a different render root. with multiple targets, each potentially belonging to a different render root.
@ -243,7 +243,7 @@ Deferred updates
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Bug 1547351 provided a new and tricky problem where a content process is rendering Bug 1547351 provided a new and tricky problem where a content process is rendering
stuff that needs go into the "default" document because it's actually an stuff that needs to go into the "default" document because it's actually an
out-of-process addon content that renders in the chrome area. Prior to this bug, out-of-process addon content that renders in the chrome area. Prior to this bug,
the WebRenderBridgeParent instances that corresponded to content processes the WebRenderBridgeParent instances that corresponded to content processes
(hereafter referred to as "sub-WRBPs", in contrast to the "root WRBP" that (hereafter referred to as "sub-WRBPs", in contrast to the "root WRBP" that
@ -255,7 +255,7 @@ The solution chosen to this problem was to have the root WebRenderLayerManager
with the render root it belongs in, and send that information over to the with the render root it belongs in, and send that information over to the
root WRBP as part of the display list transaction. The sub-WRBPs know their own root WRBP as part of the display list transaction. The sub-WRBPs know their own
pipeline ids, and therefore can find their render root by querying the root WRBP. pipeline ids, and therefore can find their render root by querying the root WRBP.
The catch is that sub-WRBPs may receive display list transactions before the The catch is that sub-WRBPs may receive display list transactions *before* the
root WRBP receives the display list update that contains the render root mapping root WRBP receives the display list update that contains the render root mapping
information. This happens in cases like during tab switch preload, where the information. This happens in cases like during tab switch preload, where the
user mouses over a background tab, and we pre-render it (i.e. compute and send user mouses over a background tab, and we pre-render it (i.e. compute and send
@ -310,7 +310,7 @@ scenario, other documents may still be backlogged, so the unthrottling is
undesirable. undesirable.
Instead, what we want is for all documents processing a particular transaction Instead, what we want is for all documents processing a particular transaction
id to finish their word and render before we send the completion message back id to finish their work and render before we send the completion message back
to content. In fact, there's a bunch of work that falls into the same category to content. In fact, there's a bunch of work that falls into the same category
as this completion message - stuff that should happen after all the WR documents as this completion message - stuff that should happen after all the WR documents
are done processing their pieces of the split transaction. are done processing their pieces of the split transaction.
@ -324,8 +324,8 @@ acts as a barrier to ensure that the call chain only gets propagated once all
the documents have done their processing work. the documents have done their processing work.
I'm listing this piece as a potential source of complexity for document splitting I'm listing this piece as a potential source of complexity for document splitting
because it seems like a fairly important piece but the relevant code that is because it seems like a fairly important piece but the relevant code is
"buried" away in place where one might not easily stumble upon it. It's also not "buried" away in a place where one might not easily stumble upon it. It's also not
clear to me that the implications of this problem and solution have been fully clear to me that the implications of this problem and solution have been fully
explored. In particular, I assume that there are latent bugs here because other explored. In particular, I assume that there are latent bugs here because other
pieces of code were assuming a certain behaviour from the pre-document-splitting pieces of code were assuming a certain behaviour from the pre-document-splitting

View file

@ -422,7 +422,7 @@ async function waitUntilApzStable() {
if (typeof waitUntilApzStable.chromeHelper == "undefined") { if (typeof waitUntilApzStable.chromeHelper == "undefined") {
waitUntilApzStable.chromeHelper = SpecialPowers.loadChromeScript(parentProcessFlush); waitUntilApzStable.chromeHelper = SpecialPowers.loadChromeScript(parentProcessFlush);
ApzCleanup.register(() => { ApzCleanup.register(() => {
waitUntilApzStable.chromeHelper.sendSyncMessage("cleanup", null); waitUntilApzStable.chromeHelper.sendAsyncMessage("cleanup", null);
waitUntilApzStable.chromeHelper.destroy(); waitUntilApzStable.chromeHelper.destroy();
delete waitUntilApzStable.chromeHelper; delete waitUntilApzStable.chromeHelper;
}); });
@ -580,7 +580,7 @@ function getSnapshot(rect) {
ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy(); }); ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy(); });
} }
return getSnapshot.chromeHelper.sendSyncMessage("snapshot", JSON.stringify(rect)).toString(); return getSnapshot.chromeHelper.sendQuery("snapshot", JSON.stringify(rect));
} }
// Takes the document's query string and parses it, assuming the query string // Takes the document's query string and parses it, assuming the query string

View file

@ -33,45 +33,56 @@ function listener(callback) {
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
function chromeTouchEventCounter(operation) { function chromeTouchEventCounter(operation) {
function chromeProcessCounter() { function chromeProcessCounter() {
addMessageListener("start", function() { const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
if (typeof topWin.eventCounts != "undefined") {
dump("Found pre-existing eventCounts object on the top window!\n");
return false;
}
topWin.eventCounts = { "touchstart": 0, "touchmove": 0, "touchend": 0 };
topWin.counter = function(e) {
topWin.eventCounts[e.type]++;
};
topWin.addEventListener("touchstart", topWin.counter, { passive: true }); const PREFIX = "apz:ctec:";
topWin.addEventListener("touchmove", topWin.counter, { passive: true });
topWin.addEventListener("touchend", topWin.counter, { passive: true });
return true; const LISTENERS = {
}); "start": function() {
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
if (typeof topWin.eventCounts != "undefined") {
dump("Found pre-existing eventCounts object on the top window!\n");
return false;
}
topWin.eventCounts = { "touchstart": 0, "touchmove": 0, "touchend": 0 };
topWin.counter = function(e) {
topWin.eventCounts[e.type]++;
};
addMessageListener("report", function() { topWin.addEventListener("touchstart", topWin.counter, { passive: true });
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); topWin.addEventListener("touchmove", topWin.counter, { passive: true });
var topWin = Services.wm.getMostRecentWindow("navigator:browser"); topWin.addEventListener("touchend", topWin.counter, { passive: true });
return JSON.stringify(topWin.eventCounts);
});
addMessageListener("end", function() { return true;
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); },
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
if (typeof topWin.eventCounts == "undefined") { "report": function() {
dump("The eventCounts object was not found on the top window!\n"); var topWin = Services.wm.getMostRecentWindow("navigator:browser");
return false; return JSON.stringify(topWin.eventCounts);
} },
topWin.removeEventListener("touchstart", topWin.counter);
topWin.removeEventListener("touchmove", topWin.counter); "end": function() {
topWin.removeEventListener("touchend", topWin.counter); for (let [msg, func] of Object.entries(LISTENERS)) {
delete topWin.counter; Services.ppmm.removeMessageListener(PREFIX + msg, func);
delete topWin.eventCounts; }
return true;
}); var topWin = Services.wm.getMostRecentWindow("navigator:browser");
if (typeof topWin.eventCounts == "undefined") {
dump("The eventCounts object was not found on the top window!\n");
return false;
}
topWin.removeEventListener("touchstart", topWin.counter);
topWin.removeEventListener("touchmove", topWin.counter);
topWin.removeEventListener("touchend", topWin.counter);
delete topWin.counter;
delete topWin.eventCounts;
return true;
},
};
for (let [msg, func] of Object.entries(LISTENERS)) {
Services.ppmm.addMessageListener(PREFIX + msg, func);
}
} }
if (typeof chromeTouchEventCounter.chromeHelper == "undefined") { if (typeof chromeTouchEventCounter.chromeHelper == "undefined") {
@ -80,7 +91,7 @@ function chromeTouchEventCounter(operation) {
ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy(); }); ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy(); });
} }
return chromeTouchEventCounter.chromeHelper.sendSyncMessage(operation, ""); return SpecialPowers.Services.cpmm.sendSyncMessage(`apz:ctec:${operation}`, "")[0];
} }
// Simple wrapper that waits until the chrome process has seen |count| instances // Simple wrapper that waits until the chrome process has seen |count| instances

View file

@ -559,7 +559,8 @@ SI void sample_clut_16(const skcms_A2B* a2b, I32 ix, F* r, F* g, F* b) {
// GCC 7.2.0 hits an internal compiler error with -finline-functions (or -O3) // GCC 7.2.0 hits an internal compiler error with -finline-functions (or -O3)
// when targeting MIPS 64, I think attempting to inline clut() into exec_ops(). // when targeting MIPS 64, I think attempting to inline clut() into exec_ops().
#if 1 && defined(__GNUC__) && !defined(__clang__) && defined(__mips64) // s390x and i*86 also hit this with GCC 7.4 and -O2
#if 1 && defined(__GNUC__) && !defined(__clang__) && (defined(__mips64) || defined(__s390x__) || defined(__i586__) || defined(__i486__) || defined(__i386__))
#define MAYBE_NOINLINE __attribute__((noinline)) #define MAYBE_NOINLINE __attribute__((noinline))
#else #else
#define MAYBE_NOINLINE #define MAYBE_NOINLINE

View file

@ -6,3 +6,4 @@ subsuite = gpu
[test_bug509244.html] [test_bug509244.html]
[test_bug513439.html] [test_bug513439.html]
[test_font_whitelist.html] [test_font_whitelist.html]
skip-if = debug || asan # Race between pref service and gfx platform IPC causes frequent failures on debug/ASan

View file

@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1121643
/** Test for Bug 1121643 **/ /** Test for Bug 1121643 **/
SimpleTest.requestFlakyTimeout("This test is flaky.");
const InspectorUtils = SpecialPowers.InspectorUtils; const InspectorUtils = SpecialPowers.InspectorUtils;
// Given an element id, returns the first font face name encountered. // Given an element id, returns the first font face name encountered.
@ -53,6 +55,7 @@ let testFontWhitelist = async function(useMono, useSans, useSerif) {
} }
await SpecialPowers.pushPrefEnv({"set": [["font.system.whitelist", await SpecialPowers.pushPrefEnv({"set": [["font.system.whitelist",
whitelist.join(", ")]]}); whitelist.join(", ")]]});
await new Promise(resolve => setTimeout(resolve, 2000));
// If whitelist is empty, then whitelisting is considered disabled // If whitelist is empty, then whitelisting is considered disabled
// and all fonts are allowed. // and all fonts are allowed.
info("font whitelist: " + JSON.stringify(whitelist)); info("font whitelist: " + JSON.stringify(whitelist));

View file

@ -13,27 +13,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1124898
/** Test for Bug 1124898 **/ /** Test for Bug 1124898 **/
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", (async () => {
true]]}); await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", true]]});
SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023.
var w = window.open("about:blank", "w", "chrome");
is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window');
is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window');
var contentURL = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
w.location = contentURL;
tryWindow();
function tryWindow() { SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023.
if (w.document.title != 'empty test page') {
info("Document not loaded yet - retrying"); var w = window.open("about:blank", "w", "chrome");
SimpleTest.executeSoon(tryWindow); is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window');
return; is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window');
var contentURL = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
w.location = contentURL;
tryWindow();
function tryWindow() {
if (w.document.title != 'empty test page') {
info("Document not loaded yet - retrying");
SimpleTest.executeSoon(tryWindow);
return;
}
is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window');
is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window');
w.close();
SimpleTest.finish();
} }
is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window'); })();
is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window');
w.close();
SimpleTest.finish();
}
</script> </script>
</head> </head>

View file

@ -14,36 +14,38 @@
<!-- test code goes here --> <!-- test code goes here -->
<script type="application/javascript"><![CDATA[ <script type="application/javascript"><![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", SimpleTest.waitForExplicitFinish();
true]]});
function init() { function init() {
var f = new Function("let test = 'let is ok'; return test;"); var f = new Function("let test = 'let is ok'; return test;");
is(f(), 'let is ok', 'let should be ok'); is(f(), 'let is ok', 'let should be ok');
SimpleTest.finish(); SimpleTest.finish();
} }
Test = { (async () => {
include: function(p) { await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
var sawError = false; true]]});
try { Test = {
Cc["@mozilla.org/moz/jssubscript-loader;1"]. include: function(p) {
getService(Ci["mozIJSSubScriptLoader"]). var sawError = false;
loadSubScript(p); try {
} catch (e) { Cc["@mozilla.org/moz/jssubscript-loader;1"].
sawError = true; getService(Ci["mozIJSSubScriptLoader"]).
} loadSubScript(p);
ok(sawError, 'should receive an error loading a not-found file'); } catch (e) {
} sawError = true;
}; }
ok(sawError, 'should receive an error loading a not-found file');
}
};
// If the include method is defined as a global function, it works. // If the include method is defined as a global function, it works.
// try to load a non existing file to produce the error // try to load a non existing file to produce the error
Test.include("notfound.js"); Test.include("notfound.js");
// If init is called directly, it works. // If init is called directly, it works.
setTimeout('init();', 0); setTimeout('init();', 0);
})();
SimpleTest.waitForExplicitFinish();
]]></script> ]]></script>
</window> </window>

View file

@ -18,8 +18,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
<script type="application/javascript"> <script type="application/javascript">
<![CDATA[ <![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", add_task(async () => {
true]]}); await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
// //
// Important! If this test starts failing after a tricky platform-y change, // Important! If this test starts failing after a tricky platform-y change,
// the stack quota numbers in XPCJSContext probably need twiddling. We want // the stack quota numbers in XPCJSContext probably need twiddling. We want
@ -76,7 +77,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
contentSb.nnslChrome = chromeSb.nearNativeStackLimit; contentSb.nnslChrome = chromeSb.nearNativeStackLimit;
var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb); var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb);
ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit); ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit);
});
]]> ]]>
</script> </script>
</window> </window>

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