Rename AtomicString to AtomString
[WebKit-https.git] / Source / WebCore / svg / SVGElement.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4  * Copyright (C) 2009-2019 Apple Inc. All rights reserved.
5  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #pragma once
24
25 #include "SVGAnimatedPropertyImpl.h"
26 #include "SVGLangSpace.h"
27 #include "SVGLocatable.h"
28 #include "SVGNames.h"
29 #include "SVGParsingError.h"
30 #include "SVGPropertyOwnerRegistry.h"
31 #include "StyledElement.h"
32 #include <wtf/HashMap.h>
33 #include <wtf/HashSet.h>
34 #include <wtf/WeakPtr.h>
35
36 namespace WebCore {
37
38 class AffineTransform;
39 class CSSStyleDeclaration;
40 class DeprecatedCSSOMValue;
41 class Document;
42 class SVGDocumentExtensions;
43 class SVGElementRareData;
44 class SVGPropertyAnimatorFactory;
45 class SVGSVGElement;
46 class SVGUseElement;
47
48 void mapAttributeToCSSProperty(HashMap<AtomStringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName);
49
50 class SVGElement : public StyledElement, public SVGLangSpace, public SVGPropertyOwner {
51     WTF_MAKE_ISO_ALLOCATED(SVGElement);
52 public:
53     bool isOutermostSVGSVGElement() const;
54
55     SVGSVGElement* ownerSVGElement() const;
56     SVGElement* viewportElement() const;
57
58     String title() const override;
59     RefPtr<DeprecatedCSSOMValue> getPresentationAttribute(const String& name);
60     virtual bool supportsMarkers() const { return false; }
61     bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); }
62     virtual bool needsPendingResourceHandling() const { return true; }
63     bool instanceUpdatesBlocked() const;
64     void setInstanceUpdatesBlocked(bool);
65     virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const;
66
67     virtual bool isSVGGraphicsElement() const { return false; }
68     virtual bool isSVGGeometryElement() const { return false; }
69     virtual bool isFilterEffect() const { return false; }
70     virtual bool isGradientStop() const { return false; }
71     virtual bool isTextContent() const { return false; }
72     virtual bool isSMILElement() const { return false; }
73
74     // For SVGTests
75     virtual bool isValid() const { return true; }
76
77     virtual void svgAttributeChanged(const QualifiedName&);
78
79     void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
80     void sendSVGLoadEventIfPossibleAsynchronously();
81     void svgLoadEventTimerFired();
82     virtual Timer* svgLoadEventTimer();
83
84     virtual AffineTransform* supplementalTransform() { return nullptr; }
85
86     void invalidateSVGAttributes() { ensureUniqueElementData().setAnimatedSVGAttributesAreDirty(true); }
87     void invalidateSVGPresentationAttributeStyle()
88     {
89         ensureUniqueElementData().setPresentationAttributeStyleIsDirty(true);
90         // Trigger style recalculation for "elements as resource" (e.g. referenced by feImage).
91         invalidateStyle();
92     }
93
94     // The instances of an element are clones made in shadow trees to implement <use>.
95     const HashSet<SVGElement*>& instances() const;
96
97     bool getBoundingBox(FloatRect&, SVGLocatable::StyleUpdateStrategy = SVGLocatable::AllowStyleUpdate);
98
99     SVGElement* correspondingElement() const;
100     RefPtr<SVGUseElement> correspondingUseElement() const;
101
102     void setCorrespondingElement(SVGElement*);
103
104     Optional<ElementStyle> resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle) override;
105
106     static QualifiedName animatableAttributeForName(const AtomString&);
107 #ifndef NDEBUG
108     bool isAnimatableAttribute(const QualifiedName&) const;
109 #endif
110
111     MutableStyleProperties* animatedSMILStyleProperties() const;
112     MutableStyleProperties& ensureAnimatedSMILStyleProperties();
113     void setUseOverrideComputedStyle(bool);
114
115     virtual bool haveLoadedRequiredResources();
116
117     bool addEventListener(const AtomString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
118     bool removeEventListener(const AtomString& eventType, EventListener&, const ListenerOptions&) override;
119     bool hasFocusEventListeners() const;
120
121     bool hasTagName(const SVGQualifiedName& name) const { return hasLocalName(name.localName()); }
122     int tabIndex() const override;
123
124     void callClearTarget() { clearTarget(); }
125
126     class InstanceUpdateBlocker;
127     class InstanceInvalidationGuard;
128
129     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGElement>;
130     virtual const SVGPropertyRegistry& propertyRegistry() const { return m_propertyRegistry; }
131     void detachAllProperties() { propertyRegistry().detachAllProperties(); }
132
133     bool isAnimatedPropertyAttribute(const QualifiedName&) const;
134     bool isAnimatedAttribute(const QualifiedName&) const;
135     bool isAnimatedStyleAttribute(const QualifiedName&) const;
136
137     void synchronizeAttribute(const QualifiedName&);
138     void synchronizeAllAttributes();
139     static void synchronizeAllAnimatedSVGAttribute(SVGElement&);
140
141     void commitPropertyChange(SVGProperty*) override;
142     void commitPropertyChange(SVGAnimatedProperty&);
143
144     const SVGElement* attributeContextElement() const override { return this; }
145     SVGPropertyAnimatorFactory& propertyAnimatorFactory() { return *m_propertyAnimatorFactory; }
146     std::unique_ptr<SVGAttributeAnimator> createAnimator(const QualifiedName&, AnimationMode, CalcMode, bool isAccumulated, bool isAdditive);
147     void animatorWillBeDeleted(const QualifiedName&);
148
149     // These are needed for the RenderTree, animation and DOM.
150     String className() const { return m_className->currentValue(); }
151     SVGAnimatedString& classNameAnimated() { return m_className; }
152
153 protected:
154     SVGElement(const QualifiedName&, Document&);
155     virtual ~SVGElement();
156
157     bool isMouseFocusable() const override;
158     bool supportsFocus() const override { return false; }
159
160     bool rendererIsNeeded(const RenderStyle&) override;
161     void parseAttribute(const QualifiedName&, const AtomString&) override;
162
163     void finishParsingChildren() override;
164     void attributeChanged(const QualifiedName&, const AtomString& oldValue, const AtomString& newValue, AttributeModificationReason = ModifiedDirectly) override;
165     bool childShouldCreateRenderer(const Node&) const override;
166
167     SVGElementRareData& ensureSVGRareData();
168
169     void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomString&);
170     static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&);
171
172     bool isPresentationAttribute(const QualifiedName&) const override;
173     void collectStyleForPresentationAttribute(const QualifiedName&, const AtomString&, MutableStyleProperties&) override;
174     InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) override;
175     void removedFromAncestor(RemovalType, ContainerNode&) override;
176     void childrenChanged(const ChildChange&) override;
177     virtual bool selfHasRelativeLengths() const { return false; }
178     void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); }
179     void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*);
180
181     void willRecalcStyle(Style::Change) override;
182
183 private:
184     const RenderStyle* computedStyle(PseudoId = PseudoId::None) final;
185
186     virtual void clearTarget() { }
187
188     void buildPendingResourcesIfNeeded();
189     void accessKeyAction(bool sendMouseEvents) override;
190
191 #ifndef NDEBUG
192     virtual bool filterOutAnimatableAttribute(const QualifiedName&) const;
193 #endif
194
195     void invalidateInstances();
196
197     std::unique_ptr<SVGElementRareData> m_svgRareData;
198
199     HashSet<SVGElement*> m_elementsWithRelativeLengths;
200
201     std::unique_ptr<SVGPropertyAnimatorFactory> m_propertyAnimatorFactory;
202
203     PropertyRegistry m_propertyRegistry { *this };
204     Ref<SVGAnimatedString> m_className { SVGAnimatedString::create(this) };
205 };
206
207 class SVGElement::InstanceInvalidationGuard {
208 public:
209     InstanceInvalidationGuard(SVGElement&);
210     ~InstanceInvalidationGuard();
211 private:
212     SVGElement& m_element;
213 };
214
215 class SVGElement::InstanceUpdateBlocker {
216 public:
217     InstanceUpdateBlocker(SVGElement&);
218     ~InstanceUpdateBlocker();
219 private:
220     SVGElement& m_element;
221 };
222
223 struct SVGAttributeHashTranslator {
224     static unsigned hash(const QualifiedName& key)
225     {
226         if (key.hasPrefix()) {
227             QualifiedNameComponents components = { nullAtom().impl(), key.localName().impl(), key.namespaceURI().impl() };
228             return hashComponents(components);
229         }
230         return DefaultHash<QualifiedName>::Hash::hash(key);
231     }
232     static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); }
233 };
234
235 inline SVGElement::InstanceInvalidationGuard::InstanceInvalidationGuard(SVGElement& element)
236     : m_element(element)
237 {
238 }
239
240 inline SVGElement::InstanceInvalidationGuard::~InstanceInvalidationGuard()
241 {
242     m_element.invalidateInstances();
243 }
244
245 inline SVGElement::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement& element)
246     : m_element(element)
247 {
248     m_element.setInstanceUpdatesBlocked(true);
249 }
250
251 inline SVGElement::InstanceUpdateBlocker::~InstanceUpdateBlocker()
252 {
253     m_element.setInstanceUpdatesBlocked(false);
254 }
255
256 inline bool Node::hasTagName(const SVGQualifiedName& name) const
257 {
258     return isSVGElement() && downcast<SVGElement>(*this).hasTagName(name);
259 }
260
261 } // namespace WebCore
262
263 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGElement)
264     static bool isType(const WebCore::Node& node) { return node.isSVGElement(); }
265 SPECIALIZE_TYPE_TRAITS_END()
266
267 #include "SVGElementTypeHelpers.h"