michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "DeleteTextTxn.h" michael@0: #include "mozilla/Assertions.h" michael@0: #include "mozilla/dom/Selection.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsDebug.h" michael@0: #include "nsEditor.h" michael@0: #include "nsError.h" michael@0: #include "nsIEditor.h" michael@0: #include "nsISelection.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsSelectionState.h" michael@0: #include "nsAString.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: DeleteTextTxn::DeleteTextTxn() : michael@0: EditTxn(), michael@0: mEditor(nullptr), michael@0: mCharData(), michael@0: mOffset(0), michael@0: mNumCharsToDelete(0), michael@0: mRangeUpdater(nullptr) michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_INHERITED(DeleteTextTxn, EditTxn, michael@0: mCharData) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteTextTxn) michael@0: NS_INTERFACE_MAP_END_INHERITING(EditTxn) michael@0: michael@0: NS_IMETHODIMP michael@0: DeleteTextTxn::Init(nsEditor* aEditor, michael@0: nsIDOMCharacterData* aCharData, michael@0: uint32_t aOffset, michael@0: uint32_t aNumCharsToDelete, michael@0: nsRangeUpdater* aRangeUpdater) michael@0: { michael@0: MOZ_ASSERT(aEditor && aCharData); michael@0: michael@0: mEditor = aEditor; michael@0: mCharData = aCharData; michael@0: michael@0: // do nothing if the node is read-only michael@0: if (!mEditor->IsModifiableNode(mCharData)) { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: mOffset = aOffset; michael@0: mNumCharsToDelete = aNumCharsToDelete; michael@0: #ifdef DEBUG michael@0: uint32_t length; michael@0: mCharData->GetLength(&length); michael@0: NS_ASSERTION(length >= aOffset + aNumCharsToDelete, michael@0: "Trying to delete more characters than in node"); michael@0: #endif michael@0: mDeletedText.Truncate(); michael@0: mRangeUpdater = aRangeUpdater; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: DeleteTextTxn::DoTransaction() michael@0: { michael@0: MOZ_ASSERT(mEditor && mCharData); michael@0: michael@0: // get the text that we're about to delete michael@0: nsresult res = mCharData->SubstringData(mOffset, mNumCharsToDelete, michael@0: mDeletedText); michael@0: MOZ_ASSERT(NS_SUCCEEDED(res)); michael@0: res = mCharData->DeleteData(mOffset, mNumCharsToDelete); michael@0: NS_ENSURE_SUCCESS(res, res); michael@0: michael@0: if (mRangeUpdater) { michael@0: mRangeUpdater->SelAdjDeleteText(mCharData, mOffset, mNumCharsToDelete); michael@0: } michael@0: michael@0: // only set selection to deletion point if editor gives permission michael@0: bool bAdjustSelection; michael@0: mEditor->ShouldTxnSetSelection(&bAdjustSelection); michael@0: if (bAdjustSelection) { michael@0: nsRefPtr selection = mEditor->GetSelection(); michael@0: NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); michael@0: res = selection->Collapse(mCharData, mOffset); michael@0: NS_ASSERTION(NS_SUCCEEDED(res), michael@0: "selection could not be collapsed after undo of deletetext."); michael@0: NS_ENSURE_SUCCESS(res, res); michael@0: } michael@0: // else do nothing - dom range gravity will adjust selection michael@0: return NS_OK; michael@0: } michael@0: michael@0: //XXX: we may want to store the selection state and restore it properly michael@0: // was it an insertion point or an extended selection? michael@0: NS_IMETHODIMP michael@0: DeleteTextTxn::UndoTransaction() michael@0: { michael@0: MOZ_ASSERT(mEditor && mCharData); michael@0: michael@0: return mCharData->InsertData(mOffset, mDeletedText); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: DeleteTextTxn::GetTxnDescription(nsAString& aString) michael@0: { michael@0: aString.AssignLiteral("DeleteTextTxn: "); michael@0: aString += mDeletedText; michael@0: return NS_OK; michael@0: }