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