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