tor-browser

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

animation-event-destroy-renderer.html (2927B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4  <title>Destroy and Hide Element in Animation Event</title>
      5  <!-- Note: this is effectively a crashtest, but as crashtests do not
      6       support variants, authoring as a promise test -->
      7  <meta name="variant" content="?animationstart">
      8  <meta name="variant" content="?animationiteration">
      9  <link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=22635">
     10  <style>
     11    .box {
     12      height: 100px;
     13      width: 100px;
     14      margin: 10px;
     15      background-color: blue;
     16      /* Use a long duration and delay for precise control over when animation
     17         events are triggered. With short animations, the animation-iteration
     18         event could be dropped if the animation finishes too son. An
     19         animation-iteration event does not fire when completing the last
     20         iteration.
     21      */
     22      animation-name: move;
     23      animation-duration: 10000s;
     24      animation-delay: 5000s;
     25      animation-iteration-count: 2;
     26    }
     27 
     28    @keyframes move {
     29      from { transform: translate(0px, 0px); }
     30      to { transform: translate(100px, 0px); }
     31    }
     32  </style>
     33  <div id="container">
     34    <div id="box1" class="box"></div>
     35    <div id="box2" class="box"></div>
     36  </div>
     37  <script src="/resources/testharness.js"></script>
     38  <script src="/resources/testharnessreport.js"></script>
     39  <script src="/common/gc.js"></script>
     40  <script>
     41  'use strict';
     42 
     43  function eventPromise(target, event, callback) {
     44    return new Promise(resolve => {
     45      const listener = () => {
     46        callback();
     47        resolve();
     48      };
     49      target.addEventListener(event, listener,
     50                              { once: true });
     51    });
     52  }
     53 
     54  function setAnimationTime(time) {
     55    document.getAnimations().forEach(a => a.currentTime = time);
     56  }
     57 
     58  promise_test(async t => {
     59    const eventType = location.search.substring(1);
     60    var box1 = document.getElementById('box1');
     61    var box2 = document.getElementById('box2');
     62 
     63    const promises = [];
     64    promises.push(eventPromise(box1, eventType, () => {
     65      box1.parentNode.removeChild(box1);
     66    }));
     67    promises.push(eventPromise(box2, eventType, () => {
     68      box2.style.display = 'none';
     69    }));
     70 
     71    await Promise.all(document.getAnimations().map(a => a.ready));
     72 
     73    promises.push(new Promise(resolve => {
     74      requestAnimationFrame(() => {
     75        // trip animationstart.
     76        setAnimationTime(6000000);
     77        requestAnimationFrame(() => {
     78          // trip animationiteration on any animations that are still running.
     79          setAnimationTime(16000000);
     80          resolve();
     81        });
     82      });
     83    }));
     84 
     85    await Promise.all(promises);
     86 
     87    // Garbage collection is best effort.
     88    if (window.garbageCollect) {
     89      await garbageCollect();
     90    }
     91 
     92    assert_equals(document.getAnimations().length, 0);
     93  }, 'Triggering the cancel of an animation during event handling does not ' +
     94     'crash.');
     95 
     96  </script>
     97 </head>
     98 </html>