editor/libeditor/base/DeleteNodeTxn.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:084578daa48e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "DeleteNodeTxn.h"
7 #include "nsDebug.h"
8 #include "nsEditor.h"
9 #include "nsError.h"
10 #include "nsSelectionState.h" // nsRangeUpdater
11 #include "nsAString.h"
12
13 using namespace mozilla;
14
15 DeleteNodeTxn::DeleteNodeTxn()
16 : EditTxn(), mNode(), mParent(), mRefNode(), mRangeUpdater(nullptr)
17 {
18 }
19
20 NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteNodeTxn, EditTxn,
21 mNode,
22 mParent,
23 mRefNode)
24
25 NS_IMPL_ADDREF_INHERITED(DeleteNodeTxn, EditTxn)
26 NS_IMPL_RELEASE_INHERITED(DeleteNodeTxn, EditTxn)
27 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteNodeTxn)
28 NS_INTERFACE_MAP_END_INHERITING(EditTxn)
29
30 nsresult
31 DeleteNodeTxn::Init(nsEditor* aEditor, nsINode* aNode,
32 nsRangeUpdater* aRangeUpdater)
33 {
34 NS_ENSURE_TRUE(aEditor && aNode, NS_ERROR_NULL_POINTER);
35 mEditor = aEditor;
36 mNode = aNode;
37 mParent = aNode->GetParentNode();
38
39 // do nothing if the node has a parent and it's read-only
40 NS_ENSURE_TRUE(!mParent || mEditor->IsModifiableNode(mParent),
41 NS_ERROR_FAILURE);
42
43 mRangeUpdater = aRangeUpdater;
44 return NS_OK;
45 }
46
47
48 NS_IMETHODIMP
49 DeleteNodeTxn::DoTransaction()
50 {
51 NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
52
53 if (!mParent) {
54 // this is a no-op, there's no parent to delete mNode from
55 return NS_OK;
56 }
57
58 // remember which child mNode was (by remembering which child was next);
59 // mRefNode can be null
60 mRefNode = mNode->GetNextSibling();
61
62 // give range updater a chance. SelAdjDeleteNode() needs to be called
63 // *before* we do the action, unlike some of the other nsRangeStore update
64 // methods.
65 if (mRangeUpdater) {
66 mRangeUpdater->SelAdjDeleteNode(mNode->AsDOMNode());
67 }
68
69 ErrorResult error;
70 mParent->RemoveChild(*mNode, error);
71 return error.ErrorCode();
72 }
73
74 NS_IMETHODIMP
75 DeleteNodeTxn::UndoTransaction()
76 {
77 if (!mParent) {
78 // this is a legal state, the txn is a no-op
79 return NS_OK;
80 }
81 if (!mNode) {
82 return NS_ERROR_NULL_POINTER;
83 }
84
85 ErrorResult error;
86 mParent->InsertBefore(*mNode, mRefNode, error);
87 return error.ErrorCode();
88 }
89
90 NS_IMETHODIMP
91 DeleteNodeTxn::RedoTransaction()
92 {
93 if (!mParent) {
94 // this is a legal state, the txn is a no-op
95 return NS_OK;
96 }
97 if (!mNode) {
98 return NS_ERROR_NULL_POINTER;
99 }
100
101 if (mRangeUpdater) {
102 mRangeUpdater->SelAdjDeleteNode(mNode->AsDOMNode());
103 }
104
105 ErrorResult error;
106 mParent->RemoveChild(*mNode, error);
107 return error.ErrorCode();
108 }
109
110 NS_IMETHODIMP
111 DeleteNodeTxn::GetTxnDescription(nsAString& aString)
112 {
113 aString.AssignLiteral("DeleteNodeTxn");
114 return NS_OK;
115 }

mercurial