File: child-document-raf-order.html

package info (click to toggle)
thunderbird 1%3A143.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 4,703,968 kB
  • sloc: cpp: 7,770,492; javascript: 5,943,842; ansic: 3,918,754; python: 1,418,263; xml: 653,354; asm: 474,045; java: 183,079; sh: 111,238; makefile: 20,410; perl: 14,359; objc: 13,059; yacc: 4,583; pascal: 3,405; lex: 1,720; ruby: 999; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 69; csh: 10
file content (140 lines) | stat: -rw-r--r-- 4,609 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<!DOCTYPE HTML>
<meta charset=UTF-8>
<title>Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Mozilla" href="https://mozilla.org/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<div id=log></div>

<!--

This test tests the interaction of just two substeps of the "Update the
rendering" steps in
https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering

These are:

 1. Let docs be the list of Document objects associated with the event
    loop in question, sorted arbitrarily except that the following
    conditions must be met:

    - Any Document B that is nested through a Document A must be listed
      after A in the list.

    - If there are two documents A and B whose browsing contexts are
      both nested browsing contexts and their browsing context
      containers are both elements in the same Document C, then the
      order of A and B in the list must match the relative tree order of
      their respective browsing context containers in C.

    In the steps below that iterate over docs, each Document must be
    processed in the order it is found in the list.

and later:

10. For each fully active Document in docs, run the animation frame
    callbacks for that Document, passing in now as the timestamp.


It tests this by setting up a tree of three documents, two children and
one parent, and testing for the relative order of the animation frame
callbacks for each.

-->

<script>

// Split array into chunks of len.
function chunk (arr, len) {
  var chunks = [],
    i = 0,
    n = arr.length;
  while (i < n) {
    chunks.push(arr.slice(i, i += len));
  }
  return chunks;
}

async_test(function (t) {
  step_timeout(setup, 0);

  let first_frame, second_frame;

  let notification_sequence = [];

  function setup() {
    // Start by creating two iframes.  To test (a little bit) the rule
    // about iteration being in document order, insert them in the reverse
    // order of creation.
    let body = document.body;
    function make_iframe() {
      let iframe = document.createElement("iframe");
      iframe.setAttribute("srcdoc", "<body onload='parent.child_ready()'>");
      iframe.setAttribute("width", "30");
      iframe.setAttribute("height", "15");
      return iframe;
    }
    second_frame = make_iframe();
    body.prepend(second_frame);
    first_frame = make_iframe();
    body.prepend(first_frame);

    let children_waiting = 2;
    window.child_ready = function() {
      if (--children_waiting == 0) {
        // Call requestAnimationFrame in neither the order nor the reverse
        // of the order in which we expect to be called (which is parent,
        // first, second).
        first_frame.contentWindow.requestAnimationFrame(first_child_raf);
        second_frame.contentWindow.requestAnimationFrame(second_child_raf);
        window.requestAnimationFrame(parent_raf);
      }
    };
  }

  let parent_raf = t.step_func(function() {
    notification_sequence.push("parent_raf");

    // Request another notification to help ensure we're getting expected behavior.
    window.requestAnimationFrame(parent_raf);
  });

  let first_child_raf = t.step_func(function() {
    notification_sequence.push("first_child_raf");

    // Request another notification to help ensure we're getting expected behavior.
    first_frame.contentWindow.requestAnimationFrame(first_child_raf);
  });

  let second_child_raf = t.step_func(function() {
    notification_sequence.push("second_child_raf");

    // Request another notification to help ensure we're getting expected behavior.
    second_frame.contentWindow.requestAnimationFrame(second_child_raf);

    step_timeout(finish, 0);
  });

  let finish = t.step_func(function() {

    // The test requests rafs recursively,
    // but since all three rafs run as part of the same "update the rendering" task,
    // they should always come in a triplet.
    assert_equals(notification_sequence.length % 3, 0);

    let chunks = chunk(notification_sequence, 3);
    for (var i = 0; i < chunks.length; i++) {
      // Assert correct ordering per triplet of rafs.
      assert_array_equals(chunks[i],
                          ["parent_raf", "first_child_raf", "second_child_raf"],
                          "expected order of notifications");
    }

    t.done();
  });
});

</script>