tor-browser

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

animation-trigger-disarmed-by-apis.tentative.html (5602B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <link rel="help" src="https://drafts.csswg.org/css-animations-2/#animation-trigger">
      5    <script src="/resources/testharness.js"></script>
      6    <script src="/resources/testharnessreport.js"></script>
      7    <script src="/web-animations/testcommon.js"></script>
      8    <script src="/dom/events/scrolling/scroll_support.js"></script>
      9    <script src="support/support.js"></script>
     10  </head>
     11  <body>
     12    <style>
     13      @keyframes myAnim {
     14        from { transform: scaleX(1); left: 0px }
     15        to { transform: scaleX(5); left: 10px }
     16      }
     17      .subject, .target {
     18        height: 50px;
     19        width: 50px;
     20        background-color: red;
     21      }
     22      .scroller {
     23        overflow-y: scroll;
     24        height: 500px;
     25        width: 500px;
     26        border: solid 1px;
     27        position: relative;
     28      }
     29      #space {
     30        width: 50px;
     31        height: 600px;
     32      }
     33    </style>
     34    <div id="wrapper">
     35      <div id="scroller" class="scroller">
     36        <div id="space"></div>
     37        <div id="subject" class="subject"></div>
     38        <div id="space"></div>
     39      </div>
     40      <div id="target" class="target"></div>
     41    </div>
     42    <script>
     43      // The trigger and exit ranges are the same for this test.
     44      const TRIGGER_START_PX = 150;
     45      const TRIGGER_END_PX = 200;
     46 
     47      const scroller = document.getElementById("scroller");
     48      const target = document.getElementById("target");
     49 
     50      const COVER_START_OFFSET = 100;
     51      const rangeBoundaries = getRangeBoundariesForTest(
     52                                    COVER_START_OFFSET + TRIGGER_START_PX,
     53                                    COVER_START_OFFSET + TRIGGER_END_PX,
     54                                    COVER_START_OFFSET + TRIGGER_START_PX,
     55                                    COVER_START_OFFSET + TRIGGER_END_PX,
     56                                    scroller);
     57 
     58      const ANIMATION_DURATION_MS = 1;
     59 
     60      function watchAnimationStatus(animation, targetCurrentTime,
     61          targetPlayState, resolve, repeat=2) {
     62        if (repeat <= 0) {
     63          resolve();
     64          return;
     65        }
     66        if (targetCurrentTime === null) {
     67          assert_equals(animation.currentTime, targetCurrentTime,
     68            "currentTime has not changed.");
     69        } else {
     70          assert_times_equal(animation.currentTime, targetCurrentTime, 1,
     71            "currentTime has not changed.");
     72        }
     73        assert_equals(animation.playState, targetPlayState,
     74          "playState has not changed.");
     75        requestAnimationFrame(() => {
     76          watchAnimationStatus(animation, targetCurrentTime, targetPlayState,
     77            resolve, repeat - 1);
     78        });
     79      }
     80 
     81      const view_timeline = new ViewTimeline({ subject: subject });
     82      function setupAnimation() {
     83        const animation = new Animation(
     84          new KeyframeEffect(
     85            target,
     86            [
     87              { transform: "scaleX(1)", backgroundColor: "pink", left: "0px" },
     88              { transform: "scaleX(5)", backgroundColor: "pink", left: "10px" }
     89            ],
     90            { duration: ANIMATION_DURATION_MS, fill: "both" }
     91          ));
     92        return animation;
     93      }
     94      function setupAnimationTrigger(use_default_trigger=false) {
     95        const trigger = new TimelineTrigger({
     96              timeline: view_timeline,
     97              rangeStart: `${TRIGGER_START_PX}px`,
     98              rangeEnd: `${TRIGGER_END_PX}px`
     99            });
    100        return trigger;
    101      }
    102 
    103      promise_test(async(test) => {
    104        const animation = setupAnimation();
    105        const trigger = setupAnimationTrigger();
    106 
    107        assert_equals(animation.currentTime, null,
    108            "animation is idle; null currentTime.");
    109        assert_equals(animation.playState, "idle", "animation is idle.");
    110        assert_array_equals(trigger.getAnimations(), [],
    111          "trigger has no animations");
    112 
    113        // Attaching the trigger should simply keep the animaiton paused at
    114        // zero currentTime.
    115        trigger.addAnimation(animation, "play-forwards", "play-backwards");
    116        await waitForNextFrame();
    117        assert_times_equal(animation.currentTime, 0,
    118            "animation is paused at currentTime zero.");
    119        assert_equals(animation.playState, "paused", "animation is paused.");
    120        assert_array_equals(trigger.getAnimations(), [animation],
    121          "trigger has the animation attached");
    122 
    123        // First, verify that the trigger is indeed active.
    124        await rangeBoundaries.enterTriggerRange();
    125        await animation.finished;
    126 
    127        assert_times_equal(animation.currentTime, ANIMATION_DURATION_MS,
    128          "animation finished (currentTime)");
    129        assert_equals(animation.playState, "finished",
    130          "animation finished (playState)");
    131        assert_array_equals(trigger.getAnimations(), [animation],
    132          "trigger has the animation attached");
    133 
    134        animation.cancel();
    135 
    136        assert_array_equals(trigger.getAnimations(), [],
    137          "trigger has no animations as the animation was cancelled");
    138 
    139        // Ensure exiting does nothing.
    140        status_promise = new Promise(resolve => {
    141          watchAnimationStatus(animation, null, "idle", resolve);
    142        });
    143        await rangeBoundaries.exitExitRangeAbove();
    144        await status_promise;
    145 
    146        // Ensure re-entering does nothing.
    147        status_promise = new Promise(resolve => {
    148          watchAnimationStatus(animation, null, "idle", resolve);
    149        });
    150        await rangeBoundaries.enterTriggerRange();
    151        await status_promise;
    152 
    153      }, "cancel disables animation trigger");
    154    </script>
    155  </body>
    156 </html>