author | Masayuki Nakano <masayuki@d-toybox.com> |
Wed, 05 Aug 2020 05:08:21 +0000 | |
changeset 543352 | de60b2f1987f7a02c012a90d653143fbff26800e |
parent 543351 | 1e439a68f0e49fb2c1bec0169564a5d69222790d |
child 543353 | f212f223bee382b61b577eda2a9e952cd8e1623b |
push id | 123402 |
push user | masayuki@d-toybox.com |
push date | Wed, 05 Aug 2020 06:52:10 +0000 |
treeherder | autoland@de60b2f1987f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | m_kato |
bugs | 1655389 |
milestone | 81.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
editor/libeditor/HTMLEditSubActionHandler.cpp | file | annotate | diff | comparison | revisions | |
editor/libeditor/HTMLEditor.h | file | annotate | diff | comparison | revisions |
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp +++ b/editor/libeditor/HTMLEditSubActionHandler.cpp @@ -3073,96 +3073,99 @@ bool HTMLEditor::AutoBlockElementsJoiner mMode = Mode::JoinOtherBlock; // Make sure it's not a table element. If so, cancel the operation // (translation: users cannot backspace or delete across table cells) if (HTMLEditUtils::IsAnyTableElement(&aOtherBlockElement)) { return false; } - // Next to a block. See if we are between a block and a br. If so, we - // really want to delete the br. Else join content at selection to the - // block. - WSScanResult scanFromCaretResult = - aDirectionAndAmount == nsIEditor::eNext - ? aWSRunScannerAtCaret.ScanPreviousVisibleNodeOrBlockBoundaryFrom( - aCaretPoint) - : aWSRunScannerAtCaret.ScanNextVisibleNodeOrBlockBoundaryFrom( - aCaretPoint); - // First find the adjacent node in the block if (aDirectionAndAmount == nsIEditor::ePrevious) { mLeafContentInOtherBlock = aHTMLEditor.GetLastEditableLeaf(aOtherBlockElement); mLeftContent = mLeafContentInOtherBlock; mRightContent = aCaretPoint.GetContainerAsContent(); } else { mLeafContentInOtherBlock = aHTMLEditor.GetFirstEditableLeaf(aOtherBlockElement); mLeftContent = aCaretPoint.GetContainerAsContent(); mRightContent = mLeafContentInOtherBlock; } + // Next to a block. See if we are between the block and a `<br>`. + // If so, we really want to delete the `<br>`. Else join content at + // selection to the block. + WSScanResult scanFromCaretResult = + aDirectionAndAmount == nsIEditor::eNext + ? aWSRunScannerAtCaret.ScanPreviousVisibleNodeOrBlockBoundaryFrom( + aCaretPoint) + : aWSRunScannerAtCaret.ScanNextVisibleNodeOrBlockBoundaryFrom( + aCaretPoint); // If we found a `<br>` element, we need to delete it instead of joining the // contents. if (scanFromCaretResult.ReachedBRElement()) { mBRElement = scanFromCaretResult.BRElementPtr(); + mMode = Mode::DeleteBRElement; return true; } return mLeftContent && mRightContent; } +EditActionResult HTMLEditor::AutoBlockElementsJoiner::DeleteBRElement( + HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount, + const EditorDOMPoint& aCaretPoint) { + MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable()); + MOZ_ASSERT(aCaretPoint.IsSetAndValid()); + MOZ_ASSERT(mBRElement); + + // If we found a `<br>` element, we should delete it instead of joining the + // contents. + nsresult rv = + aHTMLEditor.DeleteNodeWithTransaction(MOZ_KnownLive(*mBRElement)); + if (NS_WARN_IF(aHTMLEditor.Destroyed())) { + return EditActionResult(NS_ERROR_EDITOR_DESTROYED); + } + if (NS_FAILED(rv)) { + NS_WARNING("HTMLEditor::DeleteNodeWithTransaction() failed"); + return EditActionResult(rv); + } + + if (mLeftContent && mRightContent && + HTMLEditor::NodesInDifferentTableElements(*mLeftContent, + *mRightContent)) { + return EditActionHandled(); + } + + // Put selection at edge of block and we are done. + if (NS_WARN_IF(!mLeafContentInOtherBlock)) { + // XXX This must be odd case. The other block can be empty. + return EditActionHandled(NS_ERROR_FAILURE); + } + EditorDOMPoint newCaretPosition = aHTMLEditor.GetGoodCaretPointFor( + *mLeafContentInOtherBlock, aDirectionAndAmount); + if (!newCaretPosition.IsSet()) { + NS_WARNING("HTMLEditor::GetGoodCaretPointFor() failed"); + return EditActionHandled(NS_ERROR_FAILURE); + } + rv = aHTMLEditor.CollapseSelectionTo(newCaretPosition); + if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { + return EditActionHandled(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), + "HTMLEditor::CollapseSelectionTo() failed, but ignored"); + return EditActionHandled(); +} + EditActionResult HTMLEditor::AutoBlockElementsJoiner:: HandleDeleteCollapsedSelectionAtOtherBlockBoundary( - HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount, - const EditorDOMPoint& aCaretPoint) { + HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCaretPoint) { MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable()); MOZ_ASSERT(aCaretPoint.IsSetAndValid()); - - // If we found a `<br>` element, we should delete it instead of joinning the - // contents. - if (mBRElement) { - nsresult rv = - aHTMLEditor.DeleteNodeWithTransaction(MOZ_KnownLive(*mBRElement)); - if (NS_WARN_IF(aHTMLEditor.Destroyed())) { - return EditActionResult(NS_ERROR_EDITOR_DESTROYED); - } - if (NS_FAILED(rv)) { - NS_WARNING("HTMLEditor::DeleteNodeWithTransaction() failed"); - return EditActionResult(rv); - } - - if (mLeftContent && mRightContent && - HTMLEditor::NodesInDifferentTableElements(*mLeftContent, - *mRightContent)) { - return EditActionHandled(); - } - - // Put selection at edge of block and we are done. - if (NS_WARN_IF(!mLeafContentInOtherBlock)) { - // XXX This must be odd case. The other block can be empty. - return EditActionHandled(NS_ERROR_FAILURE); - } - EditorDOMPoint newCaretPosition = aHTMLEditor.GetGoodCaretPointFor( - *mLeafContentInOtherBlock, aDirectionAndAmount); - if (!newCaretPosition.IsSet()) { - NS_WARNING("HTMLEditor::GetGoodCaretPointFor() failed"); - return EditActionHandled(NS_ERROR_FAILURE); - } - rv = aHTMLEditor.CollapseSelectionTo(newCaretPosition); - if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { - return EditActionHandled(NS_ERROR_EDITOR_DESTROYED); - } - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rv), - "HTMLEditor::CollapseSelectionTo() failed, but ignored"); - return EditActionHandled(); - } - MOZ_ASSERT(mLeftContent); MOZ_ASSERT(mRightContent); if (HTMLEditor::NodesInDifferentTableElements(*mLeftContent, *mRightContent)) { // If we have not deleted `<br>` element and are not called recursively, // we should call `DeleteSelectionWithTransaction()` here, but we cannot // detect it for now. Therefore, we should just tell the caller of that
--- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -2742,24 +2742,32 @@ class HTMLEditor final : public TextEdit NS_WARNING_ASSERTION( result.Succeeded(), "AutoBlockElementsJoiner::" "HandleDeleteCollapsedSelectionAtCurrentBlockBoundary() failed"); return result; } case Mode::JoinOtherBlock: { EditActionResult result = - HandleDeleteCollapsedSelectionAtOtherBlockBoundary( - aHTMLEditor, aDirectionAndAmount, aCaretPoint); + HandleDeleteCollapsedSelectionAtOtherBlockBoundary(aHTMLEditor, + aCaretPoint); NS_WARNING_ASSERTION( result.Succeeded(), "AutoBlockElementsJoiner::" "HandleDeleteCollapsedSelectionAtOtherBlockBoundary() failed"); return result; } + case Mode::DeleteBRElement: { + EditActionResult result = + DeleteBRElement(aHTMLEditor, aDirectionAndAmount, aCaretPoint); + NS_WARNING_ASSERTION( + result.Succeeded(), + "AutoBlockElementsJoiner::DeleteBRElement() failed"); + return result; + } case Mode::NotInitialized: return EditActionIgnored(); } return EditActionResult(NS_ERROR_NOT_INITIALIZED); } nsIContent* GetLeafContentInOtherBlockElement() const { MOZ_ASSERT(mMode == Mode::JoinOtherBlock); @@ -2772,23 +2780,26 @@ class HTMLEditor final : public TextEdit } private: [[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult HandleDeleteCollapsedSelectionAtCurrentBlockBoundary( HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCaretPoint); [[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult HandleDeleteCollapsedSelectionAtOtherBlockBoundary( + HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCaretPoint); + [[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult DeleteBRElement( HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount, const EditorDOMPoint& aCaretPoint); enum class Mode { NotInitialized, JoinCurrentBlock, JoinOtherBlock, + DeleteBRElement, }; nsCOMPtr<nsIContent> mLeftContent; nsCOMPtr<nsIContent> mRightContent; nsCOMPtr<nsIContent> mLeafContentInOtherBlock; RefPtr<dom::HTMLBRElement> mBRElement; Mode mMode = Mode::NotInitialized; bool mNeedsToFallbackToDeleteSelectionWithTransaction = false; };