Backed out 4 changesets (bug 1062106) for build bustage

Backed out changeset 7ac1fffb6a87 (bug 1062106)
Backed out changeset 7682b2da0437 (bug 1062106)
Backed out changeset e77bfa57be61 (bug 1062106)
Backed out changeset a565aca3013c (bug 1062106)
This commit is contained in:
Iris Hsiao 2017-03-21 16:41:18 +08:00
Родитель fefc17425c
Коммит 96c6ba3303
28 изменённых файлов: 822 добавлений и 49 удалений

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

@ -54,6 +54,7 @@ needs to figure out the computational style of an element. Fired via
* "eRestyle_LaterSiblings"
* "eRestyle_CSSTransitions"
* "eRestyle_CSSAnimations"
* "eRestyle_SVGAttrAnimations"
* "eRestyle_StyleAttribute"
* "eRestyle_StyleAttribute_Animations"
* "eRestyle_Force"

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

@ -188,6 +188,7 @@
#include "mozilla/dom/nsCSPUtils.h"
#include "nsHTMLStyleSheet.h"
#include "nsHTMLCSSStyleSheet.h"
#include "SVGAttrAnimationRuleProcessor.h"
#include "mozilla/dom/DOMImplementation.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/Comment.h"
@ -2300,6 +2301,11 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet();
}
if (!mSVGAttrAnimationRuleProcessor) {
mSVGAttrAnimationRuleProcessor =
new mozilla::SVGAttrAnimationRuleProcessor();
}
// Now set up our style sets
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
@ -12361,6 +12367,12 @@ nsDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
mAttrStyleSheet->DOMSizeOfIncludingThis(aWindowSizes->mMallocSizeOf) :
0;
aWindowSizes->mDOMOtherSize +=
mSVGAttrAnimationRuleProcessor ?
mSVGAttrAnimationRuleProcessor->DOMSizeOfIncludingThis(
aWindowSizes->mMallocSizeOf) :
0;
aWindowSizes->mDOMOtherSize +=
mStyledLinks.ShallowSizeOfExcludingThis(aWindowSizes->mMallocSizeOf);

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

@ -109,6 +109,7 @@ class ErrorResult;
class EventStates;
class PendingAnimationTracker;
class StyleSetHandle;
class SVGAttrAnimationRuleProcessor;
template<typename> class OwningNonNull;
namespace css {
@ -1281,6 +1282,16 @@ public:
return mStyleAttrStyleSheet;
}
/**
* Get this document's SVG Animation rule processor. May return null
* if there isn't one.
*/
mozilla::SVGAttrAnimationRuleProcessor*
GetSVGAttrAnimationRuleProcessor() const
{
return mSVGAttrAnimationRuleProcessor;
}
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0;
/**
@ -3011,6 +3022,7 @@ protected:
RefPtr<mozilla::css::ImageLoader> mStyleImageLoader;
RefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
RefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
RefPtr<mozilla::SVGAttrAnimationRuleProcessor> mSVGAttrAnimationRuleProcessor;
// Tracking for images in the document.
RefPtr<mozilla::dom::ImageTracker> mImageTracker;

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

@ -282,6 +282,7 @@ private:
// Categories of node properties
// 0 is global.
#define DOM_USER_DATA 1
#define SMIL_MAPPED_ATTR_ANIMVAL 2
// IID for the nsINode interface
#define NS_INODE_IID \

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

@ -19,6 +19,7 @@ EXPORTS += [
'nsSMILInstanceTime.h',
'nsSMILInterval.h',
'nsSMILKeySpline.h',
'nsSMILMappedAttribute.h',
'nsSMILMilestone.h',
'nsSMILNullType.h',
'nsSMILRepeatCount.h',
@ -47,6 +48,7 @@ UNIFIED_SOURCES += [
'nsSMILInstanceTime.cpp',
'nsSMILInterval.cpp',
'nsSMILKeySpline.cpp',
'nsSMILMappedAttribute.cpp',
'nsSMILNullType.cpp',
'nsSMILParserUtils.cpp',
'nsSMILRepeatCount.cpp',

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

@ -687,10 +687,36 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
(aAnimElem->IsSVGElement(nsGkAtoms::animateTransform)))
return false;
// Look up target (animated) attribute-type
nsSMILTargetAttrType attributeType = aAnimElem->GetTargetAttributeType();
// Check if an 'auto' attributeType refers to a CSS property or XML attribute.
// Note that SMIL requires we search for CSS properties first. So if they
// overlap, 'auto' = 'CSS'. (SMILANIM 3.1)
bool isCSS = false;
if (attributeType == eSMILTargetAttrType_auto) {
if (attributeNamespaceID == kNameSpaceID_None) {
// width/height are special as they may be attributes or for
// outer-<svg> elements, mapped into style.
if (attributeName == nsGkAtoms::width ||
attributeName == nsGkAtoms::height) {
isCSS = targetElem->GetNameSpaceID() != kNameSpaceID_SVG;
} else {
nsCSSPropertyID prop =
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName),
CSSEnabledState::eForAllContent);
isCSS = nsSMILCSSProperty::IsPropertyAnimatable(prop);
}
}
} else {
isCSS = (attributeType == eSMILTargetAttrType_CSS);
}
// Construct the key
aResult.mElement = targetElem;
aResult.mAttributeName = attributeName;
aResult.mElement = targetElem;
aResult.mAttributeName = attributeName;
aResult.mAttributeNamespaceID = attributeNamespaceID;
aResult.mIsCSS = isCSS;
return true;
}
@ -710,9 +736,13 @@ nsSMILAnimationController::AddStyleUpdatesTo(RestyleTracker& aTracker)
continue;
}
aTracker.AddPendingRestyle(key.mElement,
eRestyle_StyleAttribute_Animations,
nsChangeHint(0));
// mIsCSS true means that the rules are the ones returned from
// Element::GetSMILOverrideStyleDeclaration (via nsSMILCSSProperty objects),
// and mIsCSS false means the rules are nsSMILMappedAttribute objects
// returned from nsSVGElement::GetAnimatedContentDeclarationBlock.
nsRestyleHint rshint = key.mIsCSS ? eRestyle_StyleAttribute_Animations
: eRestyle_SVGAttrAnimations;
aTracker.AddPendingRestyle(key.mElement, rshint, nsChangeHint(0));
}
mMightHavePendingStyleUpdates = false;

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

@ -25,7 +25,8 @@ nsSMILCompositor::HashKey(KeyTypePointer aKey)
// its 2 lowest-order bits. (Those shifted-off bits will always be 0 since
// our pointers will be word-aligned.)
return (NS_PTR_TO_UINT32(aKey->mElement.get()) >> 2) +
NS_PTR_TO_UINT32(aKey->mAttributeName.get());
NS_PTR_TO_UINT32(aKey->mAttributeName.get()) +
(aKey->mIsCSS ? 1 : 0);
}
// Cycle-collection support
@ -126,26 +127,18 @@ nsSMILCompositor::ClearAnimationEffects()
nsISMILAttr*
nsSMILCompositor::CreateSMILAttr()
{
nsCSSPropertyID propID =
nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName),
CSSEnabledState::eForAllContent);
if (nsSMILCSSProperty::IsPropertyAnimatable(propID)) {
// If we are animating the 'width' or 'height' of an outer SVG
// element we should animate it as a CSS property, but for other elements
// (e.g. <rect>) we should animate it as a length attribute.
// The easiest way to test for an outer SVG element, is to see if it is an
// SVG-namespace element mapping its width/height attribute to style.
bool animateAsAttr = (mKey.mAttributeName == nsGkAtoms::width ||
mKey.mAttributeName == nsGkAtoms::height) &&
mKey.mElement->GetNameSpaceID() == kNameSpaceID_SVG &&
!mKey.mElement->IsAttributeMapped(mKey.mAttributeName);
if (!animateAsAttr) {
return new nsSMILCSSProperty(propID, mKey.mElement.get());
if (mKey.mIsCSS) {
nsCSSPropertyID propId =
nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName),
CSSEnabledState::eForAllContent);
if (nsSMILCSSProperty::IsPropertyAnimatable(propId)) {
return new nsSMILCSSProperty(propId, mKey.mElement.get());
}
} else {
return mKey.mElement->GetAnimatedAttr(mKey.mAttributeNamespaceID,
mKey.mAttributeName);
}
return mKey.mElement->GetAnimatedAttr(mKey.mAttributeNamespaceID,
mKey.mAttributeName);
return nullptr;
}
uint32_t

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

@ -0,0 +1,150 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* representation of a SMIL-animatable mapped attribute on an element */
#include "nsSMILMappedAttribute.h"
#include "nsContentUtils.h"
#include "nsError.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
#include "nsSMILValue.h"
#include "nsSMILCSSValueType.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsCSSProps.h"
#include "mozilla/dom/Element.h"
// Callback function, for freeing string buffers stored in property table
static void
ReleaseStringBufferPropertyValue(void* aObject, /* unused */
nsIAtom* aPropertyName, /* unused */
void* aPropertyValue,
void* aData /* unused */)
{
nsStringBuffer* buf = static_cast<nsStringBuffer*>(aPropertyValue);
buf->Release();
}
nsresult
nsSMILMappedAttribute::ValueFromString(const nsAString& aStr,
const mozilla::dom::SVGAnimationElement* aSrcElement,
nsSMILValue& aValue,
bool& aPreventCachingOfSandwich) const
{
NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
&aPreventCachingOfSandwich);
return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
}
nsSMILValue
nsSMILMappedAttribute::GetBaseValue() const
{
nsAutoString baseStringValue;
RefPtr<nsIAtom> attrName = GetAttrNameAtom();
bool success = mElement->GetAttr(kNameSpaceID_None, attrName,
baseStringValue);
nsSMILValue baseValue;
if (success) {
// For base values, we don't need to worry whether the value returned is
// context-sensitive or not since the compositor will take care of comparing
// the returned (computed) base value and its cached value and determining
// if an update is required or not.
nsSMILCSSValueType::ValueFromString(mPropID, mElement,
baseStringValue, baseValue, nullptr);
} else {
// Attribute is unset -- use computed value.
// FIRST: Temporarily clear animated value, to make sure it doesn't pollute
// the computed value. (We want base value, _without_ animations applied.)
void* buf = mElement->UnsetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
attrName, nullptr);
FlushChangesToTargetAttr();
// SECOND: we use nsSMILCSSProperty::GetBaseValue to look up the property's
// computed value. NOTE: This call will temporarily clear the SMIL
// override-style for the corresponding CSS property on our target element.
// This prevents any animations that target the CSS property from affecting
// animations that target the mapped attribute.
baseValue = nsSMILCSSProperty::GetBaseValue();
// FINALLY: If we originally had an animated value set, then set it again.
if (buf) {
mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName, buf,
ReleaseStringBufferPropertyValue);
FlushChangesToTargetAttr();
}
}
return baseValue;
}
nsresult
nsSMILMappedAttribute::SetAnimValue(const nsSMILValue& aValue)
{
NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
// Convert nsSMILValue to string
nsAutoString valStr;
if (!nsSMILCSSValueType::ValueToString(aValue, valStr)) {
NS_WARNING("Failed to convert nsSMILValue for mapped attr into a string");
return NS_ERROR_FAILURE;
}
RefPtr<nsIAtom> attrName = GetAttrNameAtom();
nsStringBuffer* oldValStrBuf = static_cast<nsStringBuffer*>
(mElement->GetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName));
if (oldValStrBuf) {
nsString oldValStr;
nsContentUtils::PopulateStringFromStringBuffer(oldValStrBuf, oldValStr);
if (valStr.Equals(oldValStr)) {
// New animated value is the same as the old; nothing to do.
return NS_OK;
}
}
// Set the string as this mapped attribute's animated value.
nsStringBuffer* valStrBuf =
nsCSSValue::BufferFromString(nsString(valStr)).take();
nsresult rv = mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
attrName, valStrBuf,
ReleaseStringBufferPropertyValue);
if (rv == NS_PROPTABLE_PROP_OVERWRITTEN) {
rv = NS_OK;
}
FlushChangesToTargetAttr();
return rv;
}
void
nsSMILMappedAttribute::ClearAnimValue()
{
RefPtr<nsIAtom> attrName = GetAttrNameAtom();
mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName);
FlushChangesToTargetAttr();
}
void
nsSMILMappedAttribute::FlushChangesToTargetAttr() const
{
// Clear animated content-style-rule
mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL,
SMIL_MAPPED_ATTR_STYLEDECL_ATOM);
nsIDocument* doc = mElement->GetUncomposedDoc();
// Request animation restyle
if (doc) {
nsIPresShell* shell = doc->GetShell();
if (shell) {
shell->RestyleForAnimation(mElement, eRestyle_Self);
}
}
}
already_AddRefed<nsIAtom>
nsSMILMappedAttribute::GetAttrNameAtom() const
{
return NS_Atomize(nsCSSProps::GetStringValue(mPropID));
}

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

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* representation of a SMIL-animatable mapped attribute on an element */
#ifndef NS_SMILMAPPEDATTRIBUTE_H_
#define NS_SMILMAPPEDATTRIBUTE_H_
#include "mozilla/Attributes.h"
#include "nsSMILCSSProperty.h"
/* We'll use the empty-string atom |nsGkAtoms::_empty| as the key for storing an
* element's animated content style declaration in its Property Table, under the
* property-category SMIL_MAPPED_ATTR_ANIMVAL. Everything else stored in that
* category is keyed off of the XML attribute name, so the empty string is a
* good "reserved" key to use for storing the style rule (since XML attributes
* all have nonempty names).
*/
#define SMIL_MAPPED_ATTR_STYLEDECL_ATOM nsGkAtoms::_empty
/**
* nsSMILMappedAttribute: Implements the nsISMILAttr interface for SMIL
* animations whose targets are attributes that map to CSS properties. An
* instance of this class represents a particular animation-targeted mapped
* attribute on a particular element.
*/
class nsSMILMappedAttribute : public nsSMILCSSProperty {
public:
/**
* Constructs a new nsSMILMappedAttribute.
*
* @param aPropID The CSS property for the mapped attribute we're
* interested in animating.
* @param aElement The element whose attribute is being animated.
*/
nsSMILMappedAttribute(nsCSSPropertyID aPropID, mozilla::dom::Element* aElement) :
nsSMILCSSProperty(aPropID, aElement) {}
// nsISMILAttr methods
virtual nsresult ValueFromString(const nsAString& aStr,
const mozilla::dom::SVGAnimationElement* aSrcElement,
nsSMILValue& aValue,
bool& aPreventCachingOfSandwich) const override;
virtual nsSMILValue GetBaseValue() const override;
virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
virtual void ClearAnimValue() override;
protected:
// Helper Methods
void FlushChangesToTargetAttr() const;
already_AddRefed<nsIAtom> GetAttrNameAtom() const;
};
#endif // NS_SMILMAPPEDATTRIBUTE_H_

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

@ -12,7 +12,7 @@
/**
* Struct: nsSMILTargetIdentifier
*
* Tuple of: { Animated Element, Attribute Name }
* Tuple of: { Animated Element, Attribute Name, Attribute Type (CSS vs. XML) }
*
* Used in nsSMILAnimationController as hash key for mapping an animation
* target to the nsSMILCompositor for that target.
@ -26,18 +26,20 @@ struct nsSMILTargetIdentifier
{
nsSMILTargetIdentifier()
: mElement(nullptr), mAttributeName(nullptr),
mAttributeNamespaceID(kNameSpaceID_Unknown) {}
mAttributeNamespaceID(kNameSpaceID_Unknown), mIsCSS(false) {}
inline bool Equals(const nsSMILTargetIdentifier& aOther) const
{
return (aOther.mElement == mElement &&
aOther.mAttributeName == mAttributeName &&
aOther.mAttributeNamespaceID == mAttributeNamespaceID);
aOther.mAttributeNamespaceID == mAttributeNamespaceID &&
aOther.mIsCSS == mIsCSS);
}
RefPtr<mozilla::dom::Element> mElement;
RefPtr<nsIAtom> mAttributeName;
int32_t mAttributeNamespaceID;
RefPtr<nsIAtom> mAttributeName;
int32_t mAttributeNamespaceID;
bool mIsCSS;
};
/**
@ -55,7 +57,7 @@ class nsSMILWeakTargetIdentifier
public:
// Trivial constructor
nsSMILWeakTargetIdentifier()
: mElement(nullptr), mAttributeName(nullptr) {}
: mElement(nullptr), mAttributeName(nullptr), mIsCSS(false) {}
// Allow us to update a weak identifier to match a given non-weak identifier
nsSMILWeakTargetIdentifier&
@ -63,6 +65,7 @@ public:
{
mElement = aOther.mElement;
mAttributeName = aOther.mAttributeName;
mIsCSS = aOther.mIsCSS;
return *this;
}
@ -70,12 +73,14 @@ public:
inline bool Equals(const nsSMILTargetIdentifier& aOther) const
{
return (aOther.mElement == mElement &&
aOther.mAttributeName == mAttributeName);
aOther.mAttributeName == mAttributeName &&
aOther.mIsCSS == mIsCSS);
}
private:
const nsIContent* mElement;
const nsIAtom* mAttributeName;
bool mIsCSS;
};
#endif // NS_SMILTARGETIDENTIFIER_H_

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

@ -11,8 +11,6 @@
#include "mozilla/AutoRestore.h"
using namespace mozilla;
nsSMILTimeContainer::nsSMILTimeContainer()
:
mParent(nullptr),

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

@ -51,6 +51,15 @@ SVGAnimateMotionElement::GetTargetAttributeName(int32_t *aNamespaceID,
return true;
}
nsSMILTargetAttrType
SVGAnimateMotionElement::GetTargetAttributeType() const
{
// <animateMotion> doesn't take an attributeType, since it doesn't target an
// 'attribute' per se. We'll just return 'XML' for simplicity. (This just
// needs to match what we expect in nsSVGElement::GetAnimAttr.)
return eSMILTargetAttrType_XML;
}
} // namespace dom
} // namespace mozilla

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

@ -37,6 +37,7 @@ public:
virtual nsSMILAnimationFunction& AnimationFunction() override;
virtual bool GetTargetAttributeName(int32_t *aNamespaceID,
nsIAtom **aLocalName) const override;
virtual nsSMILTargetAttrType GetTargetAttributeType() const override;
// nsSVGElement
virtual nsIAtom* GetPathDataAttrName() const override {

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

@ -112,6 +112,21 @@ SVGAnimationElement::GetTargetAttributeName(int32_t *aNamespaceID,
aNamespaceID, aLocalName));
}
nsSMILTargetAttrType
SVGAnimationElement::GetTargetAttributeType() const
{
nsIContent::AttrValuesArray typeValues[] = { &nsGkAtoms::css,
&nsGkAtoms::XML,
nullptr};
nsSMILTargetAttrType smilTypes[] = { eSMILTargetAttrType_CSS,
eSMILTargetAttrType_XML };
int32_t index = FindAttrValueIn(kNameSpaceID_None,
nsGkAtoms::attributeType,
typeValues,
eCaseMatters);
return (index >= 0) ? smilTypes[index] : eSMILTargetAttrType_auto;
}
nsSMILTimedElement&
SVGAnimationElement::TimedElement()
{

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

@ -66,6 +66,7 @@ public:
Element* GetTargetElementContent();
virtual bool GetTargetAttributeName(int32_t* aNamespaceID,
nsIAtom** aLocalName) const;
virtual nsSMILTargetAttrType GetTargetAttributeType() const;
nsSMILTimedElement& TimedElement();
nsSMILTimeContainer* GetTimeContainer();
virtual nsSMILAnimationFunction& AnimationFunction() = 0;

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

@ -47,6 +47,7 @@
#include "nsIFrame.h"
#include "nsQueryObject.h"
#include <stdarg.h>
#include "nsSMILMappedAttribute.h"
#include "SVGMotionSMILAttr.h"
#include "nsAttrValueOrString.h"
#include "nsSMILAnimationController.h"
@ -933,6 +934,34 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
return NS_OK;
}
void
nsSVGElement::WalkAnimatedContentStyleRules(nsRuleWalker* aRuleWalker)
{
// Update & walk the animated content style rule, to include style from
// animated mapped attributes. But first, get nsPresContext to check
// whether this is a "no-animation restyle". (This should match the check
// in nsHTMLCSSStyleSheet::RulesMatching(), where we determine whether to
// apply the SMILOverrideStyle.)
RestyleManager* restyleManager =
aRuleWalker->PresContext()->RestyleManager();
MOZ_ASSERT(restyleManager->IsGecko(),
"stylo: Servo-backed style system should not be calling "
"WalkAnimatedContentStyleRules");
if (!restyleManager->AsGecko()->SkipAnimationRules()) {
// update/walk the animated content style rule.
DeclarationBlock* animContentDeclBlock = GetAnimatedContentDeclarationBlock();
if (!animContentDeclBlock) {
UpdateAnimatedContentDeclarationBlock();
animContentDeclBlock = GetAnimatedContentDeclarationBlock();
}
if (animContentDeclBlock) {
css::Declaration* declaration = animContentDeclBlock->AsGecko();
declaration->SetImmutable();
aRuleWalker->Forward(declaration);
}
}
}
NS_IMETHODIMP_(bool)
nsSVGElement::IsAttributeMapped(const nsIAtom* name) const
{
@ -1352,6 +1381,85 @@ nsSVGElement::GetContentDeclarationBlock() const
return mContentDeclarationBlock;
}
static void
ParseMappedAttrAnimValueCallback(void* aObject,
nsIAtom* aPropertyName,
void* aPropertyValue,
void* aData)
{
MOZ_ASSERT(aPropertyName != SMIL_MAPPED_ATTR_STYLEDECL_ATOM,
"animated content style rule should have been removed "
"from properties table already (we're rebuilding it now)");
MappedAttrParser* mappedAttrParser = static_cast<MappedAttrParser*>(aData);
MOZ_ASSERT(mappedAttrParser, "parser should be non-null");
nsStringBuffer* animValBuf = static_cast<nsStringBuffer*>(aPropertyValue);
MOZ_ASSERT(animValBuf, "animated value should be non-null");
nsString animValStr;
nsContentUtils::PopulateStringFromStringBuffer(animValBuf, animValStr);
mappedAttrParser->ParseMappedAttrValue(aPropertyName, animValStr);
}
// Callback for freeing animated content decl block, in property table.
static void
ReleaseDeclBlock(void* aObject, /* unused */
nsIAtom* aPropertyName,
void* aPropertyValue,
void* aData /* unused */)
{
MOZ_ASSERT(aPropertyName == SMIL_MAPPED_ATTR_STYLEDECL_ATOM,
"unexpected property name, for animated content style rule");
auto decl = static_cast<DeclarationBlock*>(aPropertyValue);
MOZ_ASSERT(decl, "unexpected null decl");
decl->Release();
}
void
nsSVGElement::UpdateAnimatedContentDeclarationBlock()
{
MOZ_ASSERT(!GetAnimatedContentDeclarationBlock(),
"Animated content declaration block already set");
nsIDocument* doc = OwnerDoc();
if (!doc) {
NS_ERROR("SVG element without owner document");
return;
}
// FIXME (bug 1342557): Support SMIL in Servo
MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
GetBaseURI(), this, StyleBackendType::Gecko);
doc->PropertyTable(SMIL_MAPPED_ATTR_ANIMVAL)->
Enumerate(this, ParseMappedAttrAnimValueCallback, &mappedAttrParser);
RefPtr<DeclarationBlock> animContentDeclBlock =
mappedAttrParser.GetDeclarationBlock();
if (animContentDeclBlock) {
#ifdef DEBUG
nsresult rv =
#endif
SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
SMIL_MAPPED_ATTR_STYLEDECL_ATOM,
animContentDeclBlock.forget().take(),
ReleaseDeclBlock);
MOZ_ASSERT(rv == NS_OK,
"SetProperty failed (or overwrote something)");
}
}
DeclarationBlock*
nsSVGElement::GetAnimatedContentDeclarationBlock()
{
return
static_cast<DeclarationBlock*>(GetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
SMIL_MAPPED_ATTR_STYLEDECL_ATOM,
nullptr));
}
/**
* Helper methods for the type-specific WillChangeXXX methods.
*
@ -2515,6 +2623,24 @@ nsISMILAttr*
nsSVGElement::GetAnimatedAttr(int32_t aNamespaceID, nsIAtom* aName)
{
if (aNamespaceID == kNameSpaceID_None) {
// We check mapped-into-style attributes first so that animations
// targeting width/height on outer-<svg> don't appear to be ignored
// because we returned a nsISMILAttr for the corresponding
// SVGAnimatedLength.
// Mapped attributes:
if (IsAttributeMapped(aName)) {
nsCSSPropertyID prop =
nsCSSProps::LookupProperty(nsDependentAtomString(aName),
CSSEnabledState::eForAllContent);
// Check IsPropertyAnimatable to avoid attributes that...
// - map to explicitly unanimatable properties (e.g. 'direction')
// - map to unsupported attributes (e.g. 'glyph-orientation-horizontal')
if (nsSMILCSSProperty::IsPropertyAnimatable(prop)) {
return new nsSMILMappedAttribute(prop, this);
}
}
// Transforms:
if (GetTransformListAttrName() == aName) {
// The transform attribute is being animated, so we must ensure that the

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

@ -357,6 +357,9 @@ protected:
nsIAtom* aAttribute,
const nsAString& aValue);
void UpdateAnimatedContentDeclarationBlock();
mozilla::DeclarationBlock* GetAnimatedContentDeclarationBlock();
nsAttrValue WillChangeValue(nsIAtom* aName);
// aNewValue is set to the old value. This value may be invalid if
// !StoresOwnData.

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

@ -408,8 +408,8 @@ RestyleManager::RestyleHintToString(nsRestyleHint aHint)
bool any = false;
const char* names[] = {
"Self", "SomeDescendants", "Subtree", "LaterSiblings", "CSSTransitions",
"CSSAnimations", "StyleAttribute", "StyleAttribute_Animations", "Force",
"ForceDescendants"
"CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
"StyleAttribute_Animations", "Force", "ForceDescendants"
};
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);

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

@ -441,6 +441,13 @@ enum nsRestyleHint {
// work.)
eRestyle_CSSAnimations = 1 << 5,
// Replace the style data coming from SVG animations (SMIL Animations)
// without updating any other style data. If a new style context
// results, update style contexts on the descendants. (Irrelevant if
// eRestyle_Self or eRestyle_Subtree is also set, since those imply a
// superset of the work.)
eRestyle_SVGAttrAnimations = 1 << 6,
// Replace the style data coming from inline style without updating
// any other style data. If a new style context results, update style
// contexts on the descendants. (Irrelevant if eRestyle_Self or
@ -450,26 +457,27 @@ enum nsRestyleHint {
// eRestyle_Self.
// If the change is for the advance of a declarative animation, use
// the value below instead.
eRestyle_StyleAttribute = 1 << 6,
eRestyle_StyleAttribute = 1 << 7,
// Same as eRestyle_StyleAttribute, but for when the change results
// from the advance of a declarative animation.
eRestyle_StyleAttribute_Animations = 1 << 7,
eRestyle_StyleAttribute_Animations = 1 << 8,
// Continue the restyling process to the current frame's children even
// if this frame's restyling resulted in no style changes.
eRestyle_Force = 1 << 8,
eRestyle_Force = 1 << 9,
// Continue the restyling process to all of the current frame's
// descendants, even if any frame's restyling resulted in no style
// changes. (Implies eRestyle_Force.) Note that this is weaker than
// eRestyle_Subtree, which makes us rerun selector matching on all
// descendants rather than just continuing the restyling process.
eRestyle_ForceDescendants = 1 << 9,
eRestyle_ForceDescendants = 1 << 10,
// Useful unions:
eRestyle_AllHintsWithAnimations = eRestyle_CSSTransitions |
eRestyle_CSSAnimations |
eRestyle_SVGAttrAnimations |
eRestyle_StyleAttribute_Animations,
};

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

@ -2,10 +2,10 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
onload="go()">
<!-- In this test, we change an animation element's "attributeType" attribute
to refer to another namespace, which invalidates a completed, frozen animation
(since there is no animatable 'x' attribute in the xlink namespace on a rect)
We verify that animation effects are removed from the previously-targeted
attribute. -->
to "CSS", which invalidates a completed, frozen animation (since in SVG,
there's no CSS property that matches the attributeName that we're
animating, "x"). We verify that animation effects are removed from the
previously-targeted attribute. -->
<script>
function go() {
// Seek animation before we start tweaking things, to make sure we've
@ -13,7 +13,7 @@
document.documentElement.setCurrentTime(2.0);
var anim = document.getElementById("anim");
anim.setAttributeNS(null, "attributeName", "xlink:x");
anim.setAttributeNS(null, "attributeType", "CSS");
setTimeAndSnapshot(2.5, false);
}
</script>

До

Ширина:  |  Высота:  |  Размер: 1.0 KiB

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

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

@ -0,0 +1,128 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="document.documentElement.setCurrentTime(1);
setTimeAndSnapshot(1, false)">
<!-- XXXdholbert the above "document.documentElement.setCurrentTime" call
shouldn't be necessary - it's a temporary workaround for Bug 552873 -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<!-- This test consists of a 4x3 grid, containing various cases with
animations that have attributeType="CSS" vs "XML", for the
presentational ("mapped") attribute 'fill-opacity'.
As one would expect, the "CSS" and "XML" versions are treated as
separate animation targets. However, there are some interactions:
- When they conflict, both the inline style & any animations with
attributeType="CSS" will have higher priority than the XML attribute
and animations with attributeType="XML".
- However, as described in the "FIRST ROW" comment below, animations
with attributeType="XML" can sometimes feed in to the base value
used for animations with attributeType="CSS". -->
<!-- GIANT GREEN BACKGROUND -->
<!-- (We'll put red rects on top, and then animate them to be transparent -->
<rect height="100%" width="100%" fill="lime" />
<!-- FIRST ROW: Additive CSS and XML animations, with CSS or XML base values.
When the base value is set using the inline style attribute, the
attributeType="XML" animation should be ignored, because the XML
attribute gets masked by the inline style.
However, when the base value is set using the XML attribute (or more
generally, when attributeType="XML" animations aren't masked by a value
in the inline style or in a stylesheet), then the animations will
effectively add together, because the (animated) XML attribute feeds
into the computed style, which gets used as the base value for the CSS
animation. -->
<g>
<!-- CSS base value + CSS animation + XML animation -->
<rect x="0" width="50" height="50" fill="red" style="fill-opacity: 0.5">
<animate attributeName="fill-opacity" attributeType="XML"
by="1" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="CSS"
by="-0.5" dur="1s" fill="freeze"/>
</rect>
<!-- CSS base value + XML animation + CSS animation -->
<rect x="50" width="50" height="50" fill="red" style="fill-opacity: 0.5">
<animate attributeName="fill-opacity" attributeType="CSS"
by="-0.5" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="XML"
by="1" dur="1s" fill="freeze"/>
</rect>
<!-- XML base value + CSS animation + XML animation -->
<rect x="100" width="50" height="50" fill="red" fill-opacity="0.5">
<animate attributeName="fill-opacity" attributeType="XML"
by="-0.2" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="CSS"
by="-0.3" dur="1s" fill="freeze"/>
</rect>
<!-- XML base value + XML animation + CSS animation -->
<rect x="150" width="50" height="50" fill="red" fill-opacity="0.5">
<animate attributeName="fill-opacity" attributeType="CSS"
by="-0.2" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="XML"
by="-0.3" dur="1s" fill="freeze"/>
</rect>
</g>
<!-- SECOND ROW: Single animation, with CSS or XML attributeType & base value.
In every case except for CSS-base-value + XML animation, the animation
should take effect. -->
<g transform="translate(0, 50)">
<!-- CSS base value + CSS animation -->
<rect x="0" width="50" height="50" fill="red" style="fill-opacity: 0.5">
<animate attributeName="fill-opacity" attributeType="CSS"
to="0" dur="1s" fill="freeze"/>
</rect>
<!-- CSS base value + XML animation -->
<!-- (starting at fill-opacity 0, since anim shouldn't have any effect -->
<rect x="50" width="50" height="50" fill="red" style="fill-opacity: 0">
<animate attributeName="fill-opacity" attributeType="XML"
to="0.5" dur="1s" fill="freeze"/>
</rect>
<!-- XML base value + CSS animation -->
<rect x="100" width="50" height="50" fill="red" fill-opacity="0.5">
<animate attributeName="fill-opacity" attributeType="CSS"
to="0" dur="1s" fill="freeze"/>
</rect>
<!-- XML base value + XML animation -->
<rect x="150" width="50" height="50" fill="red" fill-opacity="0.5">
<animate attributeName="fill-opacity" attributeType="XML"
to="0" dur="1s" fill="freeze"/>
</rect>
</g>
<!-- THIRD ROW: Competing animations, with CSS or XML attributeType & base
value. In each case, the attributeType="CSS" animation should win. -->
<g transform="translate(0, 100)">
<!-- CSS base value + CSS animation animation vs XML animation -->
<rect x="0" width="50" height="50" fill="red" style="fill-opacity: 0.5">
<animate attributeName="fill-opacity" attributeType="CSS"
to="0" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="XML"
to="1" dur="1s" fill="freeze"/>
</rect>
<!-- CSS base value + XML animation vs CSS animation -->
<rect x="50" width="50" height="50" fill="red" style="fill-opacity: 0.5">
<animate attributeName="fill-opacity" attributeType="XML"
to="1" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="CSS"
to="0" dur="1s" fill="freeze"/>
</rect>
<!-- XML base value + CSS animation vs XML animation -->
<rect x="100" width="50" height="50" fill="red" fill-opacity="0.5">
<animate attributeName="fill-opacity" attributeType="CSS"
to="0" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="XML"
to="1" dur="1s" fill="freeze"/>
</rect>
<!-- XML base value + XML animation vs CSS animation -->
<rect x="150" width="50" height="50" fill="red" fill-opacity="0.5">
<animate attributeName="fill-opacity" attributeType="XML"
to="1" dur="1s" fill="freeze"/>
<animate attributeName="fill-opacity" attributeType="CSS"
to="0" dur="1s" fill="freeze"/>
</rect>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 6.4 KiB

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

@ -253,6 +253,9 @@ fuzzy-if(cocoaWidget&&layersGPUAccelerated,1,2) == anim-gradient-attr-presence-0
== mapped-attr-long-url-1.svg lime.svg
== mapped-attr-long-url-2.svg lime.svg
# interaction between xml mapped attributes and their css equivalents
== mapped-attr-vs-css-prop-1.svg lime.svg
== min-1.svg lime.svg
== smil-transitions-interaction-1a.svg lime.svg

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

@ -0,0 +1,122 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* style rule processor for rules from SMIL Animation of SVG mapped
* attributes (attributes whose values are mapped into style)
*/
#include "SVGAttrAnimationRuleProcessor.h"
#include "nsRuleProcessorData.h"
#include "nsSVGElement.h"
using namespace mozilla;
using namespace mozilla::dom;
SVGAttrAnimationRuleProcessor::SVGAttrAnimationRuleProcessor()
{
}
SVGAttrAnimationRuleProcessor::~SVGAttrAnimationRuleProcessor()
{
}
NS_IMPL_ISUPPORTS(SVGAttrAnimationRuleProcessor, nsIStyleRuleProcessor)
/* virtual */ void
SVGAttrAnimationRuleProcessor::RulesMatching(ElementRuleProcessorData* aData)
{
ElementRulesMatching(aData->mElement, aData->mRuleWalker);
}
void
SVGAttrAnimationRuleProcessor::ElementRulesMatching(Element* aElement,
nsRuleWalker* aRuleWalker)
{
if (aElement->IsSVGElement()) {
static_cast<nsSVGElement*>(aElement)->
WalkAnimatedContentStyleRules(aRuleWalker);
}
}
/* virtual */ nsRestyleHint
SVGAttrAnimationRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData)
{
return nsRestyleHint(0);
}
/* virtual */ nsRestyleHint
SVGAttrAnimationRuleProcessor::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
{
return nsRestyleHint(0);
}
/* virtual */ bool
SVGAttrAnimationRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
{
return false;
}
/* virtual */ nsRestyleHint
SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
{
return nsRestyleHint(0);
}
/* virtual */ bool
SVGAttrAnimationRuleProcessor::MediumFeaturesChanged(nsPresContext* aPresContext)
{
return false;
}
/* virtual */ void
SVGAttrAnimationRuleProcessor::RulesMatching(PseudoElementRuleProcessorData* aData)
{
// If SMIL Animation of SVG attributes can ever target
// pseudo-elements, we need to adjust either
// nsStyleSet::RuleNodeWithReplacement or the test in
// ElementRestyler::RestyleSelf (added in bug 977991 patch 4) to
// handle such styles.
}
/* virtual */ void
SVGAttrAnimationRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData)
{
// If SMIL Animation of SVG attributes can ever target anonymous boxes,
// see comment in RulesMatching(PseudoElementRuleProcessorData*).
}
#ifdef MOZ_XUL
/* virtual */ void
SVGAttrAnimationRuleProcessor::RulesMatching(XULTreeRuleProcessorData* aData)
{
// If SMIL Animation of SVG attributes can ever target XUL tree pseudos,
// see comment in RulesMatching(PseudoElementRuleProcessorData*).
}
#endif
/* virtual */ size_t
SVGAttrAnimationRuleProcessor::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
return 0; // SVGAttrAnimationRuleProcessors are charged to the DOM, not layout
}
/* virtual */ size_t
SVGAttrAnimationRuleProcessor::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
return 0; // SVGAttrAnimationRuleProcessors are charged to the DOM, not layout
}
size_t
SVGAttrAnimationRuleProcessor::DOMSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
return n;
}

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

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* style rule processor for rules from SMIL Animation of SVG mapped
* attributes (attributes whose values are mapped into style)
*/
#ifndef mozilla_SVGAttrAnimationRuleProcessor_h_
#define mozilla_SVGAttrAnimationRuleProcessor_h_
#include "nsIStyleRuleProcessor.h"
class nsRuleWalker;
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
class SVGAttrAnimationRuleProcessor final : public nsIStyleRuleProcessor
{
public:
SVGAttrAnimationRuleProcessor();
private:
~SVGAttrAnimationRuleProcessor();
public:
NS_DECL_ISUPPORTS
// nsIStyleRuleProcessor API
virtual void RulesMatching(ElementRuleProcessorData* aData) override;
virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override;
virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
#ifdef MOZ_XUL
virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
#endif
virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult) override;
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;
size_t DOMSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
// A shortcut for nsStyleSet to call RulesMatching with less setup.
void ElementRulesMatching(mozilla::dom::Element* aElement,
nsRuleWalker* aRuleWalker);
private:
SVGAttrAnimationRuleProcessor(const SVGAttrAnimationRuleProcessor& aCopy) = delete;
SVGAttrAnimationRuleProcessor& operator=(const SVGAttrAnimationRuleProcessor& aCopy) = delete;
};
} // namespace mozilla
#endif /* !defined(mozilla_SVGAttrAnimationRuleProcessor_h_) */

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

