tor-browser

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

child-document-raf-order.html (4609B)


      1 <!DOCTYPE HTML>
      2 <meta charset=UTF-8>
      3 <title>Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order</title>
      4 <link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">
      5 <link rel="author" title="L. David Baron" href="https://dbaron.org/">
      6 <link rel="author" title="Mozilla" href="https://mozilla.org/">
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 
     10 <div id=log></div>
     11 
     12 <!--
     13 
     14 This test tests the interaction of just two substeps of the "Update the
     15 rendering" steps in
     16 https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering
     17 
     18 These are:
     19 
     20 1. Let docs be the list of Document objects associated with the event
     21    loop in question, sorted arbitrarily except that the following
     22    conditions must be met:
     23 
     24    - Any Document B that is nested through a Document A must be listed
     25      after A in the list.
     26 
     27    - If there are two documents A and B whose browsing contexts are
     28      both nested browsing contexts and their browsing context
     29      containers are both elements in the same Document C, then the
     30      order of A and B in the list must match the relative tree order of
     31      their respective browsing context containers in C.
     32 
     33    In the steps below that iterate over docs, each Document must be
     34    processed in the order it is found in the list.
     35 
     36 and later:
     37 
     38 10. For each fully active Document in docs, run the animation frame
     39    callbacks for that Document, passing in now as the timestamp.
     40 
     41 
     42 It tests this by setting up a tree of three documents, two children and
     43 one parent, and testing for the relative order of the animation frame
     44 callbacks for each.
     45 
     46 -->
     47 
     48 <script>
     49 
     50 // Split array into chunks of len.
     51 function chunk (arr, len) {
     52  var chunks = [],
     53    i = 0,
     54    n = arr.length;
     55  while (i < n) {
     56    chunks.push(arr.slice(i, i += len));
     57  }
     58  return chunks;
     59 }
     60 
     61 async_test(function (t) {
     62  step_timeout(setup, 0);
     63 
     64  let first_frame, second_frame;
     65 
     66  let notification_sequence = [];
     67 
     68  function setup() {
     69    // Start by creating two iframes.  To test (a little bit) the rule
     70    // about iteration being in document order, insert them in the reverse
     71    // order of creation.
     72    let body = document.body;
     73    function make_iframe() {
     74      let iframe = document.createElement("iframe");
     75      iframe.setAttribute("srcdoc", "<body onload='parent.child_ready()'>");
     76      iframe.setAttribute("width", "30");
     77      iframe.setAttribute("height", "15");
     78      return iframe;
     79    }
     80    second_frame = make_iframe();
     81    body.prepend(second_frame);
     82    first_frame = make_iframe();
     83    body.prepend(first_frame);
     84 
     85    let children_waiting = 2;
     86    window.child_ready = function() {
     87      if (--children_waiting == 0) {
     88        // Call requestAnimationFrame in neither the order nor the reverse
     89        // of the order in which we expect to be called (which is parent,
     90        // first, second).
     91        first_frame.contentWindow.requestAnimationFrame(first_child_raf);
     92        second_frame.contentWindow.requestAnimationFrame(second_child_raf);
     93        window.requestAnimationFrame(parent_raf);
     94      }
     95    };
     96  }
     97 
     98  let parent_raf = t.step_func(function() {
     99    notification_sequence.push("parent_raf");
    100 
    101    // Request another notification to help ensure we're getting expected behavior.
    102    window.requestAnimationFrame(parent_raf);
    103  });
    104 
    105  let first_child_raf = t.step_func(function() {
    106    notification_sequence.push("first_child_raf");
    107 
    108    // Request another notification to help ensure we're getting expected behavior.
    109    first_frame.contentWindow.requestAnimationFrame(first_child_raf);
    110  });
    111 
    112  let second_child_raf = t.step_func(function() {
    113    notification_sequence.push("second_child_raf");
    114 
    115    // Request another notification to help ensure we're getting expected behavior.
    116    second_frame.contentWindow.requestAnimationFrame(second_child_raf);
    117 
    118    step_timeout(finish, 0);
    119  });
    120 
    121  let finish = t.step_func(function() {
    122 
    123    // The test requests rafs recursively,
    124    // but since all three rafs run as part of the same "update the rendering" task,
    125    // they should always come in a triplet.
    126    assert_equals(notification_sequence.length % 3, 0);
    127 
    128    let chunks = chunk(notification_sequence, 3);
    129    for (var i = 0; i < chunks.length; i++) {
    130      // Assert correct ordering per triplet of rafs.
    131      assert_array_equals(chunks[i],
    132                          ["parent_raf", "first_child_raf", "second_child_raf"],
    133                          "expected order of notifications");
    134    }
    135 
    136    t.done();
    137  });
    138 });
    139 
    140 </script>