Home | History | Annotate | Download | only in svg
      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, 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
    296