tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

client-url-creation-url-iframe.html (3547B)


      1 <!DOCTYPE html>
      2 <title>Service Worker: Client.url is Window creation URL iframe resource</title>
      3 <script>
      4 // This is the iframe resource for the Client.url Window creation URL test.
      5 // It supports the test page telling it to navigate in various ways, and then
      6 // the iframe will post back that its done.
      7 
      8 // Turn the next time an event is raised into a promise.
      9 function wait_for_next_event(event_target, event_name) {
     10  return new Promise(resolve => {
     11    const event_handler = event => {
     12      event_target.removeEventListener(event_name, event_handler);
     13      resolve(event);
     14    };
     15    event_target.addEventListener(event_name, event_handler);
     16  });
     17 }
     18 
     19 // Perform the navigation step sent to the iframe by the test page.
     20 async function perform_navigation(navigation_kind) {
     21  // This is true if the navigation results in a new document instance.
     22  // For example, history.pushState() doesn't create a new document, but
     23  // navigating to a URL with a different query does. We need to keep
     24  // track of this so we can post a message back to the test page when the
     25  // navigation completes without loading a new document.
     26  let cross_document_navigation = false;
     27 
     28  const query_params = new URLSearchParams(location.search.substring(1));
     29  const step = parseInt(query_params.get('step'), 10);
     30 
     31  const next_url = `?step=${step + 1}`;
     32 
     33  if (navigation_kind === 'pushstate') {
     34    history.pushState({}, '', next_url);
     35  } else if (navigation_kind === 'replacestate') {
     36    history.replaceState({}, '', next_url);
     37  } else if (navigation_kind === 'back-within-same-document') {
     38    history.back();
     39  } else if (navigation_kind === 'fragment') {
     40    location.href = '#fragment';
     41    await wait_for_next_event(window, 'hashchange');
     42  } else if (navigation_kind === 'back-cross-document') {
     43    // Note there are two back navigation_kinds. Both call history.back(),
     44    // but 'back-cross-document' is for when we go back to a different
     45    // document instance and the new document will postMessage the parent
     46    // that the navigation is done, and and 'back-within-same-document' is for
     47    // when we go back but remain in the same document and so need to
     48    // postMessage the parent that the navigation is done from this document.
     49    history.back();
     50    cross_document_navigation = true;
     51  } else if (navigation_kind === 'query') {
     52    location.href = next_url;
     53    cross_document_navigation = true;
     54  } else if (navigation_kind === 'reload') {
     55    location.reload();
     56    cross_document_navigation = true;
     57  } else {
     58    throw new Error('Unknown navigation kind: ' + navigation_kind);
     59  }
     60  return cross_document_navigation;
     61 }
     62 
     63 window.addEventListener('message', async message_event => {
     64  try {
     65    const navigation_kind = message_event.data;
     66 
     67    // If its a cross document navigation, then we need to send the done
     68    // message back to the test page when the navigation has started the
     69    // new document.
     70    const cross_document_navigation = await perform_navigation(navigation_kind);
     71    if (!cross_document_navigation ) {
     72      window.parent.postMessage('done');
     73    }
     74  } catch (error) {
     75    window.parent.postMessage('error: ' + error.message);
     76  }
     77 });
     78 
     79 // Navigation steps either result in a new document instance or not. The
     80 // iframe needs to post a message back to the test page when the navigation
     81 // completes regardless. If the navigation does create a new document, then
     82 // the following postMessage informs the test page that the cross document
     83 // navigation has completed.
     84 window.parent.postMessage('done');
     85 </script>