Build cleanly with GCC 9
[WebKit-https.git] / Source / WebCore / dom / Attr.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Peter Kelly (pmk@post.com)
5  *           (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2012 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 #include "config.h"
24 #include "Attr.h"
25
26 #include "AttributeChangeInvalidation.h"
27 #include "Event.h"
28 #include "ScopedEventQueue.h"
29 #include "StyleProperties.h"
30 #include "StyledElement.h"
31 #include "TextNodeTraversal.h"
32 #include "XMLNSNames.h"
33 #include <wtf/IsoMallocInlines.h>
34 #include <wtf/text/AtomicString.h>
35
36 namespace WebCore {
37
38 WTF_MAKE_ISO_ALLOCATED_IMPL(Attr);
39
40 using namespace HTMLNames;
41
42 Attr::Attr(Element& element, const QualifiedName& name)
43     : Node(element.document(), CreateOther)
44     , m_element(&element)
45     , m_name(name)
46 {
47 }
48
49 Attr::Attr(Document& document, const QualifiedName& name, const AtomicString& standaloneValue)
50     : Node(document, CreateOther)
51     , m_name(name)
52     , m_standaloneValue(standaloneValue)
53 {
54 }
55
56 Ref<Attr> Attr::create(Element& element, const QualifiedName& name)
57 {
58     return adoptRef(*new Attr(element, name));
59 }
60
61 Ref<Attr> Attr::create(Document& document, const QualifiedName& name, const AtomicString& value)
62 {
63     return adoptRef(*new Attr(document, name, value));
64 }
65
66 Attr::~Attr()
67 {
68     ASSERT_WITH_SECURITY_IMPLICATION(!isInShadowTree());
69     ASSERT_WITH_SECURITY_IMPLICATION(treeScope().rootNode().isDocumentNode());
70 }
71
72 ExceptionOr<void> Attr::setPrefix(const AtomicString& prefix)
73 {
74     auto result = checkSetPrefix(prefix);
75     if (result.hasException())
76         return result.releaseException();
77
78     if ((prefix == xmlnsAtom() && namespaceURI() != XMLNSNames::xmlnsNamespaceURI) || qualifiedName() == xmlnsAtom())
79         return Exception { NamespaceError };
80
81     const AtomicString& newPrefix = prefix.isEmpty() ? nullAtom() : prefix;
82     if (m_element)
83         elementAttribute().setPrefix(newPrefix);
84     m_name.setPrefix(newPrefix);
85
86     return { };
87 }
88
89 void Attr::setValue(const AtomicString& value)
90 {
91     if (m_element)
92         m_element->setAttribute(qualifiedName(), value);
93     else
94         m_standaloneValue = value;
95 }
96
97 ExceptionOr<void> Attr::setNodeValue(const String& value)
98 {
99     setValue(value);
100     return { };
101 }
102
103 Ref<Node> Attr::cloneNodeInternal(Document& targetDocument, CloningOperation)
104 {
105     return adoptRef(*new Attr(targetDocument, qualifiedName(), value()));
106 }
107
108 CSSStyleDeclaration* Attr::style()
109 {
110     // This is not part of the DOM API, and therefore not available to webpages. However, WebKit SPI
111     // lets clients use this via the Objective-C and JavaScript bindings.
112     if (!is<StyledElement>(m_element))
113         return nullptr;
114     m_style = MutableStyleProperties::create();
115     downcast<StyledElement>(*m_element).collectStyleForPresentationAttribute(qualifiedName(), value(), *m_style);
116     return &m_style->ensureCSSStyleDeclaration();
117 }
118
119 const AtomicString& Attr::value() const
120 {
121     if (m_element)
122         return m_element->getAttribute(qualifiedName());
123     return m_standaloneValue;
124 }
125
126 Attribute& Attr::elementAttribute()
127 {
128     ASSERT(m_element);
129     ASSERT(m_element->elementData());
130     return *m_element->ensureUniqueElementData().findAttributeByName(qualifiedName());
131 }
132
133 void Attr::detachFromElementWithValue(const AtomicString& value)
134 {
135     ASSERT(m_element);
136     ASSERT(m_standaloneValue.isNull());
137     m_standaloneValue = value;
138     m_element = nullptr;
139     setTreeScopeRecursively(document());
140 }
141
142 void Attr::attachToElement(Element& element)
143 {
144     ASSERT(!m_element);
145     m_element = &element;
146     m_standaloneValue = nullAtom();
147     setTreeScopeRecursively(element.treeScope());
148 }
149
150 }