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) {
return new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
});
return SpecialPowers.pushPrefEnv({"set": aPrefs});
}
function popPrefs() {
return new Promise(resolve => {
SpecialPowers.popPrefEnv(resolve);
});
return SpecialPowers.popPrefEnv();
}
function updateBlocklist(aCallback) {

View file

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

View file

@ -129,9 +129,9 @@
const permission = "geolocation";
const promiseGranted = this.promiseStateChanged(permission, "granted");
this.setPermissions(ALLOW_ACTION);
promiseGranted.then(() => {
promiseGranted.then(async () => {
const promisePrompt = this.promiseStateChanged(permission, "prompt");
SpecialPowers.popPermissions();
await SpecialPowers.popPermissions();
return promisePrompt;
}).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}`);
return new Promise(resolve => {
formFillChromeScript.sendAsyncMessage(message, payload);
formFillChromeScript.addMessageListener(response, function onReceived(data) {
formFillChromeScript.removeMessageListener(response, onReceived);
resolve(data);
});
});
return formFillChromeScript.sendQuery(message, payload);
}
async function addAddress(address) {
await invokeAsyncChromeTask("FormAutofillTest:AddAddress", "FormAutofillTest:AddressAdded", {address});
await invokeAsyncChromeTask("FormAutofillTest:AddAddress", {address});
await sleep();
}
async function removeAddress(guid) {
return invokeAsyncChromeTask("FormAutofillTest:RemoveAddress", "FormAutofillTest:AddressRemoved", {guid});
return invokeAsyncChromeTask("FormAutofillTest:RemoveAddress", {guid});
}
async function updateAddress(guid, address) {
return invokeAsyncChromeTask("FormAutofillTest:UpdateAddress", "FormAutofillTest:AddressUpdated", {address, guid});
return invokeAsyncChromeTask("FormAutofillTest:UpdateAddress", {address, guid});
}
async function checkAddresses(expectedAddresses) {
return invokeAsyncChromeTask("FormAutofillTest:CheckAddresses", "FormAutofillTest:areAddressesMatching", {expectedAddresses});
return invokeAsyncChromeTask("FormAutofillTest:CheckAddresses", {expectedAddresses});
}
async function cleanUpAddresses() {
return invokeAsyncChromeTask("FormAutofillTest:CleanUpAddresses", "FormAutofillTest:AddressesCleanedUp");
return invokeAsyncChromeTask("FormAutofillTest:CleanUpAddresses");
}
async function addCreditCard(creditcard) {
await invokeAsyncChromeTask("FormAutofillTest:AddCreditCard", "FormAutofillTest:CreditCardAdded", {creditcard});
await invokeAsyncChromeTask("FormAutofillTest:AddCreditCard", {creditcard});
await sleep();
}
async function removeCreditCard(guid) {
return invokeAsyncChromeTask("FormAutofillTest:RemoveCreditCard", "FormAutofillTest:CreditCardRemoved", {guid});
return invokeAsyncChromeTask("FormAutofillTest:RemoveCreditCard", {guid});
}
async function checkCreditCards(expectedCreditCards) {
return invokeAsyncChromeTask("FormAutofillTest:CheckCreditCards", "FormAutofillTest:areCreditCardsMatching", {expectedCreditCards});
return invokeAsyncChromeTask("FormAutofillTest:CheckCreditCards", {expectedCreditCards});
}
async function cleanUpCreditCards() {
return invokeAsyncChromeTask("FormAutofillTest:CleanUpCreditCards", "FormAutofillTest:CreditCardsCleanedUp");
return invokeAsyncChromeTask("FormAutofillTest:CleanUpCreditCards");
}
async function cleanUpStorage() {
@ -230,12 +223,12 @@ async function cleanUpStorage() {
}
async function canTestOSKeyStoreLogin() {
let {canTest} = await invokeAsyncChromeTask("FormAutofillTest:CanTestOSKeyStoreLogin", "FormAutofillTest:CanTestOSKeyStoreLoginResult");
let {canTest} = await invokeAsyncChromeTask("FormAutofillTest:CanTestOSKeyStoreLogin");
return canTest;
}
async function waitForOSKeyStoreLogin(login = false) {
await invokeAsyncChromeTask("FormAutofillTest:OSKeyStoreLogin", "FormAutofillTest:OSKeyStoreLoggedIn", {login});
await invokeAsyncChromeTask("FormAutofillTest:OSKeyStoreLogin", {login});
}
function patchRecordCCNumber(record) {
@ -302,15 +295,13 @@ function formAutoFillCommonSetup() {
});
add_task(async function setup() {
formFillChromeScript.sendAsyncMessage("setup");
info(`expecting the storage setup`);
await formFillChromeScript.promiseOneMessage("setup-finished");
await formFillChromeScript.sendQuery("setup");
});
SimpleTest.registerCleanupFunction(async () => {
formFillChromeScript.sendAsyncMessage("cleanup");
info(`expecting the storage cleanup`);
await formFillChromeScript.promiseOneMessage("cleanup-finished");
await formFillChromeScript.sendQuery("cleanup");
formFillChromeScript.destroy();
expectingPopup = null;

View file

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

View file

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

View file

@ -16,7 +16,6 @@
#include "nsQueryObject.h"
#include "mozilla/dom/URL.h"
#include "nsDOMWindowList.h"
#include "nsIConsoleService.h"
#include "mozilla/dom/Document.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
// which has been saved in the preference but it doesn't exist anymore.
await SpecialPowers.pushPrefEnv({
set: [["devtools.inspector.activeSidebar"], "unexisting-sidebar-id"],
set: [["devtools.inspector.activeSidebar", "unexisting-sidebar-id"]],
});
const res = await openInspectorForURL("about:blank");

View file

@ -34,7 +34,7 @@ const HTML_VOID_ELEMENTS = [
// element markup and their respective title tooltip text.
const DISPLAY_TYPES = {
"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"),
"inline-grid": INSPECTOR_L10N.getStr("markupView.display.inlineGrid.tooltiptext"),
"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 new Promise(resolve => setTimeout(resolve, 0));
};
/**
@ -596,10 +598,8 @@ function waitForClipboardPromise(setup, expected) {
* @return {Promise} resolves when the preferences have been updated
*/
function pushPref(preferenceName, value) {
return new Promise(resolve => {
const options = {"set": [[preferenceName, value]]};
SpecialPowers.pushPrefEnv(options, resolve);
});
return SpecialPowers.pushPrefEnv(options);
}
/**

View file

@ -92,7 +92,7 @@ addEventListener("load", startTest);
// This test needs to add tabs that are controlled by a service worker
// 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(() => {
while (gBrowser.tabs.length > 1) {

View file

@ -16,6 +16,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Location.h"
#include "mozilla/dom/LocationBinding.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/dom/WindowGlobalParent.h"
@ -90,6 +91,12 @@ already_AddRefed<BrowsingContext> BrowsingContext::Get(uint64_t aId) {
return do_AddRef(sBrowsingContexts->Get(aId));
}
/* static */
already_AddRefed<BrowsingContext> BrowsingContext::GetFromWindow(
WindowProxyHolder& aProxy) {
return do_AddRef(aProxy.get());
}
CanonicalBrowsingContext* BrowsingContext::Canonical() {
return CanonicalBrowsingContext::Cast(this);
}
@ -551,6 +558,45 @@ JSObject* BrowsingContext::WrapObject(JSContext* aCx,
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() {
// We would set the user gesture activation flag on the top level browsing
// context, which would automatically be sync to other top level browsing

View file

@ -51,6 +51,7 @@ template <typename>
struct Nullable;
template <typename T>
class Sequence;
class StructuredCloneHolder;
struct WindowPostMessageOptions;
class WindowProxyHolder;
@ -104,6 +105,13 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
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.
static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent,
BrowsingContext* aOpener,
@ -266,6 +274,12 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
JSObject* WrapObject(JSContext* aCx);
static JSObject* ReadStructuredClone(JSContext* aCx,
JSStructuredCloneReader* aReader,
StructuredCloneHolder* aHolder);
bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter,
StructuredCloneHolder* aHolder);
void StartDelayedAutoplayMediaComponents();
/**

View file

@ -8,15 +8,13 @@
onload="setTimeout(nextTest, 0);"
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 type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
<script type="application/javascript" src="docshell_helpers.js" />
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
<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.
var tests = testIterator();

View file

@ -8,8 +8,6 @@
onload="setTimeout(nextTest, 0);"
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 type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
<script type="application/javascript" src="docshell_helpers.js" />

View file

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

View file

@ -44,18 +44,20 @@ function checkLoadFrame1() {
myFrame1.src = CROSS_ORIGIN_URI;
}
function checkNavFrame1() {
async function 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");
myFrame1.addEventListener("load", checkBackNavFrame1);
myFrame1.src = SAME_ORIGIN_URI + "#bar";
}
function checkBackNavFrame1() {
async function 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");
checkFinish();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,11 +16,11 @@ window.onload = function() {
'<iframe src="navigate.html#child2,form"></iframe>' +
'<iframe src="navigate.html#child3,hyperlink"></iframe>';
xpcWaitForFinishedFrames(function() {
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.");
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.");
xpcWaitForFinishedFrames(async function() {
await isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location.");
await isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open.");
await isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form.");
await isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink.");
xpcCleanupWindows();
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
[test_bug442584.js]
[test_browsing_context_structured_clone.js]
[test_nsDefaultURIFixup.js]
[test_nsDefaultURIFixup_search.js]
skip-if = os == 'android'

View file

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

View file

@ -161,17 +161,21 @@ class Selection final : public nsSupportsWeakReference,
ScrollAxis aVertical = ScrollAxis(),
ScrollAxis aHorizontal = ScrollAxis(),
int32_t aFlags = 0);
nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract,
static nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract,
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
* into multiple ranges to exclude those before adding the resulting ranges
* to this Selection.
*/
nsresult AddItem(nsRange* aRange, int32_t* aOutIndex,
nsresult AddRangesForSelectableNodes(nsRange* aRange, int32_t* aOutIndex,
bool aNoStartSelect = false);
nsresult RemoveItem(nsRange* aRange);
nsresult RemoveRangeInternal(nsRange& aRange);
public:
nsresult RemoveCollapsedRanges();
nsresult Clear(nsPresContext* aPresContext);
nsresult Collapse(nsINode* aContainer, int32_t aOffset) {
@ -737,13 +741,14 @@ class Selection final : public nsSupportsWeakReference,
int32_t* aEndIndex);
RangeData* FindRangeData(nsRange* aRange);
void UserSelectRangesToAdd(nsRange* aItem,
static void UserSelectRangesToAdd(nsRange* aItem,
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;
nsPIDOMWindowOuter* GetWindow() const;

View file

@ -10,6 +10,8 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/BrowsingContextBinding.h"
#include "mozilla/dom/StructuredCloneBlob.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/DirectoryBinding.h"
@ -910,6 +912,10 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
return ReadInputStream(aCx, aIndex, this);
}
if (aTag == SCTAG_DOM_BROWSING_CONTEXT) {
return BrowsingContext::ReadStructuredClone(aCx, aReader, this);
}
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.
if ((mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
mStructuredCloneScope ==

View file

@ -137,6 +137,8 @@ enum StructuredCloneTags {
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
// "less stable" tags!
};

View file

@ -9,7 +9,6 @@
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/WindowProxyHolder.h"
#include "nsContentUtils.h"
#include "nsDOMWindowList.h"
#include "nsGlobalWindow.h"
#include "nsHTMLDocument.h"
#include "nsJSUtils.h"
@ -18,18 +17,17 @@
namespace mozilla {
namespace dom {
static bool ShouldExposeChildWindow(nsString& aNameBeingResolved,
static bool ShouldExposeChildWindow(const nsString& aNameBeingResolved,
BrowsingContext* aChild) {
nsPIDOMWindowOuter* child = aChild->GetDOMWindow();
Element* e = child->GetFrameElementInternal();
Element* e = aChild->GetEmbedderElement();
if (e && e->IsInShadowTree()) {
return false;
}
// If we're same-origin with the child, go ahead and expose it.
nsPIDOMWindowOuter* child = aChild->GetDOMWindow();
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(child);
NS_ENSURE_TRUE(sop, false);
if (nsContentUtils::SubjectPrincipal()->Equals(sop->GetPrincipal())) {
if (sop && nsContentUtils::SubjectPrincipal()->Equals(sop->GetPrincipal())) {
return true;
}
@ -169,23 +167,12 @@ bool WindowNamedPropertiesHandler::ownPropNames(
// The names live on the outer window, which might be null
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();
if (outer) {
nsDOMWindowList* childWindows = outer->GetFrames();
if (childWindows) {
uint32_t length = childWindows->GetLength();
for (uint32_t i = 0; i < length; ++i) {
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)) {
if (BrowsingContext* bc = outer->GetBrowsingContext()) {
for (const auto& child : bc->GetChildren()) {
const nsString& name = child->Name();
if (!name.IsEmpty() && !names.Contains(name)) {
// Make sure we really would expose it from getOwnPropDescriptor.
RefPtr<BrowsingContext> child = win->GetChildWindow(name);
if (child && ShouldExposeChildWindow(name, child)) {
if (ShouldExposeChildWindow(name, child)) {
names.AppendElement(name);
}
}

View file

@ -336,7 +336,6 @@ UNIFIED_SOURCES += [
'nsDOMNavigationTiming.cpp',
'nsDOMSerializer.cpp',
'nsDOMTokenList.cpp',
'nsDOMWindowList.cpp',
'nsFocusManager.cpp',
'nsFrameLoader.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 "nsDOMJSUtils.h"
#include "nsArrayUtils.h"
#include "nsDOMWindowList.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "nsIContentSecurityPolicy.h"
@ -2708,11 +2707,7 @@ bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
FORWARD_TO_OUTER(GetClosedOuter, (), true);
}
nsDOMWindowList* nsGlobalWindowInner::GetFrames() {
FORWARD_TO_OUTER(GetFrames, (), nullptr);
}
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowInner::IndexedGetter(
Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
uint32_t aIndex) {
FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
}

View file

@ -77,7 +77,6 @@ class nsITimeoutHandler;
class nsIWebBrowserChrome;
class mozIDOMWindowProxy;
class nsDOMWindowList;
class nsScreen;
class nsHistory;
class nsGlobalWindowObserver;
@ -381,7 +380,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
NS_DECL_NSIINTERFACEREQUESTOR
// 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);
@ -612,7 +612,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
void Focus(mozilla::ErrorResult& aError);
nsresult Focus() override;
void Blur(mozilla::ErrorResult& aError);
nsDOMWindowList* GetFrames() final;
mozilla::dom::BrowsingContext* GetFrames(mozilla::ErrorResult& aError);
uint32_t Length();
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTop(

View file

@ -48,7 +48,6 @@
#include "nsISizeOfEventTarget.h"
#include "nsDOMJSUtils.h"
#include "nsArrayUtils.h"
#include "nsDOMWindowList.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.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
// window at that index.
already_AddRefed<nsPIDOMWindowOuter> GetSubframeWindow(
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const;
Nullable<WindowProxyHolder> GetSubframeWindow(JSContext* cx,
JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id) const;
bool AppendIndexedPropertyNames(JSObject* proxy,
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"));
}
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
// Fail (which means throw if strict, else return false).
return result.failCantDeleteWindowElement();
}
@ -818,7 +818,7 @@ bool nsOuterWindowProxy::has(JSContext* cx, JS::Handle<JSObject*> proxy,
return hasOwn(cx, proxy, id, bp);
}
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
*bp = true;
return true;
}
@ -851,7 +851,7 @@ bool nsOuterWindowProxy::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp);
}
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
*bp = true;
return true;
}
@ -982,28 +982,17 @@ bool nsOuterWindowProxy::GetSubframeWindow(JSContext* cx,
JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp,
bool& found) const {
nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id);
if (!frame) {
Nullable<WindowProxyHolder> frame = GetSubframeWindow(cx, proxy, id);
if (frame.IsNull()) {
found = false;
return true;
}
found = true;
// Just return the window's global
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);
return WrapObject(cx, frame.Value(), vp);
}
already_AddRefed<nsPIDOMWindowOuter> nsOuterWindowProxy::GetSubframeWindow(
Nullable<WindowProxyHolder> nsOuterWindowProxy::GetSubframeWindow(
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const {
uint32_t index = GetArrayIndexFromId(id);
if (!IsArrayIndex(index)) {
@ -1300,7 +1289,6 @@ void nsGlobalWindowOuter::CleanUp() {
StartDying();
mFrames = nullptr;
mWindowUtils = nullptr;
ClearControllers();
@ -2380,10 +2368,6 @@ void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
mTopLevelOuterContentWindow =
!mIsChrome && GetScriptableTopInternal() == this;
if (mFrames) {
mFrames->SetDocShell(aDocShell);
}
// Get our enclosing chrome shell and retrieve its global window impl, so
// that we can do some forwarding to the chrome document.
RefPtr<EventTarget> chromeEventHandler;
@ -2475,10 +2459,6 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
mDocShell = nullptr;
mBrowsingContext->ClearDocShell();
if (mFrames) {
mFrames->SetDocShell(nullptr);
}
MaybeForgiveSpamCount();
CleanUp();
}
@ -3196,20 +3176,16 @@ bool nsGlobalWindowOuter::GetClosedOuter() {
bool nsGlobalWindowOuter::Closed() { return GetClosedOuter(); }
nsDOMWindowList* nsGlobalWindowOuter::GetFrames() {
if (!mFrames && mDocShell) {
mFrames = new nsDOMWindowList(mDocShell);
}
return mFrames;
}
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::IndexedGetterOuter(
Nullable<WindowProxyHolder> nsGlobalWindowOuter::IndexedGetterOuter(
uint32_t aIndex) {
nsDOMWindowList* windows = GetFrames();
NS_ENSURE_TRUE(windows, nullptr);
BrowsingContext* bc = GetBrowsingContext();
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) {
@ -3962,9 +3938,8 @@ double nsGlobalWindowOuter::GetScrollXOuter() { return GetScrollXY(false).x; }
double nsGlobalWindowOuter::GetScrollYOuter() { return GetScrollXY(false).y; }
uint32_t nsGlobalWindowOuter::Length() {
nsDOMWindowList* windows = GetFrames();
return windows ? windows->GetLength() : 0;
BrowsingContext* bc = GetBrowsingContext();
return bc ? bc->GetChildren().Length() : 0;
}
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() {

View file

@ -74,7 +74,6 @@ class nsIWebBrowserChrome;
class mozIDOMWindowProxy;
class nsDocShellLoadState;
class nsDOMWindowList;
class nsScreen;
class nsHistory;
class nsGlobalWindowObserver;
@ -354,7 +353,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// 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;
// 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;
void BlurOuter();
mozilla::dom::BrowsingContext* GetFramesOuter();
nsDOMWindowList* GetFrames() final;
uint32_t Length();
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
@ -918,8 +917,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
virtual bool ShouldShowFocusRing() override;
virtual void SetKeyboardIndicators(UIStateChangeType aShowFocusRings)
override;
virtual void SetKeyboardIndicators(
UIStateChangeType aShowFocusRings) override;
public:
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
@ -1099,7 +1098,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// For |window.arguments|, via |openDialog|.
nsCOMPtr<nsIArray> mArguments;
RefPtr<nsDOMWindowList> mFrames;
RefPtr<nsDOMWindowUtils> mWindowUtils;
nsString mStatus;

View file

@ -25,7 +25,6 @@
#define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
class nsDOMOfflineResourceList;
class nsDOMWindowList;
class nsGlobalWindowInner;
class nsGlobalWindowOuter;
class nsIArray;
@ -546,8 +545,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
virtual nsDOMWindowList* GetFrames() = 0;
virtual nsresult GetInnerWidth(int32_t* aWidth) = 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<nsPIDOMWindowOuter> GetOpener() = 0;
virtual nsDOMWindowList* GetFrames() = 0;
// aLoadState will be passed on through to the windowwatcher.
// aForceNoOpener will act just like a "noopener" feature in aOptions except
// 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.
* Currently it is used for marking ranges that are created when splitting up
* a range to exclude a -moz-user-select:none region.
* @see Selection::AddItem
* @see Selection::AddRangesForSelectableNodes
* @see ExcludeNonSelectableNodes
*/
void SetIsGenerated(bool aIsGenerated) { mIsGenerated = aIsGenerated; }

View file

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

View file

@ -10,6 +10,8 @@
<label value="CPOWs"/>
<script type="application/javascript"><![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var test_state = "remote";
var test_node = null;
var reentered = false;
@ -400,7 +402,7 @@
let failed = false;
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 {
msg.objects.f();
} catch (e) {
@ -416,7 +418,7 @@
function recvSafe(msg) {
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 {
msg.objects.f();
} 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 **/
var file = createFileWithData("Test bug 914381");
SpecialPowers.pushPrefEnv({ set: [ "dom.file.createInChild" ]})
SpecialPowers.pushPrefEnv({ set: [["dom.file.createInChild", true]]})
.then(() => {
return File.createFromNsIFile(file);
})

View file

@ -13,12 +13,14 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish();
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(() => {
SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
Services.prefs.clearUserPref(PREF_UNSAFE_FORBIDDEN);
});
function done() {

View file

@ -23,7 +23,8 @@
<script class="testbody" type="application/javascript">
<![CDATA[
var SpecialPowers = window.opener.wrappedJSObject.SpecialPowers;
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
SimpleTest.waitForFocus(runTests, window);
@ -1480,7 +1481,7 @@ function runReleaseTests()
// Release the TIP
TIP = null;
// Needs to run GC forcibly for testing this.
SpecialPowers.gc();
Cu.forceGC();
is(input.value, "",
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 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()
reset();
@ -2004,7 +2005,7 @@ function runCompositionWithKeyEventTests()
is(input.value, "FOobarbuzzboo!",
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
reset();
@ -2108,7 +2109,7 @@ function runCompositionWithKeyEventTests()
is(events[1].type, "compositionend",
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("compositionupdate", handler, false);
@ -2155,7 +2156,7 @@ function runConsumingKeydownBeforeCompositionTests()
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 });
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.
reset();
@ -2205,7 +2206,7 @@ function runConsumingKeydownBeforeCompositionTests()
is(input.value, "",
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.
TIP.startComposition();
@ -2273,7 +2274,7 @@ function runConsumingKeydownBeforeCompositionTests()
is(input.value, "",
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("compositionupdate", handler, false);
@ -2594,7 +2595,7 @@ function runKeyTests()
// key events during composition
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");
@ -2608,7 +2609,7 @@ function runKeyTests()
is(events.length, 0,
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();
TIP.keydown(keyA);
is(events.length, 1,
@ -2624,7 +2625,7 @@ function runKeyTests()
} finally {
TIP.cancelComposition();
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
}
// Test .location computation

View file

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

View file

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

View file

@ -37,12 +37,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
function doTest() {
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 ourFile = location.href;
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([

View file

@ -16,7 +16,7 @@
</div>
<pre id="test">
<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 regionId = "";

View file

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

View file

@ -23,6 +23,7 @@ let seenClick = false;
SpecialPowers.pushPrefEnv(
{ set: [[HACK_PREF, document.domain]] },
() => {
SimpleTest.waitForFocus(() => {
// Test seeing the non-primary 'click'
document.addEventListener("click", (e) => {
@ -45,8 +46,8 @@ SpecialPowers.pushPrefEnv(
ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'");
}, { once: true });
synthesizeMouseAtCenter(linkEl, { button: 1 });
})
);
});
});
</script>
</body>
</html>

View file

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

View file

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

View file

@ -12,12 +12,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=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() {
await SpecialPowers.pushPrefEnv({"set": [["browser.enable_automatic_image_resizing", true]]});
return new Promise(resolve => {
var testWin = document.querySelector("iframe");
testWin.height = 0;
testWin.width = 0;
testWin.src = "image.png";
testWin.onload = function() {
var testDoc = testWin.contentDocument;
@ -36,8 +37,9 @@ SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", tr
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area");
SimpleTest.finish();
resolve();
};
})
});
</script>
@ -45,6 +47,6 @@ SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", tr
<body>
<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>
</html>

View file

@ -888,6 +888,14 @@ nsresult ContentChild::ProvideWindowCommon(
// load in the current process.
bool loadInDifferentProcess = aForceNoOpener && sNoopenerNewProcess;
if (aTabOpener && !loadInDifferentProcess && aURI) {
nsCOMPtr<nsILoadContext> context;
if (aParent) {
context = do_GetInterface(aTabOpener->WebNavigation());
}
// Only special-case cross-process loads if Fission is disabled. With
// 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) {
@ -896,6 +904,7 @@ nsresult ContentChild::ProvideWindowCommon(
loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
}
}
}
// If we're in a content process and we have noopener set, there's no reason
// to load in our process, so let's load it elsewhere!

View file

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

View file

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

View file

@ -17,6 +17,10 @@
namespace mozilla {
namespace dom {
JSWindowActorChild::JSWindowActorChild(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal ? aGlobal
: xpc::NativeGlobal(xpc::PrivilegedJunkScope())) {}
JSWindowActorChild::~JSWindowActorChild() { MOZ_ASSERT(!mManager); }
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,
JSWindowActor)
explicit JSWindowActorChild(nsIGlobalObject* aGlobal = nullptr);
nsIGlobalObject* GetParentObject() const override { return mGlobal; }
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<JSWindowActorChild> Constructor(GlobalObject& aGlobal,
ErrorResult& aRv) {
return MakeAndAddRef<JSWindowActorChild>();
nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(aGlobal.GetAsSupports()));
return MakeAndAddRef<JSWindowActorChild>(global);
}
WindowGlobalChild* GetManager() const;
@ -64,6 +69,8 @@ class JSWindowActorChild final : public JSWindowActor {
bool mCanSend = true;
RefPtr<WindowGlobalChild> mManager;
nsCOMPtr<nsIGlobalObject> mGlobal;
};
} // namespace dom

View file

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

View file

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

View file

@ -60,7 +60,7 @@ var tests = [
{
keySystem: "com.widevine.alpha",
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,

View file

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

View file

@ -8,12 +8,12 @@ var NotificationTest = (function() {
function setup_testing_env() {
SimpleTest.waitForExplicitFinish();
// 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() {
SpecialPowers.clearUserPref("notification.prompt.testing");
SpecialPowers.clearUserPref("notification.prompt.testing.allow");
async function teardown_testing_env() {
await SpecialPowers.clearUserPref("notification.prompt.testing");
await SpecialPowers.clearUserPref("notification.prompt.testing.allow");
SimpleTest.finish();
}
@ -78,9 +78,10 @@ var NotificationTest = (function() {
// NotificationTest API
return {
run(tests, callback) {
setup_testing_env();
let ready = setup_testing_env();
addLoadEvent(function() {
addLoadEvent(async function() {
await ready;
executeTests(tests, function() {
teardown_testing_env();
callback && callback();
@ -89,11 +90,11 @@ var NotificationTest = (function() {
},
allowNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
return SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
},
denyNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
return SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
},
clickNotification(notification) {

View file

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

View file

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

View file

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

View file

@ -108,7 +108,11 @@ function waitScrollFinish(aTarget) {
*/
function setTestPluginEnabledState(aState, aPluginName) {
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(() => {
return plugin.enabledState == newEnabledState;
});
SimpleTest.registerCleanupFunction(function() {
SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName);
SimpleTest.registerCleanupFunction(async function() {
return SpecialPowers.setTestPluginEnabledState(await oldEnabledState, pluginName);
});
}

View file

@ -10,11 +10,6 @@
"use strict";
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) {
for (var i = 0; i < navigator.plugins.length; i++) {
@ -45,7 +40,13 @@
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("disallowedPlugin", "application/x-third-test");
var pluginElement = document.getElementById("plugin-flash");
@ -70,6 +71,6 @@
}
</script>
<body onload="addPerms()">
<body onload="run()">
</body>
</html>

View file

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

View file

@ -40,14 +40,14 @@ function testSetup() {
function testInitialUnavailable() {
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");
aAvailability.onchange = function() {
aAvailability.onchange = null;
ok(aAvailability.value, "Device should be available.");
};
availability = aAvailability;
gScript.sendAsyncMessage("trigger-device-add", testDevice);
await gScript.sendQuery("trigger-device-add", testDevice);
}).catch(function(aError) {
ok(false, "Error occurred when getting availability: " + aError);
teardown();

View file

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

View file

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

View file

@ -64,8 +64,7 @@
return Promise.all(unregisterArray);
}
function testScopes() {
return new Promise(function(resolve, reject) {
async function testScopes() {
function chromeScriptSource() {
let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
.getService(Ci.nsIServiceWorkerManager);
@ -89,8 +88,8 @@
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];
getScope = async (path) => {
let rv = await chromeScript.sendQuery("getScope", { principal: docPrincipal, path });
if (rv.exception)
throw rv.exception;
return rv.scope;
@ -105,27 +104,25 @@
return base + s;
}
function fail(fn) {
async function fail(fn) {
try {
getScope(p("index.html"));
await getScope(p("index.html"));
ok(false, "No registration");
} catch(e) {
ok(true, "No registration");
}
}
is(getScope(p("sub.html")), p("sub"), "Scope should match");
is(getScope(p("sub/dir.html")), p("sub/dir.html"), "Scope should match");
is(getScope(p("sub/dir")), p("sub/dir"), "Scope should match");
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");
is(getScope(p("star*wars")), p("star*"), "Scope should match");
is(getScope(p("scope/some_file.html")), p("scope/"), "Scope should match");
fail("index.html");
fail("sua.html");
fail("star/a.html");
resolve();
});
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() {

View file

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

View file

@ -8,7 +8,7 @@
<iframe src="about:blank"></iframe>
<script type="text/javascript">
function checkForFindDialog() {
async function checkForFindDialog() {
let chromeScript = SpecialPowers.loadChromeScript(_ => {
addMessageListener("test:check", () => {
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();
return sawFind;
}
@ -67,7 +67,7 @@
"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
let sawWindow = checkForFindDialog();
let sawWindow = await checkForFindDialog();
ok(!sawWindow, "Should never have seen the dialog.");
});
}

View file

@ -11,7 +11,9 @@
var SimpleTest = opener.wrappedJSObject.SimpleTest;
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,
"Should be instance of HTMLBodyElement");
ok(doc.createElement("div") instanceof HTMLDivElement,

View file

@ -34,7 +34,7 @@ window.onload = function() {
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 iframe2 = document.createElement("iframe");
var iframe3 = document.createElement("iframe");

View file

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

View file

@ -43,8 +43,8 @@ function pressButton() {
GamepadService.newButtonEvent(gamepad_index, 0, false, false);
}
function startTest() {
SpecialPowers.pushPrefEnv({ "set": [
async function startTest() {
await SpecialPowers.pushPrefEnv({ "set": [
["dom.gamepad.extensions.enabled", true],
["dom.gamepad.extensions.lightindicator", true],
["dom.gamepad.extensions.multitouch", true]] });

View file

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

View file

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

View file

@ -17,7 +17,7 @@ async function setup() {
winUtils.advanceTimeAndRefresh(100);
}
function* runTests() {
async function* runTests() {
var e = document.getElementById("edit");
var doc = e.contentDocument;
var win = e.contentWindow;
@ -181,9 +181,9 @@ function* runTests() {
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);
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);
}
@ -196,7 +196,7 @@ async function testRunner() {
let curTest = runTests();
while (true) {
winUtils.advanceTimeAndRefresh(100);
if (curTest.next().done) {
if ((await curTest.next()).done) {
break;
}
winUtils.advanceTimeAndRefresh(100);

View file

@ -50,7 +50,7 @@ var tests = [
var loadCount = 0;
var script;
var loadListener = function(evt) {
var loadListener = async function(evt) {
if (loadCount == 0) {
/* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() {
@ -86,7 +86,7 @@ var loadListener = function(evt) {
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[1], true, "true expected (en-AU 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";
} else {
// Remove the fake dictionaries again, since it's otherwise picked up by later tests.
script.sendSyncMessage("destroy");
script.sendAsyncMessage("destroy");
SimpleTest.finish();
}

View file

@ -29,7 +29,7 @@ var content = document.getElementById("content");
var firstLoad = true;
var script;
var loadListener = function(evt) {
var loadListener = async function(evt) {
if (firstLoad) {
/* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() {
@ -53,7 +53,7 @@ var loadListener = function(evt) {
addMessageListener("en_GB-exists", () => en_GB.exists());
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)");
}
@ -97,7 +97,7 @@ var loadListener = function(evt) {
content.removeEventListener("load", loadListener);
// 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.
SimpleTest.finish();

View file

@ -34,7 +34,7 @@ var onSpellCheck =
/** Test for Bug 1205983 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
SimpleTest.waitForFocus(async function() {
/* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() {
// eslint-disable-next-line mozilla/use-services
@ -57,7 +57,7 @@ SimpleTest.waitForFocus(function() {
addMessageListener("de_DE-exists", () => de_DE.exists());
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)");
document.getElementById("de-DE").focus();
@ -106,7 +106,7 @@ function enFocus() {
is(sel.toString(), "German", "one misspelled word expected: German");
// 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.
elem_de.onfocus = null;

View file

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

View file

@ -28,7 +28,7 @@ var content = document.getElementById("content");
var firstLoad = true;
var script;
var loadListener = function(evt) {
var loadListener = async function(evt) {
if (firstLoad) {
/* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() {
@ -52,7 +52,7 @@ var loadListener = function(evt) {
addMessageListener("en_GB-exists", () => en_GB.exists());
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)");
}
@ -89,7 +89,7 @@ var loadListener = function(evt) {
content.removeEventListener("load", loadListener);
// 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".
spellchecker.SetCurrentDictionary("");

View file

@ -34,7 +34,7 @@ var onSpellCheck =
/** Test for Bug 697981 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
SimpleTest.waitForFocus(async function() {
/* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() {
// eslint-disable-next-line mozilla/use-services
@ -57,7 +57,7 @@ SimpleTest.waitForFocus(function() {
addMessageListener("de_DE-exists", () => de_DE.exists());
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)");
document.getElementById("de-DE").focus();
@ -107,7 +107,7 @@ function enFocus() {
is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
// 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.
elem_de.onfocus = null;

View file

@ -29,7 +29,7 @@ var firstLoad = true;
var expected = "";
var script;
var loadListener = function(evt) {
var loadListener = async function(evt) {
if (firstLoad) {
/* eslint-env mozilla/frame-script */
script = SpecialPowers.loadChromeScript(function() {
@ -53,7 +53,7 @@ var loadListener = function(evt) {
addMessageListener("en_GB-exists", () => en_GB.exists());
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)");
}
@ -90,7 +90,7 @@ var loadListener = function(evt) {
content.removeEventListener("load", loadListener);
// 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".
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
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
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
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
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
at separate times resulting in visual glitches.
at separate times, resulting in visual glitches.
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.
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
<https://searchfox.org/mozilla-central/rev/06bd14ced96f25ff1dbd5352cb985fc0fa12a64e/gfx/layers/ipc/APZCTreeManagerParent.cpp#76>`_
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
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,
the WebRenderBridgeParent instances that corresponded to content processes
(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
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.
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
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
@ -310,7 +310,7 @@ scenario, other documents may still be backlogged, so the unthrottling is
undesirable.
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
as this completion message - stuff that should happen after all the WR documents
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.
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
"buried" away in place where one might not easily stumble upon it. It's also not
because it seems like a fairly important piece but the relevant code is
"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
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

View file

@ -422,7 +422,7 @@ async function waitUntilApzStable() {
if (typeof waitUntilApzStable.chromeHelper == "undefined") {
waitUntilApzStable.chromeHelper = SpecialPowers.loadChromeScript(parentProcessFlush);
ApzCleanup.register(() => {
waitUntilApzStable.chromeHelper.sendSyncMessage("cleanup", null);
waitUntilApzStable.chromeHelper.sendAsyncMessage("cleanup", null);
waitUntilApzStable.chromeHelper.destroy();
delete waitUntilApzStable.chromeHelper;
});
@ -580,7 +580,7 @@ function getSnapshot(rect) {
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

View file

@ -33,8 +33,12 @@ function listener(callback) {
/* eslint-env mozilla/frame-script */
function chromeTouchEventCounter(operation) {
function chromeProcessCounter() {
addMessageListener("start", function() {
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const PREFIX = "apz:ctec:";
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");
@ -50,16 +54,18 @@ function chromeTouchEventCounter(operation) {
topWin.addEventListener("touchend", topWin.counter, { passive: true });
return true;
});
},
addMessageListener("report", function() {
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
"report": function() {
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
return JSON.stringify(topWin.eventCounts);
});
},
"end": function() {
for (let [msg, func] of Object.entries(LISTENERS)) {
Services.ppmm.removeMessageListener(PREFIX + msg, func);
}
addMessageListener("end", function() {
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
if (typeof topWin.eventCounts == "undefined") {
dump("The eventCounts object was not found on the top window!\n");
@ -71,7 +77,12 @@ function chromeTouchEventCounter(operation) {
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") {
@ -80,7 +91,7 @@ function chromeTouchEventCounter(operation) {
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

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)
// 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))
#else
#define MAYBE_NOINLINE

View file

@ -6,3 +6,4 @@ subsuite = gpu
[test_bug509244.html]
[test_bug513439.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 **/
SimpleTest.requestFlakyTimeout("This test is flaky.");
const InspectorUtils = SpecialPowers.InspectorUtils;
// 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",
whitelist.join(", ")]]});
await new Promise(resolve => setTimeout(resolve, 2000));
// If whitelist is empty, then whitelisting is considered disabled
// and all fonts are allowed.
info("font whitelist: " + JSON.stringify(whitelist));

View file

@ -13,9 +13,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1124898
/** Test for Bug 1124898 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
(async () => {
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');
@ -34,6 +36,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1124898
w.close();
SimpleTest.finish();
}
})();
</script>
</head>

View file

@ -14,14 +14,17 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
SimpleTest.waitForExplicitFinish();
function init() {
var f = new Function("let test = 'let is ok'; return test;");
is(f(), 'let is ok', 'let should be ok');
SimpleTest.finish();
}
(async () => {
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
Test = {
include: function(p) {
var sawError = false;
@ -42,8 +45,7 @@
// If init is called directly, it works.
setTimeout('init();', 0);
SimpleTest.waitForExplicitFinish();
})();
]]></script>
</window>

View file

@ -18,7 +18,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
<script type="application/javascript">
<![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
add_task(async () => {
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
//
// Important! If this test starts failing after a tricky platform-y change,
@ -76,7 +77,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
contentSb.nnslChrome = chromeSb.nearNativeStackLimit;
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);
});
]]>
</script>
</window>

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