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) {
|
function pushPrefs(...aPrefs) {
|
||||||
return new Promise(resolve => {
|
return SpecialPowers.pushPrefEnv({"set": aPrefs});
|
||||||
SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function popPrefs() {
|
function popPrefs() {
|
||||||
return new Promise(resolve => {
|
return SpecialPowers.popPrefEnv();
|
||||||
SpecialPowers.popPrefEnv(resolve);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateBlocklist(aCallback) {
|
function updateBlocklist(aCallback) {
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,9 @@ const kDumpAllStacks = false;
|
||||||
const whitelist = {
|
const whitelist = {
|
||||||
modules: new Set([
|
modules: new Set([
|
||||||
"chrome://mochikit/content/ShutdownLeaksCollector.jsm",
|
"chrome://mochikit/content/ShutdownLeaksCollector.jsm",
|
||||||
"resource://specialpowers/specialpowers.js",
|
"resource://specialpowers/SpecialPowersChild.jsm",
|
||||||
"resource://specialpowers/specialpowersAPI.js",
|
"resource://specialpowers/SpecialPowersAPI.jsm",
|
||||||
|
"resource://specialpowers/WrapPrivileged.jsm",
|
||||||
|
|
||||||
"resource://gre/modules/ContentProcessSingleton.jsm",
|
"resource://gre/modules/ContentProcessSingleton.jsm",
|
||||||
|
|
||||||
|
|
@ -64,8 +65,6 @@ const whitelist = {
|
||||||
]),
|
]),
|
||||||
frameScripts: new Set([
|
frameScripts: new Set([
|
||||||
// Test related
|
// Test related
|
||||||
"resource://specialpowers/MozillaLogger.js",
|
|
||||||
"resource://specialpowers/specialpowersFrameScript.js",
|
|
||||||
"chrome://mochikit/content/shutdown-leaks-collector.js",
|
"chrome://mochikit/content/shutdown-leaks-collector.js",
|
||||||
"chrome://mochikit/content/tests/SimpleTest/AsyncUtilsContent.js",
|
"chrome://mochikit/content/tests/SimpleTest/AsyncUtilsContent.js",
|
||||||
"chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js",
|
"chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js",
|
||||||
|
|
|
||||||
|
|
@ -129,9 +129,9 @@
|
||||||
const permission = "geolocation";
|
const permission = "geolocation";
|
||||||
const promiseGranted = this.promiseStateChanged(permission, "granted");
|
const promiseGranted = this.promiseStateChanged(permission, "granted");
|
||||||
this.setPermissions(ALLOW_ACTION);
|
this.setPermissions(ALLOW_ACTION);
|
||||||
promiseGranted.then(() => {
|
promiseGranted.then(async () => {
|
||||||
const promisePrompt = this.promiseStateChanged(permission, "prompt");
|
const promisePrompt = this.promiseStateChanged(permission, "prompt");
|
||||||
SpecialPowers.popPermissions();
|
await SpecialPowers.popPermissions();
|
||||||
return promisePrompt;
|
return promisePrompt;
|
||||||
}).then(resolve);
|
}).then(resolve);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -174,54 +174,47 @@ function checkMenuEntries(expectedValues, isFormAutofillResult = true) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function invokeAsyncChromeTask(message, response, payload = {}) {
|
function invokeAsyncChromeTask(message, payload = {}) {
|
||||||
info(`expecting the chrome task finished: ${message}`);
|
info(`expecting the chrome task finished: ${message}`);
|
||||||
return new Promise(resolve => {
|
return formFillChromeScript.sendQuery(message, payload);
|
||||||
formFillChromeScript.sendAsyncMessage(message, payload);
|
|
||||||
formFillChromeScript.addMessageListener(response, function onReceived(data) {
|
|
||||||
formFillChromeScript.removeMessageListener(response, onReceived);
|
|
||||||
|
|
||||||
resolve(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addAddress(address) {
|
async function addAddress(address) {
|
||||||
await invokeAsyncChromeTask("FormAutofillTest:AddAddress", "FormAutofillTest:AddressAdded", {address});
|
await invokeAsyncChromeTask("FormAutofillTest:AddAddress", {address});
|
||||||
await sleep();
|
await sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeAddress(guid) {
|
async function removeAddress(guid) {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:RemoveAddress", "FormAutofillTest:AddressRemoved", {guid});
|
return invokeAsyncChromeTask("FormAutofillTest:RemoveAddress", {guid});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateAddress(guid, address) {
|
async function updateAddress(guid, address) {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:UpdateAddress", "FormAutofillTest:AddressUpdated", {address, guid});
|
return invokeAsyncChromeTask("FormAutofillTest:UpdateAddress", {address, guid});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkAddresses(expectedAddresses) {
|
async function checkAddresses(expectedAddresses) {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:CheckAddresses", "FormAutofillTest:areAddressesMatching", {expectedAddresses});
|
return invokeAsyncChromeTask("FormAutofillTest:CheckAddresses", {expectedAddresses});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cleanUpAddresses() {
|
async function cleanUpAddresses() {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:CleanUpAddresses", "FormAutofillTest:AddressesCleanedUp");
|
return invokeAsyncChromeTask("FormAutofillTest:CleanUpAddresses");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addCreditCard(creditcard) {
|
async function addCreditCard(creditcard) {
|
||||||
await invokeAsyncChromeTask("FormAutofillTest:AddCreditCard", "FormAutofillTest:CreditCardAdded", {creditcard});
|
await invokeAsyncChromeTask("FormAutofillTest:AddCreditCard", {creditcard});
|
||||||
await sleep();
|
await sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeCreditCard(guid) {
|
async function removeCreditCard(guid) {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:RemoveCreditCard", "FormAutofillTest:CreditCardRemoved", {guid});
|
return invokeAsyncChromeTask("FormAutofillTest:RemoveCreditCard", {guid});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkCreditCards(expectedCreditCards) {
|
async function checkCreditCards(expectedCreditCards) {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:CheckCreditCards", "FormAutofillTest:areCreditCardsMatching", {expectedCreditCards});
|
return invokeAsyncChromeTask("FormAutofillTest:CheckCreditCards", {expectedCreditCards});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cleanUpCreditCards() {
|
async function cleanUpCreditCards() {
|
||||||
return invokeAsyncChromeTask("FormAutofillTest:CleanUpCreditCards", "FormAutofillTest:CreditCardsCleanedUp");
|
return invokeAsyncChromeTask("FormAutofillTest:CleanUpCreditCards");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cleanUpStorage() {
|
async function cleanUpStorage() {
|
||||||
|
|
@ -230,12 +223,12 @@ async function cleanUpStorage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function canTestOSKeyStoreLogin() {
|
async function canTestOSKeyStoreLogin() {
|
||||||
let {canTest} = await invokeAsyncChromeTask("FormAutofillTest:CanTestOSKeyStoreLogin", "FormAutofillTest:CanTestOSKeyStoreLoginResult");
|
let {canTest} = await invokeAsyncChromeTask("FormAutofillTest:CanTestOSKeyStoreLogin");
|
||||||
return canTest;
|
return canTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function waitForOSKeyStoreLogin(login = false) {
|
async function waitForOSKeyStoreLogin(login = false) {
|
||||||
await invokeAsyncChromeTask("FormAutofillTest:OSKeyStoreLogin", "FormAutofillTest:OSKeyStoreLoggedIn", {login});
|
await invokeAsyncChromeTask("FormAutofillTest:OSKeyStoreLogin", {login});
|
||||||
}
|
}
|
||||||
|
|
||||||
function patchRecordCCNumber(record) {
|
function patchRecordCCNumber(record) {
|
||||||
|
|
@ -302,15 +295,13 @@ function formAutoFillCommonSetup() {
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function setup() {
|
add_task(async function setup() {
|
||||||
formFillChromeScript.sendAsyncMessage("setup");
|
|
||||||
info(`expecting the storage setup`);
|
info(`expecting the storage setup`);
|
||||||
await formFillChromeScript.promiseOneMessage("setup-finished");
|
await formFillChromeScript.sendQuery("setup");
|
||||||
});
|
});
|
||||||
|
|
||||||
SimpleTest.registerCleanupFunction(async () => {
|
SimpleTest.registerCleanupFunction(async () => {
|
||||||
formFillChromeScript.sendAsyncMessage("cleanup");
|
|
||||||
info(`expecting the storage cleanup`);
|
info(`expecting the storage cleanup`);
|
||||||
await formFillChromeScript.promiseOneMessage("cleanup-finished");
|
await formFillChromeScript.sendQuery("cleanup");
|
||||||
|
|
||||||
formFillChromeScript.destroy();
|
formFillChromeScript.destroy();
|
||||||
expectingPopup = null;
|
expectingPopup = null;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ let {formAutofillStorage} = ChromeUtils.import("resource://formautofill/FormAuto
|
||||||
|
|
||||||
const {ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME} = FormAutofillUtils;
|
const {ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME} = FormAutofillUtils;
|
||||||
|
|
||||||
|
let destroyed = false;
|
||||||
|
|
||||||
var ParentUtils = {
|
var ParentUtils = {
|
||||||
async _getRecords(collectionName) {
|
async _getRecords(collectionName) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
@ -34,12 +36,16 @@ var ParentUtils = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// every notification type should have the collection name.
|
// every notification type should have the collection name.
|
||||||
let allowedNames = [ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME];
|
// We're not allowed to trigger assertions during mochitest
|
||||||
assert.ok(allowedNames.includes(subject.wrappedJSObject.collectionName),
|
// cleanup functions.
|
||||||
"should include the collection name");
|
if (!destroyed) {
|
||||||
// every notification except removeAll should have a guid.
|
let allowedNames = [ADDRESSES_COLLECTION_NAME, CREDITCARDS_COLLECTION_NAME];
|
||||||
if (data != "removeAll") {
|
assert.ok(allowedNames.includes(subject.wrappedJSObject.collectionName),
|
||||||
assert.ok(subject.wrappedJSObject.guid, "should have a guid");
|
"should include the collection name");
|
||||||
|
// every notification except removeAll should have a guid.
|
||||||
|
if (data != "removeAll") {
|
||||||
|
assert.ok(subject.wrappedJSObject.guid, "should have a guid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Services.obs.removeObserver(observer, obsTopic);
|
Services.obs.removeObserver(observer, obsTopic);
|
||||||
resolve();
|
resolve();
|
||||||
|
|
@ -47,7 +53,7 @@ var ParentUtils = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async _operateRecord(collectionName, type, msgData, contentMsg) {
|
async _operateRecord(collectionName, type, msgData) {
|
||||||
let times, topic;
|
let times, topic;
|
||||||
|
|
||||||
if (collectionName == ADDRESSES_COLLECTION_NAME) {
|
if (collectionName == ADDRESSES_COLLECTION_NAME) {
|
||||||
|
|
@ -83,14 +89,13 @@ var ParentUtils = {
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._storageChangeObserved({type, times, topic});
|
await this._storageChangeObserved({type, times, topic});
|
||||||
sendAsyncMessage(contentMsg);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async operateAddress(type, msgData, contentMsg) {
|
async operateAddress(type, msgData) {
|
||||||
await this._operateRecord(ADDRESSES_COLLECTION_NAME, ...arguments);
|
await this._operateRecord(ADDRESSES_COLLECTION_NAME, ...arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
async operateCreditCard(type, msgData, contentMsg) {
|
async operateCreditCard(type, msgData) {
|
||||||
await this._operateRecord(CREDITCARDS_COLLECTION_NAME, ...arguments);
|
await this._operateRecord(CREDITCARDS_COLLECTION_NAME, ...arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -98,7 +103,6 @@ var ParentUtils = {
|
||||||
const guids = (await this._getRecords(ADDRESSES_COLLECTION_NAME)).map(record => record.guid);
|
const guids = (await this._getRecords(ADDRESSES_COLLECTION_NAME)).map(record => record.guid);
|
||||||
|
|
||||||
if (guids.length == 0) {
|
if (guids.length == 0) {
|
||||||
sendAsyncMessage("FormAutofillTest:AddressesCleanedUp");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +116,6 @@ var ParentUtils = {
|
||||||
const guids = (await this._getRecords(CREDITCARDS_COLLECTION_NAME)).map(record => record.guid);
|
const guids = (await this._getRecords(CREDITCARDS_COLLECTION_NAME)).map(record => record.guid);
|
||||||
|
|
||||||
if (guids.length == 0) {
|
if (guids.length == 0) {
|
||||||
sendAsyncMessage("FormAutofillTest:CreditCardsCleanedUp");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,19 +170,17 @@ var ParentUtils = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async checkAddresses({expectedAddresses}) {
|
async checkAddresses({expectedAddresses}) {
|
||||||
const areMatched = await this._checkRecords(ADDRESSES_COLLECTION_NAME, expectedAddresses);
|
return this._checkRecords(ADDRESSES_COLLECTION_NAME, expectedAddresses);
|
||||||
|
|
||||||
sendAsyncMessage("FormAutofillTest:areAddressesMatching", areMatched);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async checkCreditCards({expectedCreditCards}) {
|
async checkCreditCards({expectedCreditCards}) {
|
||||||
const areMatched = await this._checkRecords(CREDITCARDS_COLLECTION_NAME, expectedCreditCards);
|
return this._checkRecords(CREDITCARDS_COLLECTION_NAME, expectedCreditCards);
|
||||||
|
|
||||||
sendAsyncMessage("FormAutofillTest:areCreditCardsMatching", areMatched);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
observe(subject, topic, data) {
|
observe(subject, topic, data) {
|
||||||
assert.ok(topic === "formautofill-storage-changed");
|
if (!destroyed) {
|
||||||
|
assert.ok(topic === "formautofill-storage-changed");
|
||||||
|
}
|
||||||
sendAsyncMessage("formautofill-storage-changed", {subject: null, topic, data});
|
sendAsyncMessage("formautofill-storage-changed", {subject: null, topic, data});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -187,62 +188,58 @@ var ParentUtils = {
|
||||||
Services.obs.addObserver(ParentUtils, "formautofill-storage-changed");
|
Services.obs.addObserver(ParentUtils, "formautofill-storage-changed");
|
||||||
|
|
||||||
Services.mm.addMessageListener("FormAutofill:FieldsIdentified", () => {
|
Services.mm.addMessageListener("FormAutofill:FieldsIdentified", () => {
|
||||||
sendAsyncMessage("FormAutofillTest:FieldsIdentified");
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:AddAddress", (msg) => {
|
addMessageListener("FormAutofillTest:AddAddress", (msg) => {
|
||||||
ParentUtils.operateAddress("add", msg, "FormAutofillTest:AddressAdded");
|
return ParentUtils.operateAddress("add", msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:RemoveAddress", (msg) => {
|
addMessageListener("FormAutofillTest:RemoveAddress", (msg) => {
|
||||||
ParentUtils.operateAddress("remove", msg, "FormAutofillTest:AddressRemoved");
|
return ParentUtils.operateAddress("remove", msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:UpdateAddress", (msg) => {
|
addMessageListener("FormAutofillTest:UpdateAddress", (msg) => {
|
||||||
ParentUtils.operateAddress("update", msg, "FormAutofillTest:AddressUpdated");
|
return ParentUtils.operateAddress("update", msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:CheckAddresses", (msg) => {
|
addMessageListener("FormAutofillTest:CheckAddresses", (msg) => {
|
||||||
ParentUtils.checkAddresses(msg);
|
return ParentUtils.checkAddresses(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:CleanUpAddresses", (msg) => {
|
addMessageListener("FormAutofillTest:CleanUpAddresses", (msg) => {
|
||||||
ParentUtils.cleanUpAddresses();
|
return ParentUtils.cleanUpAddresses();
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:AddCreditCard", (msg) => {
|
addMessageListener("FormAutofillTest:AddCreditCard", (msg) => {
|
||||||
ParentUtils.operateCreditCard("add", msg, "FormAutofillTest:CreditCardAdded");
|
return ParentUtils.operateCreditCard("add", msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:RemoveCreditCard", (msg) => {
|
addMessageListener("FormAutofillTest:RemoveCreditCard", (msg) => {
|
||||||
ParentUtils.operateCreditCard("remove", msg, "FormAutofillTest:CreditCardRemoved");
|
return ParentUtils.operateCreditCard("remove", msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:CheckCreditCards", (msg) => {
|
addMessageListener("FormAutofillTest:CheckCreditCards", (msg) => {
|
||||||
ParentUtils.checkCreditCards(msg);
|
return ParentUtils.checkCreditCards(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:CleanUpCreditCards", (msg) => {
|
addMessageListener("FormAutofillTest:CleanUpCreditCards", (msg) => {
|
||||||
ParentUtils.cleanUpCreditCards();
|
return ParentUtils.cleanUpCreditCards();
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:CanTestOSKeyStoreLogin", (msg) => {
|
addMessageListener("FormAutofillTest:CanTestOSKeyStoreLogin", (msg) => {
|
||||||
sendAsyncMessage("FormAutofillTest:CanTestOSKeyStoreLoginResult",
|
return {canTest: OSKeyStoreTestUtils.canTestOSKeyStoreLogin()};
|
||||||
{canTest: OSKeyStoreTestUtils.canTestOSKeyStoreLogin()});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("FormAutofillTest:OSKeyStoreLogin", async (msg) => {
|
addMessageListener("FormAutofillTest:OSKeyStoreLogin", async (msg) => {
|
||||||
await OSKeyStoreTestUtils.waitForOSKeyStoreLogin(msg.login);
|
await OSKeyStoreTestUtils.waitForOSKeyStoreLogin(msg.login);
|
||||||
sendAsyncMessage("FormAutofillTest:OSKeyStoreLoggedIn");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("setup", async () => {
|
addMessageListener("setup", async () => {
|
||||||
ParentUtils.setup();
|
ParentUtils.setup();
|
||||||
sendAsyncMessage("setup-finished", {});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
addMessageListener("cleanup", async () => {
|
addMessageListener("cleanup", async () => {
|
||||||
|
destroyed = true;
|
||||||
await ParentUtils.cleanup();
|
await ParentUtils.cleanup();
|
||||||
|
|
||||||
sendAsyncMessage("cleanup-finished", {});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ add_task(async function test_DE_is_valid_testcase() {
|
||||||
chromeScript.destroy();
|
chromeScript.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
let result = chromeScript.sendSyncMessage("CheckSubKeys");
|
let result = await chromeScript.sendQuery("CheckSubKeys");
|
||||||
ok(result[0][0], "Check that there are no sub_keys for the test country");
|
ok(result, "Check that there are no sub_keys for the test country");
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_form_will_submit_without_sub_keys() {
|
add_task(async function test_form_will_submit_without_sub_keys() {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
#include "nsQueryObject.h"
|
#include "nsQueryObject.h"
|
||||||
|
|
||||||
#include "mozilla/dom/URL.h"
|
#include "mozilla/dom/URL.h"
|
||||||
#include "nsDOMWindowList.h"
|
|
||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "nsIDOMWindow.h"
|
#include "nsIDOMWindow.h"
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,7 @@ add_task(async function testActiveTabOnNonExistingSidebar() {
|
||||||
// to simulate the scenario where an extension has installed a sidebar
|
// to simulate the scenario where an extension has installed a sidebar
|
||||||
// which has been saved in the preference but it doesn't exist anymore.
|
// which has been saved in the preference but it doesn't exist anymore.
|
||||||
await SpecialPowers.pushPrefEnv({
|
await SpecialPowers.pushPrefEnv({
|
||||||
set: [["devtools.inspector.activeSidebar"], "unexisting-sidebar-id"],
|
set: [["devtools.inspector.activeSidebar", "unexisting-sidebar-id"]],
|
||||||
});
|
});
|
||||||
|
|
||||||
const res = await openInspectorForURL("about:blank");
|
const res = await openInspectorForURL("about:blank");
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const HTML_VOID_ELEMENTS = [
|
||||||
// element markup and their respective title tooltip text.
|
// element markup and their respective title tooltip text.
|
||||||
const DISPLAY_TYPES = {
|
const DISPLAY_TYPES = {
|
||||||
"flex": INSPECTOR_L10N.getStr("markupView.display.flex.tooltiptext"),
|
"flex": INSPECTOR_L10N.getStr("markupView.display.flex.tooltiptext"),
|
||||||
"inline-flex": INSPECTOR_L10N.getStr("markupView.display.flex.tooltiptext"),
|
"inline-flex": INSPECTOR_L10N.getStr("markupView.display.inlineFlex.tooltiptext"),
|
||||||
"grid": INSPECTOR_L10N.getStr("markupView.display.grid.tooltiptext"),
|
"grid": INSPECTOR_L10N.getStr("markupView.display.grid.tooltiptext"),
|
||||||
"inline-grid": INSPECTOR_L10N.getStr("markupView.display.inlineGrid.tooltiptext"),
|
"inline-grid": INSPECTOR_L10N.getStr("markupView.display.inlineGrid.tooltiptext"),
|
||||||
"subgrid": INSPECTOR_L10N.getStr("markupView.display.subgrid.tooltiptiptext"),
|
"subgrid": INSPECTOR_L10N.getStr("markupView.display.subgrid.tooltiptiptext"),
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,8 @@ var closeTabAndToolbox = async function(tab = gBrowser.selectedTab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
await removeTab(tab);
|
await removeTab(tab);
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -596,10 +598,8 @@ function waitForClipboardPromise(setup, expected) {
|
||||||
* @return {Promise} resolves when the preferences have been updated
|
* @return {Promise} resolves when the preferences have been updated
|
||||||
*/
|
*/
|
||||||
function pushPref(preferenceName, value) {
|
function pushPref(preferenceName, value) {
|
||||||
return new Promise(resolve => {
|
const options = {"set": [[preferenceName, value]]};
|
||||||
const options = {"set": [[preferenceName, value]]};
|
return SpecialPowers.pushPrefEnv(options);
|
||||||
SpecialPowers.pushPrefEnv(options, resolve);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ addEventListener("load", startTest);
|
||||||
|
|
||||||
// This test needs to add tabs that are controlled by a service worker
|
// This test needs to add tabs that are controlled by a service worker
|
||||||
// so use some special powers to dig around and find gBrowser
|
// so use some special powers to dig around and find gBrowser
|
||||||
let {gBrowser} = SpecialPowers._getTopChromeWindow(SpecialPowers.window.get());
|
let {gBrowser} = SpecialPowers._getTopChromeWindow(SpecialPowers.window);
|
||||||
|
|
||||||
SimpleTest.registerCleanupFunction(() => {
|
SimpleTest.registerCleanupFunction(() => {
|
||||||
while (gBrowser.tabs.length > 1) {
|
while (gBrowser.tabs.length > 1) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/Location.h"
|
#include "mozilla/dom/Location.h"
|
||||||
#include "mozilla/dom/LocationBinding.h"
|
#include "mozilla/dom/LocationBinding.h"
|
||||||
|
#include "mozilla/dom/StructuredCloneTags.h"
|
||||||
#include "mozilla/dom/WindowBinding.h"
|
#include "mozilla/dom/WindowBinding.h"
|
||||||
#include "mozilla/dom/WindowGlobalChild.h"
|
#include "mozilla/dom/WindowGlobalChild.h"
|
||||||
#include "mozilla/dom/WindowGlobalParent.h"
|
#include "mozilla/dom/WindowGlobalParent.h"
|
||||||
|
|
@ -90,6 +91,12 @@ already_AddRefed<BrowsingContext> BrowsingContext::Get(uint64_t aId) {
|
||||||
return do_AddRef(sBrowsingContexts->Get(aId));
|
return do_AddRef(sBrowsingContexts->Get(aId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
already_AddRefed<BrowsingContext> BrowsingContext::GetFromWindow(
|
||||||
|
WindowProxyHolder& aProxy) {
|
||||||
|
return do_AddRef(aProxy.get());
|
||||||
|
}
|
||||||
|
|
||||||
CanonicalBrowsingContext* BrowsingContext::Canonical() {
|
CanonicalBrowsingContext* BrowsingContext::Canonical() {
|
||||||
return CanonicalBrowsingContext::Cast(this);
|
return CanonicalBrowsingContext::Cast(this);
|
||||||
}
|
}
|
||||||
|
|
@ -551,6 +558,45 @@ JSObject* BrowsingContext::WrapObject(JSContext* aCx,
|
||||||
return BrowsingContext_Binding::Wrap(aCx, this, aGivenProto);
|
return BrowsingContext_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BrowsingContext::WriteStructuredClone(JSContext* aCx,
|
||||||
|
JSStructuredCloneWriter* aWriter,
|
||||||
|
StructuredCloneHolder* aHolder) {
|
||||||
|
return (JS_WriteUint32Pair(aWriter, SCTAG_DOM_BROWSING_CONTEXT, 0) &&
|
||||||
|
JS_WriteUint32Pair(aWriter, uint32_t(Id()), uint32_t(Id() >> 32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
JSObject* BrowsingContext::ReadStructuredClone(JSContext* aCx,
|
||||||
|
JSStructuredCloneReader* aReader,
|
||||||
|
StructuredCloneHolder* aHolder) {
|
||||||
|
uint32_t idLow = 0;
|
||||||
|
uint32_t idHigh = 0;
|
||||||
|
if (!JS_ReadUint32Pair(aReader, &idLow, &idHigh)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
uint64_t id = uint64_t(idHigh) << 32 | idLow;
|
||||||
|
|
||||||
|
// Note: Do this check after reading our ID data. Returning null will abort
|
||||||
|
// the decode operation anyway, but we should at least be as safe as possible.
|
||||||
|
if (NS_WARN_IF(!NS_IsMainThread())) {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(false,
|
||||||
|
"We shouldn't be trying to decode a BrowsingContext "
|
||||||
|
"on a background thread.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::RootedValue val(aCx, JS::NullValue());
|
||||||
|
// We'll get rooting hazard errors from the RefPtr destructor if it isn't
|
||||||
|
// destroyed before we try to return a raw JSObject*, so create it in its own
|
||||||
|
// scope.
|
||||||
|
if (RefPtr<BrowsingContext> context = Get(id)) {
|
||||||
|
if (!GetOrCreateDOMReflector(aCx, context, &val) || !val.isObject()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val.toObjectOrNull();
|
||||||
|
}
|
||||||
|
|
||||||
void BrowsingContext::NotifyUserGestureActivation() {
|
void BrowsingContext::NotifyUserGestureActivation() {
|
||||||
// We would set the user gesture activation flag on the top level browsing
|
// We would set the user gesture activation flag on the top level browsing
|
||||||
// context, which would automatically be sync to other top level browsing
|
// context, which would automatically be sync to other top level browsing
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ template <typename>
|
||||||
struct Nullable;
|
struct Nullable;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Sequence;
|
class Sequence;
|
||||||
|
class StructuredCloneHolder;
|
||||||
struct WindowPostMessageOptions;
|
struct WindowPostMessageOptions;
|
||||||
class WindowProxyHolder;
|
class WindowProxyHolder;
|
||||||
|
|
||||||
|
|
@ -104,6 +105,13 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
|
||||||
return Get(aId);
|
return Get(aId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<BrowsingContext> GetFromWindow(
|
||||||
|
WindowProxyHolder& aProxy);
|
||||||
|
static already_AddRefed<BrowsingContext> GetFromWindow(
|
||||||
|
GlobalObject&, WindowProxyHolder& aProxy) {
|
||||||
|
return GetFromWindow(aProxy);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a brand-new BrowsingContext object.
|
// Create a brand-new BrowsingContext object.
|
||||||
static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent,
|
static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent,
|
||||||
BrowsingContext* aOpener,
|
BrowsingContext* aOpener,
|
||||||
|
|
@ -266,6 +274,12 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
|
||||||
|
|
||||||
JSObject* WrapObject(JSContext* aCx);
|
JSObject* WrapObject(JSContext* aCx);
|
||||||
|
|
||||||
|
static JSObject* ReadStructuredClone(JSContext* aCx,
|
||||||
|
JSStructuredCloneReader* aReader,
|
||||||
|
StructuredCloneHolder* aHolder);
|
||||||
|
bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||||
|
StructuredCloneHolder* aHolder);
|
||||||
|
|
||||||
void StartDelayedAutoplayMediaComponents();
|
void StartDelayedAutoplayMediaComponents();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,13 @@
|
||||||
onload="setTimeout(nextTest, 0);"
|
onload="setTimeout(nextTest, 0);"
|
||||||
title="bug 293235 test">
|
title="bug 293235 test">
|
||||||
|
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/>
|
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
|
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
|
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
|
||||||
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
||||||
<script type="application/javascript" src="docshell_helpers.js" />
|
<script type="application/javascript" src="docshell_helpers.js" />
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||||
|
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
var {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
|
||||||
// Define the generator-iterator for the tests.
|
// Define the generator-iterator for the tests.
|
||||||
var tests = testIterator();
|
var tests = testIterator();
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
onload="setTimeout(nextTest, 0);"
|
onload="setTimeout(nextTest, 0);"
|
||||||
title="bug 396649 test">
|
title="bug 396649 test">
|
||||||
|
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/specialpowersAPI.js"/>
|
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
|
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
|
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
|
||||||
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
||||||
<script type="application/javascript" src="docshell_helpers.js" />
|
<script type="application/javascript" src="docshell_helpers.js" />
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@
|
||||||
title="bug 89419 test">
|
title="bug 89419 test">
|
||||||
|
|
||||||
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/SpecialPowersObserverAPI.js"/>
|
<script src="chrome://mochikit/content/tests/SimpleTest/ChromePowers.js"/>
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/specialpowers.js"/>
|
|
||||||
<script type="application/javascript" src="docshell_helpers.js" />
|
<script type="application/javascript" src="docshell_helpers.js" />
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
<script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,18 +44,20 @@ function checkLoadFrame1() {
|
||||||
myFrame1.src = CROSS_ORIGIN_URI;
|
myFrame1.src = CROSS_ORIGIN_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkNavFrame1() {
|
async function checkNavFrame1() {
|
||||||
myFrame1.removeEventListener("load", checkNavFrame1);
|
myFrame1.removeEventListener("load", checkNavFrame1);
|
||||||
is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, CROSS_ORIGIN_URI,
|
is(await SpecialPowers.spawn(myFrame1, [], () => this.content.location.href),
|
||||||
|
CROSS_ORIGIN_URI,
|
||||||
"cross origin dummy loaded into frame1");
|
"cross origin dummy loaded into frame1");
|
||||||
|
|
||||||
myFrame1.addEventListener("load", checkBackNavFrame1);
|
myFrame1.addEventListener("load", checkBackNavFrame1);
|
||||||
myFrame1.src = SAME_ORIGIN_URI + "#bar";
|
myFrame1.src = SAME_ORIGIN_URI + "#bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkBackNavFrame1() {
|
async function checkBackNavFrame1() {
|
||||||
myFrame1.removeEventListener("load", checkBackNavFrame1);
|
myFrame1.removeEventListener("load", checkBackNavFrame1);
|
||||||
is(SpecialPowers.wrap(myFrame1.contentWindow).location.href, SAME_ORIGIN_URI + "#bar",
|
is(await SpecialPowers.spawn(myFrame1, [], () => this.content.location.href),
|
||||||
|
SAME_ORIGIN_URI + "#bar",
|
||||||
"navagiating back to same origin dummy for frame1");
|
"navagiating back to same origin dummy for frame1");
|
||||||
checkFinish();
|
checkFinish();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,11 @@ function navigateByHyperlink(name) {
|
||||||
// Functions that call into Mochitest framework
|
// Functions that call into Mochitest framework
|
||||||
// /////////////////////////////////////////////////////////////////////////
|
// /////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function isNavigated(wnd, message) {
|
async function isNavigated(wnd, message) {
|
||||||
var result = null;
|
var result = null;
|
||||||
try {
|
try {
|
||||||
result = SpecialPowers.wrap(wnd).document.body.innerHTML.trim();
|
result = await SpecialPowers.spawn(
|
||||||
|
wnd, [], () => this.content.document.body.innerHTML.trim());
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
result = ex;
|
result = ex;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,11 @@ function testChild3() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xpcWaitForFinishedFrames(function() {
|
xpcWaitForFinishedFrames(async function() {
|
||||||
isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
|
await isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
|
||||||
isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
|
await isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
|
||||||
isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
|
await isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
|
||||||
isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
|
await isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
|
||||||
|
|
||||||
window0.close();
|
window0.close();
|
||||||
window1.close();
|
window1.close();
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ window.onload = function() {
|
||||||
navigateByForm("child2");
|
navigateByForm("child2");
|
||||||
navigateByHyperlink("child3");
|
navigateByHyperlink("child3");
|
||||||
|
|
||||||
xpcWaitForFinishedFrames(function() {
|
xpcWaitForFinishedFrames(async function() {
|
||||||
isNavigated(frames[0], "Should be able to navigate off-domain child by setting location.");
|
await isNavigated(frames[0], "Should be able to navigate off-domain child by setting location.");
|
||||||
isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open.");
|
await isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open.");
|
||||||
isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form.");
|
await isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form.");
|
||||||
isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink.");
|
await isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink.");
|
||||||
|
|
||||||
xpcCleanupWindows();
|
xpcCleanupWindows();
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ window.onload = function() {
|
||||||
navigateByForm("child2_child0");
|
navigateByForm("child2_child0");
|
||||||
navigateByHyperlink("child3_child0");
|
navigateByHyperlink("child3_child0");
|
||||||
|
|
||||||
xpcWaitForFinishedFrames(function() {
|
xpcWaitForFinishedFrames(async function() {
|
||||||
isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location.");
|
await isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location.");
|
||||||
isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open.");
|
await isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open.");
|
||||||
isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form.");
|
await isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form.");
|
||||||
isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink.");
|
await isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink.");
|
||||||
|
|
||||||
xpcCleanupWindows();
|
xpcCleanupWindows();
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ window.onload = function() {
|
||||||
navigateByForm("window2");
|
navigateByForm("window2");
|
||||||
navigateByHyperlink("window3");
|
navigateByHyperlink("window3");
|
||||||
|
|
||||||
xpcWaitForFinishedFrames(function() {
|
xpcWaitForFinishedFrames(async function() {
|
||||||
isNavigated(window0, "Should be able to navigate popup by setting location.");
|
await isNavigated(window0, "Should be able to navigate popup by setting location.");
|
||||||
isNavigated(window1, "Should be able to navigate popup by calling window.open.");
|
await isNavigated(window1, "Should be able to navigate popup by calling window.open.");
|
||||||
isNavigated(window2, "Should be able to navigate popup by submitting form.");
|
await isNavigated(window2, "Should be able to navigate popup by submitting form.");
|
||||||
isNavigated(window3, "Should be able to navigate popup by targeted hyperlink.");
|
await isNavigated(window3, "Should be able to navigate popup by targeted hyperlink.");
|
||||||
|
|
||||||
window0.close();
|
window0.close();
|
||||||
window1.close();
|
window1.close();
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ function testChild3() {
|
||||||
window3 = window.open("navigate.html#child3,hyperlink", "window3", "width=10,height=10");
|
window3 = window.open("navigate.html#child3,hyperlink", "window3", "width=10,height=10");
|
||||||
}
|
}
|
||||||
|
|
||||||
xpcWaitForFinishedFrames(function() {
|
xpcWaitForFinishedFrames(async function() {
|
||||||
isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
|
await isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
|
||||||
isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
|
await isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
|
||||||
isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
|
await isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
|
||||||
isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
|
await isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
|
||||||
|
|
||||||
window0.close();
|
window0.close();
|
||||||
window1.close();
|
window1.close();
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@ window.onload = function() {
|
||||||
'<iframe src="navigate.html#child2,form"></iframe>' +
|
'<iframe src="navigate.html#child2,form"></iframe>' +
|
||||||
'<iframe src="navigate.html#child3,hyperlink"></iframe>';
|
'<iframe src="navigate.html#child3,hyperlink"></iframe>';
|
||||||
|
|
||||||
xpcWaitForFinishedFrames(function() {
|
xpcWaitForFinishedFrames(async function() {
|
||||||
isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location.");
|
await isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location.");
|
||||||
isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open.");
|
await isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open.");
|
||||||
isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form.");
|
await isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form.");
|
||||||
isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink.");
|
await isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink.");
|
||||||
|
|
||||||
xpcCleanupWindows();
|
xpcCleanupWindows();
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
|
||||||
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
|
head = head_docshell.js
|
||||||
|
|
||||||
[test_bug442584.js]
|
[test_bug442584.js]
|
||||||
|
[test_browsing_context_structured_clone.js]
|
||||||
[test_nsDefaultURIFixup.js]
|
[test_nsDefaultURIFixup.js]
|
||||||
[test_nsDefaultURIFixup_search.js]
|
[test_nsDefaultURIFixup_search.js]
|
||||||
skip-if = os == 'android'
|
skip-if = os == 'android'
|
||||||
|
|
|
||||||
|
|
@ -584,7 +584,7 @@ nsresult Selection::AddTableCellRange(nsRange* aRange, bool* aDidAddRange,
|
||||||
mFrameSelection->mSelectingTableCellMode = tableMode;
|
mFrameSelection->mSelectingTableCellMode = tableMode;
|
||||||
|
|
||||||
*aDidAddRange = true;
|
*aDidAddRange = true;
|
||||||
return AddItem(aRange, aOutIndex);
|
return AddRangesForSelectableNodes(aRange, aOutIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Figure out TableSelection::Column and TableSelection::AllCells
|
// TODO: Figure out TableSelection::Column and TableSelection::AllCells
|
||||||
|
|
@ -927,8 +927,9 @@ void Selection::UserSelectRangesToAdd(nsRange* aItem,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult Selection::AddItem(nsRange* aItem, int32_t* aOutIndex,
|
nsresult Selection::AddRangesForSelectableNodes(nsRange* aItem,
|
||||||
bool aNoStartSelect) {
|
int32_t* aOutIndex,
|
||||||
|
bool aNoStartSelect) {
|
||||||
if (!aItem) return NS_ERROR_NULL_POINTER;
|
if (!aItem) return NS_ERROR_NULL_POINTER;
|
||||||
if (!aItem->IsPositioned()) return NS_ERROR_UNEXPECTED;
|
if (!aItem->IsPositioned()) return NS_ERROR_UNEXPECTED;
|
||||||
|
|
||||||
|
|
@ -1010,7 +1011,7 @@ nsresult Selection::AddItem(nsRange* aItem, int32_t* aOutIndex,
|
||||||
GetDirection() == eDirPrevious ? 0 : rangesToAdd.Length() - 1;
|
GetDirection() == eDirPrevious ? 0 : rangesToAdd.Length() - 1;
|
||||||
for (size_t i = 0; i < rangesToAdd.Length(); ++i) {
|
for (size_t i = 0; i < rangesToAdd.Length(); ++i) {
|
||||||
int32_t index;
|
int32_t index;
|
||||||
nsresult rv = AddItemInternal(rangesToAdd[i], &index);
|
nsresult rv = MaybeAddRangeAndTruncateOverlaps(rangesToAdd[i], &index);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (i == newAnchorFocusIndex) {
|
if (i == newAnchorFocusIndex) {
|
||||||
*aOutIndex = index;
|
*aOutIndex = index;
|
||||||
|
|
@ -1021,20 +1022,23 @@ nsresult Selection::AddItem(nsRange* aItem, int32_t* aOutIndex,
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
return AddItemInternal(aItem, aOutIndex);
|
return MaybeAddRangeAndTruncateOverlaps(aItem, aOutIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
|
nsresult Selection::MaybeAddRangeAndTruncateOverlaps(nsRange* aRange,
|
||||||
MOZ_ASSERT(aItem);
|
int32_t* aOutIndex) {
|
||||||
MOZ_ASSERT(aItem->IsPositioned());
|
MOZ_ASSERT(aRange);
|
||||||
|
MOZ_ASSERT(aRange->IsPositioned());
|
||||||
MOZ_ASSERT(aOutIndex);
|
MOZ_ASSERT(aOutIndex);
|
||||||
|
|
||||||
*aOutIndex = -1;
|
*aOutIndex = -1;
|
||||||
|
|
||||||
// a common case is that we have no ranges yet
|
// a common case is that we have no ranges yet
|
||||||
if (mRanges.Length() == 0) {
|
if (mRanges.Length() == 0) {
|
||||||
if (!mRanges.AppendElement(RangeData(aItem))) return NS_ERROR_OUT_OF_MEMORY;
|
if (!mRanges.AppendElement(RangeData(aRange))) {
|
||||||
aItem->SetSelection(this);
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
aRange->SetSelection(this);
|
||||||
|
|
||||||
*aOutIndex = 0;
|
*aOutIndex = 0;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -1042,9 +1046,9 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
|
||||||
|
|
||||||
int32_t startIndex, endIndex;
|
int32_t startIndex, endIndex;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
GetIndicesForInterval(aItem->GetStartContainer(), aItem->StartOffset(),
|
GetIndicesForInterval(aRange->GetStartContainer(), aRange->StartOffset(),
|
||||||
aItem->GetEndContainer(), aItem->EndOffset(), false,
|
aRange->GetEndContainer(), aRange->EndOffset(),
|
||||||
&startIndex, &endIndex);
|
false, &startIndex, &endIndex);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (endIndex == -1) {
|
if (endIndex == -1) {
|
||||||
|
|
@ -1061,8 +1065,8 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
|
||||||
|
|
||||||
// If the range is already contained in mRanges, silently succeed
|
// If the range is already contained in mRanges, silently succeed
|
||||||
bool sameRange = EqualsRangeAtPoint(
|
bool sameRange = EqualsRangeAtPoint(
|
||||||
aItem->GetStartContainer(), aItem->StartOffset(),
|
aRange->GetStartContainer(), aRange->StartOffset(),
|
||||||
aItem->GetEndContainer(), aItem->EndOffset(), startIndex);
|
aRange->GetEndContainer(), aRange->EndOffset(), startIndex);
|
||||||
if (sameRange) {
|
if (sameRange) {
|
||||||
*aOutIndex = startIndex;
|
*aOutIndex = startIndex;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -1070,9 +1074,10 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
|
||||||
|
|
||||||
if (startIndex == endIndex) {
|
if (startIndex == endIndex) {
|
||||||
// The new range doesn't overlap any existing ranges
|
// The new range doesn't overlap any existing ranges
|
||||||
if (!mRanges.InsertElementAt(startIndex, RangeData(aItem)))
|
if (!mRanges.InsertElementAt(startIndex, RangeData(aRange))) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
aItem->SetSelection(this);
|
}
|
||||||
|
aRange->SetSelection(this);
|
||||||
*aOutIndex = startIndex;
|
*aOutIndex = startIndex;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1100,19 +1105,20 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
|
||||||
|
|
||||||
nsTArray<RangeData> temp;
|
nsTArray<RangeData> temp;
|
||||||
for (int32_t i = overlaps.Length() - 1; i >= 0; i--) {
|
for (int32_t i = overlaps.Length() - 1; i >= 0; i--) {
|
||||||
nsresult rv = SubtractRange(&overlaps[i], aItem, &temp);
|
nsresult rv = SubtractRange(&overlaps[i], aRange, &temp);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the new element into our "leftovers" array
|
// Insert the new element into our "leftovers" array
|
||||||
int32_t insertionPoint;
|
int32_t insertionPoint;
|
||||||
rv = FindInsertionPoint(&temp, aItem->GetStartContainer(),
|
rv = FindInsertionPoint(&temp, aRange->GetStartContainer(),
|
||||||
aItem->StartOffset(), CompareToRangeStart,
|
aRange->StartOffset(), CompareToRangeStart,
|
||||||
&insertionPoint);
|
&insertionPoint);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (!temp.InsertElementAt(insertionPoint, RangeData(aItem)))
|
if (!temp.InsertElementAt(insertionPoint, RangeData(aRange))) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge the leftovers back in to mRanges
|
// Merge the leftovers back in to mRanges
|
||||||
if (!mRanges.InsertElementsAt(startIndex, temp))
|
if (!mRanges.InsertElementsAt(startIndex, temp))
|
||||||
|
|
@ -1126,9 +1132,7 @@ nsresult Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult Selection::RemoveItem(nsRange* aItem) {
|
nsresult Selection::RemoveRangeInternal(nsRange& aRange) {
|
||||||
if (!aItem) return NS_ERROR_NULL_POINTER;
|
|
||||||
|
|
||||||
// Find the range's index & remove it. We could use FindInsertionPoint to
|
// Find the range's index & remove it. We could use FindInsertionPoint to
|
||||||
// get O(log n) time, but that requires many expensive DOM comparisons.
|
// get O(log n) time, but that requires many expensive DOM comparisons.
|
||||||
// For even several thousand items, this is probably faster because the
|
// For even several thousand items, this is probably faster because the
|
||||||
|
|
@ -1136,7 +1140,7 @@ nsresult Selection::RemoveItem(nsRange* aItem) {
|
||||||
int32_t idx = -1;
|
int32_t idx = -1;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i = 0; i < mRanges.Length(); i++) {
|
for (i = 0; i < mRanges.Length(); i++) {
|
||||||
if (mRanges[i].mRange == aItem) {
|
if (mRanges[i].mRange == &aRange) {
|
||||||
idx = (int32_t)i;
|
idx = (int32_t)i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1144,7 +1148,7 @@ nsresult Selection::RemoveItem(nsRange* aItem) {
|
||||||
if (idx < 0) return NS_ERROR_DOM_NOT_FOUND_ERR;
|
if (idx < 0) return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||||
|
|
||||||
mRanges.RemoveElementAt(idx);
|
mRanges.RemoveElementAt(idx);
|
||||||
aItem->SetSelection(nullptr);
|
aRange.SetSelection(nullptr);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1152,7 +1156,7 @@ nsresult Selection::RemoveCollapsedRanges() {
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while (i < mRanges.Length()) {
|
while (i < mRanges.Length()) {
|
||||||
if (mRanges[i].mRange->Collapsed()) {
|
if (mRanges[i].mRange->Collapsed()) {
|
||||||
nsresult rv = RemoveItem(mRanges[i].mRange);
|
nsresult rv = RemoveRangeInternal(*mRanges[i].mRange);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
|
|
@ -2037,7 +2041,7 @@ void Selection::AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!didAddRange) {
|
if (!didAddRange) {
|
||||||
result = AddItem(range, &rangeIndex);
|
result = AddRangesForSelectableNodes(range, &rangeIndex);
|
||||||
if (NS_FAILED(result)) {
|
if (NS_FAILED(result)) {
|
||||||
aRv.Throw(result);
|
aRv.Throw(result);
|
||||||
return;
|
return;
|
||||||
|
|
@ -2083,7 +2087,7 @@ void Selection::AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
|
||||||
|
|
||||||
void Selection::RemoveRangeAndUnselectFramesAndNotifyListeners(
|
void Selection::RemoveRangeAndUnselectFramesAndNotifyListeners(
|
||||||
nsRange& aRange, ErrorResult& aRv) {
|
nsRange& aRange, ErrorResult& aRv) {
|
||||||
nsresult rv = RemoveItem(&aRange);
|
nsresult rv = RemoveRangeInternal(aRange);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
aRv.Throw(rv);
|
aRv.Throw(rv);
|
||||||
return;
|
return;
|
||||||
|
|
@ -2267,7 +2271,7 @@ void Selection::Collapse(const RawRangeBoundary& aPoint, ErrorResult& aRv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32_t rangeIndex = -1;
|
int32_t rangeIndex = -1;
|
||||||
result = AddItem(range, &rangeIndex);
|
result = AddRangesForSelectableNodes(range, &rangeIndex);
|
||||||
if (NS_FAILED(result)) {
|
if (NS_FAILED(result)) {
|
||||||
aRv.Throw(result);
|
aRv.Throw(result);
|
||||||
return;
|
return;
|
||||||
|
|
@ -2389,11 +2393,11 @@ nsresult Selection::SetAnchorFocusToRange(nsRange* aRange) {
|
||||||
|
|
||||||
bool collapsed = IsCollapsed();
|
bool collapsed = IsCollapsed();
|
||||||
|
|
||||||
nsresult res = RemoveItem(mAnchorFocusRange);
|
nsresult res = RemoveRangeInternal(*mAnchorFocusRange);
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
|
|
||||||
int32_t aOutIndex = -1;
|
int32_t aOutIndex = -1;
|
||||||
res = AddItem(aRange, &aOutIndex, !collapsed);
|
res = AddRangesForSelectableNodes(aRange, &aOutIndex, !collapsed);
|
||||||
if (NS_FAILED(res)) return res;
|
if (NS_FAILED(res)) return res;
|
||||||
SetAnchorFocusRange(aOutIndex);
|
SetAnchorFocusRange(aOutIndex);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,17 +161,21 @@ class Selection final : public nsSupportsWeakReference,
|
||||||
ScrollAxis aVertical = ScrollAxis(),
|
ScrollAxis aVertical = ScrollAxis(),
|
||||||
ScrollAxis aHorizontal = ScrollAxis(),
|
ScrollAxis aHorizontal = ScrollAxis(),
|
||||||
int32_t aFlags = 0);
|
int32_t aFlags = 0);
|
||||||
nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract,
|
static nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract,
|
||||||
nsTArray<RangeData>* aOutput);
|
nsTArray<RangeData>* aOutput);
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* AddItem adds aRange to this Selection. If mUserInitiated is true,
|
* Adds aRange to this Selection. If mUserInitiated is true,
|
||||||
* then aRange is first scanned for -moz-user-select:none nodes and split up
|
* then aRange is first scanned for -moz-user-select:none nodes and split up
|
||||||
* into multiple ranges to exclude those before adding the resulting ranges
|
* into multiple ranges to exclude those before adding the resulting ranges
|
||||||
* to this Selection.
|
* to this Selection.
|
||||||
*/
|
*/
|
||||||
nsresult AddItem(nsRange* aRange, int32_t* aOutIndex,
|
nsresult AddRangesForSelectableNodes(nsRange* aRange, int32_t* aOutIndex,
|
||||||
bool aNoStartSelect = false);
|
bool aNoStartSelect = false);
|
||||||
nsresult RemoveItem(nsRange* aRange);
|
nsresult RemoveRangeInternal(nsRange& aRange);
|
||||||
|
|
||||||
|
public:
|
||||||
nsresult RemoveCollapsedRanges();
|
nsresult RemoveCollapsedRanges();
|
||||||
nsresult Clear(nsPresContext* aPresContext);
|
nsresult Clear(nsPresContext* aPresContext);
|
||||||
nsresult Collapse(nsINode* aContainer, int32_t aOffset) {
|
nsresult Collapse(nsINode* aContainer, int32_t aOffset) {
|
||||||
|
|
@ -737,13 +741,14 @@ class Selection final : public nsSupportsWeakReference,
|
||||||
int32_t* aEndIndex);
|
int32_t* aEndIndex);
|
||||||
RangeData* FindRangeData(nsRange* aRange);
|
RangeData* FindRangeData(nsRange* aRange);
|
||||||
|
|
||||||
void UserSelectRangesToAdd(nsRange* aItem,
|
static void UserSelectRangesToAdd(nsRange* aItem,
|
||||||
nsTArray<RefPtr<nsRange>>& rangesToAdd);
|
nsTArray<RefPtr<nsRange>>& rangesToAdd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for AddItem.
|
* Preserves the sorting of mRanges.
|
||||||
*/
|
*/
|
||||||
nsresult AddItemInternal(nsRange* aRange, int32_t* aOutIndex);
|
nsresult MaybeAddRangeAndTruncateOverlaps(nsRange* aRange,
|
||||||
|
int32_t* aOutIndex);
|
||||||
|
|
||||||
Document* GetDocument() const;
|
Document* GetDocument() const;
|
||||||
nsPIDOMWindowOuter* GetWindow() const;
|
nsPIDOMWindowOuter* GetWindow() const;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
#include "mozilla/AutoRestore.h"
|
#include "mozilla/AutoRestore.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/BlobBinding.h"
|
#include "mozilla/dom/BlobBinding.h"
|
||||||
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
|
#include "mozilla/dom/BrowsingContextBinding.h"
|
||||||
#include "mozilla/dom/StructuredCloneBlob.h"
|
#include "mozilla/dom/StructuredCloneBlob.h"
|
||||||
#include "mozilla/dom/Directory.h"
|
#include "mozilla/dom/Directory.h"
|
||||||
#include "mozilla/dom/DirectoryBinding.h"
|
#include "mozilla/dom/DirectoryBinding.h"
|
||||||
|
|
@ -910,6 +912,10 @@ JSObject* StructuredCloneHolder::CustomReadHandler(
|
||||||
return ReadInputStream(aCx, aIndex, this);
|
return ReadInputStream(aCx, aIndex, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aTag == SCTAG_DOM_BROWSING_CONTEXT) {
|
||||||
|
return BrowsingContext::ReadStructuredClone(aCx, aReader, this);
|
||||||
|
}
|
||||||
|
|
||||||
return ReadFullySerializableObjects(aCx, aReader, aTag);
|
return ReadFullySerializableObjects(aCx, aReader, aTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -973,6 +979,15 @@ bool StructuredCloneHolder::CustomWriteHandler(JSContext* aCx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See if this is a BrowsingContext object.
|
||||||
|
if (mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
|
||||||
|
mStructuredCloneScope == StructuredCloneScope::DifferentProcess) {
|
||||||
|
BrowsingContext* holder = nullptr;
|
||||||
|
if (NS_SUCCEEDED(UNWRAP_OBJECT(BrowsingContext, &obj, holder))) {
|
||||||
|
return holder->WriteStructuredClone(aCx, aWriter, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See if this is a WasmModule.
|
// See if this is a WasmModule.
|
||||||
if ((mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
|
if ((mStructuredCloneScope == StructuredCloneScope::SameProcessSameThread ||
|
||||||
mStructuredCloneScope ==
|
mStructuredCloneScope ==
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,8 @@ enum StructuredCloneTags {
|
||||||
|
|
||||||
SCTAG_DOM_STRUCTURED_CLONE_HOLDER,
|
SCTAG_DOM_STRUCTURED_CLONE_HOLDER,
|
||||||
|
|
||||||
|
SCTAG_DOM_BROWSING_CONTEXT,
|
||||||
|
|
||||||
// IMPORTANT: If you plan to add an new IDB tag, it _must_ be add before the
|
// IMPORTANT: If you plan to add an new IDB tag, it _must_ be add before the
|
||||||
// "less stable" tags!
|
// "less stable" tags!
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include "mozilla/dom/WindowBinding.h"
|
#include "mozilla/dom/WindowBinding.h"
|
||||||
#include "mozilla/dom/WindowProxyHolder.h"
|
#include "mozilla/dom/WindowProxyHolder.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDOMWindowList.h"
|
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsHTMLDocument.h"
|
#include "nsHTMLDocument.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
|
|
@ -18,18 +17,17 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
static bool ShouldExposeChildWindow(nsString& aNameBeingResolved,
|
static bool ShouldExposeChildWindow(const nsString& aNameBeingResolved,
|
||||||
BrowsingContext* aChild) {
|
BrowsingContext* aChild) {
|
||||||
nsPIDOMWindowOuter* child = aChild->GetDOMWindow();
|
Element* e = aChild->GetEmbedderElement();
|
||||||
Element* e = child->GetFrameElementInternal();
|
|
||||||
if (e && e->IsInShadowTree()) {
|
if (e && e->IsInShadowTree()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're same-origin with the child, go ahead and expose it.
|
// If we're same-origin with the child, go ahead and expose it.
|
||||||
|
nsPIDOMWindowOuter* child = aChild->GetDOMWindow();
|
||||||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(child);
|
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(child);
|
||||||
NS_ENSURE_TRUE(sop, false);
|
if (sop && nsContentUtils::SubjectPrincipal()->Equals(sop->GetPrincipal())) {
|
||||||
if (nsContentUtils::SubjectPrincipal()->Equals(sop->GetPrincipal())) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,23 +167,12 @@ bool WindowNamedPropertiesHandler::ownPropNames(
|
||||||
// The names live on the outer window, which might be null
|
// The names live on the outer window, which might be null
|
||||||
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();
|
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();
|
||||||
if (outer) {
|
if (outer) {
|
||||||
nsDOMWindowList* childWindows = outer->GetFrames();
|
if (BrowsingContext* bc = outer->GetBrowsingContext()) {
|
||||||
if (childWindows) {
|
for (const auto& child : bc->GetChildren()) {
|
||||||
uint32_t length = childWindows->GetLength();
|
const nsString& name = child->Name();
|
||||||
for (uint32_t i = 0; i < length; ++i) {
|
if (!name.IsEmpty() && !names.Contains(name)) {
|
||||||
nsCOMPtr<nsIDocShellTreeItem> item =
|
|
||||||
childWindows->GetDocShellTreeItemAt(i);
|
|
||||||
// This is a bit silly, since we could presumably just do
|
|
||||||
// item->GetWindow(). But it's not obvious whether this does the same
|
|
||||||
// thing as GetChildWindow() with the item's name (due to the complexity
|
|
||||||
// of FindChildWithName). Since GetChildWindow is what we use in
|
|
||||||
// getOwnPropDescriptor, let's try to be consistent.
|
|
||||||
nsString name;
|
|
||||||
item->GetName(name);
|
|
||||||
if (!names.Contains(name)) {
|
|
||||||
// Make sure we really would expose it from getOwnPropDescriptor.
|
// Make sure we really would expose it from getOwnPropDescriptor.
|
||||||
RefPtr<BrowsingContext> child = win->GetChildWindow(name);
|
if (ShouldExposeChildWindow(name, child)) {
|
||||||
if (child && ShouldExposeChildWindow(name, child)) {
|
|
||||||
names.AppendElement(name);
|
names.AppendElement(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,6 @@ UNIFIED_SOURCES += [
|
||||||
'nsDOMNavigationTiming.cpp',
|
'nsDOMNavigationTiming.cpp',
|
||||||
'nsDOMSerializer.cpp',
|
'nsDOMSerializer.cpp',
|
||||||
'nsDOMTokenList.cpp',
|
'nsDOMTokenList.cpp',
|
||||||
'nsDOMWindowList.cpp',
|
|
||||||
'nsFocusManager.cpp',
|
'nsFocusManager.cpp',
|
||||||
'nsFrameLoader.cpp',
|
'nsFrameLoader.cpp',
|
||||||
'nsFrameLoaderOwner.cpp',
|
'nsFrameLoaderOwner.cpp',
|
||||||
|
|
|
||||||
|
|
@ -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 "nsISizeOfEventTarget.h"
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsArrayUtils.h"
|
#include "nsArrayUtils.h"
|
||||||
#include "nsDOMWindowList.h"
|
|
||||||
#include "mozilla/dom/WakeLock.h"
|
#include "mozilla/dom/WakeLock.h"
|
||||||
#include "mozilla/dom/power/PowerManagerService.h"
|
#include "mozilla/dom/power/PowerManagerService.h"
|
||||||
#include "nsIContentSecurityPolicy.h"
|
#include "nsIContentSecurityPolicy.h"
|
||||||
|
|
@ -2708,11 +2707,7 @@ bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
|
||||||
FORWARD_TO_OUTER(GetClosedOuter, (), true);
|
FORWARD_TO_OUTER(GetClosedOuter, (), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDOMWindowList* nsGlobalWindowInner::GetFrames() {
|
Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
|
||||||
FORWARD_TO_OUTER(GetFrames, (), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowInner::IndexedGetter(
|
|
||||||
uint32_t aIndex) {
|
uint32_t aIndex) {
|
||||||
FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
|
FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ class nsITimeoutHandler;
|
||||||
class nsIWebBrowserChrome;
|
class nsIWebBrowserChrome;
|
||||||
class mozIDOMWindowProxy;
|
class mozIDOMWindowProxy;
|
||||||
|
|
||||||
class nsDOMWindowList;
|
|
||||||
class nsScreen;
|
class nsScreen;
|
||||||
class nsHistory;
|
class nsHistory;
|
||||||
class nsGlobalWindowObserver;
|
class nsGlobalWindowObserver;
|
||||||
|
|
@ -381,7 +380,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
|
|
||||||
// WebIDL interface.
|
// WebIDL interface.
|
||||||
already_AddRefed<nsPIDOMWindowOuter> IndexedGetter(uint32_t aIndex);
|
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetter(
|
||||||
|
uint32_t aIndex);
|
||||||
|
|
||||||
static bool IsPrivilegedChromeWindow(JSContext* /* unused */, JSObject* aObj);
|
static bool IsPrivilegedChromeWindow(JSContext* /* unused */, JSObject* aObj);
|
||||||
|
|
||||||
|
|
@ -612,7 +612,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||||
void Focus(mozilla::ErrorResult& aError);
|
void Focus(mozilla::ErrorResult& aError);
|
||||||
nsresult Focus() override;
|
nsresult Focus() override;
|
||||||
void Blur(mozilla::ErrorResult& aError);
|
void Blur(mozilla::ErrorResult& aError);
|
||||||
nsDOMWindowList* GetFrames() final;
|
|
||||||
mozilla::dom::BrowsingContext* GetFrames(mozilla::ErrorResult& aError);
|
mozilla::dom::BrowsingContext* GetFrames(mozilla::ErrorResult& aError);
|
||||||
uint32_t Length();
|
uint32_t Length();
|
||||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTop(
|
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTop(
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@
|
||||||
#include "nsISizeOfEventTarget.h"
|
#include "nsISizeOfEventTarget.h"
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsArrayUtils.h"
|
#include "nsArrayUtils.h"
|
||||||
#include "nsDOMWindowList.h"
|
|
||||||
#include "mozilla/dom/WakeLock.h"
|
#include "mozilla/dom/WakeLock.h"
|
||||||
#include "mozilla/dom/power/PowerManagerService.h"
|
#include "mozilla/dom/power/PowerManagerService.h"
|
||||||
#include "nsIDocShellTreeOwner.h"
|
#include "nsIDocShellTreeOwner.h"
|
||||||
|
|
@ -510,8 +509,9 @@ class nsOuterWindowProxy : public MaybeCrossOriginObject<js::Wrapper> {
|
||||||
|
|
||||||
// Returns a non-null window only if id is an index and we have a
|
// Returns a non-null window only if id is an index and we have a
|
||||||
// window at that index.
|
// window at that index.
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetSubframeWindow(
|
Nullable<WindowProxyHolder> GetSubframeWindow(JSContext* cx,
|
||||||
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const;
|
JS::Handle<JSObject*> proxy,
|
||||||
|
JS::Handle<jsid> id) const;
|
||||||
|
|
||||||
bool AppendIndexedPropertyNames(JSObject* proxy,
|
bool AppendIndexedPropertyNames(JSObject* proxy,
|
||||||
JS::MutableHandleVector<jsid> props) const;
|
JS::MutableHandleVector<jsid> props) const;
|
||||||
|
|
@ -784,7 +784,7 @@ bool nsOuterWindowProxy::delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||||
return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete"));
|
return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
|
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
|
||||||
// Fail (which means throw if strict, else return false).
|
// Fail (which means throw if strict, else return false).
|
||||||
return result.failCantDeleteWindowElement();
|
return result.failCantDeleteWindowElement();
|
||||||
}
|
}
|
||||||
|
|
@ -818,7 +818,7 @@ bool nsOuterWindowProxy::has(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||||
return hasOwn(cx, proxy, id, bp);
|
return hasOwn(cx, proxy, id, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
|
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
|
||||||
*bp = true;
|
*bp = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -851,7 +851,7 @@ bool nsOuterWindowProxy::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||||
return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp);
|
return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
|
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
|
||||||
*bp = true;
|
*bp = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -982,28 +982,17 @@ bool nsOuterWindowProxy::GetSubframeWindow(JSContext* cx,
|
||||||
JS::Handle<jsid> id,
|
JS::Handle<jsid> id,
|
||||||
JS::MutableHandle<JS::Value> vp,
|
JS::MutableHandle<JS::Value> vp,
|
||||||
bool& found) const {
|
bool& found) const {
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id);
|
Nullable<WindowProxyHolder> frame = GetSubframeWindow(cx, proxy, id);
|
||||||
if (!frame) {
|
if (frame.IsNull()) {
|
||||||
found = false;
|
found = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
// Just return the window's global
|
return WrapObject(cx, frame.Value(), vp);
|
||||||
nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(frame);
|
|
||||||
frame->EnsureInnerWindow();
|
|
||||||
JSObject* obj = global->GetGlobalJSObject();
|
|
||||||
// This null check fixes a hard-to-reproduce crash that occurs when we
|
|
||||||
// get here when we're mid-call to nsDocShell::Destroy. See bug 640904
|
|
||||||
// comment 105.
|
|
||||||
if (MOZ_UNLIKELY(!obj)) {
|
|
||||||
return xpc::Throw(cx, NS_ERROR_FAILURE);
|
|
||||||
}
|
|
||||||
vp.setObject(*obj);
|
|
||||||
return JS_WrapValue(cx, vp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsPIDOMWindowOuter> nsOuterWindowProxy::GetSubframeWindow(
|
Nullable<WindowProxyHolder> nsOuterWindowProxy::GetSubframeWindow(
|
||||||
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const {
|
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const {
|
||||||
uint32_t index = GetArrayIndexFromId(id);
|
uint32_t index = GetArrayIndexFromId(id);
|
||||||
if (!IsArrayIndex(index)) {
|
if (!IsArrayIndex(index)) {
|
||||||
|
|
@ -1300,7 +1289,6 @@ void nsGlobalWindowOuter::CleanUp() {
|
||||||
|
|
||||||
StartDying();
|
StartDying();
|
||||||
|
|
||||||
mFrames = nullptr;
|
|
||||||
mWindowUtils = nullptr;
|
mWindowUtils = nullptr;
|
||||||
|
|
||||||
ClearControllers();
|
ClearControllers();
|
||||||
|
|
@ -2380,10 +2368,6 @@ void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
|
||||||
mTopLevelOuterContentWindow =
|
mTopLevelOuterContentWindow =
|
||||||
!mIsChrome && GetScriptableTopInternal() == this;
|
!mIsChrome && GetScriptableTopInternal() == this;
|
||||||
|
|
||||||
if (mFrames) {
|
|
||||||
mFrames->SetDocShell(aDocShell);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get our enclosing chrome shell and retrieve its global window impl, so
|
// Get our enclosing chrome shell and retrieve its global window impl, so
|
||||||
// that we can do some forwarding to the chrome document.
|
// that we can do some forwarding to the chrome document.
|
||||||
RefPtr<EventTarget> chromeEventHandler;
|
RefPtr<EventTarget> chromeEventHandler;
|
||||||
|
|
@ -2475,10 +2459,6 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
|
||||||
mDocShell = nullptr;
|
mDocShell = nullptr;
|
||||||
mBrowsingContext->ClearDocShell();
|
mBrowsingContext->ClearDocShell();
|
||||||
|
|
||||||
if (mFrames) {
|
|
||||||
mFrames->SetDocShell(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeForgiveSpamCount();
|
MaybeForgiveSpamCount();
|
||||||
CleanUp();
|
CleanUp();
|
||||||
}
|
}
|
||||||
|
|
@ -3196,20 +3176,16 @@ bool nsGlobalWindowOuter::GetClosedOuter() {
|
||||||
|
|
||||||
bool nsGlobalWindowOuter::Closed() { return GetClosedOuter(); }
|
bool nsGlobalWindowOuter::Closed() { return GetClosedOuter(); }
|
||||||
|
|
||||||
nsDOMWindowList* nsGlobalWindowOuter::GetFrames() {
|
Nullable<WindowProxyHolder> nsGlobalWindowOuter::IndexedGetterOuter(
|
||||||
if (!mFrames && mDocShell) {
|
|
||||||
mFrames = new nsDOMWindowList(mDocShell);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::IndexedGetterOuter(
|
|
||||||
uint32_t aIndex) {
|
uint32_t aIndex) {
|
||||||
nsDOMWindowList* windows = GetFrames();
|
BrowsingContext* bc = GetBrowsingContext();
|
||||||
NS_ENSURE_TRUE(windows, nullptr);
|
NS_ENSURE_TRUE(bc, nullptr);
|
||||||
|
|
||||||
return windows->IndexedGetter(aIndex);
|
const BrowsingContext::Children& children = bc->GetChildren();
|
||||||
|
if (aIndex < children.Length()) {
|
||||||
|
return WindowProxyHolder(children[aIndex]);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIControllers* nsGlobalWindowOuter::GetControllersOuter(ErrorResult& aError) {
|
nsIControllers* nsGlobalWindowOuter::GetControllersOuter(ErrorResult& aError) {
|
||||||
|
|
@ -3962,9 +3938,8 @@ double nsGlobalWindowOuter::GetScrollXOuter() { return GetScrollXY(false).x; }
|
||||||
double nsGlobalWindowOuter::GetScrollYOuter() { return GetScrollXY(false).y; }
|
double nsGlobalWindowOuter::GetScrollYOuter() { return GetScrollXY(false).y; }
|
||||||
|
|
||||||
uint32_t nsGlobalWindowOuter::Length() {
|
uint32_t nsGlobalWindowOuter::Length() {
|
||||||
nsDOMWindowList* windows = GetFrames();
|
BrowsingContext* bc = GetBrowsingContext();
|
||||||
|
return bc ? bc->GetChildren().Length() : 0;
|
||||||
return windows ? windows->GetLength() : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() {
|
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() {
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ class nsIWebBrowserChrome;
|
||||||
class mozIDOMWindowProxy;
|
class mozIDOMWindowProxy;
|
||||||
|
|
||||||
class nsDocShellLoadState;
|
class nsDocShellLoadState;
|
||||||
class nsDOMWindowList;
|
|
||||||
class nsScreen;
|
class nsScreen;
|
||||||
class nsHistory;
|
class nsHistory;
|
||||||
class nsGlobalWindowObserver;
|
class nsGlobalWindowObserver;
|
||||||
|
|
@ -354,7 +353,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||||
// nsIObserver
|
// nsIObserver
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
already_AddRefed<nsPIDOMWindowOuter> IndexedGetterOuter(uint32_t aIndex);
|
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetterOuter(
|
||||||
|
uint32_t aIndex);
|
||||||
|
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetTop() override;
|
already_AddRefed<nsPIDOMWindowOuter> GetTop() override;
|
||||||
// Similar to GetTop() except that it stops at content frames that an
|
// Similar to GetTop() except that it stops at content frames that an
|
||||||
|
|
@ -535,7 +535,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||||
nsresult Focus() override;
|
nsresult Focus() override;
|
||||||
void BlurOuter();
|
void BlurOuter();
|
||||||
mozilla::dom::BrowsingContext* GetFramesOuter();
|
mozilla::dom::BrowsingContext* GetFramesOuter();
|
||||||
nsDOMWindowList* GetFrames() final;
|
|
||||||
uint32_t Length();
|
uint32_t Length();
|
||||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
|
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
|
||||||
|
|
||||||
|
|
@ -918,8 +917,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||||
|
|
||||||
virtual bool ShouldShowFocusRing() override;
|
virtual bool ShouldShowFocusRing() override;
|
||||||
|
|
||||||
virtual void SetKeyboardIndicators(UIStateChangeType aShowFocusRings)
|
virtual void SetKeyboardIndicators(
|
||||||
override;
|
UIStateChangeType aShowFocusRings) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
||||||
|
|
@ -1099,7 +1098,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||||
// For |window.arguments|, via |openDialog|.
|
// For |window.arguments|, via |openDialog|.
|
||||||
nsCOMPtr<nsIArray> mArguments;
|
nsCOMPtr<nsIArray> mArguments;
|
||||||
|
|
||||||
RefPtr<nsDOMWindowList> mFrames;
|
|
||||||
RefPtr<nsDOMWindowUtils> mWindowUtils;
|
RefPtr<nsDOMWindowUtils> mWindowUtils;
|
||||||
nsString mStatus;
|
nsString mStatus;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@
|
||||||
#define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
|
#define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
|
||||||
|
|
||||||
class nsDOMOfflineResourceList;
|
class nsDOMOfflineResourceList;
|
||||||
class nsDOMWindowList;
|
|
||||||
class nsGlobalWindowInner;
|
class nsGlobalWindowInner;
|
||||||
class nsGlobalWindowOuter;
|
class nsGlobalWindowOuter;
|
||||||
class nsIArray;
|
class nsIArray;
|
||||||
|
|
@ -546,8 +545,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||||
|
|
||||||
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
|
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
|
||||||
|
|
||||||
virtual nsDOMWindowList* GetFrames() = 0;
|
|
||||||
|
|
||||||
virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
|
virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
|
||||||
virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
|
virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
|
||||||
|
|
||||||
|
|
@ -1045,8 +1042,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
||||||
virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0;
|
virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0;
|
||||||
virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
|
virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
|
||||||
|
|
||||||
virtual nsDOMWindowList* GetFrames() = 0;
|
|
||||||
|
|
||||||
// aLoadState will be passed on through to the windowwatcher.
|
// aLoadState will be passed on through to the windowwatcher.
|
||||||
// aForceNoOpener will act just like a "noopener" feature in aOptions except
|
// aForceNoOpener will act just like a "noopener" feature in aOptions except
|
||||||
// will not affect any other window features.
|
// will not affect any other window features.
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ class nsRange final : public mozilla::dom::AbstractRange,
|
||||||
* Mark this range as being generated or not.
|
* Mark this range as being generated or not.
|
||||||
* Currently it is used for marking ranges that are created when splitting up
|
* Currently it is used for marking ranges that are created when splitting up
|
||||||
* a range to exclude a -moz-user-select:none region.
|
* a range to exclude a -moz-user-select:none region.
|
||||||
* @see Selection::AddItem
|
* @see Selection::AddRangesForSelectableNodes
|
||||||
* @see ExcludeNonSelectableNodes
|
* @see ExcludeNonSelectableNodes
|
||||||
*/
|
*/
|
||||||
void SetIsGenerated(bool aIsGenerated) { mIsGenerated = aIsGenerated; }
|
void SetIsGenerated(bool aIsGenerated) { mIsGenerated = aIsGenerated; }
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,14 @@
|
||||||
#include "nsWindowMemoryReporter.h"
|
#include "nsWindowMemoryReporter.h"
|
||||||
#include "nsWindowSizes.h"
|
#include "nsWindowSizes.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "nsDOMWindowList.h"
|
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
|
#include "mozilla/ResultExtensions.h"
|
||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "XPCJSMemoryReporter.h"
|
#include "XPCJSMemoryReporter.h"
|
||||||
|
|
@ -61,19 +62,16 @@ static nsresult AddNonJSSizeOfWindowAndItsDescendents(
|
||||||
|
|
||||||
windowSizes.addToTabSizes(aSizes);
|
windowSizes.addToTabSizes(aSizes);
|
||||||
|
|
||||||
nsDOMWindowList* frames = aWindow->GetFrames();
|
BrowsingContext* bc = aWindow->GetBrowsingContext();
|
||||||
|
if (!bc) {
|
||||||
uint32_t length = frames->GetLength();
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Measure this window's descendents.
|
// Measure this window's descendents.
|
||||||
for (uint32_t i = 0; i < length; i++) {
|
for (const auto& frame : bc->GetChildren()) {
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> child = frames->IndexedGetter(i);
|
if (auto* childWin = nsGlobalWindowOuter::Cast(frame->GetDOMWindow())) {
|
||||||
NS_ENSURE_STATE(child);
|
MOZ_TRY(AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes));
|
||||||
|
}
|
||||||
nsGlobalWindowOuter* childWin = nsGlobalWindowOuter::Cast(child);
|
|
||||||
|
|
||||||
nsresult rv = AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
<label value="CPOWs"/>
|
<label value="CPOWs"/>
|
||||||
|
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
var test_state = "remote";
|
var test_state = "remote";
|
||||||
var test_node = null;
|
var test_node = null;
|
||||||
var reentered = false;
|
var reentered = false;
|
||||||
|
|
@ -400,7 +402,7 @@
|
||||||
let failed = false;
|
let failed = false;
|
||||||
|
|
||||||
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
||||||
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
|
Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
|
||||||
try {
|
try {
|
||||||
msg.objects.f();
|
msg.objects.f();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -416,7 +418,7 @@
|
||||||
|
|
||||||
function recvSafe(msg) {
|
function recvSafe(msg) {
|
||||||
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
||||||
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
|
Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
|
||||||
try {
|
try {
|
||||||
msg.objects.f();
|
msg.objects.f();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ function createFileWithData(fileData) {
|
||||||
/** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/
|
/** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/
|
||||||
var file = createFileWithData("Test bug 914381");
|
var file = createFileWithData("Test bug 914381");
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({ set: [ "dom.file.createInChild" ]})
|
SpecialPowers.pushPrefEnv({ set: [["dom.file.createInChild", true]]})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return File.createFromNsIFile(file);
|
return File.createFromNsIFile(file);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,14 @@
|
||||||
<!-- test code goes here -->
|
<!-- test code goes here -->
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
|
|
||||||
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
|
||||||
SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
|
Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
|
||||||
SimpleTest.registerCleanupFunction(() => {
|
SimpleTest.registerCleanupFunction(() => {
|
||||||
SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
|
Services.prefs.clearUserPref(PREF_UNSAFE_FORBIDDEN);
|
||||||
});
|
});
|
||||||
|
|
||||||
function done() {
|
function done() {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@
|
||||||
<script class="testbody" type="application/javascript">
|
<script class="testbody" type="application/javascript">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
var SpecialPowers = window.opener.wrappedJSObject.SpecialPowers;
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
|
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
|
||||||
|
|
||||||
SimpleTest.waitForFocus(runTests, window);
|
SimpleTest.waitForFocus(runTests, window);
|
||||||
|
|
@ -1480,7 +1481,7 @@ function runReleaseTests()
|
||||||
// Release the TIP
|
// Release the TIP
|
||||||
TIP = null;
|
TIP = null;
|
||||||
// Needs to run GC forcibly for testing this.
|
// Needs to run GC forcibly for testing this.
|
||||||
SpecialPowers.gc();
|
Cu.forceGC();
|
||||||
|
|
||||||
is(input.value, "",
|
is(input.value, "",
|
||||||
description + "the input should be empty because the composition should be canceled");
|
description + "the input should be empty because the composition should be canceled");
|
||||||
|
|
@ -1770,7 +1771,7 @@ function runCompositionWithKeyEventTests()
|
||||||
var convertKeyEvent = new KeyboardEvent("", { key: "Convert", code: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT });
|
var convertKeyEvent = new KeyboardEvent("", { key: "Convert", code: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT });
|
||||||
var backspaceKeyEvent = new KeyboardEvent("", { key: "Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE });
|
var backspaceKeyEvent = new KeyboardEvent("", { key: "Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE });
|
||||||
|
|
||||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
|
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
|
||||||
|
|
||||||
// nsITextInputProcessor.startComposition()
|
// nsITextInputProcessor.startComposition()
|
||||||
reset();
|
reset();
|
||||||
|
|
@ -2004,7 +2005,7 @@ function runCompositionWithKeyEventTests()
|
||||||
is(input.value, "FOobarbuzzboo!",
|
is(input.value, "FOobarbuzzboo!",
|
||||||
description + "committing text directly should append the committing text to the focused editor");
|
description + "committing text directly should append the committing text to the focused editor");
|
||||||
|
|
||||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
||||||
|
|
||||||
// Even if "dom.keyboardevent.dispatch_during_composition" is true, keypress event shouldn't be fired during composition
|
// Even if "dom.keyboardevent.dispatch_during_composition" is true, keypress event shouldn't be fired during composition
|
||||||
reset();
|
reset();
|
||||||
|
|
@ -2108,7 +2109,7 @@ function runCompositionWithKeyEventTests()
|
||||||
is(events[1].type, "compositionend",
|
is(events[1].type, "compositionend",
|
||||||
description + "TIP.cancelComposition(escKeydownEvent) should cause compositionend (keyup event shouldn't be fired)");
|
description + "TIP.cancelComposition(escKeydownEvent) should cause compositionend (keyup event shouldn't be fired)");
|
||||||
|
|
||||||
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
||||||
|
|
||||||
window.removeEventListener("compositionstart", handler, false);
|
window.removeEventListener("compositionstart", handler, false);
|
||||||
window.removeEventListener("compositionupdate", handler, false);
|
window.removeEventListener("compositionupdate", handler, false);
|
||||||
|
|
@ -2155,7 +2156,7 @@ function runConsumingKeydownBeforeCompositionTests()
|
||||||
var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN });
|
var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN });
|
||||||
var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE });
|
var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE });
|
||||||
|
|
||||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
|
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
|
||||||
|
|
||||||
// If keydown before compositionstart is consumed, composition shouldn't be started.
|
// If keydown before compositionstart is consumed, composition shouldn't be started.
|
||||||
reset();
|
reset();
|
||||||
|
|
@ -2205,7 +2206,7 @@ function runConsumingKeydownBeforeCompositionTests()
|
||||||
is(input.value, "",
|
is(input.value, "",
|
||||||
description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause inserting text");
|
description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause inserting text");
|
||||||
|
|
||||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
||||||
|
|
||||||
// If composition is already started, TIP.flushPendingComposition(printableKeyEvent) shouldn't be canceled.
|
// If composition is already started, TIP.flushPendingComposition(printableKeyEvent) shouldn't be canceled.
|
||||||
TIP.startComposition();
|
TIP.startComposition();
|
||||||
|
|
@ -2273,7 +2274,7 @@ function runConsumingKeydownBeforeCompositionTests()
|
||||||
is(input.value, "",
|
is(input.value, "",
|
||||||
description + "TIP.cancelComposition(escKeyEvent) should cancel composition even if preceding keydown is consumed because there was a composition already");
|
description + "TIP.cancelComposition(escKeyEvent) should cancel composition even if preceding keydown is consumed because there was a composition already");
|
||||||
|
|
||||||
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
||||||
|
|
||||||
window.removeEventListener("compositionstart", handler, false);
|
window.removeEventListener("compositionstart", handler, false);
|
||||||
window.removeEventListener("compositionupdate", handler, false);
|
window.removeEventListener("compositionupdate", handler, false);
|
||||||
|
|
@ -2594,7 +2595,7 @@ function runKeyTests()
|
||||||
|
|
||||||
// key events during composition
|
// key events during composition
|
||||||
try {
|
try {
|
||||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
|
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
|
||||||
|
|
||||||
ok(TIP.startComposition(), "TIP.startComposition() should start composition");
|
ok(TIP.startComposition(), "TIP.startComposition() should start composition");
|
||||||
|
|
||||||
|
|
@ -2608,7 +2609,7 @@ function runKeyTests()
|
||||||
is(events.length, 0,
|
is(events.length, 0,
|
||||||
description + "TIP.keyup(keyA) shouldn't cause key events during composition if it's disabled by the pref");
|
description + "TIP.keyup(keyA) shouldn't cause key events during composition if it's disabled by the pref");
|
||||||
|
|
||||||
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
|
||||||
reset();
|
reset();
|
||||||
TIP.keydown(keyA);
|
TIP.keydown(keyA);
|
||||||
is(events.length, 1,
|
is(events.length, 1,
|
||||||
|
|
@ -2624,7 +2625,7 @@ function runKeyTests()
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
TIP.cancelComposition();
|
TIP.cancelComposition();
|
||||||
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test .location computation
|
// Test .location computation
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ function getTestPlugin(pluginName) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Copied from /dom/plugins/test/mochitest/utils.js
|
// Copied from /dom/plugins/test/mochitest/utils.js
|
||||||
function setTestPluginEnabledState(newEnabledState, pluginName) {
|
async function setTestPluginEnabledState(newEnabledState, pluginName) {
|
||||||
var oldEnabledState = SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName);
|
var oldEnabledState = await SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName);
|
||||||
if (!oldEnabledState) {
|
if (!oldEnabledState) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ function setTestPluginEnabledState(newEnabledState, pluginName) {
|
||||||
return plugin.enabledState == newEnabledState;
|
return plugin.enabledState == newEnabledState;
|
||||||
});
|
});
|
||||||
SimpleTest.registerCleanupFunction(function() {
|
SimpleTest.registerCleanupFunction(function() {
|
||||||
SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName);
|
return SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
|
||||||
|
|
||||||
function doTest() {
|
function doTest() {
|
||||||
var file = location.href;
|
var file = location.href;
|
||||||
|
|
||||||
var asyncFrame;
|
var asyncFrame;
|
||||||
/* Async parent frames from pushPrefEnv don't show up in e10s. */
|
/* Async parent frames from pushPrefEnv don't show up in e10s. */
|
||||||
var isE10S = !SpecialPowers.isMainProcess();
|
if (SpecialPowers.getBoolPref("javascript.options.asyncstack")) {
|
||||||
if (!isE10S && SpecialPowers.getBoolPref("javascript.options.asyncstack")) {
|
|
||||||
asyncFrame = `Async*@${file}:153:17
|
asyncFrame = `Async*@${file}:153:17
|
||||||
`;
|
`;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
|
||||||
|
|
||||||
function doTest() {
|
function doTest() {
|
||||||
var t = new TestInterfaceJS();
|
var t = new TestInterfaceJS();
|
||||||
/* Async parent frames from pushPrefEnv don't show up in e10s. */
|
|
||||||
var isE10S = !SpecialPowers.isMainProcess();
|
|
||||||
var asyncStack = SpecialPowers.getBoolPref("javascript.options.asyncstack");
|
var asyncStack = SpecialPowers.getBoolPref("javascript.options.asyncstack");
|
||||||
var ourFile = location.href;
|
var ourFile = location.href;
|
||||||
var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper.";
|
var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper.";
|
||||||
var parentFrame = (asyncStack && !isE10S) ? `Async*@${ourFile}:130:17
|
var parentFrame = asyncStack ? `Async*@${ourFile}:130:17
|
||||||
` : "";
|
` : "";
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
SpecialPowers.pushPrefEnv({"set": [["canvas.hitregions.enabled", true]]}, function() {
|
SpecialPowers.pushPrefEnv({"set": [["canvas.hitregions.enabled", true]]}).then(function() {
|
||||||
|
|
||||||
var input = document.getElementById("input");
|
var input = document.getElementById("input");
|
||||||
var regionId = "";
|
var regionId = "";
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ interface nsIDocShell;
|
||||||
interface BrowsingContext {
|
interface BrowsingContext {
|
||||||
static BrowsingContext? get(unsigned long long aId);
|
static BrowsingContext? get(unsigned long long aId);
|
||||||
|
|
||||||
|
static BrowsingContext? getFromWindow(WindowProxy window);
|
||||||
|
|
||||||
BrowsingContext? findChildWithName(DOMString name);
|
BrowsingContext? findChildWithName(DOMString name);
|
||||||
BrowsingContext? findWithName(DOMString name);
|
BrowsingContext? findWithName(DOMString name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,30 +23,31 @@ let seenClick = false;
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv(
|
SpecialPowers.pushPrefEnv(
|
||||||
{ set: [[HACK_PREF, document.domain]] },
|
{ set: [[HACK_PREF, document.domain]] },
|
||||||
SimpleTest.waitForFocus(() => {
|
() => {
|
||||||
// Test seeing the non-primary 'click'
|
SimpleTest.waitForFocus(() => {
|
||||||
document.addEventListener("click", (e) => {
|
// Test seeing the non-primary 'click'
|
||||||
ok(true, "Saw 'click' event");
|
document.addEventListener("click", (e) => {
|
||||||
seenClick = true;
|
ok(true, "Saw 'click' event");
|
||||||
}, { once: true });
|
seenClick = true;
|
||||||
document.addEventListener("auxclick", (e) => {
|
}, { once: true });
|
||||||
ok(true, "Saw 'auxclick' event");
|
document.addEventListener("auxclick", (e) => {
|
||||||
ok(seenClick, "Saw 'click' event before 'auxclick' event");
|
ok(true, "Saw 'auxclick' event");
|
||||||
}, { once: true });
|
ok(seenClick, "Saw 'click' event before 'auxclick' event");
|
||||||
synthesizeMouseAtCenter(testEl, { button: 1 });
|
}, { once: true });
|
||||||
|
synthesizeMouseAtCenter(testEl, { button: 1 });
|
||||||
|
|
||||||
// Test preventDefaulting on non-primary 'click'
|
// Test preventDefaulting on non-primary 'click'
|
||||||
document.addEventListener("click", (e) => {
|
document.addEventListener("click", (e) => {
|
||||||
is(e.target, linkEl, "Saw 'click' on link");
|
is(e.target, linkEl, "Saw 'click' on link");
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}, { once: true, capture: true });
|
}, { once: true, capture: true });
|
||||||
document.addEventListener("auxclick", (e) => {
|
document.addEventListener("auxclick", (e) => {
|
||||||
ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'");
|
ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'");
|
||||||
}, { once: true });
|
}, { once: true });
|
||||||
synthesizeMouseAtCenter(linkEl, { button: 1 });
|
synthesizeMouseAtCenter(linkEl, { button: 1 });
|
||||||
})
|
});
|
||||||
);
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ async function testFullscreenMouseBtn(event, button, next) {
|
||||||
// Restore the pref environment we changed before
|
// Restore the pref environment we changed before
|
||||||
// entering testNonTrustContext.
|
// entering testNonTrustContext.
|
||||||
await SpecialPowers.popPrefEnv();
|
await SpecialPowers.popPrefEnv();
|
||||||
|
await SpecialPowers.popPrefEnv();
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ function onFileOpened(message) {
|
||||||
const elem = document.getElementById("file");
|
const elem = document.getElementById("file");
|
||||||
is(getGlobal(elem), window,
|
is(getGlobal(elem), window,
|
||||||
"getGlobal() works as expected");
|
"getGlobal() works as expected");
|
||||||
isnot(getGlobal(file), window,
|
is(getGlobal(file), window,
|
||||||
"File from MessageManager is wrapped");
|
"File from MessageManager is not wrapped");
|
||||||
SpecialPowers.wrap(elem).mozSetFileArray([file]);
|
SpecialPowers.wrap(elem).mozSetFileArray([file]);
|
||||||
is(getGlobal(elem.files[0]), window,
|
is(getGlobal(elem.files[0]), window,
|
||||||
"File read back from input element is not wrapped");
|
"File read back from input element is not wrapped");
|
||||||
|
|
|
||||||
|
|
@ -12,32 +12,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1414077
|
||||||
|
|
||||||
/** Test for Bug 1414077 **/
|
/** Test for Bug 1414077 **/
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", true]]}, function() {
|
add_task(async function() {
|
||||||
var testWin = document.querySelector("iframe");
|
await SpecialPowers.pushPrefEnv({"set": [["browser.enable_automatic_image_resizing", true]]});
|
||||||
testWin.height = 0;
|
|
||||||
testWin.width = 0;
|
|
||||||
testWin.src = "image.png";
|
|
||||||
testWin.onload = function() {
|
|
||||||
var testDoc = testWin.contentDocument;
|
|
||||||
|
|
||||||
// testDoc should be a image document.
|
return new Promise(resolve => {
|
||||||
ok(testDoc.imageIsOverflowing, "image is overflowing");
|
var testWin = document.querySelector("iframe");
|
||||||
ok(testDoc.imageIsResized, "image is resized to fit visible area by default");
|
testWin.src = "image.png";
|
||||||
|
testWin.onload = function() {
|
||||||
|
var testDoc = testWin.contentDocument;
|
||||||
|
|
||||||
// Restore image to original size.
|
// testDoc should be a image document.
|
||||||
testDoc.restoreImage();
|
ok(testDoc.imageIsOverflowing, "image is overflowing");
|
||||||
ok(testDoc.imageIsOverflowing, "image is overflowing");
|
ok(testDoc.imageIsResized, "image is resized to fit visible area by default");
|
||||||
ok(!testDoc.imageIsResized, "image is restored to original size");
|
|
||||||
|
|
||||||
// Resize the image to fit visible area
|
// Restore image to original size.
|
||||||
testDoc.shrinkToFit();
|
testDoc.restoreImage();
|
||||||
ok(testDoc.imageIsOverflowing, "image is overflowing");
|
ok(testDoc.imageIsOverflowing, "image is overflowing");
|
||||||
ok(testDoc.imageIsResized, "image is resized to fit visible area");
|
ok(!testDoc.imageIsResized, "image is restored to original size");
|
||||||
|
|
||||||
SimpleTest.finish();
|
// Resize the image to fit visible area
|
||||||
};
|
testDoc.shrinkToFit();
|
||||||
|
ok(testDoc.imageIsOverflowing, "image is overflowing");
|
||||||
|
ok(testDoc.imageIsResized, "image is resized to fit visible area");
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -45,6 +47,6 @@ SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", tr
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414077">Mozilla Bug 1414077</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414077">Mozilla Bug 1414077</a>
|
||||||
<iframe></iframe>
|
<iframe width="0" height="0"></iframe>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -888,12 +888,21 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||||
// load in the current process.
|
// load in the current process.
|
||||||
bool loadInDifferentProcess = aForceNoOpener && sNoopenerNewProcess;
|
bool loadInDifferentProcess = aForceNoOpener && sNoopenerNewProcess;
|
||||||
if (aTabOpener && !loadInDifferentProcess && aURI) {
|
if (aTabOpener && !loadInDifferentProcess && aURI) {
|
||||||
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
|
nsCOMPtr<nsILoadContext> context;
|
||||||
rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
|
if (aParent) {
|
||||||
if (NS_SUCCEEDED(rv) && browserChrome3) {
|
context = do_GetInterface(aTabOpener->WebNavigation());
|
||||||
bool shouldLoad;
|
}
|
||||||
rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
|
// Only special-case cross-process loads if Fission is disabled. With
|
||||||
loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
|
// Fission enabled, the initial in-process load will automatically be
|
||||||
|
// retargeted to the correct process.
|
||||||
|
if (!(context && context->UseRemoteSubframes())) {
|
||||||
|
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
|
||||||
|
rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
|
||||||
|
if (NS_SUCCEEDED(rv) && browserChrome3) {
|
||||||
|
bool shouldLoad;
|
||||||
|
rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
|
||||||
|
loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
#include "mozilla/dom/JSWindowActorBinding.h"
|
#include "mozilla/dom/JSWindowActorBinding.h"
|
||||||
#include "mozilla/dom/MessageManagerBinding.h"
|
#include "mozilla/dom/MessageManagerBinding.h"
|
||||||
#include "mozilla/dom/PWindowGlobal.h"
|
#include "mozilla/dom/PWindowGlobal.h"
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "js/Promise.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
@ -35,10 +37,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(JSWindowActor)
|
||||||
|
|
||||||
JSWindowActor::JSWindowActor() : mNextQueryId(0) {}
|
JSWindowActor::JSWindowActor() : mNextQueryId(0) {}
|
||||||
|
|
||||||
nsIGlobalObject* JSWindowActor::GetParentObject() const {
|
|
||||||
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
|
|
||||||
}
|
|
||||||
|
|
||||||
void JSWindowActor::StartDestroy() {
|
void JSWindowActor::StartDestroy() {
|
||||||
DestroyCallback(DestroyCallbackFunction::WillDestroy);
|
DestroyCallback(DestroyCallbackFunction::WillDestroy);
|
||||||
}
|
}
|
||||||
|
|
@ -48,8 +46,7 @@ void JSWindowActor::AfterDestroy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSWindowActor::DestroyCallback(DestroyCallbackFunction callback) {
|
void JSWindowActor::DestroyCallback(DestroyCallbackFunction callback) {
|
||||||
AutoEntryScript aes(xpc::PrivilegedJunkScope(),
|
AutoEntryScript aes(GetParentObject(), "JSWindowActor destroy callback");
|
||||||
"JSWindowActor destroy callback");
|
|
||||||
JSContext* cx = aes.cx();
|
JSContext* cx = aes.cx();
|
||||||
MozActorDestroyCallbacks callbacksHolder;
|
MozActorDestroyCallbacks callbacksHolder;
|
||||||
NS_ENSURE_TRUE_VOID(GetWrapper());
|
NS_ENSURE_TRUE_VOID(GetWrapper());
|
||||||
|
|
@ -91,8 +88,8 @@ void JSWindowActor::SendAsyncMessage(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aTransfers,
|
JS::Handle<JS::Value> aTransfers,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
ipc::StructuredCloneData data;
|
ipc::StructuredCloneData data;
|
||||||
if (!aObj.isUndefined() && !nsFrameMessageManager::GetParamsForMessage(
|
if (!nsFrameMessageManager::GetParamsForMessage(aCx, aObj, aTransfers,
|
||||||
aCx, aObj, aTransfers, data)) {
|
data)) {
|
||||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -109,8 +106,8 @@ already_AddRefed<Promise> JSWindowActor::SendQuery(
|
||||||
JSContext* aCx, const nsAString& aMessageName, JS::Handle<JS::Value> aObj,
|
JSContext* aCx, const nsAString& aMessageName, JS::Handle<JS::Value> aObj,
|
||||||
JS::Handle<JS::Value> aTransfers, ErrorResult& aRv) {
|
JS::Handle<JS::Value> aTransfers, ErrorResult& aRv) {
|
||||||
ipc::StructuredCloneData data;
|
ipc::StructuredCloneData data;
|
||||||
if (!aObj.isUndefined() && !nsFrameMessageManager::GetParamsForMessage(
|
if (!nsFrameMessageManager::GetParamsForMessage(aCx, aObj, aTransfers,
|
||||||
aCx, aObj, aTransfers, data)) {
|
data)) {
|
||||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -140,8 +137,7 @@ already_AddRefed<Promise> JSWindowActor::SendQuery(
|
||||||
|
|
||||||
void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
|
void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
|
||||||
ipc::StructuredCloneData&& aData) {
|
ipc::StructuredCloneData&& aData) {
|
||||||
AutoEntryScript aes(xpc::PrivilegedJunkScope(),
|
AutoEntryScript aes(GetParentObject(), "JSWindowActor message handler");
|
||||||
"JSWindowActor message handler");
|
|
||||||
JSContext* cx = aes.cx();
|
JSContext* cx = aes.cx();
|
||||||
|
|
||||||
// Read the message into a JS object from IPC.
|
// Read the message into a JS object from IPC.
|
||||||
|
|
@ -149,6 +145,11 @@ void JSWindowActor::ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
|
||||||
JS::Rooted<JS::Value> data(cx);
|
JS::Rooted<JS::Value> data(cx);
|
||||||
aData.Read(cx, &data, error);
|
aData.Read(cx, &data, error);
|
||||||
if (NS_WARN_IF(error.Failed())) {
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
MOZ_ASSERT(false, "Should not receive non-decodable data");
|
||||||
|
} else {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(false, "Should not receive non-decodable data");
|
||||||
|
}
|
||||||
MOZ_ALWAYS_TRUE(error.MaybeSetPendingException(cx));
|
MOZ_ALWAYS_TRUE(error.MaybeSetPendingException(cx));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -235,8 +236,15 @@ void JSWindowActor::ReceiveQueryReply(JSContext* aCx,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSAutoRealm ar(aCx, promise->PromiseObj());
|
||||||
|
JS::RootedValue data(aCx, aData);
|
||||||
|
if (NS_WARN_IF(!JS_WrapValue(aCx, &data))) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (aMetadata.kind() == JSWindowActorMessageKind::QueryResolve) {
|
if (aMetadata.kind() == JSWindowActorMessageKind::QueryResolve) {
|
||||||
promise->MaybeResolve(aCx, aData);
|
promise->MaybeResolve(aCx, data);
|
||||||
} else {
|
} else {
|
||||||
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||||
}
|
}
|
||||||
|
|
@ -262,8 +270,9 @@ void JSWindowActor::QueryHandler::RejectedCallback(
|
||||||
Unused << JS::CallOriginalPromiseReject(aCx, aValue);
|
Unused << JS::CallOriginalPromiseReject(aCx, aValue);
|
||||||
|
|
||||||
// The exception probably isn't cloneable, so just send down undefined.
|
// The exception probably isn't cloneable, so just send down undefined.
|
||||||
SendReply(aCx, JSWindowActorMessageKind::QueryReject,
|
ipc::StructuredCloneData data;
|
||||||
ipc::StructuredCloneData());
|
data.Write(aCx, JS::UndefinedHandleValue, IgnoredErrorResult());
|
||||||
|
SendReply(aCx, JSWindowActorMessageKind::QueryReject, std::move(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSWindowActor::QueryHandler::ResolvedCallback(
|
void JSWindowActor::QueryHandler::ResolvedCallback(
|
||||||
|
|
@ -289,8 +298,9 @@ void JSWindowActor::QueryHandler::ResolvedCallback(
|
||||||
|
|
||||||
JS_ClearPendingException(aCx);
|
JS_ClearPendingException(aCx);
|
||||||
|
|
||||||
SendReply(aCx, JSWindowActorMessageKind::QueryReject,
|
ipc::StructuredCloneData data;
|
||||||
ipc::StructuredCloneData());
|
data.Write(aCx, JS::UndefinedHandleValue, IgnoredErrorResult());
|
||||||
|
SendReply(aCx, JSWindowActorMessageKind::QueryReject, std::move(data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class JSWindowActor : public nsISupports, public nsWrapperCache {
|
||||||
void ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
|
void ReceiveRawMessage(const JSWindowActorMessageMeta& aMetadata,
|
||||||
ipc::StructuredCloneData&& aData);
|
ipc::StructuredCloneData&& aData);
|
||||||
|
|
||||||
nsIGlobalObject* GetParentObject() const;
|
virtual nsIGlobalObject* GetParentObject() const = 0;
|
||||||
|
|
||||||
void RejectPendingQueries();
|
void RejectPendingQueries();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
JSWindowActorChild::JSWindowActorChild(nsIGlobalObject* aGlobal)
|
||||||
|
: mGlobal(aGlobal ? aGlobal
|
||||||
|
: xpc::NativeGlobal(xpc::PrivilegedJunkScope())) {}
|
||||||
|
|
||||||
JSWindowActorChild::~JSWindowActorChild() { MOZ_ASSERT(!mManager); }
|
JSWindowActorChild::~JSWindowActorChild() { MOZ_ASSERT(!mManager); }
|
||||||
|
|
||||||
JSObject* JSWindowActorChild::WrapObject(JSContext* aCx,
|
JSObject* JSWindowActorChild::WrapObject(JSContext* aCx,
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,17 @@ class JSWindowActorChild final : public JSWindowActor {
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(JSWindowActorChild,
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(JSWindowActorChild,
|
||||||
JSWindowActor)
|
JSWindowActor)
|
||||||
|
|
||||||
|
explicit JSWindowActorChild(nsIGlobalObject* aGlobal = nullptr);
|
||||||
|
|
||||||
|
nsIGlobalObject* GetParentObject() const override { return mGlobal; }
|
||||||
|
|
||||||
JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
static already_AddRefed<JSWindowActorChild> Constructor(GlobalObject& aGlobal,
|
static already_AddRefed<JSWindowActorChild> Constructor(GlobalObject& aGlobal,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
return MakeAndAddRef<JSWindowActorChild>();
|
nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(aGlobal.GetAsSupports()));
|
||||||
|
return MakeAndAddRef<JSWindowActorChild>(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowGlobalChild* GetManager() const;
|
WindowGlobalChild* GetManager() const;
|
||||||
|
|
@ -64,6 +69,8 @@ class JSWindowActorChild final : public JSWindowActor {
|
||||||
|
|
||||||
bool mCanSend = true;
|
bool mCanSend = true;
|
||||||
RefPtr<WindowGlobalChild> mManager;
|
RefPtr<WindowGlobalChild> mManager;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ namespace dom {
|
||||||
|
|
||||||
JSWindowActorParent::~JSWindowActorParent() { MOZ_ASSERT(!mManager); }
|
JSWindowActorParent::~JSWindowActorParent() { MOZ_ASSERT(!mManager); }
|
||||||
|
|
||||||
|
nsIGlobalObject* JSWindowActorParent::GetParentObject() const {
|
||||||
|
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
|
||||||
|
}
|
||||||
|
|
||||||
JSObject* JSWindowActorParent::WrapObject(JSContext* aCx,
|
JSObject* JSWindowActorParent::WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) {
|
JS::Handle<JSObject*> aGivenProto) {
|
||||||
return JSWindowActorParent_Binding::Wrap(aCx, this, aGivenProto);
|
return JSWindowActorParent_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ class JSWindowActorParent final : public JSWindowActor {
|
||||||
return MakeAndAddRef<JSWindowActorParent>();
|
return MakeAndAddRef<JSWindowActorParent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIGlobalObject* GetParentObject() const override;
|
||||||
|
|
||||||
WindowGlobalParent* GetManager() const;
|
WindowGlobalParent* GetManager() const;
|
||||||
void Init(const nsAString& aName, WindowGlobalParent* aManager);
|
void Init(const nsAString& aName, WindowGlobalParent* aManager);
|
||||||
void StartDestroy();
|
void StartDestroy();
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ var tests = [
|
||||||
{
|
{
|
||||||
keySystem: "com.widevine.alpha",
|
keySystem: "com.widevine.alpha",
|
||||||
expectedStatus: 'cdm-not-installed',
|
expectedStatus: 'cdm-not-installed',
|
||||||
prefs: [["media.eme.enabled", true], , ["media.gmp-widevinecdm.enabled", true]]
|
prefs: [["media.eme.enabled", true], ["media.gmp-widevinecdm.enabled", true]]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
keySystem: CLEARKEY_KEYSYSTEM,
|
keySystem: CLEARKEY_KEYSYSTEM,
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ function startTest(test, token) {
|
||||||
createMedia(test.type, test.name, token);
|
createMedia(test.type, test.name, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
createTestArray().then(testArray => {
|
createTestArray().then(testArray => {
|
||||||
manager.runTests(testArray, startTest);
|
manager.runTests(testArray, startTest);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ var NotificationTest = (function() {
|
||||||
function setup_testing_env() {
|
function setup_testing_env() {
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
// turn on testing pref (used by notification.cpp, and mock the alerts
|
// turn on testing pref (used by notification.cpp, and mock the alerts
|
||||||
SpecialPowers.setBoolPref("notification.prompt.testing", true);
|
return SpecialPowers.setBoolPref("notification.prompt.testing", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function teardown_testing_env() {
|
async function teardown_testing_env() {
|
||||||
SpecialPowers.clearUserPref("notification.prompt.testing");
|
await SpecialPowers.clearUserPref("notification.prompt.testing");
|
||||||
SpecialPowers.clearUserPref("notification.prompt.testing.allow");
|
await SpecialPowers.clearUserPref("notification.prompt.testing.allow");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
@ -78,9 +78,10 @@ var NotificationTest = (function() {
|
||||||
// NotificationTest API
|
// NotificationTest API
|
||||||
return {
|
return {
|
||||||
run(tests, callback) {
|
run(tests, callback) {
|
||||||
setup_testing_env();
|
let ready = setup_testing_env();
|
||||||
|
|
||||||
addLoadEvent(function() {
|
addLoadEvent(async function() {
|
||||||
|
await ready;
|
||||||
executeTests(tests, function() {
|
executeTests(tests, function() {
|
||||||
teardown_testing_env();
|
teardown_testing_env();
|
||||||
callback && callback();
|
callback && callback();
|
||||||
|
|
@ -89,11 +90,11 @@ var NotificationTest = (function() {
|
||||||
},
|
},
|
||||||
|
|
||||||
allowNotifications() {
|
allowNotifications() {
|
||||||
SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
|
return SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
|
||||||
},
|
},
|
||||||
|
|
||||||
denyNotifications() {
|
denyNotifications() {
|
||||||
SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
|
return SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
|
||||||
},
|
},
|
||||||
|
|
||||||
clickNotification(notification) {
|
clickNotification(notification) {
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@
|
||||||
Notification.requestPermission();
|
Notification.requestPermission();
|
||||||
},
|
},
|
||||||
|
|
||||||
function(done) {
|
async function(done) {
|
||||||
info("Test requestPermission deny");
|
info("Test requestPermission deny");
|
||||||
function assertPermissionDenied(perm) {
|
function assertPermissionDenied(perm) {
|
||||||
is(perm, "denied", "Permission should be denied.");
|
is(perm, "denied", "Permission should be denied.");
|
||||||
is(Notification.permission, "denied", "Permission should be denied.");
|
is(Notification.permission, "denied", "Permission should be denied.");
|
||||||
}
|
}
|
||||||
NotificationTest.denyNotifications();
|
await NotificationTest.denyNotifications();
|
||||||
Notification.requestPermission()
|
Notification.requestPermission()
|
||||||
.then(assertPermissionDenied)
|
.then(assertPermissionDenied)
|
||||||
.then(_ => Notification.requestPermission(assertPermissionDenied))
|
.then(_ => Notification.requestPermission(assertPermissionDenied))
|
||||||
|
|
@ -48,13 +48,13 @@
|
||||||
.then(done);
|
.then(done);
|
||||||
},
|
},
|
||||||
|
|
||||||
function(done) {
|
async function(done) {
|
||||||
info("Test requestPermission grant");
|
info("Test requestPermission grant");
|
||||||
function assertPermissionGranted(perm) {
|
function assertPermissionGranted(perm) {
|
||||||
is(perm, "granted", "Permission should be granted.");
|
is(perm, "granted", "Permission should be granted.");
|
||||||
is(Notification.permission, "granted", "Permission should be granted");
|
is(Notification.permission, "granted", "Permission should be granted");
|
||||||
}
|
}
|
||||||
NotificationTest.allowNotifications();
|
await NotificationTest.allowNotifications();
|
||||||
Notification.requestPermission()
|
Notification.requestPermission()
|
||||||
.then(assertPermissionGranted)
|
.then(assertPermissionGranted)
|
||||||
.then(_ => Notification.requestPermission(assertPermissionGranted))
|
.then(_ => Notification.requestPermission(assertPermissionGranted))
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1429432
|
||||||
response = await Notification.requestPermission();
|
response = await Notification.requestPermission();
|
||||||
is(response, "granted", "Granted permission in insecure context with pref set");
|
is(response, "granted", "Granted permission in insecure context with pref set");
|
||||||
|
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
script.destroy();
|
script.destroy();
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
|
||||||
|
|
@ -130,9 +130,9 @@
|
||||||
const permission = 'geolocation';
|
const permission = 'geolocation';
|
||||||
const promiseGranted = this.promiseStateChanged(permission, 'granted');
|
const promiseGranted = this.promiseStateChanged(permission, 'granted');
|
||||||
this.setPermissions(ALLOW_ACTION);
|
this.setPermissions(ALLOW_ACTION);
|
||||||
promiseGranted.then(() => {
|
promiseGranted.then(async () => {
|
||||||
const promisePrompt = this.promiseStateChanged(permission, 'prompt');
|
const promisePrompt = this.promiseStateChanged(permission, 'prompt');
|
||||||
SpecialPowers.popPermissions();
|
await SpecialPowers.popPermissions();
|
||||||
return promisePrompt;
|
return promisePrompt;
|
||||||
}).then(resolve);
|
}).then(resolve);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,11 @@ function waitScrollFinish(aTarget) {
|
||||||
*/
|
*/
|
||||||
function setTestPluginEnabledState(aState, aPluginName) {
|
function setTestPluginEnabledState(aState, aPluginName) {
|
||||||
let name = aPluginName || "Test Plug-in";
|
let name = aPluginName || "Test Plug-in";
|
||||||
SpecialPowers.setTestPluginEnabledState(aState, name);
|
let resolved = false;
|
||||||
|
SpecialPowers.setTestPluginEnabledState(aState, name).then(() => {
|
||||||
|
resolved = true;
|
||||||
|
});
|
||||||
|
SpecialPowers.Services.tm.spinEventLoopUntil(() => resolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ function setTestPluginEnabledState(newEnabledState, pluginName) {
|
||||||
SpecialPowers.Services.tm.spinEventLoopUntil(() => {
|
SpecialPowers.Services.tm.spinEventLoopUntil(() => {
|
||||||
return plugin.enabledState == newEnabledState;
|
return plugin.enabledState == newEnabledState;
|
||||||
});
|
});
|
||||||
SimpleTest.registerCleanupFunction(function() {
|
SimpleTest.registerCleanupFunction(async function() {
|
||||||
SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName);
|
return SpecialPowers.setTestPluginEnabledState(await oldEnabledState, pluginName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
function addPerms() {
|
|
||||||
ok(SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Shockwave Flash"), "Should find allowed test flash plugin");
|
|
||||||
ok(!SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Third Test Plug-in"), "Should not find disallowed plugin");
|
|
||||||
SpecialPowers.pushPermissions([{type: "plugin:flash", allow: true, context: document}], run);
|
|
||||||
}
|
|
||||||
|
|
||||||
function findPlugin(pluginName) {
|
function findPlugin(pluginName) {
|
||||||
for (var i = 0; i < navigator.plugins.length; i++) {
|
for (var i = 0; i < navigator.plugins.length; i++) {
|
||||||
|
|
@ -45,7 +40,13 @@
|
||||||
document.body.appendChild(obj);
|
document.body.appendChild(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
async function run() {
|
||||||
|
ok(await SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Shockwave Flash"), "Should find allowed test flash plugin");
|
||||||
|
ok(!await SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Third Test Plug-in"), "Should not find disallowed plugin");
|
||||||
|
await new Promise(resolve => {
|
||||||
|
SpecialPowers.pushPermissions([{type: "plugin:flash", allow: true, context: document}], resolve);
|
||||||
|
});
|
||||||
|
|
||||||
createNode("plugin-flash", "application/x-shockwave-flash-test");
|
createNode("plugin-flash", "application/x-shockwave-flash-test");
|
||||||
createNode("disallowedPlugin", "application/x-third-test");
|
createNode("disallowedPlugin", "application/x-third-test");
|
||||||
var pluginElement = document.getElementById("plugin-flash");
|
var pluginElement = document.getElementById("plugin-flash");
|
||||||
|
|
@ -70,6 +71,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<body onload="addPerms()">
|
<body onload="run()">
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
</body>
|
</body>
|
||||||
<script class="testbody" type="application/javascript">
|
<script class="testbody" type="application/javascript">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.expectChildProcessCrash();
|
SimpleTest.expectChildProcessCrash();
|
||||||
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
||||||
|
|
@ -89,9 +91,9 @@ function finishTest() {
|
||||||
os.removeObserver(testObserver, "plugin-crashed");
|
os.removeObserver(testObserver, "plugin-crashed");
|
||||||
--obsCount;
|
--obsCount;
|
||||||
}
|
}
|
||||||
SpecialPowers.clearUserPref(hangUITimeoutPref);
|
Services.prefs.clearUserPref(hangUITimeoutPref);
|
||||||
SpecialPowers.clearUserPref(hangUIMinDisplayPref);
|
Services.prefs.clearUserPref(hangUIMinDisplayPref);
|
||||||
SpecialPowers.clearUserPref(timeoutPref);
|
Services.prefs.clearUserPref(timeoutPref);
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,9 +153,9 @@ function test9b() {
|
||||||
|
|
||||||
function test9a() {
|
function test9a() {
|
||||||
resetVars();
|
resetVars();
|
||||||
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
Services.prefs.setIntPref(hangUITimeoutPref, 1);
|
||||||
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
|
Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
|
||||||
SpecialPowers.setIntPref(timeoutPref, 45);
|
Services.prefs.setIntPref(timeoutPref, 45);
|
||||||
hanguiContinue("test9a: Continue button works with checkbox", true, "test9b");
|
hanguiContinue("test9a: Continue button works with checkbox", true, "test9b");
|
||||||
p.stall(STALL_DURATION);
|
p.stall(STALL_DURATION);
|
||||||
}
|
}
|
||||||
|
|
@ -165,8 +167,8 @@ function test9() {
|
||||||
|
|
||||||
function test8a() {
|
function test8a() {
|
||||||
resetVars();
|
resetVars();
|
||||||
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
Services.prefs.setIntPref(hangUITimeoutPref, 1);
|
||||||
SpecialPowers.setIntPref(hangUIMinDisplayPref, 4);
|
Services.prefs.setIntPref(hangUIMinDisplayPref, 4);
|
||||||
hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9");
|
hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9");
|
||||||
var exceptionThrown = false;
|
var exceptionThrown = false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -184,7 +186,7 @@ function test8() {
|
||||||
|
|
||||||
function test7a() {
|
function test7a() {
|
||||||
resetVars();
|
resetVars();
|
||||||
SpecialPowers.setIntPref(hangUITimeoutPref, 0);
|
Services.prefs.setIntPref(hangUITimeoutPref, 0);
|
||||||
hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8");
|
hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8");
|
||||||
var exceptionThrown = false;
|
var exceptionThrown = false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -201,9 +203,9 @@ function test7() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function test6() {
|
function test6() {
|
||||||
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
Services.prefs.setIntPref(hangUITimeoutPref, 1);
|
||||||
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
|
Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
|
||||||
SpecialPowers.setIntPref(timeoutPref, 3);
|
Services.prefs.setIntPref(timeoutPref, 3);
|
||||||
hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7");
|
hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7");
|
||||||
var exceptionThrown = false;
|
var exceptionThrown = false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -250,9 +252,9 @@ function test2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function test1() {
|
function test1() {
|
||||||
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
Services.prefs.setIntPref(hangUITimeoutPref, 1);
|
||||||
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
|
Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
|
||||||
SpecialPowers.setIntPref(timeoutPref, 45);
|
Services.prefs.setIntPref(timeoutPref, 45);
|
||||||
hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2");
|
hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2");
|
||||||
p.stall(STALL_DURATION);
|
p.stall(STALL_DURATION);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,14 @@ function testSetup() {
|
||||||
function testInitialUnavailable() {
|
function testInitialUnavailable() {
|
||||||
request = new PresentationRequest("https://example.com");
|
request = new PresentationRequest("https://example.com");
|
||||||
|
|
||||||
return request.getAvailability().then(function(aAvailability) {
|
return request.getAvailability().then(async function(aAvailability) {
|
||||||
is(aAvailability.value, false, "Should have no available device after setup");
|
is(aAvailability.value, false, "Should have no available device after setup");
|
||||||
aAvailability.onchange = function() {
|
aAvailability.onchange = function() {
|
||||||
aAvailability.onchange = null;
|
aAvailability.onchange = null;
|
||||||
ok(aAvailability.value, "Device should be available.");
|
ok(aAvailability.value, "Device should be available.");
|
||||||
};
|
};
|
||||||
availability = aAvailability;
|
availability = aAvailability;
|
||||||
gScript.sendAsyncMessage("trigger-device-add", testDevice);
|
await gScript.sendQuery("trigger-device-add", testDevice);
|
||||||
}).catch(function(aError) {
|
}).catch(function(aError) {
|
||||||
ok(false, "Error occurred when getting availability: " + aError);
|
ok(false, "Error occurred when getting availability: " + aError);
|
||||||
teardown();
|
teardown();
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ let currentMockSocket = null;
|
||||||
function setupMockPushSocket(mockWebSocket) {
|
function setupMockPushSocket(mockWebSocket) {
|
||||||
currentMockSocket = mockWebSocket;
|
currentMockSocket = mockWebSocket;
|
||||||
currentMockSocket._isActive = true;
|
currentMockSocket._isActive = true;
|
||||||
chromeScript.sendSyncMessage("socket-setup");
|
chromeScript.sendAsyncMessage("socket-setup");
|
||||||
chromeScript.addMessageListener("socket-client-msg", function(msg) {
|
chromeScript.addMessageListener("socket-client-msg", function(msg) {
|
||||||
mockWebSocket.handleMessage(msg);
|
mockWebSocket.handleMessage(msg);
|
||||||
});
|
});
|
||||||
|
|
@ -73,7 +73,7 @@ function teardownMockPushSocket() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
currentMockSocket._isActive = false;
|
currentMockSocket._isActive = false;
|
||||||
chromeScript.addMessageListener("socket-server-teardown", resolve);
|
chromeScript.addMessageListener("socket-server-teardown", resolve);
|
||||||
chromeScript.sendSyncMessage("socket-teardown");
|
chromeScript.sendAsyncMessage("socket-teardown");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
|
||||||
}
|
}
|
||||||
|
|
||||||
var secureTestsStarted = false;
|
var secureTestsStarted = false;
|
||||||
function checkTestsCompleted() {
|
async function checkTestsCompleted() {
|
||||||
for (var prop in testsToRunInsecure) {
|
for (var prop in testsToRunInsecure) {
|
||||||
// some test hasn't run yet so we're not done
|
// some test hasn't run yet so we're not done
|
||||||
if (!testsToRunInsecure[prop])
|
if (!testsToRunInsecure[prop])
|
||||||
|
|
@ -60,7 +60,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
|
||||||
}
|
}
|
||||||
//call to change the preferences
|
//call to change the preferences
|
||||||
counter++;
|
counter++;
|
||||||
SpecialPowers.setBoolPref("security.mixed_content.block_active_content", false);
|
await SpecialPowers.setBoolPref("security.mixed_content.block_active_content", false);
|
||||||
blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content");
|
blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content");
|
||||||
log("blockActive set to "+blockActive+".");
|
log("blockActive set to "+blockActive+".");
|
||||||
secureTestsStarted = false;
|
secureTestsStarted = false;
|
||||||
|
|
|
||||||
|
|
@ -64,68 +64,65 @@
|
||||||
return Promise.all(unregisterArray);
|
return Promise.all(unregisterArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testScopes() {
|
async function testScopes() {
|
||||||
return new Promise(function(resolve, reject) {
|
function chromeScriptSource() {
|
||||||
function chromeScriptSource() {
|
let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
|
||||||
let swm = Cc["@mozilla.org/serviceworkers/manager;1"]
|
.getService(Ci.nsIServiceWorkerManager);
|
||||||
.getService(Ci.nsIServiceWorkerManager);
|
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
.getService(Ci.nsIScriptSecurityManager);
|
||||||
.getService(Ci.nsIScriptSecurityManager);
|
addMessageListener("getScope", (msg) => {
|
||||||
addMessageListener("getScope", (msg) => {
|
let principal = secMan.createCodebasePrincipalFromOrigin(msg.principal);
|
||||||
let principal = secMan.createCodebasePrincipalFromOrigin(msg.principal);
|
|
||||||
try {
|
|
||||||
return { scope: swm.getScopeForUrl(principal, msg.path) };
|
|
||||||
} catch (e) {
|
|
||||||
return { exception: e.message };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let getScope;
|
|
||||||
let parent_intercept_enabled =
|
|
||||||
SpecialPowers.getBoolPref("dom.serviceWorkers.parent_intercept");
|
|
||||||
|
|
||||||
if (parent_intercept_enabled) {
|
|
||||||
let chromeScript = SpecialPowers.loadChromeScript(chromeScriptSource);
|
|
||||||
let docPrincipal = SpecialPowers.wrap(document).nodePrincipal.URI.spec;
|
|
||||||
|
|
||||||
getScope = (path) => {
|
|
||||||
let rv = chromeScript.sendSyncMessage("getScope", { principal: docPrincipal, path })[0][0];
|
|
||||||
if (rv.exception)
|
|
||||||
throw rv.exception;
|
|
||||||
return rv.scope;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
getScope = navigator.serviceWorker.getScopeForUrl.bind(navigator.serviceWorker);
|
|
||||||
}
|
|
||||||
|
|
||||||
var base = new URL(".", document.baseURI);
|
|
||||||
|
|
||||||
function p(s) {
|
|
||||||
return base + s;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fail(fn) {
|
|
||||||
try {
|
try {
|
||||||
getScope(p("index.html"));
|
return { scope: swm.getScopeForUrl(principal, msg.path) };
|
||||||
ok(false, "No registration");
|
} catch (e) {
|
||||||
} catch(e) {
|
return { exception: e.message };
|
||||||
ok(true, "No registration");
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
is(getScope(p("sub.html")), p("sub"), "Scope should match");
|
let getScope;
|
||||||
is(getScope(p("sub/dir.html")), p("sub/dir.html"), "Scope should match");
|
let parent_intercept_enabled =
|
||||||
is(getScope(p("sub/dir")), p("sub/dir"), "Scope should match");
|
SpecialPowers.getBoolPref("dom.serviceWorkers.parent_intercept");
|
||||||
is(getScope(p("sub/dir/foo")), p("sub/dir/"), "Scope should match");
|
|
||||||
is(getScope(p("sub/dir/afoo")), p("sub/dir/a"), "Scope should match");
|
if (parent_intercept_enabled) {
|
||||||
is(getScope(p("star*wars")), p("star*"), "Scope should match");
|
let chromeScript = SpecialPowers.loadChromeScript(chromeScriptSource);
|
||||||
is(getScope(p("scope/some_file.html")), p("scope/"), "Scope should match");
|
let docPrincipal = SpecialPowers.wrap(document).nodePrincipal.URI.spec;
|
||||||
fail("index.html");
|
|
||||||
fail("sua.html");
|
getScope = async (path) => {
|
||||||
fail("star/a.html");
|
let rv = await chromeScript.sendQuery("getScope", { principal: docPrincipal, path });
|
||||||
resolve();
|
if (rv.exception)
|
||||||
});
|
throw rv.exception;
|
||||||
|
return rv.scope;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
getScope = navigator.serviceWorker.getScopeForUrl.bind(navigator.serviceWorker);
|
||||||
|
}
|
||||||
|
|
||||||
|
var base = new URL(".", document.baseURI);
|
||||||
|
|
||||||
|
function p(s) {
|
||||||
|
return base + s;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fail(fn) {
|
||||||
|
try {
|
||||||
|
await getScope(p("index.html"));
|
||||||
|
ok(false, "No registration");
|
||||||
|
} catch(e) {
|
||||||
|
ok(true, "No registration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is(await getScope(p("sub.html")), p("sub"), "Scope should match");
|
||||||
|
is(await getScope(p("sub/dir.html")), p("sub/dir.html"), "Scope should match");
|
||||||
|
is(await getScope(p("sub/dir")), p("sub/dir"), "Scope should match");
|
||||||
|
is(await getScope(p("sub/dir/foo")), p("sub/dir/"), "Scope should match");
|
||||||
|
is(await getScope(p("sub/dir/afoo")), p("sub/dir/a"), "Scope should match");
|
||||||
|
is(await getScope(p("star*wars")), p("star*"), "Scope should match");
|
||||||
|
is(await getScope(p("scope/some_file.html")), p("scope/"), "Scope should match");
|
||||||
|
await fail("index.html");
|
||||||
|
await fail("sua.html");
|
||||||
|
await fail("star/a.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,13 @@ let chromeScript = SpecialPowers.loadChromeScript(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let chromeBuildID = chromeScript.sendSyncMessage("test:getBuildID")[0][0];
|
async function onMozillaIFrameLoaded() {
|
||||||
chromeScript.destroy();
|
let chromeBuildID = await chromeScript.sendQuery("test:getBuildID");
|
||||||
|
chromeScript.destroy();
|
||||||
|
|
||||||
ok(+chromeBuildID > LEGACY_BUILD_ID,
|
ok(+chromeBuildID > LEGACY_BUILD_ID,
|
||||||
`navigator.buildID should be exposed in chrome - got "${chromeBuildID}"`);
|
`navigator.buildID should be exposed in chrome - got "${chromeBuildID}"`);
|
||||||
|
|
||||||
function onMozillaIFrameLoaded() {
|
|
||||||
//
|
//
|
||||||
// Access navigator.buildID from mozilla.org.
|
// Access navigator.buildID from mozilla.org.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<iframe src="about:blank"></iframe>
|
<iframe src="about:blank"></iframe>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
function checkForFindDialog() {
|
async function checkForFindDialog() {
|
||||||
let chromeScript = SpecialPowers.loadChromeScript(_ => {
|
let chromeScript = SpecialPowers.loadChromeScript(_ => {
|
||||||
addMessageListener("test:check", () => {
|
addMessageListener("test:check", () => {
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let sawFind = chromeScript.sendSyncMessage("test:check")[0][0];
|
let sawFind = await chromeScript.sendQuery("test:check");
|
||||||
chromeScript.destroy();
|
chromeScript.destroy();
|
||||||
return sawFind;
|
return sawFind;
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
"Should return false and not show a dialog if we pass an empty string.");
|
"Should return false and not show a dialog if we pass an empty string.");
|
||||||
|
|
||||||
// Double check to ensure that the parent didn't open a find dialog
|
// Double check to ensure that the parent didn't open a find dialog
|
||||||
let sawWindow = checkForFindDialog();
|
let sawWindow = await checkForFindDialog();
|
||||||
ok(!sawWindow, "Should never have seen the dialog.");
|
ok(!sawWindow, "Should never have seen the dialog.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@
|
||||||
var SimpleTest = opener.wrappedJSObject.SimpleTest;
|
var SimpleTest = opener.wrappedJSObject.SimpleTest;
|
||||||
var ok = opener.wrappedJSObject.ok;
|
var ok = opener.wrappedJSObject.ok;
|
||||||
|
|
||||||
var doc = frames[0].document;
|
// Note: We can't use frames[0] here because the type="content" attribute
|
||||||
|
// isolates it into a separate browsing context hierarchy.
|
||||||
|
var doc = document.querySelector("iframe").contentDocument;
|
||||||
ok(doc.createElement("body") instanceof HTMLBodyElement,
|
ok(doc.createElement("body") instanceof HTMLBodyElement,
|
||||||
"Should be instance of HTMLBodyElement");
|
"Should be instance of HTMLBodyElement");
|
||||||
ok(doc.createElement("div") instanceof HTMLDivElement,
|
ok(doc.createElement("div") instanceof HTMLDivElement,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ window.onload = function() {
|
||||||
myLoadTime = performance.now();
|
myLoadTime = performance.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({"set":[["dom.background_loading_iframe", true]]}, function () {
|
SpecialPowers.pushPrefEnv({"set":[["dom.background_loading_iframe", true]]}).then(function () {
|
||||||
var iframe1 = document.createElement("iframe");
|
var iframe1 = document.createElement("iframe");
|
||||||
var iframe2 = document.createElement("iframe");
|
var iframe2 = document.createElement("iframe");
|
||||||
var iframe3 = document.createElement("iframe");
|
var iframe3 = document.createElement("iframe");
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
var GamepadService;
|
var GamepadService;
|
||||||
|
|
||||||
function setGamepadPreferenceAndCreateIframe(iframeSrc) {
|
async function setGamepadPreferenceAndCreateIframe(iframeSrc) {
|
||||||
SpecialPowers.pushPrefEnv({"set" : [["dom.gamepad.test.enabled", true]]}, () => {
|
await SpecialPowers.pushPrefEnv({"set" : [["dom.gamepad.test.enabled", true]]});
|
||||||
let iframe = document.createElement("iframe");
|
|
||||||
iframe.src = iframeSrc;
|
let iframe = document.createElement("iframe");
|
||||||
document.body.appendChild(iframe);
|
iframe.src = iframeSrc;
|
||||||
});
|
document.body.appendChild(iframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
function runGamepadTest (callback) {
|
function runGamepadTest (callback) {
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@ function pressButton() {
|
||||||
GamepadService.newButtonEvent(gamepad_index, 0, false, false);
|
GamepadService.newButtonEvent(gamepad_index, 0, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startTest() {
|
async function startTest() {
|
||||||
SpecialPowers.pushPrefEnv({ "set": [
|
await SpecialPowers.pushPrefEnv({ "set": [
|
||||||
["dom.gamepad.extensions.enabled", true],
|
["dom.gamepad.extensions.enabled", true],
|
||||||
["dom.gamepad.extensions.lightindicator", true],
|
["dom.gamepad.extensions.lightindicator", true],
|
||||||
["dom.gamepad.extensions.multitouch", true]] });
|
["dom.gamepad.extensions.multitouch", true]] });
|
||||||
// Add a gamepad
|
// Add a gamepad
|
||||||
GamepadService.addGamepad("test gamepad", // id
|
GamepadService.addGamepad("test gamepad", // id
|
||||||
GamepadService.standardMapping,
|
GamepadService.standardMapping,
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,14 @@ function pressButton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let frames_loaded = 0;
|
let frames_loaded = 0;
|
||||||
function startTest() {
|
async function startTest() {
|
||||||
frames_loaded++;
|
frames_loaded++;
|
||||||
SpecialPowers.pushPrefEnv({ "set": [
|
let promise = SpecialPowers.pushPrefEnv({ "set": [
|
||||||
["dom.gamepad.extensions.enabled", true],
|
["dom.gamepad.extensions.enabled", true],
|
||||||
["dom.gamepad.extensions.lightindicator", true],
|
["dom.gamepad.extensions.lightindicator", true],
|
||||||
["dom.gamepad.extensions.multitouch", true]] });
|
["dom.gamepad.extensions.multitouch", true]] });
|
||||||
if (frames_loaded == 2) {
|
if (frames_loaded == 2) {
|
||||||
|
await promise;
|
||||||
// Add a gamepad
|
// Add a gamepad
|
||||||
GamepadService.addGamepad("test gamepad", // id
|
GamepadService.addGamepad("test gamepad", // id
|
||||||
GamepadService.standardMapping,
|
GamepadService.standardMapping,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ function runTest() {
|
||||||
prompt("summary", "text");
|
prompt("summary", "text");
|
||||||
info("prompt is closed");
|
info("prompt is closed");
|
||||||
|
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ async function setup() {
|
||||||
winUtils.advanceTimeAndRefresh(100);
|
winUtils.advanceTimeAndRefresh(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function* runTests() {
|
async function* runTests() {
|
||||||
var e = document.getElementById("edit");
|
var e = document.getElementById("edit");
|
||||||
var doc = e.contentDocument;
|
var doc = e.contentDocument;
|
||||||
var win = e.contentWindow;
|
var win = e.contentWindow;
|
||||||
|
|
@ -181,9 +181,9 @@ function* runTests() {
|
||||||
is(testPageSelectCommand("cmd_selectPageUp", 0), 22 - lineNum, "cmd_selectPageUp");
|
is(testPageSelectCommand("cmd_selectPageUp", 0), 22 - lineNum, "cmd_selectPageUp");
|
||||||
};
|
};
|
||||||
|
|
||||||
yield SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]});
|
await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]});
|
||||||
runSelectionTests(body, 1);
|
runSelectionTests(body, 1);
|
||||||
yield SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]});
|
await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]});
|
||||||
runSelectionTests(node(2), 0);
|
runSelectionTests(node(2), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ async function testRunner() {
|
||||||
let curTest = runTests();
|
let curTest = runTests();
|
||||||
while (true) {
|
while (true) {
|
||||||
winUtils.advanceTimeAndRefresh(100);
|
winUtils.advanceTimeAndRefresh(100);
|
||||||
if (curTest.next().done) {
|
if ((await curTest.next()).done) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
winUtils.advanceTimeAndRefresh(100);
|
winUtils.advanceTimeAndRefresh(100);
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ var tests = [
|
||||||
var loadCount = 0;
|
var loadCount = 0;
|
||||||
var script;
|
var script;
|
||||||
|
|
||||||
var loadListener = function(evt) {
|
var loadListener = async function(evt) {
|
||||||
if (loadCount == 0) {
|
if (loadCount == 0) {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
|
|
@ -86,7 +86,7 @@ var loadListener = function(evt) {
|
||||||
hunspell.removeDirectory(de_DE);
|
hunspell.removeDirectory(de_DE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var existenceChecks = script.sendSyncMessage("check-existence")[0][0];
|
var existenceChecks = await script.sendQuery("check-existence");
|
||||||
is(existenceChecks[0], true, "true expected (en-GB directory should exist)");
|
is(existenceChecks[0], true, "true expected (en-GB directory should exist)");
|
||||||
is(existenceChecks[1], true, "true expected (en-AU directory should exist)");
|
is(existenceChecks[1], true, "true expected (en-AU directory should exist)");
|
||||||
is(existenceChecks[2], true, "true expected (de-DE directory should exist)");
|
is(existenceChecks[2], true, "true expected (de-DE directory should exist)");
|
||||||
|
|
@ -124,7 +124,7 @@ function continueTest(evt) {
|
||||||
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1200533_subframe.html?firstload=false";
|
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1200533_subframe.html?firstload=false";
|
||||||
} else {
|
} else {
|
||||||
// Remove the fake dictionaries again, since it's otherwise picked up by later tests.
|
// Remove the fake dictionaries again, since it's otherwise picked up by later tests.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ var content = document.getElementById("content");
|
||||||
var firstLoad = true;
|
var firstLoad = true;
|
||||||
var script;
|
var script;
|
||||||
|
|
||||||
var loadListener = function(evt) {
|
var loadListener = async function(evt) {
|
||||||
if (firstLoad) {
|
if (firstLoad) {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
|
|
@ -53,7 +53,7 @@ var loadListener = function(evt) {
|
||||||
addMessageListener("en_GB-exists", () => en_GB.exists());
|
addMessageListener("en_GB-exists", () => en_GB.exists());
|
||||||
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
|
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
|
||||||
});
|
});
|
||||||
is(script.sendSyncMessage("en_GB-exists")[0][0], true,
|
is(await script.sendQuery("en_GB-exists"), true,
|
||||||
"true expected (en-GB directory should exist)");
|
"true expected (en-GB directory should exist)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ var loadListener = function(evt) {
|
||||||
content.removeEventListener("load", loadListener);
|
content.removeEventListener("load", loadListener);
|
||||||
|
|
||||||
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
|
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
// Reset the preference, so the last value we set doesn't collide with the next test.
|
// Reset the preference, so the last value we set doesn't collide with the next test.
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ var onSpellCheck =
|
||||||
|
|
||||||
/** Test for Bug 1205983 **/
|
/** Test for Bug 1205983 **/
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.waitForFocus(function() {
|
SimpleTest.waitForFocus(async function() {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
// eslint-disable-next-line mozilla/use-services
|
// eslint-disable-next-line mozilla/use-services
|
||||||
|
|
@ -57,7 +57,7 @@ SimpleTest.waitForFocus(function() {
|
||||||
addMessageListener("de_DE-exists", () => de_DE.exists());
|
addMessageListener("de_DE-exists", () => de_DE.exists());
|
||||||
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
|
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
|
||||||
});
|
});
|
||||||
is(script.sendSyncMessage("de_DE-exists")[0][0], true,
|
is(await script.sendQuery("de_DE-exists"), true,
|
||||||
"true expected (de_DE directory should exist)");
|
"true expected (de_DE directory should exist)");
|
||||||
|
|
||||||
document.getElementById("de-DE").focus();
|
document.getElementById("de-DE").focus();
|
||||||
|
|
@ -106,7 +106,7 @@ function enFocus() {
|
||||||
is(sel.toString(), "German", "one misspelled word expected: German");
|
is(sel.toString(), "German", "one misspelled word expected: German");
|
||||||
|
|
||||||
// Remove the fake de_DE dictionary again.
|
// Remove the fake de_DE dictionary again.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
|
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
|
||||||
elem_de.onfocus = null;
|
elem_de.onfocus = null;
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,13 @@ var onSpellCheck =
|
||||||
"resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
|
"resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.waitForFocus(function() {
|
SimpleTest.waitForFocus(async function() {
|
||||||
/* global browserElement */
|
/* global actorParent */
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
var chromeWin = browserElement.ownerGlobal.docShell
|
var chromeWin = actorParent.rootFrameLoader
|
||||||
.rootTreeItem.domWindow
|
.ownerElement.ownerGlobal.docShell
|
||||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
.rootTreeItem.domWindow;
|
||||||
var contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
|
var contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
|
||||||
contextMenu.addEventListener("popupshown",
|
contextMenu.addEventListener("popupshown",
|
||||||
() => sendAsyncMessage("popupshown"));
|
() => sendAsyncMessage("popupshown"));
|
||||||
|
|
@ -85,9 +85,9 @@ SimpleTest.waitForFocus(function() {
|
||||||
addMessageListener("contextMenu-not-null", () => contextMenu != null);
|
addMessageListener("contextMenu-not-null", () => contextMenu != null);
|
||||||
addMessageListener("de_DE-exists", () => de_DE.exists());
|
addMessageListener("de_DE-exists", () => de_DE.exists());
|
||||||
});
|
});
|
||||||
is(script.sendSyncMessage("contextMenu-not-null")[0][0], true,
|
is(await script.sendQuery("contextMenu-not-null"), true,
|
||||||
"Got context menu XUL");
|
"Got context menu XUL");
|
||||||
is(script.sendSyncMessage("de_DE-exists")[0][0], true,
|
is(await script.sendQuery("de_DE-exists"), true,
|
||||||
"true expected (de_DE directory should exist)");
|
"true expected (de_DE directory should exist)");
|
||||||
script.addMessageListener("popupshown", handlePopup);
|
script.addMessageListener("popupshown", handlePopup);
|
||||||
|
|
||||||
|
|
@ -117,8 +117,8 @@ SimpleTest.waitForFocus(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function handlePopup() {
|
async function handlePopup() {
|
||||||
var state = script.sendSyncMessage("hidepopup")[0][0];
|
var state = await script.sendQuery("hidepopup");
|
||||||
is(state, "open", "checking if popup is open");
|
is(state, "open", "checking if popup is open");
|
||||||
|
|
||||||
onSpellCheck(elem_de, function() {
|
onSpellCheck(elem_de, function() {
|
||||||
|
|
@ -135,7 +135,7 @@ function handlePopup() {
|
||||||
is(getMisspelledWords(editor_de), "heute" + "ist" + "ein" + "guter", "some misspelled words expected: heute ist ein guter");
|
is(getMisspelledWords(editor_de), "heute" + "ist" + "ein" + "guter", "some misspelled words expected: heute ist ein guter");
|
||||||
|
|
||||||
// Remove the fake de_DE dictionary again.
|
// Remove the fake de_DE dictionary again.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
// This will clear the content preferences and reset "spellchecker.dictionary".
|
// This will clear the content preferences and reset "spellchecker.dictionary".
|
||||||
spellchecker.SetCurrentDictionary("");
|
spellchecker.SetCurrentDictionary("");
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ var content = document.getElementById("content");
|
||||||
var firstLoad = true;
|
var firstLoad = true;
|
||||||
var script;
|
var script;
|
||||||
|
|
||||||
var loadListener = function(evt) {
|
var loadListener = async function(evt) {
|
||||||
if (firstLoad) {
|
if (firstLoad) {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
|
|
@ -52,7 +52,7 @@ var loadListener = function(evt) {
|
||||||
addMessageListener("en_GB-exists", () => en_GB.exists());
|
addMessageListener("en_GB-exists", () => en_GB.exists());
|
||||||
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
|
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
|
||||||
});
|
});
|
||||||
is(script.sendSyncMessage("en_GB-exists")[0][0], true,
|
is(await script.sendQuery("en_GB-exists"), true,
|
||||||
"true expected (en-GB directory should exist)");
|
"true expected (en-GB directory should exist)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ var loadListener = function(evt) {
|
||||||
content.removeEventListener("load", loadListener);
|
content.removeEventListener("load", loadListener);
|
||||||
|
|
||||||
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
|
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
// This will clear the content preferences and reset "spellchecker.dictionary".
|
// This will clear the content preferences and reset "spellchecker.dictionary".
|
||||||
spellchecker.SetCurrentDictionary("");
|
spellchecker.SetCurrentDictionary("");
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ var onSpellCheck =
|
||||||
|
|
||||||
/** Test for Bug 697981 **/
|
/** Test for Bug 697981 **/
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.waitForFocus(function() {
|
SimpleTest.waitForFocus(async function() {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
// eslint-disable-next-line mozilla/use-services
|
// eslint-disable-next-line mozilla/use-services
|
||||||
|
|
@ -57,7 +57,7 @@ SimpleTest.waitForFocus(function() {
|
||||||
addMessageListener("de_DE-exists", () => de_DE.exists());
|
addMessageListener("de_DE-exists", () => de_DE.exists());
|
||||||
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
|
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
|
||||||
});
|
});
|
||||||
is(script.sendSyncMessage("de_DE-exists")[0][0], true,
|
is(await script.sendQuery("de_DE-exists"), true,
|
||||||
"true expected (de_DE directory should exist)");
|
"true expected (de_DE directory should exist)");
|
||||||
|
|
||||||
document.getElementById("de-DE").focus();
|
document.getElementById("de-DE").focus();
|
||||||
|
|
@ -107,7 +107,7 @@ function enFocus() {
|
||||||
is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
|
is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
|
||||||
|
|
||||||
// Remove the fake de_DE dictionary again.
|
// Remove the fake de_DE dictionary again.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
|
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
|
||||||
elem_de.onfocus = null;
|
elem_de.onfocus = null;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ var firstLoad = true;
|
||||||
var expected = "";
|
var expected = "";
|
||||||
var script;
|
var script;
|
||||||
|
|
||||||
var loadListener = function(evt) {
|
var loadListener = async function(evt) {
|
||||||
if (firstLoad) {
|
if (firstLoad) {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
script = SpecialPowers.loadChromeScript(function() {
|
script = SpecialPowers.loadChromeScript(function() {
|
||||||
|
|
@ -53,7 +53,7 @@ var loadListener = function(evt) {
|
||||||
addMessageListener("en_GB-exists", () => en_GB.exists());
|
addMessageListener("en_GB-exists", () => en_GB.exists());
|
||||||
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
|
addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
|
||||||
});
|
});
|
||||||
is(script.sendSyncMessage("en_GB-exists")[0][0], true,
|
is(await script.sendQuery("en_GB-exists"), true,
|
||||||
"true expected (en-GB directory should exist)");
|
"true expected (en-GB directory should exist)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ var loadListener = function(evt) {
|
||||||
content.removeEventListener("load", loadListener);
|
content.removeEventListener("load", loadListener);
|
||||||
|
|
||||||
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
|
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
|
||||||
script.sendSyncMessage("destroy");
|
script.sendAsyncMessage("destroy");
|
||||||
|
|
||||||
// This will clear the content preferences and reset "spellchecker.dictionary".
|
// This will clear the content preferences and reset "spellchecker.dictionary".
|
||||||
spellchecker.SetCurrentDictionary("");
|
spellchecker.SetCurrentDictionary("");
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ are also in the UI process. Consider this outline of a Gecko display list:
|
||||||
If item P was a filter, for example, that would normally apply to all of items
|
If item P was a filter, for example, that would normally apply to all of items
|
||||||
A, B, and C. This would mean either sharing the filter between the "chrome" renderroot
|
A, B, and C. This would mean either sharing the filter between the "chrome" renderroot
|
||||||
and the "content" renderroot, or duplicating it such that it existed in both
|
and the "content" renderroot, or duplicating it such that it existed in both
|
||||||
renderroots. The sharing is not possibly as it violates the independence of WR
|
renderroots. The sharing is not possible as it violates the independence of WR
|
||||||
documents. The duplication is technically possible, but could result in visual
|
documents. The duplication is technically possible, but could result in visual
|
||||||
glitches as the two documents would be processed and composited separately.
|
glitches as the two documents would be processed and composited separately.
|
||||||
|
|
||||||
|
|
@ -135,7 +135,7 @@ properties do NOT get carried across the render root boundary. Similarly, a
|
||||||
scrollframe may not contain content from multiple render roots, because that
|
scrollframe may not contain content from multiple render roots, because that
|
||||||
would lead to a similar problem in APZ where it would have to update the scroll
|
would lead to a similar problem in APZ where it would have to update the scroll
|
||||||
position of scrollframes in multiple documents and they might get composited
|
position of scrollframes in multiple documents and they might get composited
|
||||||
at separate times resulting in visual glitches.
|
at separate times, resulting in visual glitches.
|
||||||
|
|
||||||
Security Concerns
|
Security Concerns
|
||||||
-----------------
|
-----------------
|
||||||
|
|
@ -225,7 +225,7 @@ helpers in gfxUtils that assist with this task.
|
||||||
|
|
||||||
The other catch is that an APZ message may be associated with multiple documents.
|
The other catch is that an APZ message may be associated with multiple documents.
|
||||||
A concrete example is if a user on a touch device does a multitouch action with
|
A concrete example is if a user on a touch device does a multitouch action with
|
||||||
one fingers landing on different documents, which would trigger a call to
|
different fingers landing on different documents, which would trigger a call to
|
||||||
`RecvSetTargetAPZC
|
`RecvSetTargetAPZC
|
||||||
<https://searchfox.org/mozilla-central/rev/06bd14ced96f25ff1dbd5352cb985fc0fa12a64e/gfx/layers/ipc/APZCTreeManagerParent.cpp#76>`_
|
<https://searchfox.org/mozilla-central/rev/06bd14ced96f25ff1dbd5352cb985fc0fa12a64e/gfx/layers/ipc/APZCTreeManagerParent.cpp#76>`_
|
||||||
with multiple targets, each potentially belonging to a different render root.
|
with multiple targets, each potentially belonging to a different render root.
|
||||||
|
|
@ -243,7 +243,7 @@ Deferred updates
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Bug 1547351 provided a new and tricky problem where a content process is rendering
|
Bug 1547351 provided a new and tricky problem where a content process is rendering
|
||||||
stuff that needs go into the "default" document because it's actually an
|
stuff that needs to go into the "default" document because it's actually an
|
||||||
out-of-process addon content that renders in the chrome area. Prior to this bug,
|
out-of-process addon content that renders in the chrome area. Prior to this bug,
|
||||||
the WebRenderBridgeParent instances that corresponded to content processes
|
the WebRenderBridgeParent instances that corresponded to content processes
|
||||||
(hereafter referred to as "sub-WRBPs", in contrast to the "root WRBP" that
|
(hereafter referred to as "sub-WRBPs", in contrast to the "root WRBP" that
|
||||||
|
|
@ -255,7 +255,7 @@ The solution chosen to this problem was to have the root WebRenderLayerManager
|
||||||
with the render root it belongs in, and send that information over to the
|
with the render root it belongs in, and send that information over to the
|
||||||
root WRBP as part of the display list transaction. The sub-WRBPs know their own
|
root WRBP as part of the display list transaction. The sub-WRBPs know their own
|
||||||
pipeline ids, and therefore can find their render root by querying the root WRBP.
|
pipeline ids, and therefore can find their render root by querying the root WRBP.
|
||||||
The catch is that sub-WRBPs may receive display list transactions before the
|
The catch is that sub-WRBPs may receive display list transactions *before* the
|
||||||
root WRBP receives the display list update that contains the render root mapping
|
root WRBP receives the display list update that contains the render root mapping
|
||||||
information. This happens in cases like during tab switch preload, where the
|
information. This happens in cases like during tab switch preload, where the
|
||||||
user mouses over a background tab, and we pre-render it (i.e. compute and send
|
user mouses over a background tab, and we pre-render it (i.e. compute and send
|
||||||
|
|
@ -310,7 +310,7 @@ scenario, other documents may still be backlogged, so the unthrottling is
|
||||||
undesirable.
|
undesirable.
|
||||||
|
|
||||||
Instead, what we want is for all documents processing a particular transaction
|
Instead, what we want is for all documents processing a particular transaction
|
||||||
id to finish their word and render before we send the completion message back
|
id to finish their work and render before we send the completion message back
|
||||||
to content. In fact, there's a bunch of work that falls into the same category
|
to content. In fact, there's a bunch of work that falls into the same category
|
||||||
as this completion message - stuff that should happen after all the WR documents
|
as this completion message - stuff that should happen after all the WR documents
|
||||||
are done processing their pieces of the split transaction.
|
are done processing their pieces of the split transaction.
|
||||||
|
|
@ -324,8 +324,8 @@ acts as a barrier to ensure that the call chain only gets propagated once all
|
||||||
the documents have done their processing work.
|
the documents have done their processing work.
|
||||||
|
|
||||||
I'm listing this piece as a potential source of complexity for document splitting
|
I'm listing this piece as a potential source of complexity for document splitting
|
||||||
because it seems like a fairly important piece but the relevant code that is
|
because it seems like a fairly important piece but the relevant code is
|
||||||
"buried" away in place where one might not easily stumble upon it. It's also not
|
"buried" away in a place where one might not easily stumble upon it. It's also not
|
||||||
clear to me that the implications of this problem and solution have been fully
|
clear to me that the implications of this problem and solution have been fully
|
||||||
explored. In particular, I assume that there are latent bugs here because other
|
explored. In particular, I assume that there are latent bugs here because other
|
||||||
pieces of code were assuming a certain behaviour from the pre-document-splitting
|
pieces of code were assuming a certain behaviour from the pre-document-splitting
|
||||||
|
|
|
||||||
|
|
@ -422,7 +422,7 @@ async function waitUntilApzStable() {
|
||||||
if (typeof waitUntilApzStable.chromeHelper == "undefined") {
|
if (typeof waitUntilApzStable.chromeHelper == "undefined") {
|
||||||
waitUntilApzStable.chromeHelper = SpecialPowers.loadChromeScript(parentProcessFlush);
|
waitUntilApzStable.chromeHelper = SpecialPowers.loadChromeScript(parentProcessFlush);
|
||||||
ApzCleanup.register(() => {
|
ApzCleanup.register(() => {
|
||||||
waitUntilApzStable.chromeHelper.sendSyncMessage("cleanup", null);
|
waitUntilApzStable.chromeHelper.sendAsyncMessage("cleanup", null);
|
||||||
waitUntilApzStable.chromeHelper.destroy();
|
waitUntilApzStable.chromeHelper.destroy();
|
||||||
delete waitUntilApzStable.chromeHelper;
|
delete waitUntilApzStable.chromeHelper;
|
||||||
});
|
});
|
||||||
|
|
@ -580,7 +580,7 @@ function getSnapshot(rect) {
|
||||||
ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy(); });
|
ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return getSnapshot.chromeHelper.sendSyncMessage("snapshot", JSON.stringify(rect)).toString();
|
return getSnapshot.chromeHelper.sendQuery("snapshot", JSON.stringify(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes the document's query string and parses it, assuming the query string
|
// Takes the document's query string and parses it, assuming the query string
|
||||||
|
|
|
||||||
|
|
@ -33,45 +33,56 @@ function listener(callback) {
|
||||||
/* eslint-env mozilla/frame-script */
|
/* eslint-env mozilla/frame-script */
|
||||||
function chromeTouchEventCounter(operation) {
|
function chromeTouchEventCounter(operation) {
|
||||||
function chromeProcessCounter() {
|
function chromeProcessCounter() {
|
||||||
addMessageListener("start", function() {
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
|
|
||||||
if (typeof topWin.eventCounts != "undefined") {
|
|
||||||
dump("Found pre-existing eventCounts object on the top window!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
topWin.eventCounts = { "touchstart": 0, "touchmove": 0, "touchend": 0 };
|
|
||||||
topWin.counter = function(e) {
|
|
||||||
topWin.eventCounts[e.type]++;
|
|
||||||
};
|
|
||||||
|
|
||||||
topWin.addEventListener("touchstart", topWin.counter, { passive: true });
|
const PREFIX = "apz:ctec:";
|
||||||
topWin.addEventListener("touchmove", topWin.counter, { passive: true });
|
|
||||||
topWin.addEventListener("touchend", topWin.counter, { passive: true });
|
|
||||||
|
|
||||||
return true;
|
const LISTENERS = {
|
||||||
});
|
"start": function() {
|
||||||
|
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||||
|
if (typeof topWin.eventCounts != "undefined") {
|
||||||
|
dump("Found pre-existing eventCounts object on the top window!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
topWin.eventCounts = { "touchstart": 0, "touchmove": 0, "touchend": 0 };
|
||||||
|
topWin.counter = function(e) {
|
||||||
|
topWin.eventCounts[e.type]++;
|
||||||
|
};
|
||||||
|
|
||||||
addMessageListener("report", function() {
|
topWin.addEventListener("touchstart", topWin.counter, { passive: true });
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
topWin.addEventListener("touchmove", topWin.counter, { passive: true });
|
||||||
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
|
topWin.addEventListener("touchend", topWin.counter, { passive: true });
|
||||||
return JSON.stringify(topWin.eventCounts);
|
|
||||||
});
|
|
||||||
|
|
||||||
addMessageListener("end", function() {
|
return true;
|
||||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
},
|
||||||
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
|
|
||||||
if (typeof topWin.eventCounts == "undefined") {
|
"report": function() {
|
||||||
dump("The eventCounts object was not found on the top window!\n");
|
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||||
return false;
|
return JSON.stringify(topWin.eventCounts);
|
||||||
}
|
},
|
||||||
topWin.removeEventListener("touchstart", topWin.counter);
|
|
||||||
topWin.removeEventListener("touchmove", topWin.counter);
|
"end": function() {
|
||||||
topWin.removeEventListener("touchend", topWin.counter);
|
for (let [msg, func] of Object.entries(LISTENERS)) {
|
||||||
delete topWin.counter;
|
Services.ppmm.removeMessageListener(PREFIX + msg, func);
|
||||||
delete topWin.eventCounts;
|
}
|
||||||
return true;
|
|
||||||
});
|
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||||
|
if (typeof topWin.eventCounts == "undefined") {
|
||||||
|
dump("The eventCounts object was not found on the top window!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
topWin.removeEventListener("touchstart", topWin.counter);
|
||||||
|
topWin.removeEventListener("touchmove", topWin.counter);
|
||||||
|
topWin.removeEventListener("touchend", topWin.counter);
|
||||||
|
delete topWin.counter;
|
||||||
|
delete topWin.eventCounts;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let [msg, func] of Object.entries(LISTENERS)) {
|
||||||
|
Services.ppmm.addMessageListener(PREFIX + msg, func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof chromeTouchEventCounter.chromeHelper == "undefined") {
|
if (typeof chromeTouchEventCounter.chromeHelper == "undefined") {
|
||||||
|
|
@ -80,7 +91,7 @@ function chromeTouchEventCounter(operation) {
|
||||||
ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy(); });
|
ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return chromeTouchEventCounter.chromeHelper.sendSyncMessage(operation, "");
|
return SpecialPowers.Services.cpmm.sendSyncMessage(`apz:ctec:${operation}`, "")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple wrapper that waits until the chrome process has seen |count| instances
|
// Simple wrapper that waits until the chrome process has seen |count| instances
|
||||||
|
|
|
||||||
|
|
@ -559,7 +559,8 @@ SI void sample_clut_16(const skcms_A2B* a2b, I32 ix, F* r, F* g, F* b) {
|
||||||
|
|
||||||
// GCC 7.2.0 hits an internal compiler error with -finline-functions (or -O3)
|
// GCC 7.2.0 hits an internal compiler error with -finline-functions (or -O3)
|
||||||
// when targeting MIPS 64, I think attempting to inline clut() into exec_ops().
|
// when targeting MIPS 64, I think attempting to inline clut() into exec_ops().
|
||||||
#if 1 && defined(__GNUC__) && !defined(__clang__) && defined(__mips64)
|
// s390x and i*86 also hit this with GCC 7.4 and -O2
|
||||||
|
#if 1 && defined(__GNUC__) && !defined(__clang__) && (defined(__mips64) || defined(__s390x__) || defined(__i586__) || defined(__i486__) || defined(__i386__))
|
||||||
#define MAYBE_NOINLINE __attribute__((noinline))
|
#define MAYBE_NOINLINE __attribute__((noinline))
|
||||||
#else
|
#else
|
||||||
#define MAYBE_NOINLINE
|
#define MAYBE_NOINLINE
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,4 @@ subsuite = gpu
|
||||||
[test_bug509244.html]
|
[test_bug509244.html]
|
||||||
[test_bug513439.html]
|
[test_bug513439.html]
|
||||||
[test_font_whitelist.html]
|
[test_font_whitelist.html]
|
||||||
|
skip-if = debug || asan # Race between pref service and gfx platform IPC causes frequent failures on debug/ASan
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1121643
|
||||||
|
|
||||||
/** Test for Bug 1121643 **/
|
/** Test for Bug 1121643 **/
|
||||||
|
|
||||||
|
SimpleTest.requestFlakyTimeout("This test is flaky.");
|
||||||
|
|
||||||
const InspectorUtils = SpecialPowers.InspectorUtils;
|
const InspectorUtils = SpecialPowers.InspectorUtils;
|
||||||
|
|
||||||
// Given an element id, returns the first font face name encountered.
|
// Given an element id, returns the first font face name encountered.
|
||||||
|
|
@ -53,6 +55,7 @@ let testFontWhitelist = async function(useMono, useSans, useSerif) {
|
||||||
}
|
}
|
||||||
await SpecialPowers.pushPrefEnv({"set": [["font.system.whitelist",
|
await SpecialPowers.pushPrefEnv({"set": [["font.system.whitelist",
|
||||||
whitelist.join(", ")]]});
|
whitelist.join(", ")]]});
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
// If whitelist is empty, then whitelisting is considered disabled
|
// If whitelist is empty, then whitelisting is considered disabled
|
||||||
// and all fonts are allowed.
|
// and all fonts are allowed.
|
||||||
info("font whitelist: " + JSON.stringify(whitelist));
|
info("font whitelist: " + JSON.stringify(whitelist));
|
||||||
|
|
|
||||||
|
|
@ -13,27 +13,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1124898
|
||||||
|
|
||||||
/** Test for Bug 1124898 **/
|
/** Test for Bug 1124898 **/
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
(async () => {
|
||||||
true]]});
|
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", true]]});
|
||||||
SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023.
|
|
||||||
var w = window.open("about:blank", "w", "chrome");
|
|
||||||
is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window');
|
|
||||||
is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window');
|
|
||||||
var contentURL = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
|
|
||||||
w.location = contentURL;
|
|
||||||
tryWindow();
|
|
||||||
|
|
||||||
function tryWindow() {
|
SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023.
|
||||||
if (w.document.title != 'empty test page') {
|
|
||||||
info("Document not loaded yet - retrying");
|
var w = window.open("about:blank", "w", "chrome");
|
||||||
SimpleTest.executeSoon(tryWindow);
|
is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window');
|
||||||
return;
|
is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window');
|
||||||
|
var contentURL = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
|
||||||
|
w.location = contentURL;
|
||||||
|
tryWindow();
|
||||||
|
|
||||||
|
function tryWindow() {
|
||||||
|
if (w.document.title != 'empty test page') {
|
||||||
|
info("Document not loaded yet - retrying");
|
||||||
|
SimpleTest.executeSoon(tryWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window');
|
||||||
|
is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window');
|
||||||
|
w.close();
|
||||||
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window');
|
})();
|
||||||
is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window');
|
|
||||||
w.close();
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -14,36 +14,38 @@
|
||||||
|
|
||||||
<!-- test code goes here -->
|
<!-- test code goes here -->
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
SimpleTest.waitForExplicitFinish();
|
||||||
true]]});
|
|
||||||
function init() {
|
function init() {
|
||||||
var f = new Function("let test = 'let is ok'; return test;");
|
var f = new Function("let test = 'let is ok'; return test;");
|
||||||
is(f(), 'let is ok', 'let should be ok');
|
is(f(), 'let is ok', 'let should be ok');
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
Test = {
|
(async () => {
|
||||||
include: function(p) {
|
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
||||||
var sawError = false;
|
true]]});
|
||||||
try {
|
Test = {
|
||||||
Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
include: function(p) {
|
||||||
getService(Ci["mozIJSSubScriptLoader"]).
|
var sawError = false;
|
||||||
loadSubScript(p);
|
try {
|
||||||
} catch (e) {
|
Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||||
sawError = true;
|
getService(Ci["mozIJSSubScriptLoader"]).
|
||||||
}
|
loadSubScript(p);
|
||||||
ok(sawError, 'should receive an error loading a not-found file');
|
} catch (e) {
|
||||||
}
|
sawError = true;
|
||||||
};
|
}
|
||||||
|
ok(sawError, 'should receive an error loading a not-found file');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// If the include method is defined as a global function, it works.
|
// If the include method is defined as a global function, it works.
|
||||||
// try to load a non existing file to produce the error
|
// try to load a non existing file to produce the error
|
||||||
Test.include("notfound.js");
|
Test.include("notfound.js");
|
||||||
|
|
||||||
// If init is called directly, it works.
|
// If init is called directly, it works.
|
||||||
setTimeout('init();', 0);
|
setTimeout('init();', 0);
|
||||||
|
})();
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
]]></script>
|
]]></script>
|
||||||
</window>
|
</window>
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
add_task(async () => {
|
||||||
true]]});
|
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
|
||||||
|
true]]});
|
||||||
//
|
//
|
||||||
// Important! If this test starts failing after a tricky platform-y change,
|
// Important! If this test starts failing after a tricky platform-y change,
|
||||||
// the stack quota numbers in XPCJSContext probably need twiddling. We want
|
// the stack quota numbers in XPCJSContext probably need twiddling. We want
|
||||||
|
|
@ -76,7 +77,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
|
||||||
contentSb.nnslChrome = chromeSb.nearNativeStackLimit;
|
contentSb.nnslChrome = chromeSb.nearNativeStackLimit;
|
||||||
var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb);
|
var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb);
|
||||||
ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit);
|
ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit);
|
||||||
|
});
|
||||||
]]>
|
]]>
|
||||||
</script>
|
</script>
|
||||||
</window>
|
</window>
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue