From 83dfd545a324eed86b9ba483d52166a580a22f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 2 Sep 2024 17:26:20 +0000 Subject: [PATCH] Bug 1914221 - Map pattern/gradientTransform to the transform property. r=longsonr And fix a typo in a test which got me confused. Differential Revision: https://phabricator.services.mozilla.com/D220728 --- dom/svg/SVGElement.cpp | 47 +++++++++---------- dom/svg/SVGGradientElement.cpp | 5 ++ dom/svg/SVGGradientElement.h | 3 +- dom/svg/SVGPatternElement.cpp | 5 ++ dom/svg/SVGPatternElement.h | 1 + .../svg/pattern-transform-presence-01-ref.svg | 8 +--- .../svg/pattern-transform-presence-01.svg | 5 +- layout/svg/SVGGradientFrame.cpp | 40 +++++----------- layout/svg/SVGGradientFrame.h | 3 +- layout/svg/SVGPatternFrame.cpp | 31 +++++------- layout/svg/SVGPatternFrame.h | 2 +- servo/components/style/sharing/mod.rs | 10 ++++ ...entation-attributes-special-cases.html.ini | 13 ----- ...presentation-attributes-special-cases.html | 2 +- 14 files changed, 76 insertions(+), 99 deletions(-) diff --git a/dom/svg/SVGElement.cpp b/dom/svg/SVGElement.cpp index 6e92b82ec67d..a75a3b86f9f4 100644 --- a/dom/svg/SVGElement.cpp +++ b/dom/svg/SVGElement.cpp @@ -1334,38 +1334,43 @@ void SVGElement::UpdateMappedDeclarationBlock() { const bool lengthAffectsStyle = SVGGeometryProperty::ElementMapsLengthsToStyle(this); bool sawTransform = false; - uint32_t i = 0; while (BorrowedAttrInfo info = GetAttrInfoAt(i++)) { const nsAttrName* attrName = info.mName; - if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom())) { + if (!attrName->IsAtom()) { continue; } - if (attrName->Atom() == nsGkAtoms::lang && + nsAtom* nameAtom = attrName->Atom(); + if (!IsAttributeMapped(nameAtom)) { + continue; + } + + if (nameAtom == nsGkAtoms::lang && HasAttr(kNameSpaceID_XML, nsGkAtoms::lang)) { // xml:lang has precedence, and will get set via Gecko_GetXMLLangValue(). continue; } if (lengthAffectsStyle) { - auto const* length = GetAnimatedLength(attrName->Atom()); + auto const* length = GetAnimatedLength(nameAtom); if (length && length->HasBaseVal()) { // This is an element with geometry property set via SVG attribute, // and the attribute is already successfully parsed. We want to go // through the optimized path to tell the style system the result // directly, rather than let it parse the same thing again. - mappedAttrParser.TellStyleAlreadyParsedResult(attrName->Atom(), - *length); + mappedAttrParser.TellStyleAlreadyParsedResult(nameAtom, *length); continue; } } - if (attrName->Atom() == nsGkAtoms::transform) { + if (nameAtom == nsGkAtoms::transform || + nameAtom == nsGkAtoms::patternTransform || + nameAtom == nsGkAtoms::gradientTransform) { sawTransform = true; const auto* transform = GetAnimatedTransformList(); - MOZ_ASSERT(GetTransformListAttrName() == nsGkAtoms::transform); + MOZ_ASSERT(GetTransformListAttrName() == nameAtom); MOZ_ASSERT(transform); // We want to go through the optimized path to tell the style system the // result directly, rather than let it parse the same thing again. @@ -1373,7 +1378,7 @@ void SVGElement::UpdateMappedDeclarationBlock() { continue; } - if (attrName->Atom() == nsGkAtoms::d) { + if (nameAtom == nsGkAtoms::d) { const auto* path = GetAnimPathSegList(); // Note: Only SVGPathElement has d attribute. MOZ_ASSERT( @@ -1399,7 +1404,7 @@ void SVGElement::UpdateMappedDeclarationBlock() { nsAutoString value; info.mValue->ToString(value); - mappedAttrParser.ParseMappedAttrValue(attrName->Atom(), value); + mappedAttrParser.ParseMappedAttrValue(nameAtom, value); } // We need to map the SVG view's transform if we haven't mapped it already. @@ -2082,21 +2087,15 @@ void SVGElement::DidChangeTransformList( void SVGElement::DidAnimateTransformList(int32_t aModType) { MOZ_ASSERT(GetTransformListAttrName(), "Animating non-existent transform data?"); - - nsAtom* transformAttr = GetTransformListAttrName(); - if (transformAttr == nsGkAtoms::transform) { - const auto* animTransformList = GetAnimatedTransformList(); - const auto* animateMotion = GetAnimateMotionTransform(); - if (animateMotion || - (animTransformList && animTransformList->IsAnimating())) { - SMILOverrideStyle()->SetSMILValue(eCSSProperty_transform, - animTransformList, animateMotion); - } else { - SMILOverrideStyle()->ClearSMILValue(eCSSProperty_transform); - } - return; + const auto* animTransformList = GetAnimatedTransformList(); + const auto* animateMotion = GetAnimateMotionTransform(); + if (animateMotion || + (animTransformList && animTransformList->IsAnimating())) { + SMILOverrideStyle()->SetSMILValue(eCSSProperty_transform, animTransformList, + animateMotion); + } else { + SMILOverrideStyle()->ClearSMILValue(eCSSProperty_transform); } - DidAnimateAttribute(kNameSpaceID_None, transformAttr); } SVGElement::StringAttributesInfo SVGElement::GetStringInfo() { diff --git a/dom/svg/SVGGradientElement.cpp b/dom/svg/SVGGradientElement.cpp index 9b59a92a6b4a..192c8550c398 100644 --- a/dom/svg/SVGGradientElement.cpp +++ b/dom/svg/SVGGradientElement.cpp @@ -208,6 +208,11 @@ already_AddRefed SVGRadialGradientElement::Fr() { return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this); } +bool SVGGradientElement::IsAttributeMapped(const nsAtom* aAttribute) const { + return aAttribute == nsGkAtoms::gradientTransform || + SVGElement::IsAttributeMapped(aAttribute); +} + //---------------------------------------------------------------------- // SVGElement methods diff --git a/dom/svg/SVGGradientElement.h b/dom/svg/SVGGradientElement.h index 69d7f6ed95da..bce61a3780bd 100644 --- a/dom/svg/SVGGradientElement.h +++ b/dom/svg/SVGGradientElement.h @@ -45,11 +45,12 @@ class SVGGradientElement : public SVGGradientElementBase { // nsIContent nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override = 0; - virtual SVGAnimatedTransformList* GetAnimatedTransformList( + SVGAnimatedTransformList* GetAnimatedTransformList( uint32_t aFlags = 0) override; nsStaticAtom* GetTransformListAttrName() const override { return nsGkAtoms::gradientTransform; } + NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override; // WebIDL already_AddRefed GradientUnits(); diff --git a/dom/svg/SVGPatternElement.cpp b/dom/svg/SVGPatternElement.cpp index 5a0a9a46f292..0cb9bf664e4e 100644 --- a/dom/svg/SVGPatternElement.cpp +++ b/dom/svg/SVGPatternElement.cpp @@ -66,6 +66,11 @@ already_AddRefed SVGPatternElement::ViewBox() { return mViewBox.ToSVGAnimatedRect(this); } +bool SVGPatternElement::IsAttributeMapped(const nsAtom* aAttribute) const { + return aAttribute == nsGkAtoms::patternTransform || + SVGPatternElementBase::IsAttributeMapped(aAttribute); +} + already_AddRefed SVGPatternElement::PreserveAspectRatio() { return mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(this); diff --git a/dom/svg/SVGPatternElement.h b/dom/svg/SVGPatternElement.h index e82a736938ab..76847572633b 100644 --- a/dom/svg/SVGPatternElement.h +++ b/dom/svg/SVGPatternElement.h @@ -41,6 +41,7 @@ class SVGPatternElement final : public SVGPatternElementBase { public: // nsIContent interface nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override; + NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override; // SVGSVGElement methods: bool HasValidDimensions() const override; diff --git a/layout/reftests/svg/pattern-transform-presence-01-ref.svg b/layout/reftests/svg/pattern-transform-presence-01-ref.svg index f57dcf0ddf5e..49e1828a8448 100644 --- a/layout/reftests/svg/pattern-transform-presence-01-ref.svg +++ b/layout/reftests/svg/pattern-transform-presence-01-ref.svg @@ -8,18 +8,12 @@ - - - - - - - + diff --git a/layout/reftests/svg/pattern-transform-presence-01.svg b/layout/reftests/svg/pattern-transform-presence-01.svg index f5e59e3bfcda..2ddfaed065f9 100644 --- a/layout/reftests/svg/pattern-transform-presence-01.svg +++ b/layout/reftests/svg/pattern-transform-presence-01.svg @@ -37,9 +37,8 @@ function addTransform() which are not defined on this element are inherited by this element.'). Hence this pattern should look IDENTICAL to patternBase. --> - +