зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1657270 - part 1: Move `HTMLEditor::MaybeDeleteTopMostEmptyAncestor()` into new stack only class r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D85995
This commit is contained in:
Родитель
555c643104
Коммит
42c32fd19a
|
@ -2462,13 +2462,13 @@ EditActionResult HTMLEditor::HandleDeleteSelectionInternal(
|
|||
if (startPoint.GetContainerAsContent()) {
|
||||
AutoEditorDOMPointChildInvalidator lockOffset(startPoint);
|
||||
|
||||
EditActionResult result = MaybeDeleteTopMostEmptyAncestor(
|
||||
MOZ_KnownLive(*startPoint.GetContainerAsContent()), *editingHost,
|
||||
aDirectionAndAmount);
|
||||
AutoEmptyBlockAncestorDeleter deleter;
|
||||
EditActionResult result =
|
||||
deleter.Run(*this, MOZ_KnownLive(*startPoint.GetContainerAsContent()),
|
||||
*editingHost, aDirectionAndAmount);
|
||||
if (result.Failed() || result.Handled()) {
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"HTMLEditor::MaybeDeleteTopMostEmptyAncestor() failed");
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"AutoEmptyBlockAncestorDeleter::Run() failed");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -7859,10 +7859,10 @@ nsresult HTMLEditor::AlignBlockContentsWithDivElement(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
||||
nsIContent& aStartContent, Element& aEditingHostElement,
|
||||
nsIEditor::EDirection aDirectionAndAmount) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
EditActionResult HTMLEditor::AutoEmptyBlockAncestorDeleter::Run(
|
||||
HTMLEditor& aHTMLEditor, nsIContent& aStartContent,
|
||||
Element& aEditingHostElement, nsIEditor::EDirection aDirectionAndAmount) {
|
||||
MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable());
|
||||
|
||||
// If the editing host is an inline element, bail out early.
|
||||
if (HTMLEditUtils::IsInlineElement(aEditingHostElement)) {
|
||||
|
@ -7876,7 +7876,7 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
RefPtr<Element> topMostEmptyBlockElement;
|
||||
while (blockElement && blockElement != &aEditingHostElement &&
|
||||
!HTMLEditUtils::IsAnyTableElement(blockElement) &&
|
||||
IsEmptyNode(*blockElement, true, false)) {
|
||||
aHTMLEditor.IsEmptyNode(*blockElement, true, false)) {
|
||||
topMostEmptyBlockElement = blockElement;
|
||||
blockElement =
|
||||
HTMLEditUtils::GetAncestorBlockElement(*topMostEmptyBlockElement);
|
||||
|
@ -7906,7 +7906,7 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
// last list item is deleted. We should follow it since current
|
||||
// behavior is annoying when you type new list item with selecting
|
||||
// all list items.
|
||||
if (IsFirstEditableChild(topMostEmptyBlockElement)) {
|
||||
if (aHTMLEditor.IsFirstEditableChild(topMostEmptyBlockElement)) {
|
||||
EditorDOMPoint atParentOfEmptyBlock(parentOfEmptyBlockElement);
|
||||
if (NS_WARN_IF(!atParentOfEmptyBlock.IsSet())) {
|
||||
return EditActionResult(NS_ERROR_FAILURE);
|
||||
|
@ -7916,15 +7916,16 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
if (!HTMLEditUtils::IsAnyListElement(
|
||||
atParentOfEmptyBlock.GetContainer())) {
|
||||
RefPtr<Element> brElement =
|
||||
InsertBRElementWithTransaction(atParentOfEmptyBlock);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
aHTMLEditor.InsertBRElementWithTransaction(atParentOfEmptyBlock);
|
||||
if (NS_WARN_IF(aHTMLEditor.Destroyed())) {
|
||||
return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (!brElement) {
|
||||
NS_WARNING("HTMLEditor::InsertBRElementWithTransaction() failed");
|
||||
return EditActionResult(NS_ERROR_FAILURE);
|
||||
}
|
||||
nsresult rv = CollapseSelectionTo(EditorRawDOMPoint(brElement));
|
||||
nsresult rv =
|
||||
aHTMLEditor.CollapseSelectionTo(EditorRawDOMPoint(brElement));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::CollapseSelectionTo() failed");
|
||||
|
@ -7945,14 +7946,14 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
advancedFromEmptyBlock,
|
||||
"Failed to set selection to the after the empty block");
|
||||
nsCOMPtr<nsIContent> nextContentOfEmptyBlock =
|
||||
GetNextNode(afterEmptyBlock);
|
||||
aHTMLEditor.GetNextNode(afterEmptyBlock);
|
||||
if (nextContentOfEmptyBlock) {
|
||||
EditorDOMPoint pt = GetGoodCaretPointFor(*nextContentOfEmptyBlock,
|
||||
aDirectionAndAmount);
|
||||
EditorDOMPoint pt = aHTMLEditor.GetGoodCaretPointFor(
|
||||
*nextContentOfEmptyBlock, aDirectionAndAmount);
|
||||
NS_WARNING_ASSERTION(
|
||||
pt.IsSet(),
|
||||
"HTMLEditor::GetGoodCaretPointFor() failed, but ignored");
|
||||
nsresult rv = CollapseSelectionTo(pt);
|
||||
nsresult rv = aHTMLEditor.CollapseSelectionTo(pt);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::CollapseSelectionTo() failed");
|
||||
return EditActionResult(rv);
|
||||
|
@ -7962,7 +7963,7 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
if (NS_WARN_IF(!advancedFromEmptyBlock)) {
|
||||
return EditActionResult(NS_ERROR_FAILURE);
|
||||
}
|
||||
nsresult rv = CollapseSelectionTo(afterEmptyBlock);
|
||||
nsresult rv = aHTMLEditor.CollapseSelectionTo(afterEmptyBlock);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::CollapseSelectionTo() failed");
|
||||
return EditActionResult(rv);
|
||||
|
@ -7976,14 +7977,14 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
// if there is. Otherwise, to after the empty block.
|
||||
EditorRawDOMPoint atEmptyBlock(topMostEmptyBlockElement);
|
||||
nsCOMPtr<nsIContent> previousContentOfEmptyBlock =
|
||||
GetPreviousEditableNode(atEmptyBlock);
|
||||
aHTMLEditor.GetPreviousEditableNode(atEmptyBlock);
|
||||
if (previousContentOfEmptyBlock) {
|
||||
EditorDOMPoint pt = GetGoodCaretPointFor(*previousContentOfEmptyBlock,
|
||||
aDirectionAndAmount);
|
||||
EditorDOMPoint pt = aHTMLEditor.GetGoodCaretPointFor(
|
||||
*previousContentOfEmptyBlock, aDirectionAndAmount);
|
||||
NS_WARNING_ASSERTION(
|
||||
pt.IsSet(),
|
||||
"HTMLEditor::GetGoodCaretPointFor() failed, but ignored");
|
||||
nsresult rv = CollapseSelectionTo(pt);
|
||||
nsresult rv = aHTMLEditor.CollapseSelectionTo(pt);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::CollapseSelectionTo() failed");
|
||||
|
@ -7996,7 +7997,7 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
if (NS_WARN_IF(!afterEmptyBlock.IsSet())) {
|
||||
return EditActionResult(NS_ERROR_FAILURE);
|
||||
}
|
||||
nsresult rv = CollapseSelectionTo(afterEmptyBlock);
|
||||
nsresult rv = aHTMLEditor.CollapseSelectionTo(afterEmptyBlock);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::CollapseSelectionTo() failed");
|
||||
|
@ -8010,8 +8011,9 @@ EditActionResult HTMLEditor::MaybeDeleteTopMostEmptyAncestor(
|
|||
MOZ_CRASH("CheckForEmptyBlock doesn't support this action yet");
|
||||
}
|
||||
}
|
||||
nsresult rv = DeleteNodeWithTransaction(*topMostEmptyBlockElement);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
nsresult rv =
|
||||
aHTMLEditor.DeleteNodeWithTransaction(*topMostEmptyBlockElement);
|
||||
if (NS_WARN_IF(aHTMLEditor.Destroyed())) {
|
||||
return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -2423,32 +2423,6 @@ class HTMLEditor final : public TextEditor,
|
|||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
RemoveEmptyInclusiveAncestorInlineElements(nsIContent& aContent);
|
||||
|
||||
/**
|
||||
* MaybeDeleteTopMostEmptyAncestor() looks for top most empty block ancestor
|
||||
* of aStartContent in aEditingHostElement.
|
||||
* If found empty ancestor is a list item element, inserts a <br> element
|
||||
* before its parent element if grand parent is a list element. Then,
|
||||
* collapse Selection to after the empty block.
|
||||
* If found empty ancestor is not a list item element, collapse Selection to
|
||||
* somewhere depending on aAction.
|
||||
* Finally, removes the empty block ancestor.
|
||||
*
|
||||
* @param aStartContent Start content to look for empty ancestors.
|
||||
* @param aEditingHostElement Current editing host.
|
||||
* @param aDirectionAndAmount If found empty ancestor block is a list item
|
||||
* element, this is ignored. Otherwise:
|
||||
* - If eNext, eNextWord or eToEndOfLine, collapse
|
||||
* Selection to after found empty ancestor.
|
||||
* - If ePrevious, ePreviousWord or
|
||||
* eToBeginningOfLine, collapse Selection to
|
||||
* end of previous editable node.
|
||||
* Otherwise, eNone is allowed but does nothing.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
MaybeDeleteTopMostEmptyAncestor(nsIContent& aStartContent,
|
||||
Element& aEditingHostElement,
|
||||
nsIEditor::EDirection aDirectionAndAmount);
|
||||
|
||||
/**
|
||||
* ExtendRangeToIncludeInvisibleNodes() extends aRange if there are some
|
||||
* invisible nodes around it.
|
||||
|
@ -2684,6 +2658,37 @@ class HTMLEditor final : public TextEditor,
|
|||
nsIEditor::EStripWrappers aStripWrappers, nsIContent& aAtomicContent,
|
||||
const EditorDOMPoint& aCaretPoint, WSRunScanner& aWSRunScannerAtCaret);
|
||||
|
||||
class MOZ_STACK_CLASS AutoEmptyBlockAncestorDeleter final {
|
||||
public:
|
||||
/**
|
||||
* Look for topmost empty block ancestor of aStartContent in
|
||||
* aEditingHostElement. If found empty ancestor is a list item element,
|
||||
* inserts a <br> element before its parent element if grand parent is a
|
||||
* list element. Then, collapse Selection to after the empty block. If
|
||||
* found empty ancestor is not a list item element, collapse Selection to
|
||||
* somewhere depending on aAction.
|
||||
* Finally, removes the empty block ancestor.
|
||||
*
|
||||
* @param aHTMLEditor The HTMLEditor.
|
||||
* @param aStartContent Start content to look for empty ancestors.
|
||||
* @param aEditingHostElement Current editing host.
|
||||
* @param aDirectionAndAmount If found empty ancestor block is a list item
|
||||
* element, this is ignored. Otherwise:
|
||||
* - If eNext, eNextWord or eToEndOfLine,
|
||||
* collapse Selection to after found empty
|
||||
* ancestor.
|
||||
* - If ePrevious, ePreviousWord or
|
||||
* eToBeginningOfLine, collapse Selection to
|
||||
* end of previous editable node.
|
||||
* - Otherwise, eNone is allowed but does
|
||||
* nothing.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
Run(HTMLEditor& aHTMLEditor, nsIContent& aStartContent,
|
||||
Element& aEditingHostElement,
|
||||
nsIEditor::EDirection aDirectionAndAmount);
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoBlockElementsJoiner final {
|
||||
public:
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче