Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGElement.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4  * Copyright (C) 2009, 2014 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifndef SVGElement_h
23 #define SVGElement_h
24
25 #include "core/SVGNames.h"
26 #include "core/dom/Element.h"
27 #include "core/svg/SVGAnimatedString.h"
28 #include "core/svg/SVGParsingError.h"
29 #include "core/svg/properties/SVGPropertyInfo.h"
30 #include "platform/Timer.h"
31 #include "wtf/HashMap.h"
32 #include "wtf/OwnPtr.h"
33
34 namespace blink {
35
36 class AffineTransform;
37 class CSSCursorImageValue;
38 class Document;
39 class SVGAnimatedPropertyBase;
40 class SubtreeLayoutScope;
41 class SVGCursorElement;
42 class SVGDocumentExtensions;
43 class SVGElement;
44 class SVGElementRareData;
45 class SVGFitToViewBox;
46 class SVGSVGElement;
47 class SVGUseElement;
48
49 void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName);
50
51 typedef WillBeHeapHashSet<RawPtrWillBeMember<SVGElement> > SVGElementSet;
52
53 class SVGElement : public Element {
54     DEFINE_WRAPPERTYPEINFO();
55 public:
56     virtual ~SVGElement();
57     virtual void attach(const AttachContext&) OVERRIDE;
58     virtual void detach(const AttachContext&) OVERRIDE;
59
60     virtual short tabIndex() const OVERRIDE;
61     virtual bool supportsFocus() const OVERRIDE { return false; }
62
63     bool isOutermostSVGSVGElement() const;
64
65     bool hasTagName(const SVGQualifiedName& name) const { return hasLocalName(name.localName()); }
66
67     virtual String title() const OVERRIDE;
68     bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); }
69     static bool isAnimatableCSSProperty(const QualifiedName&);
70     enum CTMScope {
71         NearestViewportScope, // Used by SVGGraphicsElement::getCTM()
72         ScreenScope, // Used by SVGGraphicsElement::getScreenCTM()
73         AncestorScope // Used by SVGSVGElement::get{Enclosure|Intersection}List()
74     };
75     virtual AffineTransform localCoordinateSpaceTransform(CTMScope) const;
76     virtual bool needsPendingResourceHandling() const { return true; }
77
78     bool instanceUpdatesBlocked() const;
79     void setInstanceUpdatesBlocked(bool);
80
81     SVGSVGElement* ownerSVGElement() const;
82     SVGElement* viewportElement() const;
83
84     SVGDocumentExtensions& accessDocumentSVGExtensions();
85
86     virtual bool isSVGGraphicsElement() const { return false; }
87     virtual bool isFilterEffect() const { return false; }
88     virtual bool isTextContent() const { return false; }
89     virtual bool isTextPositioning() const { return false; }
90     virtual bool isStructurallyExternal() const { return false; }
91
92     // For SVGTests
93     virtual bool isValid() const { return true; }
94
95     virtual void svgAttributeChanged(const QualifiedName&);
96
97     PassRefPtr<SVGAnimatedPropertyBase> propertyFromAttribute(const QualifiedName& attributeName);
98     static AnimatedPropertyType animatedPropertyTypeForCSSAttribute(const QualifiedName& attributeName);
99
100     void sendSVGLoadEventToSelfAndAncestorChainIfPossible();
101     bool sendSVGLoadEventIfPossible();
102     void sendSVGLoadEventIfPossibleAsynchronously();
103     void svgLoadEventTimerFired(Timer<SVGElement>*);
104     virtual Timer<SVGElement>* svgLoadEventTimer();
105
106     virtual AffineTransform* supplementalTransform() { return 0; }
107
108     void invalidateSVGAttributes() { ensureUniqueElementData().m_animatedSVGAttributesAreDirty = true; }
109     void invalidateSVGPresentationAttributeStyle() { ensureUniqueElementData().m_presentationAttributeStyleIsDirty = true; }
110
111     const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instancesForElement() const;
112     void mapInstanceToElement(SVGElement*);
113     void removeInstanceMapping(SVGElement*);
114
115     bool getBoundingBox(FloatRect&);
116
117     void setCursorElement(SVGCursorElement*);
118     void setCursorImageValue(CSSCursorImageValue*);
119
120 #if !ENABLE(OILPAN)
121     void cursorElementRemoved();
122     void cursorImageValueRemoved();
123 #endif
124
125     SVGElement* correspondingElement();
126     void setCorrespondingElement(SVGElement*);
127     SVGUseElement* correspondingUseElement() const;
128
129     void synchronizeAnimatedSVGAttribute(const QualifiedName&) const;
130
131     virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE FINAL;
132
133     virtual void synchronizeRequiredFeatures() { }
134     virtual void synchronizeRequiredExtensions() { }
135     virtual void synchronizeSystemLanguage() { }
136
137 #if ENABLE(ASSERT)
138     virtual bool isAnimatableAttribute(const QualifiedName&) const;
139 #endif
140
141     MutableStylePropertySet* animatedSMILStyleProperties() const;
142     MutableStylePropertySet* ensureAnimatedSMILStyleProperties();
143     void setUseOverrideComputedStyle(bool);
144
145     virtual bool haveLoadedRequiredResources();
146
147     virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE FINAL;
148     virtual bool removeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE FINAL;
149
150     void invalidateRelativeLengthClients(SubtreeLayoutScope* = 0);
151
152     void addToPropertyMap(PassRefPtr<SVGAnimatedPropertyBase>);
153
154     SVGAnimatedString* className() { return m_className.get(); }
155
156     bool inUseShadowTree() const;
157
158     SVGElementSet* setOfIncomingReferences() const;
159     void addReferenceTo(SVGElement*);
160     void rebuildAllIncomingReferences();
161     void removeAllIncomingReferences();
162     void removeAllOutgoingReferences();
163
164     class InvalidationGuard {
165         STACK_ALLOCATED();
166         WTF_MAKE_NONCOPYABLE(InvalidationGuard);
167     public:
168         InvalidationGuard(SVGElement* element) : m_element(element) { }
169         ~InvalidationGuard() { m_element->invalidateInstances(); }
170
171     private:
172         RawPtrWillBeMember<SVGElement> m_element;
173     };
174
175     class InstanceUpdateBlocker {
176         STACK_ALLOCATED();
177         WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker);
178     public:
179         InstanceUpdateBlocker(SVGElement* targetElement);
180         ~InstanceUpdateBlocker();
181
182     private:
183         RawPtrWillBeMember<SVGElement> m_targetElement;
184     };
185
186     void invalidateInstances();
187
188     virtual void trace(Visitor*) OVERRIDE;
189
190     static const AtomicString& eventParameterName();
191
192 protected:
193     SVGElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement);
194
195     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
196
197     // FIXME: |parseAttributeNew| is a new implementation of parseAttribute
198     // which maps attribute using |m_attributeToPropertyMap|.
199     // This is to replace |parseAttribute()| after all derived class switch to call this.
200     void parseAttributeNew(const QualifiedName&, const AtomicString&);
201
202     virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) OVERRIDE;
203
204     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
205     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
206
207     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
208     virtual void removedFrom(ContainerNode*) OVERRIDE;
209     virtual void childrenChanged(const ChildrenChange&) OVERRIDE;
210
211     static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&);
212     void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); }
213     void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*);
214
215     virtual bool selfHasRelativeLengths() const { return false; }
216
217     SVGElementRareData* ensureSVGRareData();
218     inline bool hasSVGRareData() const { return m_SVGRareData; }
219     inline SVGElementRareData* svgRareData() const
220     {
221         ASSERT(m_SVGRareData);
222         return m_SVGRareData.get();
223     }
224
225     // SVGFitToViewBox::parseAttribute uses reportAttributeParsingError.
226     friend class SVGFitToViewBox;
227     void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&);
228     bool hasFocusEventListeners() const;
229
230 private:
231     // FIXME: Author shadows should be allowed
232     // https://bugs.webkit.org/show_bug.cgi?id=77938
233     virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; }
234
235     bool isSVGElement() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
236     bool isStyledElement() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
237
238     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
239     virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE FINAL { return computedStyle(pseudoElementSpecifier); }
240     virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
241
242     void buildPendingResourcesIfNeeded();
243
244     WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > m_elementsWithRelativeLengths;
245
246     typedef HashMap<QualifiedName, RefPtr<SVGAnimatedPropertyBase> > AttributeToPropertyMap;
247     AttributeToPropertyMap m_attributeToPropertyMap;
248
249 #if ENABLE(ASSERT)
250     bool m_inRelativeLengthClientsInvalidation;
251 #endif
252
253     OwnPtrWillBeMember<SVGElementRareData> m_SVGRareData;
254     RefPtr<SVGAnimatedString> m_className;
255 };
256
257 struct SVGAttributeHashTranslator {
258     static unsigned hash(const QualifiedName& key)
259     {
260         if (key.hasPrefix()) {
261             QualifiedNameComponents components = { nullAtom.impl(), key.localName().impl(), key.namespaceURI().impl() };
262             return hashComponents(components);
263         }
264         return DefaultHash<QualifiedName>::Hash::hash(key);
265     }
266     static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); }
267 };
268
269 DEFINE_ELEMENT_TYPE_CASTS(SVGElement, isSVGElement());
270
271 template <typename T> bool isElementOfType(const SVGElement&);
272 template <> inline bool isElementOfType<const SVGElement>(const SVGElement&) { return true; }
273
274 inline bool Node::hasTagName(const SVGQualifiedName& name) const
275 {
276     return isSVGElement() && toSVGElement(*this).hasTagName(name);
277 }
278
279 // This requires isSVG*Element(const SVGElement&).
280 #define DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
281     inline bool is##thisType(const thisType* element); \
282     inline bool is##thisType(const thisType& element); \
283     inline bool is##thisType(const SVGElement* element) { return element && is##thisType(*element); } \
284     inline bool is##thisType(const Node& node) { return node.isSVGElement() ? is##thisType(toSVGElement(node)) : false; } \
285     inline bool is##thisType(const Node* node) { return node && is##thisType(*node); } \
286     template<typename T> inline bool is##thisType(const PassRefPtr<T>& node) { return is##thisType(node.get()); } \
287     template<typename T> inline bool is##thisType(const RefPtr<T>& node) { return is##thisType(node.get()); } \
288     template <> inline bool isElementOfType<const thisType>(const SVGElement& element) { return is##thisType(element); } \
289     DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType)
290
291 } // namespace blink
292
293 #include "core/SVGElementTypeHelpers.h"
294
295 #endif // SVGElement_h