Skip to content

Commit

Permalink
Implement new pseudoElement interface on KeyframeEffect
Browse files Browse the repository at this point in the history
Rename the KeyframeEffect::target() method to BlinkTarget().
This and the backing variable target_ will still return a blink::PseudoElement.
Refactor all native callers to use this new name.

Make target() return the originating element if target_ is a PseudoElement.
Add PseudoElement() property whiich returns a pseudo-selector is target_
is a pseudo-element.
Update setters for both these parts which attempt to preserve the other value.
Attempting to select a non-existent pseudo-element will set a null target.

Add pseudoElement option to KeyframeEffect constructor.
Replace duplicate copy in Animatable::animate with function call.

Change-Id: Id7d16ea6966c533e56d1170462ff60a79b277fd5
Bug: 981894
  • Loading branch information
george-steel authored and chromium-wpt-export-bot committed Dec 3, 2019
1 parent 28b0967 commit 2918c0f
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 3 deletions.
23 changes: 21 additions & 2 deletions web-animations/interfaces/Animatable/animate.html
Expand Up @@ -249,6 +249,12 @@
assert_class_string(anim, 'Animation', 'The returned object is an Animation');
}, 'animate() with pseudoElement parameter creates an Animation object');

test(t => {
const div = createDiv(t);
const anim = div.animate(null, {pseudoElement: '::before'});
assert_class_string(anim, 'Animation', 'The returned object is an Animation');
}, 'animate() with pseudoElement parameter without content creates an Animation object');

test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
Expand All @@ -268,31 +274,44 @@
test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
getComputedStyle(div,"::before").content;
const anim = div.animate(null, {pseudoElement: '::before'});
assert_equals(anim.effect.target, div, 'The returned element has the correct target element');
assert_equals(anim.effect.pseudoElement, '::before',
'The returned Animation targets to the correct selector');
}, 'animate() with pseudoElement an Animation object targeting ' +
'to the correct pseudo-element');

test(t => {
const div = createDiv(t);
const anim = div.animate(null, {pseudoElement: '::before'});
assert_equals(anim.effect.target, div, 'The returned element has the correct target element');
assert_equals(anim.effect.pseudoElement, '::before',
'The returned Animation targets to the correct selector');
}, 'animate() with pseudoElement without content creates an Animation object targeting ' +
'the correct pseudo-element');

test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
div.style.display = 'list-item';
const anim = div.animate(null, {pseudoElement: '::marker'});
assert_equals(anim.effect.target, div, 'The returned element has the correct target element');
assert_equals(anim.effect.pseudoElement, '::marker',
'The returned Animation targets to the correct selector');
}, 'animate() with pseudoElement an Animation object targeting ' +
'to the correct pseudo-element for ::marker');
'the correct pseudo-element for ::marker');

test(t => {
const div = createDiv(t);
div.classList.add('pseudo');
div.textContent = 'foo';
const anim = div.animate(null, {pseudoElement: '::first-line'});
assert_equals(anim.effect.target, div, 'The returned element has the correct target element');
assert_equals(anim.effect.pseudoElement, '::first-line',
'The returned Animation targets to the correct selector');
}, 'animate() with pseudoElement an Animation object targeting ' +
'to the correct pseudo-element for ::first-line');
'the correct pseudo-element for ::first-line');

</script>
</body>
123 changes: 122 additions & 1 deletion web-animations/interfaces/KeyframeEffect/target.html
@@ -1,11 +1,17 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>KeyframeEffect.target</title>
<title>KeyframeEffect.target and .pseudoElement</title>
<link rel="help"
href="https://drafts.csswg.org/web-animations/#dom-keyframeeffect-target">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<style>
.before::before {content: 'foo'; display: inline-block;}
.after::after {content: 'foo'; display: inline-block;}
.pseudoa::before, .pseudoc::before {margin-left: 10px;}
.pseudob::before, .pseudoc::after {margin-left: 20px;}
</style>
<body>
<div id="log"></div>
<script>
Expand Down Expand Up @@ -105,5 +111,120 @@
await waitForNextFrame();
}, 'Target element can be set to a foreign element');

