Bug 1561435 - Format dom/, a=automatic-formatting

# ignore-this-changeset

Differential Revision: https://phabricator.services.mozilla.com/D35951

--HG--
extra : source : 62f3501af4bc1c0bd1ee1977a28aee04706a6663
This commit is contained in:
Victor Porof 2019-07-05 10:44:55 +02:00
Родитель bcdc3a9567
Коммит 0a8ff0ad85
1077 изменённых файлов: 222846 добавлений и 39866 удалений

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

@ -45,7 +45,6 @@ module.exports = {
"overrides": [{
"files": [
"devtools/**",
"dom/**",
"editor/**",
"extensions/**",
"gfx/**",

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

@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
toolkit/components/telemetry/healthreport-prefs.js
# Ignore all top-level directories for now.
dom/**
editor/**
extensions/**
gfx/**

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

@ -2,11 +2,14 @@ function testWorkerAbortedFetch() {
var ac = new AbortController();
ac.abort();
fetch("slow.sjs", { signal: ac.signal }).then(() => {
postMessage(false);
}, e => {
postMessage(e.name == "AbortError");
});
fetch("slow.sjs", { signal: ac.signal }).then(
() => {
postMessage(false);
},
e => {
postMessage(e.name == "AbortError");
}
);
}
function testWorkerFetchAndAbort() {
@ -15,11 +18,14 @@ function testWorkerFetchAndAbort() {
var p = fetch("slow.sjs", { signal: ac.signal });
ac.abort();
p.then(() => {
postMessage(false);
}, e => {
postMessage(e.name == "AbortError");
});
p.then(
() => {
postMessage(false);
},
e => {
postMessage(e.name == "AbortError");
}
);
}
self.onmessage = function(e) {

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

@ -43,21 +43,44 @@ function assert_time_equals_literal(actual, expected, description) {
*/
function assert_matrix_equals(actual, expected, description) {
var matrixRegExp = /^matrix\((.+),(.+),(.+),(.+),(.+),(.+)\)/;
assert_regexp_match(actual, matrixRegExp,
'Actual value should be a matrix')
assert_regexp_match(expected, matrixRegExp,
'Expected value should be a matrix');
assert_regexp_match(actual, matrixRegExp, "Actual value should be a matrix");
assert_regexp_match(
expected,
matrixRegExp,
"Expected value should be a matrix"
);
var actualMatrixArray = actual.match(matrixRegExp).slice(1).map(Number);
var expectedMatrixArray = expected.match(matrixRegExp).slice(1).map(Number);
var actualMatrixArray = actual
.match(matrixRegExp)
.slice(1)
.map(Number);
var expectedMatrixArray = expected
.match(matrixRegExp)
.slice(1)
.map(Number);
assert_equals(actualMatrixArray.length, expectedMatrixArray.length,
'Array lengths should be equal (got \'' + expected + '\' and \'' + actual +
'\'): ' + description);
assert_equals(
actualMatrixArray.length,
expectedMatrixArray.length,
"Array lengths should be equal (got '" +
expected +
"' and '" +
actual +
"'): " +
description
);
for (var i = 0; i < actualMatrixArray.length; i++) {
assert_approx_equals(actualMatrixArray[i], expectedMatrixArray[i], 0.01,
'Matrix array should be equal (got \'' + expected + '\' and \'' + actual +
'\'): ' + description);
assert_approx_equals(
actualMatrixArray[i],
expectedMatrixArray[i],
0.01,
"Matrix array should be equal (got '" +
expected +
"' and '" +
actual +
"'): " +
description
);
}
}
@ -69,28 +92,34 @@ function assert_properties_equal(actual, expected) {
assert_equals(actual.length, expected.length);
const compareProperties = (a, b) =>
a.property == b.property ? 0 : (a.property < b.property ? -1 : 1);
a.property == b.property ? 0 : a.property < b.property ? -1 : 1;
const sortedActual = actual.sort(compareProperties);
const sortedActual = actual.sort(compareProperties);
const sortedExpected = expected.sort(compareProperties);
const serializeValues = values =>
values.map(value =>
'{ ' +
[ 'offset', 'value', 'easing', 'composite' ].map(
member => `${member}: ${value[member]}`
).join(', ') +
' }')
.join(', ');
values
.map(
value =>
"{ " +
["offset", "value", "easing", "composite"]
.map(member => `${member}: ${value[member]}`)
.join(", ") +
" }"
)
.join(", ");
for (let i = 0; i < sortedActual.length; i++) {
assert_equals(sortedActual[i].property,
sortedExpected[i].property,
'CSS property name should match');
assert_equals(serializeValues(sortedActual[i].values),
serializeValues(sortedExpected[i].values),
`Values arrays do not match for `
+ `${sortedActual[i].property} property`);
assert_equals(
sortedActual[i].property,
sortedExpected[i].property,
"CSS property name should match"
);
assert_equals(
serializeValues(sortedActual[i].values),
serializeValues(sortedExpected[i].values),
`Values arrays do not match for ` + `${sortedActual[i].property} property`
);
}
}
@ -127,12 +156,14 @@ function valueFormat(offset, value, composite, easing) {
* @param options The options passed to Element.animate().
*/
function addDivAndAnimate(t, attrs, frames, options) {
let animDur = (typeof options === 'object') ?
options.duration : options;
assert_greater_than_equal(animDur, 100 * MS_PER_SEC,
'Clients of this addDivAndAnimate API must request a duration ' +
'of at least 100s, to avoid intermittent failures from e.g.' +
'the main thread being busy for an extended period');
let animDur = typeof options === "object" ? options.duration : options;
assert_greater_than_equal(
animDur,
100 * MS_PER_SEC,
"Clients of this addDivAndAnimate API must request a duration " +
"of at least 100s, to avoid intermittent failures from e.g." +
"the main thread being busy for an extended period"
);
return addDiv(t, attrs).animate(frames, options);
}
@ -148,14 +179,14 @@ function addDivAndAnimate(t, attrs, frames, options) {
* the div.
*/
function addDiv(t, attrs) {
var div = document.createElement('div');
var div = document.createElement("div");
if (attrs) {
for (var attrName in attrs) {
div.setAttribute(attrName, attrs[attrName]);
}
}
document.body.appendChild(div);
if (t && typeof t.add_cleanup === 'function') {
if (t && typeof t.add_cleanup === "function") {
t.add_cleanup(function() {
if (div.parentNode) {
div.remove();
@ -176,17 +207,19 @@ function addDiv(t, attrs) {
* the style sheet.
*/
function addStyle(t, rules) {
var extraStyle = document.createElement('style');
var extraStyle = document.createElement("style");
document.head.appendChild(extraStyle);
if (rules) {
var sheet = extraStyle.sheet;
for (var selector in rules) {
sheet.insertRule(selector + '{' + rules[selector] + '}',
sheet.cssRules.length);
sheet.insertRule(
selector + "{" + rules[selector] + "}",
sheet.cssRules.length
);
}
}
if (t && typeof t.add_cleanup === 'function') {
if (t && typeof t.add_cleanup === "function") {
t.add_cleanup(function() {
extraStyle.remove();
});
@ -200,7 +233,7 @@ function addStyle(t, rules) {
function propertyToIDL(property) {
var prefixMatch = property.match(/^-(\w+)-/);
if (prefixMatch) {
var prefix = prefixMatch[1] === 'moz' ? 'Moz' : prefixMatch[1];
var prefix = prefixMatch[1] === "moz" ? "Moz" : prefixMatch[1];
property = prefix + property.substring(prefixMatch[0].length - 1);
}
// https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
@ -248,11 +281,10 @@ function waitForAnimationFrames(frameCount, onFrame) {
const timeAtStart = document.timeline.currentTime;
return new Promise(function(resolve, reject) {
function handleFrame() {
if (onFrame && typeof onFrame === 'function') {
if (onFrame && typeof onFrame === "function") {
onFrame();
}
if (timeAtStart != document.timeline.currentTime &&
--frameCount <= 0) {
if (timeAtStart != document.timeline.currentTime && --frameCount <= 0) {
resolve();
} else {
window.requestAnimationFrame(handleFrame); // wait another frame
@ -277,9 +309,11 @@ function waitForIdle() {
* Promise.all([animations[0].ready, animations[1].ready, ... animations[N-1].ready]);
*/
function waitForAllAnimations(animations) {
return Promise.all(animations.map(function(animation) {
return animation.ready;
}));
return Promise.all(
animations.map(function(animation) {
return animation.ready;
})
);
}
/**
@ -294,14 +328,24 @@ function flushComputedStyle(elem) {
}
if (opener) {
for (var funcName of ["async_test", "assert_not_equals", "assert_equals",
"assert_approx_equals", "assert_less_than",
"assert_less_than_equal", "assert_greater_than",
"assert_between_inclusive",
"assert_true", "assert_false",
"assert_class_string", "assert_throws",
"assert_unreached", "assert_regexp_match",
"promise_test", "test"]) {
for (var funcName of [
"async_test",
"assert_not_equals",
"assert_equals",
"assert_approx_equals",
"assert_less_than",
"assert_less_than_equal",
"assert_greater_than",
"assert_between_inclusive",
"assert_true",
"assert_false",
"assert_class_string",
"assert_throws",
"assert_unreached",
"assert_regexp_match",
"promise_test",
"test",
]) {
if (opener[funcName]) {
window[funcName] = opener[funcName].bind(opener);
}
@ -359,9 +403,11 @@ function useTestRefreshMode(t) {
* Returns true if off-main-thread animations.
*/
function isOMTAEnabled() {
const OMTAPrefKey = 'layers.offmainthreadcomposition.async-animations';
return SpecialPowers.DOMWindowUtils.layerManagerRemote &&
SpecialPowers.getBoolPref(OMTAPrefKey);
const OMTAPrefKey = "layers.offmainthreadcomposition.async-animations";
return (
SpecialPowers.DOMWindowUtils.layerManagerRemote &&
SpecialPowers.getBoolPref(OMTAPrefKey)
);
}
/**
@ -376,7 +422,7 @@ function addSVGElement(target, tag, attrs) {
if (!target) {
return null;
}
var element = document.createElementNS('http://www.w3.org/2000/svg', tag);
var element = document.createElementNS("http://www.w3.org/2000/svg", tag);
if (attrs) {
for (var attrName in attrs) {
element.setAttributeNS(null, attrName, attrs[attrName]);
@ -400,8 +446,12 @@ function getDistance(target, prop, v1, v2) {
if (!target) {
return 0.0;
}
return SpecialPowers.DOMWindowUtils
.computeAnimationDistance(target, prop, v1, v2);
return SpecialPowers.DOMWindowUtils.computeAnimationDistance(
target,
prop,
v1,
v2
);
}
/*
@ -420,8 +470,10 @@ function waitForPaints() {
// at precisely the time the animation started (due to aligning with vsync
// refresh rate) then we won't end up restyling in that frame.
function animationStartsRightNow(aAnimation) {
return aAnimation.startTime === aAnimation.timeline.currentTime &&
aAnimation.currentTime === 0;
return (
aAnimation.startTime === aAnimation.timeline.currentTime &&
aAnimation.currentTime === 0
);
}
// Waits for a given animation being ready to restyle.

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

@ -4,13 +4,15 @@ const CONSUMED_STATE = "consumed";
var ppmm = Services.ppmm;
add_task(async function(){
add_task(async function() {
// We want to count processes in this test, so let's disable the pre-allocated process manager.
await SpecialPowers.pushPrefEnv({"set": [
["dom.ipc.processPrelaunch.enabled", false],
["dom.ipc.processCount", 10],
["dom.ipc.keepProcessesAlive.web", 10],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.ipc.processPrelaunch.enabled", false],
["dom.ipc.processCount", 10],
["dom.ipc.keepProcessesAlive.web", 10],
],
});
});
// Ensure that the preloaded browser exists, and it's finished loading.
@ -25,10 +27,11 @@ async function ensurePreloaded(gBrowser) {
});
}
add_task(async function(){
add_task(async function() {
// This test is only relevant in e10s.
if (!gMultiProcessBrowser)
if (!gMultiProcessBrowser) {
return;
}
ppmm.releaseCachedProcesses();
@ -44,7 +47,11 @@ add_task(async function(){
await ensurePreloaded(gBrowser);
// Check that the process count did not change.
is(ppmm.childCount, originalChildCount, "Preloaded browser should not create a new content process.")
is(
ppmm.childCount,
originalChildCount,
"Preloaded browser should not create a new content process."
);
// Let's do another round.
BrowserOpenTab();
@ -52,13 +59,20 @@ add_task(async function(){
await ensurePreloaded(gBrowser);
// Check that the process count did not change.
is(ppmm.childCount, originalChildCount, "Preloaded browser should (still) not create a new content process.")
is(
ppmm.childCount,
originalChildCount,
"Preloaded browser should (still) not create a new content process."
);
// Navigate to a content page from the parent side.
BrowserTestUtils.loadURI(tab2.linkedBrowser, TEST_URL);
await BrowserTestUtils.browserLoaded(tab2.linkedBrowser, false, TEST_URL);
is(ppmm.childCount, originalChildCount + 1,
"Navigating away from the preloaded browser (parent side) should create a new content process.")
is(
ppmm.childCount,
originalChildCount + 1,
"Navigating away from the preloaded browser (parent side) should create a new content process."
);
// Navigate to a content page from the child side.
await BrowserTestUtils.switchTab(gBrowser, tab1);
@ -69,8 +83,11 @@ add_task(async function(){
});
/* eslint-enable no-shadow */
await BrowserTestUtils.browserLoaded(tab1.linkedBrowser, false, TEST_URL);
is(ppmm.childCount, originalChildCount + 2,
"Navigating away from the preloaded browser (child side) should create a new content process.")
is(
ppmm.childCount,
originalChildCount + 2,
"Navigating away from the preloaded browser (child side) should create a new content process."
);
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
@ -86,23 +103,44 @@ add_task(async function(){
add_task(async function preloaded_state_attribute() {
// Wait for a preloaded browser to exist, use it, and then create another one
await ensurePreloaded(gBrowser);
let preloadedTabState = gBrowser.preloadedBrowser.getAttribute("preloadedState");
is(preloadedTabState, PRELOADED_STATE, "Sanity check that the first preloaded browser has the correct attribute");
let preloadedTabState = gBrowser.preloadedBrowser.getAttribute(
"preloadedState"
);
is(
preloadedTabState,
PRELOADED_STATE,
"Sanity check that the first preloaded browser has the correct attribute"
);
BrowserOpenTab();
await ensurePreloaded(gBrowser);
// Now check that the tabs have the correct browser attributes set
let consumedTabState = gBrowser.selectedBrowser.getAttribute("preloadedState");
is(consumedTabState, CONSUMED_STATE, "The opened tab consumed the preloaded browser and updated the attribute");
let consumedTabState = gBrowser.selectedBrowser.getAttribute(
"preloadedState"
);
is(
consumedTabState,
CONSUMED_STATE,
"The opened tab consumed the preloaded browser and updated the attribute"
);
preloadedTabState = gBrowser.preloadedBrowser.getAttribute("preloadedState");
is(preloadedTabState, PRELOADED_STATE, "The preloaded browser has the correct attribute");
is(
preloadedTabState,
PRELOADED_STATE,
"The preloaded browser has the correct attribute"
);
// Navigate away and check that the attribute has been removed altogether
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URL);
let navigatedTabHasState = gBrowser.selectedBrowser.hasAttribute("preloadedState");
ok(!navigatedTabHasState, "Correctly removed the preloadState attribute when navigating away");
let navigatedTabHasState = gBrowser.selectedBrowser.hasAttribute(
"preloadedState"
);
ok(
!navigatedTabHasState,
"Correctly removed the preloadState attribute when navigating away"
);
// Remove tabs and preloaded browsers
BrowserTestUtils.removeTab(gBrowser.selectedTab);

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

@ -1,4 +1,8 @@
const TEST_URI = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "file_blocking_image.html";
const TEST_URI =
getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
) + "file_blocking_image.html";
/**
* Loading an image from https:// should work.
@ -9,7 +13,7 @@ add_task(async function load_image_from_https_test() {
gBrowser.selectedTab = tab;
await ContentTask.spawn(tab.linkedBrowser, { }, async function() {
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
function imgListener(img) {
return new Promise((resolve, reject) => {
img.addEventListener("load", () => resolve());
@ -43,7 +47,7 @@ add_task(async function load_image_from_http_test() {
gBrowser.selectedTab = tab;
await ContentTask.spawn(tab.linkedBrowser, { }, async function () {
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
function imgListener(img) {
return new Promise((resolve, reject) => {
img.addEventListener("load", () => reject());
@ -51,7 +55,7 @@ add_task(async function load_image_from_http_test() {
});
}
let img = content.document.createElement('img');
let img = content.document.createElement("img");
img.src = "http://example.com/tests/image/test/mochitest/shaver.png";
content.document.body.appendChild(img);
@ -62,8 +66,11 @@ add_task(async function load_image_from_http_test() {
Assert.ok(false);
}
Assert.equal(img.imageBlockingStatus, Ci.nsIContentPolicy.REJECT_SERVER,
"images from http should be blocked");
Assert.equal(
img.imageBlockingStatus,
Ci.nsIContentPolicy.REJECT_SERVER,
"images from http should be blocked"
);
});
gBrowser.removeTab(tab);
@ -85,7 +92,7 @@ add_task(async function load_https_and_http_test() {
gBrowser.selectedTab = tab;
await ContentTask.spawn(tab.linkedBrowser, { }, async function () {
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
function imgListener(img) {
return new Promise((resolve, reject) => {
img.addEventListener("load", () => reject());
@ -106,8 +113,11 @@ add_task(async function load_https_and_http_test() {
Assert.ok(false);
}
Assert.equal(img.imageBlockingStatus, Ci.nsIContentPolicy.REJECT_SERVER,
"image.src changed to http should be blocked");
Assert.equal(
img.imageBlockingStatus,
Ci.nsIContentPolicy.REJECT_SERVER,
"image.src changed to http should be blocked"
);
});
gBrowser.removeTab(tab);
@ -126,7 +136,7 @@ add_task(async function block_pending_request_test() {
gBrowser.selectedTab = tab;
await ContentTask.spawn(tab.linkedBrowser, { }, async function () {
await ContentTask.spawn(tab.linkedBrowser, {}, async function() {
let wrapper = {
_resolve: null,
_sizeAvail: false,
@ -151,14 +161,16 @@ add_task(async function block_pending_request_test() {
},
QueryInterface(aIID) {
if (aIID.equals(Ci.imgIScriptedNotificationObserver))
if (aIID.equals(Ci.imgIScriptedNotificationObserver)) {
return this;
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
},
};
let observer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
.createScriptedObserver(wrapper);
let observer = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools)
.createScriptedObserver(wrapper);
let img = content.document.createElement("img");
img.src = "https://example.com/tests/image/test/mochitest/shaver.png";
@ -176,8 +188,11 @@ add_task(async function block_pending_request_test() {
// Now we change to load from http:// site, which will be blocked.
img.src = "http://example.com/tests/image/test/mochitest/shaver.png";
Assert.equal(img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST), req,
"CURRENT_REQUEST shouldn't be replaced.");
Assert.equal(
img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST),
req,
"CURRENT_REQUEST shouldn't be replaced."
);
Assert.equal(img.imageBlockingStatus, Ci.nsIContentPolicy.ACCEPT);
});

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

@ -4,7 +4,7 @@ add_task(async function() {
var statusTexts = [];
var xhr = new XMLHttpRequest();
var observer = {
observe: function (aSubject, aTopic, aData) {
observe: function(aSubject, aTopic, aData) {
try {
var channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
channel.getResponseHeader("Location");
@ -12,18 +12,18 @@ add_task(async function() {
return;
}
statusTexts.push(xhr.statusText);
}
},
};
Services.obs.addObserver(observer, "http-on-examine-response");
await new Promise((resolve) => {
await new Promise(resolve => {
xhr.addEventListener("load", function() {
statusTexts.push(this.statusText);
is(statusTexts[0], "", "Empty statusText value for HTTP 302");
is(statusTexts[1], "OK", "OK statusText value for the redirect.");
resolve();
});
xhr.open("GET", gHttpTestRoot+ "file_bug1011748_redirect.sjs", true);
xhr.open("GET", gHttpTestRoot + "file_bug1011748_redirect.sjs", true);
xhr.send();
});

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

@ -4,10 +4,12 @@
"use strict";
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
SpecialPowers.pushPrefEnv({
set: [["security.allow_eval_with_system_principal", true]],
});
const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
const PAGE =
"data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
/**
* Returns a Promise that resolves when it sees a pageshow and
@ -25,7 +27,7 @@ const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20pag
* @returns Promise
*/
function prepareForVisibilityEvents(browser, expectedOrder) {
return new Promise((resolve) => {
return new Promise(resolve => {
let order = [];
let rmvHide, rmvShow;
@ -45,21 +47,31 @@ function prepareForVisibilityEvents(browser, expectedOrder) {
}
};
let eventListener = (type) => {
let eventListener = type => {
order.push(type);
checkSatisfied();
};
let checkFn = (e) => e.persisted;
let checkFn = e => e.persisted;
rmvHide = BrowserTestUtils.addContentEventListener(browser, "pagehide",
() => eventListener("pagehide"),
{}, checkFn,
false, false);
rmvShow = BrowserTestUtils.addContentEventListener(browser, "pageshow",
() => eventListener("pageshow"),
{}, checkFn,
false, false);
rmvHide = BrowserTestUtils.addContentEventListener(
browser,
"pagehide",
() => eventListener("pagehide"),
{},
checkFn,
false,
false
);
rmvShow = BrowserTestUtils.addContentEventListener(
browser,
"pageshow",
() => eventListener("pageshow"),
{},
checkFn,
false,
false
);
});
}
@ -95,7 +107,7 @@ add_task(async function test_swap_frameloader_pagevisibility_events() {
// Wait for that initial browser to show its pageshow event if it hasn't
// happened so that we don't confuse it with the other expected events.
await ContentTask.spawn(emptyBrowser, {}, async() => {
await ContentTask.spawn(emptyBrowser, {}, async () => {
if (content.document.visibilityState === "hidden") {
info("waiting for hidden emptyBrowser to pageshow");
await ContentTaskUtils.waitForEvent(content, "pageshow", {});
@ -104,8 +116,10 @@ add_task(async function test_swap_frameloader_pagevisibility_events() {
// The empty tab we just added show now fire a pagehide as its replaced,
// and a pageshow once the swap is finished.
let emptyBrowserPromise =
prepareForVisibilityEvents(emptyBrowser, ["pagehide", "pageshow"]);
let emptyBrowserPromise = prepareForVisibilityEvents(emptyBrowser, [
"pagehide",
"pageshow",
]);
gBrowser.swapBrowsersAndCloseOther(newTab, newWindow.gBrowser.selectedTab);

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

@ -35,108 +35,237 @@ add_task(async function() {
});
async function testLinkClick(withFrame, loadDivertedInBackground) {
await SpecialPowers.pushPrefEnv({"set": [["browser.tabs.loadDivertedInBackground", loadDivertedInBackground]]});
await SpecialPowers.pushPrefEnv({
set: [["browser.tabs.loadDivertedInBackground", loadDivertedInBackground]],
});
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser,
BASE_URL + (withFrame ? "file_bug1303838_with_iframe.html" : "file_bug1303838.html"));
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
BASE_URL +
(withFrame ? "file_bug1303838_with_iframe.html" : "file_bug1303838.html")
);
is(gBrowser.tabs.length, 2, "check tabs.length");
is(gBrowser.selectedTab, tab, "check selectedTab");
info("Test normal links with loadDivertedInBackground=" + loadDivertedInBackground + ", withFrame=" + withFrame);
info(
"Test normal links with loadDivertedInBackground=" +
loadDivertedInBackground +
", withFrame=" +
withFrame
);
let [testTab] = await clickLink(withFrame, "#link-1", tab.linkedBrowser);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#link-2", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#link-2",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#link-3", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#link-3",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#link-4", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground, 2);
await clickLink(
withFrame,
"#link-4",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground,
2
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
info("Test anchor links with loadDivertedInBackground=" + loadDivertedInBackground + ", withFrame=" + withFrame);
info(
"Test anchor links with loadDivertedInBackground=" +
loadDivertedInBackground +
", withFrame=" +
withFrame
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#anchor-link-1", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#anchor-link-1",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#anchor-link-2", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#anchor-link-2",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#anchor-link-3", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#anchor-link-3",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
info("Test iframe links with loadDivertedInBackground=" + loadDivertedInBackground + ", withFrame=" + withFrame);
info(
"Test iframe links with loadDivertedInBackground=" +
loadDivertedInBackground +
", withFrame=" +
withFrame
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#frame-link-1", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#frame-link-1",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#frame-link-2", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#frame-link-2",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
if (!loadDivertedInBackground) {
await BrowserTestUtils.switchTab(gBrowser, tab);
}
await clickLink(withFrame, "#frame-link-3", tab.linkedBrowser, testTab.linkedBrowser, !loadDivertedInBackground);
await clickLink(
withFrame,
"#frame-link-3",
tab.linkedBrowser,
testTab.linkedBrowser,
!loadDivertedInBackground
);
is(gBrowser.tabs.length, 3, "check tabs.length");
is(gBrowser.selectedTab, loadDivertedInBackground ? tab : testTab, "check selectedTab");
is(
gBrowser.selectedTab,
loadDivertedInBackground ? tab : testTab,
"check selectedTab"
);
BrowserTestUtils.removeTab(testTab);
BrowserTestUtils.removeTab(tab);
}
function clickLink(isFrame, linkId, browser, testBrowser, awaitTabSwitch = false, locationChangeNum = 1) {
function clickLink(
isFrame,
linkId,
browser,
testBrowser,
awaitTabSwitch = false,
locationChangeNum = 1
) {
let promises = [];
if (awaitTabSwitch) {
promises.push(waitForTabSwitch(gBrowser));
}
promises.push(testBrowser ?
waitForLocationChange(testBrowser, locationChangeNum) :
BrowserTestUtils.waitForNewTab(gBrowser));
promises.push(ContentTask.spawn(browser, [isFrame, linkId],
([contentIsFrame, contentLinkId]) => {
let doc = content.document;
if (contentIsFrame) {
let frame = content.document.getElementById("frame");
doc = frame.contentDocument;
}
info("Clicking " + contentLinkId);
doc.querySelector(contentLinkId).click();
}));
promises.push(
testBrowser
? waitForLocationChange(testBrowser, locationChangeNum)
: BrowserTestUtils.waitForNewTab(gBrowser)
);
promises.push(
ContentTask.spawn(
browser,
[isFrame, linkId],
([contentIsFrame, contentLinkId]) => {
let doc = content.document;
if (contentIsFrame) {
let frame = content.document.getElementById("frame");
doc = frame.contentDocument;
}
info("Clicking " + contentLinkId);
doc.querySelector(contentLinkId).click();
}
)
);
return Promise.all(promises);
}
@ -166,8 +295,10 @@ function waitForLocationChange(browser, locationChangeNum) {
resolve();
}
},
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])
QueryInterface: ChromeUtils.generateQI([
Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference,
]),
};
browser.addProgressListener(locationChangeListener);
});

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

@ -4,44 +4,50 @@
* X-Frame-Options: DENY iframe into the document and verifies that the document
* loads. The policy we are enforcing is outlined here:
* https://bugzilla.mozilla.org/show_bug.cgi?id=593387#c17
*/
*/
add_task(async function test() {
// We have to disable CSP for this test otherwise the CSP of about:mozilla will
// block the dynamic frame creation.
await SpecialPowers.pushPrefEnv({"set": [["security.csp.enable", false],]});
await SpecialPowers.pushPrefEnv({ set: [["security.csp.enable", false]] });
await BrowserTestUtils.withNewTab({ gBrowser,
url: "chrome://global/content/mozilla.xhtml" },
async function(newBrowser) {
// NB: We load the chrome:// page in the parent process.
await testXFOFrameInChrome(newBrowser);
await BrowserTestUtils.withNewTab(
{ gBrowser, url: "chrome://global/content/mozilla.xhtml" },
async function(newBrowser) {
// NB: We load the chrome:// page in the parent process.
await testXFOFrameInChrome(newBrowser);
// Run next test (try the same with a content top-level context)
await BrowserTestUtils.loadURI(newBrowser, "http://example.com/");
await BrowserTestUtils.browserLoaded(newBrowser);
// Run next test (try the same with a content top-level context)
await BrowserTestUtils.loadURI(newBrowser, "http://example.com/");
await BrowserTestUtils.browserLoaded(newBrowser);
await ContentTask.spawn(newBrowser, null, testXFOFrameInContent);
});
await ContentTask.spawn(newBrowser, null, testXFOFrameInContent);
}
);
});
function testXFOFrameInChrome(newBrowser) {
// Insert an iframe that specifies "X-Frame-Options: DENY" and verify
// that it loads, since the top context is chrome
var deferred = {};
deferred.promise = new Promise((resolve) => {
deferred.promise = new Promise(resolve => {
deferred.resolve = resolve;
});
var frame = newBrowser.contentDocument.createElement("iframe");
frame.src = "http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny";
frame.addEventListener("load", function() {
// Test that the frame loaded
var test = this.contentDocument.getElementById("test");
is(test.tagName, "H1", "wrong element type");
is(test.textContent, "deny", "wrong textContent");
deferred.resolve();
}, {capture: true, once: true});
frame.src =
"http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny";
frame.addEventListener(
"load",
function() {
// Test that the frame loaded
var test = this.contentDocument.getElementById("test");
is(test.tagName, "H1", "wrong element type");
is(test.textContent, "deny", "wrong textContent");
deferred.resolve();
},
{ capture: true, once: true }
);
newBrowser.contentDocument.body.appendChild(frame);
return deferred.promise;
@ -51,19 +57,24 @@ function testXFOFrameInContent(newBrowser) {
// Insert an iframe that specifies "X-Frame-Options: DENY" and verify that it
// is blocked from loading since the top browsing context is another site
var deferred = {};
deferred.promise = new Promise((resolve) => {
deferred.promise = new Promise(resolve => {
deferred.resolve = resolve;
});
var frame = content.document.createElement("iframe");
frame.src = "http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny";
frame.addEventListener("load", function() {
// Test that the frame DID NOT load
var test = this.contentDocument.getElementById("test");
Assert.equal(test, null, "should be about:blank");
frame.src =
"http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny";
frame.addEventListener(
"load",
function() {
// Test that the frame DID NOT load
var test = this.contentDocument.getElementById("test");
Assert.equal(test, null, "should be about:blank");
deferred.resolve();
}, {capture: true, once: true});
deferred.resolve();
},
{ capture: true, once: true }
);
content.document.body.appendChild(frame);
return deferred.promise;

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

@ -4,28 +4,38 @@
add_task(async function mixed_content_block_for_target_top_test() {
const PREF_ACTIVE = "security.mixed_content.block_active_content";
const httpsTestRoot = getRootDirectory(gTestPath)
.replace("chrome://mochitests/content", "https://example.com");
const httpsTestRoot = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
);
await SpecialPowers.pushPrefEnv({ set: [[ PREF_ACTIVE, true ]] });
await SpecialPowers.pushPrefEnv({ set: [[PREF_ACTIVE, true]] });
let newTab = await BrowserTestUtils.openNewForegroundTab({ gBrowser,
waitForLoad: true });
let newTab = await BrowserTestUtils.openNewForegroundTab({
gBrowser,
waitForLoad: true,
});
let testBrowser = newTab.linkedBrowser;
var url = httpsTestRoot + "file_bug902350.html";
var frameUrl = httpsTestRoot + "file_bug902350_frame.html";
let loadPromise = BrowserTestUtils.browserLoaded(testBrowser, false, url);
let frameLoadPromise = BrowserTestUtils.browserLoaded(testBrowser, true,
frameUrl);
let frameLoadPromise = BrowserTestUtils.browserLoaded(
testBrowser,
true,
frameUrl
);
BrowserTestUtils.loadURI(testBrowser, url);
await loadPromise;
await frameLoadPromise;
// Find the iframe and click the link in it.
let insecureUrl = "http://example.com/";
let insecureLoadPromise = BrowserTestUtils.browserLoaded(testBrowser, false,
insecureUrl);
let insecureLoadPromise = BrowserTestUtils.browserLoaded(
testBrowser,
false,
insecureUrl
);
ContentTask.spawn(testBrowser, null, function() {
var frame = content.document.getElementById("testing_frame");
var topTarget = frame.contentWindow.document.getElementById("topTarget");
@ -36,9 +46,11 @@ add_task(async function mixed_content_block_for_target_top_test() {
await insecureLoadPromise;
// The link click should not invoke the Mixed Content Blocker.
let {gIdentityHandler} = testBrowser.ownerGlobal;
ok (!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
"Mixed Content Doorhanger did not appear when trying to navigate top");
let { gIdentityHandler } = testBrowser.ownerGlobal;
ok(
!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
"Mixed Content Doorhanger did not appear when trying to navigate top"
);
BrowserTestUtils.removeTab(newTab);
});

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

@ -5,8 +5,9 @@ const CONTENT_CREATED = "ipc:content-created";
// Make sure that BTU.withNewTab({ ..., forceNewProcess: true }) loads
// new tabs in their own process.
async function spawnNewAndTest(recur, pids) {
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank", forceNewProcess: true },
async function(browser) {
await BrowserTestUtils.withNewTab(
{ gBrowser, url: "about:blank", forceNewProcess: true },
async function(browser) {
// Make sure our new browser is in its own process.
let newPid = browser.frameLoader.remoteTab.osPid;
ok(!pids.has(newPid), "new tab is in its own process: " + recur);
@ -20,14 +21,18 @@ async function spawnNewAndTest(recur, pids) {
};
Services.obs.addObserver(observer, CONTENT_CREATED);
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function() {
// If this new tab caused us to create a new process, the ok(false)
// should have already happened. Therefore, if we get here, we've
// passed. Simply remove the observer.
Services.obs.removeObserver(observer, CONTENT_CREATED);
});
await BrowserTestUtils.withNewTab(
{ gBrowser, url: "about:blank" },
function() {
// If this new tab caused us to create a new process, the ok(false)
// should have already happened. Therefore, if we get here, we've
// passed. Simply remove the observer.
Services.obs.removeObserver(observer, CONTENT_CREATED);
}
);
}
});
}
);
}
add_task(async function test() {
@ -36,5 +41,5 @@ add_task(async function test() {
// Use at least one more tab than max processes or at least 5 to make this
// test interesting.
await spawnNewAndTest(Math.max(maxCount + 1, 5), new Set([ curPid ]));
await spawnNewAndTest(Math.max(maxCount + 1, 5), new Set([curPid]));
});

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

@ -3,7 +3,7 @@
const URIs = [
"about:about",
"http://example.com/browser/dom/base/test/empty.html"
"http://example.com/browser/dom/base/test/empty.html",
];
async function runTest(input, url) {
@ -12,15 +12,20 @@ async function runTest(input, url) {
await BrowserTestUtils.browserLoaded(browser);
let stream = Cc['@mozilla.org/io/string-input-stream;1']
.createInstance(Ci.nsIStringInputStream);
let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
Ci.nsIStringInputStream
);
stream.setData(input, input.length);
let data = {
inputStream: stream
inputStream: stream,
};
is(data.inputStream.available(), input.length, "The length of the inputStream matches: " + input.length);
is(
data.inputStream.available(),
input.length,
"The length of the inputStream matches: " + input.length
);
/* eslint-disable no-shadow */
let dataBack = await ContentTask.spawn(browser, data, function(data) {
@ -29,18 +34,25 @@ async function runTest(input, url) {
check: true,
};
if (content.location.href.startsWith('about:')) {
dataBack.check = data.inputStream instanceof content.Components.interfaces.nsIInputStream;
if (content.location.href.startsWith("about:")) {
dataBack.check =
data.inputStream instanceof
content.Components.interfaces.nsIInputStream;
}
return dataBack;
});
/* eslint-enable no-shadow */
ok(dataBack.check, "The inputStream is a nsIInputStream also on content.");
ok(data.inputStream instanceof Ci.nsIInputStream, "The original object was an inputStream");
ok(dataBack.inputStream instanceof Ci.nsIInputStream, "We have an inputStream back from the content.");
ok(
data.inputStream instanceof Ci.nsIInputStream,
"The original object was an inputStream"
);
ok(
dataBack.inputStream instanceof Ci.nsIInputStream,
"We have an inputStream back from the content."
);
BrowserTestUtils.removeTab(tab);
}
@ -48,7 +60,7 @@ async function runTest(input, url) {
add_task(async function test() {
let a = "a";
for (let i = 0; i < 25; ++i) {
a+=a;
a += a;
}
for (let i = 0; i < URIs.length; ++i) {

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

@ -7,7 +7,9 @@ function getBaseNumberOfProcesses() {
// additional processes for those, so let's add these to the base count to
// not have system WebExtensions cause test failures.
for (let i = 0; i < Services.ppmm.childCount; i++) {
if (Services.ppmm.getChildAt(i).remoteType === E10SUtils.EXTENSION_REMOTE_TYPE) {
if (
Services.ppmm.getChildAt(i).remoteType === E10SUtils.EXTENSION_REMOTE_TYPE
) {
processCount += 1;
}
}
@ -17,15 +19,20 @@ function getBaseNumberOfProcesses() {
function checkBaseProcessCount(description) {
const baseProcessCount = getBaseNumberOfProcesses();
const {childCount} = Services.ppmm;
const { childCount } = Services.ppmm;
// With preloaded activity-stream, process count is a bit undeterministic, so
// allow for some variation
const extraCount = baseProcessCount + 1;
ok(childCount === baseProcessCount || childCount === extraCount, `${description} (${baseProcessCount} or ${extraCount})`);
ok(
childCount === baseProcessCount || childCount === extraCount,
`${description} (${baseProcessCount} or ${extraCount})`
);
}
function processScript() {
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
if (Services.cpmm !== this) {
dump("Test failed: wrong global object\n");
return;
@ -61,54 +68,65 @@ var checkProcess = async function(mm) {
function promiseMessage(messageManager, message) {
return new Promise(resolve => {
let listener = (msg) => {
let listener = msg => {
messageManager.removeMessageListener(message, listener);
resolve(msg);
};
messageManager.addMessageListener(message, listener);
})
});
}
add_task(async function(){
add_task(async function() {
// We want to count processes in this test, so let's disable the pre-allocated process manager.
await SpecialPowers.pushPrefEnv({"set": [
["dom.ipc.processPrelaunch.enabled", false],
]});
})
await SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processPrelaunch.enabled", false]],
});
});
add_task(async function(){
add_task(async function() {
// This test is only relevant in e10s.
if (!gMultiProcessBrowser)
if (!gMultiProcessBrowser) {
return;
}
Services.ppmm.releaseCachedProcesses();
await SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 5]]})
await SpecialPowers.pushPrefEnv({"set": [["dom.ipc.keepProcessesAlive.web", 5]]})
await SpecialPowers.pushPrefEnv({ set: [["dom.ipc.processCount", 5]] });
await SpecialPowers.pushPrefEnv({
set: [["dom.ipc.keepProcessesAlive.web", 5]],
});
let tabs = [];
for (let i = 0; i < 3; i++) {
tabs[i] = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
tabs[i] = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
}
for (let i = 0; i < 3; i++) {
// FIXME: This should wait for the tab removal gets reflected to the
// process count (bug 1446726).
let sessionStorePromise = BrowserTestUtils.waitForSessionStoreUpdate(tabs[i]);
let sessionStorePromise = BrowserTestUtils.waitForSessionStoreUpdate(
tabs[i]
);
BrowserTestUtils.removeTab(tabs[i]);
await sessionStorePromise;
}
Services.ppmm.releaseCachedProcesses();
checkBaseProcessCount("Should get back to the base number of processes at this point");
})
checkBaseProcessCount(
"Should get back to the base number of processes at this point"
);
});
// Test that loading a process script loads in all existing processes
add_task(async function() {
let checks = [];
for (let i = 0; i < Services.ppmm.childCount; i++)
for (let i = 0; i < Services.ppmm.childCount; i++) {
checks.push(checkProcess(Services.ppmm.getChildAt(i)));
}
Services.ppmm.loadProcessScript(processScriptURL, false);
await Promise.all(checks);
@ -117,10 +135,13 @@ add_task(async function() {
// Test that loading a process script loads in new processes
add_task(async function() {
// This test is only relevant in e10s
if (!gMultiProcessBrowser)
if (!gMultiProcessBrowser) {
return;
}
checkBaseProcessCount("Should still be at the base number of processes at this point");
checkBaseProcessCount(
"Should still be at the base number of processes at this point"
);
// Load something in the main process
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
@ -146,12 +167,15 @@ add_task(async function() {
check = checkProcess(Services.ppmm);
// Reset the default browser to start a new child process
gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser,
{ remoteType: E10SUtils.DEFAULT_REMOTE_TYPE });
gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, {
remoteType: E10SUtils.DEFAULT_REMOTE_TYPE,
});
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:blank");
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
checkBaseProcessCount("Should be back to the base number of processes at this point");
checkBaseProcessCount(
"Should be back to the base number of processes at this point"
);
// The new process should have responded
await check;

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

@ -1,5 +1,4 @@
function frameScript()
{
function frameScript() {
sendSyncMessage("Test:Message");
sendAsyncMessage("Test:Message");
sendAsyncMessage("Test:Done");
@ -15,12 +14,18 @@ function test() {
let frameLoader = browser.frameLoader;
ok(frameLoader !== null, "frameLoader looks okay");
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
browser.messageManager.loadFrameScript(
"data:,(" + frameScript.toString() + ")()",
false
);
browser.messageManager.addMessageListener("Test:Message", (msg) => {
browser.messageManager.addMessageListener("Test:Message", msg => {
ok(msg.target === browser, "<browser> is correct");
ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct");
ok(browser.frameLoader === msg.targetFrameLoader, "browser frameloader is correct");
ok(
browser.frameLoader === msg.targetFrameLoader,
"browser frameloader is correct"
);
});
browser.messageManager.addMessageListener("Test:Done", () => {

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

@ -1,13 +1,18 @@
function frameScript()
{
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
function frameScript() {
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
function eventHandler(e) {
if (!docShell) {
sendAsyncMessage("Test:Fail", "docShell is null");
}
sendAsyncMessage("Test:Event", [e.type, e.target === content.document, e.eventPhase]);
sendAsyncMessage("Test:Event", [
e.type,
e.target === content.document,
e.eventPhase,
]);
}
let outerID = content.windowUtils.outerWindowID;
@ -19,26 +24,37 @@ function frameScript()
let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
sendAsyncMessage("Test:Event", ["outer-window-destroyed", id == outerID]);
if (id == outerID) {
Services.obs.removeObserver(onOuterWindowDestroyed, "outer-window-destroyed");
Services.obs.removeObserver(
onOuterWindowDestroyed,
"outer-window-destroyed"
);
}
}
let url = "https://example.com/browser/dom/base/test/file_messagemanager_unload.html";
let url =
"https://example.com/browser/dom/base/test/file_messagemanager_unload.html";
content.location = url;
addEventListener("load", (e) => {
if (e.target.location != url) {
return;
}
addEventListener(
"load",
e => {
if (e.target.location != url) {
return;
}
addEventListener("unload", eventHandler, false);
addEventListener("unload", eventHandler, true);
addEventListener("pagehide", eventHandler, false);
addEventListener("pagehide", eventHandler, true);
Services.obs.addObserver(onOuterWindowDestroyed, "outer-window-destroyed");
addEventListener("unload", eventHandler, false);
addEventListener("unload", eventHandler, true);
addEventListener("pagehide", eventHandler, false);
addEventListener("pagehide", eventHandler, true);
Services.obs.addObserver(
onOuterWindowDestroyed,
"outer-window-destroyed"
);
sendAsyncMessage("Test:Ready");
}, true);
sendAsyncMessage("Test:Ready");
},
true
);
}
const EXPECTED = [
@ -72,27 +88,45 @@ function test() {
let frameLoader = browser.frameLoader;
ok(frameLoader !== null, "frameLoader looks okay");
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
browser.messageManager.loadFrameScript(
"data:,(" + frameScript.toString() + ")()",
false
);
browser.messageManager.addMessageListener("Test:Fail", (msg) => {
ok(false, msg.data);
}, true);
browser.messageManager.addMessageListener(
"Test:Fail",
msg => {
ok(false, msg.data);
},
true
);
let index = 0;
browser.messageManager.addMessageListener("Test:Event", (msg) => {
ok(msg.target === browser, "<browser> is correct");
ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct");
ok(browser.frameLoader === null, "browser frameloader null during teardown");
browser.messageManager.addMessageListener(
"Test:Event",
msg => {
ok(msg.target === browser, "<browser> is correct");
ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct");
ok(
browser.frameLoader === null,
"browser frameloader null during teardown"
);
info(JSON.stringify(msg.data));
info(JSON.stringify(msg.data));
is(JSON.stringify(msg.data), JSON.stringify(EXPECTED[index]), "results match");
index++;
is(
JSON.stringify(msg.data),
JSON.stringify(EXPECTED[index]),
"results match"
);
index++;
if (index == EXPECTED.length) {
finish();
}
}, true);
if (index == EXPECTED.length) {
finish();
}
},
true
);
browser.messageManager.addMessageListener("Test:Ready", () => {
info("Got ready message");

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

@ -20,7 +20,7 @@ function WindowObserver(count) {
Services.ww.unregisterNotification(windowObserver);
resolve();
}
}
};
Services.ww.registerNotification(windowObserver);
});
}
@ -28,12 +28,17 @@ function WindowObserver(count) {
add_task(async _ => {
info("All opened if the pref is off");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", false],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", false],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -41,12 +46,20 @@ add_task(async _ => {
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#openPopups",
{},
tab.linkedBrowser
);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});
@ -54,17 +67,29 @@ add_task(async _ => {
add_task(async _ => {
info("2 window.open()s in a click event allowed because whitelisted domain.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
const uri = Services.io.newURI(TEST_DOMAIN);
const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
const principal = Services.scriptSecurityManager.createCodebasePrincipal(
uri,
{}
);
Services.perms.addFromPrincipal(principal, "popup", Services.perms.ALLOW_ACTION);
Services.perms.addFromPrincipal(
principal,
"popup",
Services.perms.ALLOW_ACTION
);
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -72,37 +97,62 @@ add_task(async _ => {
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#openPopups",
{},
tab.linkedBrowser
);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
await new Promise(aResolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
Assert.equal(value, 0);
aResolve();
});
Services.clearData.deleteData(
Ci.nsIClearDataService.CLEAR_PERMISSIONS,
value => {
Assert.equal(value, 0);
aResolve();
}
);
});
});
add_task(async _ => {
info("2 window.open()s in a mouseup event allowed because whitelisted domain.");
info(
"2 window.open()s in a mouseup event allowed because whitelisted domain."
);
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
const uri = Services.io.newURI(TEST_DOMAIN);
const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
const principal = Services.scriptSecurityManager.createCodebasePrincipal(
uri,
{}
);
Services.perms.addFromPrincipal(principal, "popup", Services.perms.ALLOW_ACTION);
Services.perms.addFromPrincipal(
principal,
"popup",
Services.perms.ALLOW_ACTION
);
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -110,32 +160,50 @@ add_task(async _ => {
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#input", { type: "mouseup" }, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#input",
{ type: "mouseup" },
tab.linkedBrowser
);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
await new Promise(aResolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
Assert.equal(value, 0);
aResolve();
});
Services.clearData.deleteData(
Ci.nsIClearDataService.CLEAR_PERMISSIONS,
value => {
Assert.equal(value, 0);
aResolve();
}
);
});
});
add_task(async _ => {
info("2 window.open()s in a single click event: only the first one is allowed.");
info(
"2 window.open()s in a single click event: only the first one is allowed."
);
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -143,35 +211,54 @@ add_task(async _ => {
let p = ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
content.addEventListener("DOMPopupBlocked", () => {
ok(true, "The popup has been blocked");
resolve();
}, {once:true});
content.addEventListener(
"DOMPopupBlocked",
() => {
ok(true, "The popup has been blocked");
resolve();
},
{ once: true }
);
});
});
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#openPopups",
{},
tab.linkedBrowser
);
await p;
await obs;
ok(true, "We had only 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("2 window.open()s in a single mouseup event: only the first one is allowed.");
info(
"2 window.open()s in a single mouseup event: only the first one is allowed."
);
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -179,22 +266,34 @@ add_task(async _ => {
let p = ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
content.addEventListener("DOMPopupBlocked", () => {
ok(true, "The popup has been blocked");
resolve();
}, {once:true});
content.addEventListener(
"DOMPopupBlocked",
() => {
ok(true, "The popup has been blocked");
resolve();
},
{ once: true }
);
});
});
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#input", { type: "mouseup" }, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#input",
{ type: "mouseup" },
tab.linkedBrowser
);
await p;
await obs;
ok(true, "We had only 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});
@ -202,12 +301,17 @@ add_task(async _ => {
add_task(async _ => {
info("2 window.open()s by non-event code: no windows allowed.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html?openPopups")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html?openPopups"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -225,14 +329,18 @@ add_task(async _ => {
});
let p = content.document.createElement("p");
p.setAttribute('id', 'start');
p.setAttribute("id", "start");
content.document.body.appendChild(p);
});
});
ok(true, "We had 0 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});
@ -240,19 +348,31 @@ add_task(async _ => {
add_task(async _ => {
info("2 window.open()s by non-event code allowed by permission");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
const uri = Services.io.newURI(TEST_DOMAIN);
const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
const principal = Services.scriptSecurityManager.createCodebasePrincipal(
uri,
{}
);
Services.perms.addFromPrincipal(principal, "popup", Services.perms.ALLOW_ACTION);
Services.perms.addFromPrincipal(
principal,
"popup",
Services.perms.ALLOW_ACTION
);
let obs = new WindowObserver(2);
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html?openPopups")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html?openPopups"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -260,27 +380,41 @@ add_task(async _ => {
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
await new Promise(aResolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
Assert.equal(value, 0);
aResolve();
});
Services.clearData.deleteData(
Ci.nsIClearDataService.CLEAR_PERMISSIONS,
value => {
Assert.equal(value, 0);
aResolve();
}
);
});
});
add_task(async _ => {
info("1 window.open() executing another window.open(): only the first one is allowed.");
info(
"1 window.open() executing another window.open(): only the first one is allowed."
);
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -289,12 +423,20 @@ add_task(async _ => {
// We don't receive DOMPopupBlocked for nested windows. Let's use just the observer.
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#openNestedPopups", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#openNestedPopups",
{},
tab.linkedBrowser
);
await obs;
ok(true, "We had 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});
@ -302,12 +444,17 @@ add_task(async _ => {
add_task(async _ => {
info("window.open() and .click() on the element opening the window.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -315,22 +462,34 @@ add_task(async _ => {
let p = ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
content.addEventListener("DOMPopupBlocked", () => {
ok(true, "The popup has been blocked");
resolve();
}, {once:true});
content.addEventListener(
"DOMPopupBlocked",
() => {
ok(true, "The popup has been blocked");
resolve();
},
{ once: true }
);
});
});
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopupAndClick", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#openPopupAndClick",
{},
tab.linkedBrowser
);
await p;
await obs;
ok(true, "We had only 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});
@ -338,12 +497,17 @@ add_task(async _ => {
add_task(async _ => {
info("All opened from chrome.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
await SpecialPowers.pushPrefEnv({
set: [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
],
});
let tab = BrowserTestUtils.addTab(gBrowser, CHROME_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
let tab = BrowserTestUtils.addTab(
gBrowser,
CHROME_DOMAIN + TEST_PATH + "browser_multiple_popups.html"
);
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
@ -351,12 +515,20 @@ add_task(async _ => {
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#openPopups",
{},
tab.linkedBrowser
);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
await BrowserTestUtils.synthesizeMouseAtCenter(
"#closeAllWindows",
{},
tab.linkedBrowser
);
BrowserTestUtils.removeTab(tab);
});

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

@ -4,12 +4,18 @@ function test() {
var tab = BrowserTestUtils.addTab(gBrowser);
gBrowser.selectedTab = tab;
tab.linkedBrowser.addEventListener("load", function() {
tab.linkedBrowser.addEventListener("pagehide", function() {
ok(true, "got page hide event");
finish();
});
tab.linkedBrowser.addEventListener(
"load",
function() {
tab.linkedBrowser.addEventListener("pagehide", function() {
ok(true, "got page hide event");
finish();
});
executeSoon(() => { gBrowser.removeTab(tab); });
}, {capture: true, once: true});
executeSoon(() => {
gBrowser.removeTab(tab);
});
},
{ capture: true, once: true }
);
}

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

@ -29,10 +29,14 @@ const gWindowUtils = window.windowUtils;
* current window.
*/
function assertNoFlushesRequired() {
Assert.ok(!gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_STYLE),
"No style flushes are required.");
Assert.ok(!gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_LAYOUT),
"No layout flushes are required.");
Assert.ok(
!gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_STYLE),
"No style flushes are required."
);
Assert.ok(
!gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_LAYOUT),
"No layout flushes are required."
);
}
/**
@ -40,10 +44,14 @@ function assertNoFlushesRequired() {
* are required.
*/
function assertFlushesRequired() {
Assert.ok(gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_STYLE),
"Style flush required.");
Assert.ok(gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_LAYOUT),
"Layout flush required.");
Assert.ok(
gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_STYLE),
"Style flush required."
);
Assert.ok(
gWindowUtils.needsFlush(Ci.nsIDOMWindowUtils.FLUSH_LAYOUT),
"Layout flush required."
);
}
/**
@ -104,8 +112,7 @@ add_task(async function test_can_get_results_from_callback() {
});
for (let prop in paddings) {
Assert.equal(paddings[prop], NEW_PADDING,
"Got expected padding");
Assert.equal(paddings[prop], NEW_PADDING, "Got expected padding");
}
await cleanTheDOM();
@ -120,8 +127,10 @@ add_task(async function test_can_get_results_from_callback() {
Assert.ok(false, "A reflow should not have occurred.");
},
reflowInterruptible() {},
QueryInterface: ChromeUtils.generateQI([Ci.nsIReflowObserver,
Ci.nsISupportsWeakReference])
QueryInterface: ChromeUtils.generateQI([
Ci.nsIReflowObserver,
Ci.nsISupportsWeakReference,
]),
};
let docShell = window.docShell;
@ -138,7 +147,10 @@ add_task(async function test_can_get_results_from_callback() {
// rect was returned, so checking for properties being greater than
// 0 is sufficient.
for (let property of ["width", "height"]) {
Assert.ok(rect[property] > 0, `Rect property ${property} > 0 (${rect[property]})`);
Assert.ok(
rect[property] > 0,
`Rect property ${property} > 0 (${rect[property]})`
);
}
await cleanTheDOM();
@ -205,43 +217,52 @@ add_task(async function test_execution_order() {
let result = [];
dirtyStyleAndLayout(1);
let promise1 = window.promiseDocumentFlushed(() => {
result.push(0);
}).then(() => {
result.push(2);
});
let promise1 = window
.promiseDocumentFlushed(() => {
result.push(0);
})
.then(() => {
result.push(2);
});
let promise2 = window.promiseDocumentFlushed(() => {
result.push(1);
}).then(() => {
result.push(3);
});
let promise2 = window
.promiseDocumentFlushed(() => {
result.push(1);
})
.then(() => {
result.push(3);
});
await Promise.all([promise1, promise2]);
Assert.equal(result.length, 4,
"Should have run all callbacks and Promises.");
Assert.equal(result.length, 4, "Should have run all callbacks and Promises.");
let promise3 = window.promiseDocumentFlushed(() => {
result.push(4);
}).then(() => {
result.push(6);
});
let promise3 = window
.promiseDocumentFlushed(() => {
result.push(4);
})
.then(() => {
result.push(6);
});
let promise4 = window.promiseDocumentFlushed(() => {
result.push(5);
}).then(() => {
result.push(7);
});
let promise4 = window
.promiseDocumentFlushed(() => {
result.push(5);
})
.then(() => {
result.push(7);
});
await Promise.all([promise3, promise4]);
Assert.equal(result.length, 8,
"Should have run all callbacks and Promises.");
Assert.equal(result.length, 8, "Should have run all callbacks and Promises.");
for (let i = 0; i < result.length; ++i) {
Assert.equal(result[i], i,
"Callbacks and Promises should have run in the expected order.");
Assert.equal(
result[i],
i,
"Callbacks and Promises should have run in the expected order."
);
}
await cleanTheDOM();

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

@ -4,18 +4,19 @@
"use strict";
const { addObserver, removeObserver } = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const { openWindow } = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
const { addObserver, removeObserver } = Cc[
"@mozilla.org/observer-service;1"
].getService(Ci.nsIObserverService);
const { openWindow } = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(
Ci.nsIWindowWatcher
);
const Test = routine => () => {
waitForExplicitFinish();
routine()
.then(finish, error => {
ok(false, error);
finish();
});
routine().then(finish, error => {
ok(false, error);
finish();
});
};
// Returns promise for the observer notification subject for
@ -33,7 +34,9 @@ const receive = (topic, p, syncCallback) => {
observe: subject => {
// Browser loads bunch of other documents that we don't care
// about so we let allow filtering notifications via `p` function.
if (p && !p(subject)) return;
if (p && !p(subject)) {
return;
}
// If observer is a first one with a given `topic`
// in a queue resolve promise and take it off the queue
// otherwise keep waiting.
@ -48,7 +51,7 @@ const receive = (topic, p, syncCallback) => {
}
resolve(subject);
}
}
},
};
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
const id = setTimeout(timeout, 90000);
@ -58,7 +61,8 @@ const receive = (topic, p, syncCallback) => {
};
receive.queue = [];
const openTab = uri => gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, uri);
const openTab = uri =>
(gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, uri));
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
@ -67,17 +71,22 @@ const isData = document => document.URL.startsWith("data:");
const uri1 = "data:text/html;charset=utf-8,<h1>1</h1>";
// For whatever reason going back on load event doesn't work so timeout it is :(
const uri2 = "data:text/html;charset=utf-8,<h1>2</h1><script>setTimeout(SpecialPowers.wrap(window).back,100)</script>";
const uri2 =
"data:text/html;charset=utf-8,<h1>2</h1><script>setTimeout(SpecialPowers.wrap(window).back,100)</script>";
const uri3 = "data:text/html;charset=utf-8,<h1>3</h1>";
const uri4 = "chrome://browser/content/license.html";
const test = Test(async function() {
let documentInteractive = receive("content-document-interactive", isData, d => {
// This test is executed synchronously when the event is received.
is(d.readyState, "interactive", "document is interactive");
is(d.URL, uri1, "document.URL matches tab url");
});
let documentInteractive = receive(
"content-document-interactive",
isData,
d => {
// This test is executed synchronously when the event is received.
is(d.readyState, "interactive", "document is interactive");
is(d.URL, uri1, "document.URL matches tab url");
}
);
let documentLoaded = receive("content-document-loaded", isData);
let pageShown = receive("content-page-shown", isData);
@ -124,7 +133,6 @@ const test = Test(async function() {
info("go back to uri#1");
documentInteractive = receive("content-document-interactive", isData, d => {
// This test is executed synchronously when the event is received.
is(d.readyState, "interactive", "document is interactive");

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

@ -32,7 +32,11 @@ async function runTest(url) {
let newBrowser = gBrowser.getBrowserForTab(newTab);
// Wait for the UI to indicate that audio is being played back.
let promise = BrowserTestUtils.waitForAttribute("soundplaying", newTab, "true");
let promise = BrowserTestUtils.waitForAttribute(
"soundplaying",
newTab,
"true"
);
BrowserTestUtils.loadURI(newBrowser, url);
await promise;
@ -55,9 +59,9 @@ async function runTest(url) {
}
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({"set": [
["dom.min_background_timeout_value", kMinTimeoutBackground],
]});
await SpecialPowers.pushPrefEnv({
set: [["dom.min_background_timeout_value", kMinTimeoutBackground]],
});
});
add_task(async function test() {

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

@ -10,81 +10,122 @@ const gHttpTestRoot = "http://example.com/browser/dom/base/test/";
var gOldContentCanRecord = false;
var gOldParentCanRecord = false;
add_task(async function test_initialize() {
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
gOldParentCanRecord = Telemetry.canRecordExtended
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
Ci.nsITelemetry
);
gOldParentCanRecord = Telemetry.canRecordExtended;
Telemetry.canRecordExtended = true;
// Because canRecordExtended is a per-process variable, we need to make sure
// that all of the pages load in the same content process. Limit the number
// of content processes to at most 1 (or 0 if e10s is off entirely).
await SpecialPowers.pushPrefEnv({ set: [[ "dom.ipc.processCount", 1 ]] });
await SpecialPowers.pushPrefEnv({ set: [["dom.ipc.processCount", 1]] });
gOldContentCanRecord = await ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
let old = telemetry.canRecordExtended;
telemetry.canRecordExtended = true;
return old;
});
gOldContentCanRecord = await ContentTask.spawn(
gBrowser.selectedBrowser,
{},
function() {
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
Ci.nsITelemetry
);
let old = telemetry.canRecordExtended;
telemetry.canRecordExtended = true;
return old;
}
);
info("canRecord for content: " + gOldContentCanRecord);
});
add_task(async function() {
// Check that use counters are incremented by SVGs loaded directly in iframes.
await check_use_counter_iframe("file_use_counter_svg_getElementById.svg",
"SVGSVGELEMENT_GETELEMENTBYID");
await check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_getter");
await check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_setter");
await check_use_counter_iframe(
"file_use_counter_svg_getElementById.svg",
"SVGSVGELEMENT_GETELEMENTBYID"
);
await check_use_counter_iframe(
"file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_getter"
);
await check_use_counter_iframe(
"file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_setter"
);
// Check that even loads from the imglib cache update use counters. The
// images should still be there, because we just loaded them in the last
// set of tests. But we won't get updated counts for the document
// counters, because we won't be re-parsing the SVG documents.
await check_use_counter_iframe("file_use_counter_svg_getElementById.svg",
"SVGSVGELEMENT_GETELEMENTBYID", false);
await check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_getter", false);
await check_use_counter_iframe("file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_setter", false);
await check_use_counter_iframe(
"file_use_counter_svg_getElementById.svg",
"SVGSVGELEMENT_GETELEMENTBYID",
false
);
await check_use_counter_iframe(
"file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_getter",
false
);
await check_use_counter_iframe(
"file_use_counter_svg_currentScale.svg",
"SVGSVGELEMENT_CURRENTSCALE_setter",
false
);
// Check that use counters are incremented by SVGs loaded as images.
// Note that SVG images are not permitted to execute script, so we can only
// check for properties here.
await check_use_counter_img("file_use_counter_svg_getElementById.svg",
"PROPERTY_FILL");
await check_use_counter_img("file_use_counter_svg_currentScale.svg",
"PROPERTY_FILL");
await check_use_counter_img(
"file_use_counter_svg_getElementById.svg",
"PROPERTY_FILL"
);
await check_use_counter_img(
"file_use_counter_svg_currentScale.svg",
"PROPERTY_FILL"
);
// Check that use counters are incremented by directly loading SVGs
// that reference patterns defined in another SVG file.
await check_use_counter_direct("file_use_counter_svg_fill_pattern.svg",
"PROPERTY_FILLOPACITY", /*xfail=*/true);
await check_use_counter_direct(
"file_use_counter_svg_fill_pattern.svg",
"PROPERTY_FILLOPACITY",
/*xfail=*/ true
);
// Check that use counters are incremented by directly loading SVGs
// that reference patterns defined in the same file or in data: URLs.
await check_use_counter_direct("file_use_counter_svg_fill_pattern_internal.svg",
"PROPERTY_FILLOPACITY");
await check_use_counter_direct(
"file_use_counter_svg_fill_pattern_internal.svg",
"PROPERTY_FILLOPACITY"
);
// data: URLs don't correctly propagate to their referring document yet.
//yield check_use_counter_direct("file_use_counter_svg_fill_pattern_data.svg",
// "PROPERTY_FILL_OPACITY");
});
add_task(async function() {
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
Ci.nsITelemetry
);
Telemetry.canRecordExtended = gOldParentCanRecord;
await ContentTask.spawn(gBrowser.selectedBrowser, { oldCanRecord: gOldContentCanRecord }, async function(arg) {
const {PromiseUtils} = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
await new Promise(resolve => {
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
telemetry.canRecordExtended = arg.oldCanRecord;
resolve();
});
});
await ContentTask.spawn(
gBrowser.selectedBrowser,
{ oldCanRecord: gOldContentCanRecord },
async function(arg) {
const { PromiseUtils } = ChromeUtils.import(
"resource://gre/modules/PromiseUtils.jsm"
);
await new Promise(resolve => {
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
Ci.nsITelemetry
);
telemetry.canRecordExtended = arg.oldCanRecord;
resolve();
});
}
);
});
function waitForDestroyedDocuments() {
let deferred = PromiseUtils.defer();
SpecialPowers.exactGC(deferred.resolve);
@ -93,19 +134,23 @@ function waitForDestroyedDocuments() {
function waitForPageLoad(browser) {
return ContentTask.spawn(browser, null, async function() {
const {PromiseUtils} = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
const { PromiseUtils } = ChromeUtils.import(
"resource://gre/modules/PromiseUtils.jsm"
);
await new Promise(resolve => {
let listener = () => {
removeEventListener("load", listener, true);
resolve();
}
};
addEventListener("load", listener, true);
});
});
}
function grabHistogramsFromContent(use_counter_middlefix, page_before = null) {
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
Ci.nsITelemetry
);
let gather = () => {
let snapshots;
if (Services.appinfo.browserTabsRemoteAutostart) {
@ -113,7 +158,7 @@ function grabHistogramsFromContent(use_counter_middlefix, page_before = null) {
} else {
snapshots = telemetry.getSnapshotForHistograms("main", false).parent;
}
let checkGet = (probe) => {
let checkGet = probe => {
return snapshots[probe] ? snapshots[probe].sum : 0;
};
return [
@ -128,32 +173,46 @@ function grabHistogramsFromContent(use_counter_middlefix, page_before = null) {
}).then(gather, gather);
}
var check_use_counter_iframe = async function(file, use_counter_middlefix, check_documents=true) {
var check_use_counter_iframe = async function(
file,
use_counter_middlefix,
check_documents = true
) {
info("checking " + file + " with histogram " + use_counter_middlefix);
let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
gBrowser.selectedTab = newTab;
newTab.linkedBrowser.stop();
// Hold on to the current values of the telemetry histograms we're
// interested in.
let [histogram_page_before, histogram_document_before,
histogram_docs_before, histogram_toplevel_docs_before] =
await grabHistogramsFromContent(use_counter_middlefix);
let [
histogram_page_before,
histogram_document_before,
histogram_docs_before,
histogram_toplevel_docs_before,
] = await grabHistogramsFromContent(use_counter_middlefix);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gHttpTestRoot + "file_use_counter_outer.html");
BrowserTestUtils.loadURI(
gBrowser.selectedBrowser,
gHttpTestRoot + "file_use_counter_outer.html"
);
await waitForPageLoad(gBrowser.selectedBrowser);
// Inject our desired file into the iframe of the newly-loaded page.
await ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) {
const {PromiseUtils} = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
await ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(
opts
) {
const { PromiseUtils } = ChromeUtils.import(
"resource://gre/modules/PromiseUtils.jsm"
);
let deferred = PromiseUtils.defer();
let wu = content.window.windowUtils;
let iframe = content.document.getElementById('content');
let iframe = content.document.getElementById("content");
iframe.src = opts.file;
let listener = (event) => {
let listener = event => {
event.target.removeEventListener("load", listener, true);
// We flush the main document first, then the iframe's document to
@ -178,22 +237,38 @@ var check_use_counter_iframe = async function(file, use_counter_middlefix, check
await waitForDestroyedDocuments();
// Grab histograms again and compare.
let [histogram_page_after, histogram_document_after,
histogram_docs_after, histogram_toplevel_docs_after] =
await grabHistogramsFromContent(use_counter_middlefix, histogram_page_before);
let [
histogram_page_after,
histogram_document_after,
histogram_docs_after,
histogram_toplevel_docs_after,
] = await grabHistogramsFromContent(
use_counter_middlefix,
histogram_page_before
);
is(histogram_page_after, histogram_page_before + 1,
"page counts for " + use_counter_middlefix + " after are correct");
ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
"top level document counts are correct");
is(
histogram_page_after,
histogram_page_before + 1,
"page counts for " + use_counter_middlefix + " after are correct"
);
ok(
histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
"top level document counts are correct"
);
if (check_documents) {
is(histogram_document_after, histogram_document_before + 1,
"document counts for " + use_counter_middlefix + " after are correct");
is(
histogram_document_after,
histogram_document_before + 1,
"document counts for " + use_counter_middlefix + " after are correct"
);
}
};
var check_use_counter_img = async function(file, use_counter_middlefix) {
info("checking " + file + " as image with histogram " + use_counter_middlefix);
info(
"checking " + file + " as image with histogram " + use_counter_middlefix
);
let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
gBrowser.selectedTab = newTab;
@ -201,38 +276,50 @@ var check_use_counter_img = async function(file, use_counter_middlefix) {
// Hold on to the current values of the telemetry histograms we're
// interested in.
let [histogram_page_before, histogram_document_before,
histogram_docs_before, histogram_toplevel_docs_before] =
await grabHistogramsFromContent(use_counter_middlefix);
let [
histogram_page_before,
histogram_document_before,
histogram_docs_before,
histogram_toplevel_docs_before,
] = await grabHistogramsFromContent(use_counter_middlefix);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gHttpTestRoot + "file_use_counter_outer.html");
BrowserTestUtils.loadURI(
gBrowser.selectedBrowser,
gHttpTestRoot + "file_use_counter_outer.html"
);
await waitForPageLoad(gBrowser.selectedBrowser);
// Inject our desired file into the img of the newly-loaded page.
await ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, async function(opts) {
const {PromiseUtils} = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
let deferred = PromiseUtils.defer();
await ContentTask.spawn(
gBrowser.selectedBrowser,
{ file: file },
async function(opts) {
const { PromiseUtils } = ChromeUtils.import(
"resource://gre/modules/PromiseUtils.jsm"
);
let deferred = PromiseUtils.defer();
let img = content.document.getElementById('display');
img.src = opts.file;
let listener = (event) => {
img.removeEventListener("load", listener, true);
let img = content.document.getElementById("display");
img.src = opts.file;
let listener = event => {
img.removeEventListener("load", listener, true);
// Flush for the image. It matters what order we do these in, so that
// the image can propagate its use counters to the document prior to the
// document reporting its use counters.
let wu = content.window.windowUtils;
wu.forceUseCounterFlush(img);
// Flush for the image. It matters what order we do these in, so that
// the image can propagate its use counters to the document prior to the
// document reporting its use counters.
let wu = content.window.windowUtils;
wu.forceUseCounterFlush(img);
// Flush for the main window.
wu.forceUseCounterFlush(content.document);
// Flush for the main window.
wu.forceUseCounterFlush(content.document);
deferred.resolve();
};
img.addEventListener("load", listener, true);
deferred.resolve();
};
img.addEventListener("load", listener, true);
return deferred.promise;
});
return deferred.promise;
}
);
// Tear down the page.
gBrowser.removeTab(newTab);
@ -243,37 +330,62 @@ var check_use_counter_img = async function(file, use_counter_middlefix) {
await waitForDestroyedDocuments();
// Grab histograms again and compare.
let [histogram_page_after, histogram_document_after,
histogram_docs_after, histogram_toplevel_docs_after] =
await grabHistogramsFromContent(use_counter_middlefix, histogram_page_before);
is(histogram_page_after, histogram_page_before + 1,
"page counts for " + use_counter_middlefix + " after are correct");
is(histogram_document_after, histogram_document_before + 1,
"document counts for " + use_counter_middlefix + " after are correct");
ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
"top level document counts are correct");
let [
histogram_page_after,
histogram_document_after,
histogram_docs_after,
histogram_toplevel_docs_after,
] = await grabHistogramsFromContent(
use_counter_middlefix,
histogram_page_before
);
is(
histogram_page_after,
histogram_page_before + 1,
"page counts for " + use_counter_middlefix + " after are correct"
);
is(
histogram_document_after,
histogram_document_before + 1,
"document counts for " + use_counter_middlefix + " after are correct"
);
ok(
histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
"top level document counts are correct"
);
// 2 documents: one for the outer html page containing the <img> element, and
// one for the SVG image itself.
ok(histogram_docs_after >= histogram_docs_before + 2,
"document counts are correct");
ok(
histogram_docs_after >= histogram_docs_before + 2,
"document counts are correct"
);
};
var check_use_counter_direct = async function(file, use_counter_middlefix, xfail=false) {
var check_use_counter_direct = async function(
file,
use_counter_middlefix,
xfail = false
) {
info("checking " + file + " with histogram " + use_counter_middlefix);
let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
gBrowser.selectedTab = newTab;
newTab.linkedBrowser.stop();
// Hold on to the current values of the telemetry histograms we're
// interested in.
let [histogram_page_before, histogram_document_before,
histogram_docs_before, histogram_toplevel_docs_before] =
await grabHistogramsFromContent(use_counter_middlefix);
let [
histogram_page_before,
histogram_document_before,
histogram_docs_before,
histogram_toplevel_docs_before,
] = await grabHistogramsFromContent(use_counter_middlefix);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gHttpTestRoot + file);
await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
const {PromiseUtils} = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
const { PromiseUtils } = ChromeUtils.import(
"resource://gre/modules/PromiseUtils.jsm"
);
await new Promise(resolve => {
let listener = () => {
removeEventListener("load", listener, true);
@ -282,7 +394,7 @@ var check_use_counter_direct = async function(file, use_counter_middlefix, xfail
wu.forceUseCounterFlush(content.document);
setTimeout(resolve, 0);
}
};
addEventListener("load", listener, true);
});
});
@ -296,17 +408,33 @@ var check_use_counter_direct = async function(file, use_counter_middlefix, xfail
await waitForDestroyedDocuments();
// Grab histograms again and compare.
let [histogram_page_after, histogram_document_after,
histogram_docs_after, histogram_toplevel_docs_after] =
await grabHistogramsFromContent(use_counter_middlefix, histogram_page_before);
let [
histogram_page_after,
histogram_document_after,
histogram_docs_after,
histogram_toplevel_docs_after,
] = await grabHistogramsFromContent(
use_counter_middlefix,
histogram_page_before
);
if (!xfail) {
is(histogram_page_after, histogram_page_before + 1,
"page counts for " + use_counter_middlefix + " after are correct");
is(histogram_document_after, histogram_document_before + 1,
"document counts for " + use_counter_middlefix + " after are correct");
is(
histogram_page_after,
histogram_page_before + 1,
"page counts for " + use_counter_middlefix + " after are correct"
);
is(
histogram_document_after,
histogram_document_before + 1,
"document counts for " + use_counter_middlefix + " after are correct"
);
}
ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
"top level document counts are correct");
ok(histogram_docs_after >= histogram_docs_before + 1,
"document counts are correct");
ok(
histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
"top level document counts are correct"
);
ok(
histogram_docs_after >= histogram_docs_before + 1,
"document counts are correct"
);
};

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

@ -1,14 +1,16 @@
Cu.importGlobalProperties(["File"]);
var testFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
testFile.append("prefs.js");
addMessageListener("file.open", function () {
addMessageListener("file.open", function() {
File.createFromNsIFile(testFile).then(function(file) {
File.createFromNsIFile(testFile, { lastModified: 123 }).then(function(fileWithDate) {
File.createFromNsIFile(testFile, { lastModified: 123 }).then(function(
fileWithDate
) {
sendAsyncMessage("file.opened", {
file,
mtime: testFile.lastModifiedTime,

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

@ -1,3 +1,3 @@
var a = 0;
var b = 0;
c();
c();

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

@ -1,10 +1,10 @@
var file;
Cu.importGlobalProperties(["File"]);
addMessageListener("file.create", function (message) {
addMessageListener("file.create", function(message) {
file = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("TmpD", Ci.nsIFile);
.getService(Ci.nsIProperties)
.get("TmpD", Ci.nsIFile);
file.append("foo.txt");
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
File.createFromNsIFile(file).then(function(domFile) {
@ -12,7 +12,7 @@ addMessageListener("file.create", function (message) {
});
});
addMessageListener("file.remove", function (message) {
addMessageListener("file.remove", function(message) {
file.remove(false);
sendAsyncMessage("file.removed", {});
});

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

@ -1,3 +1,3 @@
var a = 0;
var global = "ran";
c();
c();

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

@ -1,3 +1,3 @@
var a = 0;
var global = "ran";
c();
c();

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

@ -3,7 +3,9 @@
var test = function(isContent) {
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", true]]});
SpecialPowers.pushPrefEnv({
set: [["security.allow_eval_with_system_principal", true]],
});
let { ww } = SpecialPowers.Services;
window.chromeWindow = ww.activeWindow;
@ -38,16 +40,20 @@ var test = function(isContent) {
};
// Returns generator object that iterates through pref values.
let prefVals = (function* () { yield false; yield true; })();
let prefVals = (function*() {
yield false;
yield true;
})();
// The main test function, runs until all pref values are exhausted.
let nextTest = function() {
let {value: prefValue, done} = prefVals.next();
let { value: prefValue, done } = prefVals.next();
if (done) {
SimpleTest.finish();
return;
}
SpecialPowers.pushPrefEnv({set: [["privacy.resistFingerprinting", prefValue]]},
SpecialPowers.pushPrefEnv(
{ set: [["privacy.resistFingerprinting", prefValue]] },
function() {
// We will be resisting fingerprinting if the pref is enabled,
// and we are in a content script (not chrome).
@ -57,18 +63,23 @@ var test = function(isContent) {
if (resisting) {
checkPair("window." + item, onVal);
} else if (!item.startsWith("moz")) {
checkPair("window." + item, "chromeWindow." + item);
}
checkPair("window." + item, "chromeWindow." + item);
}
});
if (!resisting) {
// Hard to predict these values, but we can enforce constraints:
ok(window.mozInnerScreenX >= chromeWindow.mozInnerScreenX,
"mozInnerScreenX");
ok(window.mozInnerScreenY >= chromeWindow.mozInnerScreenY,
"mozInnerScreenY");
ok(
window.mozInnerScreenX >= chromeWindow.mozInnerScreenX,
"mozInnerScreenX"
);
ok(
window.mozInnerScreenY >= chromeWindow.mozInnerScreenY,
"mozInnerScreenY"
);
}
nextTest();
});
nextTest();
}
);
};
nextTest();

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

@ -53,22 +53,34 @@ var sync_obj;
var async_obj;
function make_object() {
let o = { };
let o = {};
o.i = 5;
o.b = true;
o.s = "hello";
o.x = { i: 10 };
o.f = function() { return 99; };
o.ctor = function() { this.a = 3; };
o.f = function() {
return 99;
};
o.ctor = function() {
this.a = 3;
};
// Doing anything with this Proxy will throw.
var throwing = new Proxy({}, new Proxy({}, {
get(trap) { throw trap; },
}));
var throwing = new Proxy(
{},
new Proxy(
{},
{
get(trap) {
throw trap;
},
}
)
);
let array = [1, 2, 3];
let for_json = { "n": 3, "a": array, "s": "hello", o: { "x": 10 } };
let for_json = { n: 3, a: array, s: "hello", o: { x: 10 } };
let proto = { data: 42 };
let with_proto = Object.create(proto);
@ -76,14 +88,15 @@ function make_object() {
let with_null_proto = Object.create(null);
content.document.title = "Hello, Kitty";
return { "data": o,
"throwing": throwing,
"document": content.document,
"array": array,
"for_json": for_json,
"with_proto": with_proto,
"with_null_proto": with_null_proto,
};
return {
data: o,
throwing,
document: content.document,
array,
for_json,
with_proto,
with_null_proto,
};
}
function make_json() {
@ -101,7 +114,7 @@ function parent_test(finish) {
return result;
}
addMessageListener("cpows:from_parent", (msg) => {
addMessageListener("cpows:from_parent", msg => {
let obj = msg.objects.obj;
if (is_remote) {
ok(obj.a == undefined, "__exposedProps__ should not work");
@ -121,7 +134,7 @@ function parent_test(finish) {
finish();
});
sendRpcMessage("cpows:parent_test", {}, {func: f});
sendRpcMessage("cpows:parent_test", {}, { func: f });
}
function error_reporting_test(finish) {
@ -134,7 +147,7 @@ function dom_test(finish) {
element.id = "it_works";
content.document.body.appendChild(element);
sendRpcMessage("cpows:dom_test", {}, {element});
sendRpcMessage("cpows:dom_test", {}, { element });
Cu.schedulePreciseGC(function() {
sendRpcMessage("cpows:dom_test_after_gc");
finish();
@ -145,7 +158,7 @@ function xray_test(finish) {
let element = content.document.createElement("div");
element.wrappedJSObject.foo = "hello";
sendRpcMessage("cpows:xray_test", {}, {element});
sendRpcMessage("cpows:xray_test", {}, { element });
finish();
}
@ -158,7 +171,7 @@ function symbol_test(finish) {
[named]: named,
};
let test = ["a"];
sendRpcMessage("cpows:symbol_test", {}, {object, test});
sendRpcMessage("cpows:symbol_test", {}, { object, test });
finish();
}
@ -172,15 +185,26 @@ function compartment_test(finish) {
return;
}
let sb = Cu.Sandbox("http://www.example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
sb.eval("function getUnprivilegedObject() { var xhr = new XMLHttpRequest(); xhr.expando = 42; return xhr; }");
let sb = Cu.Sandbox("http://www.example.com", {
wantGlobalProperties: ["XMLHttpRequest"],
});
sb.eval(
"function getUnprivilegedObject() { var xhr = new XMLHttpRequest(); xhr.expando = 42; return xhr; }"
);
function testParentObject(obj) {
let results = [];
function is(a, b, msg) { results.push({ result: a === b ? "PASS" : "FAIL", message: msg }); }
function ok1(x, msg) { results.push({ result: x ? "PASS" : "FAIL", message: msg }); }
function is(a, b, msg) {
results.push({ result: a === b ? "PASS" : "FAIL", message: msg });
}
function ok1(x, msg) {
results.push({ result: x ? "PASS" : "FAIL", message: msg });
}
let cpowLocation = Cu.getRealmLocation(obj);
ok1(/shared JSM global/.test(cpowLocation),
"child->parent CPOWs should live in the privileged junk scope: " + cpowLocation);
ok1(
/shared JSM global/.test(cpowLocation),
"child->parent CPOWs should live in the privileged junk scope: " +
cpowLocation
);
is(obj(), 42, "child->parent CPOW is invokable");
try {
obj.expando;
@ -191,8 +215,11 @@ function compartment_test(finish) {
return results;
}
sendRpcMessage("cpows:compartment_test", {}, { getUnprivilegedObject: sb.getUnprivilegedObject,
testParentObject });
sendRpcMessage(
"cpows:compartment_test",
{},
{ getUnprivilegedObject: sb.getUnprivilegedObject, testParentObject }
);
finish();
}
@ -209,18 +236,14 @@ function postmessage_test(finish) {
function sync_test(finish) {
dump("beginning cpow sync test\n");
sync_obj = make_object();
sendRpcMessage("cpows:sync",
make_json(),
make_object());
sendRpcMessage("cpows:sync", make_json(), make_object());
finish();
}
function async_test(finish) {
dump("beginning cpow async test\n");
async_obj = make_object();
sendAsyncMessage("cpows:async",
make_json(),
async_obj);
sendAsyncMessage("cpows:async", make_json(), async_obj);
addMessageListener("cpows:async_done", finish);
}
@ -231,12 +254,10 @@ function rpc_test(finish) {
dump("beginning cpow rpc test\n");
rpc_obj = make_object();
rpc_obj.data.reenter = function() {
sendRpcMessage("cpows:reenter", { }, { data: { valid: true } });
sendRpcMessage("cpows:reenter", {}, { data: { valid: true } });
return "ok";
};
sendRpcMessage("cpows:rpc",
make_json(),
rpc_obj);
sendRpcMessage("cpows:rpc", make_json(), rpc_obj);
finish();
}
@ -250,13 +271,13 @@ function lifetime_test(finish) {
}
dump("beginning lifetime test\n");
var obj = {"will_die": {"f": 1}};
let [result] = sendRpcMessage("cpows:lifetime_test_1", {}, {obj});
var obj = { will_die: { f: 1 } };
let [result] = sendRpcMessage("cpows:lifetime_test_1", {}, { obj });
ok(result == 10, "got sync result");
ok(obj.wont_die.f == undefined, "got reverse CPOW");
obj.will_die = null;
Cu.schedulePreciseGC(function() {
addMessageListener("cpows:lifetime_test_3", (msg) => {
addMessageListener("cpows:lifetime_test_3", msg => {
ok(obj.wont_die.f == undefined, "reverse CPOW still works");
finish();
});
@ -271,7 +292,8 @@ function cancel_test(finish) {
return;
}
let fin1 = false, fin2 = false;
let fin1 = false,
fin2 = false;
// CPOW from the parent runs f. When it sends a sync message, the
// CPOW is canceled. The parent starts running again immediately
@ -280,13 +302,17 @@ function cancel_test(finish) {
let res = sendSyncMessage("cpows:cancel_sync_message");
ok(res[0] == 12, "cancel_sync_message result correct");
fin1 = true;
if (fin1 && fin2) finish();
if (fin1 && fin2) {
finish();
}
}
sendAsyncMessage("cpows:cancel_test", null, {f});
sendAsyncMessage("cpows:cancel_test", null, { f });
addMessageListener("cpows:cancel_test_done", msg => {
fin2 = true;
if (fin1 && fin2) finish();
if (fin1 && fin2) {
finish();
}
});
}
@ -297,7 +323,8 @@ function cancel_test2(finish) {
return;
}
let fin1 = false, fin2 = false;
let fin1 = false,
fin2 = false;
// CPOW from the parent runs f. When it does a sync XHR, the
// CPOW is canceled. The parent starts running again immediately
@ -320,13 +347,17 @@ function cancel_test2(finish) {
ok(fin === true, "XHR happened");
fin1 = true;
if (fin1 && fin2) finish();
if (fin1 && fin2) {
finish();
}
}
sendAsyncMessage("cpows:cancel_test2", null, {f});
sendAsyncMessage("cpows:cancel_test2", null, { f });
addMessageListener("cpows:cancel_test2_done", msg => {
fin2 = true;
if (fin1 && fin2) finish();
if (fin1 && fin2) {
finish();
}
});
}
@ -339,9 +370,9 @@ function unsafe_test(finish) {
function f() {}
sendAsyncMessage("cpows:unsafe", null, {f});
sendAsyncMessage("cpows:unsafe", null, { f });
addMessageListener("cpows:unsafe_done", msg => {
sendRpcMessage("cpows:safe", null, {f});
sendRpcMessage("cpows:safe", null, { f });
addMessageListener("cpows:safe_done", finish);
});
}
@ -381,10 +412,12 @@ function localStorage_test(finish) {
function f() {}
sendAsyncMessage("cpows:localStorage", null, {f});
sendAsyncMessage("cpows:localStorage", null, { f });
addMessageListener("cpows:localStorage_done", finish);
for (let i = 0; i < 3; i++) {
try { content.localStorage.setItem("foo", "bar"); } catch (ex) {}
try {
content.localStorage.setItem("foo", "bar");
} catch (ex) {}
}
}

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

@ -15,39 +15,48 @@ function modifySelection(s) {
a.selectNode(d);
g.removeAllRanges();
g.addRange(a);
window.setTimeout(function () {
e.remove();
g.removeAllRanges();
g.addRange(l);
}, 0)
window.setTimeout(function() {
e.remove();
g.removeAllRanges();
g.addRange(l);
}, 0);
}
function getLoadContext() {
var Ci = SpecialPowers.Ci;
return SpecialPowers.wrap(window).docShell
.QueryInterface(Ci.nsILoadContext);
return SpecialPowers.wrap(window).docShell.QueryInterface(Ci.nsILoadContext);
}
async function testCopyPaste (isXHTML) {
async function testCopyPaste(isXHTML) {
var suppressUnicodeCheckIfHidden = !!isXHTML;
var suppressHTMLCheck = !!isXHTML;
var docShell = SpecialPowers.wrap(window).docShell;
var documentViewer = docShell.contentViewer
.QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
var documentViewer = docShell.contentViewer.QueryInterface(
SpecialPowers.Ci.nsIContentViewerEdit
);
var clipboard = SpecialPowers.Services.clipboard;
var textarea = SpecialPowers.wrap(document.getElementById('input'));
var textarea = SpecialPowers.wrap(document.getElementById("input"));
async function copySelectionToClipboard(suppressUnicodeCheck) {
await SimpleTest.promiseClipboardChange(() => true,
() => { documentViewer.copySelection(); });
if (!suppressUnicodeCheck)
ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1), "check text/unicode");
if (!suppressHTMLCheck)
await SimpleTest.promiseClipboardChange(
() => true,
() => {
documentViewer.copySelection();
}
);
if (!suppressUnicodeCheck) {
ok(
clipboard.hasDataMatchingFlavors(["text/unicode"], 1),
"check text/unicode"
);
}
if (!suppressHTMLCheck) {
ok(clipboard.hasDataMatchingFlavors(["text/html"], 1), "check text/html");
}
}
function clear(node, suppressUnicodeCheck) {
textarea.blur();
@ -61,16 +70,22 @@ async function testCopyPaste (isXHTML) {
window.getSelection().addRange(r);
await copySelectionToClipboard(suppressUnicodeCheck);
}
function addRange(startNode,startIndex,endNode,endIndex) {
function addRange(startNode, startIndex, endNode, endIndex) {
var sel = window.getSelection();
var r = document.createRange();
r.setStart(startNode,startIndex)
r.setEnd(endNode,endIndex)
r.setStart(startNode, startIndex);
r.setEnd(endNode, endIndex);
sel.addRange(r);
}
async function copyRangeToClipboard(startNode,startIndex,endNode,endIndex,suppressUnicodeCheck) {
async function copyRangeToClipboard(
startNode,
startIndex,
endNode,
endIndex,
suppressUnicodeCheck
) {
clear();
addRange(startNode,startIndex,endNode,endIndex);
addRange(startNode, startIndex, endNode, endIndex);
await copySelectionToClipboard(suppressUnicodeCheck);
}
async function copyChildrenToClipboard(id) {
@ -79,13 +94,14 @@ async function testCopyPaste (isXHTML) {
await copySelectionToClipboard();
}
function getClipboardData(mime) {
var transferable = SpecialPowers.Cc['@mozilla.org/widget/transferable;1']
.createInstance(SpecialPowers.Ci.nsITransferable);
var transferable = SpecialPowers.Cc[
"@mozilla.org/widget/transferable;1"
].createInstance(SpecialPowers.Ci.nsITransferable);
transferable.init(getLoadContext());
transferable.addDataFlavor(mime);
clipboard.getData(transferable, 1);
var data = SpecialPowers.createBlankObject();
transferable.getTransferData(mime, data) ;
transferable.getTransferData(mime, data);
return data;
}
function testHtmlClipboardValue(mime, expected) {
@ -93,24 +109,29 @@ async function testCopyPaste (isXHTML) {
var expectedValue = expected;
if (navigator.platform.includes("Win")) {
// Windows has extra content.
var expectedValue = "<html><body>\n<!--StartFragment-->" +
expected.replace(/\n/g, '\n') +
"<!--EndFragment-->\n</body>\n</html>";
var expectedValue =
"<html><body>\n<!--StartFragment-->" +
expected.replace(/\n/g, "\n") +
"<!--EndFragment-->\n</body>\n</html>";
}
testClipboardValue(mime, expectedValue);
}
function testClipboardValue(mime, expected) {
if (suppressHTMLCheck && mime == "text/html")
if (suppressHTMLCheck && mime == "text/html") {
return null;
}
var data = SpecialPowers.wrap(getClipboardData(mime));
is (data.value == null ? data.value :
data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data,
is(
data.value == null
? data.value
: data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data,
expected,
mime + " value in the clipboard");
mime + " value in the clipboard"
);
return data.value;
}
function testPasteText(expected) {
textarea.value="";
textarea.value = "";
textarea.focus();
textarea.editor.paste(1);
is(textarea.value, expected, "value of the textarea after the paste");
@ -118,11 +139,18 @@ async function testCopyPaste (isXHTML) {
function testPasteHTML(id, expected) {
var contentEditable = $(id);
contentEditable.focus();
synthesizeKey("v", {accelKey: true});
is(contentEditable.innerHTML, expected, id+".innerHtml after the paste");
synthesizeKey("v", { accelKey: true });
is(contentEditable.innerHTML, expected, id + ".innerHtml after the paste");
}
function testSelectionToString(expected) {
is(window.getSelection().toString().replace(/\r\n/g,"\n"), expected, "Selection.toString");
is(
window
.getSelection()
.toString()
.replace(/\r\n/g, "\n"),
expected,
"Selection.toString"
);
}
function testInnerHTML(id, expected) {
var value = document.getElementById(id).innerHTML;
@ -131,39 +159,60 @@ async function testCopyPaste (isXHTML) {
await copyChildrenToClipboard("draggable");
testSelectionToString("This is a draggable bit of text.");
testClipboardValue("text/unicode",
"This is a draggable bit of text.");
testHtmlClipboardValue("text/html",
"<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em> bit of text.</div>");
testClipboardValue("text/unicode", "This is a draggable bit of text.");
testHtmlClipboardValue(
"text/html",
'<div id="draggable" title="title to have a long HTML line">This is a <em>draggable</em> bit of text.</div>'
);
testPasteText("This is a draggable bit of text.");
await copyChildrenToClipboard("alist");
testSelectionToString(" bla\n\n foo\n bar\n\n");
testClipboardValue("text/unicode", " bla\n\n foo\n bar\n\n");
testHtmlClipboardValue("text/html", "<div id=\"alist\">\n bla\n <ul>\n <li>foo</li>\n \n <li>bar</li>\n </ul>\n </div>");
testHtmlClipboardValue(
"text/html",
'<div id="alist">\n bla\n <ul>\n <li>foo</li>\n \n <li>bar</li>\n </ul>\n </div>'
);
testPasteText(" bla\n\n foo\n bar\n\n");
await copyChildrenToClipboard("blist");
testSelectionToString(" mozilla\n\n foo\n bar\n\n");
testClipboardValue("text/unicode", " mozilla\n\n foo\n bar\n\n");
testHtmlClipboardValue("text/html", "<div id=\"blist\">\n mozilla\n <ol>\n <li>foo</li>\n \n <li>bar</li>\n </ol>\n </div>");
testHtmlClipboardValue(
"text/html",
'<div id="blist">\n mozilla\n <ol>\n <li>foo</li>\n \n <li>bar</li>\n </ol>\n </div>'
);
testPasteText(" mozilla\n\n foo\n bar\n\n");
await copyChildrenToClipboard("clist");
testSelectionToString(" mzla\n\n foo\n bazzinga!\n bar\n\n");
testClipboardValue("text/unicode", " mzla\n\n foo\n bazzinga!\n bar\n\n");
testHtmlClipboardValue("text/html", "<div id=\"clist\">\n mzla\n <ul>\n <li>foo<ul>\n <li>bazzinga!</li>\n </ul></li>\n \n <li>bar</li>\n </ul>\n </div>");
testClipboardValue(
"text/unicode",
" mzla\n\n foo\n bazzinga!\n bar\n\n"
);
testHtmlClipboardValue(
"text/html",
'<div id="clist">\n mzla\n <ul>\n <li>foo<ul>\n <li>bazzinga!</li>\n </ul></li>\n \n <li>bar</li>\n </ul>\n </div>'
);
testPasteText(" mzla\n\n foo\n bazzinga!\n bar\n\n");
await copyChildrenToClipboard("div4");
testSelectionToString(" Tt t t ");
testClipboardValue("text/unicode", " Tt t t ");
if (isXHTML) {
testHtmlClipboardValue("text/html", "<div id=\"div4\">\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\">t t t</textarea>\n</div>");
testInnerHTML("div4", "\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\">t t t</textarea>\n");
}
else {
testHtmlClipboardValue("text/html", "<div id=\"div4\">\n T<textarea>t t t</textarea>\n</div>");
testHtmlClipboardValue(
"text/html",
'<div id="div4">\n T<textarea xmlns="http://www.w3.org/1999/xhtml">t t t</textarea>\n</div>'
);
testInnerHTML(
"div4",
'\n T<textarea xmlns="http://www.w3.org/1999/xhtml">t t t</textarea>\n'
);
} else {
testHtmlClipboardValue(
"text/html",
'<div id="div4">\n T<textarea>t t t</textarea>\n</div>'
);
testInnerHTML("div4", "\n T<textarea>t t t</textarea>\n");
}
testPasteText(" Tt t t ");
@ -172,46 +221,78 @@ async function testCopyPaste (isXHTML) {
testSelectionToString(" T ");
testClipboardValue("text/unicode", " T ");
if (isXHTML) {
testHtmlClipboardValue("text/html", "<div id=\"div5\">\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\"> </textarea>\n</div>");
testInnerHTML("div5", "\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\"> </textarea>\n");
}
else {
testHtmlClipboardValue("text/html", "<div id=\"div5\">\n T<textarea> </textarea>\n</div>");
testHtmlClipboardValue(
"text/html",
'<div id="div5">\n T<textarea xmlns="http://www.w3.org/1999/xhtml"> </textarea>\n</div>'
);
testInnerHTML(
"div5",
'\n T<textarea xmlns="http://www.w3.org/1999/xhtml"> </textarea>\n'
);
} else {
testHtmlClipboardValue(
"text/html",
'<div id="div5">\n T<textarea> </textarea>\n</div>'
);
testInnerHTML("div5", "\n T<textarea> </textarea>\n");
}
testPasteText(" T ");
await copyRangeToClipboard($("div6").childNodes[0],0, $("div6").childNodes[1],1,suppressUnicodeCheckIfHidden);
await copyRangeToClipboard(
$("div6").childNodes[0],
0,
$("div6").childNodes[1],
1,
suppressUnicodeCheckIfHidden
);
testSelectionToString("");
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
testInnerHTML("div6", "div6");
await copyRangeToClipboard($("div7").childNodes[0],0, $("div7").childNodes[0],4,suppressUnicodeCheckIfHidden);
await copyRangeToClipboard(
$("div7").childNodes[0],
0,
$("div7").childNodes[0],
4,
suppressUnicodeCheckIfHidden
);
testSelectionToString("");
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
testInnerHTML("div7", "div7");
await copyRangeToClipboard($("div8").childNodes[0],0, $("div8").childNodes[0],4,suppressUnicodeCheckIfHidden);
await copyRangeToClipboard(
$("div8").childNodes[0],
0,
$("div8").childNodes[0],
4,
suppressUnicodeCheckIfHidden
);
testSelectionToString("");
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
// START Disabled due to bug 564688
if (false) {
testClipboardValue("text/unicode", "");
testClipboardValue("text/html", "");
}
// END Disabled due to bug 564688
testInnerHTML("div8", "div8");
await copyRangeToClipboard($("div9").childNodes[0],0, $("div9").childNodes[0],4,suppressUnicodeCheckIfHidden);
await copyRangeToClipboard(
$("div9").childNodes[0],
0,
$("div9").childNodes[0],
4,
suppressUnicodeCheckIfHidden
);
testSelectionToString("div9");
testClipboardValue("text/unicode", "div9");
testHtmlClipboardValue("text/html", "div9");
@ -224,10 +305,22 @@ if (false) {
await copyToClipboard($("div10").firstChild, suppressUnicodeCheckIfHidden);
testSelectionToString("");
await copyRangeToClipboard($("div10").childNodes[0],0, $("div10").childNodes[0],1,suppressUnicodeCheckIfHidden);
await copyRangeToClipboard(
$("div10").childNodes[0],
0,
$("div10").childNodes[0],
1,
suppressUnicodeCheckIfHidden
);
testSelectionToString("");
await copyRangeToClipboard($("div10").childNodes[1],0, $("div10").childNodes[1],1,suppressUnicodeCheckIfHidden);
await copyRangeToClipboard(
$("div10").childNodes[1],
0,
$("div10").childNodes[1],
1,
suppressUnicodeCheckIfHidden
);
testSelectionToString("");
if (!isXHTML) {
@ -236,128 +329,144 @@ if (false) {
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
var ul = $('ul1');
var ul = $("ul1");
var parent = ul.parentNode;
r.setStart(parent, 0);
r.setEnd(parent.firstChild, 15); // the end of "Copy..."
r.setEnd(parent.firstChild, 15); // the end of "Copy..."
sel.addRange(r);
r = document.createRange();
r.setStart(ul, 1); // before the space inside the UL
r.setEnd(parent, 2); // after the UL
r.setStart(ul, 1); // before the space inside the UL
r.setEnd(parent, 2); // after the UL
sel.addRange(r);
await copySelectionToClipboard(true);
testPasteHTML('contentEditable1', 'Copy1then Paste');
testPasteHTML("contentEditable1", "Copy1then Paste");
// with text end node
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
var ul = $('ul2');
var ul = $("ul2");
var parent = ul.parentNode;
r.setStart(parent, 0);
r.setEnd(ul, 1); // after the space
r.setEnd(ul, 1); // after the space
sel.addRange(r);
r = document.createRange();
r.setStart(parent.childNodes[1], 0); // the start of "Copy..."
r.setStart(parent.childNodes[1], 0); // the start of "Copy..."
r.setEnd(parent, 2);
sel.addRange(r);
await copySelectionToClipboard(true);
testPasteHTML('contentEditable2', 'Copy2then Paste');
testPasteHTML("contentEditable2", "Copy2then Paste");
// with text end node and non-empty start
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
var ul = $('ul3');
var ul = $("ul3");
var parent = ul.parentNode;
r.setStart(parent, 0);
r.setEnd(ul, 1); // after the space
r.setEnd(ul, 1); // after the space
sel.addRange(r);
r = document.createRange();
r.setStart(parent.childNodes[1], 0); // the start of "Copy..."
r.setStart(parent.childNodes[1], 0); // the start of "Copy..."
r.setEnd(parent, 2);
sel.addRange(r);
await copySelectionToClipboard(true);
testPasteHTML('contentEditable3', '<ul id="ul3"><li>\n<br></li></ul>Copy3then Paste');
testPasteHTML(
"contentEditable3",
'<ul id="ul3"><li>\n<br></li></ul>Copy3then Paste'
);
// with elements of different depth
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
var div1 = $('div1s');
var div1 = $("div1s");
var parent = div1.parentNode;
r.setStart(parent, 0);
r.setEnd(document.getElementById('div1se1'), 1); // after the "inner" DIV
r.setEnd(document.getElementById("div1se1"), 1); // after the "inner" DIV
sel.addRange(r);
r = document.createRange();
r.setStart(div1.childNodes[1], 0); // the start of "after"
r.setStart(div1.childNodes[1], 0); // the start of "after"
r.setEnd(parent, 1);
sel.addRange(r);
await copySelectionToClipboard(true);
testPasteHTML('contentEditable4', '<div id="div1s"><div id="div1se1">before</div></div><div id="div1s">after</div>');
testPasteHTML(
"contentEditable4",
'<div id="div1s"><div id="div1se1">before</div></div><div id="div1s">after</div>'
);
// with elements of different depth, and a text node at the end
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
var div1 = $('div2s');
var div1 = $("div2s");
var parent = div1.parentNode;
r.setStart(parent, 0);
r.setEnd(document.getElementById('div2se1'), 1); // after the "inner" DIV
r.setEnd(document.getElementById("div2se1"), 1); // after the "inner" DIV
sel.addRange(r);
r = document.createRange();
r.setStart(div1.childNodes[1], 0); // the start of "after"
r.setStart(div1.childNodes[1], 0); // the start of "after"
r.setEnd(parent, 1);
sel.addRange(r);
await copySelectionToClipboard(true);
testPasteHTML('contentEditable5', '<div id="div2s"><div id="div2se1">before</div></div><div id="div2s">after</div>');
testPasteHTML(
"contentEditable5",
'<div id="div2s"><div id="div2se1">before</div></div><div id="div2s">after</div>'
);
// crash test for bug 1127835
var e1 = document.getElementById('1127835crash1');
var e2 = document.getElementById('1127835crash2');
var e3 = document.getElementById('1127835crash3');
var e1 = document.getElementById("1127835crash1");
var e2 = document.getElementById("1127835crash2");
var e3 = document.getElementById("1127835crash3");
var t1 = e1.childNodes[0];
var t3 = e3.childNodes[0];
var sel = window.getSelection();
sel.removeAllRanges();
var r = document.createRange();
r.setStart(t1, 1);
r.setEnd(e2, 0);
sel.addRange(r);
r = document.createRange();
r.setStart(e2, 1);
r.setEnd(t3, 0);
sel.addRange(r);
await copySelectionToClipboard(true);
testPasteHTML('contentEditable6', '<span id="1127835crash1"></span><div id="1127835crash2"><div>\n</div></div><br>');
testPasteHTML(
"contentEditable6",
'<span id="1127835crash1"></span><div id="1127835crash2"><div>\n</div></div><br>'
);
}
// ============ copy/paste test from/to a textarea
var val = "1\n 2\n 3";
textarea.value=val;
textarea.value = val;
textarea.select();
await SimpleTest.promiseClipboardChange(() => true,
() => { textarea.editor.copy(); });
textarea.value="";
await SimpleTest.promiseClipboardChange(
() => true,
() => {
textarea.editor.copy();
}
);
textarea.value = "";
textarea.editor.paste(1);
is(textarea.value, val);
textarea.value="";
textarea.value = "";
// ============ NOSCRIPT should not be copied
await copyChildrenToClipboard("div13");
testSelectionToString("__");
testClipboardValue("text/unicode", "__");
testHtmlClipboardValue("text/html", "<div id=\"div13\">__</div>");
testHtmlClipboardValue("text/html", '<div id="div13">__</div>');
testPasteText("__");
// ============ converting cell boundaries to tabs in tables
@ -368,36 +477,60 @@ if (false) {
if (!isXHTML) {
// ============ spanning multiple rows
await copyRangeToClipboard($("tr2"),0,$("tr3"),0);
await copyRangeToClipboard($("tr2"), 0, $("tr3"), 0);
testClipboardValue("text/unicode", "1\t2\n3\t4\n");
testHtmlClipboardValue("text/html", '<table><tbody><tr id="tr2"><tr id="tr2"><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr><tr id="tr3"></tr></tr></tbody></table>');
testHtmlClipboardValue(
"text/html",
'<table><tbody><tr id="tr2"><tr id="tr2"><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr><tr id="tr3"></tr></tr></tbody></table>'
);
// ============ spanning multiple rows in multi-range selection
clear();
addRange($("tr2"),0,$("tr2"),2);
addRange($("tr3"),0,$("tr3"),2);
addRange($("tr2"), 0, $("tr2"), 2);
addRange($("tr3"), 0, $("tr3"), 2);
await copySelectionToClipboard();
testClipboardValue("text/unicode", "1\t2\n5\t6");
testHtmlClipboardValue("text/html", '<table><tbody><tr id="tr2"><td>1</td><td>2</td></tr><tr id="tr3"><td>5</td><td>6</td></tr></tbody></table>');
testHtmlClipboardValue(
"text/html",
'<table><tbody><tr id="tr2"><td>1</td><td>2</td></tr><tr id="tr3"><td>5</td><td>6</td></tr></tbody></table>'
);
}
// ============ manipulating Selection in oncopy
await copyRangeToClipboard($("div11").childNodes[0],0, $("div11").childNodes[1],2);
await copyRangeToClipboard(
$("div11").childNodes[0],
0,
$("div11").childNodes[1],
2
);
testClipboardValue("text/unicode", "Xdiv11");
testHtmlClipboardValue("text/html", "<div><p>X<span>div</span>11</p></div>");
await new Promise(resolve => { setTimeout(resolve, 0); });
await new Promise(resolve => {
setTimeout(resolve, 0);
});
testSelectionToString("div11");
await new Promise(resolve => { setTimeout(resolve, 0); });
await copyRangeToClipboard($("div12").childNodes[0],0, $("div12").childNodes[1],2);
await new Promise(resolve => {
setTimeout(resolve, 0);
});
await copyRangeToClipboard(
$("div12").childNodes[0],
0,
$("div12").childNodes[1],
2
);
testClipboardValue("text/unicode", "Xdiv12");
testHtmlClipboardValue("text/html", "<div><p>X<span>div</span>12</p></div>");
await new Promise(resolve => { setTimeout(resolve, 0); });
testSelectionToString("div12");
await new Promise(resolve => {
setTimeout(resolve, 0);
});
testSelectionToString("div12");
await new Promise(resolve => { setTimeout(resolve, 0); });
await new Promise(resolve => {
setTimeout(resolve, 0);
});
}

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

@ -16,11 +16,11 @@ var gData1 = "TEST_DATA_1:ABCDEFGHIJKLMNOPQRSTUVWXYZ" + gPadding;
var gData2 = "TEST_DATA_2:1234567890" + gPadding;
function ok(a, msg) {
postMessage({type: "status", status: !!a, msg: msg });
postMessage({ type: "status", status: !!a, msg: msg });
}
function is(a, b, msg) {
postMessage({type: "status", status: a === b, msg: msg });
postMessage({ type: "status", status: a === b, msg: msg });
}
function checkData(xhr, data, mapped, cb) {
@ -43,7 +43,7 @@ self.onmessage = function onmessage(event) {
return "jar:" + jar + "!/" + entry;
}
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
var xhr = new XMLHttpRequest({ mozAnon: true, mozSystem: true });
function reset_event_hander() {
xhr.onerror = function(e) {
@ -60,8 +60,10 @@ self.onmessage = function onmessage(event) {
var loadendCount = 0;
function checkEventCount(cb) {
ok(readystatechangeCount == 1 && loadCount == 1 && loadendCount == 1,
"Saw all expected events");
ok(
readystatechangeCount == 1 && loadCount == 1 && loadendCount == 1,
"Saw all expected events"
);
cb();
}
@ -72,16 +74,16 @@ self.onmessage = function onmessage(event) {
xhr.onreadystatechange = function() {
if (xhr.readyState == xhr.DONE) {
readystatechangeCount++;
checkData(xhr, gData2, false, function() {} );
checkData(xhr, gData2, false, function() {});
}
};
xhr.onload = function() {
loadCount++;
checkData(xhr, gData2, false, function() {} );
checkData(xhr, gData2, false, function() {});
};
xhr.onloadend = function() {
loadendCount++;
checkData(xhr, gData2, false, function() {} );
checkData(xhr, gData2, false, function() {});
};
xhr.open("GET", makeJarURL(gEntry2), false);
xhr.responseType = "arraybuffer";
@ -130,12 +132,12 @@ self.onmessage = function onmessage(event) {
test_sync_xhr_data1,
test_sync_xhr_data2,
test_async_xhr_data1,
test_async_xhr_data2
test_async_xhr_data2,
];
function runTests() {
if (!tests.length) {
postMessage({type: "finish" });
postMessage({ type: "finish" });
return;
}

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

@ -1,13 +1,21 @@
Cu.importGlobalProperties(["File"]);
function createFileWithData(message) {
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(
Ci.nsIProperties
);
var testFile = dirSvc.get("ProfD", Ci.nsIFile);
testFile.append("fileAPItestfileBug1198095");
var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0o666, 0);
var outStream = Cc[
"@mozilla.org/network/file-output-stream;1"
].createInstance(Ci.nsIFileOutputStream);
outStream.init(
testFile,
0x02 | 0x08 | 0x20, // write, create, truncate
0o666,
0
);
outStream.write(message, message.length);
outStream.close();
@ -15,13 +23,13 @@ function createFileWithData(message) {
return File.createFromNsIFile(testFile);
}
addMessageListener("file.open", function (message) {
addMessageListener("file.open", function(message) {
createFileWithData(message).then(function(file) {
sendAsyncMessage("file.opened", file);
});
});
addMessageListener("file.modify", function (message) {
addMessageListener("file.modify", function(message) {
createFileWithData(message).then(function(file) {
sendAsyncMessage("file.modified", file);
});

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

@ -2,15 +2,18 @@
SimpleTest.waitForExplicitFinish();
function testGetElements (root, classtestCount) {
function testGetElements(root, classtestCount) {
ok(root.getElementsByClassName, "getElementsByClassName exists");
is(typeof(root.getElementsByClassName), "function", "getElementsByClassName is a function");
is(
typeof root.getElementsByClassName,
"function",
"getElementsByClassName is a function"
);
var nodes = root.getElementsByClassName("f");
is(typeof(nodes.item), "function");
is(typeof(nodes.length), "number");
is(typeof nodes.item, "function");
is(typeof nodes.length, "number");
is(nodes.length, 0, "string with no matching class should get an empty list");
nodes = root.getElementsByClassName("foo");
@ -20,33 +23,37 @@ function testGetElements (root, classtestCount) {
// should match int class
nodes = root.getElementsByClassName("1");
is(nodes[0], $('int-class'), "match integer class name");
is(nodes[0], $("int-class"), "match integer class name");
nodes = root.getElementsByClassName([1]);
is(nodes[0], $('int-class'), "match integer class name 2");
is(nodes[0], $("int-class"), "match integer class name 2");
nodes = root.getElementsByClassName(["1 junk"]);
is(nodes.length, 0, "two classes, but no elements have both");
nodes = root.getElementsByClassName("test1");
is(nodes[0], $('test1'), "Id and class name turn up the same node");
is(nodes[0], $("test1"), "Id and class name turn up the same node");
nodes = root.getElementsByClassName("test1 test2");
is(nodes.length, 0, "two classes, but no elements have both");
// WHATWG examples
nodes = document.getElementById('example').getElementsByClassName('aaa');
nodes = document.getElementById("example").getElementsByClassName("aaa");
is(nodes.length, 2, "returns 2 elements");
nodes = document.getElementById('example').getElementsByClassName('ccc bbb')
is(nodes.length, 1, "only match elements that have all the classes specified in that array. tokenize string arg.")
is(nodes[0], $('p3'), "matched tokenized string");
nodes = document.getElementById("example").getElementsByClassName("ccc bbb");
is(
nodes.length,
1,
"only match elements that have all the classes specified in that array. tokenize string arg."
);
is(nodes[0], $("p3"), "matched tokenized string");
nodes = document.getElementById('example').getElementsByClassName('');
nodes = document.getElementById("example").getElementsByClassName("");
is(nodes.length, 0, "class name with empty string shouldn't return nodes");
nodes = root.getElementsByClassName({});
ok(nodes, "bogus arg shouldn't be null");
is(typeof(nodes.item), "function");
is(typeof(nodes.length), "number");
is(typeof nodes.item, "function");
is(typeof nodes.length, "number");
is(nodes.length, 0, "bogus arg should get an empty nodelist");
}
@ -54,11 +61,14 @@ addLoadEvent(function() {
if (document.getElementsByName) {
var anchorNodes = document.getElementsByName("nametest");
is(anchorNodes.length, 1, "getElementsByName still works");
is(anchorNodes[0].getAttribute("name"), "nametest",
"getElementsByName still works");
is(
anchorNodes[0].getAttribute("name"),
"nametest",
"getElementsByName still works"
);
}
testGetElements($("content"), 1);
testGetElements(document.documentElement, 3);
testGetElements(document, 3);
testGetElements(document, 3);
});
addLoadEvent(SimpleTest.finish);

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

@ -1 +1 @@
var stringFromCharsetScript = "¡";
var stringFromCharsetScript = "<EFBFBD>";

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

@ -1 +1 @@
var stringFromInheritScript = "¡";
var stringFromInheritScript = "<EFBFBD>";

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

@ -30,5 +30,3 @@ function incrementLoad2(tag, expectedLoadCount) {
function postfail(msg) {
window.parent.postMessage("fail-" + msg, window.location.origin);
}

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

@ -1,6 +1,6 @@
var gData1 = "TEST_DATA_1:ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var gData2 = "TEST_DATA_2:1234567890";
var gPaddingChar = '.';
var gPaddingChar = ".";
var gPaddingSize = 10000;
var gPadding = "";
@ -9,11 +9,11 @@ for (var i = 0; i < gPaddingSize; i++) {
}
function ok(a, msg) {
postMessage({type: 'status', status: !!a, msg: msg });
postMessage({ type: "status", status: !!a, msg: msg });
}
function is(a, b, msg) {
postMessage({type: 'status', status: a === b, msg: msg });
postMessage({ type: "status", status: a === b, msg: msg });
}
function checkData(response, data_head, cb) {
@ -33,9 +33,9 @@ self.onmessage = function onmessage(event) {
}
function test_mapped_sync() {
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
xhr.open('GET', makeJarURL('data_1.txt'), false);
xhr.responseType = 'arraybuffer';
var xhr = new XMLHttpRequest({ mozAnon: true, mozSystem: true });
xhr.open("GET", makeJarURL("data_1.txt"), false);
xhr.responseType = "arraybuffer";
xhr.send();
if (xhr.status) {
ok(xhr.status == 200, "Status is 200");
@ -46,9 +46,9 @@ self.onmessage = function onmessage(event) {
}
function test_mapped_async() {
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
xhr.open('GET', makeJarURL('data_1.txt'));
xhr.responseType = 'arraybuffer';
var xhr = new XMLHttpRequest({ mozAnon: true, mozSystem: true });
xhr.open("GET", makeJarURL("data_1.txt"));
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function() {
if (xhr.readyState !== xhr.DONE) {
return;
@ -58,17 +58,17 @@ self.onmessage = function onmessage(event) {
var ct = xhr.getResponseHeader("Content-Type");
ok(ct.includes("mem-mapped"), "Data is memory-mapped");
checkData(xhr.response, gData1, runTests);
}
}
}
};
xhr.send();
}
// Make sure array buffer retrieved from compressed file in package is
// handled by memory allocation instead of memory mapping.
function test_non_mapped() {
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
xhr.open('GET', makeJarURL('data_2.txt'));
xhr.responseType = 'arraybuffer';
var xhr = new XMLHttpRequest({ mozAnon: true, mozSystem: true });
xhr.open("GET", makeJarURL("data_2.txt"));
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function() {
if (xhr.readyState !== xhr.DONE) {
return;
@ -78,20 +78,16 @@ self.onmessage = function onmessage(event) {
var ct = xhr.getResponseHeader("Content-Type");
ok(!ct.includes("mem-mapped"), "Data is not memory-mapped");
checkData(xhr.response, gData2, runTests);
}
}
}
};
xhr.send();
}
var tests = [
test_mapped_sync,
test_mapped_async,
test_non_mapped
];
var tests = [test_mapped_sync, test_mapped_async, test_non_mapped];
function runTests() {
if (!tests.length) {
postMessage({type: 'finish' });
postMessage({ type: "finish" });
return;
}

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

@ -1,5 +1,6 @@
function baz() {}
function bar() {}
function foo() { bar() }
function foo() {
bar();
}
foo();

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

@ -3,7 +3,7 @@ function send_ping() {
}
send_ping(); // ping (=1)
window.addEventListener("load", function () {
window.addEventListener("load", function() {
send_ping(); // ping (=2)
// Append a script which should call |foo|, before the encoding of this script

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

@ -1,7 +1,8 @@
import { func2 } from "./module_cyclic2.js";
export function func1(x, y) {
if (x <= 0)
return y;
return func2(x - 1, y + "1");
if (x <= 0) {
return y;
}
return func2(x - 1, y + "1");
}

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

@ -1,7 +1,8 @@
import { func3 } from "./module_cyclic3.js";
export function func2(x, y) {
if (x <= 0)
return y;
return func3(x - 1, y + "2");
if (x <= 0) {
return y;
}
return func3(x - 1, y + "2");
}

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

@ -1,7 +1,8 @@
import { func1 } from "./module_cyclic1.js";
export function func3(x, y) {
if (x <= 0)
return y;
return func1(x - 1, y + "3");
if (x <= 0) {
return y;
}
return func1(x - 1, y + "3");
}

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

@ -1,5 +1,5 @@
// Extract the introductionType for this module in conjunction with
// iframe_extractIntroType.html.
extractIntroType = function() {
debugger;
}
debugger;
};

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

@ -1,2 +1,2 @@
import { x } from "./module_simpleExport.js"
import { x } from "./module_simpleExport.js";
result = x;

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

@ -13,21 +13,27 @@ const METHODS = {
const ATTRIBUTES = [];
function once(target, eventName, useCapture = false) {
info("Waiting for event: '" + JSON.stringify(eventName) + "' on " + target + ".");
info(
"Waiting for event: '" + JSON.stringify(eventName) + "' on " + target + "."
);
return new Promise(resolve => {
for (let [add, remove] of [
["addEventListener", "removeEventListener"],
["addMessageListener", "removeMessageListener"],
]) {
if ((add in target) && (remove in target)) {
if (add in target && remove in target) {
eventName.forEach(evName => {
target[add](evName, function onEvent(...aArgs) {
info("Got event: '" + evName + "' on " + target + ".");
target[remove](evName, onEvent, useCapture);
resolve(aArgs);
}, useCapture);
});
target[add](
evName,
function onEvent(...aArgs) {
info("Got event: '" + evName + "' on " + target + ".");
target[remove](evName, onEvent, useCapture);
resolve(aArgs);
},
useCapture
);
});
break;
}
}
@ -40,7 +46,7 @@ async function loadFrame(attributes = {}) {
for (let key in attributes) {
iframe.setAttribute(key, attributes[key]);
}
let loaded = once(iframe, [ "load", "mozbrowserloadend" ]);
let loaded = once(iframe, ["load", "mozbrowserloadend"]);
document.body.appendChild(iframe);
await loaded;
return iframe;

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

@ -1,7 +1,8 @@
// Copied from /dom/plugins/test/mochitest/utils.js
function getTestPlugin(pluginName) {
var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
.getService(SpecialPowers.Ci.nsIPluginHost);
var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"].getService(
SpecialPowers.Ci.nsIPluginHost
);
var tags = ph.getPluginTags();
var name = pluginName || "Test Plug-in";
for (var tag of tags) {
@ -15,7 +16,10 @@ function getTestPlugin(pluginName) {
}
// Copied from /dom/plugins/test/mochitest/utils.js
async function setTestPluginEnabledState(newEnabledState, pluginName) {
var oldEnabledState = await SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName);
var oldEnabledState = await SpecialPowers.setTestPluginEnabledState(
newEnabledState,
pluginName
);
if (!oldEnabledState) {
return;
}

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

@ -3,281 +3,339 @@
* These are sent in case of error, or when the loads we await have completed.
*/
window.addEventListener("message", function(event) {
if (event.data == "childLoadComplete") {
// all loads happen, continue the test.
advance();
} else if (event.data == "childOverload") {
// too many loads happened in a test frame, abort.
ok(false, "Too many load handlers called in test.");
SimpleTest.finish();
} else if (event.data.indexOf("fail-") == 0) {
// something else failed in the test frame, abort.
ok(false, "Child failed the test with error " + event.data.substr(5));
SimpleTest.finish();
}});
if (event.data == "childLoadComplete") {
// all loads happen, continue the test.
advance();
} else if (event.data == "childOverload") {
// too many loads happened in a test frame, abort.
ok(false, "Too many load handlers called in test.");
SimpleTest.finish();
} else if (event.data.indexOf("fail-") == 0) {
// something else failed in the test frame, abort.
ok(false, "Child failed the test with error " + event.data.substr(5));
SimpleTest.finish();
}
});
/**
* helper to perform an XHR.
*/
function doXHR(url, onSuccess, onFail) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
xhr.onload = function() {
if (xhr.status == 200) {
onSuccess(xhr);
} else {
onFail(xhr);
}
};
xhr.open('GET', url, true);
xhr.open("GET", url, true);
xhr.send(null);
}
/**
* This triggers state-resetting on the counter server.
*/
function resetCounter() {
doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset',
advance,
function(xhr) {
ok(false, "Need to be able to reset the request counter");
SimpleTest.finish();
});
doXHR("/tests/dom/base/test/bug704320_counter.sjs?reset", advance, function(
xhr
) {
ok(false, "Need to be able to reset the request counter");
SimpleTest.finish();
});
}
/**
* Grabs the results via XHR and passes to checker.
*/
function checkIndividualResults(testname, expected) {
doXHR('/tests/dom/base/test/bug704320_counter.sjs?results',
function(xhr) {
var results = JSON.parse(xhr.responseText);
info(xhr.responseText);
doXHR(
"/tests/dom/base/test/bug704320_counter.sjs?results",
function(xhr) {
var results = JSON.parse(xhr.responseText);
info(xhr.responseText);
ok('img' in results,
testname + " test: some image loads required in results object.");
is(results['img'].count, 2,
testname + " Test: Expected 2 loads for image requests.");
ok(
"img" in results,
testname + " test: some image loads required in results object."
);
is(
results["img"].count,
2,
testname + " Test: Expected 2 loads for image requests."
);
expected.forEach(function (ref) {
ok(results['img'].referrers.includes(ref),
testname + " Test: Expected " + ref + " referrer policy in test, results were " +
JSON.stringify(results['img'].referrers) +".");
});
advance();
},
function(xhr) {
ok(false, "Can't get results from the counter server.");
SimpleTest.finish();
});
expected.forEach(function(ref) {
ok(
results["img"].referrers.includes(ref),
testname +
" Test: Expected " +
ref +
" referrer policy in test, results were " +
JSON.stringify(results["img"].referrers) +
"."
);
});
advance();
},
function(xhr) {
ok(false, "Can't get results from the counter server.");
SimpleTest.finish();
}
);
}
/**
* Grabs the results via XHR and checks them
*/
function checkExpectedGlobalResults(testName) {
var url = 'bug704320.sjs?action=get-test-results';
doXHR(url,
function(xhr) {
var response = JSON.parse(xhr.response);
var url = "bug704320.sjs?action=get-test-results";
doXHR(
url,
function(xhr) {
var response = JSON.parse(xhr.response);
for (type in response) {
for (scheme in response[type]) {
for (policy in response[type][scheme]) {
var expectedResult = EXPECTED_RESULTS[type] === undefined ?
EXPECTED_RESULTS['default'][scheme][policy] :
EXPECTED_RESULTS[type][scheme][policy];
is(response[type][scheme][policy], expectedResult, type + ' ' + scheme + ' ' + policy);
}
}
}
advance(testName);
},
function(xhr) {
ok(false, "Can't get results from the counter server.");
SimpleTest.finish();
});
for (type in response) {
for (scheme in response[type]) {
for (policy in response[type][scheme]) {
var expectedResult =
EXPECTED_RESULTS[type] === undefined
? EXPECTED_RESULTS["default"][scheme][policy]
: EXPECTED_RESULTS[type][scheme][policy];
is(
response[type][scheme][policy],
expectedResult,
type + " " + scheme + " " + policy
);
}
}
}
advance(testName);
},
function(xhr) {
ok(false, "Can't get results from the counter server.");
SimpleTest.finish();
}
);
}
var EXPECTED_RESULTS = {
// From docshell/base/nsDocShell.cpp:
// "If the document containing the hyperlink being audited was not retrieved
// over an encrypted connection and its address does not have the same
// origin as "ping URL", send a referrer."
'link-ping': {
"link-ping": {
// Same-origin
'http-to-http': {
'no-referrer': '',
'unsafe-url': '',
'origin': '',
'origin-when-cross-origin': '',
'no-referrer-when-downgrade': '',
'same-origin': '',
'strict-origin': '',
'strict-origin-when-cross-origin':''
"http-to-http": {
"no-referrer": "",
"unsafe-url": "",
origin: "",
"origin-when-cross-origin": "",
"no-referrer-when-downgrade": "",
"same-origin": "",
"strict-origin": "",
"strict-origin-when-cross-origin": "",
},
'http-to-https': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade',
'same-origin': '',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/'
"http-to-https": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url",
origin: "http://example.com/",
"origin-when-cross-origin": "http://example.com/",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade",
"same-origin": "",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin": "http://example.com/",
},
// Encrypted and not same-origin
'https-to-http': {
'no-referrer': '',
'unsafe-url': '',
'origin': '',
'origin-when-cross-origin': '',
'no-referrer-when-downgrade': '',
'same-origin': '',
'strict-origin': '',
'strict-origin-when-cross-origin':''
"https-to-http": {
"no-referrer": "",
"unsafe-url": "",
origin: "",
"origin-when-cross-origin": "",
"no-referrer-when-downgrade": "",
"same-origin": "",
"strict-origin": "",
"strict-origin-when-cross-origin": "",
},
// Encrypted
'https-to-https': {
'no-referrer': '',
'unsafe-url': '',
'origin': '',
'origin-when-cross-origin': '',
'no-referrer-when-downgrade': '',
'same-origin': '',
'strict-origin': '',
'strict-origin-when-cross-origin':''
}
"https-to-https": {
"no-referrer": "",
"unsafe-url": "",
origin: "",
"origin-when-cross-origin": "",
"no-referrer-when-downgrade": "",
"same-origin": "",
"strict-origin": "",
"strict-origin-when-cross-origin": "",
},
},
// form is tested in a 2nd level iframe.
'form': {
'http-to-http': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=form',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin&type=form',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=form',
'same-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin&type=form',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin&type=form'
form: {
"http-to-http": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=form",
origin: "http://example.com/",
"origin-when-cross-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin&type=form",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=form",
"same-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin&type=form",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin&type=form",
},
'http-to-https': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=form',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=form',
'same-origin': '',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/'
"http-to-https": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=form",
origin: "http://example.com/",
"origin-when-cross-origin": "http://example.com/",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=form",
"same-origin": "",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin": "http://example.com/",
},
'https-to-http': {
'no-referrer': '',
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=form',
'origin': 'https://example.com/',
'origin-when-cross-origin': 'https://example.com/',
'no-referrer-when-downgrade': '',
'same-origin': '',
'strict-origin': '',
'strict-origin-when-cross-origin':''
"https-to-http": {
"no-referrer": "",
"unsafe-url":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=form",
origin: "https://example.com/",
"origin-when-cross-origin": "https://example.com/",
"no-referrer-when-downgrade": "",
"same-origin": "",
"strict-origin": "",
"strict-origin-when-cross-origin": "",
},
"https-to-https": {
"no-referrer": "",
"unsafe-url":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=form",
origin: "https://example.com/",
"origin-when-cross-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin&type=form",
"no-referrer-when-downgrade":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=form",
"same-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin&type=form",
"strict-origin": "https://example.com/",
"strict-origin-when-cross-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin&type=form",
},
'https-to-https': {
'no-referrer': '',
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=form',
'origin': 'https://example.com/',
'origin-when-cross-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin&type=form',
'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=form',
'same-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin&type=form',
'strict-origin': 'https://example.com/',
'strict-origin-when-cross-origin':'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin&type=form'
}
},
// window.location is tested in a 2nd level iframe.
'window.location': {
'http-to-http': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=window.location',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin&type=window.location',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=window.location',
'same-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin&type=window.location',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin&type=window.location'
"window.location": {
"http-to-http": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=window.location",
origin: "http://example.com/",
"origin-when-cross-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin&type=window.location",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=window.location",
"same-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin&type=window.location",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin&type=window.location",
},
'http-to-https': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=window.location',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location',
'same-origin': '',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/'
"http-to-https": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=window.location",
origin: "http://example.com/",
"origin-when-cross-origin": "http://example.com/",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location",
"same-origin": "",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin": "http://example.com/",
},
'https-to-http': {
'no-referrer': '',
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=window.location',
'origin': 'https://example.com/',
'origin-when-cross-origin': 'https://example.com/',
'no-referrer-when-downgrade': '',
'same-origin': '',
'strict-origin': '',
'strict-origin-when-cross-origin':''
"https-to-http": {
"no-referrer": "",
"unsafe-url":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=window.location",
origin: "https://example.com/",
"origin-when-cross-origin": "https://example.com/",
"no-referrer-when-downgrade": "",
"same-origin": "",
"strict-origin": "",
"strict-origin-when-cross-origin": "",
},
"https-to-https": {
"no-referrer": "",
"unsafe-url":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=window.location",
origin: "https://example.com/",
"origin-when-cross-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin&type=window.location",
"no-referrer-when-downgrade":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location",
"same-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin&type=window.location",
"strict-origin": "https://example.com/",
"strict-origin-when-cross-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin&type=window.location",
},
'https-to-https': {
'no-referrer': '',
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=window.location',
'origin': 'https://example.com/',
'origin-when-cross-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin&type=window.location',
'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location',
'same-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin&type=window.location',
'strict-origin': 'https://example.com/',
'strict-origin-when-cross-origin':'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin&type=window.location'
}
},
'default': {
'http-to-http': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade',
'same-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin'
default: {
"http-to-http": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url",
origin: "http://example.com/",
"origin-when-cross-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade",
"same-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin",
},
'http-to-https': {
'no-referrer': '',
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
'origin': 'http://example.com/',
'origin-when-cross-origin': 'http://example.com/',
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade',
'same-origin': '',
'strict-origin': 'http://example.com/',
'strict-origin-when-cross-origin':'http://example.com/'
"http-to-https": {
"no-referrer": "",
"unsafe-url":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url",
origin: "http://example.com/",
"origin-when-cross-origin": "http://example.com/",
"no-referrer-when-downgrade":
"http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade",
"same-origin": "",
"strict-origin": "http://example.com/",
"strict-origin-when-cross-origin": "http://example.com/",
},
'https-to-http': {
'no-referrer': '',
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url',
'origin': 'https://example.com/',
'origin-when-cross-origin': 'https://example.com/',
'no-referrer-when-downgrade': '',
'same-origin': '',
'strict-origin': '',
'strict-origin-when-cross-origin':''
"https-to-http": {
"no-referrer": "",
"unsafe-url":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url",
origin: "https://example.com/",
"origin-when-cross-origin": "https://example.com/",
"no-referrer-when-downgrade": "",
"same-origin": "",
"strict-origin": "",
"strict-origin-when-cross-origin": "",
},
'https-to-https': {
'no-referrer': '',
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url',
'origin': 'https://example.com/',
'origin-when-cross-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin',
'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade',
'same-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin',
'strict-origin': 'https://example.com/',
'strict-origin-when-cross-origin':'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin'
}
}
"https-to-https": {
"no-referrer": "",
"unsafe-url":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url",
origin: "https://example.com/",
"origin-when-cross-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin",
"no-referrer-when-downgrade":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade",
"same-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin",
"strict-origin": "https://example.com/",
"strict-origin-when-cross-origin":
"https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin",
},
},
};

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

@ -4,11 +4,13 @@
/*
* common functionality for iframe, anchor, and area referrer attribute tests
*/
const GET_RESULT = SJS + 'ACTION=get-test-results';
const RESET_STATE = SJS + 'ACTION=resetState';
const GET_RESULT = SJS + "ACTION=get-test-results";
const RESET_STATE = SJS + "ACTION=resetState";
SimpleTest.waitForExplicitFinish();
var advance = function() { tests.next(); };
var advance = function() {
tests.next();
};
/**
* Listen for notifications from the child.
@ -27,15 +29,15 @@ window.addEventListener("message", function(event) {
*/
function doXHR(aUrl, onSuccess, onFail) {
// The server is at http[s]://example.com so we need cross-origin XHR.
var xhr = new XMLHttpRequest({mozSystem: true});
var xhr = new XMLHttpRequest({ mozSystem: true });
xhr.responseType = "json";
xhr.onload = function () {
xhr.onload = function() {
onSuccess(xhr);
};
xhr.onerror = function () {
xhr.onerror = function() {
onFail(xhr);
};
xhr.open('GET', "http" + aUrl, true);
xhr.open("GET", "http" + aUrl, true);
xhr.send(null);
}
@ -47,7 +49,16 @@ function checkIndividualResults(aTestname, aExpectedReferrer, aName) {
var results = xhr.response;
info(JSON.stringify(xhr.response));
ok(aName in results, aName + " tests have to be performed.");
is(results[aName].policy, aExpectedReferrer, aTestname + ' --- ' + results[aName].policy + ' (' + results[aName].referrer + ')');
is(
results[aName].policy,
aExpectedReferrer,
aTestname +
" --- " +
results[aName].policy +
" (" +
results[aName].referrer +
")"
);
advance();
};
var onerror = xhr => {
@ -58,28 +69,34 @@ function checkIndividualResults(aTestname, aExpectedReferrer, aName) {
}
function resetState() {
doXHR(RESET_STATE,
advance,
function(xhr) {
ok(false, "error in reset state");
SimpleTest.finish();
});
doXHR(RESET_STATE, advance, function(xhr) {
ok(false, "error in reset state");
SimpleTest.finish();
});
}
/**
* testing if referrer header is sent correctly
*/
var tests = (function*() {
yield SpecialPowers.pushPrefEnv({"set": [['network.preload', true]]}, advance);
yield SpecialPowers.pushPrefEnv({"set": [['security.mixed_content.block_active_content', false]]}, advance);
yield SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], advance);
yield SpecialPowers.pushPrefEnv(
{ set: [["network.preload", true]] },
advance
);
yield SpecialPowers.pushPrefEnv(
{ set: [["security.mixed_content.block_active_content", false]] },
advance
);
yield SpecialPowers.pushPermissions(
[{ type: "systemXHR", allow: true, context: document }],
advance
);
var iframe = document.getElementById("testframe");
for (var j = 0; j < testCases.length; j++) {
if (testCases[j].PREFS) {
yield SpecialPowers.pushPrefEnv({"set": testCases[j].PREFS}, advance);
yield SpecialPowers.pushPrefEnv({ set: testCases[j].PREFS }, advance);
}
var actions = testCases[j].ACTION;
@ -97,11 +114,15 @@ var tests = (function*() {
}
}
var schemeFrom = subTests[i].SCHEME_FROM || "http";
yield iframe.src = schemeFrom + SJS + searchParams.toString();
yield checkIndividualResults(subTests[i].DESC, subTests[i].RESULT, subTests[i].NAME);
};
};
};
yield (iframe.src = schemeFrom + SJS + searchParams.toString());
yield checkIndividualResults(
subTests[i].DESC,
subTests[i].RESULT,
subTests[i].NAME
);
}
}
}
// complete.
SimpleTest.finish();

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

@ -1 +1 @@
document.write("Räksmörgås");
document.write("Räksmörgås");

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

@ -3,8 +3,9 @@ Cu.importGlobalProperties(["File"]);
var tmpFile;
function writeFile(text, answer) {
var stream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
var stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
Ci.nsIFileOutputStream
);
stream.init(tmpFile, 0x02 | 0x08 | 0x10, 0o600, 0);
stream.write(text, text.length);
stream.close();
@ -14,17 +15,17 @@ function writeFile(text, answer) {
});
}
addMessageListener("file.open", function (e) {
addMessageListener("file.open", function(e) {
tmpFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get('TmpD', Ci.nsIFile)
tmpFile.append('foo.txt');
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("TmpD", Ci.nsIFile);
tmpFile.append("foo.txt");
tmpFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
writeFile("hello world", "file.opened");
});
addMessageListener("file.change", function (e) {
addMessageListener("file.change", function(e) {
writeFile("hello world---------------", "file.changed");
});

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

@ -1,10 +1,10 @@
Cu.importGlobalProperties(["File"]);
addMessageListener("file.open", function () {
addMessageListener("file.open", function() {
var testFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
testFile.append("prefs.js");
File.createFromNsIFile(testFile).then(function(file) {
@ -12,13 +12,13 @@ addMessageListener("file.open", function () {
});
});
addMessageListener("dir.open", function () {
addMessageListener("dir.open", function() {
var testFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get("ProfD", Ci.nsIFile);
sendAsyncMessage("dir.opened", {
dir: testFile.path
dir: testFile.path,
});
});

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

@ -6,13 +6,27 @@
SimpleTest.waitForExplicitFinish();
var legacyProps = ["fgColor", "bgColor", "linkColor", "vlinkColor", "alinkColor"];
var legacyProps = [
"fgColor",
"bgColor",
"linkColor",
"vlinkColor",
"alinkColor",
];
var testColors = ["blue", "silver", "green", "orange", "red"];
var rgbTestColors = ["rgb(255, 0, 0)", "rgb(192, 192, 192)", "rgb(0, 128, 0)", "rgb(255, 165, 0)", "rgb(255, 0, 0)"];
var idPropList = [ {id: "plaintext", prop: "color"},
{id: "body", prop: "background-color"},
{id: "nonvisitedlink", prop: "color"},
{id: "visitedlink", prop: "color"} ];
var rgbTestColors = [
"rgb(255, 0, 0)",
"rgb(192, 192, 192)",
"rgb(0, 128, 0)",
"rgb(255, 165, 0)",
"rgb(255, 0, 0)",
];
var idPropList = [
{ id: "plaintext", prop: "color" },
{ id: "body", prop: "background-color" },
{ id: "nonvisitedlink", prop: "color" },
{ id: "visitedlink", prop: "color" },
];
var initialValues = [];
function setAndTestProperty(prop, color) {
@ -33,16 +47,22 @@ for (let i = 0; i < legacyProps.length; i++) {
/**
* After BODY loads, run some more tests.
*/
addLoadEvent( function() {
addLoadEvent(function() {
// Verify that the legacy color properties still have their original values.
for (let i = 0; i < legacyProps.length; i++) {
is(document[legacyProps[i]], initialValues[i], "document[" + legacyProps[i] + "] altered after body load");
is(
document[legacyProps[i]],
initialValues[i],
"document[" + legacyProps[i] + "] altered after body load"
);
}
// Verify that legacy color properties applied before BODY are really ignored when rendering.
// Save current computed style colors for later use.
for (let i = 0; i < idPropList.length; i++) {
var style = window.getComputedStyle(document.getElementById(idPropList[i].id));
var style = window.getComputedStyle(
document.getElementById(idPropList[i].id)
);
var color = style.getPropertyValue(idPropList[i].prop);
idPropList[i].initialComputedColor = color;
isnot(color, rgbTestColors[i], "element rendered using before-body style");
@ -54,17 +74,25 @@ addLoadEvent( function() {
// to be read as the string "undefined".
for (let i = 0; i < legacyProps.length; i++) {
document[legacyProps[i]] = undefined;
is(document[legacyProps[i]], "undefined",
"Unexpected value of " + legacyProps[i] + " after setting to undefined");
is(
document[legacyProps[i]],
"undefined",
"Unexpected value of " + legacyProps[i] + " after setting to undefined"
);
}
// Verify that setting legacy color props to undefined led to result
// of parsing undefined as a color.
for (let i = 0; i < idPropList.length; i++) {
var style = window.getComputedStyle(document.getElementById(idPropList[i].id));
var style = window.getComputedStyle(
document.getElementById(idPropList[i].id)
);
var color = style.getPropertyValue(idPropList[i].prop);
is(color, "rgb(0, 239, 14)",
"element's style should get result of parsing undefined as a color");
is(
color,
"rgb(0, 239, 14)",
"element's style should get result of parsing undefined as a color"
);
}
// Mark the test as finished.

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

@ -3,38 +3,68 @@
* 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/. */
var {HTTP_400, HTTP_401, HTTP_402, HTTP_403, HTTP_404, HTTP_405, HTTP_406, HTTP_407, HTTP_408, HTTP_409, HTTP_410, HTTP_411, HTTP_412, HTTP_413, HTTP_414, HTTP_415, HTTP_417, HTTP_500, HTTP_501, HTTP_502, HTTP_503, HTTP_504, HTTP_505, HttpError, HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
var {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var {
HTTP_400,
HTTP_401,
HTTP_402,
HTTP_403,
HTTP_404,
HTTP_405,
HTTP_406,
HTTP_407,
HTTP_408,
HTTP_409,
HTTP_410,
HTTP_411,
HTTP_412,
HTTP_413,
HTTP_414,
HTTP_415,
HTTP_417,
HTTP_500,
HTTP_501,
HTTP_502,
HTTP_503,
HTTP_504,
HTTP_505,
HttpError,
HttpServer,
} = ChromeUtils.import("resource://testing-common/httpd.js");
var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const nsIDocumentEncoder = Ci.nsIDocumentEncoder;
const replacementChar = Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
const replacementChar =
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
function loadContentFile(aFile, aCharset) {
// if(aAsIso == undefined) aAsIso = false;
if (aCharset == undefined)
aCharset = "UTF-8";
// if(aAsIso == undefined) aAsIso = false;
if (aCharset == undefined) {
aCharset = "UTF-8";
}
var file = do_get_file(aFile);
var file = do_get_file(aFile);
var chann = NetUtil.newChannel({
uri: Services.io.newFileURI(file),
loadUsingSystemPrincipal: true,
});
chann.contentCharset = aCharset;
var chann = NetUtil.newChannel({
uri: Services.io.newFileURI(file),
loadUsingSystemPrincipal: true,
});
chann.contentCharset = aCharset;
/* var inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
/* var inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
inputStream.init(chann.open());
return inputStream.read(file.fileSize);
*/
var inputStream = Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Ci.nsIConverterInputStream);
inputStream.init(chann.open(), aCharset, 1024, replacementChar);
var str = {}, content = "";
while (inputStream.readString(4096, str) != 0) {
content += str.value;
}
return content;
var inputStream = Cc[
"@mozilla.org/intl/converter-input-stream;1"
].createInstance(Ci.nsIConverterInputStream);
inputStream.init(chann.open(), aCharset, 1024, replacementChar);
var str = {},
content = "";
while (inputStream.readString(4096, str) != 0) {
content += str.value;
}
return content;
}

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

@ -4,13 +4,13 @@
* 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/. */
const I = Ci;
const C = Cc;
const I = Ci;
const C = Cc;
const nsIFile = I.nsIFile;
const nsIProperties = I.nsIProperties;
const nsIFileInputStream = I.nsIFileInputStream;
const nsIInputStream = I.nsIInputStream;
const nsIFile = I.nsIFile;
const nsIProperties = I.nsIProperties;
const nsIFileInputStream = I.nsIFileInputStream;
const nsIInputStream = I.nsIInputStream;
function getParser() {
var parser = new DOMParser();
@ -21,7 +21,7 @@ function getParser() {
var __testsDirectory = null;
function ParseFile(file) {
if (typeof(file) == "string") {
if (typeof file == "string") {
if (!__testsDirectory) {
__testsDirectory = do_get_cwd();
}
@ -32,22 +32,27 @@ function ParseFile(file) {
Assert.equal(file instanceof nsIFile, true);
var fileStr = C["@mozilla.org/network/file-input-stream;1"]
.createInstance(nsIFileInputStream);
var fileStr = C["@mozilla.org/network/file-input-stream;1"].createInstance(
nsIFileInputStream
);
// Init for readonly reading
fileStr.init(file, 0x01, 0o400, nsIFileInputStream.CLOSE_ON_EOF);
return ParseXML(fileStr);
}
function ParseXML(data) {
if (typeof(data) == "string") {
if (typeof data == "string") {
return getParser().parseFromString(data, "application/xml");
}
Assert.equal(data instanceof nsIInputStream, true);
return getParser().parseFromStream(data, "UTF-8", data.available(),
"application/xml");
return getParser().parseFromStream(
data,
"UTF-8",
data.available(),
"application/xml"
);
}
function DOMSerializer() {
@ -59,7 +64,7 @@ function SerializeXML(node) {
}
function roundtrip(obj) {
if (typeof(obj) == "string") {
if (typeof obj == "string") {
return SerializeXML(ParseXML(obj));
}
@ -79,8 +84,13 @@ function do_compare_attrs(e1, e2) {
if (att.namespaceURI != xmlns) {
var att2 = a2.getNamedItemNS(att.namespaceURI, att.localName);
if (!att2) {
do_throw("Missing attribute with namespaceURI '" + att.namespaceURI +
"' and localName '" + att.localName + "'");
do_throw(
"Missing attribute with namespaceURI '" +
att.namespaceURI +
"' and localName '" +
att.localName +
"'"
);
}
Assert.equal(att.value, att2.value);
}
@ -90,28 +100,28 @@ function do_compare_attrs(e1, e2) {
function do_check_equiv(dom1, dom2) {
Assert.equal(dom1.nodeType, dom2.nodeType);
switch (dom1.nodeType) {
case Node.PROCESSING_INSTRUCTION_NODE:
Assert.equal(dom1.target, dom2.target);
Assert.equal(dom1.data, dom2.data);
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
case Node.COMMENT_NODE:
Assert.equal(dom1.data, dom2.data);
break;
case Node.ELEMENT_NODE:
Assert.equal(dom1.namespaceURI, dom2.namespaceURI);
Assert.equal(dom1.localName, dom2.localName);
// Compare attrs in both directions -- do_compare_attrs does a
// subset check.
do_compare_attrs(dom1, dom2);
do_compare_attrs(dom2, dom1);
case Node.PROCESSING_INSTRUCTION_NODE:
Assert.equal(dom1.target, dom2.target);
Assert.equal(dom1.data, dom2.data);
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
case Node.COMMENT_NODE:
Assert.equal(dom1.data, dom2.data);
break;
case Node.ELEMENT_NODE:
Assert.equal(dom1.namespaceURI, dom2.namespaceURI);
Assert.equal(dom1.localName, dom2.localName);
// Compare attrs in both directions -- do_compare_attrs does a
// subset check.
do_compare_attrs(dom1, dom2);
do_compare_attrs(dom2, dom1);
// Fall through
case Node.DOCUMENT_NODE:
Assert.equal(dom1.childNodes.length, dom2.childNodes.length);
for (var i = 0; i < dom1.childNodes.length; ++i) {
do_check_equiv(dom1.childNodes.item(i), dom2.childNodes.item(i));
}
break;
case Node.DOCUMENT_NODE:
Assert.equal(dom1.childNodes.length, dom2.childNodes.length);
for (var i = 0; i < dom1.childNodes.length; ++i) {
do_check_equiv(dom1.childNodes.item(i), dom2.childNodes.item(i));
}
break;
}
}
@ -130,8 +140,9 @@ function ScriptableInput(arg) {
arg = arg.inputStream;
}
var str = C["@mozilla.org/scriptableinputstream;1"].
createInstance(I.nsIScriptableInputStream);
var str = C["@mozilla.org/scriptableinputstream;1"].createInstance(
I.nsIScriptableInputStream
);
str.init(arg);

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

@ -2,7 +2,7 @@
* 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/. */
var {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
var { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
var server = new HttpServer();
server.start(-1);
@ -29,8 +29,7 @@ function headerCheckHandler(metadata, response) {
try {
metadata.getHeader("X-Unwanted-Header");
do_throw("Unwanted header present after redirect");
} catch (x) {
}
} catch (x) {}
response.setStatusLine(metadata.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/plain");
response.write("");
@ -54,6 +53,5 @@ function run_test() {
try {
request.setRequestHeader("X-Unwanted-Header", "present");
do_throw("Shouldn't be able to set a header after send");
} catch (x) {
}
} catch (x) {}
}

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

@ -9,9 +9,7 @@ function run_test() {
let result = '<?xml version="1.0"><html>\u00c0</html>';
let xhr = new XMLHttpRequest();
xhr.open("GET",
"data:text/xml;charset=abc," + body,
false);
xhr.open("GET", "data:text/xml;charset=abc," + body, false);
xhr.send(null);
Assert.equal(xhr.responseText, result);

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

@ -1,6 +1,7 @@
// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var prefetch = Cc["@mozilla.org/prefetch-service;1"].
getService(Ci.nsIPrefetchService);
var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
Ci.nsIPrefetchService
);
var ios = Services.io;
var prefs = Services.prefs;
@ -8,9 +9,10 @@ var parser = new DOMParser();
var doc;
var docbody = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' +
'<link id="node1"/><link id="node2"/>' +
"</body></html>";
var docbody =
'<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' +
'<link id="node1"/><link id="node2"/>' +
"</body></html>";
var node1;
var node2;
@ -41,16 +43,22 @@ add_test(function test_cancel1() {
didFail = 1;
}
Assert.ok(didFail == 1, "Prefetching the same request with the same " +
"node fails.");
Assert.ok(
didFail == 1,
"Prefetching the same request with the same " + "node fails."
);
Assert.ok(prefetch.hasMoreElements(), "There is still request in " +
"the queue");
Assert.ok(
prefetch.hasMoreElements(),
"There is still request in " + "the queue"
);
prefetch.cancelPrefetchPreloadURI(uri, node1);
Assert.ok(!prefetch.hasMoreElements(), "There is no request in the " +
"queue");
Assert.ok(
!prefetch.hasMoreElements(),
"There is no request in the " + "queue"
);
run_next_test();
});
@ -66,8 +74,10 @@ add_test(function test_cancel2() {
prefetch.cancelPrefetchPreloadURI(uri, node1);
Assert.ok(prefetch.hasMoreElements(), "There is still one more request " +
"in the queue");
Assert.ok(
prefetch.hasMoreElements(),
"There is still one more request " + "in the queue"
);
prefetch.cancelPrefetchPreloadURI(uri, node2);
@ -92,8 +102,10 @@ add_test(function test_cancel3() {
}
Assert.ok(didFail == 1, "Canceling the request failed");
Assert.ok(prefetch.hasMoreElements(), "There is still a request " +
"in the queue");
Assert.ok(
prefetch.hasMoreElements(),
"There is still a request " + "in the queue"
);
prefetch.cancelPrefetchPreloadURI(uri, node1);
Assert.ok(!prefetch.hasMoreElements(), "There is no request in the queue");
@ -118,8 +130,10 @@ add_test(function test_cancel4() {
}
Assert.ok(didFail == 1, "Canceling the request failed");
Assert.ok(prefetch.hasMoreElements(), "There is still a request " +
"in the queue");
Assert.ok(
prefetch.hasMoreElements(),
"There is still a request " + "in the queue"
);
prefetch.cancelPrefetchPreloadURI(uri1, node1);
Assert.ok(!prefetch.hasMoreElements(), "There is no request in the queue");

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

@ -8,25 +8,29 @@ function run_test() {
// Test vectors from RFC 4648, section 10.
let textTests = {
"": "",
"f": "Zg",
"fo": "Zm8",
"foo": "Zm9v",
"foob": "Zm9vYg",
"fooba": "Zm9vYmE",
"foobar": "Zm9vYmFy",
f: "Zg",
fo: "Zm8",
foo: "Zm9v",
foob: "Zm9vYg",
fooba: "Zm9vYmE",
foobar: "Zm9vYmFy",
};
// Examples from RFC 4648, section 9.
let binaryTests = [{
decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]),
encoded: "FPucA9l-",
}, {
decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9]),
encoded: "FPucA9k",
}, {
decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03]),
encoded: "FPucAw",
}];
let binaryTests = [
{
decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]),
encoded: "FPucA9l-",
},
{
decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9]),
encoded: "FPucA9k",
},
{
decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03]),
encoded: "FPucAw",
},
];
function padEncodedValue(value) {
switch (value.length % 4) {
@ -42,19 +46,31 @@ function padEncodedValue(value) {
}
function testEncode(input, encoded) {
equal(ChromeUtils.base64URLEncode(input, { pad: false }),
encoded, encoded + " without padding");
equal(ChromeUtils.base64URLEncode(input, { pad: true }),
padEncodedValue(encoded), encoded + " with padding");
equal(
ChromeUtils.base64URLEncode(input, { pad: false }),
encoded,
encoded + " without padding"
);
equal(
ChromeUtils.base64URLEncode(input, { pad: true }),
padEncodedValue(encoded),
encoded + " with padding"
);
}
function test_base64URLEncode() {
throws(_ => ChromeUtils.base64URLEncode(new Uint8Array(0)), /TypeError/,
"Should require encoding options");
throws(_ => ChromeUtils.base64URLEncode(new Uint8Array(0), {}), /TypeError/,
"Encoding should require the padding option");
throws(
_ => ChromeUtils.base64URLEncode(new Uint8Array(0)),
/TypeError/,
"Should require encoding options"
);
throws(
_ => ChromeUtils.base64URLEncode(new Uint8Array(0), {}),
/TypeError/,
"Encoding should require the padding option"
);
for (let {decoded, encoded} of binaryTests) {
for (let { decoded, encoded } of binaryTests) {
testEncode(decoded, encoded);
}
@ -74,29 +90,45 @@ function testDecode(input, decoded) {
deepEqual(new Uint8Array(buffer), decoded, input + " with padding ignored");
if (paddedValue.length > input.length) {
throws(_ => ChromeUtils.base64URLDecode(paddedValue, { padding: "reject" }),
/NS_ERROR_ILLEGAL_VALUE/,
paddedValue + " with padding rejected should throw");
throws(
_ => ChromeUtils.base64URLDecode(paddedValue, { padding: "reject" }),
/NS_ERROR_ILLEGAL_VALUE/,
paddedValue + " with padding rejected should throw"
);
throws(_ => ChromeUtils.base64URLDecode(input, { padding: "require" }),
/NS_ERROR_ILLEGAL_VALUE/,
input + " with padding required should throw");
throws(
_ => ChromeUtils.base64URLDecode(input, { padding: "require" }),
/NS_ERROR_ILLEGAL_VALUE/,
input + " with padding required should throw"
);
buffer = ChromeUtils.base64URLDecode(paddedValue, { padding: "require" });
deepEqual(new Uint8Array(buffer), decoded, paddedValue + " with padding required");
deepEqual(
new Uint8Array(buffer),
decoded,
paddedValue + " with padding required"
);
}
}
function test_base64URLDecode() {
throws(_ => ChromeUtils.base64URLDecode(""), /TypeError/,
"Should require decoding options");
throws(_ => ChromeUtils.base64URLDecode("", {}), /TypeError/,
"Decoding should require the padding option");
throws(_ => ChromeUtils.base64URLDecode("", { padding: "chocolate" }),
/TypeError/,
"Decoding should throw for invalid padding policy");
throws(
_ => ChromeUtils.base64URLDecode(""),
/TypeError/,
"Should require decoding options"
);
throws(
_ => ChromeUtils.base64URLDecode("", {}),
/TypeError/,
"Decoding should require the padding option"
);
throws(
_ => ChromeUtils.base64URLDecode("", { padding: "chocolate" }),
/TypeError/,
"Decoding should throw for invalid padding policy"
);
for (let {decoded, encoded} of binaryTests) {
for (let { decoded, encoded } of binaryTests) {
testDecode(encoded, decoded);
}

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

@ -7,8 +7,10 @@ add_task(function test_shallowclone() {
numProp: 123,
strProp: "str",
boolProp: true,
arrayProp: [{item1: "1", item2: "2"}],
fnProp() { return "fn result"; },
arrayProp: [{ item1: "1", item2: "2" }],
fnProp() {
return "fn result";
},
promise: Promise.resolve("promised-value"),
weakmap: new WeakMap(),
proxy: new Proxy({}, {}),
@ -16,30 +18,43 @@ add_task(function test_shallowclone() {
let clonedObject = ChromeUtils.shallowClone(fullyCloneableObject);
Assert.deepEqual(clonedObject, fullyCloneableObject,
"Got the expected cloned object for an object with regular properties");
Assert.deepEqual(
clonedObject,
fullyCloneableObject,
"Got the expected cloned object for an object with regular properties"
);
// Check that shallow cloning an object with getters and setters properties,
// results into a new object without all the properties from the source object excluded
// its getters and setters.
const objectWithGetterAndSetter = {
get myGetter() { return "getter result"; },
get myGetter() {
return "getter result";
},
set mySetter(v) {},
myFunction() { return "myFunction result"; },
myFunction() {
return "myFunction result";
},
};
clonedObject = ChromeUtils.shallowClone(objectWithGetterAndSetter);
Assert.deepEqual(clonedObject, {
myFunction: objectWithGetterAndSetter.myFunction,
}, "Got the expected cloned object for an object with getters and setters");
Assert.deepEqual(
clonedObject,
{
myFunction: objectWithGetterAndSetter.myFunction,
},
"Got the expected cloned object for an object with getters and setters"
);
// Check that shallow cloning a proxy object raises the expected exception..
const proxyObject = new Proxy(fullyCloneableObject, {});
Assert.throws(
() => { ChromeUtils.shallowClone(proxyObject); },
() => {
ChromeUtils.shallowClone(proxyObject);
},
/Shallow cloning a proxy object is not allowed/,
"Got the expected error on ChromeUtils.shallowClone called on a proxy object");
"Got the expected error on ChromeUtils.shallowClone called on a proxy object"
);
});

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

@ -4,7 +4,7 @@
*/
var gExpectedStatus = null;
var gNextTestFunc = null;
var gNextTestFunc = null;
var prefs = Services.prefs;
@ -14,7 +14,9 @@ var asyncXHR = {
request.open("GET", "http://localhost:4444/test_error_code.xml", true);
var self = this;
request.addEventListener("error", function(event) { self.onError(event); });
request.addEventListener("error", function(event) {
self.onError(event);
});
request.send(null);
},
onError: function doAsyncRequest_onError(event) {
@ -33,8 +35,7 @@ function run_test() {
function run_test_pt1() {
try {
Services.io.manageOfflineStatus = false;
} catch (e) {
}
} catch (e) {}
Services.io.offline = true;
prefs.setBoolPref("network.dns.offline-localhost", false);

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

@ -30,34 +30,55 @@ function test_generate_xpath() {
let inputWithId = doc.getElementById("input1");
let inputWithIdXPath = inputWithId.generateXPath();
let inputWithIdExpXPath = "//xhtml:input[@id='input1']";
equal(inputWithIdExpXPath, inputWithIdXPath, " xpath generated for input with id");
equal(
inputWithIdExpXPath,
inputWithIdXPath,
" xpath generated for input with id"
);
// Test generate xpath for input with id has single quote.
info("Test generate xpath for input with id has single quote");
let inputWithIdSingleQuote = doc.getElementsByTagName("input")[1];
let inputWithIdXPathSingleQuote = inputWithIdSingleQuote.generateXPath();
let inputWithIdExpXPathSingleQuote = '//xhtml:input[@id="input2\'"]';
equal(inputWithIdExpXPathSingleQuote, inputWithIdXPathSingleQuote, " xpath generated for input with id");
equal(
inputWithIdExpXPathSingleQuote,
inputWithIdXPathSingleQuote,
" xpath generated for input with id"
);
// Test generate xpath for input with id has double quote.
info("Test generate xpath for input with id has double quote");
let inputWithIdDoubleQuote = doc.getElementsByTagName("input")[2];
let inputWithIdXPathDoubleQuote = inputWithIdDoubleQuote.generateXPath();
let inputWithIdExpXPathDoubleQuote = "//xhtml:input[@id='\"input3\"']";
equal(inputWithIdExpXPathDoubleQuote, inputWithIdXPathDoubleQuote, " xpath generated for input with id");
equal(
inputWithIdExpXPathDoubleQuote,
inputWithIdXPathDoubleQuote,
" xpath generated for input with id"
);
// Test generate xpath for input with id has both single and double quote.
info("Test generate xpath for input with id has single and double quote");
let inputWithIdSingleDoubleQuote = doc.getElementsByTagName("input")[3];
inputWithIdSingleDoubleQuote.setAttribute("id", "\"input'4");
let inputWithIdXPathSingleDoubleQuote = inputWithIdSingleDoubleQuote.generateXPath();
let inputWithIdExpXPathSingleDoubleQuote = "//xhtml:input[@id=concat('\"input',\"'\",'4')]";
equal(inputWithIdExpXPathSingleDoubleQuote, inputWithIdXPathSingleDoubleQuote, " xpath generated for input with id");
let inputWithIdExpXPathSingleDoubleQuote =
"//xhtml:input[@id=concat('\"input',\"'\",'4')]";
equal(
inputWithIdExpXPathSingleDoubleQuote,
inputWithIdXPathSingleDoubleQuote,
" xpath generated for input with id"
);
// Test generate xpath for input without id.
info("Test generate xpath for input without id");
let inputNoId = doc.getElementsByTagName("input")[4];
let inputNoIdXPath = inputNoId.generateXPath();
let inputNoIdExpXPath = "/xhtml:html/xhtml:body/xhtml:label[5]/xhtml:input";
equal(inputNoIdExpXPath, inputNoIdXPath, " xpath generated for input without id");
equal(
inputNoIdExpXPath,
inputNoIdXPath,
" xpath generated for input without id"
);
}

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

@ -39,14 +39,12 @@ function test_isEqualNode_setAttribute() {
check_eq_nodes(node1, node2);
node1.setAttribute("bar", "baz");
check_neq_nodes(node1, node2);
node2.setAttribute("bar", "baz");
check_eq_nodes(node1, node2);
// the null namespace is equivalent to no namespace -- section 1.3.3
// (XML Namespaces) of DOM 3 Core
node1.setAttributeNS(null, "quux", "17");
@ -55,7 +53,6 @@ function test_isEqualNode_setAttribute() {
node2.setAttribute("quux", "17");
check_eq_nodes(node1, node2);
node2.setAttributeNS("http://mozilla.org/", "seamonkey", "rheet");
check_neq_nodes(node1, node2);
@ -119,30 +116,30 @@ function test_isEqualNode_clones() {
}
function test_isEqualNode_variety() {
const nodes =
[
doc.createElement("foo"),
doc.createElementNS("http://example.com/", "foo"),
doc.createElementNS("http://example.org/", "foo"),
doc.createElementNS("http://example.com/", "FOO"),
doc.createAttribute("foo", "href='biz'"),
doc.createAttributeNS("http://example.com/", "foo", "href='biz'"),
doc.createTextNode("foo"),
doc.createTextNode(" "),
doc.createTextNode(" "),
doc.createComment("foo"),
doc.createProcessingInstruction("foo", "href='biz'"),
doc.implementation.createDocumentType("foo", "href='biz'", ""),
doc.implementation.createDocument("http://example.com/", "foo", null),
doc.createDocumentFragment(),
];
const nodes = [
doc.createElement("foo"),
doc.createElementNS("http://example.com/", "foo"),
doc.createElementNS("http://example.org/", "foo"),
doc.createElementNS("http://example.com/", "FOO"),
doc.createAttribute("foo", "href='biz'"),
doc.createAttributeNS("http://example.com/", "foo", "href='biz'"),
doc.createTextNode("foo"),
doc.createTextNode(" "),
doc.createTextNode(" "),
doc.createComment("foo"),
doc.createProcessingInstruction("foo", "href='biz'"),
doc.implementation.createDocumentType("foo", "href='biz'", ""),
doc.implementation.createDocument("http://example.com/", "foo", null),
doc.createDocumentFragment(),
];
for (var i = 0; i < nodes.length; i++) {
for (var j = i; j < nodes.length; j++) {
if (i == j)
if (i == j) {
check_eq_nodes(nodes[i], nodes[j]);
else
} else {
check_neq_nodes(nodes[i], nodes[j]);
}
}
}
}
@ -172,10 +169,12 @@ function test_isEqualNode_normalization() {
check_eq_nodes(node1, node2);
// reset
while (node1.hasChildNodes())
while (node1.hasChildNodes()) {
node1.removeChild(node1.childNodes.item(0));
while (node2.hasChildNodes())
}
while (node2.hasChildNodes()) {
node2.removeChild(node2.childNodes.item(0));
}
// attribute normalization testing
@ -353,12 +352,8 @@ function test_isEqualNode_null() {
function test_isEqualNode_wholeDoc() {
doc = ParseFile("isequalnode_data.xml");
var doc2 = ParseFile("isequalnode_data.xml");
var tw1 =
doc.createTreeWalker(doc, NodeFilter.SHOW_ALL,
null);
var tw2 =
doc2.createTreeWalker(doc2, NodeFilter.SHOW_ALL,
null);
var tw1 = doc.createTreeWalker(doc, NodeFilter.SHOW_ALL, null);
var tw2 = doc2.createTreeWalker(doc2, NodeFilter.SHOW_ALL, null);
do {
check_eq_nodes(tw1.currentNode, tw2.currentNode);
tw1.nextNode();
@ -381,26 +376,33 @@ function equality_check_kids(parentId, areEqual) {
var kid1 = parent.childNodes.item(1);
var kid2 = parent.childNodes.item(3);
if (areEqual)
if (areEqual) {
check_eq_nodes(kid1, kid2);
else
} else {
check_neq_nodes(kid1, kid2);
}
}
function check_eq_nodes(n1, n2) {
if (n1 && !n1.isEqualNode(n2))
if (n1 && !n1.isEqualNode(n2)) {
do_throw(n1 + " should be equal to " + n2);
if (n2 && !n2.isEqualNode(n1))
}
if (n2 && !n2.isEqualNode(n1)) {
do_throw(n2 + " should be equal to " + n1);
if (!n1 && !n2)
}
if (!n1 && !n2) {
do_throw("nodes both null!");
}
}
function check_neq_nodes(n1, n2) {
if (n1 && n1.isEqualNode(n2))
if (n1 && n1.isEqualNode(n2)) {
do_throw(n1 + " should not be equal to " + n2);
if (n2 && n2.isEqualNode(n1))
}
if (n2 && n2.isEqualNode(n1)) {
do_throw(n2 + " should not be equal to " + n1);
if (!n1 && !n2)
}
if (!n1 && !n2) {
do_throw("n1 and n2 both null!");
}
}

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

@ -6,51 +6,52 @@
"use strict";
function errors() {
return [
// The following two errors MUST NOT be captured.
new Error("This is an error: " + Math.random()),
new RangeError("This is a RangeError: " + Math.random()),
"This is a string: " + Math.random(),
null,
undefined,
Math.random(),
{},
return [
// The following two errors MUST NOT be captured.
new Error("This is an error: " + Math.random()),
new RangeError("This is a RangeError: " + Math.random()),
"This is a string: " + Math.random(),
null,
undefined,
Math.random(),
{},
// The following errors MUST be captured.
new TypeError("This is a TypeError: " + Math.random()),
new SyntaxError("This is a SyntaxError: " + Math.random()),
new ReferenceError("This is a ReferenceError: " + Math.random()),
];
// The following errors MUST be captured.
new TypeError("This is a TypeError: " + Math.random()),
new SyntaxError("This is a SyntaxError: " + Math.random()),
new ReferenceError("This is a ReferenceError: " + Math.random()),
];
}
function isDeveloperError(e) {
if (e == null || typeof e != "object") {
return false;
}
if (e == null || typeof e != "object") {
return false;
}
return e.constructor == TypeError
|| e.constructor == SyntaxError
|| e.constructor == ReferenceError;
return (
e.constructor == TypeError ||
e.constructor == SyntaxError ||
e.constructor == ReferenceError
);
}
function run_test() {
ChromeUtils.clearRecentJSDevError();
Assert.equal(ChromeUtils.recentJSDevError, undefined);
for (let exn of errors()) {
ChromeUtils.clearRecentJSDevError();
try {
throw exn;
} catch (e) {
// Discard error.
}
if (isDeveloperError(exn)) {
Assert.equal(ChromeUtils.recentJSDevError.message, "" + exn);
} else {
Assert.equal(ChromeUtils.recentJSDevError, undefined);
}
ChromeUtils.clearRecentJSDevError();
Assert.equal(ChromeUtils.recentJSDevError, undefined);
for (let exn of errors()) {
ChromeUtils.clearRecentJSDevError();
try {
throw exn;
} catch (e) {
// Discard error.
}
if (isDeveloperError(exn)) {
Assert.equal(ChromeUtils.recentJSDevError.message, "" + exn);
} else {
Assert.equal(ChromeUtils.recentJSDevError, undefined);
}
ChromeUtils.clearRecentJSDevError();
Assert.equal(ChromeUtils.recentJSDevError, undefined);
}
}
}

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

@ -14,18 +14,25 @@ function test_getElementsByTagName() {
var root = doc.documentElement;
// Check that getElementsByTagName returns an HTMLCollection.
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagName("*")),
"HTMLCollection");
Assert.ok(ChromeUtils.getClassName(root.getElementsByTagName("*")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagName("*")),
"HTMLCollection"
);
Assert.ok(
ChromeUtils.getClassName(root.getElementsByTagName("*")),
"HTMLCollection"
);
// Check that getElementsByTagName excludes the element it's called on.
Assert.equal(doc.getElementsByTagName("*").length,
root.getElementsByTagName("*").length + 1);
Assert.equal(doc.getElementById("test2").getElementsByTagName("*").length,
8);
Assert.equal(doc.getElementById("test2").getElementsByTagName("test").length,
3);
Assert.equal(
doc.getElementsByTagName("*").length,
root.getElementsByTagName("*").length + 1
);
Assert.equal(doc.getElementById("test2").getElementsByTagName("*").length, 8);
Assert.equal(
doc.getElementById("test2").getElementsByTagName("test").length,
3
);
// Check that the first element of getElementsByTagName on the document is
// the right thing.
@ -37,21 +44,29 @@ function test_getElementsByTagName() {
for (var i = 1; i <= numTests; ++i) {
Assert.ok(Element.isInstance(doc.getElementById("test" + i)));
Assert.equal(doc.getElementById("test" + i),
doc.getElementsByTagName("test").item(i - 1));
Assert.equal(
doc.getElementById("test" + i),
doc.getElementsByTagName("test").item(i - 1)
);
}
// Check that we handle tagnames containing ':' correctly
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagName("foo:test")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagName("foo:test")),
"HTMLCollection"
);
Assert.equal(doc.getElementsByTagName("foo:test").length, 2);
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagName("foo2:test")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagName("foo2:test")),
"HTMLCollection"
);
Assert.equal(doc.getElementsByTagName("foo2:test").length, 3);
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagName("bar:test")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagName("bar:test")),
"HTMLCollection"
);
Assert.equal(doc.getElementsByTagName("bar:test").length, 4);
}
@ -60,10 +75,14 @@ function test_getElementsByTagNameNS() {
var root = doc.documentElement;
// Check that getElementsByTagNameNS returns an HTMLCollection.
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagNameNS("*", "*")),
"HTMLCollection");
Assert.equal(ChromeUtils.getClassName(root.getElementsByTagNameNS("*", "*")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagNameNS("*", "*")),
"HTMLCollection"
);
Assert.equal(
ChromeUtils.getClassName(root.getElementsByTagNameNS("*", "*")),
"HTMLCollection"
);
// Check that passing "" and null for the namespace URI gives the same result
var list1 = doc.getElementsByTagNameNS("", "test");
@ -74,17 +93,22 @@ function test_getElementsByTagNameNS() {
}
// Check that getElementsByTagNameNS excludes the element it's called on.
Assert.equal(doc.getElementsByTagNameNS("*", "*").length,
root.getElementsByTagNameNS("*", "*").length + 1);
Assert.equal(doc.getElementById("test2")
.getElementsByTagNameNS("*", "*").length,
8);
Assert.equal(doc.getElementById("test2")
.getElementsByTagNameNS("", "test").length,
1);
Assert.equal(doc.getElementById("test2")
.getElementsByTagNameNS("*", "test").length,
7);
Assert.equal(
doc.getElementsByTagNameNS("*", "*").length,
root.getElementsByTagNameNS("*", "*").length + 1
);
Assert.equal(
doc.getElementById("test2").getElementsByTagNameNS("*", "*").length,
8
);
Assert.equal(
doc.getElementById("test2").getElementsByTagNameNS("", "test").length,
1
);
Assert.equal(
doc.getElementById("test2").getElementsByTagNameNS("*", "test").length,
7
);
// Check that the first element of getElementsByTagNameNS on the document is
// the right thing.
@ -93,52 +117,51 @@ function test_getElementsByTagNameNS() {
// Check that we get the right things in the right order
var numTests = doc.getElementsByTagNameNS("*", "test").length;
Assert.equal(numTests, 14);
for (i = 1; i <= numTests; ++i) {
Assert.ok(Element.isInstance(doc.getElementById("test" + i)));
Assert.equal(doc.getElementById("test" + i),
doc.getElementsByTagNameNS("*", "test").item(i - 1));
Assert.equal(
doc.getElementById("test" + i),
doc.getElementsByTagNameNS("*", "test").item(i - 1)
);
}
// Check general proper functioning of having a non-wildcard namespace.
var test2 = doc.getElementById("test2");
Assert.equal(doc.getElementsByTagNameNS("", "test").length,
3);
Assert.equal(test2.getElementsByTagNameNS("", "test").length,
1);
Assert.equal(doc.getElementsByTagNameNS("foo", "test").length,
7);
Assert.equal(test2.getElementsByTagNameNS("foo", "test").length,
4);
Assert.equal(doc.getElementsByTagNameNS("foo2", "test").length,
0);
Assert.equal(test2.getElementsByTagNameNS("foo2", "test").length,
0);
Assert.equal(doc.getElementsByTagNameNS("bar", "test").length,
4);
Assert.equal(test2.getElementsByTagNameNS("bar", "test").length,
2);
Assert.equal(doc.getElementsByTagNameNS("", "test").length, 3);
Assert.equal(test2.getElementsByTagNameNS("", "test").length, 1);
Assert.equal(doc.getElementsByTagNameNS("foo", "test").length, 7);
Assert.equal(test2.getElementsByTagNameNS("foo", "test").length, 4);
Assert.equal(doc.getElementsByTagNameNS("foo2", "test").length, 0);
Assert.equal(test2.getElementsByTagNameNS("foo2", "test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("bar", "test").length, 4);
Assert.equal(test2.getElementsByTagNameNS("bar", "test").length, 2);
// Check that we handle tagnames containing ':' correctly
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagNameNS(null, "foo:test")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagNameNS(null, "foo:test")),
"HTMLCollection"
);
Assert.equal(doc.getElementsByTagNameNS(null, "foo:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("foo", "foo:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("bar", "foo:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("*", "foo:test").length, 0);
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagNameNS(null, "foo2:test")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagNameNS(null, "foo2:test")),
"HTMLCollection"
);
Assert.equal(doc.getElementsByTagNameNS(null, "foo2:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("foo2", "foo2:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("bar", "foo2:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("*", "foo2:test").length, 0);
Assert.equal(ChromeUtils.getClassName(doc.getElementsByTagNameNS(null, "bar:test")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(doc.getElementsByTagNameNS(null, "bar:test")),
"HTMLCollection"
);
Assert.equal(doc.getElementsByTagNameNS(null, "bar:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("bar", "bar:test").length, 0);
Assert.equal(doc.getElementsByTagNameNS("*", "bar:test").length, 0);
@ -148,8 +171,10 @@ function test_getElementsByTagNameNS() {
// If someone wants to run these in a browser, some use of Math.random() may
// be in order.
list1 = doc.getElementsByTagNameNS("random-bogus-namespace", "foo");
list2 = doc.documentElement.getElementsByTagNameNS("random-bogus-namespace2",
"foo");
list2 = doc.documentElement.getElementsByTagNameNS(
"random-bogus-namespace2",
"foo"
);
Assert.notEqual(list1, list2);
Assert.equal(list1.length, 0);
Assert.equal(list2.length, 0);
@ -170,8 +195,10 @@ function test_getElementsByAttribute() {
Assert.equal(ChromeUtils.getClassName(root), "XULElement");
Assert.equal(ChromeUtils.getClassName(root.getElementsByAttribute("foo", "foo")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(root.getElementsByAttribute("foo", "foo")),
"HTMLCollection"
);
var master1 = doc.getElementById("master1");
var master2 = doc.getElementById("master2");
@ -184,97 +211,57 @@ function test_getElementsByAttribute() {
Assert.equal(ChromeUtils.getClassName(external), "XULElement");
// Basic tests
Assert.equal(root.getElementsByAttribute("foo", "foo").length,
14);
Assert.equal(master1.getElementsByAttribute("foo", "foo").length,
4);
Assert.equal(root.getElementsByAttribute("foo", "foo").length, 14);
Assert.equal(master1.getElementsByAttribute("foo", "foo").length, 4);
Assert.equal(root.getElementsByAttribute("foo", "bar").length,
7);
Assert.equal(master1.getElementsByAttribute("foo", "bar").length,
2);
Assert.equal(root.getElementsByAttribute("foo", "bar").length, 7);
Assert.equal(master1.getElementsByAttribute("foo", "bar").length, 2);
Assert.equal(root.getElementsByAttribute("bar", "bar").length,
7);
Assert.equal(master1.getElementsByAttribute("bar", "bar").length,
2);
Assert.equal(root.getElementsByAttribute("bar", "bar").length, 7);
Assert.equal(master1.getElementsByAttribute("bar", "bar").length, 2);
Assert.equal(root.getElementsByAttribute("foo", "*").length,
21);
Assert.equal(master1.getElementsByAttribute("foo", "*").length,
6);
Assert.equal(root.getElementsByAttribute("foo", "*").length, 21);
Assert.equal(master1.getElementsByAttribute("foo", "*").length, 6);
// Test the various combinations of attributes with colons in the name
Assert.equal(root.getElementsByAttribute("foo:foo", "foo").length,
16);
Assert.equal(master1.getElementsByAttribute("foo:foo", "foo").length,
5);
Assert.equal(master2.getElementsByAttribute("foo:foo", "foo").length,
4);
Assert.equal(master3.getElementsByAttribute("foo:foo", "foo").length,
4);
Assert.equal(external.getElementsByAttribute("foo:foo", "foo").length,
2);
Assert.equal(root.getElementsByAttribute("foo:foo", "foo").length, 16);
Assert.equal(master1.getElementsByAttribute("foo:foo", "foo").length, 5);
Assert.equal(master2.getElementsByAttribute("foo:foo", "foo").length, 4);
Assert.equal(master3.getElementsByAttribute("foo:foo", "foo").length, 4);
Assert.equal(external.getElementsByAttribute("foo:foo", "foo").length, 2);
Assert.equal(root.getElementsByAttribute("foo:foo", "bar").length,
9);
Assert.equal(master1.getElementsByAttribute("foo:foo", "bar").length,
2);
Assert.equal(master2.getElementsByAttribute("foo:foo", "bar").length,
3);
Assert.equal(master3.getElementsByAttribute("foo:foo", "bar").length,
2);
Assert.equal(external.getElementsByAttribute("foo:foo", "bar").length,
1);
Assert.equal(root.getElementsByAttribute("foo:foo", "bar").length, 9);
Assert.equal(master1.getElementsByAttribute("foo:foo", "bar").length, 2);
Assert.equal(master2.getElementsByAttribute("foo:foo", "bar").length, 3);
Assert.equal(master3.getElementsByAttribute("foo:foo", "bar").length, 2);
Assert.equal(external.getElementsByAttribute("foo:foo", "bar").length, 1);
Assert.equal(root.getElementsByAttribute("foo:bar", "foo").length,
7);
Assert.equal(master1.getElementsByAttribute("foo:bar", "foo").length,
2);
Assert.equal(master2.getElementsByAttribute("foo:bar", "foo").length,
2);
Assert.equal(master3.getElementsByAttribute("foo:bar", "foo").length,
2);
Assert.equal(external.getElementsByAttribute("foo:bar", "foo").length,
1);
Assert.equal(root.getElementsByAttribute("foo:bar", "foo").length, 7);
Assert.equal(master1.getElementsByAttribute("foo:bar", "foo").length, 2);
Assert.equal(master2.getElementsByAttribute("foo:bar", "foo").length, 2);
Assert.equal(master3.getElementsByAttribute("foo:bar", "foo").length, 2);
Assert.equal(external.getElementsByAttribute("foo:bar", "foo").length, 1);
Assert.equal(root.getElementsByAttribute("foo:bar", "bar").length,
14);
Assert.equal(master1.getElementsByAttribute("foo:bar", "bar").length,
4);
Assert.equal(master2.getElementsByAttribute("foo:bar", "bar").length,
4);
Assert.equal(master3.getElementsByAttribute("foo:bar", "bar").length,
4);
Assert.equal(external.getElementsByAttribute("foo:bar", "bar").length,
2);
Assert.equal(root.getElementsByAttribute("foo:bar", "bar").length, 14);
Assert.equal(master1.getElementsByAttribute("foo:bar", "bar").length, 4);
Assert.equal(master2.getElementsByAttribute("foo:bar", "bar").length, 4);
Assert.equal(master3.getElementsByAttribute("foo:bar", "bar").length, 4);
Assert.equal(external.getElementsByAttribute("foo:bar", "bar").length, 2);
Assert.equal(root.getElementsByAttribute("foo2:foo", "foo").length,
8);
Assert.equal(master1.getElementsByAttribute("foo2:foo", "foo").length,
2);
Assert.equal(master2.getElementsByAttribute("foo2:foo", "foo").length,
2);
Assert.equal(master3.getElementsByAttribute("foo2:foo", "foo").length,
3);
Assert.equal(external.getElementsByAttribute("foo2:foo", "foo").length,
1);
Assert.equal(root.getElementsByAttribute("foo2:foo", "foo").length, 8);
Assert.equal(master1.getElementsByAttribute("foo2:foo", "foo").length, 2);
Assert.equal(master2.getElementsByAttribute("foo2:foo", "foo").length, 2);
Assert.equal(master3.getElementsByAttribute("foo2:foo", "foo").length, 3);
Assert.equal(external.getElementsByAttribute("foo2:foo", "foo").length, 1);
Assert.equal(root.getElementsByAttribute("foo:foo", "*").length,
25);
Assert.equal(master1.getElementsByAttribute("foo:foo", "*").length,
7);
Assert.equal(master2.getElementsByAttribute("foo:foo", "*").length,
7);
Assert.equal(master3.getElementsByAttribute("foo:foo", "*").length,
6);
Assert.equal(external.getElementsByAttribute("foo:foo", "*").length,
3);
Assert.equal(root.getElementsByAttribute("foo:foo", "*").length, 25);
Assert.equal(master1.getElementsByAttribute("foo:foo", "*").length, 7);
Assert.equal(master2.getElementsByAttribute("foo:foo", "*").length, 7);
Assert.equal(master3.getElementsByAttribute("foo:foo", "*").length, 6);
Assert.equal(external.getElementsByAttribute("foo:foo", "*").length, 3);
Assert.equal(root.getElementsByAttribute("foo2:foo", "bar").length,
0);
Assert.equal(root.getElementsByAttribute("foo:foo", "baz").length,
0);
Assert.equal(root.getElementsByAttribute("foo2:foo", "bar").length, 0);
Assert.equal(root.getElementsByAttribute("foo:foo", "baz").length, 0);
}
function test_getElementsByAttributeNS() {
@ -287,8 +274,10 @@ function test_getElementsByAttributeNS() {
Assert.equal(ChromeUtils.getClassName(root), "XULElement");
// Check that getElementsByAttributeNS returns an HTMLCollection.
Assert.equal(ChromeUtils.getClassName(root.getElementsByAttributeNS("*", "*", "*")),
"HTMLCollection");
Assert.equal(
ChromeUtils.getClassName(root.getElementsByAttributeNS("*", "*", "*")),
"HTMLCollection"
);
var master1 = doc.getElementById("master1");
var master2 = doc.getElementById("master2");
@ -301,86 +290,62 @@ function test_getElementsByAttributeNS() {
Assert.equal(ChromeUtils.getClassName(external), "XULElement");
// Test wildcard namespace
Assert.equal(root.getElementsByAttributeNS("*", "foo", "foo").length,
38);
Assert.equal(master1.getElementsByAttributeNS("*", "foo", "foo").length,
11);
Assert.equal(master2.getElementsByAttributeNS("*", "foo", "foo").length,
10);
Assert.equal(master3.getElementsByAttributeNS("*", "foo", "foo").length,
11);
Assert.equal(root.getElementsByAttributeNS("*", "foo", "foo").length, 38);
Assert.equal(master1.getElementsByAttributeNS("*", "foo", "foo").length, 11);
Assert.equal(master2.getElementsByAttributeNS("*", "foo", "foo").length, 10);
Assert.equal(master3.getElementsByAttributeNS("*", "foo", "foo").length, 11);
Assert.equal(root.getElementsByAttributeNS("*", "foo", "bar").length,
16);
Assert.equal(master1.getElementsByAttributeNS("*", "foo", "bar").length,
4);
Assert.equal(master2.getElementsByAttributeNS("*", "foo", "bar").length,
5);
Assert.equal(master3.getElementsByAttributeNS("*", "foo", "bar").length,
4);
Assert.equal(root.getElementsByAttributeNS("*", "foo", "bar").length, 16);
Assert.equal(master1.getElementsByAttributeNS("*", "foo", "bar").length, 4);
Assert.equal(master2.getElementsByAttributeNS("*", "foo", "bar").length, 5);
Assert.equal(master3.getElementsByAttributeNS("*", "foo", "bar").length, 4);
Assert.equal(root.getElementsByAttributeNS("*", "bar", "bar").length,
21);
Assert.equal(master1.getElementsByAttributeNS("*", "bar", "bar").length,
6);
Assert.equal(master2.getElementsByAttributeNS("*", "bar", "bar").length,
6);
Assert.equal(master3.getElementsByAttributeNS("*", "bar", "bar").length,
6);
Assert.equal(root.getElementsByAttributeNS("*", "bar", "bar").length, 21);
Assert.equal(master1.getElementsByAttributeNS("*", "bar", "bar").length, 6);
Assert.equal(master2.getElementsByAttributeNS("*", "bar", "bar").length, 6);
Assert.equal(master3.getElementsByAttributeNS("*", "bar", "bar").length, 6);
Assert.equal(root.getElementsByAttributeNS("*", "foo", "*").length,
54);
Assert.equal(master1.getElementsByAttributeNS("*", "foo", "*").length,
15);
Assert.equal(master2.getElementsByAttributeNS("*", "foo", "*").length,
15);
Assert.equal(master3.getElementsByAttributeNS("*", "foo", "*").length,
15);
Assert.equal(root.getElementsByAttributeNS("*", "foo", "*").length, 54);
Assert.equal(master1.getElementsByAttributeNS("*", "foo", "*").length, 15);
Assert.equal(master2.getElementsByAttributeNS("*", "foo", "*").length, 15);
Assert.equal(master3.getElementsByAttributeNS("*", "foo", "*").length, 15);
// Test null namespace. This should be the same as getElementsByAttribute.
Assert.equal(root.getElementsByAttributeNS("", "foo", "foo").length,
root.getElementsByAttribute("foo", "foo").length);
Assert.equal(master1.getElementsByAttributeNS("", "foo", "foo").length,
master1.getElementsByAttribute("foo", "foo").length);
Assert.equal(master2.getElementsByAttributeNS("", "foo", "foo").length,
master2.getElementsByAttribute("foo", "foo").length);
Assert.equal(master3.getElementsByAttributeNS("", "foo", "foo").length,
master3.getElementsByAttribute("foo", "foo").length);
Assert.equal(
root.getElementsByAttributeNS("", "foo", "foo").length,
root.getElementsByAttribute("foo", "foo").length
);
Assert.equal(
master1.getElementsByAttributeNS("", "foo", "foo").length,
master1.getElementsByAttribute("foo", "foo").length
);
Assert.equal(
master2.getElementsByAttributeNS("", "foo", "foo").length,
master2.getElementsByAttribute("foo", "foo").length
);
Assert.equal(
master3.getElementsByAttributeNS("", "foo", "foo").length,
master3.getElementsByAttribute("foo", "foo").length
);
// Test namespace "foo"
Assert.equal(root.getElementsByAttributeNS("foo", "foo", "foo").length,
24);
Assert.equal(master1.getElementsByAttributeNS("foo", "foo", "foo").length,
7);
Assert.equal(master2.getElementsByAttributeNS("foo", "foo", "foo").length,
6);
Assert.equal(master3.getElementsByAttributeNS("foo", "foo", "foo").length,
7);
Assert.equal(root.getElementsByAttributeNS("foo", "foo", "foo").length, 24);
Assert.equal(master1.getElementsByAttributeNS("foo", "foo", "foo").length, 7);
Assert.equal(master2.getElementsByAttributeNS("foo", "foo", "foo").length, 6);
Assert.equal(master3.getElementsByAttributeNS("foo", "foo", "foo").length, 7);
Assert.equal(root.getElementsByAttributeNS("foo", "foo", "bar").length,
9);
Assert.equal(master1.getElementsByAttributeNS("foo", "foo", "bar").length,
2);
Assert.equal(master2.getElementsByAttributeNS("foo", "foo", "bar").length,
3);
Assert.equal(master3.getElementsByAttributeNS("foo", "foo", "bar").length,
2);
Assert.equal(root.getElementsByAttributeNS("foo", "foo", "bar").length, 9);
Assert.equal(master1.getElementsByAttributeNS("foo", "foo", "bar").length, 2);
Assert.equal(master2.getElementsByAttributeNS("foo", "foo", "bar").length, 3);
Assert.equal(master3.getElementsByAttributeNS("foo", "foo", "bar").length, 2);
Assert.equal(root.getElementsByAttributeNS("foo", "bar", "foo").length,
7);
Assert.equal(master1.getElementsByAttributeNS("foo", "bar", "foo").length,
2);
Assert.equal(master2.getElementsByAttributeNS("foo", "bar", "foo").length,
2);
Assert.equal(master3.getElementsByAttributeNS("foo", "bar", "foo").length,
2);
Assert.equal(root.getElementsByAttributeNS("foo", "bar", "foo").length, 7);
Assert.equal(master1.getElementsByAttributeNS("foo", "bar", "foo").length, 2);
Assert.equal(master2.getElementsByAttributeNS("foo", "bar", "foo").length, 2);
Assert.equal(master3.getElementsByAttributeNS("foo", "bar", "foo").length, 2);
Assert.equal(root.getElementsByAttributeNS("foo", "bar", "bar").length,
14);
Assert.equal(master1.getElementsByAttributeNS("foo", "bar", "bar").length,
4);
Assert.equal(master2.getElementsByAttributeNS("foo", "bar", "bar").length,
4);
Assert.equal(master3.getElementsByAttributeNS("foo", "bar", "bar").length,
4);
Assert.equal(root.getElementsByAttributeNS("foo", "bar", "bar").length, 14);
Assert.equal(master1.getElementsByAttributeNS("foo", "bar", "bar").length, 4);
Assert.equal(master2.getElementsByAttributeNS("foo", "bar", "bar").length, 4);
Assert.equal(master3.getElementsByAttributeNS("foo", "bar", "bar").length, 4);
}

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

@ -36,7 +36,6 @@ function test_element() {
x.normalize();
Assert.equal(x.childNodes.length, 0);
// multiple empty Text nodes
x.appendChild(doc.createTextNode(""));
x.appendChild(doc.createTextNode(""));
@ -45,7 +44,6 @@ function test_element() {
x.normalize();
Assert.equal(x.childNodes.length, 0);
// empty Text node followed by other Text node
x.appendChild(doc.createTextNode(""));
x.appendChild(doc.createTextNode("Guaraldi"));
@ -55,7 +53,6 @@ function test_element() {
Assert.equal(x.childNodes.length, 1);
Assert.equal(x.childNodes.item(0).nodeValue, "Guaraldi");
// Text node followed by empty Text node
clearKids(x);
x.appendChild(doc.createTextNode("Guaraldi"));
@ -65,7 +62,6 @@ function test_element() {
x.normalize();
Assert.equal(x.childNodes.item(0).nodeValue, "Guaraldi");
// Text node followed by empty Text node followed by other Node
clearKids(x);
x.appendChild(doc.createTextNode("Guaraldi"));
@ -78,7 +74,6 @@ function test_element() {
Assert.equal(x.childNodes.item(0).nodeValue, "Guaraldi");
Assert.equal(x.childNodes.item(1).nodeName, "jazzy");
// Nodes are recursively normalized
clearKids(x);
var kid = doc.createElement("eit");
@ -96,10 +91,10 @@ function test_element() {
Assert.equal(x.childNodes.item(1).childNodes.length, 0);
}
// UTILITY FUNCTIONS
function clearKids(node) {
while (node.hasChildNodes())
while (node.hasChildNodes()) {
node.removeChild(node.childNodes.item(0));
}
}

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

@ -11,9 +11,9 @@ const UNORDERED_TYPE = 8; // XPathResult.ANY_UNORDERED_NODE_TYPE
* @return NodeFilter.FILTER_ACCEPT otherwise.
*/
function isWhitespace(aNode) {
return ((/\S/).test(aNode.nodeValue)) ?
NodeFilter.FILTER_SKIP :
NodeFilter.FILTER_ACCEPT;
return /\S/.test(aNode.nodeValue)
? NodeFilter.FILTER_SKIP
: NodeFilter.FILTER_ACCEPT;
}
/**
@ -75,7 +75,9 @@ function evalXPathInDocumentFragment(aContextNode, aPath) {
var childIndex = 1;
var bracketIndex = prefix.indexOf("[");
if (bracketIndex != -1) {
childIndex = Number(prefix.substring(bracketIndex + 1, prefix.indexOf("]")));
childIndex = Number(
prefix.substring(bracketIndex + 1, prefix.indexOf("]"))
);
Assert.ok(childIndex > 0);
prefix = prefix.substr(0, bracketIndex);
}
@ -84,7 +86,10 @@ function evalXPathInDocumentFragment(aContextNode, aPath) {
var targetNodeName = prefix;
if (prefix.indexOf("processing-instruction(") == 0) {
targetType = NodeFilter.SHOW_PROCESSING_INSTRUCTION;
targetNodeName = prefix.substring(prefix.indexOf("(") + 2, prefix.indexOf(")") - 1);
targetNodeName = prefix.substring(
prefix.indexOf("(") + 2,
prefix.indexOf(")") - 1
);
}
switch (prefix) {
case "text()":
@ -125,9 +130,10 @@ function evalXPathInDocumentFragment(aContextNode, aPath) {
// Look for the node matching the step from the document fragment.
var walker = aContextNode.ownerDocument.createTreeWalker(
aContextNode,
targetType,
filter);
aContextNode,
targetType,
filter
);
var targetNode = walker.nextNode();
Assert.notEqual(targetNode, null);
@ -170,7 +176,9 @@ function getRange(aSourceNode, aFragment) {
* @param aPath The path to the local document.
*/
function getParsedDocument(aPath) {
return do_parse_document(aPath, "application/xml").then(processParsedDocument);
return do_parse_document(aPath, "application/xml").then(
processParsedDocument
);
}
function processParsedDocument(doc) {
@ -178,10 +186,11 @@ function processParsedDocument(doc) {
Assert.equal(ChromeUtils.getClassName(doc), "XMLDocument");
// Clean out whitespace.
var walker = doc.createTreeWalker(doc,
NodeFilter.SHOW_TEXT |
NodeFilter.SHOW_CDATA_SECTION,
isWhitespace);
var walker = doc.createTreeWalker(
doc,
NodeFilter.SHOW_TEXT | NodeFilter.SHOW_CDATA_SECTION,
isWhitespace
);
while (walker.nextNode()) {
var parent = walker.currentNode.parentNode;
parent.removeChild(walker.currentNode);
@ -273,9 +282,7 @@ function do_extract_test(doc) {
Assert.ok(baseFrag.isEqualNode(resultFrag));
dump("Ensure the original nodes weren't extracted - test " + i + "\n\n");
var walker = doc.createTreeWalker(baseFrag,
NodeFilter.SHOW_ALL,
null);
var walker = doc.createTreeWalker(baseFrag, NodeFilter.SHOW_ALL, null);
var foundStart = false;
var foundEnd = false;
do {
@ -306,9 +313,7 @@ function do_extract_test(doc) {
Assert.ok(baseFrag.isEqualNode(resultFrag));
dump("Ensure the original nodes weren't deleted - test " + i + "\n\n");
walker = doc.createTreeWalker(baseFrag,
NodeFilter.SHOW_ALL,
null);
walker = doc.createTreeWalker(baseFrag, NodeFilter.SHOW_ALL, null);
foundStart = false;
foundEnd = false;
do {
@ -339,8 +344,9 @@ function run_miscellaneous_tests() {
}
function isText(node) {
return node.nodeType == node.TEXT_NODE ||
node.nodeType == node.CDATA_SECTION_NODE;
return (
node.nodeType == node.TEXT_NODE || node.nodeType == node.CDATA_SECTION_NODE
);
}
function do_miscellaneous_tests(doc) {
@ -359,9 +365,11 @@ function do_miscellaneous_tests(doc) {
var endOffset = baseRange.endOffset;
// Text range manipulation.
if ((endOffset > startOffset) &&
(startContainer == endContainer) &&
isText(startContainer)) {
if (
endOffset > startOffset &&
startContainer == endContainer &&
isText(startContainer)
) {
// Invalid start node
try {
baseRange.setStart(null, 0);
@ -387,9 +395,9 @@ function do_miscellaneous_tests(doc) {
}
// Invalid index
var newOffset = isText(startContainer) ?
startContainer.nodeValue.length + 1 :
startContainer.childNodes.length + 1;
var newOffset = isText(startContainer)
? startContainer.nodeValue.length + 1
: startContainer.childNodes.length + 1;
try {
baseRange.setStart(startContainer, newOffset);
do_throw("Should have thrown IndexSizeError!");
@ -410,7 +418,9 @@ function do_miscellaneous_tests(doc) {
Assert.equal(baseRange.startOffset, 0);
Assert.ok(baseRange.collapsed);
} else {
do_throw("The first test should be a text-only range test. Test is invalid.");
do_throw(
"The first test should be a text-only range test. Test is invalid."
);
}
/* See what happens when a range has a startContainer in one fragment, and an

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

@ -1,85 +1,99 @@
const encoders = {
xml: (doc) => {
let enc = Cu.createDocumentEncoder("text/xml");
enc.init(doc, "text/xml", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
html: (doc) => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
htmlBasic: (doc) => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(doc, "text/html",
Ci.nsIDocumentEncoder.OutputEncodeBasicEntities |
Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
xhtml: (doc) => {
let enc = Cu.createDocumentEncoder("application/xhtml+xml");
enc.init(doc, "application/xhtml+xml",
Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
xml: doc => {
let enc = Cu.createDocumentEncoder("text/xml");
enc.init(doc, "text/xml", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
html: doc => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
htmlBasic: doc => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(
doc,
"text/html",
Ci.nsIDocumentEncoder.OutputEncodeBasicEntities |
Ci.nsIDocumentEncoder.OutputLFLineBreak
);
return enc;
},
xhtml: doc => {
let enc = Cu.createDocumentEncoder("application/xhtml+xml");
enc.init(
doc,
"application/xhtml+xml",
Ci.nsIDocumentEncoder.OutputLFLineBreak
);
return enc;
},
};
// Which characters should we encode as entities? It depends on the serializer.
const encodeAll = { html: true, htmlBasic: true, xhtml: true, xml: true };
const encodeHTMLBasic = { html: false, htmlBasic: true, xhtml: false, xml: false };
const encodeHTMLBasic = {
html: false,
htmlBasic: true,
xhtml: false,
xml: false,
};
const encodeXML = { html: false, htmlBasic: false, xhtml: true, xml: true };
const encodeNone = { html: false, htmlBasic: false, xhtml: false, xml: false };
const encodingInfoMap = new Map([
// Basic sanity chars '<', '>', '"', '&' get encoded in all cases.
[ '<', encodeAll ],
[ '>', encodeAll ],
[ '&', encodeAll ],
// nbsp is only encoded with the HTML encoder when encoding basic entities.
[ '\xA0', encodeHTMLBasic ],
// Basic sanity chars '<', '>', '"', '&' get encoded in all cases.
["<", encodeAll],
[">", encodeAll],
["&", encodeAll],
// nbsp is only encoded with the HTML encoder when encoding basic entities.
["\xA0", encodeHTMLBasic],
]);
const encodingMap = new Map([
[ '<', '&lt;' ],
[ '>', '&gt;' ],
[ '&', '&amp;' ],
// nbsp is only encoded with the HTML encoder when encoding basic entities.
[ '\xA0', '&nbsp;' ],
["<", "&lt;"],
[">", "&gt;"],
["&", "&amp;"],
// nbsp is only encoded with the HTML encoder when encoding basic entities.
["\xA0", "&nbsp;"],
]);
function encodingInfoForChar(c) {
var info = encodingInfoMap.get(c);
if (info) {
return info;
}
return encodeNone;
var info = encodingInfoMap.get(c);
if (info) {
return info;
}
return encodeNone;
}
function encodingForChar(c, type) {
var info = encodingInfoForChar(c);
if (!info[type]) {
return c;
}
return encodingMap.get(c);
var info = encodingInfoForChar(c);
if (!info[type]) {
return c;
}
return encodingMap.get(c);
}
const doc = new DOMParser().parseFromString("<root></root>", "text/xml")
const doc = new DOMParser().parseFromString("<root></root>", "text/xml");
const root = doc.documentElement;
for (let i = 0; i < 255; ++i) {
let el = doc.createElement("span");
el.textContent = String.fromCharCode(i);
root.appendChild(el);
let el = doc.createElement("span");
el.textContent = String.fromCharCode(i);
root.appendChild(el);
}
for (let type of ["xml", "xhtml", "htmlBasic", "html"]) {
let str = encoders[type](doc).encodeToString();
const prefix = "<root><span>";
const suffix = "</span></root>";
Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`);
Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`);
str = str.substring(prefix.length, str.length - suffix.length);
let encodings = str.split("</span><span>");
for (let i = 0; i < 255; ++i) {
let c = String.fromCharCode(i);
Assert.equal(encodingForChar(c, type), encodings[i],
`${type} encoding of char ${i} is correct`);
}
let str = encoders[type](doc).encodeToString();
const prefix = "<root><span>";
const suffix = "</span></root>";
Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`);
Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`);
str = str.substring(prefix.length, str.length - suffix.length);
let encodings = str.split("</span><span>");
for (let i = 0; i < 255; ++i) {
let c = String.fromCharCode(i);
Assert.equal(
encodingForChar(c, type),
encodings[i],
`${type} encoding of char ${i} is correct`
);
}
}

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

@ -1,94 +1,108 @@
const encoders = {
xml: (doc) => {
let enc = Cu.createDocumentEncoder("text/xml");
enc.init(doc, "text/xml", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
html: (doc) => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
htmlBasic: (doc) => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(doc, "text/html",
Ci.nsIDocumentEncoder.OutputEncodeBasicEntities |
Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
xhtml: (doc) => {
let enc = Cu.createDocumentEncoder("application/xhtml+xml");
enc.init(doc, "application/xhtml+xml",
Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
xml: doc => {
let enc = Cu.createDocumentEncoder("text/xml");
enc.init(doc, "text/xml", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
html: doc => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputLFLineBreak);
return enc;
},
htmlBasic: doc => {
let enc = Cu.createDocumentEncoder("text/html");
enc.init(
doc,
"text/html",
Ci.nsIDocumentEncoder.OutputEncodeBasicEntities |
Ci.nsIDocumentEncoder.OutputLFLineBreak
);
return enc;
},
xhtml: doc => {
let enc = Cu.createDocumentEncoder("application/xhtml+xml");
enc.init(
doc,
"application/xhtml+xml",
Ci.nsIDocumentEncoder.OutputLFLineBreak
);
return enc;
},
};
// Which characters should we encode as entities? It depends on the serializer.
const encodeAll = { html: true, htmlBasic: true, xhtml: true, xml: true };
const encodeHTMLBasic = { html: false, htmlBasic: true, xhtml: false, xml: false };
const encodeHTMLBasic = {
html: false,
htmlBasic: true,
xhtml: false,
xml: false,
};
const encodeXML = { html: false, htmlBasic: false, xhtml: true, xml: true };
const encodeNone = { html: false, htmlBasic: false, xhtml: false, xml: false };
const encodingInfoMap = new Map([
// Basic sanity chars '<', '>', '"', '&' get encoded in all cases.
[ '<', encodeAll ],
[ '>', encodeAll ],
[ '"', encodeAll ],
[ '&', encodeAll ],
// nbsp is only encoded with the HTML encoder when encoding basic entities.
[ '\xA0', encodeHTMLBasic ],
// Whitespace bits are only encoded in XML.
[ '\n', encodeXML ],
[ '\r', encodeXML ],
[ '\t', encodeXML ],
// Basic sanity chars '<', '>', '"', '&' get encoded in all cases.
["<", encodeAll],
[">", encodeAll],
['"', encodeAll],
["&", encodeAll],
// nbsp is only encoded with the HTML encoder when encoding basic entities.
["\xA0", encodeHTMLBasic],
// Whitespace bits are only encoded in XML.
["\n", encodeXML],
["\r", encodeXML],
["\t", encodeXML],
]);
const encodingMap = new Map([
[ '<', '&lt;' ],
[ '>', '&gt;' ],
[ '"', '&quot;' ],
[ '&', '&amp;' ],
[ '\xA0', '&nbsp;' ],
[ '\n', '&#xA;' ],
[ '\r', '&#xD;' ],
[ '\t', '&#9;' ],
["<", "&lt;"],
[">", "&gt;"],
['"', "&quot;"],
["&", "&amp;"],
["\xA0", "&nbsp;"],
["\n", "&#xA;"],
["\r", "&#xD;"],
["\t", "&#9;"],
]);
function encodingInfoForChar(c) {
var info = encodingInfoMap.get(c);
if (info) {
return info;
}
return encodeNone;
var info = encodingInfoMap.get(c);
if (info) {
return info;
}
return encodeNone;
}
function encodingForChar(c, type) {
var info = encodingInfoForChar(c);
if (!info[type]) {
return c;
}
return encodingMap.get(c);
var info = encodingInfoForChar(c);
if (!info[type]) {
return c;
}
return encodingMap.get(c);
}
const doc = new DOMParser().parseFromString("<root></root>", "text/xml")
const doc = new DOMParser().parseFromString("<root></root>", "text/xml");
const root = doc.documentElement;
for (let i = 0; i < 255; ++i) {
let el = doc.createElement("span");
el.setAttribute("x", String.fromCharCode(i));
el.textContent = " ";
root.appendChild(el);
let el = doc.createElement("span");
el.setAttribute("x", String.fromCharCode(i));
el.textContent = " ";
root.appendChild(el);
}
for (let type of ["xml", "xhtml", "htmlBasic", "html"]) {
let str = encoders[type](doc).encodeToString();
const prefix = '<root><span x="';
const suffix = '"> </span></root>';
Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`);
Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`);
str = str.substring(prefix.length, str.length - suffix.length);
let encodings = str.split('"> </span><span x="');
for (let i = 0; i < 255; ++i) {
let c = String.fromCharCode(i);
Assert.equal(encodingForChar(c, type), encodings[i],
`${type} encoding of char ${i} is correct`);
}
let str = encoders[type](doc).encodeToString();
const prefix = '<root><span x="';
const suffix = '"> </span></root>';
Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`);
Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`);
str = str.substring(prefix.length, str.length - suffix.length);
let encodings = str.split('"> </span><span x="');
for (let i = 0; i < 255; ++i) {
let c = String.fromCharCode(i);
Assert.equal(
encodingForChar(c, type),
encodings[i],
`${type} encoding of char ${i} is correct`
);
}
}

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

@ -4,44 +4,67 @@ const global = this;
add_task(async function test_structuredCloneHolder() {
let principal = Services.scriptSecurityManager.createCodebasePrincipal(
Services.io.newURI("http://example.com/"), {});
Services.io.newURI("http://example.com/"),
{}
);
let sandbox = Cu.Sandbox(principal);
const obj = {foo: [{bar: "baz"}]};
const obj = { foo: [{ bar: "baz" }] };
let holder = new StructuredCloneHolder(obj);
// Test same-compartment deserialization
let res = holder.deserialize(global, true);
notEqual(res, obj, "Deserialized result is a different object from the original");
notEqual(
res,
obj,
"Deserialized result is a different object from the original"
);
deepEqual(res, obj, "Deserialized result is deeply equivalent to the original");
equal(Cu.getObjectPrincipal(res), Cu.getObjectPrincipal(global),
"Deserialized result has the correct principal");
deepEqual(
res,
obj,
"Deserialized result is deeply equivalent to the original"
);
equal(
Cu.getObjectPrincipal(res),
Cu.getObjectPrincipal(global),
"Deserialized result has the correct principal"
);
// Test non-object-value round-trip.
equal(new StructuredCloneHolder("foo").deserialize(global), "foo",
"Round-tripping non-object values works as expected");
equal(
new StructuredCloneHolder("foo").deserialize(global),
"foo",
"Round-tripping non-object values works as expected"
);
// Test cross-compartment deserialization
res = holder.deserialize(sandbox, true);
notEqual(res, obj, "Cross-compartment-deserialized result is a different object from the original");
notEqual(
res,
obj,
"Cross-compartment-deserialized result is a different object from the original"
);
deepEqual(res, obj, "Cross-compartment-deserialized result is deeply equivalent to the original");
equal(Cu.getObjectPrincipal(res), principal,
"Cross-compartment-deserialized result has the correct principal");
deepEqual(
res,
obj,
"Cross-compartment-deserialized result is deeply equivalent to the original"
);
equal(
Cu.getObjectPrincipal(res),
principal,
"Cross-compartment-deserialized result has the correct principal"
);
// Test message manager transportability
@ -55,52 +78,82 @@ add_task(async function test_structuredCloneHolder() {
res = await resultPromise;
ok(res.data instanceof StructuredCloneHolder,
"Sending structured clone holders through message managers works as expected");
ok(
res.data instanceof StructuredCloneHolder,
"Sending structured clone holders through message managers works as expected"
);
deepEqual(res.data.deserialize(global, true), obj,
"Sending structured clone holders through message managers works as expected");
deepEqual(
res.data.deserialize(global, true),
obj,
"Sending structured clone holders through message managers works as expected"
);
// Test that attempting to deserialize a neutered holder throws.
deepEqual(holder.deserialize(global), obj, "Deserialized result is correct when discarding data");
deepEqual(
holder.deserialize(global),
obj,
"Deserialized result is correct when discarding data"
);
Assert.throws(() => holder.deserialize(global),
err => err.result == Cr.NS_ERROR_NOT_INITIALIZED,
"Attempting to deserialize neutered holder throws");
Assert.throws(
() => holder.deserialize(global),
err => err.result == Cr.NS_ERROR_NOT_INITIALIZED,
"Attempting to deserialize neutered holder throws"
);
Assert.throws(() => holder.deserialize(global, true),
err => err.result == Cr.NS_ERROR_NOT_INITIALIZED,
"Attempting to deserialize neutered holder throws");
Assert.throws(
() => holder.deserialize(global, true),
err => err.result == Cr.NS_ERROR_NOT_INITIALIZED,
"Attempting to deserialize neutered holder throws"
);
});
// Test that X-rays passed to an exported function are serialized
// through their exported wrappers.
add_task(async function test_structuredCloneHolder_xray() {
let principal = Services.scriptSecurityManager.createCodebasePrincipal(
Services.io.newURI("http://example.com/"), {});
Services.io.newURI("http://example.com/"),
{}
);
let sandbox1 = Cu.Sandbox(principal, {wantXrays: true});
let sandbox1 = Cu.Sandbox(principal, { wantXrays: true });
let sandbox2 = Cu.Sandbox(principal, {wantXrays: true});
let sandbox2 = Cu.Sandbox(principal, { wantXrays: true });
Cu.evalInSandbox(`this.x = {y: "z", get z() { return "q" }}`, sandbox2);
sandbox1.x = sandbox2.x;
let holder;
Cu.exportFunction(function serialize(val) {
holder = new StructuredCloneHolder(val, sandbox1);
}, sandbox1, {defineAs: "serialize"});
Cu.exportFunction(
function serialize(val) {
holder = new StructuredCloneHolder(val, sandbox1);
},
sandbox1,
{ defineAs: "serialize" }
);
Cu.evalInSandbox(`serialize(x)`, sandbox1);
const obj = {y: "z"};
const obj = { y: "z" };
let res = holder.deserialize(global);
deepEqual(res, obj, "Deserialized result is deeply equivalent to the expected object");
deepEqual(res, sandbox2.x, "Deserialized result is deeply equivalent to the X-ray-wrapped object");
deepEqual(
res,
obj,
"Deserialized result is deeply equivalent to the expected object"
);
deepEqual(
res,
sandbox2.x,
"Deserialized result is deeply equivalent to the X-ray-wrapped object"
);
equal(Cu.getObjectPrincipal(res), Cu.getObjectPrincipal(global),
"Deserialized result has the correct principal");
equal(
Cu.getObjectPrincipal(res),
Cu.getObjectPrincipal(global),
"Deserialized result has the correct principal"
);
});

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

@ -18,8 +18,7 @@ function do_check_throws(f, result, stack) {
try {
// We might not have a 'Components' object.
stack = Components.stack.caller;
} catch (e) {
}
} catch (e) {}
}
try {
@ -32,7 +31,9 @@ function do_check_throws(f, result, stack) {
}
function run_test() {
let util = Cc["@mozilla.org/thirdpartyutil;1"].getService(Ci.mozIThirdPartyUtil);
let util = Cc["@mozilla.org/thirdpartyutil;1"].getService(
Ci.mozIThirdPartyUtil
);
// Create URIs and channels pointing to foo.com and bar.com.
// We will use these to put foo.com into first and third party contexts.
@ -41,16 +42,24 @@ function run_test() {
let uri1 = NetUtil.newURI(spec1);
let uri2 = NetUtil.newURI(spec2);
const contentPolicyType = Ci.nsIContentPolicy.TYPE_DOCUMENT;
let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true, contentPolicyType});
NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true, contentPolicyType});
let channel1 = NetUtil.newChannel({
uri: uri1,
loadUsingSystemPrincipal: true,
contentPolicyType,
});
NetUtil.newChannel({
uri: uri2,
loadUsingSystemPrincipal: true,
contentPolicyType,
});
// Create some file:// URIs.
let filespec1 = "file://foo.txt";
let filespec2 = "file://bar.txt";
let fileuri1 = NetUtil.newURI(filespec1);
let fileuri2 = NetUtil.newURI(filespec2);
NetUtil.newChannel({uri: fileuri1, loadUsingSystemPrincipal: true});
NetUtil.newChannel({uri: fileuri2, loadUsingSystemPrincipal: true});
NetUtil.newChannel({ uri: fileuri1, loadUsingSystemPrincipal: true });
NetUtil.newChannel({ uri: fileuri2, loadUsingSystemPrincipal: true });
// Test isThirdPartyURI.
Assert.ok(!util.isThirdPartyURI(uri1, uri1));
@ -59,12 +68,15 @@ function run_test() {
Assert.ok(!util.isThirdPartyURI(fileuri1, fileuri1));
Assert.ok(!util.isThirdPartyURI(fileuri1, fileuri2));
Assert.ok(util.isThirdPartyURI(uri1, fileuri1));
do_check_throws(function() { util.isThirdPartyURI(uri1, null); },
NS_ERROR_INVALID_ARG);
do_check_throws(function() { util.isThirdPartyURI(null, uri1); },
NS_ERROR_INVALID_ARG);
do_check_throws(function() { util.isThirdPartyURI(null, null); },
NS_ERROR_INVALID_ARG);
do_check_throws(function() {
util.isThirdPartyURI(uri1, null);
}, NS_ERROR_INVALID_ARG);
do_check_throws(function() {
util.isThirdPartyURI(null, uri1);
}, NS_ERROR_INVALID_ARG);
do_check_throws(function() {
util.isThirdPartyURI(null, null);
}, NS_ERROR_INVALID_ARG);
// We can't test isThirdPartyWindow since we can't really set up a window
// hierarchy. We leave that to mochitests.
@ -72,8 +84,9 @@ function run_test() {
// Test isThirdPartyChannel. As above, we can't test the bits that require
// a load context or window heirarchy. Because of bug 1259873, we assume
// that these are not third-party.
do_check_throws(function() { util.isThirdPartyChannel(null); },
NS_ERROR_INVALID_ARG);
do_check_throws(function() {
util.isThirdPartyChannel(null);
}, NS_ERROR_INVALID_ARG);
Assert.ok(!util.isThirdPartyChannel(channel1));
Assert.ok(!util.isThirdPartyChannel(channel1, uri1));
Assert.ok(util.isThirdPartyChannel(channel1, uri2));
@ -84,4 +97,3 @@ function run_test() {
Assert.ok(!util.isThirdPartyChannel(channel1, uri1));
Assert.ok(util.isThirdPartyChannel(channel1, uri2));
}

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

@ -2,18 +2,21 @@
* 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/. */
var {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js");
var { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
var server = new HttpServer();
server.start(-1);
var docbody = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>';
var docbody =
'<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>';
function handler(metadata, response) {
var {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
let body = NetUtil.readInputStreamToString(metadata.bodyInputStream,
metadata.bodyInputStream.available());
let body = NetUtil.readInputStreamToString(
metadata.bodyInputStream,
metadata.bodyInputStream.available()
);
response.setStatusLine(metadata.httpVersion, 200, "OK");
response.write(body, body.length);
}
@ -33,6 +36,10 @@ function run_test() {
Assert.equal(false, false);
server.stop(do_test_finished);
};
xhr.open("POST", "http://localhost:" + server.identity.primaryPort + "/foo", true);
xhr.open(
"POST",
"http://localhost:" + server.identity.primaryPort + "/foo",
true
);
xhr.send(doc);
}

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

@ -1,7 +1,8 @@
let server = new HttpServer();
server.start(-1);
let body = "<!DOCTYPE HTML><html><head><meta charset='utf-8'></head><body></body></html>";
let body =
"<!DOCTYPE HTML><html><head><meta charset='utf-8'></head><body></body></html>";
function handler(request, response) {
response.setStatusLine(request.httpVersion, 200, "Ok");
@ -22,7 +23,11 @@ function run_test() {
server.registerPathHandler("/foo", handler);
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:" + server.identity.primaryPort + "/foo", true);
xhr.open(
"GET",
"http://localhost:" + server.identity.primaryPort + "/foo",
true
);
xhr.send(null);
xhr.onload = function() {
@ -30,8 +35,12 @@ function run_test() {
// specify with different origin attributes, which will make the XHR use a
// different cookie-jar than the previous one.
let xhr2 = new XMLHttpRequest();
xhr2.open("GET", "http://localhost:" + server.identity.primaryPort + "/foo", true);
xhr2.setOriginAttributes({userContextId: 1});
xhr2.open(
"GET",
"http://localhost:" + server.identity.primaryPort + "/foo",
true
);
xhr2.setOriginAttributes({ userContextId: 1 });
xhr2.send(null);
let loadInfo = xhr2.channel.loadInfo;

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

@ -6,14 +6,14 @@
// in non-window non-Worker context
function run_test() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "data:,", false);
var exceptionThrown = false;
try {
xhr.responseType = "";
xhr.withCredentials = false;
} catch (e) {
exceptionThrown = true;
}
Assert.equal(false, exceptionThrown);
var xhr = new XMLHttpRequest();
xhr.open("GET", "data:,", false);
var exceptionThrown = false;
try {
xhr.responseType = "";
xhr.withCredentials = false;
} catch (e) {
exceptionThrown = true;
}
Assert.equal(false, exceptionThrown);
}

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

@ -7,13 +7,13 @@ function run_test() {
}
var tests = [
[ test1, "Unable to parse basic XML document" ],
[ test2, "ParseXML doesn't return Document" ],
[ test3, "ParseXML return value's documentElement is not Element" ],
[ test4, "" ],
[ test5, "" ],
[ test6, "" ],
[ null ],
[test1, "Unable to parse basic XML document"],
[test2, "ParseXML doesn't return Document"],
[test3, "ParseXML return value's documentElement is not Element"],
[test4, ""],
[test5, ""],
[test6, ""],
[null],
];
function test1() {
@ -21,7 +21,7 @@ function test1() {
}
function test2() {
return (ChromeUtils.getClassName(ParseXML("<root/>")) === "XMLDocument");
return ChromeUtils.getClassName(ParseXML("<root/>")) === "XMLDocument";
}
function test3() {

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

@ -1,4 +1,3 @@
// The xml serializer uses the default line break of the plateform.
// So we need to know the value of this default line break, in order
// to build correctly the reference strings for tests.
@ -49,7 +48,9 @@ function test1() {
testString('<a:root xmlns:a="ns1"><a:child/></a:root>');
testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1"/></a:root>');
testString('<a:root xmlns:a="ns1"><a:child xmlns:a="ns2"/></a:root>');
testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1" b:attr=""/></a:root>');
testString(
'<a:root xmlns:a="ns1"><b:child xmlns:b="ns1" b:attr=""/></a:root>'
);
}
function test2() {
@ -72,25 +73,31 @@ function test3() {
var child = doc.createElementNS("ns2", "child");
root.appendChild(child);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1"><child xmlns="ns2"/></root>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1"><child xmlns="ns2"/></root>'
);
doc = ParseXML('<root xmlns="ns1"/>');
root = doc.documentElement;
child = doc.createElementNS("ns2", "prefix:child");
root.appendChild(child);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1"><prefix:child xmlns:prefix="ns2"/></root>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1"><prefix:child xmlns:prefix="ns2"/></root>'
);
doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>');
root = doc.documentElement;
child = doc.createElementNS("ns2", "prefix:child");
root.appendChild(child);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1"><a0:child xmlns:a0="ns2"/>' +
"</prefix:root>");
Assert.equal(
SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1"><a0:child xmlns:a0="ns2"/>' +
"</prefix:root>"
);
}
function test4() {
@ -100,22 +107,28 @@ function test4() {
var root = doc.documentElement;
root.setAttributeNS("ns1", "prefix:local", "val");
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1" prefix:local="val" xmlns:prefix="ns1"/>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1" prefix:local="val" xmlns:prefix="ns1"/>'
);
doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>');
root = doc.documentElement;
root.setAttributeNS("ns1", "local", "val");
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1" prefix:local="val"/>');
Assert.equal(
SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1" prefix:local="val"/>'
);
doc = ParseXML('<root xmlns="ns1"/>');
root = doc.documentElement;
root.setAttributeNS("ns2", "local", "val");
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1" a0:local="val" xmlns:a0="ns2"/>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1" a0:local="val" xmlns:a0="ns2"/>'
);
// Handling of prefix-generation for non-null-namespace attributes
// which have the same namespace as the current default namespace
@ -124,13 +137,17 @@ function test4() {
root = doc.documentElement;
root.setAttributeNS("ns1", "local", "val");
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>'
);
// Tree-walking test
doc = ParseXML('<root xmlns="ns1" xmlns:a="ns2">' +
'<child xmlns:b="ns2" xmlns:a="ns3">' +
"<child2/></child></root>");
doc = ParseXML(
'<root xmlns="ns1" xmlns:a="ns2">' +
'<child xmlns:b="ns2" xmlns:a="ns3">' +
"<child2/></child></root>"
);
root = doc.documentElement;
var node = root.firstChild.firstChild;
node.setAttributeNS("ns4", "l1", "v1");
@ -150,22 +167,24 @@ function test4() {
// Note: we end up with "a2" as the prefix on "l11" and "l12" because we use
// "a1" earlier, and discard it in favor of something we get off the
// namespace stack, apparently
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1" xmlns:a="ns2">' +
'<child xmlns:b="ns2" xmlns:a="ns3">' +
'<child2 a0:l1="v1" xmlns:a0="ns4"' +
' a0:l2="v2"' +
' l3="v3"' +
' a:l4="v4"' +
' a:l5="v5"' +
' a:l6="v6"' +
' b:l7="v7"' +
' b:l8="v8"' +
' b:l9="v9"' +
' b:l10="v10"' +
' a2:l11="v11" xmlns:a2="ns1"' +
' a2:l12="v12"' +
' a2:l13="v13"/></child></root>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1" xmlns:a="ns2">' +
'<child xmlns:b="ns2" xmlns:a="ns3">' +
'<child2 a0:l1="v1" xmlns:a0="ns4"' +
' a0:l2="v2"' +
' l3="v3"' +
' a:l4="v4"' +
' a:l5="v5"' +
' a:l6="v6"' +
' b:l7="v7"' +
' b:l8="v8"' +
' b:l9="v9"' +
' b:l10="v10"' +
' a2:l11="v11" xmlns:a2="ns1"' +
' a2:l12="v12"' +
' a2:l13="v13"/></child></root>'
);
}
function test5() {
@ -175,8 +194,7 @@ function test5() {
var child = doc.createElement("child");
doc.documentElement.appendChild(child);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1"><child xmlns=""/></root>');
Assert.equal(SerializeXML(doc), '<root xmlns="ns1"><child xmlns=""/></root>');
}
function test6() {
@ -189,31 +207,40 @@ function test6() {
child1.appendChild(child2);
root.appendChild(child1);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1"><a0:child1 xmlns:a0="ns2">' +
"<prefix:child2/></a0:child1></prefix:root>");
Assert.equal(
SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1"><a0:child1 xmlns:a0="ns2">' +
"<prefix:child2/></a0:child1></prefix:root>"
);
doc = ParseXML('<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2"/></root>');
doc = ParseXML(
'<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2"/></root>'
);
root = doc.documentElement;
child1 = root.firstChild;
child2 = doc.createElementNS("ns1", "prefix:child2");
child1.appendChild(child2);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2">' +
"<child2/></prefix:child1></root>");
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2">' +
"<child2/></prefix:child1></root>"
);
doc = ParseXML('<prefix:root xmlns:prefix="ns1">' +
'<prefix:child1 xmlns:prefix="ns2"/></prefix:root>');
doc = ParseXML(
'<prefix:root xmlns:prefix="ns1">' +
'<prefix:child1 xmlns:prefix="ns2"/></prefix:root>'
);
root = doc.documentElement;
child1 = root.firstChild;
child2 = doc.createElementNS("ns1", "prefix:child2");
child1.appendChild(child2);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1"><prefix:child1 xmlns:prefix="ns2">' +
'<a0:child2 xmlns:a0="ns1"/></prefix:child1></prefix:root>');
Assert.equal(
SerializeXML(doc),
'<prefix:root xmlns:prefix="ns1"><prefix:child1 xmlns:prefix="ns2">' +
'<a0:child2 xmlns:a0="ns1"/></prefix:child1></prefix:root>'
);
doc = ParseXML('<root xmlns="ns1"/>');
root = doc.documentElement;
@ -222,9 +249,11 @@ function test6() {
child1.appendChild(child2);
root.appendChild(child1);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>' +
"</child1></root>");
Assert.equal(
SerializeXML(doc),
'<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>' +
"</child1></root>"
);
}
function test7() {
@ -232,44 +261,64 @@ function test7() {
// element (bug 326994).
var doc = ParseXML('<root xmlns=""/>');
var root = doc.documentElement;
root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
root.setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns",
"http://www.w3.org/1999/xhtml"
);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc), "<root/>");
doc = ParseXML('<root xmlns=""><child1/></root>');
root = doc.documentElement;
root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
root.setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns",
"http://www.w3.org/1999/xhtml"
);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc), "<root><child1/></root>");
doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
'<child1 xmlns=""><child2/></child1></root>');
doc = ParseXML(
'<root xmlns="http://www.w3.org/1999/xhtml">' +
'<child1 xmlns=""><child2/></child1></root>'
);
root = doc.documentElement;
var child1 = root.firstChild;
child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
child1.setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns",
"http://www.w3.org/1999/xhtml"
);
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
"<child2/></child1></root>");
Assert.equal(
SerializeXML(doc),
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
"<child2/></child1></root>"
);
doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
'<child1 xmlns="">' +
'<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' +
"</child1></root>");
doc = ParseXML(
'<root xmlns="http://www.w3.org/1999/xhtml">' +
'<child1 xmlns="">' +
'<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' +
"</child1></root>"
);
root = doc.documentElement;
child1 = root.firstChild;
var child2 = child1.firstChild;
child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
"http://www.w3.org/1999/xhtml");
child1.setAttributeNS(
"http://www.w3.org/2000/xmlns/",
"xmlns",
"http://www.w3.org/1999/xhtml"
);
child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
do_check_serialize(doc);
Assert.equal(SerializeXML(doc),
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
'<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>');
Assert.equal(
SerializeXML(doc),
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
'<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>'
);
}
function test8() {
@ -303,9 +352,8 @@ function test8() {
function test9() {
// Test behavior of serializing between given charsets, using
// windows-1252-representable text.
var contents = "<root>" +
"\u00BD + \u00BE == \u00BD\u00B2 + \u00BC + \u00BE" +
"</root>";
var contents =
"<root>" + "\u00BD + \u00BE == \u00BD\u00B2 + \u00BC + \u00BE" + "</root>";
var str1 = '<?xml version="1.0" encoding="windows-1252"?>' + LB + contents;
var str2 = '<?xml version="1.0" encoding="UTF-8"?>' + LB + contents;
var str3 = '<?xml version="1.0" encoding="UTF-16"?>' + LB + contents;
@ -331,11 +379,12 @@ function test10() {
// Unicode characters (XXX but only BMP ones because I don't know
// how to create one with non-BMP characters, either with JS strings
// or using DOM APIs).
var contents = "<root>" +
"AZaz09 \u007F " + // U+000000 to U+00007F
"\u0080 \u0398 \u03BB \u0725 " + // U+000080 to U+0007FF
"\u0964 \u0F5F \u20AC \uFFFB" + // U+000800 to U+00FFFF
"</root>";
var contents =
"<root>" +
"AZaz09 \u007F " + // U+000000 to U+00007F
"\u0080 \u0398 \u03BB \u0725 " + // U+000080 to U+0007FF
"\u0964 \u0F5F \u20AC \uFFFB" + // U+000800 to U+00FFFF
"</root>";
var str1 = '<?xml version="1.0" encoding="UTF-8"?>' + LB + contents;
var str2 = '<?xml version="1.0" encoding="UTF-16"?>' + LB + contents;
var doc1 = ParseXML(str1);
@ -353,9 +402,10 @@ function checkSerialization(doc, toCharset, expectedString) {
DOMSerializer().serializeToStream(doc, p.outputStream, toCharset);
p.outputStream.close();
var inCharset = (toCharset == "UTF-16") ? "UTF-8" : toCharset;
var cin = C["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(I.nsIConverterInputStream);
var inCharset = toCharset == "UTF-16" ? "UTF-8" : toCharset;
var cin = C["@mozilla.org/intl/converter-input-stream;1"].createInstance(
I.nsIConverterInputStream
);
cin.init(p.inputStream, inCharset, 1024, 0x0);
// compare the first expectedString.length characters for equality

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

@ -4,94 +4,120 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
async function xmlEncode(aFile, aFlags, aCharset) {
if (aFlags == undefined) aFlags = 0;
if (aCharset == undefined) aCharset = "UTF-8";
if (aFlags == undefined) {
aFlags = 0;
}
if (aCharset == undefined) {
aCharset = "UTF-8";
}
var doc = await do_parse_document(aFile, "text/xml");
var doc = await do_parse_document(aFile, "text/xml");
var encoder = Cu.createDocumentEncoder("text/xml");
encoder.setCharset(aCharset);
encoder.init(doc, "text/xml", aFlags);
return encoder.encodeToString();
var encoder = Cu.createDocumentEncoder("text/xml");
encoder.setCharset(aCharset);
encoder.init(doc, "text/xml", aFlags);
return encoder.encodeToString();
}
add_task(async function() {
var result, expected;
const de = Ci.nsIDocumentEncoder;
var result, expected;
const de = Ci.nsIDocumentEncoder;
result = await xmlEncode("1_original.xml", de.OutputLFLineBreak);
expected = loadContentFile("1_result.xml");
Assert.equal(expected, result);
result = await xmlEncode("1_original.xml", de.OutputLFLineBreak);
expected = loadContentFile("1_result.xml");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputLFLineBreak);
expected = loadContentFile("2_result_1.xml");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputLFLineBreak);
expected = loadContentFile("2_result_1.xml");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputCRLineBreak);
expected = expected.replace(/\n/g, "\r");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputCRLineBreak);
expected = expected.replace(/\n/g, "\r");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputCRLineBreak);
expected = expected.replace(/\r/mg, "\r\n");
Assert.equal(expected, result);
result = await xmlEncode(
"2_original.xml",
de.OutputLFLineBreak | de.OutputCRLineBreak
);
expected = expected.replace(/\r/gm, "\r\n");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputFormatted);
expected = loadContentFile("2_result_2.xml");
Assert.equal(expected, result);
result = await xmlEncode(
"2_original.xml",
de.OutputLFLineBreak | de.OutputFormatted
);
expected = loadContentFile("2_result_2.xml");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap);
expected = loadContentFile("2_result_3.xml");
Assert.equal(expected, result);
result = await xmlEncode(
"2_original.xml",
de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap
);
expected = loadContentFile("2_result_3.xml");
Assert.equal(expected, result);
result = await xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputWrap);
expected = loadContentFile("2_result_4.xml");
Assert.equal(expected, result);
result = await xmlEncode(
"2_original.xml",
de.OutputLFLineBreak | de.OutputWrap
);
expected = loadContentFile("2_result_4.xml");
Assert.equal(expected, result);
result = await xmlEncode("3_original.xml", de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap);
expected = loadContentFile("3_result.xml");
Assert.equal(expected, result);
result = await xmlEncode(
"3_original.xml",
de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap
);
expected = loadContentFile("3_result.xml");
Assert.equal(expected, result);
result = await xmlEncode("3_original.xml", de.OutputLFLineBreak | de.OutputWrap);
expected = loadContentFile("3_result_2.xml");
Assert.equal(expected, result);
result = await xmlEncode(
"3_original.xml",
de.OutputLFLineBreak | de.OutputWrap
);
expected = loadContentFile("3_result_2.xml");
Assert.equal(expected, result);
// tests on namespaces
var doc = await do_parse_document("4_original.xml", "text/xml");
// tests on namespaces
var doc = await do_parse_document("4_original.xml", "text/xml");
var encoder = Cu.createDocumentEncoder("text/xml");
encoder.setCharset("UTF-8");
encoder.init(doc, "text/xml", de.OutputLFLineBreak);
var encoder = Cu.createDocumentEncoder("text/xml");
encoder.setCharset("UTF-8");
encoder.init(doc, "text/xml", de.OutputLFLineBreak);
result = encoder.encodeToString();
expected = loadContentFile("4_result_1.xml");
Assert.equal(expected, result);
result = encoder.encodeToString();
expected = loadContentFile("4_result_1.xml");
Assert.equal(expected, result);
encoder.setNode(doc.documentElement.childNodes[9]);
result = encoder.encodeToString();
expected = loadContentFile("4_result_2.xml");
Assert.equal(expected, result);
encoder.setNode(doc.documentElement.childNodes[9]);
result = encoder.encodeToString();
expected = loadContentFile("4_result_2.xml");
Assert.equal(expected, result);
encoder.setNode(doc.documentElement.childNodes[7].childNodes[1]);
result = encoder.encodeToString();
expected = loadContentFile("4_result_3.xml");
Assert.equal(expected, result);
encoder.setNode(doc.documentElement.childNodes[7].childNodes[1]);
result = encoder.encodeToString();
expected = loadContentFile("4_result_3.xml");
Assert.equal(expected, result);
encoder.setNode(doc.documentElement.childNodes[11].childNodes[1]);
result = encoder.encodeToString();
expected = loadContentFile("4_result_4.xml");
Assert.equal(expected, result);
encoder.setNode(doc.documentElement.childNodes[11].childNodes[1]);
result = encoder.encodeToString();
expected = loadContentFile("4_result_4.xml");
Assert.equal(expected, result);
encoder.setCharset("UTF-8");
// it doesn't support this flags
encoder.init(doc, "text/xml", de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap);
encoder.setWrapColumn(40);
result = encoder.encodeToString();
expected = loadContentFile("4_result_5.xml");
Assert.equal(expected, result);
encoder.setCharset("UTF-8");
// it doesn't support this flags
encoder.init(
doc,
"text/xml",
de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap
);
encoder.setWrapColumn(40);
result = encoder.encodeToString();
expected = loadContentFile("4_result_5.xml");
Assert.equal(expected, result);
encoder.init(doc, "text/xml", de.OutputLFLineBreak | de.OutputWrap);
encoder.setWrapColumn(40);
result = encoder.encodeToString();
expected = loadContentFile("4_result_6.xml");
Assert.equal(expected, result);
encoder.init(doc, "text/xml", de.OutputLFLineBreak | de.OutputWrap);
encoder.setWrapColumn(40);
result = encoder.encodeToString();
expected = loadContentFile("4_result_6.xml");
Assert.equal(expected, result);
});

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

@ -1,4 +1,3 @@
function run_test()
{
function run_test() {
run_test_in_child("../unit/test_bug553888.js");
}
}

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

@ -1,20 +1,34 @@
function scaleRatio(scale) {
return {
"set": [
[ "layout.css.devPixelsPerPx", "" + scale ],
[ "apz.allow_zooming", true ],
[ "dom.meta-viewport.enabled", true ],
]
set: [
["layout.css.devPixelsPerPx", "" + scale],
["apz.allow_zooming", true],
["dom.meta-viewport.enabled", true],
],
};
}
function getViewportInfo(aDisplayWidth, aDisplayHeight) {
let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {},
width = {}, height = {}, autoSize = {};
let defaultZoom = {},
allowZoom = {},
minZoom = {},
maxZoom = {},
width = {},
height = {},
autoSize = {};
let cwu = SpecialPowers.getDOMWindowUtils(window);
cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom,
minZoom, maxZoom, width, height, autoSize);
cwu.getViewportInfo(
aDisplayWidth,
aDisplayHeight,
defaultZoom,
allowZoom,
minZoom,
maxZoom,
width,
height,
autoSize
);
return {
defaultZoom: defaultZoom.value,
minZoom: minZoom.value,
@ -22,6 +36,6 @@ function getViewportInfo(aDisplayWidth, aDisplayHeight) {
width: width.value,
height: height.value,
autoSize: autoSize.value,
allowZoom: allowZoom.value
allowZoom: allowZoom.value,
};
}

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

@ -1,33 +1,33 @@
function test_workers() {
onmessage = function(e) {
postMessage(e.data, e.ports);
}
};
}
function test_broadcastChannel() {
var bc = new BroadcastChannel('postMessagesTest_inWorkers');
var bc = new BroadcastChannel("postMessagesTest_inWorkers");
bc.onmessage = function(e) {
postMessage(e.data);
}
};
}
function test_messagePort(port) {
port.onmessage = function(e) {
postMessage(e.data, e.ports);
}
};
}
onmessage = function(e) {
if (e.data == 'workers') {
if (e.data == "workers") {
test_workers();
postMessage('ok');
} else if (e.data == 'broadcastChannel') {
postMessage("ok");
} else if (e.data == "broadcastChannel") {
test_broadcastChannel();
postMessage('ok');
} else if (e.data == 'messagePort') {
postMessage("ok");
} else if (e.data == "messagePort") {
test_messagePort(e.ports[0]);
postMessage('ok');
postMessage("ok");
} else {
postMessage('ko');
postMessage("ko");
}
}
};

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

@ -6,17 +6,24 @@
"use strict";
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
function TestInterfaceJS(anyArg, objectArg) {}
TestInterfaceJS.prototype = {
classID: Components.ID("{2ac4e026-cf25-47d5-b067-78d553c3cad8}"),
contractID: "@mozilla.org/dom/test-interface-js;1",
QueryInterface: ChromeUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, Ci.mozITestInterfaceJS]),
QueryInterface: ChromeUtils.generateQI([
Ci.nsIDOMGlobalPropertyInitializer,
Ci.mozITestInterfaceJS,
]),
init(win) { this._win = win; },
init(win) {
this._win = win;
},
__init(anyArg, objectArg, dictionaryArg) {
this._anyAttr = undefined;
@ -26,33 +33,78 @@ TestInterfaceJS.prototype = {
this._dictionaryArg = dictionaryArg;
},
get anyArg() { return this._anyArg; },
get objectArg() { return this._objectArg; },
getDictionaryArg() { return this._dictionaryArg; },
get anyAttr() { return this._anyAttr; },
set anyAttr(val) { this._anyAttr = val; },
get objectAttr() { return this._objectAttr; },
set objectAttr(val) { this._objectAttr = val; },
getDictionaryAttr() { return this._dictionaryAttr; },
setDictionaryAttr(val) { this._dictionaryAttr = val; },
pingPongAny(any) { return any; },
pingPongObject(obj) { return obj; },
pingPongObjectOrString(objectOrString) { return objectOrString; },
pingPongDictionary(dict) { return dict; },
pingPongDictionaryOrLong(dictOrLong) { return dictOrLong.anyMember || dictOrLong; },
pingPongRecord(rec) { return JSON.stringify(rec); },
objectSequenceLength(seq) { return seq.length; },
anySequenceLength(seq) { return seq.length; },
get anyArg() {
return this._anyArg;
},
get objectArg() {
return this._objectArg;
},
getDictionaryArg() {
return this._dictionaryArg;
},
get anyAttr() {
return this._anyAttr;
},
set anyAttr(val) {
this._anyAttr = val;
},
get objectAttr() {
return this._objectAttr;
},
set objectAttr(val) {
this._objectAttr = val;
},
getDictionaryAttr() {
return this._dictionaryAttr;
},
setDictionaryAttr(val) {
this._dictionaryAttr = val;
},
pingPongAny(any) {
return any;
},
pingPongObject(obj) {
return obj;
},
pingPongObjectOrString(objectOrString) {
return objectOrString;
},
pingPongDictionary(dict) {
return dict;
},
pingPongDictionaryOrLong(dictOrLong) {
return dictOrLong.anyMember || dictOrLong;
},
pingPongRecord(rec) {
return JSON.stringify(rec);
},
objectSequenceLength(seq) {
return seq.length;
},
anySequenceLength(seq) {
return seq.length;
},
getCallerPrincipal() {
return Cu.getWebIDLCallerPrincipal().origin;
},
getCallerPrincipal() { return Cu.getWebIDLCallerPrincipal().origin; },
convertSVS(svs) {
return svs;
},
convertSVS(svs) { return svs; },
pingPongUnion(x) { return x; },
pingPongUnionContainingNull(x) { return x; },
pingPongNullableUnion(x) { return x; },
returnBadUnion(x) { return 3; },
pingPongUnion(x) {
return x;
},
pingPongUnionContainingNull(x) {
return x;
},
pingPongNullableUnion(x) {
return x;
},
returnBadUnion(x) {
return 3;
},
testSequenceOverload(arg) {},
testSequenceUnion(arg) {},
@ -62,8 +114,10 @@ TestInterfaceJS.prototype = {
},
testThrowDOMException() {
throw new this._win.DOMException("We are a DOMException",
"NotSupportedError");
throw new this._win.DOMException(
"We are a DOMException",
"NotSupportedError"
);
},
testThrowTypeError() {
@ -71,7 +125,7 @@ TestInterfaceJS.prototype = {
},
testThrowNsresult() {
throw Cr.NS_BINDING_ABORTED;
throw Cr.NS_BINDING_ABORTED;
},
testThrowNsresultFromNative(x) {
@ -99,13 +153,15 @@ TestInterfaceJS.prototype = {
},
testPromiseWithThrowingContentPromiseInit(func) {
return new this._win.Promise(func);
return new this._win.Promise(func);
},
testPromiseWithDOMExceptionThrowingPromiseInit() {
return new this._win.Promise(() => {
throw new this._win.DOMException("We are a second DOMException",
"NotFoundError");
throw new this._win.DOMException(
"We are a second DOMException",
"NotFoundError"
);
});
},
@ -121,13 +177,15 @@ TestInterfaceJS.prototype = {
testPromiseWithDOMExceptionThrowingThenFunction() {
return this._win.Promise.resolve(5).then(() => {
throw new this._win.DOMException("We are a third DOMException",
"NetworkError");
throw new this._win.DOMException(
"We are a third DOMException",
"NetworkError"
);
});
},
testPromiseWithThrowingChromeThenable() {
var thenable = {
var thenable = {
then() {
noSuchMethodExistsYo3();
},
@ -146,10 +204,12 @@ TestInterfaceJS.prototype = {
},
testPromiseWithDOMExceptionThrowingThenable() {
var thenable = {
var thenable = {
then: () => {
throw new this._win.DOMException("We are a fourth DOMException",
"TypeMismatchError");
throw new this._win.DOMException(
"We are a fourth DOMException",
"TypeMismatchError"
);
},
};
return new this._win.Promise(function(resolve) {

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

@ -5,7 +5,9 @@
"use strict";
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
function TestInterfaceJSMaplike() {}
@ -14,7 +16,9 @@ TestInterfaceJSMaplike.prototype = {
contractID: "@mozilla.org/dom/test-interface-js-maplike;1",
QueryInterface: ChromeUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer]),
init(win) { this._win = win; },
init(win) {
this._win = win;
},
__init() {},

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

@ -4,8 +4,11 @@ onconnect = function(evt) {
evt.ports[0].onmessage = function(evt1) {
var bc = new BroadcastChannel("foobar");
bc.addEventListener("message", function(event) {
bc.postMessage(event.data == "hello world from the window" ?
"hello world from the worker" : "KO");
bc.postMessage(
event.data == "hello world from the window"
? "hello world from the worker"
: "KO"
);
bc.close();
});

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

@ -10,7 +10,11 @@ onmessage = function(evt) {
var bc = new BroadcastChannel("foobar");
bc.addEventListener("message", function(event) {
bc.postMessage(event.data == "hello world from the window" ? "hello world from the worker" : "KO");
bc.postMessage(
event.data == "hello world from the window"
? "hello world from the worker"
: "KO"
);
bc.close();
});

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

@ -1,7 +1,7 @@
(new BroadcastChannel("foobar")).addEventListener("message", function(event) {
new BroadcastChannel("foobar").addEventListener("message", function(event) {
if (event.data != "READY") {
event.target.postMessage(event.data);
}
});
(new BroadcastChannel("foobar")).postMessage("READY");
new BroadcastChannel("foobar").postMessage("READY");

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

@ -1,4 +1,4 @@
(new BroadcastChannel("foobar")).onmessage = function(event) {
new BroadcastChannel("foobar").onmessage = function(event) {
event.target.postMessage(event.data);
};

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

@ -1,22 +1,31 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const URL = "http://mochi.test:8888/browser/dom/broadcastchannel/tests/blank.html";
const URL =
"http://mochi.test:8888/browser/dom/broadcastchannel/tests/blank.html";
add_task(async function() {
var win1 = OpenBrowserWindow({private: true});
var win1 = OpenBrowserWindow({ private: true });
var win1Promise = new win1.Promise(resolve => {
win1.addEventListener("load", function() {
resolve();
}, {once: true});
win1.addEventListener(
"load",
function() {
resolve();
},
{ once: true }
);
});
await win1Promise;
var win2 = OpenBrowserWindow({private: false});
var win2 = OpenBrowserWindow({ private: false });
var win2Promise = new win2.Promise(resolve => {
win2.addEventListener("load", function() {
resolve();
}, {once: true});
win2.addEventListener(
"load",
function() {
resolve();
},
{ once: true }
);
});
await win2Promise;
@ -31,14 +40,18 @@ add_task(async function() {
var p1 = ContentTask.spawn(browser1, null, function(opts) {
return new content.window.Promise(resolve => {
content.window.bc = new content.window.BroadcastChannel("foobar");
content.window.bc.onmessage = function(e) { resolve(e.data); };
content.window.bc.onmessage = function(e) {
resolve(e.data);
};
});
});
var p2 = ContentTask.spawn(browser2, null, function(opts) {
return new content.window.Promise(resolve => {
content.window.bc = new content.window.BroadcastChannel("foobar");
content.window.bc.onmessage = function(e) { resolve(e.data); };
content.window.bc.onmessage = function(e) {
resolve(e.data);
};
});
});
@ -59,10 +72,18 @@ add_task(async function() {
});
var what1 = await p1;
is(what1, "hello world from private browsing", "No messages received from the other window.");
is(
what1,
"hello world from private browsing",
"No messages received from the other window."
);
var what2 = await p2;
is(what2, "hello world from non private browsing", "No messages received from the other window.");
is(
what2,
"hello world from non private browsing",
"No messages received from the other window."
);
BrowserTestUtils.removeTab(tab1);
await BrowserTestUtils.closeWindow(win1);

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

@ -7,7 +7,7 @@
"use strict";
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
function debug(msg) {
// dump("BrowserElementChild - " + msg + "\n");
@ -22,7 +22,9 @@ function parentDocShell(docshell) {
return null;
}
let treeitem = docshell.QueryInterface(Ci.nsIDocShellTreeItem);
return treeitem.parent ? treeitem.parent.QueryInterface(Ci.nsIDocShell) : null;
return treeitem.parent
? treeitem.parent.QueryInterface(Ci.nsIDocShell)
: null;
}
function isTopBrowserElement(docShell) {
@ -44,14 +46,23 @@ if (!BrowserElementIsReady) {
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
// general content apps
if (isTopBrowserElement(docShell)) {
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js", this);
Services.scriptloader.loadSubScript(
"chrome://global/content/BrowserElementCopyPaste.js",
this
);
}
} else {
// rocketbar in system app and other in-process case (ex. B2G desktop client)
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js", this);
Services.scriptloader.loadSubScript(
"chrome://global/content/BrowserElementCopyPaste.js",
this
);
}
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js", this);
Services.scriptloader.loadSubScript(
"chrome://global/content/BrowserElementChildPreload.js",
this
);
}
function onDestroy() {
@ -73,4 +84,4 @@ if (!BrowserElementIsReady) {
debug("BE already loaded, abort");
}
sendAsyncMessage("browser-element-api:call", { "msg_name": "hello" });
sendAsyncMessage("browser-element-api:call", { msg_name: "hello" });

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

@ -14,14 +14,18 @@ debug("loaded");
var BrowserElementIsReady;
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var {BrowserElementPromptService} = ChromeUtils.import("resource://gre/modules/BrowserElementPromptService.jsm");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { BrowserElementPromptService } = ChromeUtils.import(
"resource://gre/modules/BrowserElementPromptService.jsm"
);
var kLongestReturnedString = 128;
var Timer = Components.Constructor("@mozilla.org/timer;1",
"nsITimer",
"initWithCallback");
var Timer = Components.Constructor(
"@mozilla.org/timer;1",
"nsITimer",
"initWithCallback"
);
function sendAsyncMsg(msg, data) {
// Ensure that we don't send any messages before BrowserElementChild.js
@ -31,7 +35,7 @@ function sendAsyncMsg(msg, data) {
}
if (!data) {
data = { };
data = {};
}
data.msg_name = msg;
@ -46,7 +50,7 @@ function sendSyncMsg(msg, data) {
}
if (!data) {
data = { };
data = {};
}
data.msg_name = msg;
@ -67,7 +71,11 @@ var LISTENED_EVENTS = [
{ type: "DOMLinkAdded", useCapture: true, wantsUntrusted: false },
{ type: "MozScrolledAreaChanged", useCapture: true, wantsUntrusted: false },
{ type: "MozDOMFullscreen:Request", useCapture: true, wantsUntrusted: false },
{ type: "MozDOMFullscreen:NewOrigin", useCapture: true, wantsUntrusted: false },
{
type: "MozDOMFullscreen:NewOrigin",
useCapture: true,
wantsUntrusted: false,
},
{ type: "MozDOMFullscreen:Exit", useCapture: true, wantsUntrusted: false },
{ type: "DOMMetaAdded", useCapture: true, wantsUntrusted: false },
{ type: "DOMMetaChanged", useCapture: true, wantsUntrusted: false },
@ -115,20 +123,24 @@ function BrowserElementChild() {
}
BrowserElementChild.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
QueryInterface: ChromeUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference,
]),
_init() {
debug("Starting up.");
BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
docShell.QueryInterface(Ci.nsIWebProgress)
.addProgressListener(this._progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION |
Ci.nsIWebProgress.NOTIFY_SECURITY |
Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
docShell
.QueryInterface(Ci.nsIWebProgress)
.addProgressListener(
this._progressListener,
Ci.nsIWebProgress.NOTIFY_LOCATION |
Ci.nsIWebProgress.NOTIFY_SECURITY |
Ci.nsIWebProgress.NOTIFY_STATE_WINDOW
);
let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
if (!webNavigation.sessionHistory) {
@ -139,8 +151,9 @@ BrowserElementChild.prototype = {
}
// This is necessary to get security web progress notifications.
var securityUI = Cc["@mozilla.org/secure_browser_ui;1"]
.createInstance(Ci.nsISecureBrowserUI);
var securityUI = Cc["@mozilla.org/secure_browser_ui;1"].createInstance(
Ci.nsISecureBrowserUI
);
securityUI.init(docShell);
// A cache of the menuitem dom objects keyed by the id we generate
@ -152,7 +165,12 @@ BrowserElementChild.prototype = {
this._shuttingDown = false;
LISTENED_EVENTS.forEach(event => {
addEventListener(event.type, this, event.useCapture, event.wantsUntrusted);
addEventListener(
event.type,
this,
event.useCapture,
event.wantsUntrusted
);
});
// Registers a MozAfterPaint handler for the very first paint.
@ -163,10 +181,15 @@ BrowserElementChild.prototype = {
addMessageListener("browser-element-api:call", this);
LISTENED_SYSTEM_EVENTS.forEach(event => {
Services.els.addSystemEventListener(global, event.type, this, event.useCapture);
Services.els.addSystemEventListener(
global,
event.type,
this,
event.useCapture
);
});
OBSERVED_EVENTS.forEach((aTopic) => {
OBSERVED_EVENTS.forEach(aTopic => {
Services.obs.addObserver(this, aTopic);
});
},
@ -183,20 +206,31 @@ BrowserElementChild.prototype = {
BrowserElementPromptService.unmapWindowToBrowserElementChild(content);
docShell.QueryInterface(Ci.nsIWebProgress)
.removeProgressListener(this._progressListener);
docShell
.QueryInterface(Ci.nsIWebProgress)
.removeProgressListener(this._progressListener);
LISTENED_EVENTS.forEach(event => {
removeEventListener(event.type, this, event.useCapture, event.wantsUntrusted);
removeEventListener(
event.type,
this,
event.useCapture,
event.wantsUntrusted
);
});
removeMessageListener("browser-element-api:call", this);
LISTENED_SYSTEM_EVENTS.forEach(event => {
Services.els.removeSystemEventListener(global, event.type, this, event.useCapture);
Services.els.removeSystemEventListener(
global,
event.type,
this,
event.useCapture
);
});
OBSERVED_EVENTS.forEach((aTopic) => {
OBSERVED_EVENTS.forEach(aTopic => {
Services.obs.removeObserver(this, aTopic);
});
},
@ -266,9 +300,9 @@ BrowserElementChild.prototype = {
"get-can-go-forward": this._recvCanGoForward,
"go-back": this._recvGoBack,
"go-forward": this._recvGoForward,
"reload": this._recvReload,
"stop": this._recvStop,
"zoom": this._recvZoom,
reload: this._recvReload,
stop: this._recvStop,
zoom: this._recvZoom,
"unblock-modal-prompt": this._recvStopWaiting,
"fire-ctx-callback": this._recvFireCtxCallback,
"owner-visibility-change": this._recvOwnerVisibilityChange,
@ -287,17 +321,20 @@ BrowserElementChild.prototype = {
// Ignore notifications not about our document. (Note that |content| /can/
// be null; see bug 874900.)
if (topic !== "activity-done" &&
topic !== "audio-playback" &&
topic !== "will-launch-app" &&
(!content || subject !== content.document)) {
if (
topic !== "activity-done" &&
topic !== "audio-playback" &&
topic !== "will-launch-app" &&
(!content || subject !== content.document)
) {
return;
}
if (topic == "activity-done" && docShell !== subject)
if (topic == "activity-done" && docShell !== subject) {
return;
}
switch (topic) {
case "activity-done":
sendAsyncMsg("activitydone", { success: (data == "activity-success") });
sendAsyncMsg("activitydone", { success: data == "activity-success" });
break;
case "audio-playback":
if (subject === content) {
@ -314,14 +351,20 @@ BrowserElementChild.prototype = {
}
// If this is not a content process, let's not freeze painting.
if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_CONTENT) {
if (
Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_CONTENT
) {
return;
}
docShell.contentViewer.pausePainting();
this._paintFrozenTimer && this._paintFrozenTimer.cancel();
this._paintFrozenTimer = new Timer(this, 3000, Ci.nsITimer.TYPE_ONE_SHOT);
this._paintFrozenTimer = new Timer(
this,
3000,
Ci.nsITimer.TYPE_ONE_SHOT
);
break;
}
},
@ -351,15 +394,19 @@ BrowserElementChild.prototype = {
showModalPrompt(win, args) {
let utils = win.windowUtils;
args.windowID = { outer: utils.outerWindowID,
inner: this._tryGetInnerWindowID(win) };
args.windowID = {
outer: utils.outerWindowID,
inner: this._tryGetInnerWindowID(win),
};
sendAsyncMsg("showmodalprompt", args);
let returnValue = this._waitForResult(win);
if (args.promptType == "prompt" ||
args.promptType == "confirm" ||
args.promptType == "custom-prompt") {
if (
args.promptType == "prompt" ||
args.promptType == "confirm" ||
args.promptType == "custom-prompt"
) {
return returnValue;
}
return undefined;
@ -384,8 +431,14 @@ BrowserElementChild.prototype = {
this._windowIDDict[outerWindowID] = Cu.getWeakReference(win);
debug("Entering modal state (outerWindowID=" + outerWindowID + ", " +
"innerWindowID=" + innerWindowID + ")");
debug(
"Entering modal state (outerWindowID=" +
outerWindowID +
", " +
"innerWindowID=" +
innerWindowID +
")"
);
utils.enterModalState();
@ -403,8 +456,10 @@ BrowserElementChild.prototype = {
// window navigated. Bail out when we're shutting down because otherwise
// we'll leak our window.
if (this._tryGetInnerWindowID(win) !== innerWindowID) {
debug("_waitForResult: Inner window ID changed " +
"while in nested event loop.");
debug(
"_waitForResult: Inner window ID changed " +
"while in nested event loop."
);
return true;
}
@ -419,8 +474,10 @@ BrowserElementChild.prototype = {
// If we exited the loop because the inner window changed, then bail on the
// modal prompt.
if (innerWindowID !== this._tryGetInnerWindowID(win)) {
throw Components.Exception("Modal state aborted by navigation",
Cr.NS_ERROR_NOT_AVAILABLE);
throw Components.Exception(
"Modal state aborted by navigation",
Cr.NS_ERROR_NOT_AVAILABLE
);
}
let returnValue = win.modalReturnValue;
@ -430,8 +487,14 @@ BrowserElementChild.prototype = {
utils.leaveModalState();
}
debug("Leaving modal state (outerID=" + outerWindowID + ", " +
"innerID=" + innerWindowID + ")");
debug(
"Leaving modal state (outerID=" +
outerWindowID +
", " +
"innerID=" +
innerWindowID +
")"
);
return returnValue;
},
@ -439,8 +502,15 @@ BrowserElementChild.prototype = {
let outerID = msg.json.windowID.outer;
let innerID = msg.json.windowID.inner;
let returnValue = msg.json.returnValue;
debug("recvStopWaiting(outer=" + outerID + ", inner=" + innerID +
", returnValue=" + returnValue + ")");
debug(
"recvStopWaiting(outer=" +
outerID +
", inner=" +
innerID +
", returnValue=" +
returnValue +
")"
);
if (!this._windowIDDict[outerID]) {
debug("recvStopWaiting: No record of outer window ID " + outerID);
@ -465,8 +535,10 @@ BrowserElementChild.prototype = {
},
_recvEnteredFullscreen() {
if (!this._windowUtils.handleFullscreenRequests() &&
!content.document.fullscreenElement) {
if (
!this._windowUtils.handleFullscreenRequests() &&
!content.document.fullscreenElement
) {
// If we don't actually have any pending fullscreen request
// to handle, neither we have been in fullscreen, tell the
// parent to just exit.
@ -512,8 +584,7 @@ BrowserElementChild.prototype = {
return;
}
sendAsyncMsg("opensearch", { title: e.target.title,
href: e.target.href });
sendAsyncMsg("opensearch", { title: e.target.title, href: e.target.href });
},
// Processes the "rel" field in <link> tags and forward to specific handlers.
@ -527,10 +598,10 @@ BrowserElementChild.prototype = {
}
let handlers = {
"icon": this._iconChangedHandler.bind(this),
icon: this._iconChangedHandler.bind(this),
"apple-touch-icon": this._iconChangedHandler.bind(this),
"apple-touch-icon-precomposed": this._iconChangedHandler.bind(this),
"search": this._openSearchHandler,
search: this._openSearchHandler,
};
debug("Got linkAdded: (" + e.target.href + ") " + e.target.rel);
@ -558,11 +629,10 @@ BrowserElementChild.prototype = {
return;
}
debug("Got metaChanged: (" + (name || property) + ") " +
e.target.content);
debug("Got metaChanged: (" + (name || property) + ") " + e.target.content);
let handlers = {
"viewmode": this._genericMetaHandler,
viewmode: this._genericMetaHandler,
"theme-color": this._genericMetaHandler,
"theme-group": this._genericMetaHandler,
"application-name": this._applicationNameChangedHandler,
@ -586,22 +656,26 @@ BrowserElementChild.prototype = {
return;
}
let meta = { name,
content: target.content };
let meta = { name, content: target.content };
let lang;
let elm;
for (elm = target;
!lang && elm && elm.nodeType == target.ELEMENT_NODE;
elm = elm.parentNode) {
for (
elm = target;
!lang && elm && elm.nodeType == target.ELEMENT_NODE;
elm = elm.parentNode
) {
if (elm.hasAttribute("lang")) {
lang = elm.getAttribute("lang");
continue;
}
if (elm.hasAttributeNS("http://www.w3.org/XML/1998/namespace", "lang")) {
lang = elm.getAttributeNS("http://www.w3.org/XML/1998/namespace", "lang");
lang = elm.getAttributeNS(
"http://www.w3.org/XML/1998/namespace",
"lang"
);
continue;
}
}
@ -628,22 +702,24 @@ BrowserElementChild.prototype = {
_ClickHandler(e) {
let isHTMLLink = node =>
((ChromeUtils.getClassName(node) === "HTMLAnchorElement" && node.href) ||
(ChromeUtils.getClassName(node) === "HTMLAreaElement" && node.href) ||
ChromeUtils.getClassName(node) === "HTMLLinkElement");
(ChromeUtils.getClassName(node) === "HTMLAnchorElement" && node.href) ||
(ChromeUtils.getClassName(node) === "HTMLAreaElement" && node.href) ||
ChromeUtils.getClassName(node) === "HTMLLinkElement";
// Open in a new tab if middle click or ctrl/cmd-click,
// and e.target is a link or inside a link.
if ((Services.appinfo.OS == "Darwin" && e.metaKey) ||
(Services.appinfo.OS != "Darwin" && e.ctrlKey) ||
e.button == 1) {
if (
(Services.appinfo.OS == "Darwin" && e.metaKey) ||
(Services.appinfo.OS != "Darwin" && e.ctrlKey) ||
e.button == 1
) {
let node = e.target;
while (node && !isHTMLLink(node)) {
node = node.parentNode;
}
if (node) {
sendAsyncMsg("opentab", {url: node.href});
sendAsyncMsg("opentab", { url: node.href });
}
}
},
@ -662,8 +738,11 @@ BrowserElementChild.prototype = {
let uri = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
if (uri.spec != "about:blank") {
debug("Got afterpaint event: " + uri.spec);
removeEventListener("MozAfterPaint", onMozAfterPaint,
/* useCapture = */ true);
removeEventListener(
"MozAfterPaint",
onMozAfterPaint,
/* useCapture = */ true
);
callback();
}
}
@ -725,9 +804,11 @@ BrowserElementChild.prototype = {
this._ctxHandlers = {};
var elem = e.target;
var menuData = {systemTargets: [], contextmenu: null};
var menuData = { systemTargets: [], contextmenu: null };
var ctxMenuId = null;
var clipboardPlainTextOnly = Services.prefs.getBoolPref("clipboard.plainTextOnly");
var clipboardPlainTextOnly = Services.prefs.getBoolPref(
"clipboard.plainTextOnly"
);
var copyableElements = {
image: false,
link: false,
@ -738,7 +819,9 @@ BrowserElementChild.prototype = {
// Set the event target as the copy image command needs it to
// determine what was context-clicked on.
docShell.contentViewer.QueryInterface(Ci.nsIContentViewerEdit).setCommandNode(elem);
docShell.contentViewer
.QueryInterface(Ci.nsIContentViewerEdit)
.setCommandNode(elem);
while (elem && elem.parentNode) {
var ctxData = this._getSystemCtxMenuData(elem);
@ -749,7 +832,11 @@ BrowserElementChild.prototype = {
});
}
if (!ctxMenuId && "hasAttribute" in elem && elem.hasAttribute("contextmenu")) {
if (
!ctxMenuId &&
"hasAttribute" in elem &&
elem.hasAttribute("contextmenu")
) {
ctxMenuId = elem.getAttribute("contextmenu");
}
@ -791,42 +878,54 @@ BrowserElementChild.prototype = {
},
_getSystemCtxMenuData(elem) {
let documentURI =
docShell.QueryInterface(Ci.nsIWebNavigation).currentURI.spec;
let documentURI = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI
.spec;
if ((ChromeUtils.getClassName(elem) === "HTMLAnchorElement" && elem.href) ||
(ChromeUtils.getClassName(elem) === "HTMLAreaElement" && elem.href)) {
return {uri: elem.href,
documentURI,
text: elem.textContent.substring(0, kLongestReturnedString)};
if (
(ChromeUtils.getClassName(elem) === "HTMLAnchorElement" && elem.href) ||
(ChromeUtils.getClassName(elem) === "HTMLAreaElement" && elem.href)
) {
return {
uri: elem.href,
documentURI,
text: elem.textContent.substring(0, kLongestReturnedString),
};
}
if (elem instanceof Ci.nsIImageLoadingContent &&
(elem.currentRequestFinalURI || elem.currentURI)) {
if (
elem instanceof Ci.nsIImageLoadingContent &&
(elem.currentRequestFinalURI || elem.currentURI)
) {
let uri = elem.currentRequestFinalURI || elem.currentURI;
return {uri: uri.spec, documentURI};
return { uri: uri.spec, documentURI };
}
if (ChromeUtils.getClassName(elem) === "HTMLImageElement") {
return {uri: elem.src, documentURI};
return { uri: elem.src, documentURI };
}
if (ChromeUtils.getClassName(elem) === "HTMLVideoElement" ||
ChromeUtils.getClassName(elem) === "HTMLAudioElement") {
let hasVideo = !(elem.readyState >= elem.HAVE_METADATA &&
(elem.videoWidth == 0 || elem.videoHeight == 0));
return {uri: elem.currentSrc || elem.src,
hasVideo,
documentURI};
if (
ChromeUtils.getClassName(elem) === "HTMLVideoElement" ||
ChromeUtils.getClassName(elem) === "HTMLAudioElement"
) {
let hasVideo = !(
elem.readyState >= elem.HAVE_METADATA &&
(elem.videoWidth == 0 || elem.videoHeight == 0)
);
return { uri: elem.currentSrc || elem.src, hasVideo, documentURI };
}
if (ChromeUtils.getClassName(elem) === "HTMLInputElement" &&
elem.hasAttribute("name")) {
if (
ChromeUtils.getClassName(elem) === "HTMLInputElement" &&
elem.hasAttribute("name")
) {
// For input elements, we look for a parent <form> and if there is
// one we return the form's method and action uri.
let parent = elem.parentNode;
while (parent) {
if (ChromeUtils.getClassName(parent) === "HTMLFormElement" &&
parent.hasAttribute("action")) {
let actionHref = docShell.QueryInterface(Ci.nsIWebNavigation)
.currentURI
.resolve(parent.getAttribute("action"));
if (
ChromeUtils.getClassName(parent) === "HTMLFormElement" &&
parent.hasAttribute("action")
) {
let actionHref = docShell
.QueryInterface(Ci.nsIWebNavigation)
.currentURI.resolve(parent.getAttribute("action"));
let method = parent.hasAttribute("method")
? parent.getAttribute("method").toLowerCase()
: "get";
@ -877,7 +976,7 @@ BrowserElementChild.prototype = {
_recvFireCtxCallback(data) {
debug("Received fireCtxCallback message: (" + data.json.menuitem + ")");
let doCommandIfEnabled = (command) => {
let doCommandIfEnabled = command => {
if (docShell.isCommandEnabled(command)) {
docShell.doCommand(command);
}
@ -897,17 +996,19 @@ BrowserElementChild.prototype = {
},
_buildMenuObj(menu, idPrefix, copyableElements) {
var menuObj = {type: "menu", customized: false, items: []};
var menuObj = { type: "menu", customized: false, items: [] };
// Customized context menu
if (menu) {
this._maybeCopyAttribute(menu, menuObj, "label");
for (var i = 0, child; (child = menu.children[i++]);) {
for (var i = 0, child; (child = menu.children[i++]); ) {
if (child.nodeName === "MENU") {
menuObj.items.push(this._buildMenuObj(child, idPrefix + i + "_", false));
menuObj.items.push(
this._buildMenuObj(child, idPrefix + i + "_", false)
);
} else if (child.nodeName === "MENUITEM") {
var id = this._ctxCounter + "_" + idPrefix + i;
var menuitem = {id, type: "menuitem"};
var menuitem = { id, type: "menuitem" };
this._maybeCopyAttribute(child, menuitem, "label");
this._maybeCopyAttribute(child, menuitem, "icon");
this._ctxHandlers[id] = child;
@ -923,11 +1024,11 @@ BrowserElementChild.prototype = {
// put together with other image options if elem is an image link.
// "Copy Link" menu item
if (copyableElements.link) {
menuObj.items.push({id: "copy-link"});
menuObj.items.push({ id: "copy-link" });
}
// "Copy Image" menu item
if (copyableElements.image) {
menuObj.items.push({id: "copy-image"});
menuObj.items.push({ id: "copy-image" });
}
return menuObj;
@ -953,8 +1054,14 @@ BrowserElementChild.prototype = {
_recvSendMouseEvent(data) {
let json = data.json;
let utils = content.windowUtils;
utils.sendMouseEventToWindow(json.type, json.x, json.y, json.button,
json.clickCount, json.modifiers);
utils.sendMouseEventToWindow(
json.type,
json.x,
json.y,
json.button,
json.clickCount,
json.modifiers
);
},
_recvCanGoBack(data) {
@ -991,9 +1098,9 @@ BrowserElementChild.prototype = {
_recvReload(data) {
let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
let reloadFlags = data.json.hardReload ?
webNav.LOAD_FLAGS_BYPASS_PROXY | webNav.LOAD_FLAGS_BYPASS_CACHE :
webNav.LOAD_FLAGS_NONE;
let reloadFlags = data.json.hardReload
? webNav.LOAD_FLAGS_BYPASS_PROXY | webNav.LOAD_FLAGS_BYPASS_CACHE
: webNav.LOAD_FLAGS_NONE;
try {
webNav.reload(reloadFlags);
} catch (e) {
@ -1009,8 +1116,10 @@ BrowserElementChild.prototype = {
// The docShell keeps a weak reference to the progress listener, so we need
// to keep a strong ref to it ourselves.
_progressListener: {
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
QueryInterface: ChromeUtils.generateQI([
Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference,
]),
_seenLoadStart: false,
onLocationChange(webProgress, request, location, flags) {
@ -1030,9 +1139,11 @@ BrowserElementChild.prototype = {
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
sendAsyncMsg("locationchange", { url: location.spec,
canGoBack: webNav.canGoBack,
canGoForward: webNav.canGoForward });
sendAsyncMsg("locationchange", {
url: location.spec,
canGoBack: webNav.canGoBack,
canGoForward: webNav.canGoForward,
});
},
// eslint-disable-next-line complexity
@ -1049,102 +1160,103 @@ BrowserElementChild.prototype = {
if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
let bgColor = "transparent";
try {
bgColor = content.getComputedStyle(content.document.body)
.getPropertyValue("background-color");
bgColor = content
.getComputedStyle(content.document.body)
.getPropertyValue("background-color");
} catch (e) {}
sendAsyncMsg("loadend", {backgroundColor: bgColor});
sendAsyncMsg("loadend", { backgroundColor: bgColor });
switch (status) {
case Cr.NS_OK :
case Cr.NS_BINDING_ABORTED :
// Ignoring NS_BINDING_ABORTED, which is set when loading page is
// stopped.
case Cr.NS_OK:
case Cr.NS_BINDING_ABORTED:
// Ignoring NS_BINDING_ABORTED, which is set when loading page is
// stopped.
case Cr.NS_ERROR_PARSED_DATA_CACHED:
return;
// TODO See nsDocShell::DisplayLoadError to see what extra
// information we should be annotating this first block of errors
// with. Bug 1107091.
case Cr.NS_ERROR_UNKNOWN_PROTOCOL :
case Cr.NS_ERROR_UNKNOWN_PROTOCOL:
sendAsyncMsg("error", { type: "unknownProtocolFound" });
return;
case Cr.NS_ERROR_FILE_NOT_FOUND :
case Cr.NS_ERROR_FILE_NOT_FOUND:
sendAsyncMsg("error", { type: "fileNotFound" });
return;
case Cr.NS_ERROR_UNKNOWN_HOST :
case Cr.NS_ERROR_UNKNOWN_HOST:
sendAsyncMsg("error", { type: "dnsNotFound" });
return;
case Cr.NS_ERROR_CONNECTION_REFUSED :
case Cr.NS_ERROR_CONNECTION_REFUSED:
sendAsyncMsg("error", { type: "connectionFailure" });
return;
case Cr.NS_ERROR_NET_INTERRUPT :
case Cr.NS_ERROR_NET_INTERRUPT:
sendAsyncMsg("error", { type: "netInterrupt" });
return;
case Cr.NS_ERROR_NET_TIMEOUT :
case Cr.NS_ERROR_NET_TIMEOUT:
sendAsyncMsg("error", { type: "netTimeout" });
return;
case Cr.NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION :
case Cr.NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION:
sendAsyncMsg("error", { type: "cspBlocked" });
return;
case Cr.NS_ERROR_PHISHING_URI :
case Cr.NS_ERROR_PHISHING_URI:
sendAsyncMsg("error", { type: "deceptiveBlocked" });
return;
case Cr.NS_ERROR_MALWARE_URI :
case Cr.NS_ERROR_MALWARE_URI:
sendAsyncMsg("error", { type: "malwareBlocked" });
return;
case Cr.NS_ERROR_HARMFUL_URI :
case Cr.NS_ERROR_HARMFUL_URI:
sendAsyncMsg("error", { type: "harmfulBlocked" });
return;
case Cr.NS_ERROR_UNWANTED_URI :
case Cr.NS_ERROR_UNWANTED_URI:
sendAsyncMsg("error", { type: "unwantedBlocked" });
return;
case Cr.NS_ERROR_FORBIDDEN_URI :
case Cr.NS_ERROR_FORBIDDEN_URI:
sendAsyncMsg("error", { type: "forbiddenBlocked" });
return;
case Cr.NS_ERROR_OFFLINE :
case Cr.NS_ERROR_OFFLINE:
sendAsyncMsg("error", { type: "offline" });
return;
case Cr.NS_ERROR_MALFORMED_URI :
case Cr.NS_ERROR_MALFORMED_URI:
sendAsyncMsg("error", { type: "malformedURI" });
return;
case Cr.NS_ERROR_REDIRECT_LOOP :
case Cr.NS_ERROR_REDIRECT_LOOP:
sendAsyncMsg("error", { type: "redirectLoop" });
return;
case Cr.NS_ERROR_UNKNOWN_SOCKET_TYPE :
case Cr.NS_ERROR_UNKNOWN_SOCKET_TYPE:
sendAsyncMsg("error", { type: "unknownSocketType" });
return;
case Cr.NS_ERROR_NET_RESET :
case Cr.NS_ERROR_NET_RESET:
sendAsyncMsg("error", { type: "netReset" });
return;
case Cr.NS_ERROR_DOCUMENT_NOT_CACHED :
case Cr.NS_ERROR_DOCUMENT_NOT_CACHED:
sendAsyncMsg("error", { type: "notCached" });
return;
case Cr.NS_ERROR_DOCUMENT_IS_PRINTMODE :
case Cr.NS_ERROR_DOCUMENT_IS_PRINTMODE:
sendAsyncMsg("error", { type: "isprinting" });
return;
case Cr.NS_ERROR_PORT_ACCESS_NOT_ALLOWED :
case Cr.NS_ERROR_PORT_ACCESS_NOT_ALLOWED:
sendAsyncMsg("error", { type: "deniedPortAccess" });
return;
case Cr.NS_ERROR_UNKNOWN_PROXY_HOST :
case Cr.NS_ERROR_UNKNOWN_PROXY_HOST:
sendAsyncMsg("error", { type: "proxyResolveFailure" });
return;
case Cr.NS_ERROR_PROXY_CONNECTION_REFUSED :
case Cr.NS_ERROR_PROXY_CONNECTION_REFUSED:
sendAsyncMsg("error", { type: "proxyConnectFailure" });
return;
case Cr.NS_ERROR_INVALID_CONTENT_ENCODING :
case Cr.NS_ERROR_INVALID_CONTENT_ENCODING:
sendAsyncMsg("error", { type: "contentEncodingFailure" });
return;
case Cr.NS_ERROR_REMOTE_XUL :
case Cr.NS_ERROR_REMOTE_XUL:
sendAsyncMsg("error", { type: "remoteXUL" });
return;
case Cr.NS_ERROR_UNSAFE_CONTENT_TYPE :
case Cr.NS_ERROR_UNSAFE_CONTENT_TYPE:
sendAsyncMsg("error", { type: "unsafeContentType" });
return;
case Cr.NS_ERROR_CORRUPTED_CONTENT :
case Cr.NS_ERROR_CORRUPTED_CONTENT:
sendAsyncMsg("error", { type: "corruptedContentErrorv2" });
return;
case Cr.NS_ERROR_BLOCKED_BY_POLICY :
case Cr.NS_ERROR_BLOCKED_BY_POLICY:
sendAsyncMsg("error", { type: "blockedByPolicy" });
return;
@ -1152,15 +1264,21 @@ BrowserElementChild.prototype = {
// getErrorClass() will throw if the error code passed in is not a NSS
// error code.
try {
let nssErrorsService = Cc["@mozilla.org/nss_errors_service;1"]
.getService(Ci.nsINSSErrorsService);
if (nssErrorsService.getErrorClass(status)
== Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT) {
let nssErrorsService = Cc[
"@mozilla.org/nss_errors_service;1"
].getService(Ci.nsINSSErrorsService);
if (
nssErrorsService.getErrorClass(status) ==
Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT
) {
// XXX Is there a point firing the event if the error page is not
// certerror? If yes, maybe we should add a property to the
// event to to indicate whether there is a custom page. That would
// let the embedder have more control over the desired behavior.
let errorPage = Services.prefs.getCharPref(CERTIFICATE_ERROR_PAGE_PREF, "");
let errorPage = Services.prefs.getCharPref(
CERTIFICATE_ERROR_PAGE_PREF,
""
);
if (errorPage == "certerror") {
sendAsyncMsg("error", { type: "certerror" });
@ -1192,17 +1310,25 @@ BrowserElementChild.prototype = {
}
var mixedStateDesc;
if (state & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
if (
state & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT
) {
mixedStateDesc = "blocked_mixed_active_content";
} else if (state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT) {
} else if (
state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT
) {
// Note that STATE_LOADED_MIXED_ACTIVE_CONTENT implies STATE_IS_BROKEN
mixedStateDesc = "loaded_mixed_active_content";
}
var isEV = !!(state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL);
var isMixedContent = !!(state &
var isEV = !!(
state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL
);
var isMixedContent = !!(
state &
(Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT |
Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT));
Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT)
);
sendAsyncMsg("securitychange", {
state: securityStateDesc,
@ -1227,7 +1353,10 @@ BrowserElementChild.prototype = {
};
var api = null;
if ("DoPreloadPostfork" in this && typeof this.DoPreloadPostfork === "function") {
if (
"DoPreloadPostfork" in this &&
typeof this.DoPreloadPostfork === "function"
) {
// If we are preloaded, instantiate BrowserElementChild after a content
// process is forked.
this.DoPreloadPostfork(function() {

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

@ -22,21 +22,29 @@ debug("loaded");
var CopyPasteAssistent = {
COMMAND_MAP: {
"cut": "cmd_cut",
"copy": "cmd_copy",
"paste": "cmd_paste",
"selectall": "cmd_selectAll",
cut: "cmd_cut",
copy: "cmd_copy",
paste: "cmd_paste",
selectall: "cmd_selectAll",
},
init() {
addEventListener("mozcaretstatechanged", this,
/* useCapture = */ true, /* wantsUntrusted = */ false);
addEventListener(
"mozcaretstatechanged",
this,
/* useCapture = */ true,
/* wantsUntrusted = */ false
);
addMessageListener("browser-element-api:call", this);
},
destroy() {
removeEventListener("mozcaretstatechanged", this,
/* useCapture = */ true, /* wantsUntrusted = */ false);
removeEventListener(
"mozcaretstatechanged",
this,
/* useCapture = */ true,
/* wantsUntrusted = */ false
);
removeMessageListener("browser-element-api:call", this);
},
@ -80,7 +88,8 @@ var CopyPasteAssistent = {
let boundingClientRect = e.boundingClientRect;
this._isCommandEnabled("paste");
let zoomFactor = content.innerWidth == 0 ? 1 : content.screen.width / content.innerWidth;
let zoomFactor =
content.innerWidth == 0 ? 1 : content.screen.width / content.innerWidth;
let detail = {
rect: {

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

@ -9,8 +9,10 @@
* appropriate action here in the parent.
*/
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {BrowserElementPromptService} = ChromeUtils.import("resource://gre/modules/BrowserElementPromptService.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { BrowserElementPromptService } = ChromeUtils.import(
"resource://gre/modules/BrowserElementPromptService.jsm"
);
function debug(msg) {
// dump("BrowserElementParent - " + msg + "\n");
@ -18,7 +20,9 @@ function debug(msg) {
function handleWindowEvent(e) {
if (this._browserElementParents) {
let beps = ChromeUtils.nondeterministicGetWeakMapKeys(this._browserElementParents);
let beps = ChromeUtils.nondeterministicGetWeakMapKeys(
this._browserElementParents
);
beps.forEach(bep => bep._handleOwnerEvent(e));
}
}
@ -51,19 +55,28 @@ function BrowserElementParent() {
this._pendingPromises = {};
this._pendingDOMFullscreen = false;
Services.obs.addObserver(this, "oop-frameloader-crashed", /* ownsWeak = */ true);
Services.obs.addObserver(this, "ask-children-to-execute-copypaste-command", /* ownsWeak = */ true);
Services.obs.addObserver(
this,
"oop-frameloader-crashed",
/* ownsWeak = */ true
);
Services.obs.addObserver(
this,
"ask-children-to-execute-copypaste-command",
/* ownsWeak = */ true
);
Services.obs.addObserver(this, "back-docommand", /* ownsWeak = */ true);
}
BrowserElementParent.prototype = {
classDescription: "BrowserElementAPI implementation",
classID: Components.ID("{9f171ac4-0939-4ef8-b360-3408aedc3060}"),
contractID: "@mozilla.org/dom/browser-element-api;1",
QueryInterface: ChromeUtils.generateQI([Ci.nsIBrowserElementAPI,
Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
QueryInterface: ChromeUtils.generateQI([
Ci.nsIBrowserElementAPI,
Ci.nsIObserver,
Ci.nsISupportsWeakReference,
]),
setFrameLoader(frameLoader) {
debug("Setting frameLoader");
@ -88,15 +101,22 @@ BrowserElementParent.prototype = {
let handler = handleWindowEvent.bind(this._window);
let windowEvents = ["visibilitychange", "fullscreenchange"];
for (let event of windowEvents) {
Services.els.addSystemEventListener(this._window, event, handler,
/* useCapture = */ true);
Services.els.addSystemEventListener(
this._window,
event,
handler,
/* useCapture = */ true
);
}
}
this._window._browserElementParents.set(this, null);
// Insert ourself into the prompt service.
BrowserElementPromptService.mapFrameToBrowserElementParent(this._frameElement, this);
BrowserElementPromptService.mapFrameToBrowserElementParent(
this._frameElement,
this
);
this._setupMessageListener();
},
@ -135,43 +155,46 @@ BrowserElementParent.prototype = {
// We use a single message and dispatch to various function based
// on data.msg_name
let mmCalls = {
"hello": this._recvHello,
"loadstart": this._fireProfiledEventFromMsg,
"loadend": this._fireProfiledEventFromMsg,
"close": this._fireEventFromMsg,
"error": this._fireEventFromMsg,
"firstpaint": this._fireProfiledEventFromMsg,
"documentfirstpaint": this._fireProfiledEventFromMsg,
hello: this._recvHello,
loadstart: this._fireProfiledEventFromMsg,
loadend: this._fireProfiledEventFromMsg,
close: this._fireEventFromMsg,
error: this._fireEventFromMsg,
firstpaint: this._fireProfiledEventFromMsg,
documentfirstpaint: this._fireProfiledEventFromMsg,
"got-can-go-back": this._gotAsyncResult,
"got-can-go-forward": this._gotAsyncResult,
"requested-dom-fullscreen": this._requestedDOMFullscreen,
"fullscreen-origin-change": this._fullscreenOriginChange,
"exit-dom-fullscreen": this._exitDomFullscreen,
"scrollviewchange": this._handleScrollViewChange,
"caretstatechanged": this._handleCaretStateChanged,
scrollviewchange: this._handleScrollViewChange,
caretstatechanged: this._handleCaretStateChanged,
};
let mmSecuritySensitiveCalls = {
"audioplaybackchange": this._fireEventFromMsg,
"showmodalprompt": this._handleShowModalPrompt,
"contextmenu": this._fireCtxMenuEvent,
"securitychange": this._fireEventFromMsg,
"locationchange": this._fireEventFromMsg,
"iconchange": this._fireEventFromMsg,
"scrollareachanged": this._fireEventFromMsg,
"titlechange": this._fireProfiledEventFromMsg,
"opensearch": this._fireEventFromMsg,
"metachange": this._fireEventFromMsg,
"resize": this._fireEventFromMsg,
"activitydone": this._fireEventFromMsg,
"scroll": this._fireEventFromMsg,
"opentab": this._fireEventFromMsg,
audioplaybackchange: this._fireEventFromMsg,
showmodalprompt: this._handleShowModalPrompt,
contextmenu: this._fireCtxMenuEvent,
securitychange: this._fireEventFromMsg,
locationchange: this._fireEventFromMsg,
iconchange: this._fireEventFromMsg,
scrollareachanged: this._fireEventFromMsg,
titlechange: this._fireProfiledEventFromMsg,
opensearch: this._fireEventFromMsg,
metachange: this._fireEventFromMsg,
resize: this._fireEventFromMsg,
activitydone: this._fireEventFromMsg,
scroll: this._fireEventFromMsg,
opentab: this._fireEventFromMsg,
};
if (aMsg.data.msg_name in mmCalls) {
return mmCalls[aMsg.data.msg_name].apply(this, arguments);
} else if (aMsg.data.msg_name in mmSecuritySensitiveCalls) {
return mmSecuritySensitiveCalls[aMsg.data.msg_name].apply(this, arguments);
return mmSecuritySensitiveCalls[aMsg.data.msg_name].apply(
this,
arguments
);
}
return undefined;
},
@ -185,9 +208,11 @@ BrowserElementParent.prototype = {
* false. (You'll likely get an exception if you do.)
*/
_isAlive() {
return !Cu.isDeadWrapper(this._frameElement) &&
!Cu.isDeadWrapper(this._frameElement.ownerDocument) &&
!Cu.isDeadWrapper(this._frameElement.ownerGlobal);
return (
!Cu.isDeadWrapper(this._frameElement) &&
!Cu.isDeadWrapper(this._frameElement.ownerDocument) &&
!Cu.isDeadWrapper(this._frameElement.ownerGlobal)
);
},
get _window() {
@ -216,20 +241,28 @@ BrowserElementParent.prototype = {
/* username and password */
let detail = {
host: authDetail.host,
path: authDetail.path,
realm: authDetail.realm,
isProxy: authDetail.isProxy,
host: authDetail.host,
path: authDetail.path,
realm: authDetail.realm,
isProxy: authDetail.isProxy,
};
evt = this._createEvent("usernameandpasswordrequired", detail,
/* cancelable */ true);
Cu.exportFunction(function(username, password) {
if (callbackCalled)
return;
callbackCalled = true;
callback(true, username, password);
}, evt.detail, { defineAs: "authenticate" });
evt = this._createEvent(
"usernameandpasswordrequired",
detail,
/* cancelable */ true
);
Cu.exportFunction(
function(username, password) {
if (callbackCalled) {
return;
}
callbackCalled = true;
callback(true, username, password);
},
evt.detail,
{ defineAs: "authenticate" }
);
Cu.exportFunction(cancelCallback, evt.detail, { defineAs: "cancel" });
@ -243,7 +276,7 @@ BrowserElementParent.prototype = {
_sendAsyncMsg(msg, data) {
try {
if (!data) {
data = { };
data = {};
}
data.msg_name = msg;
@ -282,9 +315,13 @@ BrowserElementParent.prototype = {
if (detail.contextmenu) {
var self = this;
Cu.exportFunction(function(id) {
self._sendAsyncMsg("fire-ctx-callback", {menuitem: id});
}, evt.detail, { defineAs: "contextMenuItemSelected" });
Cu.exportFunction(
function(id) {
self._sendAsyncMsg("fire-ctx-callback", { menuitem: id });
},
evt.detail,
{ defineAs: "contextMenuItemSelected" }
);
}
// The embedder may have default actions on context menu events, so
@ -318,8 +355,7 @@ BrowserElementParent.prototype = {
}
debug("fireEventFromMsg: " + name + ", " + JSON.stringify(detail));
let evt = this._createEvent(name, detail,
/* cancelable = */ false);
let evt = this._createEvent(name, detail, /* cancelable = */ false);
this._frameElement.dispatchEvent(evt);
},
@ -343,8 +379,11 @@ BrowserElementParent.prototype = {
let windowID = detail.windowID;
delete detail.windowID;
debug("Event will have detail: " + JSON.stringify(detail));
let evt = this._createEvent("showmodalprompt", detail,
/* cancelable = */ true);
let evt = this._createEvent(
"showmodalprompt",
detail,
/* cancelable = */ true
);
let self = this;
let unblockMsgSent = false;
@ -357,8 +396,7 @@ BrowserElementParent.prototype = {
// We don't need to sanitize evt.detail.returnValue (e.g. converting the
// return value of confirm() to a boolean); Gecko does that for us.
let data = { windowID,
returnValue: evt.detail.returnValue };
let data = { windowID, returnValue: evt.detail.returnValue };
self._sendAsyncMsg("unblock-modal-prompt", data);
}
@ -391,22 +429,30 @@ BrowserElementParent.prototype = {
// - selectedTextContent: Contains current selected text content, which is
// equivalent to the string returned by Selection.toString().
_handleCaretStateChanged(data) {
let evt = this._createEvent("caretstatechanged", data.json,
/* cancelable = */ false);
let evt = this._createEvent(
"caretstatechanged",
data.json,
/* cancelable = */ false
);
let self = this;
function sendDoCommandMsg(cmd) {
let data = { command: cmd };
self._sendAsyncMsg("copypaste-do-command", data);
}
Cu.exportFunction(sendDoCommandMsg, evt.detail, { defineAs: "sendDoCommandMsg" });
Cu.exportFunction(sendDoCommandMsg, evt.detail, {
defineAs: "sendDoCommandMsg",
});
this._frameElement.dispatchEvent(evt);
},
_handleScrollViewChange(data) {
let evt = this._createEvent("scrollviewchange", data.json,
/* cancelable = */ false);
let evt = this._createEvent(
"scrollviewchange",
data.json,
/* cancelable = */ false
);
this._frameElement.dispatchEvent(evt);
},
@ -415,15 +461,17 @@ BrowserElementParent.prototype = {
// detail. For now, it's OK.
if (detail !== undefined && detail !== null) {
detail = Cu.cloneInto(detail, this._window);
return new this._window.CustomEvent("mozbrowser" + evtName,
{ bubbles: true,
cancelable,
detail });
return new this._window.CustomEvent("mozbrowser" + evtName, {
bubbles: true,
cancelable,
detail,
});
}
return new this._window.Event("mozbrowser" + evtName,
{ bubbles: true,
cancelable });
return new this._window.Event("mozbrowser" + evtName, {
bubbles: true,
cancelable,
});
},
/**
@ -450,7 +498,7 @@ BrowserElementParent.prototype = {
if (!self._isAlive()) {
return;
}
if (self._sendAsyncMsg(msgName, {id, args})) {
if (self._sendAsyncMsg(msgName, { id, args })) {
self._pendingPromises[id] = { p, resolve, reject };
} else {
reject(new this._window.DOMException("fail"));
@ -488,23 +536,33 @@ BrowserElementParent.prototype = {
p.resolve(clientObj);
} else {
debug("Got error in gotAsyncResult.");
p.reject(new this._window.DOMException(
Cu.cloneInto(data.json.errorMsg, this._window)));
p.reject(
new this._window.DOMException(
Cu.cloneInto(data.json.errorMsg, this._window)
)
);
}
},
sendMouseEvent: defineNoReturnMethod(function(type, x, y, button, clickCount, modifiers) {
sendMouseEvent: defineNoReturnMethod(function(
type,
x,
y,
button,
clickCount,
modifiers
) {
// This method used to attempt to transform from the parent
// coordinate space to the child coordinate space, but the
// transform was always a no-op, because this._frameLoader.remoteTab
// was null.
this._sendAsyncMsg("send-mouse-event", {
"type": type,
"x": x,
"y": y,
"button": button,
"clickCount": clickCount,
"modifiers": modifiers,
type,
x,
y,
button,
clickCount,
modifiers,
});
}),
@ -520,7 +578,7 @@ BrowserElementParent.prototype = {
}),
reload: defineNoReturnMethod(function(hardReload) {
this._sendAsyncMsg("reload", {hardReload});
this._sendAsyncMsg("reload", { hardReload });
}),
stop: defineNoReturnMethod(function() {
@ -531,8 +589,9 @@ BrowserElementParent.prototype = {
* Called when the visibility of the window which owns this iframe changes.
*/
_ownerVisibilityChange() {
this._sendAsyncMsg("owner-visibility-change",
{visible: !this._window.document.hidden});
this._sendAsyncMsg("owner-visibility-change", {
visible: !this._window.document.hidden,
});
},
_requestedDOMFullscreen() {
@ -542,7 +601,10 @@ BrowserElementParent.prototype = {
_fullscreenOriginChange(data) {
Services.obs.notifyObservers(
this._frameElement, "fullscreen-origin-change", data.json.originNoSuffix);
this._frameElement,
"fullscreen-origin-change",
data.json.originNoSuffix
);
},
_exitDomFullscreen(data) {
@ -566,31 +628,34 @@ BrowserElementParent.prototype = {
},
_fireFatalError() {
let evt = this._createEvent("error", {type: "fatal"},
/* cancelable = */ false);
let evt = this._createEvent(
"error",
{ type: "fatal" },
/* cancelable = */ false
);
this._frameElement.dispatchEvent(evt);
},
observe(subject, topic, data) {
switch (topic) {
case "oop-frameloader-crashed":
if (this._isAlive() && subject == this._frameLoader) {
this._fireFatalError();
}
break;
case "ask-children-to-execute-copypaste-command":
if (this._isAlive() && this._frameElement == subject.wrappedJSObject) {
this._sendAsyncMsg("copypaste-do-command", { command: data });
}
break;
case "back-docommand":
if (this._isAlive() && this._frameLoader.visible) {
case "oop-frameloader-crashed":
if (this._isAlive() && subject == this._frameLoader) {
this._fireFatalError();
}
break;
case "ask-children-to-execute-copypaste-command":
if (this._isAlive() && this._frameElement == subject.wrappedJSObject) {
this._sendAsyncMsg("copypaste-do-command", { command: data });
}
break;
case "back-docommand":
if (this._isAlive() && this._frameLoader.visible) {
this.goBack();
}
break;
default:
debug("Unknown topic: " + topic);
break;
}
break;
default:
debug("Unknown topic: " + topic);
break;
}
},
};

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

@ -9,7 +9,7 @@ var Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
var EXPORTED_SYMBOLS = ["BrowserElementPromptService"];
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
const BROWSER_FRAMES_ENABLED_PREF = "dom.mozBrowserFramesEnabled";
@ -27,8 +27,12 @@ BrowserElementPrompt.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrompt]),
alert(title, text) {
this._browserElementChild.showModalPrompt(
this._win, {promptType: "alert", title, message: text, returnValue: undefined});
this._browserElementChild.showModalPrompt(this._win, {
promptType: "alert",
title,
message: text,
returnValue: undefined,
});
},
alertCheck(title, text, checkMsg, checkState) {
@ -38,8 +42,12 @@ BrowserElementPrompt.prototype = {
},
confirm(title, text) {
return this._browserElementChild.showModalPrompt(
this._win, {promptType: "confirm", title, message: text, returnValue: undefined});
return this._browserElementChild.showModalPrompt(this._win, {
promptType: "confirm",
title,
message: text,
returnValue: undefined,
});
},
confirmCheck(title, text, checkMsg, checkState) {
@ -58,30 +66,37 @@ BrowserElementPrompt.prototype = {
// int button, // Index of the button that user pressed.
// boolean checked, // True if the check box is checked.
// }
confirmEx(title, text, buttonFlags, button0Title, button1Title,
button2Title, checkMsg, checkState) {
let buttonProperties = this._buildConfirmExButtonProperties(buttonFlags,
button0Title,
button1Title,
button2Title);
confirmEx(
title,
text,
buttonFlags,
button0Title,
button1Title,
button2Title,
checkMsg,
checkState
) {
let buttonProperties = this._buildConfirmExButtonProperties(
buttonFlags,
button0Title,
button1Title,
button2Title
);
let defaultReturnValue = { selectedButton: buttonProperties.defaultButton };
if (checkMsg) {
defaultReturnValue.checked = checkState.value;
}
let ret = this._browserElementChild.showModalPrompt(
this._win,
{
promptType: "custom-prompt",
title,
message: text,
defaultButton: buttonProperties.defaultButton,
buttons: buttonProperties.buttons,
showCheckbox: !!checkMsg,
checkboxMessage: checkMsg,
checkboxCheckedByDefault: !!checkState.value,
returnValue: defaultReturnValue,
}
);
let ret = this._browserElementChild.showModalPrompt(this._win, {
promptType: "custom-prompt",
title,
message: text,
defaultButton: buttonProperties.defaultButton,
buttons: buttonProperties.buttons,
showCheckbox: !!checkMsg,
checkboxMessage: checkMsg,
checkboxCheckedByDefault: !!checkState.value,
returnValue: defaultReturnValue,
});
if (checkMsg) {
checkState.value = ret.checked;
}
@ -89,13 +104,13 @@ BrowserElementPrompt.prototype = {
},
prompt(title, text, value, checkMsg, checkState) {
let rv = this._browserElementChild.showModalPrompt(
this._win,
{ promptType: "prompt",
title,
message: text,
initialValue: value.value,
returnValue: null });
let rv = this._browserElementChild.showModalPrompt(this._win, {
promptType: "prompt",
title,
message: text,
initialValue: value.value,
returnValue: null,
});
value.value = rv;
@ -107,7 +122,14 @@ BrowserElementPrompt.prototype = {
return rv !== null;
},
promptUsernameAndPassword(title, text, username, password, checkMsg, checkState) {
promptUsernameAndPassword(
title,
text,
username,
password,
checkMsg,
checkState
) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
@ -119,8 +141,12 @@ BrowserElementPrompt.prototype = {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
_buildConfirmExButtonProperties(buttonFlags, button0Title,
button1Title, button2Title) {
_buildConfirmExButtonProperties(
buttonFlags,
button0Title,
button1Title,
button2Title
) {
let r = {
defaultButton: -1,
buttons: [],
@ -151,34 +177,34 @@ BrowserElementPrompt.prototype = {
ret.messageType = "builtin";
switch (titleType) {
case Ci.nsIPrompt.BUTTON_TITLE_OK:
ret.message = "ok";
break;
case Ci.nsIPrompt.BUTTON_TITLE_CANCEL:
ret.message = "cancel";
break;
case Ci.nsIPrompt.BUTTON_TITLE_YES:
ret.message = "yes";
break;
case Ci.nsIPrompt.BUTTON_TITLE_NO:
ret.message = "no";
break;
case Ci.nsIPrompt.BUTTON_TITLE_SAVE:
ret.message = "save";
break;
case Ci.nsIPrompt.BUTTON_TITLE_DONT_SAVE:
ret.message = "dontsave";
break;
case Ci.nsIPrompt.BUTTON_TITLE_REVERT:
ret.message = "revert";
break;
case Ci.nsIPrompt.BUTTON_TITLE_IS_STRING:
ret.message = buttonTitle;
ret.messageType = "custom";
break;
default:
// This button is not shown.
return;
case Ci.nsIPrompt.BUTTON_TITLE_OK:
ret.message = "ok";
break;
case Ci.nsIPrompt.BUTTON_TITLE_CANCEL:
ret.message = "cancel";
break;
case Ci.nsIPrompt.BUTTON_TITLE_YES:
ret.message = "yes";
break;
case Ci.nsIPrompt.BUTTON_TITLE_NO:
ret.message = "no";
break;
case Ci.nsIPrompt.BUTTON_TITLE_SAVE:
ret.message = "save";
break;
case Ci.nsIPrompt.BUTTON_TITLE_DONT_SAVE:
ret.message = "dontsave";
break;
case Ci.nsIPrompt.BUTTON_TITLE_REVERT:
ret.message = "revert";
break;
case Ci.nsIPrompt.BUTTON_TITLE_IS_STRING:
ret.message = buttonTitle;
ret.messageType = "custom";
break;
default:
// This button is not shown.
return;
}
// If this is the default button, set r.defaultButton to
@ -198,17 +224,17 @@ BrowserElementPrompt.prototype = {
// If defaultButton is still -1 here, it means the default button won't
// be shown.
if (r.defaultButton === -1) {
throw new Components.Exception("Default button won't be shown",
Cr.NS_ERROR_FAILURE);
throw new Components.Exception(
"Default button won't be shown",
Cr.NS_ERROR_FAILURE
);
}
return r;
},
};
function BrowserElementAuthPrompt() {
}
function BrowserElementAuthPrompt() {}
BrowserElementAuthPrompt.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIAuthPrompt2]),
@ -217,12 +243,20 @@ BrowserElementAuthPrompt.prototype = {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
asyncPromptAuth: function asyncPromptAuth(channel, callback, context, level, authInfo) {
asyncPromptAuth: function asyncPromptAuth(
channel,
callback,
context,
level,
authInfo
) {
debug("asyncPromptAuth");
// The cases that we don't support now.
if ((authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) &&
(authInfo.flags & Ci.nsIAuthInformation.ONLY_PASSWORD)) {
if (
authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY &&
authInfo.flags & Ci.nsIAuthInformation.ONLY_PASSWORD
) {
throw Cr.NS_ERROR_FAILURE;
}
@ -232,8 +266,9 @@ BrowserElementAuthPrompt.prototype = {
throw Cr.NS_ERROR_FAILURE;
}
let browserElementParent =
BrowserElementPromptService.getBrowserElementParentForFrame(frame);
let browserElementParent = BrowserElementPromptService.getBrowserElementParentForFrame(
frame
);
if (!browserElementParent) {
debug("Failed to load browser element parent.");
@ -290,8 +325,9 @@ BrowserElementAuthPrompt.prototype = {
}
// Didn't find an available prompt, so just return.
if (!hashKey)
if (!hashKey) {
return;
}
let prompt = this._asyncPrompts[hashKey];
@ -300,8 +336,9 @@ BrowserElementAuthPrompt.prototype = {
let self = this;
let callback = function(ok, username, password) {
debug("Async auth callback is called, ok = " +
ok + ", username = " + username);
debug(
"Async auth callback is called, ok = " + ok + ", username = " + username
);
// Here we got the username and password provided by embedder, or
// ok = false if the prompt was cancelled by embedder.
@ -319,7 +356,7 @@ BrowserElementAuthPrompt.prototype = {
if (idx == -1) {
prompt.authInfo.username = username;
} else {
prompt.authInfo.domain = username.substring(0, idx);
prompt.authInfo.domain = username.substring(0, idx);
prompt.authInfo.username = username.substring(idx + 1);
}
} else {
@ -341,12 +378,17 @@ BrowserElementAuthPrompt.prototype = {
try {
if (ok) {
debug("Ok, calling onAuthAvailable to finish auth");
consumer.callback.onAuthAvailable(consumer.context, prompt.authInfo);
consumer.callback.onAuthAvailable(
consumer.context,
prompt.authInfo
);
} else {
debug("Cancelled, calling onAuthCancelled to finish auth.");
consumer.callback.onAuthCancelled(consumer.context, true);
}
} catch (e) { /* Throw away exceptions caused by callback */ }
} catch (e) {
/* Throw away exceptions caused by callback */
}
}
// Process the next prompt, if one is pending.
@ -358,7 +400,8 @@ BrowserElementAuthPrompt.prototype = {
// Call promptAuth of browserElementParent, to show the prompt.
prompt.browserElementParent.promptAuth(
self._createAuthDetail(prompt.channel, prompt.authInfo),
callback);
callback
);
},
};
@ -366,19 +409,21 @@ BrowserElementAuthPrompt.prototype = {
},
_getFrameFromChannel(channel) {
let loadContext = channel.notificationCallbacks.getInterface(Ci.nsILoadContext);
let loadContext = channel.notificationCallbacks.getInterface(
Ci.nsILoadContext
);
return loadContext.topFrameElement;
},
_createAuthDetail(channel, authInfo) {
let [hostname, httpRealm] = this._getAuthTarget(channel, authInfo);
return {
host: hostname,
path: channel.URI.pathQueryRef,
realm: httpRealm,
username: authInfo.username,
isProxy: !!(authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY),
isOnlyPassword: !!(authInfo.flags & Ci.nsIAuthInformation.ONLY_PASSWORD),
host: hostname,
path: channel.URI.pathQueryRef,
realm: httpRealm,
username: authInfo.username,
isProxy: !!(authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY),
isOnlyPassword: !!(authInfo.flags & Ci.nsIAuthInformation.ONLY_PASSWORD),
};
},
@ -390,23 +435,29 @@ BrowserElementAuthPrompt.prototype = {
// If our proxy is demanding authentication, don't use the
// channel's actual destination.
if (authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) {
if (!(channel instanceof Ci.nsIProxiedChannel))
if (!(channel instanceof Ci.nsIProxiedChannel)) {
throw new Error("proxy auth needs nsIProxiedChannel");
}
let info = channel.proxyInfo;
if (!info)
if (!info) {
throw new Error("proxy auth needs nsIProxyInfo");
}
// Proxies don't have a scheme, but we'll use "moz-proxy://"
// so that it's more obvious what the login is for.
var idnService = Cc["@mozilla.org/network/idn-service;1"].
getService(Ci.nsIIDNService);
hostname = "moz-proxy://" +
idnService.convertUTF8toACE(info.host) +
":" + info.port;
var idnService = Cc["@mozilla.org/network/idn-service;1"].getService(
Ci.nsIIDNService
);
hostname =
"moz-proxy://" +
idnService.convertUTF8toACE(info.host) +
":" +
info.port;
realm = authInfo.realm;
if (!realm)
if (!realm) {
realm = hostname;
}
return [hostname, realm];
}
@ -417,8 +468,9 @@ BrowserElementAuthPrompt.prototype = {
// will be available here. If it wasn't set or wasn't HTTP, we'll use
// the formatted hostname instead.
realm = authInfo.realm;
if (!realm)
if (!realm) {
realm = hostname;
}
return [hostname, realm];
},
@ -431,7 +483,6 @@ BrowserElementAuthPrompt.prototype = {
},
};
function AuthPromptWrapper(oldImpl, browserElementImpl) {
this._oldImpl = oldImpl;
this._browserElementImpl = browserElementImpl;
@ -443,27 +494,42 @@ AuthPromptWrapper.prototype = {
if (this._canGetParentElement(channel)) {
return this._browserElementImpl.promptAuth(channel, level, authInfo);
}
return this._oldImpl.promptAuth(channel, level, authInfo);
return this._oldImpl.promptAuth(channel, level, authInfo);
},
asyncPromptAuth(channel, callback, context, level, authInfo) {
if (this._canGetParentElement(channel)) {
return this._browserElementImpl.asyncPromptAuth(channel, callback, context, level, authInfo);
return this._browserElementImpl.asyncPromptAuth(
channel,
callback,
context,
level,
authInfo
);
}
return this._oldImpl.asyncPromptAuth(channel, callback, context, level, authInfo);
return this._oldImpl.asyncPromptAuth(
channel,
callback,
context,
level,
authInfo
);
},
_canGetParentElement(channel) {
try {
let context = channel.notificationCallbacks.getInterface(Ci.nsILoadContext);
let context = channel.notificationCallbacks.getInterface(
Ci.nsILoadContext
);
let frame = context.topFrameElement;
if (!frame) {
// This function returns a boolean value
return !!context.nestedFrameId;
}
if (!BrowserElementPromptService.getBrowserElementParentForFrame(frame))
if (!BrowserElementPromptService.getBrowserElementParentForFrame(frame)) {
return false;
}
return true;
} catch (e) {
@ -490,32 +556,45 @@ BrowserElementPromptFactory.prototype = {
},
_getNativePromptIfAllowed(win, iid, err) {
if (this._mayUseNativePrompt())
if (this._mayUseNativePrompt()) {
return this._wrapped.getPrompt(win, iid);
}
// Not allowed, throw an exception.
throw err;
// Not allowed, throw an exception.
throw err;
},
getPrompt(win, iid) {
// It is possible for some object to get a prompt without passing
// valid reference of window, like nsNSSComponent. In such case, we
// should just fall back to the native prompt service
if (!win)
if (!win) {
return this._getNativePromptIfAllowed(win, iid, Cr.NS_ERROR_INVALID_ARG);
}
if (iid.number != Ci.nsIPrompt.number &&
iid.number != Ci.nsIAuthPrompt2.number) {
debug("We don't recognize the requested IID (" + iid + ", " +
"allowed IID: " +
"nsIPrompt=" + Ci.nsIPrompt + ", " +
"nsIAuthPrompt2=" + Ci.nsIAuthPrompt2 + ")");
if (
iid.number != Ci.nsIPrompt.number &&
iid.number != Ci.nsIAuthPrompt2.number
) {
debug(
"We don't recognize the requested IID (" +
iid +
", " +
"allowed IID: " +
"nsIPrompt=" +
Ci.nsIPrompt +
", " +
"nsIAuthPrompt2=" +
Ci.nsIAuthPrompt2 +
")"
);
return this._getNativePromptIfAllowed(win, iid, Cr.NS_ERROR_INVALID_ARG);
}
// Try to find a BrowserElementChild for the window.
let browserElementChild =
BrowserElementPromptService.getBrowserElementChildForWindow(win);
let browserElementChild = BrowserElementPromptService.getBrowserElementChildForWindow(
win
);
if (iid.number === Ci.nsIAuthPrompt2.number) {
debug("Caller requests an instance of nsIAuthPrompt2.");
@ -534,30 +613,34 @@ BrowserElementPromptFactory.prototype = {
// functions of nsIAuthPrompt2.
if (this._mayUseNativePrompt()) {
return new AuthPromptWrapper(
this._wrapped.getPrompt(win, iid),
new BrowserElementAuthPrompt().QueryInterface(iid))
.QueryInterface(iid);
this._wrapped.getPrompt(win, iid),
new BrowserElementAuthPrompt().QueryInterface(iid)
).QueryInterface(iid);
}
// Falling back is not allowed, so we don't need wrap the
// BrowserElementPrompt.
return new BrowserElementAuthPrompt().QueryInterface(iid);
// Falling back is not allowed, so we don't need wrap the
// BrowserElementPrompt.
return new BrowserElementAuthPrompt().QueryInterface(iid);
}
if (!browserElementChild) {
debug("We can't find a browserElementChild for " +
win + ", " + win.location);
debug(
"We can't find a browserElementChild for " + win + ", " + win.location
);
return this._getNativePromptIfAllowed(win, iid, Cr.NS_ERROR_FAILURE);
}
debug("Returning wrapped getPrompt for " + win);
return new BrowserElementPrompt(win, browserElementChild)
.QueryInterface(iid);
return new BrowserElementPrompt(win, browserElementChild).QueryInterface(
iid
);
},
};
var BrowserElementPromptService = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
QueryInterface: ChromeUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference,
]),
_initialized: false,
@ -568,14 +651,22 @@ var BrowserElementPromptService = {
// If the pref is disabled, do nothing except wait for the pref to change.
if (!this._browserFramesPrefEnabled()) {
Services.prefs.addObserver(BROWSER_FRAMES_ENABLED_PREF, this, /* ownsWeak = */ true);
Services.prefs.addObserver(
BROWSER_FRAMES_ENABLED_PREF,
this,
/* ownsWeak = */ true
);
return;
}
this._initialized = true;
this._browserElementParentMap = new WeakMap();
Services.obs.addObserver(this, "outer-window-destroyed", /* ownsWeak = */ true);
Services.obs.addObserver(
this,
"outer-window-destroyed",
/* ownsWeak = */ true
);
// Wrap the existing @mozilla.org/prompter;1 implementation.
var contractID = "@mozilla.org/prompter;1";
@ -599,9 +690,12 @@ var BrowserElementPromptService = {
return newInstance.QueryInterface(iid);
},
};
Cm.registerFactory(newCID,
"BrowserElementPromptService's prompter;1 wrapper",
contractID, newFactory);
Cm.registerFactory(
newCID,
"BrowserElementPromptService's prompter;1 wrapper",
contractID,
newFactory
);
debug("Done installing new prompt factory.");
},
@ -612,7 +706,9 @@ var BrowserElementPromptService = {
_browserElementChildMap: {},
mapWindowToBrowserElementChild(win, browserElementChild) {
this._browserElementChildMap[this._getOuterWindowID(win)] = browserElementChild;
this._browserElementChildMap[
this._getOuterWindowID(win)
] = browserElementChild;
},
unmapWindowToBrowserElementChild(win) {
delete this._browserElementChildMap[this._getOuterWindowID(win)];
@ -645,16 +741,16 @@ var BrowserElementPromptService = {
observe(subject, topic, data) {
switch (topic) {
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
if (data == BROWSER_FRAMES_ENABLED_PREF) {
this._init();
}
break;
case "outer-window-destroyed":
this._observeOuterWindowDestroyed(subject);
break;
default:
debug("Observed unexpected topic " + topic);
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
if (data == BROWSER_FRAMES_ENABLED_PREF) {
this._init();
}
break;
case "outer-window-destroyed":
this._observeOuterWindowDestroyed(subject);
break;
default:
debug("Observed unexpected topic " + topic);
}
},
};

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

@ -41,9 +41,9 @@
}
// not a generator, wrap it.
if (func.constructor.name !== "GeneratorFunction") {
gen = (function* () {
gen = (function*() {
return func.apply(self, functionArgs);
}());
})();
} else {
gen = func.apply(self, functionArgs);
}
@ -53,21 +53,23 @@
reject(err);
}
function step({value, done}) {
function step({ value, done }) {
if (done) {
return resolve(value);
}
if (value instanceof Promise) {
return value.then(
result => step(gen.next(result)),
error => {
try {
step(gen.throw(error));
} catch (err) {
throw err;
return value
.then(
result => step(gen.next(result)),
error => {
try {
step(gen.throw(error));
} catch (err) {
throw err;
}
}
}
).catch(err => reject(err));
)
.catch(err => reject(err));
}
return step(gen.next(value));
}
@ -75,4 +77,4 @@
};
}
exports.async = async;
}(this || self));
})(this || self);

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

@ -9,8 +9,8 @@ function _getPath() {
return "/chrome/dom/browser-element/mochitest";
}
return window.location.pathname
.substring(0, window.location.pathname.lastIndexOf("/"))
.replace("/priority", "");
.substring(0, window.location.pathname.lastIndexOf("/"))
.replace("/priority", "");
}
const browserElementTestHelpers = {
@ -25,15 +25,24 @@ const browserElementTestHelpers = {
_setPref(pref, value) {
this.lockTestReady();
if (value !== undefined && value !== null) {
SpecialPowers.pushPrefEnv({"set": [[pref, value]]}, this.unlockTestReady.bind(this));
SpecialPowers.pushPrefEnv(
{ set: [[pref, value]] },
this.unlockTestReady.bind(this)
);
} else {
SpecialPowers.pushPrefEnv({"clear": [[pref]]}, this.unlockTestReady.bind(this));
SpecialPowers.pushPrefEnv(
{ clear: [[pref]] },
this.unlockTestReady.bind(this)
);
}
},
_setPrefs() {
this.lockTestReady();
SpecialPowers.pushPrefEnv({"set": Array.from(arguments)}, this.unlockTestReady.bind(this));
SpecialPowers.pushPrefEnv(
{ set: Array.from(arguments) },
this.unlockTestReady.bind(this)
);
},
_testReadyLockCount: 0,
@ -62,8 +71,10 @@ const browserElementTestHelpers = {
},
setEnabledPref(value) {
this._setPrefs(["dom.mozBrowserFramesEnabled", value],
["network.disable.ipc.security", value]);
this._setPrefs(
["dom.mozBrowserFramesEnabled", value],
["network.disable.ipc.security", value]
);
},
setupAccessibleCaretPref() {
@ -80,12 +91,16 @@ const browserElementTestHelpers = {
addPermission() {
this.lockTestReady();
SpecialPowers.pushPermissions(
[{"type": "browser", "allow": 1, "context": document}],
this.unlockTestReady.bind(this));
[{ type: "browser", allow: 1, context: document }],
this.unlockTestReady.bind(this)
);
},
allowTopLevelDataURINavigation() {
this._setPref("security.data_uri.block_toplevel_data_uri_navigations", false);
this._setPref(
"security.data_uri.block_toplevel_data_uri_navigations",
false
);
},
_observers: [],
@ -110,17 +125,19 @@ const browserElementTestHelpers = {
cleanUp() {
for (var i = 0; i < this._observers.length; i++) {
SpecialPowers.removeObserver(this._observers[i][0],
this._observers[i][1]);
SpecialPowers.removeObserver(
this._observers[i][0],
this._observers[i][1]
);
}
},
// Some basically-empty pages from different domains you can load.
"emptyPage1": "http://example.com" + _getPath() + "/file_empty.html",
"fileEmptyPage1": "file_empty.html",
"emptyPage2": "http://example.org" + _getPath() + "/file_empty.html",
"emptyPage3": "http://test1.example.org" + _getPath() + "/file_empty.html",
"focusPage": "http://example.org" + _getPath() + "/file_focus.html",
emptyPage1: "http://example.com" + _getPath() + "/file_empty.html",
fileEmptyPage1: "file_empty.html",
emptyPage2: "http://example.org" + _getPath() + "/file_empty.html",
emptyPage3: "http://test1.example.org" + _getPath() + "/file_empty.html",
focusPage: "http://example.org" + _getPath() + "/file_focus.html",
};
// Returns a promise which is resolved when a subprocess is created. The
@ -187,9 +204,14 @@ function expectPriorityChange(childID, expectedPriority) {
// we'll expect /every/ priority change to match expectedPriority.
observed = true;
is(priority, expectedPriority,
"Expected priority of childID " + childID +
" to change to " + expectedPriority);
is(
priority,
expectedPriority,
"Expected priority of childID " +
childID +
" to change to " +
expectedPriority
);
if (priority == expectedPriority) {
resolve();
@ -252,11 +274,17 @@ function expectMozbrowserEvent(iframe, eventName) {
browserElementTestHelpers.lockTestReady();
SpecialPowers.setBoolPref("network.disable.ipc.security", true);
SpecialPowers.pushPrefEnv({set: [["browser.pagethumbnails.capturing_disabled", true],
["dom.ipc.browser_frames.oop_by_default", oop],
["dom.ipc.tabs.disabled", false],
["security.mixed_content.block_active_content", false]]},
browserElementTestHelpers.unlockTestReady.bind(browserElementTestHelpers));
SpecialPowers.pushPrefEnv(
{
set: [
["browser.pagethumbnails.capturing_disabled", true],
["dom.ipc.browser_frames.oop_by_default", oop],
["dom.ipc.tabs.disabled", false],
["security.mixed_content.block_active_content", false],
],
},
browserElementTestHelpers.unlockTestReady.bind(browserElementTestHelpers)
);
})();
addEventListener("unload", function() {
@ -266,5 +294,7 @@ addEventListener("unload", function() {
// Wait for the load event before unlocking the test-ready event.
browserElementTestHelpers.lockTestReady();
addEventListener("load", function() {
SimpleTest.executeSoon(browserElementTestHelpers.unlockTestReady.bind(browserElementTestHelpers));
SimpleTest.executeSoon(
browserElementTestHelpers.unlockTestReady.bind(browserElementTestHelpers)
);
});

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

@ -31,13 +31,21 @@ function runTest() {
// Wait for the initial load to finish, then navigate the page, then wait
// for that load to finish, then start test1.
iframe.addEventListener("mozbrowserloadend", function() {
iframe.src = browserElementTestHelpers.emptyPage1;
iframe.addEventListener(
"mozbrowserloadend",
function() {
iframe.src = browserElementTestHelpers.emptyPage1;
iframe.addEventListener("mozbrowserloadend", function() {
SimpleTest.executeSoon(test1);
}, {once: true});
}, {once: true});
iframe.addEventListener(
"mozbrowserloadend",
function() {
SimpleTest.executeSoon(test1);
},
{ once: true }
);
},
{ once: true }
);
}
function test1() {
@ -45,7 +53,8 @@ function test1() {
// Do window.alert within the iframe, then modify the global |testState|
// after the alert.
var script = 'data:,\
var script =
'data:,\
this.testState = 0; \
content.alert("Hello, world!"); \
this.testState = 1; \
@ -63,13 +72,16 @@ function test2(e) {
is(e.detail.message, "Hello, world!");
e.preventDefault(); // cause the alert to block.
SimpleTest.executeSoon(function() { test2a(e); });
SimpleTest.executeSoon(function() {
test2a(e);
});
}
function test2a(e) {
// The iframe should be blocked on the alert call at the moment, so testState
// should still be 0.
var script = 'data:,\
var script =
'data:,\
if (this.testState === 0) { \
sendAsyncMessage("test-success", "1: Correct testState"); \
} \
@ -80,14 +92,17 @@ function test2a(e) {
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
numPendingChildTests++;
waitForPendingTests(function() { test3(e); });
waitForPendingTests(function() {
test3(e);
});
}
function test3(e) {
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 = 'data:,\
var script2 =
'data:,\
if (this.testState === 1) { \
sendAsyncMessage("test-success", "2: Correct testState"); \
} \
@ -149,7 +164,8 @@ var promptBlockers = [];
function test6() {
iframe.addEventListener("mozbrowsershowmodalprompt", test6a);
var script = "data:,\
var script =
"data:,\
this.testState = 0; \
content.alert(1); \
this.testState = 3; \
@ -168,7 +184,8 @@ function test6a(e) {
}
function test6b() {
var script = 'data:,\
var script =
'data:,\
if (this.testState === 0) { \
sendAsyncMessage("test-success", "1: Correct testState"); \
} \
@ -184,7 +201,8 @@ function test6b() {
function test6c() {
iframe.addEventListener("mozbrowsershowmodalprompt", test6d);
var script = "data:,\
var script =
"data:,\
this.testState = 1; \
content.alert(2); \
this.testState = 2; \
@ -203,7 +221,8 @@ function test6d(e) {
}
function test6e() {
var script = 'data:,\
var script =
'data:,\
if (this.testState === 1) { \
sendAsyncMessage("test-success", "2: Correct testState"); \
} \
@ -221,7 +240,8 @@ function test6f() {
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 = 'data:,\
var script2 =
'data:,\
if (this.testState === 2) { \
sendAsyncMessage("test-success", "3: Correct testState"); \
} \
@ -253,7 +273,8 @@ function test6g() {
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 = 'data:,\
var script2 =
'data:,\
if (this.testState === 3) { \
sendAsyncMessage("test-success", "4: Correct testState"); \
} \
@ -292,7 +313,9 @@ function waitForPendingTests(next) {
}
if (numPendingChildTests > 0) {
SimpleTest.executeSoon(function() { waitForPendingTests(next); });
SimpleTest.executeSoon(function() {
waitForPendingTests(next);
});
return;
}

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

@ -10,7 +10,9 @@ SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
const { NetUtil } = SpecialPowers.Cu.import("resource://gre/modules/NetUtil.jsm");
const { NetUtil } = SpecialPowers.Cu.import(
"resource://gre/modules/NetUtil.jsm"
);
function testFail(msg) {
ok(false, JSON.stringify(msg));
@ -25,35 +27,59 @@ function runTest() {
// Wait for the initial load to finish, then navigate the page, then start test
// by loading SJS with http 401 response.
iframe.addEventListener("mozbrowserloadend", function() {
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testHttpAuthCancel);
SimpleTest.executeSoon(function() {
// Use absolute path because we need to specify host.
iframe.src = "http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
});
}, {once: true});
iframe.addEventListener(
"mozbrowserloadend",
function() {
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuthCancel
);
SimpleTest.executeSoon(function() {
// Use absolute path because we need to specify host.
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
});
},
{ once: true }
);
}
function testHttpAuthCancel(e) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testHttpAuthCancel);
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuthCancel
);
// Will cancel authentication, but prompt should not be shown again. Instead,
// we will be led to fail message
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
iframe.addEventListener("mozbrowsertitlechange", function(f) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(f.detail, "http auth failed", "expected authentication to fail");
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testHttpAuth);
SimpleTest.executeSoon(function() {
// Use absolute path because we need to specify host.
iframe.src = "http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
});
}, {once: true});
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(f.detail, "http auth failed", "expected authentication to fail");
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuth
);
SimpleTest.executeSoon(function() {
// Use absolute path because we need to specify host.
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
});
},
{ once: true }
);
is(e.detail.realm, "http_realm", "expected realm matches");
is(e.detail.host, "http://test", "expected host matches");
is(e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"expected path matches");
is(
e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"expected path matches"
);
e.preventDefault();
SimpleTest.executeSoon(function() {
@ -62,22 +88,34 @@ function testHttpAuthCancel(e) {
}
function testHttpAuth(e) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testHttpAuth);
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuth
);
// Will authenticate with correct password, prompt should not be
// called again.
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
iframe.addEventListener("mozbrowsertitlechange", function(f) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(f.detail, "http auth success", "expect authentication to succeed");
SimpleTest.executeSoon(testProxyAuth);
}, {once: true});
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(f.detail, "http auth success", "expect authentication to succeed");
SimpleTest.executeSoon(testProxyAuth);
},
{ once: true }
);
is(e.detail.realm, "http_realm", "expected realm matches");
is(e.detail.host, "http://test", "expected host matches");
is(e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"expected path matches");
is(
e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"expected path matches"
);
is(e.detail.isProxy, false, "expected isProxy is false");
e.preventDefault();
@ -90,23 +128,39 @@ function testProxyAuth() {
// The testingSJS simulates the 407 proxy authentication required response
// for proxy server, which will trigger the browser element to send prompt
// event with proxy infomation.
var testingSJS = "http://test/tests/dom/browser-element/mochitest/file_http_407_response.sjs";
var testingSJS =
"http://test/tests/dom/browser-element/mochitest/file_http_407_response.sjs";
var mozproxy;
function onUserNameAndPasswordRequired(e) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired);
iframe.addEventListener("mozbrowsertitlechange", function(event) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(event.detail, "http auth success", "expect authentication to succeed");
SimpleTest.executeSoon(testAuthJarNoInterfere);
}, {once: true});
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
iframe.addEventListener(
"mozbrowsertitlechange",
function(event) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(
event.detail,
"http auth success",
"expect authentication to succeed"
);
SimpleTest.executeSoon(testAuthJarNoInterfere);
},
{ once: true }
);
is(e.detail.realm, "http_realm", "expected realm matches");
is(e.detail.host, mozproxy, "expected host matches");
is(e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_407_response.sjs",
"expected path matches");
is(
e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_407_response.sjs",
"expected path matches"
);
is(e.detail.isProxy, true, "expected isProxy is true");
e.preventDefault();
@ -121,7 +175,11 @@ function testProxyAuth() {
// eslint-disable-next-line mozilla/use-chromeutils-generateqi
QueryInterface(iid) {
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
if (!interfaces.some( function(v) { return iid.equals(v); } )) {
if (
!interfaces.some(function(v) {
return iid.equals(v);
})
) {
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
}
return this;
@ -132,8 +190,10 @@ function testProxyAuth() {
if (pi) {
mozproxy = "moz-proxy://" + pi.host + ":" + pi.port;
}
iframe.addEventListener("mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired);
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
iframe.src = testingSJS;
},
@ -144,88 +204,157 @@ function testProxyAuth() {
loadUsingSystemPrincipal: true,
});
var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"]
.getService();
var pps = SpecialPowers.Cc[
"@mozilla.org/network/protocol-proxy-service;1"
].getService();
pps.asyncResolve(channel, 0, resolveCallback);
}
function testAuthJarNoInterfere(e) {
let authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
.getService(SpecialPowers.Ci.nsIHttpAuthManager);
let authMgr = SpecialPowers.Cc[
"@mozilla.org/network/http-auth-manager;1"
].getService(SpecialPowers.Ci.nsIHttpAuthManager);
let secMan = SpecialPowers.Services.scriptSecurityManager;
let ioService = SpecialPowers.Services.io;
var uri = ioService.newURI("http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs");
var uri = ioService.newURI(
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs"
);
// Set a bunch of auth data that should not conflict with the correct auth data already
// stored in the cache.
var attrs = {userContextId: 1};
var attrs = { userContextId: 1 };
var principal = secMan.createCodebasePrincipal(uri, attrs);
authMgr.setAuthIdentity("http", "test", -1, "basic", "http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"", "httpuser", "wrongpass", false, principal);
attrs = {userContextId: 1, inIsolatedMozBrowser: true};
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
attrs = { userContextId: 1, inIsolatedMozBrowser: true };
principal = secMan.createCodebasePrincipal(uri, attrs);
authMgr.setAuthIdentity("http", "test", -1, "basic", "http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"", "httpuser", "wrongpass", false, principal);
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
principal = secMan.createCodebasePrincipal(uri, {});
authMgr.setAuthIdentity("http", "test", -1, "basic", "http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"", "httpuser", "wrongpass", false, principal);
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
// Will authenticate with correct password, prompt should not be
// called again.
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
iframe.addEventListener("mozbrowsertitlechange", function(f) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(f.detail, "http auth success", "expected authentication success");
SimpleTest.executeSoon(testAuthJarInterfere);
}, {once: true});
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(f.detail, "http auth success", "expected authentication success");
SimpleTest.executeSoon(testAuthJarInterfere);
},
{ once: true }
);
// Once more with feeling. Ensure that our new auth data doesn't interfere with this mozbrowser's
// auth data.
iframe.src = "http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
}
function testAuthJarInterfere(e) {
let authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
.getService(SpecialPowers.Ci.nsIHttpAuthManager);
let authMgr = SpecialPowers.Cc[
"@mozilla.org/network/http-auth-manager;1"
].getService(SpecialPowers.Ci.nsIHttpAuthManager);
let secMan = SpecialPowers.Services.scriptSecurityManager;
let ioService = SpecialPowers.Services.io;
var uri = ioService.newURI("http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs");
var uri = ioService.newURI(
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs"
);
// Set some auth data that should overwrite the successful stored details.
var principal = secMan.createCodebasePrincipal(uri, {inIsolatedMozBrowser: true});
authMgr.setAuthIdentity("http", "test", -1, "basic", "http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"", "httpuser", "wrongpass", false, principal);
var principal = secMan.createCodebasePrincipal(uri, {
inIsolatedMozBrowser: true,
});
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
// Will authenticate with correct password, prompt should not be
// called again.
var gotusernamepasswordrequired = false;
function onUserNameAndPasswordRequired() {
gotusernamepasswordrequired = true;
gotusernamepasswordrequired = true;
}
iframe.addEventListener("mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired);
iframe.addEventListener("mozbrowsertitlechange", function(f) {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired);
ok(gotusernamepasswordrequired,
"Should have dispatched mozbrowserusernameandpasswordrequired event");
testFinish();
}, {once: true});
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
ok(
gotusernamepasswordrequired,
"Should have dispatched mozbrowserusernameandpasswordrequired event"
);
testFinish();
},
{ once: true }
);
// Once more with feeling. Ensure that our new auth data interferes with this mozbrowser's
// auth data.
iframe.src = "http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
}
function testFinish() {
// Clear login information stored in password manager.
let authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
.getService(SpecialPowers.Ci.nsIHttpAuthManager);
let authMgr = SpecialPowers.Cc[
"@mozilla.org/network/http-auth-manager;1"
].getService(SpecialPowers.Ci.nsIHttpAuthManager);
authMgr.clearAll();
SpecialPowers.Services.logins.removeAllLogins();
@ -235,5 +364,15 @@ function testFinish() {
addEventListener("testready", function() {
// Enable http authentiication.
SpecialPowers.pushPrefEnv({"set": [["network.auth.non-web-content-triggered-resources-http-auth-allow", true]]}, runTest);
SpecialPowers.pushPrefEnv(
{
set: [
[
"network.auth.non-web-content-triggered-resources-http-auth-allow",
true,
],
],
},
runTest
);
});

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

@ -36,7 +36,11 @@ function runTest() {
function checkCanGoBackAndForward(canGoBack, canGoForward, nextTest) {
var seenCanGoBackResult = false;
iframe.getCanGoBack().then(function(result) {
is(seenCanGoBackResult, false, "onsuccess handler shouldn't be called twice.");
is(
seenCanGoBackResult,
false,
"onsuccess handler shouldn't be called twice."
);
seenCanGoBackResult = true;
is(result, canGoBack);
maybeRunNextTest();
@ -44,7 +48,11 @@ function checkCanGoBackAndForward(canGoBack, canGoForward, nextTest) {
var seenCanGoForwardResult = false;
iframe.getCanGoForward().then(function(result) {
is(seenCanGoForwardResult, false, "onsuccess handler shouldn't be called twice.");
is(
seenCanGoForwardResult,
false,
"onsuccess handler shouldn't be called twice."
);
seenCanGoForwardResult = true;
is(result, canGoForward);
maybeRunNextTest();

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

@ -25,7 +25,9 @@ function runTest() {
ok(true, "Got first mozbrowseropenwindow event.");
document.body.appendChild(e.detail.frameElement);
e.detail.frameElement.addEventListener("mozbrowserlocationchange", function(f) {
e.detail.frameElement.addEventListener("mozbrowserlocationchange", function(
f
) {
if (f.detail.url == "http://example.com/#2") {
ok(true, "Got locationchange to http://example.com/#2");
SimpleTest.finish();

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

@ -12,16 +12,18 @@ browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
function runTest() {
var srcResizeTo = "data:text/html, \
var srcResizeTo =
"data:text/html, \
<script type='application/javascript'> \
window.resizeTo(300, 300); \
<\/script> \
</script> \
";
var srcResizeBy = "data:text/html, \
var srcResizeBy =
"data:text/html, \
<script type='application/javascript'> \
window.resizeBy(-100, -100); \
<\/script> \
</script> \
";
var count = 0;

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

@ -21,7 +21,8 @@ function runTest() {
SimpleTest.finish();
});
iframe.src = "data:text/html,<html><body><script>window.close()</script></body></html>";
iframe.src =
"data:text/html,<html><body><script>window.close()</script></body></html>";
}
addEventListener("testready", runTest);

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

@ -24,7 +24,6 @@ function runTest() {
});
});
document.body.appendChild(iframe);
// file_browserElement_CloseFromOpener opens a new window and then calls

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше