mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
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:
parent
087c7979ab
commit
76b257fb0f
@ -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(
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user