Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Ciure Andrei 2019-03-27 18:40:06 +02:00
Родитель e125040c2f daa05061c1
Коммит 289f67a603
32 изменённых файлов: 379 добавлений и 27 удалений

Просмотреть файл

@ -23,7 +23,9 @@ CSSPseudoElement::CSSPseudoElement(dom::Element* aElement,
: mOriginatingElement(aElement), mPseudoType(aType) {
MOZ_ASSERT(aElement);
MOZ_ASSERT(
aType == PseudoStyleType::after || aType == PseudoStyleType::before,
aType == PseudoStyleType::after ||
aType == PseudoStyleType::before ||
aType == PseudoStyleType::marker,
"Unexpected Pseudo Type");
}
@ -106,10 +108,13 @@ nsAtom* CSSPseudoElement::GetCSSPseudoElementPropertyAtom(
case PseudoStyleType::after:
return nsGkAtoms::cssPseudoElementAfterProperty;
case PseudoStyleType::marker:
return nsGkAtoms::cssPseudoElementMarkerProperty;
default:
MOZ_ASSERT_UNREACHABLE(
"Should not try to get CSSPseudoElement "
"other than ::before or ::after");
"other than ::before, ::after or ::marker");
return nullptr;
}
}

Просмотреть файл

@ -69,7 +69,7 @@ class CSSPseudoElement final : public nsWrapperCache {
dom::Element* aElement, PseudoStyleType aType);
private:
// Only ::before and ::after are supported.
// Only ::before, ::after and ::marker are supported.
CSSPseudoElement(dom::Element* aElement, PseudoStyleType aType);
static nsAtom* GetCSSPseudoElementPropertyAtom(PseudoStyleType aType);

Просмотреть файл

