Line data Source code
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 "InsertTextTransaction.h"
7 :
8 : #include "mozilla/EditorBase.h" // mEditorBase
9 : #include "mozilla/SelectionState.h" // RangeUpdater
10 : #include "mozilla/dom/Selection.h" // Selection local var
11 : #include "mozilla/dom/Text.h" // mTextNode
12 : #include "nsAString.h" // nsAString parameter
13 : #include "nsDebug.h" // for NS_ASSERTION, etc.
14 : #include "nsError.h" // for NS_OK, etc.
15 : #include "nsQueryObject.h" // for do_QueryObject
16 :
17 : namespace mozilla {
18 :
19 : using namespace dom;
20 :
21 0 : InsertTextTransaction::InsertTextTransaction(Text& aTextNode,
22 : uint32_t aOffset,
23 : const nsAString& aStringToInsert,
24 : EditorBase& aEditorBase,
25 0 : RangeUpdater* aRangeUpdater)
26 : : mTextNode(&aTextNode)
27 : , mOffset(aOffset)
28 : , mStringToInsert(aStringToInsert)
29 : , mEditorBase(&aEditorBase)
30 0 : , mRangeUpdater(aRangeUpdater)
31 : {
32 0 : }
33 :
34 0 : InsertTextTransaction::~InsertTextTransaction()
35 : {
36 0 : }
37 :
38 0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertTextTransaction, EditTransactionBase,
39 : mEditorBase,
40 : mTextNode)
41 :
42 0 : NS_IMPL_ADDREF_INHERITED(InsertTextTransaction, EditTransactionBase)
43 0 : NS_IMPL_RELEASE_INHERITED(InsertTextTransaction, EditTransactionBase)
44 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertTextTransaction)
45 0 : if (aIID.Equals(NS_GET_IID(InsertTextTransaction))) {
46 0 : foundInterface = static_cast<nsITransaction*>(this);
47 : } else
48 0 : NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
49 :
50 :
51 : NS_IMETHODIMP
52 0 : InsertTextTransaction::DoTransaction()
53 : {
54 0 : if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
55 0 : return NS_ERROR_NOT_AVAILABLE;
56 : }
57 :
58 0 : nsresult rv = mTextNode->InsertData(mOffset, mStringToInsert);
59 0 : NS_ENSURE_SUCCESS(rv, rv);
60 :
61 : // Only set selection to insertion point if editor gives permission
62 0 : if (mEditorBase->GetShouldTxnSetSelection()) {
63 0 : RefPtr<Selection> selection = mEditorBase->GetSelection();
64 0 : NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
65 : DebugOnly<nsresult> rv =
66 0 : selection->Collapse(mTextNode, mOffset + mStringToInsert.Length());
67 0 : NS_ASSERTION(NS_SUCCEEDED(rv),
68 : "Selection could not be collapsed after insert");
69 : } else {
70 : // Do nothing - DOM Range gravity will adjust selection
71 : }
72 0 : mRangeUpdater->SelAdjInsertText(*mTextNode, mOffset, mStringToInsert);
73 :
74 0 : return NS_OK;
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : InsertTextTransaction::UndoTransaction()
79 : {
80 0 : return mTextNode->DeleteData(mOffset, mStringToInsert.Length());
81 : }
82 :
83 : NS_IMETHODIMP
84 0 : InsertTextTransaction::Merge(nsITransaction* aTransaction,
85 : bool* aDidMerge)
86 : {
87 0 : if (!aTransaction || !aDidMerge) {
88 0 : return NS_OK;
89 : }
90 : // Set out param default value
91 0 : *aDidMerge = false;
92 :
93 : // If aTransaction is a InsertTextTransaction, and if the selection hasn't
94 : // changed, then absorb it.
95 0 : RefPtr<InsertTextTransaction> otherTransaction = do_QueryObject(aTransaction);
96 0 : if (otherTransaction && IsSequentialInsert(*otherTransaction)) {
97 0 : nsAutoString otherData;
98 0 : otherTransaction->GetData(otherData);
99 0 : mStringToInsert += otherData;
100 0 : *aDidMerge = true;
101 : }
102 :
103 0 : return NS_OK;
104 : }
105 :
106 : NS_IMETHODIMP
107 0 : InsertTextTransaction::GetTxnDescription(nsAString& aString)
108 : {
109 0 : aString.AssignLiteral("InsertTextTransaction: ");
110 0 : aString += mStringToInsert;
111 0 : return NS_OK;
112 : }
113 :
114 : /* ============ private methods ================== */
115 :
116 : void
117 0 : InsertTextTransaction::GetData(nsString& aResult)
118 : {
119 0 : aResult = mStringToInsert;
120 0 : }
121 :
122 : bool
123 0 : InsertTextTransaction::IsSequentialInsert(
124 : InsertTextTransaction& aOtherTransaction)
125 : {
126 0 : return aOtherTransaction.mTextNode == mTextNode &&
127 0 : aOtherTransaction.mOffset == mOffset + mStringToInsert.Length();
128 : }
129 :
130 : } // namespace mozilla
|