summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/service-workers/service-worker/resources/partitioned-utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/service-workers/service-worker/resources/partitioned-utils.js')
-rw-r--r--testing/web-platform/tests/service-workers/service-worker/resources/partitioned-utils.js110
1 files changed, 110 insertions, 0 deletions
diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/partitioned-utils.js b/testing/web-platform/tests/service-workers/service-worker/resources/partitioned-utils.js
new file mode 100644
index 0000000000..22e90beaec
--- /dev/null
+++ b/testing/web-platform/tests/service-workers/service-worker/resources/partitioned-utils.js
@@ -0,0 +1,110 @@
+// The resolve function for the current pending event listener's promise.
+// It is nulled once the promise is resolved.
+var message_event_promise_resolve = null;
+
+function messageEventHandler(evt) {
+ if (message_event_promise_resolve) {
+ local_resolve = message_event_promise_resolve;
+ message_event_promise_resolve = null;
+ local_resolve(evt.data);
+ }
+}
+
+function makeMessagePromise() {
+ if (message_event_promise_resolve != null) {
+ // Do not create a new promise until the previous is settled.
+ return;
+ }
+
+ return new Promise(resolve => {
+ message_event_promise_resolve = resolve;
+ });
+}
+
+// Loads a url for the frame type and then returns a promise for
+// the data that was postMessage'd from the loaded frame.
+// If the frame type is 'window' then `url` is encoded into the search param
+// as the url the 3p window is meant to iframe.
+function loadAndReturnSwData(t, url, frame_type) {
+ if (frame_type !== 'iframe' && frame_type !== 'window') {
+ return;
+ }
+
+ const message_promise = makeMessagePromise();
+
+ // Create the iframe or window and then return the promise for data.
+ if ( frame_type === 'iframe' ) {
+ const frame = with_iframe(url, false);
+ t.add_cleanup(async () => {
+ const f = await frame;
+ f.remove();
+ });
+ }
+ else {
+ // 'window' case.
+ const search_param = new URLSearchParams();
+ search_param.append('target', url);
+
+ const third_party_window_url = new URL(
+ './resources/partitioned-service-worker-third-party-window.html' +
+ '?' + search_param,
+ get_host_info().HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);
+
+ const w = window.open(third_party_window_url);
+ t.add_cleanup(() => w.close());
+ }
+
+ return message_promise;
+}
+
+// Checks for an existing service worker registration. If not present,
+// registers and maintains a service worker. Used in windows or iframes
+// that will be partitioned from the main frame.
+async function setupServiceWorker() {
+
+ const script = './partitioned-storage-sw.js';
+ const scope = './partitioned-';
+
+ var reg = await navigator.serviceWorker.register(script, { scope: scope });
+
+ // We should keep track if we installed a worker or not. If we did then we
+ // need to uninstall it. Otherwise we let the top level test uninstall it
+ // (If partitioning is not working).
+ var installed_a_worker = true;
+ await new Promise(resolve => {
+ // Check if a worker is already activated.
+ var worker = reg.active;
+ // If so, just resolve.
+ if ( worker ) {
+ installed_a_worker = false;
+ resolve();
+ return;
+ }
+
+ //Otherwise check if one is waiting.
+ worker = reg.waiting;
+ // If not waiting, grab the installing worker.
+ if ( !worker ) {
+ worker = reg.installing;
+ }
+
+ // Resolve once it's activated.
+ worker.addEventListener('statechange', evt => {
+ if (worker.state === 'activated') {
+ resolve();
+ }
+ });
+ });
+
+ self.addEventListener('unload', async () => {
+ // If we didn't install a worker then that means the top level test did, and
+ // that test is therefore responsible for cleaning it up.
+ if ( !installed_a_worker ) {
+ return;
+ }
+
+ await reg.unregister();
+ });
+
+ return reg;
+} \ No newline at end of file