Remove the SVG elements' attributes macros
[WebKit-https.git] / Source / WebCore / svg / SVGExternalResourcesRequired.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2007 Rob Buis <buis@kde.org>
4  * Copyright (C) 2018 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 #include "config.h"
23 #include "SVGExternalResourcesRequired.h"
24
25 #include "SVGElement.h"
26 #include "SVGNames.h"
27
28 namespace WebCore {
29
30 SVGExternalResourcesRequired::SVGExternalResourcesRequired(SVGElement* contextElement)
31     : m_contextElement(*contextElement)
32 {
33     registerAttributes();
34 }
35
36 void SVGExternalResourcesRequired::registerAttributes()
37 {
38     auto& registry = attributeRegistry();
39     if (!registry.isEmpty())
40         return;
41     registry.registerAttribute<SVGNames::externalResourcesRequiredAttr, &SVGEllipseElement::m_externalResourcesRequired>();
42 }
43
44 void SVGExternalResourcesRequired::parseAttribute(const QualifiedName& name, const AtomicString& value)
45 {
46     if (name == SVGNames::externalResourcesRequiredAttr)
47         setExternalResourcesRequired(value == "true");
48 }
49
50 void SVGExternalResourcesRequired::svgAttributeChanged(const QualifiedName& attrName)
51 {
52     if (!isKnownAttribute(attrName))
53         return;
54     if (!m_contextElement.isConnected())
55         return;
56
57     // Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false'
58     // causes an immediate dispatch of the SVGLoad event. If the attribute value was 'false' before inserting the script element
59     // in the document, the SVGLoad event has already been dispatched.
60     if (!externalResourcesRequired() && !haveFiredLoadEvent() && !isParserInserted()) {
61         setHaveFiredLoadEvent(true);
62
63         ASSERT(m_contextElement.haveLoadedRequiredResources());
64         m_contextElement.sendSVGLoadEventIfPossible();
65     }
66
67     auto* renderer = m_contextElement.renderer();
68     if (renderer && is<RenderSVGShape>(renderer)) {
69         SVGElement::InstanceInvalidationGuard guard(m_contextElement);
70         RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
71     }
72 }
73
74 void SVGExternalResourcesRequired::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
75 {
76     supportedAttributes.add(SVGNames::externalResourcesRequiredAttr);
77 }
78
79 void SVGExternalResourcesRequired::dispatchLoadEvent()
80 {
81     if (isParserInserted())
82         ASSERT(externalResourcesRequired() != haveFiredLoadEvent());
83     else if (haveFiredLoadEvent())
84         return;
85
86     // HTML and SVG differ completely in the 'onload' event handling of <script> elements.
87     // HTML fires the 'load' event after it sucessfully loaded a remote resource, otherwise an error event.
88     // SVG fires the SVGLoad event immediately after parsing the <script> element, if externalResourcesRequired
89     // is set to 'false', otherwise it dispatches the 'SVGLoad' event just after loading the remote resource.
90     if (!externalResourcesRequired())
91         return;
92
93     ASSERT(!haveFiredLoadEvent());
94
95     // Dispatch SVGLoad event
96     setHaveFiredLoadEvent(true);
97     ASSERT(m_contextElement.haveLoadedRequiredResources());
98
99     m_contextElement.sendSVGLoadEventIfPossible();
100 }
101
102 void SVGExternalResourcesRequired::insertedIntoDocument()
103 {
104     if (isParserInserted())
105         return;
106
107     // Eventually send SVGLoad event now for the dynamically inserted script element.
108     if (externalResourcesRequired())
109         return;
110     setHaveFiredLoadEvent(true);
111     m_contextElement.sendSVGLoadEventIfPossibleAsynchronously();
112 }
113
114 void SVGExternalResourcesRequired::finishParsingChildren()
115 {
116     // A SVGLoad event has been fired by SVGElement::finishParsingChildren.
117     if (!externalResourcesRequired())
118         setHaveFiredLoadEvent(true);
119 }
120
121 bool SVGExternalResourcesRequired::haveLoadedRequiredResources() const
122 {
123     return !externalResourcesRequired() || haveFiredLoadEvent();
124 }
125
126 }