// Pseudo-element cases
for (const aContent of [true, false]){
//const aContent = aContentRef;
test(t => {
const d = createDiv(t);
d.classList.add('pseudoa');
if (aContent) {
d.classList.add('before');
getComputedStyle(d,"::before").content;
}

const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
const anim = new Animation(effect, document.timeline);
anim.play();

anim.currentTime = 50 * MS_PER_SEC;
assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
'Value at 50% progress before setting new target');
effect.target = d;
assert_equals(effect.target, d, "Target element is set correctly in-between calls");
effect.pseudoElement = '::before';

assert_equals(effect.target, d, "Target element is set correctly");
assert_equals(effect.pseudoElement, '::before', "Target pseudo-element set correctly");
assert_equals(getComputedStyle(d, '::before').marginLeft, '50px',
'Value at 50% progress after setting new target');
}, "Change target from null to " + (aContent ? "an existing" : "a non-existing") +
" pseudoElement setting target first.");

test(t => {
const d = createDiv(t);
d.classList.add('pseudoa');
if (aContent) {
d.classList.add('before');
getComputedStyle(d,"::before").content;
}

const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
const anim = new Animation(effect, document.timeline);
anim.play();

anim.currentTime = 50 * MS_PER_SEC;
assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
'Value at 50% progress before setting new target');
effect.pseudoElement = '::before';
effect.target = d;

assert_equals(effect.target, d, "Target element is set correctly");
assert_equals(effect.pseudoElement, '::before', "Target pseudo-element set correctly");
assert_equals(getComputedStyle(d, '::before').marginLeft, '50px',
'Value at 50% progress after setting new target');
}, "Change target from null to " + (aContent ? "an existing" : "a non-existing") +
" pseudoElement setting pseudoElement first.");

for (const bContent of [true, false]) {
//const bContent = bContentRef;

test(t => {
const a = createDiv(t);
a.classList.add('pseudoa');
const b = createDiv(t);
b.classList.add('pseudob');
if (aContent) a.classList.add('before');
if (bContent) b.classList.add('before');

// sync on updating the pseudo-elements
getComputedStyle(a,"::before").content;
getComputedStyle(b,"::before").content;
const anim = a.animate(gKeyFrames, {duration: 100 * MS_PER_SEC, pseudoElement: '::before'});

anim.currentTime = 50 * MS_PER_SEC;
anim.effect.target = b;
assert_equals(anim.effect.target, b,
"Animation targets specified element (target element)");
assert_equals(anim.effect.pseudoElement, '::before',
"Animation targets specified element (pseudo-selector)");
assert_equals(getComputedStyle(a, '::before').marginLeft, '10px',
'Value of 1st element (currently not targeted) after ' +
'changing the effect target');
assert_equals(getComputedStyle(b, '::before').marginLeft, '50px',
'Value of 2nd element (currently targeted) after ' +
'changing the effect target');
}, "Change target from " + (aContent ? "an existing" : "a non-existing") +
" to " + (bContent ? "an existing" : "a non-existing") + " pseudo-element by setting target.");

test(t => {
const d = createDiv(t);
d.classList.add('pseudoc');
if (aContent) d.classList.add('before');
if (bContent) d.classList.add('after');

// sync on updating the pseudo-elements
getComputedStyle(d,"::before").content;
getComputedStyle(d,"::after").content;
const anim = d.animate(gKeyFrames, {duration: 100 * MS_PER_SEC, pseudoElement: '::before'});

anim.currentTime = 50 * MS_PER_SEC;
anim.effect.pseudoElement = '::after';
assert_equals(anim.effect.target, d,
"Animation targets specified element (target element)");
assert_equals(anim.effect.pseudoElement, '::after',
"Animation targets specified element (pseudo-selector)");
assert_equals(getComputedStyle(d, '::before').marginLeft, '10px',
'Value of 1st element (currently not targeted) after ' +
'changing the effect target');
assert_equals(getComputedStyle(d, '::after').marginLeft, '50px',
'Value of 2nd element (currently targeted) after ' +
'changing the effect target');
}, "Change target from " + (aContent ? "an existing" : "a non-existing") +
" to " + (bContent ? "an existing" : "a non-existing") + " pseudo-element by setting pseudoElement.");
}
}



</script>
</body>

0 comments on commit 2918c0f

Please sign in to comment.