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, 2014 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#ifndef SVGElement_h 24#define SVGElement_h 25 26#include "CSSPropertyNames.h" 27#include "SVGAnimatedString.h" 28#include "SVGElementTypeHelpers.h" 29#include "SVGLangSpace.h" 30#include "SVGLocatable.h" 31#include "SVGParsingError.h" 32#include "SVGPropertyInfo.h" 33#include "StyledElement.h" 34#include "Timer.h" 35#include <wtf/HashMap.h> 36#include <wtf/HashSet.h> 37#include <wtf/PassRefPtr.h> 38 39namespace WebCore { 40 41class AffineTransform; 42class CSSCursorImageValue; 43class CSSStyleDeclaration; 44class CSSValue; 45class Document; 46class SVGAttributeToPropertyMap; 47class SVGCursorElement; 48class SVGDocumentExtensions; 49class SVGElementInstance; 50class SVGElementRareData; 51class SVGSVGElement; 52 53void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName); 54 55class SVGElement : public StyledElement, public SVGLangSpace { 56public: 57 bool isOutermostSVGSVGElement() const; 58 59 String xmlbase() const; 60 void setXmlbase(const String&, ExceptionCode&); 61 62 SVGSVGElement* ownerSVGElement() const; 63 SVGElement* viewportElement() const; 64 65 virtual String title() const override; 66 static bool isAnimatableCSSProperty(const QualifiedName&); 67 bool isKnownAttribute(const QualifiedName&); 68 PassRefPtr<CSSValue> getPresentationAttribute(const String& name); 69 virtual bool supportsMarkers() const { return false; } 70 bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); } 71 virtual bool needsPendingResourceHandling() const { return true; } 72 bool instanceUpdatesBlocked() const; 73 void setInstanceUpdatesBlocked(bool); 74 virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const; 75 76 SVGDocumentExtensions* accessDocumentSVGExtensions(); 77 78 virtual bool isSVGGraphicsElement() const { return false; } 79 virtual bool isFilterEffect() const { return false; } 80 virtual bool isGradientStop() const { return false; } 81 virtual bool isTextContent() const { return false; } 82 virtual bool isSMILElement() const { return false; } 83 84 // For SVGTests 85 virtual bool isValid() const { return true; } 86 87 virtual void svgAttributeChanged(const QualifiedName&); 88 89 virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&); 90 91 void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false); 92 void sendSVGLoadEventIfPossibleAsynchronously(); 93 void svgLoadEventTimerFired(Timer<SVGElement>*); 94 virtual Timer<SVGElement>* svgLoadEventTimer(); 95 96 virtual AffineTransform* supplementalTransform() { return 0; } 97 98 void invalidateSVGAttributes() { ensureUniqueElementData().setAnimatedSVGAttributesAreDirty(true); } 99 void invalidateSVGPresentationAttributeStyle() { ensureUniqueElementData().setPresentationAttributeStyleIsDirty(true); } 100 101 const HashSet<SVGElementInstance*>& instancesForElement() const; 102 103 bool getBoundingBox(FloatRect&, SVGLocatable::StyleUpdateStrategy = SVGLocatable::AllowStyleUpdate); 104 105 void setCursorElement(SVGCursorElement*); 106 void cursorElementRemoved(); 107 void setCursorImageValue(CSSCursorImageValue*); 108 void cursorImageValueRemoved(); 109 110 SVGElement* correspondingElement(); 111 void setCorrespondingElement(SVGElement*); 112 113 void synchronizeAnimatedSVGAttribute(const QualifiedName&) const; 114 static void synchronizeAllAnimatedSVGAttribute(SVGElement*); 115 116 virtual PassRefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle) override; 117 118 static void synchronizeRequiredFeatures(SVGElement* contextElement); 119 static void synchronizeRequiredExtensions(SVGElement* contextElement); 120 static void synchronizeSystemLanguage(SVGElement* contextElement); 121 122 virtual void synchronizeRequiredFeatures() { } 123 virtual void synchronizeRequiredExtensions() { } 124 virtual void synchronizeSystemLanguage() { } 125 126 static QualifiedName animatableAttributeForName(const AtomicString&); 127#ifndef NDEBUG 128 bool isAnimatableAttribute(const QualifiedName&) const; 129#endif 130 131 MutableStyleProperties* animatedSMILStyleProperties() const; 132 MutableStyleProperties& ensureAnimatedSMILStyleProperties(); 133 void setUseOverrideComputedStyle(bool); 134 135 virtual bool haveLoadedRequiredResources(); 136 137 virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override; 138 virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override; 139 bool hasFocusEventListeners() const; 140 141#if ENABLE(CSS_REGIONS) 142 virtual bool shouldMoveToFlowThread(const RenderStyle&) const override; 143#endif 144 145 bool hasTagName(const SVGQualifiedName& name) const { return hasLocalName(name.localName()); } 146 virtual short tabIndex() const override; 147 148 void callClearTarget() { clearTarget(); } 149 150protected: 151 SVGElement(const QualifiedName&, Document&); 152 virtual ~SVGElement(); 153 154 virtual bool isMouseFocusable() const override; 155 virtual bool supportsFocus() const override { return false; } 156 157 virtual bool rendererIsNeeded(const RenderStyle&) override; 158 virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; 159 160 virtual void finishParsingChildren() override; 161 virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override; 162 virtual bool childShouldCreateRenderer(const Node&) const override; 163 164 SVGElementRareData& ensureSVGRareData(); 165 166 void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&); 167 static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&); 168 169 virtual bool isPresentationAttribute(const QualifiedName&) const override; 170 virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; 171 virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; 172 virtual void removedFrom(ContainerNode&) override; 173 virtual void childrenChanged(const ChildChange&) override; 174 virtual bool selfHasRelativeLengths() const { return false; } 175 void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); } 176 void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*); 177 178private: 179 friend class SVGElementInstance; 180 181 virtual RenderStyle* computedStyle(PseudoId = NOPSEUDO) override final; 182 virtual bool willRecalcStyle(Style::Change) override; 183 184 virtual bool isSupported(StringImpl* feature, StringImpl* version) const; 185 186 virtual void clearTarget() { } 187 188 void mapInstanceToElement(SVGElementInstance*); 189 void removeInstanceMapping(SVGElementInstance*); 190 191 void buildPendingResourcesIfNeeded(); 192 virtual void accessKeyAction(bool sendMouseEvents) override; 193 194#ifndef NDEBUG 195 virtual bool filterOutAnimatableAttribute(const QualifiedName&) const; 196#endif 197 198 std::unique_ptr<SVGElementRareData> m_svgRareData; 199 200 HashSet<SVGElement*> m_elementsWithRelativeLengths; 201 202 BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGElement) 203 DECLARE_ANIMATED_STRING(ClassName, className) 204 END_DECLARE_ANIMATED_PROPERTIES 205 206}; 207 208struct SVGAttributeHashTranslator { 209 static unsigned hash(const QualifiedName& key) 210 { 211 if (key.hasPrefix()) { 212 QualifiedNameComponents components = { nullAtom.impl(), key.localName().impl(), key.namespaceURI().impl() }; 213 return hashComponents(components); 214 } 215 return DefaultHash<QualifiedName>::Hash::hash(key); 216 } 217 static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); } 218}; 219 220void isSVGElement(const SVGElement&); // Catch unnecessary runtime check of type known at compile time. 221inline bool isSVGElement(const Node& node) { return node.isSVGElement(); } 222template <> inline bool isElementOfType<const SVGElement>(const Element& element) { return element.isSVGElement(); } 223 224NODE_TYPE_CASTS(SVGElement) 225 226inline bool Node::hasTagName(const SVGQualifiedName& name) const 227{ 228 return isSVGElement() && toSVGElement(*this).hasTagName(name); 229} 230 231} 232 233#endif 234