summaryrefslogtreecommitdiffstats
path: root/dom/animation/test/mozilla/test_pending_animation_tracker.html
blob: 022efa7bcfa3c485b378b4aae96983b2ca778bc1 (plain)
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
<!doctype html>
<head>
<meta charset=utf-8>
<title>Test animations in PendingAnimationTracker</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../testcommon.js"></script>
</head>
<body>
<div id="log"></div>
<script>
"use strict";

promise_test(function waitForLoad() {
  return new Promise(resolve => {
    window.addEventListener("load", resolve, { once: true });
  });
});

promise_test(async t => {
  // See below, but we should ensure we are in a rAF callback before proceeding
  // or else we will get inconsistent results.
  await waitForNextFrame();

  const target = addDiv(t);
  const anim = target.animate(null, 100 * MS_PER_SEC);
  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be tracked by tracker');

  anim.effect = null;
  await waitForNextFrame();

  assert_false(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
               'The animation should NOT be tracked by the tracker');
}, 'An animation whose effect is made null while pending is subsequently'
   + ' removed from the tracker');

test(t => {
  const target = addDiv(t);
  const anim = target.animate(null, 100 * MS_PER_SEC);
  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be tracked by tracker');

  const newEffect = new KeyframeEffect(target, null);
  anim.effect = newEffect;

  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be still tracked by tracker');
}, 'Setting another effect keeps the pending animation in the tracker');

test(t => {
  const effect = new KeyframeEffect(null, null);
  const anim = new Animation(effect);
  anim.play();
  assert_false(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
               'The orphaned animation should NOT be tracked by tracker');

  const target = addDiv(t);
  const newEffect = new KeyframeEffect(target, null);
  anim.effect = newEffect;

  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be now tracked by tracker');
}, 'Setting effect having target element starts being tracked by the ' +
   'tracker');

test(t => {
  const target = addDiv(t);
  const anim = target.animate(null, 100 * MS_PER_SEC);
  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be tracked by tracker');

  anim.cancel();

  assert_false(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
               'The animation should NOT be tracked by the tracker');
}, 'Calling cancel() removes the animation from the tracker');

promise_test(async t => {
  // Before proceeding this test, make sure following code is _NOT_ processed
  // between paint and refresh driver's tick.  Otherwise, waitForNextFrame below
  // doesn't ensure that a paint process happens which means that there is
  // no chance to call TriggerPendingAnimationsOnNextTick to discard the
  // animation from the pending animation tracker.
  await waitForNextFrame();

  const target = addDiv(t);
  const anim = target.animate(null, 100 * MS_PER_SEC);

  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be tracked by tracker');

  target.remove();

  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation is still being tracked by the tracker');

  await waitForNextFrame();
  assert_false(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
               'The animation should NOT be tracked by the tracker in the ' +
               'next frame');
}, 'Removing target element from the document removes the animation from ' +
   'the tracker in the next tick');

test(t => {
  const target = addDiv(t);
  const anotherTarget = addDiv(t);
  const anim = target.animate(null, 100 * MS_PER_SEC);
  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be tracked by tracker');

  anim.effect.target = anotherTarget;

  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be still tracked by tracker');
}, 'Setting another target keeps the pending animation in the tracker');

test(t => {
  const effect = new KeyframeEffect(null, null);
  const anim = new Animation(effect);
  anim.play();
  assert_false(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
               'The orphaned animation should NOT be tracked by tracker');

  const target = addDiv(t);
  anim.effect.target = target;

  assert_true(SpecialPowers.DOMWindowUtils.isAnimationInPendingTracker(anim),
              'The animation should be now tracked by tracker');
}, 'Setting target element to the orphaned animation starts being tracked ' +
   'by the tracker');

</script>
</body>