diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/measure-memory/resources/common.js | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/measure-memory/resources/common.js')
-rw-r--r-- | testing/web-platform/tests/measure-memory/resources/common.js | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/testing/web-platform/tests/measure-memory/resources/common.js b/testing/web-platform/tests/measure-memory/resources/common.js new file mode 100644 index 0000000000..4332c6e79c --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/common.js @@ -0,0 +1,178 @@ +const ORIGINS = { + 'same-origin': get_host_info().HTTPS_ORIGIN, + 'cross-origin': get_host_info().HTTPS_REMOTE_ORIGIN, + 'cross-site': get_host_info().HTTPS_NOTSAMESITE_ORIGIN, +} + +function url(params) { + let origin = null; + for (const key of Object.keys(ORIGINS)) { + if (params.id.startsWith(key)) { + origin = ORIGINS[key]; + } + } + const child = params.window_open ? 'window' : 'iframe'; + let file = `measure-memory/resources/${child}.sub.html`; + if (params.redirect) { + file = `measure-memory/resources/${child}.redirect.sub.html`; + } + let url = `${origin}/${file}?id=${params.id}`; + if (params.redirect === 'server') { + url = (`${origin}/measure-memory/resources/redirect.py?` + + `location=${encodeURIComponent(url)}`); + } + return url; +} + +// A simple multiplexor of messages based on iframe ids. +let waitForMessage = (function () { + class Inbox { + constructor() { + this.queue = []; + this.resolve = null; + } + push(value) { + if (this.resolve) { + this.resolve(value); + this.resolve = null; + } else { + this.queue.push(value); + } + } + pop() { + let promise = new Promise(resolve => this.resolve = resolve); + if (this.queue.length > 0) { + this.resolve(this.queue.shift()); + this.resolve = null; + } + return promise; + } + } + const inbox = {}; + + window.onmessage = function (message) { + const id = message.data.id; + const payload = message.data.payload; + inbox[id] = inbox[id] || new Inbox(); + inbox[id].push(payload); + } + return function (id) { + inbox[id] = inbox[id] || new Inbox(); + return inbox[id].pop(); + } +})(); + +function getMainWindow() { + let main = window; + while (true) { + if (main === main.parent) { + if (!main.opener) { + break; + } else { + main = main.opener; + } + } else { + main = main.parent; + } + } + return main; +} + +function isSameOrigin(other) { + try { + other.descendants; + } catch (e) { + // Cross-origin iframe that cannot access the main frame. + return false; + } + return !!other.descendants; +} + +function getId() { + const params = new URLSearchParams(document.location.search); + return params.get('id'); +} + +function getParent() { + if (window.parent == window && window.opener) { + return window.opener; + } + return window.parent; +} + +// Constructs iframes based on their descriptoin. +async function build(children) { + window.descendants = {iframes: {}, windows: {}}; + await Promise.all(children.map(buildChild)); + const result = window.descendants; + return result; +} + +async function buildChild(params) { + let child = null; + function target() { + return params.window_open ? child : child.contentWindow; + } + if (params.window_open) { + child = window.open(url(params)); + if (!params.id.startsWith('same-origin')) { + // Cross-origin windows gets their own browsing context groups with COOP. + // The postMessage calls before would not work for them, so we do not + // wait for them to load. + return; + } + } else { + child = document.createElement('iframe'); + child.src = url(params); + child.id = params.id; + document.body.appendChild(child); + } + const ready = await waitForMessage(params.id); + target().postMessage({id: 'parent', payload: params.children}, '*'); + const done = await waitForMessage(params.id); + if (!params.window_open) { + const main = getMainWindow(); + if (isSameOrigin(main)) { + main.descendants.iframes[params.id] = child; + } + } +} + +// This function runs within an iframe. +// It gets the children descriptions from the parent and constructs them. +async function setupChild() { + const id = getId(); + const main = getMainWindow(); + if (isSameOrigin(main)) { + main.descendants.windows[id] = window; + } + document.getElementById('title').textContent = id; + getParent().postMessage({id : id, payload: 'ready'}, '*'); + const children = await waitForMessage('parent'); + if (children) { + await Promise.all(children.map(buildChild)); + } + getParent().postMessage({id: id, payload: 'done'}, '*'); +} + +function sameOriginContexts(children) { + const result = []; + for (const [id, child] of Object.entries(children)) { + if (id.includes('same-origin')) { + result.push(child.contentWindow + ? child.contentWindow.performance : child.performance); + } + } + return result; +} + +async function createWorker(bytes) { + const worker = new Worker('resources/worker.js'); + let resolve_promise; + const promise = new Promise(resolve => resolve_promise = resolve); + worker.onmessage = function (message) { + resolve_promise(message.data); + } + worker.postMessage({bytes}); + return promise; +}
\ No newline at end of file |