tor-browser

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

target.html (10643B)


      1 <!DOCTYPE html>
      2 <meta charset=utf-8>
      3 <title>KeyframeEffect.target and .pseudoElement</title>
      4 <link rel="help"
      5  href="https://drafts.csswg.org/web-animations/#dom-keyframeeffect-target">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="../../testcommon.js"></script>
      9 <style>
     10  .before::before {content: 'foo'; display: inline-block;}
     11  .after::after {content: 'bar'; display: inline-block;}
     12  .pseudoa::before, .pseudoc::before {margin-left: 10px;}
     13  .pseudob::before, .pseudoc::after {margin-left: 20px;}
     14 </style>
     15 <body>
     16 <div id="log"></div>
     17 <script>
     18 'use strict';
     19 
     20 const gKeyFrames = { 'marginLeft': ['0px', '100px'] };
     21 
     22 test(t => {
     23  const div = createDiv(t);
     24  const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
     25  effect.target = div;
     26 
     27  const anim = new Animation(effect, document.timeline);
     28  anim.play();
     29 
     30  anim.currentTime = 50 * MS_PER_SEC;
     31  assert_equals(getComputedStyle(div).marginLeft, '50px',
     32                'Value at 50% progress');
     33 }, 'Test setting target before constructing the associated animation');
     34 
     35 test(t => {
     36  const div = createDiv(t);
     37  div.style.marginLeft = '10px';
     38  const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
     39  const anim = new Animation(effect, document.timeline);
     40  anim.play();
     41 
     42  anim.currentTime = 50 * MS_PER_SEC;
     43  assert_equals(getComputedStyle(div).marginLeft, '10px',
     44                'Value at 50% progress before setting new target');
     45  effect.target = div;
     46  assert_equals(getComputedStyle(div).marginLeft, '50px',
     47                'Value at 50% progress after setting new target');
     48 }, 'Test setting target from null to a valid target');
     49 
     50 test(t => {
     51  const div = createDiv(t);
     52  div.style.marginLeft = '10px';
     53  const anim = div.animate(gKeyFrames, 100 * MS_PER_SEC);
     54 
     55  anim.currentTime = 50 * MS_PER_SEC;
     56  assert_equals(getComputedStyle(div).marginLeft, '50px',
     57                'Value at 50% progress before clearing the target')
     58 
     59  anim.effect.target = null;
     60  assert_equals(getComputedStyle(div).marginLeft, '10px',
     61                'Value after clearing the target')
     62 }, 'Test setting target from a valid target to null');
     63 
     64 test(t => {
     65  const a = createDiv(t);
     66  const b = createDiv(t);
     67  a.style.marginLeft = '10px';
     68  b.style.marginLeft = '20px';
     69  const anim = a.animate(gKeyFrames, 100 * MS_PER_SEC);
     70 
     71  anim.currentTime = 50 * MS_PER_SEC;
     72  assert_equals(getComputedStyle(a).marginLeft, '50px',
     73                'Value of 1st element (currently targeted) before ' +
     74                'changing the effect target');
     75  assert_equals(getComputedStyle(b).marginLeft, '20px',
     76                'Value of 2nd element (currently not targeted) before ' +
     77                'changing the effect target');
     78  anim.effect.target = b;
     79  assert_equals(getComputedStyle(a).marginLeft, '10px',
     80                'Value of 1st element (currently not targeted) after ' +
     81                'changing the effect target');
     82  assert_equals(getComputedStyle(b).marginLeft, '50px',
     83                'Value of 2nd element (currently targeted) after ' +
     84                'changing the effect target');
     85 
     86  // This makes sure the animation property is changed correctly on new
     87  // targeted element.
     88  anim.currentTime = 75 * MS_PER_SEC;
     89  assert_equals(getComputedStyle(b).marginLeft, '75px',
     90                'Value of 2nd target (currently targeted) after ' +
     91                'changing the animation current time.');
     92 }, 'Test setting target from a valid target to another target');
     93 
     94 promise_test(async t => {
     95  const animation = createDiv(t).animate(
     96    { opacity: 0 },
     97    { duration: 1, fill: 'forwards' }
     98  );
     99 
    100  const foreignElement
    101    = document.createElementNS('http://example.org/test', 'test');
    102  document.body.appendChild(foreignElement);
    103  t.add_cleanup(() => {
    104    foreignElement.remove();
    105  });
    106 
    107  animation.effect.target = foreignElement;
    108 
    109  // Wait a frame to make sure nothing bad happens when the UA tries to update
    110  // style.
    111  await waitForNextFrame();
    112 }, 'Target element can be set to a foreign element');
    113 
    114 // Pseudo-element tests
    115 // (testing target and pseudoElement in these cases)
    116 // Since blink uses separate code paths for handling pseudo-element styles
    117 // depending on whether content is set (putting the pseudo-element in the layout),
    118 // we run tests on both cases.
    119 for (const hasContent of [true, false]){
    120  test(t => {
    121    const d = createDiv(t);
    122    d.classList.add('pseudoa');
    123    if (hasContent) {
    124      d.classList.add('before');
    125    }
    126 
    127    const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
    128    const anim = new Animation(effect, document.timeline);
    129    anim.play();
    130 
    131    anim.currentTime = 50 * MS_PER_SEC;
    132    assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
    133                  'Value at 50% progress before setting new target');
    134    effect.target = d;
    135    effect.pseudoElement = '::before';
    136 
    137    assert_equals(effect.target, d, "Target element is set correctly");
    138    assert_equals(effect.pseudoElement, '::before', "Target pseudo-element set correctly");
    139    assert_equals(getComputedStyle(d, '::before').marginLeft, '50px',
    140                  'Value at 50% progress after setting new target');
    141  }, "Change target from null to " + (hasContent ? "an existing" : "a non-existing") +
    142     " pseudoElement setting target first.");
    143 
    144  test(t => {
    145    const d = createDiv(t);
    146    d.classList.add('pseudoa');
    147    if (hasContent) {
    148      d.classList.add('before');
    149    }
    150 
    151    const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
    152    const anim = new Animation(effect, document.timeline);
    153    anim.play();
    154 
    155    anim.currentTime = 50 * MS_PER_SEC;
    156    assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
    157                  'Value at 50% progress before setting new target');
    158    effect.pseudoElement = '::before';
    159    effect.target = d;
    160 
    161    assert_equals(effect.target, d, "Target element is set correctly");
    162    assert_equals(effect.pseudoElement, '::before', "Target pseudo-element set correctly");
    163    assert_equals(getComputedStyle(d, '::before').marginLeft, '50px',
    164                  'Value at 50% progress after setting new target');
    165  }, "Change target from null to " + (hasContent ? "an existing" : "a non-existing") +
    166     " pseudoElement setting pseudoElement first.");
    167 
    168  test(t => {
    169    const d = createDiv(t);
    170    d.classList.add('pseudoa');
    171    if (hasContent) {
    172      d.classList.add('before');
    173    }
    174    const anim = d.animate(gKeyFrames, {duration: 100 * MS_PER_SEC, pseudoElement: '::before'});
    175 
    176    anim.currentTime = 50 * MS_PER_SEC;
    177    anim.effect.pseudoElement = null;
    178    assert_equals(anim.effect.target, d,
    179                  "Animation targets specified element (target element)");
    180    assert_equals(anim.effect.pseudoElement, null,
    181                  "Animation targets specified element (null pseudo-selector)");
    182    assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
    183                  'Value of 1st element (currently not targeted) after ' +
    184                  'changing the effect target');
    185    assert_equals(getComputedStyle(d).marginLeft, '50px',
    186                  'Value of 2nd element (currently targeted) after ' +
    187                  'changing the effect target');
    188  }, "Change target from " + (hasContent ? "an existing" : "a non-existing") + " pseudo-element to the originating element.");
    189 
    190  for (const prevHasContent of [true, false]) {
    191    test(t => {
    192      const a = createDiv(t);
    193      a.classList.add('pseudoa');
    194      const b = createDiv(t);
    195      b.classList.add('pseudob');
    196      if (prevHasContent) {
    197        a.classList.add('before');
    198      }
    199      if (hasContent) {
    200        b.classList.add('before');
    201      }
    202 
    203      const anim = a.animate(gKeyFrames, {duration: 100 * MS_PER_SEC, pseudoElement: '::before'});
    204 
    205      anim.currentTime = 50 * MS_PER_SEC;
    206      anim.effect.target = b;
    207      assert_equals(anim.effect.target, b,
    208                    "Animation targets specified pseudo-element (target element)");
    209      assert_equals(anim.effect.pseudoElement, '::before',
    210                    "Animation targets specified pseudo-element (pseudo-selector)");
    211      assert_equals(getComputedStyle(a, '::before').marginLeft, '10px',
    212                    'Value of 1st element (currently not targeted) after ' +
    213                    'changing the effect target');
    214      assert_equals(getComputedStyle(b, '::before').marginLeft, '50px',
    215                    'Value of 2nd element (currently targeted) after ' +
    216                    'changing the effect target');
    217    }, "Change target from " + (prevHasContent ? "an existing" : "a non-existing") +
    218        " to a different " + (hasContent ? "existing" : "non-existing") +
    219        " pseudo-element by setting target.");
    220 
    221    test(t => {
    222      const d = createDiv(t);
    223      d.classList.add('pseudoc');
    224      if (prevHasContent) {
    225        d.classList.add('before');
    226      }
    227      if (hasContent) {
    228        d.classList.add('after');
    229      }
    230 
    231      const anim = d.animate(gKeyFrames, {duration: 100 * MS_PER_SEC, pseudoElement: '::before'});
    232 
    233      anim.currentTime = 50 * MS_PER_SEC;
    234      anim.effect.pseudoElement = '::after';
    235      assert_equals(anim.effect.target, d,
    236                    "Animation targets specified pseudo-element (target element)");
    237      assert_equals(anim.effect.pseudoElement, '::after',
    238                    "Animation targets specified pseudo-element (pseudo-selector)");
    239      assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
    240                    'Value of 1st element (currently not targeted) after ' +
    241                    'changing the effect target');
    242      assert_equals(getComputedStyle(d, '::after').marginLeft, '50px',
    243                    'Value of 2nd element (currently targeted) after ' +
    244                    'changing the effect target');
    245    }, "Change target from " + (prevHasContent ? "an existing" : "a non-existing") +
    246        " to a different " + (hasContent ? "existing" : "non-existing") +
    247        " pseudo-element by setting pseudoElement.");
    248  }
    249 }
    250 
    251 for (const pseudo of [
    252  '',
    253  'before',
    254  ':abc',
    255  '::abc',
    256 ]) {
    257  test(t => {
    258    const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
    259    assert_throws_dom("SyntaxError", () => effect.pseudoElement = pseudo );
    260  }, `Changing pseudoElement to a non-null invalid pseudo-selector ` +
    261     `'${pseudo}' throws a SyntaxError`);
    262 }
    263 
    264 test(t => {
    265  const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
    266  effect.pseudoElement = '::placeHOLDER';
    267  assert_equals(effect.pseudoElement, '::placeholder');
    268 }, `Changing pseudoElement to ::placeHOLDER works`);
    269 
    270 </script>
    271 </body>