Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / inspector / DOMEditor.cpp
1 /*
2  * Copyright (C) 2012 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 "DOMEditor.h"
33
34 #include "DOMPatchSupport.h"
35 #include "Document.h"
36 #include "Element.h"
37 #include "ExceptionCode.h"
38 #include "ExceptionCodeDescription.h"
39 #include "InspectorHistory.h"
40 #include "Node.h"
41 #include "Text.h"
42 #include "markup.h"
43 #include <wtf/RefPtr.h>
44
45 namespace WebCore {
46
47 class DOMEditor::RemoveChildAction : public InspectorHistory::Action {
48     WTF_MAKE_NONCOPYABLE(RemoveChildAction);
49 public:
50     RemoveChildAction(Node* parentNode, Node* node)
51         : InspectorHistory::Action("RemoveChild")
52         , m_parentNode(parentNode)
53         , m_node(node)
54     {
55     }
56
57     virtual bool perform(ExceptionCode& ec) override
58     {
59         m_anchorNode = m_node->nextSibling();
60         return redo(ec);
61     }
62
63     virtual bool undo(ExceptionCode& ec) override
64     {
65         return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
66     }
67
68     virtual bool redo(ExceptionCode& ec) override
69     {
70         return m_parentNode->removeChild(m_node.get(), ec);
71     }
72
73 private:
74     RefPtr<Node> m_parentNode;
75     RefPtr<Node> m_node;
76     RefPtr<Node> m_anchorNode;
77 };
78
79 class DOMEditor::InsertBeforeAction : public InspectorHistory::Action {
80     WTF_MAKE_NONCOPYABLE(InsertBeforeAction);
81 public:
82     InsertBeforeAction(Node* parentNode, RefPtr<Node>&& node, Node* anchorNode)
83         : InspectorHistory::Action("InsertBefore")
84         , m_parentNode(parentNode)
85         , m_node(WTFMove(node))
86         , m_anchorNode(anchorNode)
87     {
88     }
89
90     virtual bool perform(ExceptionCode& ec) override
91     {
92         if (m_node->parentNode()) {
93             m_removeChildAction = std::make_unique<RemoveChildAction>(m_node->parentNode(), m_node.get());
94             if (!m_removeChildAction->perform(ec))
95                 return false;
96         }
97         return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
98     }
99
100     virtual bool undo(ExceptionCode& ec) override
101     {
102         if (!m_parentNode->removeChild(m_node.get(), ec))
103             return false;
104         if (m_removeChildAction)
105             return m_removeChildAction->undo(ec);
106         return true;
107     }
108
109     virtual bool redo(ExceptionCode& ec) override
110     {
111         if (m_removeChildAction && !m_removeChildAction->redo(ec))
112             return false;
113         return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
114     }
115
116 private:
117     RefPtr<Node> m_parentNode;
118     RefPtr<Node> m_node;
119     RefPtr<Node> m_anchorNode;
120     std::unique_ptr<RemoveChildAction> m_removeChildAction;
121 };
122
123 class DOMEditor::RemoveAttributeAction : public InspectorHistory::Action {
124     WTF_MAKE_NONCOPYABLE(RemoveAttributeAction);
125 public:
126     RemoveAttributeAction(Element* element, const String& name)
127         : InspectorHistory::Action("RemoveAttribute")
128         , m_element(element)
129         , m_name(name)
130     {
131     }
132
133     virtual bool perform(ExceptionCode& ec) override
134     {
135         m_value = m_element->getAttribute(m_name);
136         return redo(ec);
137     }
138
139     virtual bool undo(ExceptionCode& ec) override
140     {
141         m_element->setAttribute(m_name, m_value, ec);
142         return true;
143     }
144
145     virtual bool redo(ExceptionCode&) override
146     {
147         m_element->removeAttribute(m_name);
148         return true;
149     }
150
151 private:
152     RefPtr<Element> m_element;
153     String m_name;
154     String m_value;
155 };
156
157 class DOMEditor::SetAttributeAction : public InspectorHistory::Action {
158     WTF_MAKE_NONCOPYABLE(SetAttributeAction);
159 public:
160     SetAttributeAction(Element* element, const String& name, const String& value)
161         : InspectorHistory::Action("SetAttribute")
162         , m_element(element)
163         , m_name(name)
164         , m_value(value)
165         , m_hadAttribute(false)
166     {
167     }
168
169     virtual bool perform(ExceptionCode& ec) override
170     {
171         m_hadAttribute = m_element->hasAttribute(m_name);
172         if (m_hadAttribute)
173             m_oldValue = m_element->getAttribute(m_name);
174         return redo(ec);
175     }
176
177     virtual bool undo(ExceptionCode& ec) override
178     {
179         if (m_hadAttribute)
180             m_element->setAttribute(m_name, m_oldValue, ec);
181         else
182             m_element->removeAttribute(m_name);
183         return true;
184     }
185
186     virtual bool redo(ExceptionCode& ec) override
187     {
188         m_element->setAttribute(m_name, m_value, ec);
189         return true;
190     }
191
192 private:
193     RefPtr<Element> m_element;
194     String m_name;
195     String m_value;
196     bool m_hadAttribute;
197     String m_oldValue;
198 };
199
200 class DOMEditor::SetOuterHTMLAction : public InspectorHistory::Action {
201     WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction);
202 public:
203     SetOuterHTMLAction(Node& node, const String& html)
204         : InspectorHistory::Action("SetOuterHTML")
205         , m_node(node)
206         , m_nextSibling(node.nextSibling())
207         , m_html(html)
208         , m_newNode(nullptr)
209         , m_history(std::make_unique<InspectorHistory>())
210         , m_domEditor(std::make_unique<DOMEditor>(m_history.get()))
211     {
212     }
213
214     virtual bool perform(ExceptionCode& ec) override
215     {
216         m_oldHTML = createMarkup(m_node.get());
217         DOMPatchSupport domPatchSupport(m_domEditor.get(), &m_node->document());
218         m_newNode = domPatchSupport.patchNode(m_node.get(), m_html, ec);
219         return !ec;
220     }
221
222     virtual bool undo(ExceptionCode& ec) override
223     {
224         return m_history->undo(ec);
225     }
226
227     virtual bool redo(ExceptionCode& ec) override
228     {
229         return m_history->redo(ec);
230     }
231
232     Node* newNode()
233     {
234         return m_newNode;
235     }
236
237 private:
238     Ref<Node> m_node;
239     RefPtr<Node> m_nextSibling;
240     String m_html;
241     String m_oldHTML;
242     Node* m_newNode;
243     std::unique_ptr<InspectorHistory> m_history;
244     std::unique_ptr<DOMEditor> m_domEditor;
245 };
246
247 class DOMEditor::ReplaceWholeTextAction : public InspectorHistory::Action {
248     WTF_MAKE_NONCOPYABLE(ReplaceWholeTextAction);
249 public:
250     ReplaceWholeTextAction(Text* textNode, const String& text)
251         : InspectorHistory::Action("ReplaceWholeText")
252         , m_textNode(textNode)
253         , m_text(text)
254     {
255     }
256
257     virtual bool perform(ExceptionCode& ec) override
258     {
259         m_oldText = m_textNode->wholeText();
260         return redo(ec);
261     }
262
263     virtual bool undo(ExceptionCode& ec) override
264     {
265         m_textNode->replaceWholeText(m_oldText, ec);
266         return true;
267     }
268
269     virtual bool redo(ExceptionCode& ec) override
270     {
271         m_textNode->replaceWholeText(m_text, ec);
272         return true;
273     }
274
275 private:
276     RefPtr<Text> m_textNode;
277     String m_text;
278     String m_oldText;
279 };
280
281 class DOMEditor::ReplaceChildNodeAction : public InspectorHistory::Action {
282     WTF_MAKE_NONCOPYABLE(ReplaceChildNodeAction);
283 public:
284     ReplaceChildNodeAction(Node* parentNode, RefPtr<Node>&& newNode, Node* oldNode)
285         : InspectorHistory::Action("ReplaceChildNode")
286         , m_parentNode(parentNode)
287         , m_newNode(WTFMove(newNode))
288         , m_oldNode(oldNode)
289     {
290     }
291
292     virtual bool perform(ExceptionCode& ec) override
293     {
294         return redo(ec);
295     }
296
297     virtual bool undo(ExceptionCode& ec) override
298     {
299         return m_parentNode->replaceChild(m_oldNode, m_newNode.get(), ec);
300     }
301
302     virtual bool redo(ExceptionCode& ec) override
303     {
304         return m_parentNode->replaceChild(m_newNode, m_oldNode.get(), ec);
305     }
306
307 private:
308     RefPtr<Node> m_parentNode;
309     RefPtr<Node> m_newNode;
310     RefPtr<Node> m_oldNode;
311 };
312
313 class DOMEditor::SetNodeValueAction : public InspectorHistory::Action {
314     WTF_MAKE_NONCOPYABLE(SetNodeValueAction);
315 public:
316     SetNodeValueAction(Node* node, const String& value)
317         : InspectorHistory::Action("SetNodeValue")
318         , m_node(node)
319         , m_value(value)
320     {
321     }
322
323     virtual bool perform(ExceptionCode& ec) override
324     {
325         m_oldValue = m_node->nodeValue();
326         return redo(ec);
327     }
328
329     virtual bool undo(ExceptionCode& ec) override
330     {
331         m_node->setNodeValue(m_oldValue, ec);
332         return !ec;
333     }
334
335     virtual bool redo(ExceptionCode& ec) override
336     {
337         m_node->setNodeValue(m_value, ec);
338         return !ec;
339     }
340
341 private:
342     RefPtr<Node> m_node;
343     String m_value;
344     String m_oldValue;
345 };
346
347 DOMEditor::DOMEditor(InspectorHistory* history) : m_history(history) { }
348
349 DOMEditor::~DOMEditor() { }
350
351 bool DOMEditor::insertBefore(Node* parentNode, RefPtr<Node>&& node, Node* anchorNode, ExceptionCode& ec)
352 {
353     return m_history->perform(std::make_unique<InsertBeforeAction>(parentNode, WTFMove(node), anchorNode), ec);
354 }
355
356 bool DOMEditor::removeChild(Node* parentNode, Node* node, ExceptionCode& ec)
357 {
358     return m_history->perform(std::make_unique<RemoveChildAction>(parentNode, node), ec);
359 }
360
361 bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ExceptionCode& ec)
362 {
363     return m_history->perform(std::make_unique<SetAttributeAction>(element, name, value), ec);
364 }
365
366 bool DOMEditor::removeAttribute(Element* element, const String& name, ExceptionCode& ec)
367 {
368     return m_history->perform(std::make_unique<RemoveAttributeAction>(element, name), ec);
369 }
370
371 bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ExceptionCode& ec)
372 {
373     auto action = std::make_unique<SetOuterHTMLAction>(node, html);
374     SetOuterHTMLAction* rawAction = action.get();
375     bool result = m_history->perform(WTFMove(action), ec);
376     if (result)
377         *newNode = rawAction->newNode();
378     return result;
379 }
380
381 bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ExceptionCode& ec)
382 {
383     return m_history->perform(std::make_unique<ReplaceWholeTextAction>(textNode, text), ec);
384 }
385
386 bool DOMEditor::replaceChild(Node* parentNode, RefPtr<Node>&& newNode, Node* oldNode, ExceptionCode& ec)
387 {
388     return m_history->perform(std::make_unique<ReplaceChildNodeAction>(parentNode, WTFMove(newNode), oldNode), ec);
389 }
390
391 bool DOMEditor::setNodeValue(Node* node, const String& value, ExceptionCode& ec)
392 {
393     return m_history->perform(std::make_unique<SetNodeValueAction>(node, value), ec);
394 }
395
396 static void populateErrorString(const ExceptionCode& ec, ErrorString& errorString)
397 {
398     if (ec) {
399         ExceptionCodeDescription description(ec);
400         errorString = description.name;
401     }
402 }
403
404 bool DOMEditor::insertBefore(Node* parentNode, RefPtr<Node>&& node, Node* anchorNode, ErrorString& errorString)
405 {
406     ExceptionCode ec = 0;
407     bool result = insertBefore(parentNode, WTFMove(node), anchorNode, ec);
408     populateErrorString(ec, errorString);
409     return result;
410 }
411
412 bool DOMEditor::removeChild(Node* parentNode, Node* node, ErrorString& errorString)
413 {
414     ExceptionCode ec = 0;
415     bool result = removeChild(parentNode, node, ec);
416     populateErrorString(ec, errorString);
417     return result;
418 }
419
420 bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ErrorString& errorString)
421 {
422     ExceptionCode ec = 0;
423     bool result = setAttribute(element, name, value, ec);
424     populateErrorString(ec, errorString);
425     return result;
426 }
427
428 bool DOMEditor::removeAttribute(Element* element, const String& name, ErrorString& errorString)
429 {
430     ExceptionCode ec = 0;
431     bool result = removeAttribute(element, name, ec);
432     populateErrorString(ec, errorString);
433     return result;
434 }
435
436 bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ErrorString& errorString)
437 {
438     ExceptionCode ec = 0;
439     bool result = setOuterHTML(node, html, newNode, ec);
440     populateErrorString(ec, errorString);
441     return result;
442 }
443
444 bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ErrorString& errorString)
445 {
446     ExceptionCode ec = 0;
447     bool result = replaceWholeText(textNode, text, ec);
448     populateErrorString(ec, errorString);
449     return result;
450 }
451
452 } // namespace WebCore