tor-browser

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

subordinate-frame.sub.html (3933B)


      1 <!doctype html>
      2 <meta charset="utf-8">
      3 <html>
      4 <head>
      5 <!--- Allow injected scripts to use functions in fledge-util.sub.js --->
      6 <base href="..">
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testdriver.js"></script>
      9 <script src="/resources/testdriver-vendor.js"></script>
     10 <script src="/common/utils.js"></script>
     11 <script src="resources/fledge-util.sub.js"></script>
     12 </head>
     13 <body>
     14 <script>
     15 
     16  // This can be used for either iframes or top-level windows.
     17  // If there is an opener, this is a top-level window, so
     18  // send messages to the opener. Otherwise, this is an iframe,
     19  // so send messages to the parent.
     20  let message_dest = window.opener;
     21  if (!message_dest)
     22    message_dest = window.parent;
     23 
     24  // In order to use some WPT test fixture features in another frame
     25  // (particularly, testdriver), we need to set the test context for the test
     26  // driver. This is main window driving the test.
     27  //
     28  // To find that window, follow both parent and opener links to very end;
     29  // keeping in mind that top-level windows' parent fields loop back to
     30  // themselves.
     31  let main_test_window = window;
     32  while (true) {
     33    if (main_test_window.opener) {
     34      main_test_window = main_test_window.opener;
     35    } else if (main_test_window.parent !== main_test_window) {
     36      main_test_window = main_test_window.parent;
     37    } else {
     38      break;
     39    }
     40  }
     41 
     42  test_driver.set_test_context(main_test_window);
     43 
     44  // Fake Test class that only supports adding cleanup callbacks,
     45  // primarily to leave interest groups once the test is complete.
     46  function Test() {
     47    this.cleanup_callbacks = [];
     48  }
     49 
     50  // Registers a cleanup method with Test.
     51  Test.prototype.add_cleanup = function(callback) {
     52    this.cleanup_callbacks.push(callback);
     53  };
     54 
     55  // Runs all previously registered cleanup methods, waiting for
     56  // them all to complete.
     57  Test.prototype.do_cleanup = async function() {
     58    while (this.cleanup_callbacks.length > 0) {
     59      await this.cleanup_callbacks[0]();
     60      this.cleanup_callbacks = this.cleanup_callbacks.slice(1);
     61    }
     62  };
     63 
     64  // Create a bogus test instance that tracks cleanup callbacks. The
     65  // main frame managing the test is expected to post a message
     66  // to run test_instance.do_cleanup() and wait for it to complete
     67  // before destroying the frame.
     68  let test_instance = new Test();
     69 
     70  // Register a message event listener that listens for events with data
     71  // in the format {messageUuid: <uuid>, script: <script>}, and when such
     72  // a message is received, tries to eval the script and then returns a
     73  // message in the format:
     74  //   {messageUuid: <uuid>, result: <result>, returnValue: <returnValue>}
     75  //
     76  // On success, <result> is "success", while on failure, it's an error
     77  // message. <script> is interpreted as a possibly asynchronous function
     78  // body. Exceptions are caught and their stringified value is returned
     79  // as <result>. <returnValue> is a value returned to the caller of
     80  // the function that sent the message. It's up to the received script
     81  // to set it, if a return value is needed.
     82  //
     83  // "messageUuid" serves to allow the listener to make sure the message
     84  // is intended for it.
     85  window.addEventListener('message', async function(event) {
     86    // If not a message for this listener, do nothing.
     87    if (!event.data.messageUuid)
     88      return;
     89    let message = {result: 'unexpected'};
     90    try {
     91      let param = event.data.param;
     92      message = await eval(
     93          `(async () => {
     94            ${event.data.script};
     95            return {result: 'success'};
     96          })()`);
     97    } catch (e) {
     98      message.result = e.toString();
     99    }
    100    message.messageUuid = event.data.messageUuid;
    101 
    102    message_dest.postMessage(message, '*');
    103  });
    104 
    105  // Inform "message_dest" that the frame has finished loading.
    106  message_dest.postMessage(
    107      {messageUuid: '{{GET[uuid]}}', result: 'load complete'},
    108      '*');
    109 </script>
    110 </body>
    111 </html>