From 74e4b434087b4225ffa84af341a88087fd3bf6ec Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 24 Apr 2020 15:22:42 +0000 Subject: [PATCH] Bug 1632724 - part 2: Move `DeleteSelectionWithTransaction()` from `TextEditor` to `EditorBase` since it's used by `HTMLEditor` too r=m_kato Depends on D72290 Differential Revision: https://phabricator.services.mozilla.com/D72291 --- editor/libeditor/EditorBase.cpp | 118 ++++++++++++++++++ editor/libeditor/EditorBase.h | 12 ++ editor/libeditor/HTMLEditor.cpp | 4 +- editor/libeditor/TextEditSubActionHandler.cpp | 4 +- editor/libeditor/TextEditor.cpp | 116 ----------------- editor/libeditor/TextEditor.h | 11 -- 6 files changed, 134 insertions(+), 131 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 022f192b0da4e..bf7c9d983ab2d 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -5068,6 +5068,124 @@ nsresult EditorBase::ExtendSelectionForDelete( } } +nsresult EditorBase::DeleteSelectionWithTransaction( + nsIEditor::EDirection aDirectionAndAmount, + nsIEditor::EStripWrappers aStripWrappers) { + MOZ_ASSERT(IsEditActionDataAvailable()); + MOZ_ASSERT(aStripWrappers == eStrip || aStripWrappers == eNoStrip); + + RefPtr deleteSelectionTransaction; + nsCOMPtr deleteNode; + int32_t deleteCharOffset = 0, deleteCharLength = 0; + if (!SelectionRefPtr()->IsCollapsed() || + aDirectionAndAmount != nsIEditor::eNone) { + deleteSelectionTransaction = CreateTxnForDeleteSelection( + aDirectionAndAmount, getter_AddRefs(deleteNode), &deleteCharOffset, + &deleteCharLength); + if (!deleteSelectionTransaction) { + NS_WARNING("EditorBase::CreateTxnForDeleteSelection() failed"); + return NS_ERROR_FAILURE; + } + } + + RefPtr deleteCharData = + CharacterData::FromNodeOrNull(deleteNode); + IgnoredErrorResult ignoredError; + AutoEditSubActionNotifier startToHandleEditSubAction( + *this, EditSubAction::eDeleteSelectedContent, aDirectionAndAmount, + ignoredError); + if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) { + return ignoredError.StealNSResult(); + } + NS_WARNING_ASSERTION( + !ignoredError.Failed(), + "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"); + + if (IsHTMLEditor()) { + if (!deleteNode) { + // XXX We may remove multiple ranges in the following. Therefore, + // this must have a bug since we only add the first range into + // the changed range. + TopLevelEditSubActionDataRef().WillDeleteRange( + *this, EditorBase::GetStartPoint(*SelectionRefPtr()), + EditorBase::GetEndPoint(*SelectionRefPtr())); + } else if (!deleteCharData) { + MOZ_ASSERT(deleteNode->IsContent()); + TopLevelEditSubActionDataRef().WillDeleteContent( + *this, *deleteNode->AsContent()); + } + } + + // Notify nsIEditActionListener::WillDelete[Selection|Text] + if (!mActionListeners.IsEmpty()) { + if (!deleteNode) { + AutoActionListenerArray listeners(mActionListeners); + for (auto& listener : listeners) { + DebugOnly rvIgnored = + listener->WillDeleteSelection(SelectionRefPtr()); + NS_WARNING_ASSERTION( + NS_SUCCEEDED(rvIgnored), + "nsIEditActionListener::WillDeleteSelection() failed, but ignored"); + } + } else if (deleteCharData) { + AutoActionListenerArray listeners(mActionListeners); + for (auto& listener : listeners) { + DebugOnly rvIgnored = + listener->WillDeleteText(deleteCharData, deleteCharOffset, 1); + NS_WARNING_ASSERTION( + NS_SUCCEEDED(rvIgnored), + "nsIEditActionListener::WillDeleteText() failed, but ignored"); + } + } + } + + // Delete the specified amount + nsresult rv = DoTransactionInternal(deleteSelectionTransaction); + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), + "EditorBase::DoTransactionInternal() failed"); + + if (IsHTMLEditor() && deleteCharData) { + MOZ_ASSERT(deleteNode); + TopLevelEditSubActionDataRef().DidDeleteText(*this, + EditorRawDOMPoint(deleteNode)); + } + + if (mTextServicesDocument && NS_SUCCEEDED(rv) && deleteNode && + !deleteCharData) { + RefPtr textServicesDocument = mTextServicesDocument; + textServicesDocument->DidDeleteNode(deleteNode); + } + + // Notify nsIEditActionListener::DidDelete[Selection|Text|Node] + AutoActionListenerArray listeners(mActionListeners); + if (!deleteNode) { + for (auto& listener : mActionListeners) { + DebugOnly rvIgnored = + listener->DidDeleteSelection(SelectionRefPtr()); + NS_WARNING_ASSERTION( + NS_SUCCEEDED(rvIgnored), + "nsIEditActionListener::DidDeleteSelection() failed, but ignored"); + } + } else if (deleteCharData) { + for (auto& listener : mActionListeners) { + DebugOnly rvIgnored = + listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, rv); + NS_WARNING_ASSERTION( + NS_SUCCEEDED(rvIgnored), + "nsIEditActionListener::DidDeleteText() failed, but ignored"); + } + } else { + for (auto& listener : mActionListeners) { + DebugOnly rvIgnored = listener->DidDeleteNode(deleteNode, rv); + NS_WARNING_ASSERTION( + NS_SUCCEEDED(rvIgnored), + "nsIEditActionListener::DidDeleteNode() failed, but ignored"); + } + } + + return rv; +} + nsresult EditorBase::CreateRange(nsINode* aStartContainer, int32_t aStartOffset, nsINode* aEndContainer, int32_t aEndOffset, nsRange** aRange) { diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 0417810d67d20..26206a14241d7 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -2548,6 +2548,18 @@ class EditorBase : public nsIEditor, [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult ExtendSelectionForDelete(nsIEditor::EDirection* aDirectionAndAmount); + /** + * DeleteSelectionWithTransaction() removes selected content or content + * around caret with transactions. + * + * @param aDirectionAndAmount How much range should be removed. + * @param aStripWrappers Whether the parent blocks should be removed + * when they become empty. + */ + MOZ_CAN_RUN_SCRIPT virtual nsresult DeleteSelectionWithTransaction( + nsIEditor::EDirection aDirectionAndAmount, + nsIEditor::EStripWrappers aStripWrappers); + private: nsCOMPtr mSelectionController; RefPtr mDocument; diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 6b22b5a9394e4..7e0d3e87ce66f 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -3050,9 +3050,9 @@ nsresult HTMLEditor::DeleteSelectionWithTransaction( MOZ_ASSERT(aStripWrappers == eStrip || aStripWrappers == eNoStrip); nsresult rv = - TextEditor::DeleteSelectionWithTransaction(aAction, aStripWrappers); + EditorBase::DeleteSelectionWithTransaction(aAction, aStripWrappers); if (NS_FAILED(rv)) { - NS_WARNING("TextEditor::DeleteSelectionWithTransaction() failed"); + NS_WARNING("EditorBase::DeleteSelectionWithTransaction() failed"); return rv; } diff --git a/editor/libeditor/TextEditSubActionHandler.cpp b/editor/libeditor/TextEditSubActionHandler.cpp index 48570f4861f56..7f5a8d7c86483 100644 --- a/editor/libeditor/TextEditSubActionHandler.cpp +++ b/editor/libeditor/TextEditSubActionHandler.cpp @@ -790,7 +790,7 @@ EditActionResult TextEditor::HandleDeleteSelectionInternal( DeleteSelectionWithTransaction(aDirectionAndAmount, aStripWrappers); NS_WARNING_ASSERTION( NS_SUCCEEDED(rv), - "TextEditor::DeleteSelectionWithTransaction() failed"); + "EditorBase::DeleteSelectionWithTransaction() failed"); return EditActionHandled(rv); } @@ -815,7 +815,7 @@ EditActionResult TextEditor::HandleDeleteSelectionInternal( return EditActionResult(NS_ERROR_EDITOR_DESTROYED); } NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), - "TextEditor::DeleteSelectionWithTransaction() failed"); + "EditorBase::DeleteSelectionWithTransaction() failed"); return EditActionHandled(rv); } diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 2235358ebf66a..db2924d39712a 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -424,122 +424,6 @@ nsresult TextEditor::InsertLineBreakAsAction(nsIPrincipal* aPrincipal) { return EditorBase::ToGenericNSResult(rv); } -nsresult TextEditor::DeleteSelectionWithTransaction( - EDirection aDirection, EStripWrappers aStripWrappers) { - MOZ_ASSERT(IsEditActionDataAvailable()); - - MOZ_ASSERT(aStripWrappers == eStrip || aStripWrappers == eNoStrip); - - RefPtr deleteSelectionTransaction; - nsCOMPtr deleteNode; - int32_t deleteCharOffset = 0, deleteCharLength = 0; - if (!SelectionRefPtr()->IsCollapsed() || aDirection != eNone) { - deleteSelectionTransaction = - CreateTxnForDeleteSelection(aDirection, getter_AddRefs(deleteNode), - &deleteCharOffset, &deleteCharLength); - if (!deleteSelectionTransaction) { - NS_WARNING("EditorBase::CreateTxnForDeleteSelection() failed"); - return NS_ERROR_FAILURE; - } - } - - RefPtr deleteCharData = - CharacterData::FromNodeOrNull(deleteNode); - IgnoredErrorResult ignoredError; - AutoEditSubActionNotifier startToHandleEditSubAction( - *this, EditSubAction::eDeleteSelectedContent, aDirection, ignoredError); - if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) { - return ignoredError.StealNSResult(); - } - NS_WARNING_ASSERTION( - !ignoredError.Failed(), - "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"); - - if (AsHTMLEditor()) { - if (!deleteNode) { - // XXX We may remove multiple ranges in the following. Therefore, - // this must have a bug since we only add the first range into - // the changed range. - TopLevelEditSubActionDataRef().WillDeleteRange( - *this, EditorBase::GetStartPoint(*SelectionRefPtr()), - EditorBase::GetEndPoint(*SelectionRefPtr())); - } else if (!deleteCharData) { - MOZ_ASSERT(deleteNode->IsContent()); - TopLevelEditSubActionDataRef().WillDeleteContent( - *this, *deleteNode->AsContent()); - } - } - - // Notify nsIEditActionListener::WillDelete[Selection|Text] - if (!mActionListeners.IsEmpty()) { - if (!deleteNode) { - AutoActionListenerArray listeners(mActionListeners); - for (auto& listener : listeners) { - DebugOnly rvIgnored = - listener->WillDeleteSelection(SelectionRefPtr()); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rvIgnored), - "nsIEditActionListener::WillDeleteSelection() failed, but ignored"); - } - } else if (deleteCharData) { - AutoActionListenerArray listeners(mActionListeners); - for (auto& listener : listeners) { - DebugOnly rvIgnored = - listener->WillDeleteText(deleteCharData, deleteCharOffset, 1); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rvIgnored), - "nsIEditActionListener::WillDeleteText() failed, but ignored"); - } - } - } - - // Delete the specified amount - nsresult rv = DoTransactionInternal(deleteSelectionTransaction); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), - "EditorBase::DoTransactionInternal() failed"); - - if (AsHTMLEditor() && deleteCharData) { - MOZ_ASSERT(deleteNode); - TopLevelEditSubActionDataRef().DidDeleteText(*this, - EditorRawDOMPoint(deleteNode)); - } - - if (mTextServicesDocument && NS_SUCCEEDED(rv) && deleteNode && - !deleteCharData) { - RefPtr textServicesDocument = mTextServicesDocument; - textServicesDocument->DidDeleteNode(deleteNode); - } - - // Notify nsIEditActionListener::DidDelete[Selection|Text|Node] - AutoActionListenerArray listeners(mActionListeners); - if (!deleteNode) { - for (auto& listener : mActionListeners) { - DebugOnly rvIgnored = - listener->DidDeleteSelection(SelectionRefPtr()); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rvIgnored), - "nsIEditActionListener::DidDeleteSelection() failed, but ignored"); - } - } else if (deleteCharData) { - for (auto& listener : mActionListeners) { - DebugOnly rvIgnored = - listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, rv); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rvIgnored), - "nsIEditActionListener::DidDeleteText() failed, but ignored"); - } - } else { - for (auto& listener : mActionListeners) { - DebugOnly rvIgnored = listener->DidDeleteNode(deleteNode, rv); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rvIgnored), - "nsIEditActionListener::DidDeleteNode() failed, but ignored"); - } - } - - return rv; -} - already_AddRefed TextEditor::DeleteSelectionAndCreateElement( nsAtom& aTag) { MOZ_ASSERT(IsEditActionDataAvailable()); diff --git a/editor/libeditor/TextEditor.h b/editor/libeditor/TextEditor.h index 54815a697959f..d3fe7f41fc919 100644 --- a/editor/libeditor/TextEditor.h +++ b/editor/libeditor/TextEditor.h @@ -363,17 +363,6 @@ class TextEditor : public EditorBase, public nsITimerCallback, public nsINamed { [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult DeleteSelectionByDragAsAction(bool aDispatchInputEvent); - /** - * DeleteSelectionWithTransaction() removes selected content or content - * around caret with transactions. - * - * @param aDirection How much range should be removed. - * @param aStripWrappers Whether the parent blocks should be removed - * when they become empty. - */ - MOZ_CAN_RUN_SCRIPT virtual nsresult DeleteSelectionWithTransaction( - EDirection aAction, EStripWrappers aStripWrappers); - /** * Replace existed string with aString. Caller must guarantee that there * is a placeholder transaction which will have the transaction.