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 "InsertNodeTransaction.h"
7 :
8 : #include "mozilla/EditorBase.h" // for EditorBase
9 :
10 : #include "mozilla/dom/Selection.h" // for Selection
11 :
12 : #include "nsAString.h"
13 : #include "nsDebug.h" // for NS_ENSURE_TRUE, etc.
14 : #include "nsError.h" // for NS_ERROR_NULL_POINTER, etc.
15 : #include "nsIContent.h" // for nsIContent
16 : #include "nsMemory.h" // for nsMemory
17 : #include "nsReadableUtils.h" // for ToNewCString
18 : #include "nsString.h" // for nsString
19 :
20 : namespace mozilla {
21 :
22 : using namespace dom;
23 :
24 3 : InsertNodeTransaction::InsertNodeTransaction(nsIContent& aNode,
25 : nsINode& aParent,
26 : int32_t aOffset,
27 3 : EditorBase& aEditorBase)
28 : : mNode(&aNode)
29 : , mParent(&aParent)
30 : , mOffset(aOffset)
31 3 : , mEditorBase(&aEditorBase)
32 : {
33 3 : }
34 :
35 6 : InsertNodeTransaction::~InsertNodeTransaction()
36 : {
37 9 : }
38 :
39 0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertNodeTransaction, EditTransactionBase,
40 : mEditorBase,
41 : mNode,
42 : mParent)
43 :
44 7 : NS_IMPL_ADDREF_INHERITED(InsertNodeTransaction, EditTransactionBase)
45 7 : NS_IMPL_RELEASE_INHERITED(InsertNodeTransaction, EditTransactionBase)
46 17 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertNodeTransaction)
47 2 : NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
48 :
49 : NS_IMETHODIMP
50 3 : InsertNodeTransaction::DoTransaction()
51 : {
52 3 : if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mNode) || NS_WARN_IF(!mParent)) {
53 0 : return NS_ERROR_NOT_INITIALIZED;
54 : }
55 :
56 3 : uint32_t count = mParent->GetChildCount();
57 3 : if (mOffset > static_cast<int32_t>(count) || mOffset == -1) {
58 : // -1 is sentinel value meaning "append at end"
59 0 : mOffset = count;
60 : }
61 :
62 : // Note, it's ok for ref to be null. That means append.
63 6 : nsCOMPtr<nsIContent> ref = mParent->GetChildAt(mOffset);
64 :
65 3 : mEditorBase->MarkNodeDirty(GetAsDOMNode(mNode));
66 :
67 6 : ErrorResult rv;
68 3 : mParent->InsertBefore(*mNode, ref, rv);
69 3 : NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult());
70 :
71 : // Only set selection to insertion point if editor gives permission
72 3 : if (mEditorBase->GetShouldTxnSetSelection()) {
73 6 : RefPtr<Selection> selection = mEditorBase->GetSelection();
74 3 : NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
75 : // Place the selection just after the inserted element
76 3 : selection->Collapse(mParent, mOffset + 1);
77 : } else {
78 : // Do nothing - DOM Range gravity will adjust selection
79 : }
80 3 : return NS_OK;
81 : }
82 :
83 : NS_IMETHODIMP
84 0 : InsertNodeTransaction::UndoTransaction()
85 : {
86 0 : if (NS_WARN_IF(!mNode) || NS_WARN_IF(!mParent)) {
87 0 : return NS_ERROR_NOT_INITIALIZED;
88 : }
89 0 : ErrorResult rv;
90 0 : mParent->RemoveChild(*mNode, rv);
91 0 : return rv.StealNSResult();
92 : }
93 :
94 : NS_IMETHODIMP
95 0 : InsertNodeTransaction::GetTxnDescription(nsAString& aString)
96 : {
97 0 : aString.AssignLiteral("InsertNodeTransaction");
98 0 : return NS_OK;
99 : }
100 :
101 : } // namespace mozilla
|