1/*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifndef SVGUseElement_h
22#define SVGUseElement_h
23
24#if ENABLE(SVG)
25#include "CachedResourceHandle.h"
26#include "CachedSVGDocumentClient.h"
27#include "SVGAnimatedBoolean.h"
28#include "SVGAnimatedLength.h"
29#include "SVGExternalResourcesRequired.h"
30#include "SVGLangSpace.h"
31#include "SVGStyledTransformableElement.h"
32#include "SVGTests.h"
33#include "SVGURIReference.h"
34
35namespace WebCore {
36
37class CachedSVGDocument;
38class SVGElementInstance;
39
40class SVGUseElement FINAL : public SVGStyledTransformableElement,
41                            public SVGTests,
42                            public SVGLangSpace,
43                            public SVGExternalResourcesRequired,
44                            public SVGURIReference,
45                            public CachedSVGDocumentClient {
46public:
47    static PassRefPtr<SVGUseElement> create(const QualifiedName&, Document*, bool wasInsertedByParser);
48    virtual ~SVGUseElement();
49
50    SVGElementInstance* instanceRoot();
51    SVGElementInstance* animatedInstanceRoot() const;
52    SVGElementInstance* instanceForShadowTreeElement(Node*) const;
53    void invalidateShadowTree();
54    void invalidateDependentShadowTrees();
55
56    RenderObject* rendererClipChild() const;
57
58protected:
59    virtual void didNotifySubtreeInsertions(ContainerNode*) override;
60
61private:
62    SVGUseElement(const QualifiedName&, Document*, bool wasInsertedByParser);
63
64    virtual bool isValid() const { return SVGTests::isValid(); }
65    virtual bool supportsFocus() const OVERRIDE { return true; }
66
67    virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
68    virtual void removedFrom(ContainerNode*) OVERRIDE;
69    virtual void buildPendingResource();
70
71    bool isSupportedAttribute(const QualifiedName&);
72    virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
73    virtual void svgAttributeChanged(const QualifiedName&);
74
75    virtual bool willRecalcStyle(StyleChange);
76
77    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
78    virtual void toClipPath(Path&);
79
80    void clearResourceReferences();
81    void buildShadowAndInstanceTree(SVGElement* target);
82    void detachInstance();
83
84    virtual bool haveLoadedRequiredResources() { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); }
85
86    virtual void finishParsingChildren();
87    virtual bool selfHasRelativeLengths() const;
88
89    // Instance tree handling
90    void buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundCycle, bool foundUse);
91    bool hasCycleUseReferencing(SVGUseElement*, SVGElementInstance* targetInstance, SVGElement*& newTarget);
92
93    // Shadow tree handling
94    void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance);
95
96    void expandUseElementsInShadowTree(Node* element);
97    void expandSymbolElementsInShadowTree(Node* element);
98
99    // "Tree connector"
100    void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance);
101    SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const;
102
103    void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const;
104    void transferEventListenersToShadowTree(SVGElementInstance* target);
105
106    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGUseElement)
107        DECLARE_ANIMATED_LENGTH(X, x)
108        DECLARE_ANIMATED_LENGTH(Y, y)
109        DECLARE_ANIMATED_LENGTH(Width, width)
110        DECLARE_ANIMATED_LENGTH(Height, height)
111        DECLARE_ANIMATED_STRING(Href, href)
112        DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
113    END_DECLARE_ANIMATED_PROPERTIES
114
115    bool cachedDocumentIsStillLoading();
116    Document* externalDocument() const;
117    bool instanceTreeIsLoading(SVGElementInstance*);
118    virtual void notifyFinished(CachedResource*);
119    Document* referencedDocument() const;
120    void setCachedDocument(CachedResourceHandle<CachedSVGDocument>);
121
122    // SVGTests
123    virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); }
124    virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
125    virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
126
127    // SVGExternalResourcesRequired
128    virtual void setHaveFiredLoadEvent(bool haveFiredLoadEvent) { m_haveFiredLoadEvent = haveFiredLoadEvent; }
129    virtual bool isParserInserted() const { return m_wasInsertedByParser; }
130    virtual bool haveFiredLoadEvent() const { return m_haveFiredLoadEvent; }
131    virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
132
133    bool m_wasInsertedByParser;
134    bool m_haveFiredLoadEvent;
135    bool m_needsShadowTreeRecreation;
136    RefPtr<SVGElementInstance> m_targetElementInstance;
137    CachedResourceHandle<CachedSVGDocument> m_cachedDocument;
138    Timer<SVGElement> m_svgLoadEventTimer;
139};
140
141}
142
143#endif
144#endif
145