blob: 684785809254f511efe10463a6a701403568a60b [file] [log] [blame]
export function insertIframe(hostname, header) {
const iframe = document.createElement("iframe");
const navigatePromise = navigateIframe(iframe, hostname, header);
document.body.append(iframe);
return navigatePromise;
}
export function navigateIframe(iframeEl, hostname, header) {
const url = getURL(hostname, header);
const waitPromise = waitForIframe(iframeEl, url);
iframeEl.src = url;
return waitPromise;
}
export function waitForIframe(iframeEl, destinationForErrorMessage) {
return new Promise((resolve, reject) => {
iframeEl.addEventListener("load", () => resolve(iframeEl.contentWindow));
iframeEl.addEventListener(
"error",
() => reject(new Error(`Could not navigate to ${destinationForErrorMessage}`))
);
});
}
function getURL(hostname, header) {
const url = new URL("send-origin-isolation-header.py", import.meta.url);
url.hostname = hostname;
if (header !== undefined) {
url.searchParams.set("header", header);
}
return url.href;
}
// This function is coupled to ./send-origin-isolation-header.py, which ensures
// that sending such a message will result in a message back.
export async function sendWasmModule(frameWindow) {
frameWindow.postMessage(await createWasmModule(), "*");
return waitForMessage(frameWindow);
}
export async function sendWasmModuleBetween(frameWindow, indexIntoParentFrameOfDestination) {
frameWindow.postMessage({ command: "send WASM module", indexIntoParentFrameOfDestination }, "*");
return waitForMessage(frameWindow);
}
export async function accessDocumentBetween(frameWindow, indexIntoParentFrameOfDestination) {
frameWindow.postMessage({ command: "access document", indexIntoParentFrameOfDestination }, "*");
return waitForMessage(frameWindow);
}
// This function is coupled to ./send-origin-isolation-header.py, which ensures
// that sending such a message will result in a message back.
export async function setBothDocumentDomains(frameWindow) {
// By setting both this page's document.domain and the iframe's document.domain to the same
// value, we ensure that they can synchronously access each other, unless they are
// origin-isolated.
// NOTE: document.domain being unset is different than it being set to its current value.
// It is a terrible API.
document.domain = document.domain;
frameWindow.postMessage({ command: "set document.domain", newDocumentDomain: document.domain }, "*");
const whatHappened = await waitForMessage(frameWindow);
assert_equals(whatHappened, "document.domain is set");
}
function waitForMessage(expectedSource) {
return new Promise(resolve => {
const handler = e => {
if (e.source === expectedSource) {
resolve(e.data);
window.removeEventListener("message", handler);
}
};
window.addEventListener("message", handler);
});
}
// Any WebAssembly.Module will work fine for our tests; we just want to find out if it gives
// message or messageerror. So, we reuse one from the /wasm/ tests.
async function createWasmModule() {
const response = await fetch("/wasm/serialization/module/resources/incrementer.wasm");
const ab = await response.arrayBuffer();
return WebAssembly.compile(ab);
}