tor-browser

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

animation-trigger-addAnimation.tentative.html (6253B)


      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      .subject, .target {
     14        height: 50px;
     15        width: 50px;
     16        background-color: red;
     17      }
     18      .scroller {
     19        overflow-y: scroll;
     20        height: 500px;
     21        width: 500px;
     22        border: solid 1px;
     23        position: relative;
     24      }
     25      #space {
     26        width: 50px;
     27        height: 600px;
     28      }
     29    </style>
     30    <div id="wrapper">
     31      <div id="scroller" class="scroller">
     32        <div id="space"></div>
     33        <div id="subject" class="subject"></div>
     34        <div id="space"></div>
     35      </div>
     36      <div id="target" class="target"></div>
     37    </div>
     38    <script>
     39      // The trigger and exit ranges are the same for this test.
     40      const TRIGGER_START_PX = 150;
     41      const TRIGGER_END_PX = 200;
     42      const scroller = document.getElementById("scroller");
     43      const target = document.getElementById("target");
     44      const COVER_START_OFFSET = 100;
     45      const rangeBoundaries = getRangeBoundariesForTest(
     46                                    COVER_START_OFFSET + TRIGGER_START_PX,
     47                                    COVER_START_OFFSET + TRIGGER_END_PX,
     48                                    COVER_START_OFFSET + TRIGGER_START_PX,
     49                                    COVER_START_OFFSET + TRIGGER_END_PX,
     50                                    scroller);
     51      const ANIMATION_DURATION_MS = 1;
     52      const view_timeline = new ViewTimeline({ subject: subject });
     53      function setupAnimation() {
     54        const animation = new Animation(
     55          new KeyframeEffect(
     56            target,
     57            [
     58              { transform: "scaleX(1)", backgroundColor: "pink", left: "0px" },
     59              { transform: "scaleX(5)", backgroundColor: "pink", left: "10px" }
     60            ],
     61            { duration: ANIMATION_DURATION_MS, fill: "both" }
     62          ));
     63        return animation;
     64      }
     65      function setupAnimationTrigger(use_default_trigger=false) {
     66        const trigger = use_default_trigger ? new TimelineTrigger()
     67            : new TimelineTrigger({
     68              timeline: view_timeline,
     69              rangeStart: `${TRIGGER_START_PX}px`,
     70              rangeEnd: `${TRIGGER_END_PX}px`
     71            });
     72        return trigger;
     73      }
     74 
     75      promise_test(async (test) => {
     76        const animation = setupAnimation();
     77        const trigger = setupAnimationTrigger(/*use_default_trigger=*/true);
     78        assert_array_equals(trigger.getAnimations(), [],
     79          "trigger has no animations");
     80 
     81        // As the default trigger is always  in the tripped state, the animation
     82        // should be played right away.
     83        trigger.addAnimation(animation, "play-forwards", "play-backwards");
     84        await animation.finished;
     85 
     86        assert_times_equal(animation.currentTime, ANIMATION_DURATION_MS,
     87          "animation finish reflected in currentTime");
     88        assert_equals(animation.playState, "finished",
     89          "animation finish reflected in playeState");
     90        assert_array_equals(trigger.getAnimations(), [animation],
     91          "trigger has animation attached");
     92      }, "Animation attached to tripped (default) trigger plays.");
     93 
     94      promise_test(async (test) => {
     95        const animation = setupAnimation();
     96        const trigger = setupAnimationTrigger();
     97 
     98        assert_equals(animation.playState, "idle", "animation is idle");
     99        assert_equals(animation.currentTime, null, "currentTime is null");
    100        assert_array_equals(trigger.getAnimations(), [],
    101          "trigger has no animations");
    102 
    103        assert_equals(scroller.scrollTop, 0, "scroller is not scrolled, i.e. " +
    104          "not within the trigger range");
    105 
    106        trigger.addAnimation(animation, "play-forwards", "play-backwards");
    107 
    108        await waitForAnimationFrames(2);
    109 
    110        assert_equals(animation.playState, "paused",
    111          "animation is paused, awaiting trigger event");
    112        assert_times_equal(animation.currentTime, 0, "currentTime is 0");
    113 
    114        // Entering the trigger range should play the animation.
    115        rangeBoundaries.enterTriggerRange();
    116        await animation.finished;
    117 
    118        assert_equals(animation.playState, "finished",
    119          "animation is paused, awaiting trigger event");
    120        assert_times_equal(animation.currentTime, ANIMATION_DURATION_MS,
    121          "currentTime is 0");
    122        assert_array_equals(trigger.getAnimations(), [animation],
    123          "trigger has animation attached");
    124      }, "Animation attached to untripped trigger is paused at the beginning.");
    125 
    126      promise_test(async (test) => {
    127        await waitForScrollReset(test, scroller);
    128 
    129        assert_equals(scroller.scrollTop, 0, "scroller is not scrolled, i.e. " +
    130          "not within the trigger range");
    131 
    132        const animation = setupAnimation();
    133        const trigger = setupAnimationTrigger();
    134 
    135        assert_equals(animation.playState, "idle", "animation is idle");
    136        assert_equals(animation.currentTime, null, "currentTime is null");
    137        assert_array_equals(trigger.getAnimations(), [],
    138          "trigger has no animations");
    139 
    140        rangeBoundaries.enterTriggerRange();
    141        await waitForAnimationFrames(2);
    142 
    143        assert_equals(animation.playState, "idle", "animation is still idle");
    144        assert_equals(animation.currentTime, null, "currentTime is still null");
    145 
    146        trigger.addAnimation(animation, "play-forwards", "play-backwards");
    147        await animation.finished;
    148 
    149        assert_equals(animation.playState, "finished",
    150          "animation is paused, awaiting trigger event");
    151        assert_times_equal(animation.currentTime, ANIMATION_DURATION_MS,
    152          `currentTime is ${ANIMATION_DURATION_MS}`);
    153        assert_array_equals(trigger.getAnimations(), [animation],
    154          "trigger has animation attached");
    155      }, "Animation attached to tripped trigger is played immediately.");
    156    </script>
    157  </body>
    158 </html>