@ -335,18 +335,22 @@ void EffectCompositor::ClearRestyleRequestsFor(Element* aElement) {
PseudoStyleType pseudoType = aElement->GetPseudoElementType();
if (pseudoType == PseudoStyleType::NotPseudo) {
PseudoElementHashEntry::KeyType notPseudoKey = {aElement,
PseudoStyleType::NotPseudo};
PseudoElementHashEntry::KeyType beforePseudoKey = {aElement,
PseudoStyleType::before};
PseudoElementHashEntry::KeyType afterPseudoKey = {aElement,
PseudoStyleType::after};
PseudoElementHashEntry::KeyType notPseudoKey =
{aElement, PseudoStyleType::NotPseudo};
PseudoElementHashEntry::KeyType beforePseudoKey =
{aElement, PseudoStyleType::before};
PseudoElementHashEntry::KeyType afterPseudoKey =
{aElement, PseudoStyleType::after};
PseudoElementHashEntry::KeyType markerPseudoKey =
{aElement, PseudoStyleType::marker};
elementsToRestyle.Remove(notPseudoKey);
elementsToRestyle.Remove(beforePseudoKey);
elementsToRestyle.Remove(afterPseudoKey);
elementsToRestyle.Remove(markerPseudoKey);
} else if (pseudoType == PseudoStyleType::before ||
pseudoType == PseudoStyleType::after) {
pseudoType == PseudoStyleType::after ||
pseudoType == PseudoStyleType::marker) {
Element* parentElement = aElement->GetParentElement();
MOZ_ASSERT(parentElement);
PseudoElementHashEntry::KeyType key = {parentElement, pseudoType};
@ -444,9 +448,13 @@ bool EffectCompositor::GetServoAnimationRule(
return nsLayoutUtils::GetAfterPseudo(aElement);
}
if (aPseudoType == PseudoStyleType::marker) {
return nsLayoutUtils::GetMarkerPseudo(aElement);
}
MOZ_ASSERT_UNREACHABLE(
"Should not try to get the element to restyle for "
"a pseudo other that :before or :after");
"a pseudo other that :before, :after or ::marker");
return nullptr;
}
@ -520,7 +528,8 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) {
if (pseudoType != PseudoStyleType::NotPseudo &&
pseudoType != PseudoStyleType::before &&
pseudoType != PseudoStyleType::after) {
pseudoType != PseudoStyleType::after &&
pseudoType != PseudoStyleType::marker) {
return result;
}
@ -530,7 +539,8 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) {
}
if (pseudoType == PseudoStyleType::before ||
pseudoType == PseudoStyleType::after) {
pseudoType == PseudoStyleType::after ||
pseudoType == PseudoStyleType::marker) {
content = content->GetParent();
if (!content) {
return result;
@ -722,7 +732,8 @@ bool EffectCompositor::PreTraverseInSubtree(ServoTraversalFlags aFlags,
// of the root element later in this function, but for pseudo elements the
// element in mElementsToRestyle is the parent of the pseudo.
if (aRoot && (aRoot->IsGeneratedContentContainerForBefore() ||
aRoot->IsGeneratedContentContainerForAfter())) {
aRoot->IsGeneratedContentContainerForAfter() ||
aRoot->IsGeneratedContentContainerForMarker())) {
aRoot = aRoot->GetParentElement();
}
@ -865,7 +876,8 @@ bool EffectCompositor::PreTraverse(dom::Element* aElement,
bool found = false;
if (aPseudoType != PseudoStyleType::NotPseudo &&
aPseudoType != PseudoStyleType::before &&
aPseudoType != PseudoStyleType::after) {
aPseudoType != PseudoStyleType::after &&
aPseudoType != PseudoStyleType::marker) {
return found;
}

Просмотреть файл

@ -104,7 +104,7 @@ class EffectCompositor {
void PostRestyleForThrottledAnimations();
// Clear all pending restyle requests for the given (pseudo-) element (and its
// ::before and ::after elements if the given element is not pseudo).
// ::before, ::after and ::marker elements if the given element is not pseudo).
void ClearRestyleRequestsFor(dom::Element* aElement);
// Called when computed style on the specified (pseudo-) element might
@ -203,7 +203,7 @@ class EffectCompositor {
// Returns the target element for restyling.
//
// If |aPseudoType| is ::after or ::before, returns the generated content
// If |aPseudoType| is ::after, ::before or ::marker, returns the generated content
// element of which |aElement| is the parent. If |aPseudoType| is any other
// pseudo type (other than PseudoStyleType::NotPseudo) returns nullptr.
// Otherwise, returns |aElement|.

Просмотреть файл

@ -150,7 +150,9 @@ nsAtom** EffectSet::GetEffectSetPropertyAtoms() {
static nsAtom* effectSetPropertyAtoms[] = {
nsGkAtoms::animationEffectsProperty,
nsGkAtoms::animationEffectsForBeforeProperty,
nsGkAtoms::animationEffectsForAfterProperty, nullptr};
nsGkAtoms::animationEffectsForAfterProperty,
nsGkAtoms::animationEffectsForMarkerProperty,
nullptr};
return effectSetPropertyAtoms;
}
@ -167,10 +169,13 @@ nsAtom* EffectSet::GetEffectSetPropertyAtom(PseudoStyleType aPseudoType) {
case PseudoStyleType::after:
return nsGkAtoms::animationEffectsForAfterProperty;
case PseudoStyleType::marker:
return nsGkAtoms::animationEffectsForMarkerProperty;
default:
MOZ_ASSERT_UNREACHABLE(
"Should not try to get animation effects for "
"a pseudo other that :before or :after");
"a pseudo other that :before, :after or ::marker");
return nullptr;
}
}

Просмотреть файл

@ -942,6 +942,7 @@ void KeyframeEffect::GetTarget(
switch (mTarget->mPseudoType) {
case PseudoStyleType::before:
case PseudoStyleType::after:
case PseudoStyleType::marker:
aRv.SetValue().SetAsCSSPseudoElement() =
CSSPseudoElement::GetCSSPseudoElement(mTarget->mElement,
mTarget->mPseudoType);
@ -1389,6 +1390,8 @@ nsIFrame* KeyframeEffect::GetPrimaryFrame() const {
frame = nsLayoutUtils::GetBeforeFrame(mTarget->mElement);
} else if (mTarget->mPseudoType == PseudoStyleType::after) {
frame = nsLayoutUtils::GetAfterFrame(mTarget->mElement);
} else if (mTarget->mPseudoType == PseudoStyleType::marker) {
frame = nsLayoutUtils::GetMarkerFrame(mTarget->mElement);
} else {
frame = mTarget->mElement->GetPrimaryFrame();
MOZ_ASSERT(mTarget->mPseudoType == PseudoStyleType::NotPseudo,

Просмотреть файл

@ -1777,7 +1777,8 @@ nsresult Element::BindToTree(Document* aDocument, nsIContent* aParent,
PseudoStyleType pseudoType = GetPseudoElementType();
if ((pseudoType == PseudoStyleType::NotPseudo ||
pseudoType == PseudoStyleType::before ||
pseudoType == PseudoStyleType::after) &&
pseudoType == PseudoStyleType::after ||
pseudoType == PseudoStyleType::marker) &&
EffectSet::GetEffectSet(this, pseudoType)) {
if (nsPresContext* presContext = aDocument->GetPresContext()) {
presContext->EffectCompositor()->RequestRestyle(
@ -1913,9 +1914,11 @@ void Element::UnbindFromTree(bool aDeep, bool aNullParent) {
if (MayHaveAnimations()) {
DeleteProperty(nsGkAtoms::transitionsOfBeforeProperty);
DeleteProperty(nsGkAtoms::transitionsOfAfterProperty);
DeleteProperty(nsGkAtoms::transitionsOfMarkerProperty);
DeleteProperty(nsGkAtoms::transitionsProperty);
DeleteProperty(nsGkAtoms::animationsOfBeforeProperty);
DeleteProperty(nsGkAtoms::animationsOfAfterProperty);
DeleteProperty(nsGkAtoms::animationsOfMarkerProperty);
DeleteProperty(nsGkAtoms::animationsProperty);
if (document) {
if (nsPresContext* presContext = document->GetPresContext()) {
@ -3493,14 +3496,19 @@ void Element::GetAnimations(const AnimationFilter& filter,
} else if (IsGeneratedContentContainerForAfter()) {
elem = GetParentElement();
pseudoType = PseudoStyleType::after;
} else if (IsGeneratedContentContainerForMarker()) {
elem = GetParentElement();
pseudoType = PseudoStyleType::marker;
}
if (!elem) {
return;
}
if (!filter.mSubtree || pseudoType == PseudoStyleType::before ||
pseudoType == PseudoStyleType::after) {
if (!filter.mSubtree ||
pseudoType == PseudoStyleType::before ||
pseudoType == PseudoStyleType::after ||
pseudoType == PseudoStyleType::marker) {
GetAnimationsUnsorted(elem, pseudoType, aAnimations);
} else {
for (nsIContent* node = this; node; node = node->GetNextNode(this)) {
@ -3514,6 +3522,8 @@ void Element::GetAnimations(const AnimationFilter& filter,
aAnimations);
Element::GetAnimationsUnsorted(element, PseudoStyleType::after,
aAnimations);
Element::GetAnimationsUnsorted(element, PseudoStyleType::marker,
aAnimations);
}
}
aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
@ -3525,7 +3535,8 @@ void Element::GetAnimationsUnsorted(Element* aElement,
nsTArray<RefPtr<Animation>>& aAnimations) {
MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo ||
aPseudoType == PseudoStyleType::after ||
aPseudoType == PseudoStyleType::before,
aPseudoType == PseudoStyleType::before ||
aPseudoType == PseudoStyleType::marker,
"Unsupported pseudo type");
MOZ_ASSERT(aElement, "Null element");

Просмотреть файл

@ -1230,6 +1230,8 @@ void nsGlobalWindowInner::FreeInnerObjects() {
mExternal = nullptr;
mInstallTrigger = nullptr;
mLocalStorage = nullptr;
mSessionStorage = nullptr;
mPerformance = nullptr;
mSharedWorkers.Clear();

Просмотреть файл

@ -1983,6 +1983,7 @@ void RestyleManager::AnimationsWithDestroyedFrame ::
StopAnimationsWithoutFrame(mContents, PseudoStyleType::NotPseudo);
StopAnimationsWithoutFrame(mBeforeContents, PseudoStyleType::before);
StopAnimationsWithoutFrame(mAfterContents, PseudoStyleType::after);
StopAnimationsWithoutFrame(mAfterContents, PseudoStyleType::marker);
}
void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame(
@ -2004,6 +2005,10 @@ void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame(
if (nsLayoutUtils::GetAfterFrame(content)) {
continue;
}
} else if (aPseudoType == PseudoStyleType::marker) {
if (nsLayoutUtils::GetMarkerFrame(content)) {
continue;
}
}
dom::Element* element = content->AsElement();

Просмотреть файл

@ -263,6 +263,10 @@ class RestyleManager {
MOZ_ASSERT(aContent->NodeInfo()->NameAtom() ==
nsGkAtoms::mozgeneratedcontentafter);
mAfterContents.AppendElement(aContent->GetParent());
} else if (pseudoType == PseudoStyleType::marker) {
MOZ_ASSERT(aContent->NodeInfo()->NameAtom() ==
nsGkAtoms::mozgeneratedcontentmarker);
mMarkerContents.AppendElement(aContent->GetParent());
}
}
@ -278,12 +282,13 @@ class RestyleManager {
// Below three arrays might include elements that have already had their
// animations or transitions stopped.
//
// mBeforeContents and mAfterContents hold the real element rather than
// the content node for the generated content (which might change during
// a reframe)
// mBeforeContents, mAfterContents and mMarkerContents hold the real element
// rather than the content node for the generated content (which might
// change during a reframe)
nsTArray<RefPtr<nsIContent>> mContents;
nsTArray<RefPtr<nsIContent>> mBeforeContents;
nsTArray<RefPtr<nsIContent>> mAfterContents;
nsTArray<RefPtr<nsIContent>> mMarkerContents;
};
/**

Просмотреть файл

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<style>
#target::marker {
content: 'content';
}
#target {
display: list-item;
margin-left: 200px;
}
</style>
<div id='target'></div>
</html>

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<style>
@keyframes anim {
from { content: 'content'; }
to { content: ''; }
}
#target::marker {
content: 'initial';
animation: anim 100s paused;
}
#target {
display: list-item;
margin-left: 200px;
}
</style>
<div id='target'></div>
</html>

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<style>
@keyframes anim {
from { content: ''; }
to { content: 'content'; }
}
#target::marker {
content: 'initial';
animation: anim 100s linear -50s paused;
}
#target {
display: list-item;
margin-left: 200px;
}
</style>
<div id='target'></div>
</html>

Просмотреть файл

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<title>In visibility hidden color animation on pseudo element</title>
<style>
div::marker {
visibility: visible;
color: blue;
content: "Color Animation";
}
div {
color: black;
visibility: hidden;
display: list-item;
list-style-position: inside;
}
</style>
<div>color animation on visible psuedo element attached to invisible element</div>

Просмотреть файл

@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<title>In visibility hidden color animation on pseudo element</title>
<style>
@keyframes color {
0% { color: black }
1% { color: blue }
100% { color: blue }
}
div::marker {
visibility: visible;
content: "Color Animation";
animation: color 0.1s 1 forwards;
}
div {
color: black;
visibility: hidden;
display: list-item;
list-style-position: inside;
}
</style>
<div id="target">color animation on visible pseudo element attached to invisible element</div>
<script>
document.getElementById("target").addEventListener("animationend", AnimationEndListener);
function AnimationEndListener(event) {
setTimeout(RemoveReftestWait, 0);
}
function RemoveReftestWait() {
document.documentElement.classList.remove("reftest-wait");
}
</script>

Просмотреть файл

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<style>
#target::marker {
content: '';
background-color: rgb(255, 255, 255);
height: 100px;
width: 100px;
position: absolute;
}
#target {
display: list-item;
list-style-position: inside;
}
</style>
<div id="target"></div>
</html>

Просмотреть файл

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html class="reftest-wait">
<style>
@keyframes anim {
from { background-color: rgb(255, 255, 255); }
to { background-color: rgb(255, 255, 255); }
}
#target::marker {
content: 'initial';
background-color: rgb(0, 0, 0);
height: 100px;
width: 100px;
position: absolute;
}
#target.hover::marker{
content: '';
animation: anim 100s steps(1, start);
}
#target {
display: list-item;
list-style-position: inside;
}
</style>
<div id="target"></div>
<script>
window.addEventListener("load", () => {
target.className = 'hover';
target.addEventListener('animationstart', () => {
document.documentElement.classList.remove('reftest-wait');
});
});
</script>
</html>

Просмотреть файл

@ -8,6 +8,7 @@ fails != print-no-animations.html print-no-animations-notref.html # reftest harn
== animation-on-empty-height-frame.html about:blank
== in-visibility-hidden-animation.html in-visibility-hidden-animation-ref.html
== in-visibility-hidden-animation-pseudo-element.html in-visibility-hidden-animation-pseudo-element-ref.html
== in-visibility-hidden-animation-marker-pseudo-element.html in-visibility-hidden-animation-marker-pseudo-element-ref.html
== partially-out-of-view-animation.html partially-out-of-view-animation-ref.html
== animate-display-table-opacity.html animate-display-table-opacity-ref.html
# We need to run 100% opacity test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor
@ -57,9 +58,13 @@ fails-if(layerChecksEnabled) == background-position-important.html background-po
== stop-animation-on-discarded-pseudo-element.html about:blank
== updating-animation-on-pseudo-element.html updating-animation-on-pseudo-element-ref.html
== updating-animation-on-marker-pseudo-element.html updating-animation-on-marker-pseudo-element-ref.html
== content-on-pseudo-element-at-beginning.html content-on-pseudo-element-ref.html
== content-on-pseudo-element-at-half.html content-on-pseudo-element-ref.html
== content-on-marker-pseudo-element-at-beginning.html content-on-marker-pseudo-element-at-beginning-ref.html
== content-on-marker-pseudo-element-at-half.html content-on-marker-pseudo-element-at-beginning-ref.html
== reframe-and-animation-starts-at-the-same-time.html reframe-and-animation-starts-at-the-same-time-ref.html
== marker-reframe-and-animation-starts-at-the-same-time.html marker-reframe-and-animation-starts-at-the-same-time-ref.html
== change-animation-name-to-none-in-rule.html change-animation-name-in-rule-ref.html
== change-animation-name-to-other-in-rule.html change-animation-name-in-rule-ref.html
== change-animation-name-to-non-existent-in-rule.html change-animation-name-in-rule-ref.html

Просмотреть файл

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<style>
#target::marker {
content: 'marker';
margin-left: 10em;
font-size: 20px;
}
#target {
display: list-item;
margin-left: 200px;
}
</style>
<div id="target"></div>
</html>

Просмотреть файл

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html class="reftest-wait">
<style>
@keyframes anim {
from { margin-left: 10em; }
to { margin-left: 10em; }
}
#target::marker {
content: 'marker';
}
#target.anim::marker {
animation: anim 100s infinite;
font-size: 10px;
}
#target.bigger-font::marker {
font-size: 20px;
}
#target {
display: list-item;
margin-left: 200px;
}
</style>
<div id="target"></div>
<script>
addEventListener('DOMContentLoaded', () => {
var target = document.getElementById('target');
// Start an animation on pseudo element.
target.classList.add('anim');
requestAnimationFrame(() => {
// The animation on pseudo element should be updated
// when the target element classes are modified.
target.classList.add('bigger-font');
requestAnimationFrame(() => {
document.documentElement.classList.remove('reftest-wait');
});
});
});
</script>
</html>

Просмотреть файл

@ -117,6 +117,8 @@ AnimationCollection<AnimationType>::GetPropertyAtomForPseudoType(
propName = TraitsType::BeforePropertyAtom();
} else if (aPseudoType == PseudoStyleType::after) {
propName = TraitsType::AfterPropertyAtom();
} else if (aPseudoType == PseudoStyleType::marker) {
propName = TraitsType::MarkerPropertyAtom();
}
return propName;

Просмотреть файл

@ -47,7 +47,7 @@ class CommonAnimationManager {
/**
* Stop animations on the element. This method takes the real element
* rather than the element for the generated content for animations on
* ::before and ::after.
* ::before, ::after and ::marker.
*/
void StopAnimationsForElement(dom::Element* aElement,
PseudoStyleType aPseudoType) {
@ -123,6 +123,10 @@ class OwningElementRef final {
return mTarget.mPseudoType == PseudoStyleType::NotPseudo ||
(mTarget.mPseudoType == PseudoStyleType::before &&
aOther.mTarget.mPseudoType == PseudoStyleType::after) ||
(mTarget.mPseudoType == PseudoStyleType::marker &&
aOther.mTarget.mPseudoType == PseudoStyleType::before) ||
(mTarget.mPseudoType == PseudoStyleType::marker &&
aOther.mTarget.mPseudoType == PseudoStyleType::after);
}

Просмотреть файл

@ -470,6 +470,11 @@ static PseudoStyleType GetPseudoTypeFromElementForAnimation(
return PseudoStyleType::after;
}
if (aElementOrPseudo->IsGeneratedContentContainerForMarker()) {
aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
return PseudoStyleType::marker;
}
return PseudoStyleType::NotPseudo;
}

Просмотреть файл

@ -1228,6 +1228,11 @@ already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleLazilyInternal(
elementForStyleResolution = pseudo;
pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
}
} else if (aPseudoType == PseudoStyleType::marker) {
if (Element* pseudo = nsLayoutUtils::GetMarkerPseudo(aElement)) {
elementForStyleResolution = pseudo;
pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
}
}
RefPtr<ComputedStyle> computedValues =

Просмотреть файл

@ -255,6 +255,9 @@ struct AnimationTypeTraits<dom::CSSAnimation> {
static nsAtom* AfterPropertyAtom() {
return nsGkAtoms::animationsOfAfterProperty;
}
static nsAtom* MarkerPropertyAtom() {
return nsGkAtoms::animationsOfMarkerProperty;
}
};
} /* namespace mozilla */

Просмотреть файл

@ -119,6 +119,8 @@ nsString nsCSSPseudoElements::PseudoTypeAsString(Type aPseudoType) {
return NS_LITERAL_STRING("::before");
case PseudoStyleType::after:
return NS_LITERAL_STRING("::after");
case PseudoStyleType::marker:
return NS_LITERAL_STRING("::marker");
default:
MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo,
"Unexpected pseudo type");

Просмотреть файл

@ -135,6 +135,10 @@ static bool DocumentNeedsRestyle(const Document* aDocument, Element* aElement,
if (EffectSet::GetEffectSet(aElement, PseudoStyleType::after)) {
return true;
}
} else if (aPseudo == nsCSSPseudoElements::marker()) {
if (EffectSet::GetEffectSet(aElement, PseudoStyleType::marker)) {
return true;
}
}
}

Просмотреть файл

@ -276,6 +276,9 @@ struct AnimationTypeTraits<dom::CSSTransition> {
static nsAtom* AfterPropertyAtom() {
return nsGkAtoms::transitionsOfAfterProperty;
}
static nsAtom* MarkerPropertyAtom() {
return nsGkAtoms::transitionsOfMarkerProperty;
}
};
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,35 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Animations Test: AnimationEvent pseudoElement</title>
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-animations/#interface-animationevent">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#target::marker {
content: "";
animation: move 1s;
}
@keyframes move {
to { transform: translate(100px); }
}
#target {
display: list-item;
list-style-position: inside;
}
</style>
<div id='target'></div>
<script>
async_test(function(t) {
var target = document.getElementById('target');
target.addEventListener("animationstart", t.step_func(function(evt) {
assert_true(evt instanceof window.AnimationEvent);
assert_equals(evt.pseudoElement, "::marker");
t.done();
}), true);
}, "AnimationEvent should have the correct pseudoElement memeber");
</script>

Просмотреть файл

@ -243,6 +243,12 @@ test(t => {
assert_class_string(anim, 'Animation', 'The returned object is an Animation');
}, 'CSSPseudoElement.animate() creates an Animation object');
test(t => {
const pseudoTarget = getPseudoElement(t, 'marker');
const anim = pseudoTarget.animate(null);
assert_class_string(anim, 'Animation', 'The returned object is an Animation for ::marker');
}, 'CSSPseudoElement.animate() creates an Animation object for ::marker');
test(t => {
const pseudoTarget = getPseudoElement(t, 'before');
const anim = pseudoTarget.animate(null);
@ -250,5 +256,13 @@ test(t => {
'The returned Animation targets to the correct object');
}, 'CSSPseudoElement.animate() creates an Animation object targeting ' +
'to the correct CSSPseudoElement object');
test(t => {
const pseudoTarget = getPseudoElement(t, 'marker');
const anim = pseudoTarget.animate(null);
assert_equals(anim.effect.target, pseudoTarget,
'The returned Animation targets to the correct object for ::marker');
}, 'CSSPseudoElement.animate() creates an Animation object targeting ' +
'to the correct CSSPseudoElement object for ::marker');
</script>
</body>

Просмотреть файл

@ -93,6 +93,9 @@ function getPseudoElement(test, type) {
[`.pseudo::${type}`]: 'animation: anim 10s; ' +
'content: \'\';' });
const div = createDiv(test);
if (type == 'marker') {
div.style.display = 'list-item';
}
div.classList.add('pseudo');
const anims = document.getAnimations();
assert_true(anims.length >= 1);

Просмотреть файл

@ -2049,15 +2049,19 @@ STATIC_ATOMS = [
Atom("animationsProperty", "AnimationsProperty"), # FrameAnimations*
Atom("animationsOfBeforeProperty", "AnimationsOfBeforeProperty"), # FrameAnimations*
Atom("animationsOfAfterProperty", "AnimationsOfAfterProperty"), # FrameAnimations*
Atom("animationsOfMarkerProperty", "AnimationsOfMarkerProperty"), # FrameAnimations*
Atom("animationEffectsProperty", "AnimationEffectsProperty"), # EffectSet*
Atom("animationEffectsForBeforeProperty", "AnimationsEffectsForBeforeProperty"), # EffectSet*
Atom("animationEffectsForAfterProperty", "AnimationsEffectsForAfterProperty"), # EffectSet*
Atom("animationEffectsForMarkerProperty", "AnimationsEffectsForMarkerProperty"), # EffectSet*
Atom("beforePseudoProperty", "beforePseudoProperty"), # nsXMLElement*
Atom("cssPseudoElementBeforeProperty", "CSSPseudoElementBeforeProperty"), # CSSPseudoElement*
Atom("cssPseudoElementAfterProperty", "CSSPseudoElementAfterProperty"), # CSSPseudoElement*
Atom("cssPseudoElementMarkerProperty", "CSSPseudoElementMarkerProperty"), # CSSPseudoElement*
Atom("transitionsProperty", "TransitionsProperty"), # FrameTransitions*
Atom("transitionsOfBeforeProperty", "TransitionsOfBeforeProperty"), # FrameTransitions*
Atom("transitionsOfAfterProperty", "TransitionsOfAfterProperty"), # FrameTransitions*
Atom("transitionsOfMarkerProperty", "TransitionsOfMarkerProperty"), # FrameTransitions*
Atom("genConInitializerProperty", "QuoteNodeProperty"),
Atom("labelMouseDownPtProperty", "LabelMouseDownPtProperty"),
Atom("lockedStyleStates", "lockedStyleStates"),