forked from mirrors/gecko-dev
Merge mozilla-central to autoland. a=merge on a CLOSED TREE
This commit is contained in:
commit
960e4c47d4
206 changed files with 4454 additions and 3727 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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", {});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
62
docshell/test/unit/test_browsing_context_structured_clone.js
Normal file
62
docshell/test/unit/test_browsing_context_structured_clone.js
Normal 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");
|
||||
});
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ==
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,7 +336,6 @@ UNIFIED_SOURCES += [
|
|||
'nsDOMNavigationTiming.cpp',
|
||||
'nsDOMSerializer.cpp',
|
||||
'nsDOMTokenList.cpp',
|
||||
'nsDOMWindowList.cpp',
|
||||
'nsFocusManager.cpp',
|
||||
'nsFrameLoader.cpp',
|
||||
'nsFrameLoaderOwner.cpp',
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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___
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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([
|
||||
|
|
|
|||
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ function startTest(test, token) {
|
|||
createMedia(test.type, test.name, token);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
createTestArray().then(testArray => {
|
||||
manager.runTests(testArray, startTest);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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]] });
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ function runTest() {
|
|||
prompt("summary", "text");
|
||||
info("prompt is closed");
|
||||
|
||||
script.sendSyncMessage("destroy");
|
||||
script.sendAsyncMessage("destroy");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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("");
|
||||
|
|
|
|||
|
|
@ -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("");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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("");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue