File indexing completed on 2024-04-28 15:24:29

0001 /*
0002     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005, 2006 Rob Buis <buis@kde.org>
0004 
0005     This file is part of the KDE project
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #ifndef SVGElement_h
0024 #define SVGElement_h
0025 
0026 #if ENABLE(SVG)
0027 #include "Document.h"
0028 #include "FloatRect.h"
0029 //#include "StyledElement.h"
0030 #include "SVGAnimatedTemplate.h"
0031 #include "SVGDocumentExtensions.h"
0032 #include "SVGNames.h"
0033 
0034 #include "ExceptionCode.h"
0035 
0036 #define ANIMATED_PROPERTY_EMPTY_DECLARATIONS(BareType, NullType, UpperProperty, LowerProperty) \
0037     public: \
0038     virtual BareType LowerProperty() const { ASSERT_NOT_REACHED(); return NullType; } \
0039     virtual void set##UpperProperty(BareType) { ASSERT_NOT_REACHED(); }\
0040     virtual BareType LowerProperty##BaseValue() const { ASSERT_NOT_REACHED(); return NullType; } \
0041     virtual void set##UpperProperty##BaseValue(BareType) { ASSERT_NOT_REACHED(); } \
0042     virtual void start##UpperProperty() const { ASSERT_NOT_REACHED(); } \
0043     virtual void stop##UpperProperty() { ASSERT_NOT_REACHED(); }
0044 
0045 #define ANIMATED_PROPERTY_FORWARD_DECLARATIONS(ForwardClass, BareType, UpperProperty, LowerProperty) \
0046     public: \
0047     BareType LowerProperty() const override { return ForwardClass::LowerProperty(); } \
0048     void set##UpperProperty(BareType newValue) override { ForwardClass::set##UpperProperty(newValue); } \
0049     BareType LowerProperty##BaseValue() const override { return ForwardClass::LowerProperty##BaseValue(); } \
0050     void set##UpperProperty##BaseValue(BareType newValue) override { ForwardClass::set##UpperProperty##BaseValue(newValue); } \
0051     void start##UpperProperty() const override { ForwardClass::start##UpperProperty(); } \
0052     void stop##UpperProperty() override { ForwardClass::stop##UpperProperty(); }
0053 
0054 #define ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassType, ClassStorageType, BareType, StorageType, UpperProperty, LowerProperty) \
0055     class SVGAnimatedTemplate##UpperProperty \
0056         : public SVGAnimatedTemplate<BareType> \
0057     { \
0058     public: \
0059         SVGAnimatedTemplate##UpperProperty(const ClassType*, const QualifiedName&); \
0060         virtual ~SVGAnimatedTemplate##UpperProperty() { } \
0061         virtual BareType baseVal() const; \
0062         virtual void setBaseVal(BareType); \
0063         virtual BareType animVal() const; \
0064         virtual void setAnimVal(BareType); \
0065         \
0066     protected: \
0067         ClassStorageType m_element; \
0068     }; \
0069     public: \
0070     BareType LowerProperty() const; \
0071     void set##UpperProperty(BareType); \
0072     BareType LowerProperty##BaseValue() const; \
0073     void set##UpperProperty##BaseValue(BareType); \
0074     PassRefPtr<SVGAnimatedTemplate##UpperProperty> LowerProperty##Animated() const; \
0075     void start##UpperProperty() const; \
0076     void stop##UpperProperty(); \
0077     \
0078     private: \
0079     StorageType m_##LowerProperty;
0080 
0081 #define ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassType, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, ContextElement) \
0082     ClassName::SVGAnimatedTemplate##UpperProperty::SVGAnimatedTemplate##UpperProperty(const ClassType* element, const QualifiedName& attributeName) \
0083         : SVGAnimatedTemplate<BareType>(attributeName), m_element(const_cast<ClassType*>(element)) { } \
0084     \
0085     BareType ClassName::SVGAnimatedTemplate##UpperProperty::baseVal() const \
0086     { \
0087         return m_element->LowerProperty##BaseValue(); \
0088     } \
0089     void ClassName::SVGAnimatedTemplate##UpperProperty::setBaseVal(BareType newBaseVal) \
0090     { \
0091         m_element->set##UpperProperty##BaseValue(newBaseVal); \
0092     } \
0093     BareType ClassName::SVGAnimatedTemplate##UpperProperty::animVal() const \
0094     { \
0095         return m_element->LowerProperty(); \
0096     } \
0097     void ClassName::SVGAnimatedTemplate##UpperProperty::setAnimVal(BareType newAnimVal) \
0098     { \
0099         m_element->set##UpperProperty(newAnimVal); \
0100     } \
0101     BareType ClassName::LowerProperty() const \
0102     { \
0103         return StorageGetter; \
0104     } \
0105     void ClassName::set##UpperProperty(BareType newValue) \
0106     { \
0107         m_##LowerProperty = newValue; \
0108     } \
0109     BareType ClassName::LowerProperty##BaseValue() const \
0110     { \
0111         const SVGElement* context = ContextElement; \
0112         ASSERT(context); \
0113         SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : nullptr); \
0114         if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) \
0115             return extensions->baseValue<BareType>(context, AttrName); \
0116         return LowerProperty(); \
0117     } \
0118     void ClassName::set##UpperProperty##BaseValue(BareType newValue) \
0119     { \
0120         const SVGElement* context = ContextElement; \
0121         ASSERT(context); \
0122         SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : nullptr); \
0123         if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) { \
0124             extensions->setBaseValue<BareType>(context, AttrName, newValue); \
0125             return; \
0126         } \
0127         /* Only update stored property, if not animating */ \
0128         set##UpperProperty(newValue); \
0129     } \
0130     \
0131     void ClassName::start##UpperProperty() const \
0132     { \
0133         const SVGElement* context = ContextElement; \
0134         ASSERT(context); \
0135         SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : nullptr); \
0136         if (extensions) { \
0137             ASSERT(!extensions->hasBaseValue<BareType>(context, AttrName)); \
0138             extensions->setBaseValue<BareType>(context, AttrName, LowerProperty()); \
0139         } \
0140     } \
0141     \
0142     void ClassName::stop##UpperProperty() \
0143     { \
0144         const SVGElement* context = ContextElement; \
0145         ASSERT(context); \
0146         SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : nullptr); \
0147         if (extensions) { \
0148             ASSERT(extensions->hasBaseValue<BareType>(context, AttrName)); \
0149             set##UpperProperty(extensions->baseValue<BareType>(context, AttrName)); \
0150             extensions->removeBaseValue<BareType>(context, AttrName); \
0151         } \
0152     }
0153 
0154 // These are the macros which will be used to declare/implement the svg animated properties...
0155 #define ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \
0156     ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(SVGElement, RefPtr<SVGElement>, BareType, StorageType, UpperProperty, LowerProperty)
0157 
0158 #define ANIMATED_PROPERTY_DECLARATIONS(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \
0159     ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassName, RefPtr<ClassName>, BareType, StorageType, UpperProperty, LowerProperty)
0160 
0161 #define ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
0162     ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, SVGElement, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName.localName(), StorageGetter, contextElement()) \
0163     PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
0164     { \
0165         const SVGElement* context = contextElement(); \
0166         ASSERT(context); \
0167         return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, SVGElement>(context, AttrName, AttrName.localName()); \
0168     }
0169 
0170 #define ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, AttrIdentifier, StorageGetter) \
0171     ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName.localName(), StorageGetter, this) \
0172     PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
0173     { \
0174         return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, ClassName>(this, AttrName, AttrIdentifier); \
0175     }
0176 
0177 #define ANIMATED_PROPERTY_DEFINITIONS(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
0178     ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, AttrName.localName(), StorageGetter)
0179 
0180 namespace WebCore
0181 {
0182 
0183 class SVGPreserveAspectRatio;
0184 class SVGSVGElement;
0185 
0186 class SVGElement : public StyledElement
0187 {
0188 public:
0189     SVGElement(const QualifiedName &, Document *);
0190     virtual ~SVGElement();
0191     bool isSVGElement() const override
0192     {
0193         return true;
0194     }
0195     virtual bool isSupported(StringImpl *feature, StringImpl *version) const;
0196 
0197     String attrid() const;
0198     void setId(const String &, ExceptionCode &);
0199     String xmlbase() const;
0200     void setXmlbase(const String &, ExceptionCode &);
0201 
0202     SVGSVGElement *ownerSVGElement() const;
0203     SVGElement *viewportElement() const;
0204 
0205     virtual void parseMappedAttribute(MappedAttribute *);
0206 
0207     virtual bool isStyled() const
0208     {
0209         return false;
0210     }
0211     virtual bool isStyledTransformable() const
0212     {
0213         return false;
0214     }
0215     virtual bool isStyledLocatable() const
0216     {
0217         return false;
0218     }
0219     virtual bool isSVG() const
0220     {
0221         return false;
0222     }
0223     virtual bool isFilterEffect() const
0224     {
0225         return false;
0226     }
0227     virtual bool isGradientStop() const
0228     {
0229         return false;
0230     }
0231     virtual bool isTextContent() const
0232     {
0233         return false;
0234     }
0235 
0236     bool isShadowNode() const override
0237     {
0238         return false; /*FIXME khtml return m_shadowParent;*/
0239     }
0240     Node *shadowParentNode() override
0241     {
0242         return m_shadowParent;
0243     }
0244     void setShadowParentNode(Node *node)
0245     {
0246         m_shadowParent = node;
0247     }
0248     virtual Node *eventParentNode()
0249     {
0250         return isShadowNode() ? shadowParentNode() : parentNode();
0251     }
0252 
0253     // For SVGTests
0254     virtual bool isValid() const
0255     {
0256         return true;
0257     }
0258 
0259     virtual void finishParsingChildren();
0260     // KHTML compatibility
0261     void close() override
0262     {
0263         finishParsingChildren();
0264         Element::close();
0265     }
0266     bool rendererIsNeeded(RenderStyle *) override
0267     {
0268         return false;
0269     }
0270     virtual bool childShouldCreateRenderer(Node *) const;
0271 
0272     void insertedIntoDocument() override;
0273     virtual void buildPendingResource() { }
0274 
0275     virtual void svgAttributeChanged(const QualifiedName &) { }
0276     using DOM::ElementImpl::attributeChanged;
0277     void attributeChanged(Attribute *, bool preserveDecls = false) override;
0278 
0279     void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
0280 
0281     virtual AffineTransform *supplementalTransform()
0282     {
0283         return nullptr;
0284     }
0285 
0286     // Forwarded properties (declared/defined anywhere else in the inheritance structure)
0287 
0288     // -> For SVGURIReference
0289     ANIMATED_PROPERTY_EMPTY_DECLARATIONS(String, String(), Href, href)
0290 
0291     // -> For SVGFitToViewBox
0292     ANIMATED_PROPERTY_EMPTY_DECLARATIONS(FloatRect, FloatRect(), ViewBox, viewBox)
0293     ANIMATED_PROPERTY_EMPTY_DECLARATIONS(SVGPreserveAspectRatio *, nullptr, PreserveAspectRatio, preserveAspectRatio)
0294 
0295     // -> For SVGExternalResourcesRequired
0296     ANIMATED_PROPERTY_EMPTY_DECLARATIONS(bool, false, ExternalResourcesRequired, externalResourcesRequired)
0297 
0298     virtual bool dispatchEvent(Event *e, ExceptionCode &ec, bool tempEvent = false);
0299 
0300     // for KHTML compatibility
0301     void parseAttribute(Attribute *attr) override
0302     {
0303         parseMappedAttribute(attr);
0304     }
0305     virtual void addCSSProperty(Attribute *attr, int id, const String &value);
0306     virtual void addCSSProperty(Attribute *attr, int id, int value);
0307 
0308 private:
0309     void addSVGEventListener(const DOM::EventImpl::EventId &eventType, const DOM::AttributeImpl *);
0310     virtual bool haveLoadedRequiredResources();
0311 
0312     Node *m_shadowParent;
0313 };
0314 
0315 } // namespace WebCore
0316 
0317 #endif // ENABLE(SVG)
0318 #endif // SVGElement_h