| 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); |
| } |