Bug 1657270 - part 4: Split caret computation part off from AutoEmptyBlockAncestorDeleter::Run() r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D85998
This commit is contained in:
Masayuki Nakano 2020-08-11 05:04:08 +00:00
parent 087c7979ab
commit 76b257fb0f
2 changed files with 89 additions and 79 deletions

View File

@ -4337,7 +4337,7 @@ nsresult HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
} }
EditorDOMPoint HTMLEditor::GetGoodCaretPointFor( EditorDOMPoint HTMLEditor::GetGoodCaretPointFor(
nsIContent& aContent, nsIEditor::EDirection aDirectionAndAmount) { nsIContent& aContent, nsIEditor::EDirection aDirectionAndAmount) const {
MOZ_ASSERT(IsEditActionDataAvailable()); MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(aDirectionAndAmount == nsIEditor::eNext || MOZ_ASSERT(aDirectionAndAmount == nsIEditor::eNext ||
aDirectionAndAmount == nsIEditor::eNextWord || aDirectionAndAmount == nsIEditor::eNextWord ||
@ -7940,6 +7940,70 @@ Result<RefPtr<Element>, nsresult> HTMLEditor::AutoEmptyBlockAncestorDeleter::
return brElement; return brElement;
} }
Result<EditorDOMPoint, nsresult>
HTMLEditor::AutoEmptyBlockAncestorDeleter::GetNewCaretPoisition(
const HTMLEditor& aHTMLEditor,
nsIEditor::EDirection aDirectionAndAmount) const {
MOZ_ASSERT(mEmptyInclusiveAncestorBlockElement);
MOZ_ASSERT(mEmptyInclusiveAncestorBlockElement->GetParentElement());
MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable());
switch (aDirectionAndAmount) {
case nsIEditor::eNext:
case nsIEditor::eNextWord:
case nsIEditor::eToEndOfLine: {
// Collapse Selection to next node of after empty block element
// if there is. Otherwise, to just after the empty block.
EditorDOMPoint afterEmptyBlock(
EditorRawDOMPoint::After(mEmptyInclusiveAncestorBlockElement));
MOZ_ASSERT(afterEmptyBlock.IsSet());
if (nsIContent* nextContentOfEmptyBlock =
aHTMLEditor.GetNextNode(afterEmptyBlock)) {
EditorDOMPoint pt = aHTMLEditor.GetGoodCaretPointFor(
*nextContentOfEmptyBlock, aDirectionAndAmount);
if (!pt.IsSet()) {
NS_WARNING("HTMLEditor::GetGoodCaretPointFor() failed");
return Err(NS_ERROR_FAILURE);
}
return pt;
}
if (NS_WARN_IF(!afterEmptyBlock.IsSet())) {
return Err(NS_ERROR_FAILURE);
}
return afterEmptyBlock;
}
case nsIEditor::ePrevious:
case nsIEditor::ePreviousWord:
case nsIEditor::eToBeginningOfLine: {
// Collapse Selection to previous editable node of the empty block
// if there is. Otherwise, to after the empty block.
EditorRawDOMPoint atEmptyBlock(mEmptyInclusiveAncestorBlockElement);
if (nsIContent* previousContentOfEmptyBlock =
aHTMLEditor.GetPreviousEditableNode(atEmptyBlock)) {
EditorDOMPoint pt = aHTMLEditor.GetGoodCaretPointFor(
*previousContentOfEmptyBlock, aDirectionAndAmount);
if (!pt.IsSet()) {
NS_WARNING("HTMLEditor::GetGoodCaretPointFor() failed");
return Err(NS_ERROR_FAILURE);
}
return pt;
}
EditorDOMPoint afterEmptyBlock(
EditorRawDOMPoint::After(*mEmptyInclusiveAncestorBlockElement));
if (NS_WARN_IF(!afterEmptyBlock.IsSet())) {
return Err(NS_ERROR_FAILURE);
}
return afterEmptyBlock;
}
case nsIEditor::eNone:
return EditorDOMPoint();
default:
MOZ_CRASH(
"AutoEmptyBlockAncestorDeleter doesn't support this action yet");
return EditorDOMPoint();
}
}
EditActionResult HTMLEditor::AutoEmptyBlockAncestorDeleter::Run( EditActionResult HTMLEditor::AutoEmptyBlockAncestorDeleter::Run(
HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount) { HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount) {
MOZ_ASSERT(mEmptyInclusiveAncestorBlockElement); MOZ_ASSERT(mEmptyInclusiveAncestorBlockElement);
@ -7966,81 +8030,19 @@ EditActionResult HTMLEditor::AutoEmptyBlockAncestorDeleter::Run(
} }
} }
} else { } else {
switch (aDirectionAndAmount) { Result<EditorDOMPoint, nsresult> result =
case nsIEditor::eNext: GetNewCaretPoisition(aHTMLEditor, aDirectionAndAmount);
case nsIEditor::eNextWord: if (result.isErr()) {
case nsIEditor::eToEndOfLine: { NS_WARNING(
// Collapse Selection to next node of after empty block element "AutoEmptyBlockAncestorDeleter::GetNewCaretPoisition() failed");
// if there is. Otherwise, to just after the empty block. return EditActionResult(result.inspectErr());
EditorRawDOMPoint afterEmptyBlock(mEmptyInclusiveAncestorBlockElement); }
bool advancedFromEmptyBlock = afterEmptyBlock.AdvanceOffset(); if (result.inspect().IsSet()) {
NS_WARNING_ASSERTION( nsresult rv = aHTMLEditor.CollapseSelectionTo(result.inspect());
advancedFromEmptyBlock, if (NS_FAILED(rv)) {
"Failed to set selection to the after the empty block"); NS_WARNING("HTMLEditor::CollapseSelectionTo() failed");
nsCOMPtr<nsIContent> nextContentOfEmptyBlock = return EditActionResult(rv);
aHTMLEditor.GetNextNode(afterEmptyBlock);
if (nextContentOfEmptyBlock) {
EditorDOMPoint pt = aHTMLEditor.GetGoodCaretPointFor(
*nextContentOfEmptyBlock, aDirectionAndAmount);
NS_WARNING_ASSERTION(
pt.IsSet(),
"HTMLEditor::GetGoodCaretPointFor() failed, but ignored");
nsresult rv = aHTMLEditor.CollapseSelectionTo(pt);
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::CollapseSelectionTo() failed");
return EditActionResult(rv);
}
break;
}
if (NS_WARN_IF(!advancedFromEmptyBlock)) {
return EditActionResult(NS_ERROR_FAILURE);
}
nsresult rv = aHTMLEditor.CollapseSelectionTo(afterEmptyBlock);
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::CollapseSelectionTo() failed");
return EditActionResult(rv);
}
break;
} }
case nsIEditor::ePrevious:
case nsIEditor::ePreviousWord:
case nsIEditor::eToBeginningOfLine: {
// Collapse Selection to previous editable node of the empty block
// if there is. Otherwise, to after the empty block.
EditorRawDOMPoint atEmptyBlock(mEmptyInclusiveAncestorBlockElement);
nsCOMPtr<nsIContent> previousContentOfEmptyBlock =
aHTMLEditor.GetPreviousEditableNode(atEmptyBlock);
if (previousContentOfEmptyBlock) {
EditorDOMPoint pt = aHTMLEditor.GetGoodCaretPointFor(
*previousContentOfEmptyBlock, aDirectionAndAmount);
NS_WARNING_ASSERTION(
pt.IsSet(),
"HTMLEditor::GetGoodCaretPointFor() failed, but ignored");
nsresult rv = aHTMLEditor.CollapseSelectionTo(pt);
if (NS_FAILED(rv)) {
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::CollapseSelectionTo() failed");
return EditActionResult(rv);
}
break;
}
EditorRawDOMPoint afterEmptyBlock(
EditorRawDOMPoint::After(*mEmptyInclusiveAncestorBlockElement));
if (NS_WARN_IF(!afterEmptyBlock.IsSet())) {
return EditActionResult(NS_ERROR_FAILURE);
}
nsresult rv = aHTMLEditor.CollapseSelectionTo(afterEmptyBlock);
if (NS_FAILED(rv)) {
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::CollapseSelectionTo() failed");
return EditActionResult(rv);
}
break;
}
case nsIEditor::eNone:
break;
default:
MOZ_CRASH("CheckForEmptyBlock doesn't support this action yet");
} }
} }
nsresult rv = aHTMLEditor.DeleteNodeWithTransaction( nsresult rv = aHTMLEditor.DeleteNodeWithTransaction(

View File

@ -2412,7 +2412,7 @@ class HTMLEditor final : public TextEditor,
* Set the direction of handled edit action. * Set the direction of handled edit action.
*/ */
EditorDOMPoint GetGoodCaretPointFor( EditorDOMPoint GetGoodCaretPointFor(
nsIContent& aContent, nsIEditor::EDirection aDirectionAndAmount); nsIContent& aContent, nsIEditor::EDirection aDirectionAndAmount) const;
/** /**
* RemoveEmptyInclusiveAncestorInlineElements() removes empty inclusive * RemoveEmptyInclusiveAncestorInlineElements() removes empty inclusive
@ -2678,9 +2678,9 @@ class HTMLEditor final : public TextEditor,
* If found one is a list item element, calls * If found one is a list item element, calls
* `MaybeInsertBRElementBeforeEmptyListItemElement()` before deleting * `MaybeInsertBRElementBeforeEmptyListItemElement()` before deleting
* the list item element. * the list item element.
* If found empty ancestor is not a list item element, collapse Selection * If found empty ancestor is not a list item element,
* to somewhere depending on aDirectionAndAmount. Finally, removes the * `GetNewCaretPoisition()` will be called to determine new caret position.
* empty block ancestor. * Finally, removes the empty block ancestor.
* *
* @param aHTMLEditor The HTMLEditor. * @param aHTMLEditor The HTMLEditor.
* @param aDirectionAndAmount If found empty ancestor block is a list item * @param aDirectionAndAmount If found empty ancestor block is a list item
@ -2707,6 +2707,14 @@ class HTMLEditor final : public TextEditor,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult> [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult>
MaybeInsertBRElementBeforeEmptyListItemElement(HTMLEditor& aHTMLEditor); MaybeInsertBRElementBeforeEmptyListItemElement(HTMLEditor& aHTMLEditor);
/**
* GetNewCaretPoisition() returns new caret position after deleting
* `mEmptyInclusiveAncestorBlockElement`.
*/
[[nodiscard]] Result<EditorDOMPoint, nsresult> GetNewCaretPoisition(
const HTMLEditor& aHTMLEditor,
nsIEditor::EDirection aDirectionAndAmount) const;
RefPtr<Element> mEmptyInclusiveAncestorBlockElement; RefPtr<Element> mEmptyInclusiveAncestorBlockElement;
}; };