@ -21,6 +21,7 @@ enum class SheetType : uint8_t {
Agent, // CSS
User, // CSS
PresHint,
SVGAttrAnimation,
Doc, // CSS
ScopedDoc,
StyleAttr,

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

@ -228,6 +228,7 @@ UNIFIED_SOURCES += [
'StyleAnimationValue.cpp',
'StyleRule.cpp',
'StyleSheet.cpp',
'SVGAttrAnimationRuleProcessor.cpp',
]
# - nsCSSRuleProcessor.cpp needs to be built separately because it uses

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

@ -36,6 +36,7 @@
#include "GeckoProfiler.h"
#include "nsHTMLCSSStyleSheet.h"
#include "nsHTMLStyleSheet.h"
#include "SVGAttrAnimationRuleProcessor.h"
#include "nsCSSRules.h"
#include "nsPrintfCString.h"
#include "nsIFrame.h"
@ -292,6 +293,7 @@ nsStyleSet::Init(nsPresContext *aPresContext)
// don't have style sheets. The other levels will have their calls
// triggered by DirtyRuleProcessors.
GatherRuleProcessors(SheetType::PresHint);
GatherRuleProcessors(SheetType::SVGAttrAnimation);
GatherRuleProcessors(SheetType::StyleAttr);
GatherRuleProcessors(SheetType::Animation);
GatherRuleProcessors(SheetType::Transition);
@ -476,6 +478,11 @@ nsStyleSet::GatherRuleProcessors(SheetType aType)
mRuleProcessors[aType] =
PresContext()->Document()->GetAttributeStyleSheet();
return NS_OK;
case SheetType::SVGAttrAnimation:
MOZ_ASSERT(mSheets[aType].IsEmpty());
mRuleProcessors[aType] =
PresContext()->Document()->GetSVGAttrAnimationRuleProcessor();
return NS_OK;
default:
// keep going
break;
@ -1108,6 +1115,7 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
// - UA normal rules = Agent normal
// - User normal rules = User normal
// - Presentation hints = PresHint normal
// - SVG Animation (highest pres hint) = SVGAttrAnimation normal
// - Author normal rules = Document normal
// - Override normal rules = Override normal
// - animation rules = Animation normal
@ -1139,7 +1147,11 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
aRuleWalker->SetLevel(SheetType::PresHint, false, false);
if (mRuleProcessors[SheetType::PresHint])
(*aCollectorFunc)(mRuleProcessors[SheetType::PresHint], aData);
nsRuleNode* lastPresHintRN = aRuleWalker->CurrentNode();
aRuleWalker->SetLevel(SheetType::SVGAttrAnimation, false, false);
if (mRuleProcessors[SheetType::SVGAttrAnimation])
(*aCollectorFunc)(mRuleProcessors[SheetType::SVGAttrAnimation], aData);
nsRuleNode* lastSVGAttrAnimationRN = aRuleWalker->CurrentNode();
aRuleWalker->SetLevel(SheetType::Doc, false, true);
bool cutOffInheritance = false;
@ -1213,11 +1225,11 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
if (haveImportantDocRules) {
aRuleWalker->SetLevel(SheetType::Doc, true, false);
AddImportantRules(lastDocRN, lastPresHintRN, aRuleWalker); // doc
AddImportantRules(lastDocRN, lastSVGAttrAnimationRN, aRuleWalker); // doc
}
#ifdef DEBUG
else {
AssertNoImportantRules(lastDocRN, lastPresHintRN);
AssertNoImportantRules(lastDocRN, lastSVGAttrAnimationRN);
}
#endif
@ -1242,7 +1254,7 @@ nsStyleSet::FileRules(nsIStyleRuleProcessor::EnumFunc aCollectorFunc,
#endif
#ifdef DEBUG
AssertNoCSSRules(lastPresHintRN, lastUserRN);
AssertNoCSSRules(lastSVGAttrAnimationRN, lastUserRN);
#endif
if (haveImportantUserRules) {
@ -1299,6 +1311,9 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
if (mRuleProcessors[SheetType::PresHint])
(*aFunc)(mRuleProcessors[SheetType::PresHint], aData);
if (mRuleProcessors[SheetType::SVGAttrAnimation])
(*aFunc)(mRuleProcessors[SheetType::SVGAttrAnimation], aData);
bool cutOffInheritance = false;
if (mBindingManager) {
// We can supply additional document-level sheets that should be walked.
@ -1482,6 +1497,7 @@ static const CascadeLevel gCascadeLevels[] = {
{ SheetType::Agent, false, false, nsRestyleHint(0) },
{ SheetType::User, false, false, nsRestyleHint(0) },
{ SheetType::PresHint, false, false, nsRestyleHint(0) },
{ SheetType::SVGAttrAnimation, false, false, eRestyle_SVGAttrAnimations },
{ SheetType::Doc, false, false, nsRestyleHint(0) },
{ SheetType::ScopedDoc, false, false, nsRestyleHint(0) },
{ SheetType::StyleAttr, false, true, eRestyle_StyleAttribute |
@ -1519,6 +1535,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
MOZ_ASSERT(!(aReplacements & ~(eRestyle_CSSTransitions |
eRestyle_CSSAnimations |
eRestyle_SVGAttrAnimations |
eRestyle_StyleAttribute |
eRestyle_StyleAttribute_Animations)),
"unexpected replacement bits");
@ -1638,6 +1655,16 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
}
break;
}
case SheetType::SVGAttrAnimation: {
SVGAttrAnimationRuleProcessor* ruleProcessor =
static_cast<SVGAttrAnimationRuleProcessor*>(
mRuleProcessors[SheetType::SVGAttrAnimation].get());
if (ruleProcessor &&
aPseudoType == CSSPseudoElementType::NotPseudo) {
ruleProcessor->ElementRulesMatching(aElement, &ruleWalker);
}
break;
}
case SheetType::StyleAttr: {
if (!level->mIsImportant) {
// First time through, we handle the non-!important rule.

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

@ -46,7 +46,7 @@ function observeStyling(frameCount) {
var markers = docShell.popProfileTimelineMarkers();
docShell.recordProfileTimelineMarkers = false;
var stylingMarkers = markers.filter(function(marker, index) {
return marker.restyleHint == "eRestyle_StyleAttribute_Animations";
return marker.restyleHint == "eRestyle_SVGAttrAnimations";
});
resolve(stylingMarkers);
});