1 /* 2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann (at) kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis (at) 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/dom/Element.h" 26 #include "core/svg/SVGAnimatedString.h" 27 #include "core/svg/SVGParsingError.h" 28 #include "core/svg/properties/SVGAnimatedPropertyMacros.h" 29 #include "core/svg/properties/SVGPropertyInfo.h" 30 #include "platform/Timer.h" 31 #include "wtf/HashMap.h" 32 33 namespace WebCore { 34 35 class AffineTransform; 36 class CSSCursorImageValue; 37 class Document; 38 class SubtreeLayoutScope; 39 class SVGAttributeToPropertyMap; 40 class SVGCursorElement; 41 class SVGDocumentExtensions; 42 class SVGElementInstance; 43 class SVGElementRareData; 44 class SVGSVGElement; 45 46 void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName); 47 48 class SVGElement : public Element { 49 public: 50 virtual ~SVGElement(); 51 52 bool isOutermostSVGSVGElement() const; 53 54 virtual String title() const; 55 bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); } 56 virtual bool supportsMarkers() const { return false; } 57 PassRefPtr<CSSValue> getPresentationAttribute(const String& name); 58 static bool isAnimatableCSSProperty(const QualifiedName&); 59 enum CTMScope { 60 NearestViewportScope, // Used by SVGGraphicsElement::getCTM() 61 ScreenScope // Used by SVGGraphicsElement::getScreenCTM() 62 }; 63 virtual AffineTransform localCoordinateSpaceTransform(CTMScope) const; 64 virtual bool needsPendingResourceHandling() const { return true; } 65 66 bool instanceUpdatesBlocked() const; 67 void setInstanceUpdatesBlocked(bool); 68 69 String xmlbase() const; 70 void setXMLbase(const String&); 71 72 String xmllang() const; 73 void setXMLlang(const String& xmlLang); 74 75 String xmlspace() const; 76 void setXMLspace(const String& xmlSpace); 77 78 SVGSVGElement* ownerSVGElement() const; 79 SVGElement* viewportElement() const; 80 81 SVGDocumentExtensions* accessDocumentSVGExtensions(); 82 83 virtual bool isSVGGraphicsElement() const { return false; } 84 virtual bool isSVGSVGElement() const { return false; } 85 virtual bool isFilterEffect() const { return false; } 86 virtual bool isGradientStop() const { return false; } 87 virtual bool isTextContent() const { return false; } 88 89 // For SVGTests 90 virtual bool isValid() const { return true; } 91 92 virtual void svgAttributeChanged(const QualifiedName&); 93 94 virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&); 95 96 void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false); 97 void sendSVGLoadEventIfPossibleAsynchronously(); 98 void svgLoadEventTimerFired(Timer<SVGElement>*); 99 virtual Timer<SVGElement>* svgLoadEventTimer(); 100 101 virtual AffineTransform* supplementalTransform() { return 0; } 102 103 void invalidateSVGAttributes() { ensureUniqueElementData()->m_animatedSVGAttributesAreDirty = true; } 104 105 const HashSet<SVGElementInstance*>& instancesForElement() const; 106 107 bool getBoundingBox(FloatRect&); 108 109 void setCursorElement(SVGCursorElement*); 110 void cursorElementRemoved(); 111 void setCursorImageValue(CSSCursorImageValue*); 112 void cursorImageValueRemoved(); 113 114 SVGElement* correspondingElement(); 115 void setCorrespondingElement(SVGElement*); 116 117 void synchronizeAnimatedSVGAttribute(const QualifiedName&) const; 118 119 virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE; 120 121 static void synchronizeRequiredFeatures(SVGElement* contextElement); 122 static void synchronizeRequiredExtensions(SVGElement* contextElement); 123 static void synchronizeSystemLanguage(SVGElement* contextElement); 124 125 virtual void synchronizeRequiredFeatures() { } 126 virtual void synchronizeRequiredExtensions() { } 127 virtual void synchronizeSystemLanguage() { } 128 129 #ifndef NDEBUG 130 bool isAnimatableAttribute(const QualifiedName&) const; 131 #endif 132 133 MutableStylePropertySet* animatedSMILStyleProperties() const; 134 MutableStylePropertySet* ensureAnimatedSMILStyleProperties(); 135 void setUseOverrideComputedStyle(bool); 136 137 virtual bool haveLoadedRequiredResources(); 138 139 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) OVERRIDE; 140 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE; 141 142 virtual bool shouldMoveToFlowThread(RenderStyle*) const OVERRIDE; 143 144 void invalidateRelativeLengthClients(SubtreeLayoutScope* = 0); 145 146 bool isContextElement() const { return m_isContextElement; } 147 void setContextElement() { m_isContextElement = true; } 148 149 protected: 150 SVGElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement); 151 152 virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE; 153 154 virtual void finishParsingChildren(); 155 virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) OVERRIDE; 156 virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE; 157 158 virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE; 159 virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE; 160 virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE; 161 162 virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE; 163 virtual void removedFrom(ContainerNode*) OVERRIDE; 164 virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); 165 166 static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&); 167 void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); } 168 void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*); 169 170 virtual bool selfHasRelativeLengths() const { return false; } 171 172 SVGElementRareData* svgRareData() const; 173 SVGElementRareData* ensureSVGRareData(); 174 175 void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&); 176 bool hasFocusEventListeners() const; 177 178 class CleanUpAnimatedPropertiesCaller { 179 public: 180 CleanUpAnimatedPropertiesCaller() 181 : m_owner(0) 182 { 183 } 184 185 ~CleanUpAnimatedPropertiesCaller() 186 { 187 ASSERT(m_owner); 188 m_owner->cleanupAnimatedProperties(); 189 } 190 191 void setOwner(SVGElement* owner) { m_owner = owner; } 192 193 private: 194 SVGElement* m_owner; 195 }; 196 197 private: 198 friend class SVGElementInstance; 199 200 // FIXME: Author shadows should be allowed 201 // https://bugs.webkit.org/show_bug.cgi?id=77938 202 virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; } 203 204 RenderStyle* computedStyle(PseudoId = NOPSEUDO); 205 virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return computedStyle(pseudoElementSpecifier); } 206 virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE; 207 virtual bool isKeyboardFocusable() const OVERRIDE; 208 209 void buildPendingResourcesIfNeeded(); 210 211 void mapInstanceToElement(SVGElementInstance*); 212 void removeInstanceMapping(SVGElementInstance*); 213 214 void cleanupAnimatedProperties(); 215 friend class CleanUpAnimatedPropertiesCaller; 216 217 HashSet<SVGElement*> m_elementsWithRelativeLengths; 218 219 BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGElement) 220 DECLARE_ANIMATED_STRING(ClassName, className) 221 END_DECLARE_ANIMATED_PROPERTIES 222 223 #if !ASSERT_DISABLED 224 bool m_inRelativeLengthClientsInvalidation; 225 #endif 226 bool m_animatedPropertiesDestructed; 227 bool m_isContextElement; 228 }; 229 230 struct SVGAttributeHashTranslator { 231 static unsigned hash(const QualifiedName& key) 232 { 233 if (key.hasPrefix()) { 234 QualifiedNameComponents components = { nullAtom.impl(), key.localName().impl(), key.namespaceURI().impl() }; 235 return hashComponents(components); 236 } 237 return DefaultHash<QualifiedName>::Hash::hash(key); 238 } 239 static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); } 240 }; 241 242 DEFINE_NODE_TYPE_CASTS(SVGElement, isSVGElement()); 243 244 } 245 246 #endif 247