tor-browser

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

cancel-animation.html (7141B)


      1 <!DOCTYPE html>
      2 <meta charset=utf-8>
      3 <title>Canceling an animation</title>
      4 <link rel="help"
      5    href="https://drafts.csswg.org/web-animations/#canceling-an-animation-section">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="/web-animations/testcommon.js"></script>
      9 <script src="testcommon.js"></script>
     10 <style>
     11 .scroller {
     12  overflow: auto;
     13  height: 100px;
     14  width: 100px;
     15  will-change: transform;
     16 }
     17 
     18 .contents {
     19  height: 1000px;
     20  width: 100%;
     21 }
     22 </style>
     23 <body>
     24 <script>
     25 'use strict';
     26 
     27 promise_test(async t => {
     28  let animation;
     29  // Wait for new animation frame which allows the timeline to compute new
     30  // current time.
     31  await runAndWaitForFrameUpdate(() => {
     32    animation = createScrollLinkedAnimation(t);
     33  });
     34  animation.play();
     35  animation.cancel();
     36 
     37  assert_equals(animation.startTime, null,
     38                'The start time of a canceled animation should be unresolved');
     39  assert_equals(animation.currentTime, null,
     40                'The hold time of a canceled animation should be unresolved');
     41 }, 'Canceling an animation should cause its start time and hold time to be'
     42   + ' unresolved');
     43 
     44 promise_test(async t => {
     45  const animation = createScrollLinkedAnimation(t);
     46  // Wait for new animation frame which allows the timeline to compute new
     47  // current time.
     48  await waitForNextFrame();
     49  animation.play();
     50  const retPromise = animation.ready.then(() => {
     51    assert_unreached('ready promise was fulfilled');
     52  }).catch(err => {
     53    assert_equals(err.name, 'AbortError',
     54                  'ready promise is rejected with AbortError');
     55  });
     56 
     57  animation.cancel();
     58 
     59  return retPromise;
     60 }, 'A play-pending ready promise should be rejected when the animation is'
     61   + ' canceled');
     62 
     63 promise_test(async t => {
     64  const animation = createScrollLinkedAnimation(t);
     65  // Wait for new animation frame which allows the timeline to compute new
     66  // current time.
     67  await waitForNextFrame();
     68  animation.play();
     69  await animation.ready;
     70 
     71  // Make it pause-pending
     72  animation.pause();
     73 
     74  // We need to store the original ready promise since cancel() will
     75  // replace it
     76  const originalPromise = animation.ready;
     77  animation.cancel();
     78 
     79  await promise_rejects_dom(t, 'AbortError', originalPromise,
     80                            'Cancel should abort ready promise');
     81 }, 'A pause-pending ready promise should be rejected when the animation is'
     82   + ' canceled');
     83 
     84 promise_test(async t => {
     85  const animation = createScrollLinkedAnimation(t);
     86  // Wait for new animation frame which allows the timeline to compute new
     87  // current time.
     88  await waitForNextFrame();
     89  animation.play();
     90  animation.cancel();
     91  const promiseResult = await animation.ready;
     92  assert_equals(promiseResult, animation);
     93 }, 'When an animation is canceled, it should create a resolved Promise');
     94 
     95 promise_test(async t => {
     96  const animation = createScrollLinkedAnimation(t);
     97  // Wait for new animation frame which allows the timeline to compute new
     98  // current time.
     99  await waitForNextFrame();
    100  animation.play();
    101  const promise = animation.ready;
    102  animation.cancel();
    103  assert_not_equals(animation.ready, promise);
    104  promise_rejects_dom(t, 'AbortError', promise,
    105                      'Cancel should abort ready promise');
    106 }, 'The ready promise should be replaced when the animation is canceled');
    107 
    108 promise_test(async t => {
    109  const animation = createScrollLinkedAnimation(t);
    110  // Wait for new animation frame which allows the timeline to compute new
    111  // current time.
    112  await waitForNextFrame();
    113  assert_equals(animation.playState, 'idle',
    114                'The animation should be initially idle');
    115 
    116  animation.finished.then(t.step_func(() => {
    117    assert_unreached('Finished promise should not resolve');
    118  }), t.step_func(() => {
    119    assert_unreached('Finished promise should not reject');
    120  }));
    121 
    122  animation.cancel();
    123 
    124  return waitForAnimationFrames(3);
    125 }, 'The finished promise should NOT be rejected if the animation is already'
    126   + ' idle');
    127 
    128 promise_test(async t => {
    129  const animation = createScrollLinkedAnimation(t);
    130  // Wait for new animation frame which allows the timeline to compute new
    131  // current time.
    132  await waitForNextFrame();
    133  assert_equals(animation.playState, 'idle',
    134                'The animation should be initially idle');
    135 
    136  animation.oncancel = t.step_func(() => {
    137    assert_unreached('Cancel event should not be fired');
    138  });
    139 
    140  animation.cancel();
    141 
    142  return waitForAnimationFrames(3);
    143 }, 'The cancel event should NOT be fired if the animation is already idle');
    144 
    145 promise_test(async t => {
    146  const animation = createScrollLinkedAnimation(t);
    147  // Wait for new animation frame which allows the timeline to compute new
    148  // current time.
    149  await waitForNextFrame();
    150  animation.play();
    151  animation.effect.target.remove();
    152 
    153  const eventWatcher = new EventWatcher(t, animation, 'cancel');
    154 
    155  await animation.ready;
    156  animation.cancel();
    157 
    158  await eventWatcher.wait_for('cancel');
    159 
    160  assert_equals(animation.effect.target.parentNode, null,
    161      'cancel event should be fired for the animation on an orphaned element');
    162 }, 'Canceling an animation should fire cancel event on orphaned element');
    163 
    164 promise_test(async t => {
    165  const animation = createScrollLinkedAnimation(t);
    166  const scroller = animation.timeline.source;
    167 
    168  // Wait for new animation frame which allows the timeline to compute new
    169  // current time.
    170  await waitForNextFrame();
    171  animation.play();
    172  await animation.ready;
    173 
    174  // Make the scroll timeline inactive.
    175  await runAndWaitForFrameUpdate(() => {
    176    scroller.style.overflow = 'visible';
    177  });
    178  assert_equals(animation.timeline.currentTime, null,
    179                'Sanity check the timeline is inactive.');
    180  animation.cancel();
    181  assert_equals(animation.startTime, null,
    182                'The start time of a canceled animation should be unresolved');
    183  assert_equals(animation.currentTime, null,
    184              'The current time of a canceled animation should be unresolved');
    185 }, 'Canceling an animation with inactive timeline should cause its start time'
    186   + ' and hold time to be unresolved');
    187 
    188 promise_test(async t => {
    189  const animation = createScrollLinkedAnimation(t);
    190  const scroller = animation.timeline.source;
    191 
    192  // Wait for new animation frame which allows the timeline to compute new
    193  // current time.
    194  await waitForNextFrame();
    195  animation.play();
    196  await animation.ready;
    197 
    198  // Make the scroll timeline inactive.
    199  await runAndWaitForFrameUpdate(() => {
    200    scroller.style.overflow = 'visible';
    201  });
    202  assert_equals(animation.timeline.currentTime, null,
    203                'Sanity check the timeline is inactive.');
    204 
    205  const eventWatcher = new EventWatcher(t, animation, 'cancel');
    206  animation.cancel();
    207  const cancelEvent = await eventWatcher.wait_for('cancel');
    208 
    209  assert_equals(cancelEvent.currentTime, null,
    210      'event.currentTime should be unresolved when the timeline is inactive.');
    211  assert_equals(cancelEvent.timelineTime, null,
    212      'event.timelineTime should be unresolved when the timeline is inactive');
    213 }, 'oncancel event is fired when the timeline is inactive.');
    214 
    215 </script>
    216 </body>