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 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/SVGElementTypeHelpers.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 WebCore { 35 36 class AffineTransform; 37 class CSSCursorImageValue; 38 class Document; 39 class SVGAnimatedPropertyBase; 40 class SubtreeLayoutScope; 41 class SVGCursorElement; 42 class SVGDocumentExtensions; 43 class SVGElementRareData; 44 class SVGFitToViewBox; 45 class SVGSVGElement; 46 47 void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName); 48 49 class SVGElement : public Element { 50 public: 51 virtual ~SVGElement(); 52 virtual void attach(const AttachContext&) OVERRIDE; 53 virtual void detach(const AttachContext&) OVERRIDE; 54 55 virtual short tabIndex() const OVERRIDE; supportsFocus()56 virtual bool supportsFocus() const OVERRIDE { return false; } 57 58 bool isOutermostSVGSVGElement() const; 59 60 virtual String title() const OVERRIDE; hasRelativeLengths()61 bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); } 62 static bool isAnimatableCSSProperty(const QualifiedName&); 63 enum CTMScope { 64 NearestViewportScope, // Used by SVGGraphicsElement::getCTM() 65 ScreenScope, // Used by SVGGraphicsElement::getScreenCTM() 66 AncestorScope // Used by SVGSVGElement::get{Enclosure|Intersection}List() 67 }; 68 virtual AffineTransform localCoordinateSpaceTransform(CTMScope) const; needsPendingResourceHandling()69 virtual bool needsPendingResourceHandling() const { return true; } 70 71 bool instanceUpdatesBlocked() const; 72 void setInstanceUpdatesBlocked(bool); 73 74 const AtomicString& xmlbase() const; 75 void setXMLbase(const AtomicString&); 76 77 const AtomicString& xmllang() const; 78 void setXMLlang(const AtomicString&); 79 80 const AtomicString& xmlspace() const; 81 void setXMLspace(const AtomicString&); 82 83 SVGSVGElement* ownerSVGElement() const; 84 SVGElement* viewportElement() const; 85 86 SVGDocumentExtensions& accessDocumentSVGExtensions(); 87 isSVGGraphicsElement()88 virtual bool isSVGGraphicsElement() const { return false; } isFilterEffect()89 virtual bool isFilterEffect() const { return false; } isTextContent()90 virtual bool isTextContent() const { return false; } isTextPositioning()91 virtual bool isTextPositioning() const { return false; } isStructurallyExternal()92 virtual bool isStructurallyExternal() const { return false; } 93 94 // For SVGTests isValid()95 virtual bool isValid() const { return true; } 96 97 virtual void svgAttributeChanged(const QualifiedName&); 98 99 PassRefPtr<SVGAnimatedPropertyBase> propertyFromAttribute(const QualifiedName& attributeName); 100 static AnimatedPropertyType animatedPropertyTypeForCSSAttribute(const QualifiedName& attributeName); 101 102 void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false); 103 void sendSVGLoadEventIfPossibleAsynchronously(); 104 void svgLoadEventTimerFired(Timer<SVGElement>*); 105 virtual Timer<SVGElement>* svgLoadEventTimer(); 106 supplementalTransform()107 virtual AffineTransform* supplementalTransform() { return 0; } 108 invalidateSVGAttributes()109 void invalidateSVGAttributes() { ensureUniqueElementData().m_animatedSVGAttributesAreDirty = true; } invalidateSVGPresentationAttributeStyle()110 void invalidateSVGPresentationAttributeStyle() { ensureUniqueElementData().m_presentationAttributeStyleIsDirty = true; } 111 112 const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instancesForElement() const; 113 void mapInstanceToElement(SVGElement*); 114 void removeInstanceMapping(SVGElement*); 115 116 bool getBoundingBox(FloatRect&); 117 118 void setCursorElement(SVGCursorElement*); 119 void setCursorImageValue(CSSCursorImageValue*); 120 121 #if !ENABLE(OILPAN) 122 void cursorElementRemoved(); 123 void cursorImageValueRemoved(); 124 #endif 125 126 SVGElement* correspondingElement(); 127 void setCorrespondingElement(SVGElement*); 128 SVGUseElement* correspondingUseElement() const; 129 130 void synchronizeAnimatedSVGAttribute(const QualifiedName&) const; 131 132 virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE FINAL; 133 synchronizeRequiredFeatures()134 virtual void synchronizeRequiredFeatures() { } synchronizeRequiredExtensions()135 virtual void synchronizeRequiredExtensions() { } synchronizeSystemLanguage()136 virtual void synchronizeSystemLanguage() { } 137 138 #ifndef NDEBUG 139 virtual bool isAnimatableAttribute(const QualifiedName&) const; 140 #endif 141 142 MutableStylePropertySet* animatedSMILStyleProperties() const; 143 MutableStylePropertySet* ensureAnimatedSMILStyleProperties(); 144 void setUseOverrideComputedStyle(bool); 145 146 virtual bool haveLoadedRequiredResources(); 147 148 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE FINAL; 149 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture = false) OVERRIDE FINAL; 150 151 void invalidateRelativeLengthClients(SubtreeLayoutScope* = 0); 152 isContextElement()153 bool isContextElement() const { return m_isContextElement; } setContextElement()154 void setContextElement() { m_isContextElement = true; } 155 156 void addToPropertyMap(PassRefPtr<SVGAnimatedPropertyBase>); 157 className()158 SVGAnimatedString* className() { return m_className.get(); } 159 160 bool inUseShadowTree() const; 161 162 class InvalidationGuard { 163 STACK_ALLOCATED(); 164 WTF_MAKE_NONCOPYABLE(InvalidationGuard); 165 public: InvalidationGuard(SVGElement * element)166 InvalidationGuard(SVGElement* element) : m_element(element) { } ~InvalidationGuard()167 ~InvalidationGuard() { m_element->invalidateInstances(); } 168 169 private: 170 RawPtrWillBeMember<SVGElement> m_element; 171 }; 172 173 class InstanceUpdateBlocker { 174 STACK_ALLOCATED(); 175 WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker); 176 public: 177 InstanceUpdateBlocker(SVGElement* targetElement); 178 ~InstanceUpdateBlocker(); 179 180 private: 181 RawPtrWillBeMember<SVGElement> m_targetElement; 182 }; 183 184 void invalidateInstances(); 185 186 virtual void trace(Visitor*) OVERRIDE; 187 188 static const AtomicString& eventParameterName(); 189 190 protected: 191 SVGElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement); 192 193 virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE; 194 195 virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) OVERRIDE; 196 197 virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE; 198 virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE; 199 virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE; 200 201 virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE; 202 virtual void removedFrom(ContainerNode*) OVERRIDE; 203 virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE; 204 205 static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&); updateRelativeLengthsInformation()206 void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); } 207 void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*); 208 selfHasRelativeLengths()209 virtual bool selfHasRelativeLengths() const { return false; } 210 211 SVGElementRareData* ensureSVGRareData(); 212 hasSVGRareData()213 inline bool hasSVGRareData() const { return m_SVGRareData; } svgRareData()214 inline SVGElementRareData* svgRareData() const 215 { 216 ASSERT(m_SVGRareData); 217 return m_SVGRareData.get(); 218 } 219 220 // SVGFitToViewBox::parseAttribute uses reportAttributeParsingError. 221 friend class SVGFitToViewBox; 222 void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&); 223 bool hasFocusEventListeners() const; 224 225 private: 226 // FIXME: Author shadows should be allowed 227 // https://bugs.webkit.org/show_bug.cgi?id=77938 areAuthorShadowsAllowed()228 virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; } 229 230 RenderStyle* computedStyle(PseudoId = NOPSEUDO); 231 virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE FINAL { return computedStyle(pseudoElementSpecifier); } 232 virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE; 233 234 void buildPendingResourcesIfNeeded(); 235 236 bool supportsSpatialNavigationFocus() const; 237 238 WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > m_elementsWithRelativeLengths; 239 240 typedef HashMap<QualifiedName, RefPtr<SVGAnimatedPropertyBase> > AttributeToPropertyMap; 241 AttributeToPropertyMap m_newAttributeToPropertyMap; 242 243 #if ASSERT_ENABLED 244 bool m_inRelativeLengthClientsInvalidation; 245 #endif 246 unsigned m_isContextElement : 1; 247 248 OwnPtrWillBeMember<SVGElementRareData> m_SVGRareData; 249 RefPtr<SVGAnimatedString> m_className; 250 }; 251 252 struct SVGAttributeHashTranslator { hashSVGAttributeHashTranslator253 static unsigned hash(const QualifiedName& key) 254 { 255 if (key.hasPrefix()) { 256 QualifiedNameComponents components = { nullAtom.impl(), key.localName().impl(), key.namespaceURI().impl() }; 257 return hashComponents(components); 258 } 259 return DefaultHash<QualifiedName>::Hash::hash(key); 260 } equalSVGAttributeHashTranslator261 static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); } 262 }; 263 264 DEFINE_ELEMENT_TYPE_CASTS(SVGElement, isSVGElement()); 265 266 template <> inline bool isElementOfType<const SVGElement>(const Node& node) { return node.isSVGElement(); } 267 268 } 269 270 #endif 271