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