summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/measure-memory/resources/common.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/measure-memory/resources/common.js
parentInitial commit. (diff)
downloadfirefox-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.js178
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