1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/editor/libeditor/base/InsertElementTxn.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,106 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <stdio.h> // for printf 1.10 + 1.11 +#include "InsertElementTxn.h" 1.12 +#include "nsAString.h" 1.13 +#include "nsDebug.h" // for NS_ENSURE_TRUE, etc 1.14 +#include "nsError.h" // for NS_ERROR_NULL_POINTER, etc 1.15 +#include "nsIContent.h" // for nsIContent 1.16 +#include "nsIEditor.h" // for nsIEditor 1.17 +#include "nsINode.h" // for nsINode 1.18 +#include "nsISelection.h" // for nsISelection 1.19 +#include "nsMemory.h" // for nsMemory 1.20 +#include "nsReadableUtils.h" // for ToNewCString 1.21 +#include "nsString.h" // for nsString 1.22 + 1.23 +InsertElementTxn::InsertElementTxn() 1.24 + : EditTxn() 1.25 +{ 1.26 +} 1.27 + 1.28 +NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertElementTxn, EditTxn, 1.29 + mNode, 1.30 + mParent) 1.31 + 1.32 +NS_IMPL_ADDREF_INHERITED(InsertElementTxn, EditTxn) 1.33 +NS_IMPL_RELEASE_INHERITED(InsertElementTxn, EditTxn) 1.34 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertElementTxn) 1.35 +NS_INTERFACE_MAP_END_INHERITING(EditTxn) 1.36 + 1.37 +NS_IMETHODIMP InsertElementTxn::Init(nsIDOMNode *aNode, 1.38 + nsIDOMNode *aParent, 1.39 + int32_t aOffset, 1.40 + nsIEditor *aEditor) 1.41 +{ 1.42 + NS_ASSERTION(aNode && aParent && aEditor, "bad arg"); 1.43 + NS_ENSURE_TRUE(aNode && aParent && aEditor, NS_ERROR_NULL_POINTER); 1.44 + 1.45 + mNode = do_QueryInterface(aNode); 1.46 + mParent = do_QueryInterface(aParent); 1.47 + mOffset = aOffset; 1.48 + mEditor = aEditor; 1.49 + NS_ENSURE_TRUE(mNode && mParent && mEditor, NS_ERROR_INVALID_ARG); 1.50 + return NS_OK; 1.51 +} 1.52 + 1.53 + 1.54 +NS_IMETHODIMP InsertElementTxn::DoTransaction(void) 1.55 +{ 1.56 + NS_ENSURE_TRUE(mNode && mParent, NS_ERROR_NOT_INITIALIZED); 1.57 + 1.58 + nsCOMPtr<nsINode> parent = do_QueryInterface(mParent); 1.59 + NS_ENSURE_STATE(parent); 1.60 + 1.61 + uint32_t count = parent->GetChildCount(); 1.62 + if (mOffset > int32_t(count) || mOffset == -1) { 1.63 + // -1 is sentinel value meaning "append at end" 1.64 + mOffset = count; 1.65 + } 1.66 + 1.67 + nsCOMPtr<nsIContent> refContent = parent->GetChildAt(mOffset); 1.68 + // note, it's ok for refNode to be null. that means append 1.69 + nsCOMPtr<nsIDOMNode> refNode = refContent ? refContent->AsDOMNode() : nullptr; 1.70 + 1.71 + mEditor->MarkNodeDirty(mNode); 1.72 + 1.73 + nsCOMPtr<nsIDOMNode> resultNode; 1.74 + nsresult result = mParent->InsertBefore(mNode, refNode, getter_AddRefs(resultNode)); 1.75 + NS_ENSURE_SUCCESS(result, result); 1.76 + NS_ENSURE_TRUE(resultNode, NS_ERROR_NULL_POINTER); 1.77 + 1.78 + // only set selection to insertion point if editor gives permission 1.79 + bool bAdjustSelection; 1.80 + mEditor->ShouldTxnSetSelection(&bAdjustSelection); 1.81 + if (bAdjustSelection) 1.82 + { 1.83 + nsCOMPtr<nsISelection> selection; 1.84 + result = mEditor->GetSelection(getter_AddRefs(selection)); 1.85 + NS_ENSURE_SUCCESS(result, result); 1.86 + NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); 1.87 + // place the selection just after the inserted element 1.88 + selection->Collapse(mParent, mOffset+1); 1.89 + } 1.90 + else 1.91 + { 1.92 + // do nothing - dom range gravity will adjust selection 1.93 + } 1.94 + return result; 1.95 +} 1.96 + 1.97 +NS_IMETHODIMP InsertElementTxn::UndoTransaction(void) 1.98 +{ 1.99 + NS_ENSURE_TRUE(mNode && mParent, NS_ERROR_NOT_INITIALIZED); 1.100 + 1.101 + nsCOMPtr<nsIDOMNode> resultNode; 1.102 + return mParent->RemoveChild(mNode, getter_AddRefs(resultNode)); 1.103 +} 1.104 + 1.105 +NS_IMETHODIMP InsertElementTxn::GetTxnDescription(nsAString& aString) 1.106 +{ 1.107 + aString.AssignLiteral("InsertElementTxn"); 1.108 + return NS_OK; 1.109 +}