Improve use of NeverDestroyed
[WebKit-https.git] / Source / WebCore / svg / SVGCursorElement.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006, 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 #include "config.h"
22 #include "SVGCursorElement.h"
23
24 #include "CSSCursorImageValue.h"
25 #include "Document.h"
26 #include "SVGNames.h"
27 #include "SVGStringList.h"
28 #include "XLinkNames.h"
29 #include <wtf/NeverDestroyed.h>
30
31 namespace WebCore {
32
33 // Animated property definitions
34 DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::xAttr, X, x)
35 DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::yAttr, Y, y)
36 DEFINE_ANIMATED_STRING(SVGCursorElement, XLinkNames::hrefAttr, Href, href)
37 DEFINE_ANIMATED_BOOLEAN(SVGCursorElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
38
39 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGCursorElement)
40     REGISTER_LOCAL_ANIMATED_PROPERTY(x)
41     REGISTER_LOCAL_ANIMATED_PROPERTY(y)
42     REGISTER_LOCAL_ANIMATED_PROPERTY(href)
43     REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
44     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
45 END_REGISTER_ANIMATED_PROPERTIES
46
47 inline SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document& document)
48     : SVGElement(tagName, document)
49     , m_x(LengthModeWidth)
50     , m_y(LengthModeHeight)
51 {
52     ASSERT(hasTagName(SVGNames::cursorTag));
53     registerAnimatedPropertiesForSVGCursorElement();
54 }
55
56 Ref<SVGCursorElement> SVGCursorElement::create(const QualifiedName& tagName, Document& document)
57 {
58     return adoptRef(*new SVGCursorElement(tagName, document));
59 }
60
61 SVGCursorElement::~SVGCursorElement()
62 {
63     for (auto& client : m_clients)
64         client->cursorElementRemoved(*this);
65 }
66
67 bool SVGCursorElement::isSupportedAttribute(const QualifiedName& attrName)
68 {
69     static const auto supportedAttributes = makeNeverDestroyed([] {
70         HashSet<QualifiedName> set;
71         SVGTests::addSupportedAttributes(set);
72         SVGExternalResourcesRequired::addSupportedAttributes(set);
73         SVGURIReference::addSupportedAttributes(set);
74         set.add({ SVGNames::xAttr, SVGNames::yAttr });
75         return set;
76     }());
77     return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
78 }
79
80 void SVGCursorElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
81 {
82     SVGParsingError parseError = NoError;
83
84     if (name == SVGNames::xAttr)
85         setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
86     else if (name == SVGNames::yAttr)
87         setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
88
89     reportAttributeParsingError(parseError, name, value);
90
91     SVGElement::parseAttribute(name, value);
92     SVGTests::parseAttribute(name, value);
93     SVGExternalResourcesRequired::parseAttribute(name, value);
94     SVGURIReference::parseAttribute(name, value);
95 }
96
97 void SVGCursorElement::addClient(CSSCursorImageValue& value)
98 {
99     m_clients.add(&value);
100 }
101
102 void SVGCursorElement::removeClient(CSSCursorImageValue& value)
103 {
104     m_clients.remove(&value);
105 }
106
107 void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName)
108 {
109     if (!isSupportedAttribute(attrName)) {
110         SVGElement::svgAttributeChanged(attrName);
111         return;
112     }
113
114     InstanceInvalidationGuard guard(*this);
115     for (auto& client : m_clients)
116         client->cursorElementChanged(*this);
117 }
118
119 void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
120 {
121     SVGElement::addSubresourceAttributeURLs(urls);
122
123     addSubresourceURL(urls, document().completeURL(href()));
124 }
125
126 Ref<SVGStringList> SVGCursorElement::requiredFeatures()
127 {
128     return SVGTests::requiredFeatures(*this);
129 }
130
131 Ref<SVGStringList> SVGCursorElement::requiredExtensions()
132
133     return SVGTests::requiredExtensions(*this);
134 }
135
136 Ref<SVGStringList> SVGCursorElement::systemLanguage()
137 {
138     return SVGTests::systemLanguage(*this);
139 }
140
141 }