tor-browser

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

CSSTransition-effect.tentative.html (7355B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>CSSTransition.effect</title>
      4 <!-- TODO: Add a more specific link for this once it is specified. -->
      5 <link rel="help" href="https://drafts.csswg.org/css-transitions-2/#csstransition">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src='support/helper.js'></script>
      9 <div id="log"></div>
     10 <script>
     11 'use strict';
     12 
     13 function singleFrame() {
     14  return new Promise((resolve, reject) => {
     15    requestAnimationFrame(resolve);
     16  });
     17 }
     18 
     19 test(t => {
     20  const div = addDiv(t);
     21  div.style.left = '0px';
     22 
     23  div.style.transition = 'left 100s';
     24  getComputedStyle(div).left;
     25  div.style.left = '100px';
     26 
     27  const transition = div.getAnimations()[0];
     28 
     29  transition.effect = null;
     30 
     31  assert_equals(transition.transitionProperty, 'left');
     32 }, 'After setting a transition\'s effect to null, it still reports the'
     33   + ' original transition property');
     34 
     35 promise_test(async t => {
     36  const div = addDiv(t);
     37  div.style.left = '0px';
     38 
     39  div.style.transition = 'left 100s';
     40  getComputedStyle(div).left;
     41  div.style.left = '100px';
     42 
     43  const transition = div.getAnimations()[0];
     44  await transition.ready;
     45 
     46  transition.effect = null;
     47  assert_equals(transition.playState, 'finished');
     48 }, 'After setting a transition\'s effect to null, it becomes finished');
     49 
     50 promise_test(async t => {
     51  const div = addDiv(t);
     52  div.style.left = '0px';
     53 
     54  div.style.transition = 'left 100s';
     55  getComputedStyle(div).left;
     56  div.style.left = '100px';
     57 
     58  const transition = div.getAnimations()[0];
     59  await transition.ready;
     60 
     61  transition.effect = null;
     62  assert_equals(getComputedStyle(div).left, '100px');
     63 }, 'After setting a transition\'s effect to null, style is updated');
     64 
     65 // This is a regression test for https://crbug.com/964113, where Chromium would
     66 // crash if the running transition's effect was set to null and a new transition
     67 // was started before the running one could finish.
     68 promise_test(async t => {
     69  const div = addDiv(t);
     70  div.style.left = '0px';
     71 
     72  div.style.transition = 'left 100s';
     73  getComputedStyle(div).left;
     74  div.style.left = '100px';
     75 
     76  assert_equals(div.getAnimations().length, 1);
     77 
     78  const transition = div.getAnimations()[0];
     79  await transition.ready;
     80 
     81  // Without yielding to the rendering loop, set the current transition's
     82  // effect to null and start a new transition. This should work correctly.
     83  transition.effect = null;
     84 
     85  div.style.left = '150px';
     86 
     87  // This will run style update.
     88  const animations = div.getAnimations();
     89  assert_equals(animations.length, 1);
     90 
     91  const new_transition = animations[0];
     92  await new_transition.ready;
     93 
     94  assert_not_equals(getComputedStyle(div).left, '150px');
     95 }, 'After setting a transition\'s effect to null, a new transition can be started');
     96 
     97 // This is a regression test for https://crbug.com/992668, where Chromium would
     98 // crash if the running transition's effect was set to null and the transition
     99 // was interrupted before it could finish due to the null effect.
    100 promise_test(async t => {
    101  const div = addDiv(t);
    102  div.style.left = '0px';
    103 
    104  div.style.transition = 'left 100s';
    105  getComputedStyle(div).left;
    106  div.style.left = '100px';
    107 
    108  assert_equals(div.getAnimations().length, 1);
    109 
    110  const transition = div.getAnimations()[0];
    111  await transition.ready;
    112 
    113  // The transition needs to have a non-zero currentTime for the interruption
    114  // reversal logic to apply.
    115  while (getComputedStyle(div).left == '0px') {
    116    await singleFrame();
    117  }
    118  assert_not_equals(transition.currentTime, 0);
    119 
    120  // Without yielding to the rendering loop, set the current transition's
    121  // effect to null and interrupt the transition. This should work correctly.
    122  transition.effect = null;
    123  div.style.left = '0px';
    124 
    125  // Yield to the rendering loop. This should not crash.
    126  await singleFrame();
    127 }, 'After setting a transition\'s effect to null, it should be possible to '
    128    + 'interrupt that transition');
    129 
    130 promise_test(async t => {
    131  const div = addDiv(t);
    132  div.style.left = '0px';
    133  div.style.width = '0px';
    134 
    135  div.style.transition = 'left 100s';
    136  getComputedStyle(div).left;
    137  div.style.left = '100px';
    138 
    139  const transition = div.getAnimations()[0];
    140  await transition.ready;
    141 
    142  transition.currentTime = 50 * MS_PER_SEC;
    143  transition.effect = new KeyframeEffect(div,
    144                                         { left: [ '0px' , '100px'] },
    145                                         20 * MS_PER_SEC);
    146 
    147  assert_equals(transition.playState, 'finished');
    148 }, 'After setting a new keyframe effect with a shorter duration,'
    149   + ' the transition becomes finished');
    150 
    151 promise_test(async t => {
    152  const div = addDiv(t);
    153  div.style.left = '0px';
    154  div.style.width = '0px';
    155 
    156  div.style.transition = 'left 100s';
    157  getComputedStyle(div).left;
    158  div.style.left = '100px';
    159 
    160  const transition = div.getAnimations()[0];
    161  transition.effect = new KeyframeEffect(div,
    162                                         { marginLeft: [ '0px' , '100px'] },
    163                                         100 * MS_PER_SEC);
    164  assert_equals(transition.transitionProperty, 'left');
    165 }, 'After setting a new keyframe effect targeting different properties,'
    166   + ' the transition continues to report the original transition property');
    167 
    168 promise_test(async t => {
    169  const div = addDiv(t);
    170  div.style.left = '0px';
    171  div.style.width = '0px';
    172 
    173  div.style.transition = 'left 100s';
    174  getComputedStyle(div).left;
    175  div.style.left = '100px';
    176 
    177  const transition = div.getAnimations()[0];
    178  assert_true(transition.pending);
    179 
    180  transition.effect = new KeyframeEffect(div,
    181                                         { marginLeft: [ '0px' , '100px'] },
    182                                         100 * MS_PER_SEC);
    183  assert_true(transition.pending);
    184 
    185  // As a sanity check, check that the transition actually exits the
    186  // pending state.
    187  await transition.ready;
    188  assert_false(transition.pending);
    189 }, 'After setting a new keyframe effect on a play-pending transition,'
    190   + ' the transition remains pending');
    191 
    192 test(t => {
    193  const div = addDiv(t);
    194 
    195  div.style.left = '0px';
    196  getComputedStyle(div).transitionProperty;
    197  div.style.transition = 'left 100s';
    198  div.style.left = '100px';
    199 
    200  const transition = div.getAnimations()[0];
    201  transition.effect = null;
    202 
    203  assert_equals(transition.transitionProperty, 'left');
    204 }, 'A transition with no effect still returns the original transitionProperty');
    205 
    206 test(t => {
    207  const div = addDiv(t);
    208 
    209  div.style.left = '0px';
    210  getComputedStyle(div).transitionProperty;
    211  div.style.transition = 'left 100s';
    212  div.style.left = '100px';
    213 
    214  const transition = div.getAnimations()[0];
    215 
    216  // Seek to the middle and get the portion.
    217  transition.currentTime = 50 * MS_PER_SEC;
    218  const portion = transition.effect.getComputedTiming().progress;
    219 
    220  // Replace the effect but keep the original timing
    221  transition.effect = new KeyframeEffect(
    222    div,
    223    { top: ['200px', '300px', '100px'] },
    224    transition.effect.getTiming()
    225  );
    226 
    227  // Reverse the transition
    228  div.style.left = '0px';
    229  const reversedTransition = div.getAnimations()[0];
    230 
    231  const expectedDuration = 100 * MS_PER_SEC * portion;
    232  assert_approx_equals(
    233    reversedTransition.effect.getComputedTiming().activeDuration,
    234    expectedDuration,
    235    1
    236  );
    237 }, 'A transition with a replaced effect still exhibits the regular transition'
    238   + ' reversing behavior');
    239 
    240 </script>