зеркало из https://github.com/mozilla/gecko-dev.git
164 строки
4.6 KiB
HTML
164 строки
4.6 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Test for Bug 1647519</title>
|
|
<meta charset="utf-8">
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
</head>
|
|
<body>
|
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1647519">Mozilla Bug 1647519</a>
|
|
|
|
<script type="application/javascript">
|
|
"use strict";
|
|
|
|
function promiseMessage(source, filter = event => true) {
|
|
return new Promise(resolve => {
|
|
function listener(event) {
|
|
if (event.source == source && filter(event)) {
|
|
window.removeEventListener("message", listener);
|
|
resolve(event);
|
|
}
|
|
}
|
|
window.addEventListener("message", listener);
|
|
});
|
|
}
|
|
|
|
async function runTests(resourcePath) {
|
|
/* globals Assert, content */
|
|
let doc = content.document;
|
|
|
|
// Sends a message to the given target window and waits for a response a few
|
|
// times to (more or less) ensure that a `javascript:` load request has had
|
|
// time to succeed, if it were going to.
|
|
async function doSomeRoundTrips(target) {
|
|
for (let i = 0; i < 3; i++) {
|
|
// Note: The ping message needs to be sent from a script running in the
|
|
// content scope or there will be no source window for the reply to be
|
|
// sent to.
|
|
await content.wrappedJSObject.ping(target);
|
|
}
|
|
}
|
|
|
|
function promiseEvent(target, name) {
|
|
return new Promise(resolve => {
|
|
target.addEventListener(name, resolve, { once: true });
|
|
});
|
|
}
|
|
|
|
function createIframe(host, id) {
|
|
let iframe = doc.createElement("iframe");
|
|
iframe.id = id;
|
|
iframe.name = id;
|
|
iframe.src = `http://${host}${resourcePath}file_content_javascript_loads_frame.html`;
|
|
doc.body.appendChild(iframe);
|
|
return promiseEvent(iframe, "load");
|
|
}
|
|
|
|
const ID_SAME_ORIGIN = "frame-same-origin";
|
|
const ID_SAME_BASE_DOMAIN = "frame-same-base-domain";
|
|
const ID_CROSS_BASE_DOMAIN = "frame-cross-base-domain";
|
|
|
|
await Promise.all([
|
|
createIframe("example.com", ID_SAME_ORIGIN),
|
|
createIframe("test1.example.com", ID_SAME_BASE_DOMAIN),
|
|
createIframe("example.org", ID_CROSS_BASE_DOMAIN),
|
|
]);
|
|
|
|
let gotJSLoadFrom = null;
|
|
let pendingJSLoadID = null;
|
|
content.addEventListener("message", event => {
|
|
if ("javascriptLoadID" in event.data) {
|
|
Assert.equal(
|
|
event.data.javascriptLoadID,
|
|
pendingJSLoadID,
|
|
"Message from javascript: load should have the expected ID"
|
|
);
|
|
Assert.equal(
|
|
gotJSLoadFrom,
|
|
null,
|
|
"Should not have seen a previous load message this cycle"
|
|
);
|
|
gotJSLoadFrom = event.source.name;
|
|
}
|
|
});
|
|
|
|
async function watchForJSLoads(frameName, expected, task) {
|
|
let loadId = Math.random();
|
|
|
|
let jsURI =
|
|
"javascript:" +
|
|
encodeURI(`parent.postMessage({ javascriptLoadID: ${loadId} }, "*")`);
|
|
|
|
pendingJSLoadID = loadId;
|
|
gotJSLoadFrom = null;
|
|
|
|
await task(jsURI);
|
|
|
|
await doSomeRoundTrips(content.wrappedJSObject[frameName]);
|
|
|
|
if (expected) {
|
|
Assert.equal(
|
|
gotJSLoadFrom,
|
|
frameName,
|
|
`Should have seen javascript: URI loaded into ${frameName}`
|
|
);
|
|
} else {
|
|
Assert.equal(
|
|
gotJSLoadFrom,
|
|
null,
|
|
"Should not have seen javascript: URI loaded"
|
|
);
|
|
}
|
|
}
|
|
|
|
let frames = [
|
|
{ name: ID_SAME_ORIGIN, expectLoad: true },
|
|
{ name: ID_SAME_BASE_DOMAIN, expectLoad: false },
|
|
{ name: ID_CROSS_BASE_DOMAIN, expectLoad: false },
|
|
];
|
|
for (let { name, expectLoad } of frames) {
|
|
info(`Checking loads for frame "${name}". Expecting loads: ${expectLoad}`);
|
|
|
|
info("Checking location setter");
|
|
await watchForJSLoads(name, expectLoad, jsURI => {
|
|
// Note: We need to do this from the content scope since security checks
|
|
// depend on the JS caller scope.
|
|
content.wrappedJSObject.setFrameLocation(name, jsURI);
|
|
});
|
|
|
|
info("Checking targeted <a> load");
|
|
await watchForJSLoads(name, expectLoad, jsURI => {
|
|
let a = doc.createElement("a");
|
|
a.target = name;
|
|
a.href = jsURI;
|
|
doc.body.appendChild(a);
|
|
a.click();
|
|
a.remove();
|
|
});
|
|
|
|
info("Checking targeted window.open load");
|
|
await watchForJSLoads(name, expectLoad, jsURI => {
|
|
content.wrappedJSObject.open(jsURI, name);
|
|
});
|
|
}
|
|
}
|
|
|
|
add_task(async function() {
|
|
const resourcePath = location.pathname.replace(/[^\/]+$/, "");
|
|
|
|
let win = window.open(
|
|
`http://example.com${resourcePath}file_content_javascript_loads_root.html`
|
|
);
|
|
await promiseMessage(win, event => event.data == "ready");
|
|
|
|
await SpecialPowers.spawn(win, [resourcePath], runTests);
|
|
|
|
win.close();
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|