2
* Copyright (C) 2012 Google Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are
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
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.
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.
35
#include "DOMEditor.h"
37
#include "DOMPatchSupport.h"
40
#include "ExceptionCode.h"
41
#include "InspectorHistory.h"
47
#include <wtf/RefPtr.h>
53
class DOMEditor::RemoveChildAction : public InspectorHistory::Action {
54
WTF_MAKE_NONCOPYABLE(RemoveChildAction);
56
RemoveChildAction(Node* parentNode, Node* node)
57
: InspectorHistory::Action("RemoveChild")
58
, m_parentNode(parentNode)
63
virtual bool perform(ExceptionCode& ec)
65
m_anchorNode = m_node->nextSibling();
69
virtual bool undo(ExceptionCode& ec)
71
return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
74
virtual bool redo(ExceptionCode& ec)
76
return m_parentNode->removeChild(m_node.get(), ec);
80
RefPtr<Node> m_parentNode;
82
RefPtr<Node> m_anchorNode;
85
class DOMEditor::InsertBeforeAction : public InspectorHistory::Action {
86
WTF_MAKE_NONCOPYABLE(InsertBeforeAction);
88
InsertBeforeAction(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode)
89
: InspectorHistory::Action("InsertBefore")
90
, m_parentNode(parentNode)
92
, m_anchorNode(anchorNode)
96
virtual bool perform(ExceptionCode& ec)
98
if (m_node->parentNode()) {
99
m_removeChildAction = adoptPtr(new RemoveChildAction(m_node->parentNode(), m_node.get()));
100
if (!m_removeChildAction->perform(ec))
103
return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
106
virtual bool undo(ExceptionCode& ec)
108
if (!m_parentNode->removeChild(m_node.get(), ec))
110
if (m_removeChildAction)
111
return m_removeChildAction->undo(ec);
115
virtual bool redo(ExceptionCode& ec)
117
if (m_removeChildAction && !m_removeChildAction->redo(ec))
119
return m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), ec);
123
RefPtr<Node> m_parentNode;
125
RefPtr<Node> m_anchorNode;
126
OwnPtr<RemoveChildAction> m_removeChildAction;
129
class DOMEditor::RemoveAttributeAction : public InspectorHistory::Action {
130
WTF_MAKE_NONCOPYABLE(RemoveAttributeAction);
132
RemoveAttributeAction(Element* element, const String& name)
133
: InspectorHistory::Action("RemoveAttribute")
139
virtual bool perform(ExceptionCode& ec)
141
m_value = m_element->getAttribute(m_name);
145
virtual bool undo(ExceptionCode& ec)
147
m_element->setAttribute(m_name, m_value, ec);
151
virtual bool redo(ExceptionCode&)
153
m_element->removeAttribute(m_name);
158
RefPtr<Element> m_element;
163
class DOMEditor::SetAttributeAction : public InspectorHistory::Action {
164
WTF_MAKE_NONCOPYABLE(SetAttributeAction);
166
SetAttributeAction(Element* element, const String& name, const String& value)
167
: InspectorHistory::Action("SetAttribute")
171
, m_hadAttribute(false)
175
virtual bool perform(ExceptionCode& ec)
177
m_hadAttribute = m_element->hasAttribute(m_name);
179
m_oldValue = m_element->getAttribute(m_name);
183
virtual bool undo(ExceptionCode& ec)
186
m_element->setAttribute(m_name, m_oldValue, ec);
188
m_element->removeAttribute(m_name);
192
virtual bool redo(ExceptionCode& ec)
194
m_element->setAttribute(m_name, m_value, ec);
199
RefPtr<Element> m_element;
206
class DOMEditor::SetOuterHTMLAction : public InspectorHistory::Action {
207
WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction);
209
SetOuterHTMLAction(Node* node, const String& html)
210
: InspectorHistory::Action("SetOuterHTML")
212
, m_nextSibling(node->nextSibling())
215
, m_history(adoptPtr(new InspectorHistory()))
216
, m_domEditor(adoptPtr(new DOMEditor(m_history.get())))
220
virtual bool perform(ExceptionCode& ec)
222
m_oldHTML = createMarkup(m_node.get());
223
DOMPatchSupport domPatchSupport(m_domEditor.get(), m_node->ownerDocument());
224
m_newNode = domPatchSupport.patchNode(m_node.get(), m_html, ec);
228
virtual bool undo(ExceptionCode& ec)
230
return m_history->undo(ec);
233
virtual bool redo(ExceptionCode& ec)
235
return m_history->redo(ec);
245
RefPtr<Node> m_nextSibling;
249
OwnPtr<InspectorHistory> m_history;
250
OwnPtr<DOMEditor> m_domEditor;
253
class DOMEditor::ReplaceWholeTextAction : public InspectorHistory::Action {
254
WTF_MAKE_NONCOPYABLE(ReplaceWholeTextAction);
256
ReplaceWholeTextAction(Text* textNode, const String& text)
257
: InspectorHistory::Action("ReplaceWholeText")
258
, m_textNode(textNode)
263
virtual bool perform(ExceptionCode& ec)
265
m_oldText = m_textNode->wholeText();
269
virtual bool undo(ExceptionCode& ec)
271
m_textNode->replaceWholeText(m_oldText, ec);
275
virtual bool redo(ExceptionCode& ec)
277
m_textNode->replaceWholeText(m_text, ec);
282
RefPtr<Text> m_textNode;
287
class DOMEditor::ReplaceChildNodeAction : public InspectorHistory::Action {
288
WTF_MAKE_NONCOPYABLE(ReplaceChildNodeAction);
290
ReplaceChildNodeAction(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode)
291
: InspectorHistory::Action("ReplaceChildNode")
292
, m_parentNode(parentNode)
298
virtual bool perform(ExceptionCode& ec)
303
virtual bool undo(ExceptionCode& ec)
305
return m_parentNode->replaceChild(m_oldNode, m_newNode.get(), ec);
308
virtual bool redo(ExceptionCode& ec)
310
return m_parentNode->replaceChild(m_newNode, m_oldNode.get(), ec);
314
RefPtr<Node> m_parentNode;
315
RefPtr<Node> m_newNode;
316
RefPtr<Node> m_oldNode;
319
class DOMEditor::SetNodeValueAction : public InspectorHistory::Action {
320
WTF_MAKE_NONCOPYABLE(SetNodeValueAction);
322
SetNodeValueAction(Node* node, const String& value)
323
: InspectorHistory::Action("SetNodeValue")
329
virtual bool perform(ExceptionCode& ec)
331
m_oldValue = m_node->nodeValue();
335
virtual bool undo(ExceptionCode& ec)
337
m_node->setNodeValue(m_oldValue, ec);
341
virtual bool redo(ExceptionCode& ec)
343
m_node->setNodeValue(m_value, ec);
353
DOMEditor::DOMEditor(InspectorHistory* history) : m_history(history) { }
355
DOMEditor::~DOMEditor() { }
357
bool DOMEditor::insertBefore(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode, ExceptionCode& ec)
359
return m_history->perform(adoptPtr(new InsertBeforeAction(parentNode, node, anchorNode)), ec);
362
bool DOMEditor::removeChild(Node* parentNode, Node* node, ExceptionCode& ec)
364
return m_history->perform(adoptPtr(new RemoveChildAction(parentNode, node)), ec);
367
bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ExceptionCode& ec)
369
return m_history->perform(adoptPtr(new SetAttributeAction(element, name, value)), ec);
372
bool DOMEditor::removeAttribute(Element* element, const String& name, ExceptionCode& ec)
374
return m_history->perform(adoptPtr(new RemoveAttributeAction(element, name)), ec);
377
bool DOMEditor::setOuterHTML(Node* node, const String& html, Node** newNode, ExceptionCode& ec)
379
OwnPtr<SetOuterHTMLAction> action = adoptPtr(new SetOuterHTMLAction(node, html));
380
SetOuterHTMLAction* rawAction = action.get();
381
bool result = m_history->perform(action.release(), ec);
383
*newNode = rawAction->newNode();
387
bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ExceptionCode& ec)
389
return m_history->perform(adoptPtr(new ReplaceWholeTextAction(textNode, text)), ec);
392
bool DOMEditor::replaceChild(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode, ExceptionCode& ec)
394
return m_history->perform(adoptPtr(new ReplaceChildNodeAction(parentNode, newNode, oldNode)), ec);
397
bool DOMEditor::setNodeValue(Node* node, const String& value, ExceptionCode& ec)
399
return m_history->perform(adoptPtr(new SetNodeValueAction(node, value)), ec);
402
static void populateErrorString(const ExceptionCode& ec, ErrorString* errorString)
405
ExceptionCodeDescription description(ec);
406
*errorString = description.name;
410
bool DOMEditor::insertBefore(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode, ErrorString* errorString)
412
ExceptionCode ec = 0;
413
bool result = insertBefore(parentNode, node, anchorNode, ec);
414
populateErrorString(ec, errorString);
418
bool DOMEditor::removeChild(Node* parentNode, Node* node, ErrorString* errorString)
420
ExceptionCode ec = 0;
421
bool result = removeChild(parentNode, node, ec);
422
populateErrorString(ec, errorString);
426
bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ErrorString* errorString)
428
ExceptionCode ec = 0;
429
bool result = setAttribute(element, name, value, ec);
430
populateErrorString(ec, errorString);
434
bool DOMEditor::removeAttribute(Element* element, const String& name, ErrorString* errorString)
436
ExceptionCode ec = 0;
437
bool result = removeAttribute(element, name, ec);
438
populateErrorString(ec, errorString);
442
bool DOMEditor::setOuterHTML(Node* node, const String& html, Node** newNode, ErrorString* errorString)
444
ExceptionCode ec = 0;
445
bool result = setOuterHTML(node, html, newNode, ec);
446
populateErrorString(ec, errorString);
450
bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ErrorString* errorString)
452
ExceptionCode ec = 0;
453
bool result = replaceWholeText(textNode, text, ec);
454
populateErrorString(ec, errorString);
458
} // namespace WebCore
460
#endif // ENABLE(INSPECTOR)