2 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 #include "SVGMPathElement.h"
24 #include "SVGAnimateMotionElement.h"
25 #include "SVGDocumentExtensions.h"
27 #include "SVGPathElement.h"
28 #include "XLinkNames.h"
29 #include <wtf/NeverDestroyed.h>
33 // Animated property definitions
34 DEFINE_ANIMATED_STRING(SVGMPathElement, XLinkNames::hrefAttr, Href, href)
35 DEFINE_ANIMATED_BOOLEAN(SVGMPathElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
37 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMPathElement)
38 REGISTER_LOCAL_ANIMATED_PROPERTY(href)
39 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
40 END_REGISTER_ANIMATED_PROPERTIES
42 inline SVGMPathElement::SVGMPathElement(const QualifiedName& tagName, Document& document)
43 : SVGElement(tagName, document)
45 ASSERT(hasTagName(SVGNames::mpathTag));
46 registerAnimatedPropertiesForSVGMPathElement();
49 PassRefPtr<SVGMPathElement> SVGMPathElement::create(const QualifiedName& tagName, Document& document)
51 return adoptRef(new SVGMPathElement(tagName, document));
54 SVGMPathElement::~SVGMPathElement()
56 clearResourceReferences();
59 void SVGMPathElement::buildPendingResource()
61 clearResourceReferences();
66 Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
68 // Do not register as pending if we are already pending this resource.
69 if (document().accessSVGExtensions().isPendingResource(this, id))
73 document().accessSVGExtensions().addPendingResource(id, this);
74 ASSERT(hasPendingResources());
76 } else if (target->isSVGElement()) {
77 // Register us with the target in the dependencies map. Any change of hrefElement
78 // that leads to relayout/repainting now informs us, so we can react to it.
79 document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target));
85 void SVGMPathElement::clearResourceReferences()
87 document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
90 Node::InsertionNotificationRequest SVGMPathElement::insertedInto(ContainerNode& rootParent)
92 SVGElement::insertedInto(rootParent);
93 if (rootParent.inDocument())
94 return InsertionShouldCallDidNotifySubtreeInsertions;
98 void SVGMPathElement::didNotifySubtreeInsertions(ContainerNode*)
100 buildPendingResource();
103 void SVGMPathElement::removedFrom(ContainerNode& rootParent)
105 SVGElement::removedFrom(rootParent);
106 notifyParentOfPathChange(&rootParent);
107 if (rootParent.inDocument())
108 clearResourceReferences();
111 bool SVGMPathElement::isSupportedAttribute(const QualifiedName& attrName)
113 static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
114 if (supportedAttributes.get().isEmpty()) {
115 SVGURIReference::addSupportedAttributes(supportedAttributes);
116 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
118 return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
121 void SVGMPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
123 if (!isSupportedAttribute(name)) {
124 SVGElement::parseAttribute(name, value);
128 if (SVGURIReference::parseAttribute(name, value))
130 if (SVGExternalResourcesRequired::parseAttribute(name, value))
133 ASSERT_NOT_REACHED();
136 void SVGMPathElement::svgAttributeChanged(const QualifiedName& attrName)
138 if (!isSupportedAttribute(attrName)) {
139 SVGElement::svgAttributeChanged(attrName);
143 SVGElementInstance::InvalidationGuard invalidationGuard(this);
145 if (SVGURIReference::isKnownAttribute(attrName)) {
146 buildPendingResource();
150 if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
153 ASSERT_NOT_REACHED();
156 SVGPathElement* SVGMPathElement::pathElement()
158 Element* target = targetElementFromIRIString(href(), document());
159 if (target && isSVGPathElement(target))
160 return downcast<SVGPathElement>(target);
164 void SVGMPathElement::targetPathChanged()
166 notifyParentOfPathChange(parentNode());
169 void SVGMPathElement::notifyParentOfPathChange(ContainerNode* parent)
171 if (parent && isSVGAnimateMotionElement(parent))
172 downcast<SVGAnimateMotionElement>(*parent).updateAnimationPath();
175 } // namespace WebCore