Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / dom / MutationRecord.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "MutationRecord.h"
33
34 #include "CharacterData.h"
35 #include "StaticNodeList.h"
36 #include <wtf/NeverDestroyed.h>
37 #include <wtf/StdLibExtras.h>
38
39 namespace WebCore {
40
41 namespace {
42
43 class ChildListRecord : public MutationRecord {
44 public:
45     ChildListRecord(ContainerNode& target, Ref<NodeList>&& added, Ref<NodeList>&& removed, RefPtr<Node>&& previousSibling, RefPtr<Node>&& nextSibling)
46         : m_target(target)
47         , m_addedNodes(WTFMove(added))
48         , m_removedNodes(WTFMove(removed))
49         , m_previousSibling(WTFMove(previousSibling))
50         , m_nextSibling(WTFMove(nextSibling))
51     {
52     }
53
54 private:
55     const AtomicString& type() override;
56     Node* target() override { return m_target.ptr(); }
57     NodeList* addedNodes() override { return m_addedNodes.get(); }
58     NodeList* removedNodes() override { return m_removedNodes.get(); }
59     Node* previousSibling() override { return m_previousSibling.get(); }
60     Node* nextSibling() override { return m_nextSibling.get(); }
61
62     Ref<ContainerNode> m_target;
63     RefPtr<NodeList> m_addedNodes;
64     RefPtr<NodeList> m_removedNodes;
65     RefPtr<Node> m_previousSibling;
66     RefPtr<Node> m_nextSibling;
67 };
68
69 class RecordWithEmptyNodeLists : public MutationRecord {
70 public:
71     RecordWithEmptyNodeLists(Node& target, const String& oldValue)
72         : m_target(target)
73         , m_oldValue(oldValue)
74     {
75     }
76
77 private:
78     Node* target() override { return m_target.ptr(); }
79     String oldValue() override { return m_oldValue; }
80     NodeList* addedNodes() override { return lazilyInitializeEmptyNodeList(m_addedNodes); }
81     NodeList* removedNodes() override { return lazilyInitializeEmptyNodeList(m_removedNodes); }
82
83     static NodeList* lazilyInitializeEmptyNodeList(RefPtr<NodeList>& nodeList)
84     {
85         if (!nodeList)
86             nodeList = StaticNodeList::create();
87         return nodeList.get();
88     }
89
90     Ref<Node> m_target;
91     String m_oldValue;
92     RefPtr<NodeList> m_addedNodes;
93     RefPtr<NodeList> m_removedNodes;
94 };
95
96 class AttributesRecord : public RecordWithEmptyNodeLists {
97 public:
98     AttributesRecord(Element& target, const QualifiedName& name, const AtomicString& oldValue)
99         : RecordWithEmptyNodeLists(target, oldValue)
100         , m_attributeName(name.localName())
101         , m_attributeNamespace(name.namespaceURI())
102     {
103     }
104
105 private:
106     const AtomicString& type() override;
107     const AtomicString& attributeName() override { return m_attributeName; }
108     const AtomicString& attributeNamespace() override { return m_attributeNamespace; }
109
110     AtomicString m_attributeName;
111     AtomicString m_attributeNamespace;
112 };
113
114 class CharacterDataRecord : public RecordWithEmptyNodeLists {
115 public:
116     CharacterDataRecord(CharacterData& target, const String& oldValue)
117         : RecordWithEmptyNodeLists(target, oldValue)
118     {
119     }
120
121 private:
122     const AtomicString& type() override;
123 };
124
125 class MutationRecordWithNullOldValue : public MutationRecord {
126 public:
127     MutationRecordWithNullOldValue(MutationRecord& record)
128         : m_record(record)
129     {
130     }
131
132 private:
133     const AtomicString& type() override { return m_record->type(); }
134     Node* target() override { return m_record->target(); }
135     NodeList* addedNodes() override { return m_record->addedNodes(); }
136     NodeList* removedNodes() override { return m_record->removedNodes(); }
137     Node* previousSibling() override { return m_record->previousSibling(); }
138     Node* nextSibling() override { return m_record->nextSibling(); }
139     const AtomicString& attributeName() override { return m_record->attributeName(); }
140     const AtomicString& attributeNamespace() override { return m_record->attributeNamespace(); }
141
142     String oldValue() override { return String(); }
143
144     Ref<MutationRecord> m_record;
145 };
146
147 const AtomicString& ChildListRecord::type()
148 {
149     static NeverDestroyed<AtomicString> childList("childList", AtomicString::ConstructFromLiteral);
150     return childList;
151 }
152
153 const AtomicString& AttributesRecord::type()
154 {
155     static NeverDestroyed<AtomicString> attributes("attributes", AtomicString::ConstructFromLiteral);
156     return attributes;
157 }
158
159 const AtomicString& CharacterDataRecord::type()
160 {
161     static NeverDestroyed<AtomicString> characterData("characterData", AtomicString::ConstructFromLiteral);
162     return characterData;
163 }
164
165 } // namespace
166
167 Ref<MutationRecord> MutationRecord::createChildList(ContainerNode& target, Ref<NodeList>&& added, Ref<NodeList>&& removed, RefPtr<Node>&& previousSibling, RefPtr<Node>&& nextSibling)
168 {
169     return adoptRef(static_cast<MutationRecord&>(*new ChildListRecord(target, WTFMove(added), WTFMove(removed), WTFMove(previousSibling), WTFMove(nextSibling))));
170 }
171
172 Ref<MutationRecord> MutationRecord::createAttributes(Element& target, const QualifiedName& name, const AtomicString& oldValue)
173 {
174     return adoptRef(static_cast<MutationRecord&>(*new AttributesRecord(target, name, oldValue)));
175 }
176
177 Ref<MutationRecord> MutationRecord::createCharacterData(CharacterData& target, const String& oldValue)
178 {
179     return adoptRef(static_cast<MutationRecord&>(*new CharacterDataRecord(target, oldValue)));
180 }
181
182 Ref<MutationRecord> MutationRecord::createWithNullOldValue(MutationRecord& record)
183 {
184     return adoptRef(static_cast<MutationRecord&>(*new MutationRecordWithNullOldValue(record)));
185 }
186
187 MutationRecord::~MutationRecord() = default;
188
189 } // namespace WebCore