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 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;
     56     virtual bool supportsFocus() const OVERRIDE { return false; }
     57 
     58     bool isOutermostSVGSVGElement() const;
     59 
     60     virtual String title() const OVERRIDE;
     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;
     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 
     88     virtual bool isSVGGraphicsElement() const { return false; }
     89     virtual bool isFilterEffect() const { return false; }
     90     virtual bool isTextContent() const { return false; }
     91     virtual bool isTextPositioning() const { return false; }
     92     virtual bool isStructurallyExternal() const { return false; }
     93 
     94     // For SVGTests
     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 
    107     virtual AffineTransform* supplementalTransform() { return 0; }
    108 
    109     void invalidateSVGAttributes() { ensureUniqueElementData().m_animatedSVGAttributesAreDirty = true; }
    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 
    134     virtual void synchronizeRequiredFeatures() { }
    135     virtual void synchronizeRequiredExtensions() { }
    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 
    153     bool isContextElement() const { return m_isContextElement; }
    154     void setContextElement() { m_isContextElement = true; }
    155 
    156     void addToPropertyMap(PassRefPtr<SVGAnimatedPropertyBase>);
    157 
    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:
    166         InvalidationGuard(SVGElement* element) : m_element(element) { }
    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&);
    206     void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); }
    207     void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*);
    208 
    209     virtual bool selfHasRelativeLengths() const { return false; }
    210 
    211     SVGElementRareData* ensureSVGRareData();
    212 
    213     inline bool hasSVGRareData() const { return m_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
    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 {
    253     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     }
    261     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