Bug 1574852 - part 101: Move HTMLEditRules::DidDeleteSelection() to HTMLEditor r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D45295

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2019-09-12 07:27:30 +00:00
parent 94e642e603
commit d0e7a72d94
5 changed files with 69 additions and 63 deletions

View File

@ -490,10 +490,13 @@ nsresult HTMLEditor::OnEndHandlingTopLevelEditSubActionInternal() {
// Note we only want to do this if the overall operation was deletion,
// not if deletion was done along the way for
// EditSubAction::eInsertHTMLSource, EditSubAction::eInsertText, etc.
// That's why this is here rather than DidDeleteSelection().
// That's why this is here rather than DeleteSelectionAsSubAction().
// However, we shouldn't insert <br> elements if we've already removed
// empty block parents because users may want to disappear the line by
// the deletion.
// XXX We should make HandleDeleteSelection() store expected container
// for handling this here since we cannot trust current selection is
// collapsed at deleted point.
if (GetTopLevelEditSubAction() == EditSubAction::eDeleteSelectedContent &&
TopLevelEditSubActionDataRef().mDidDeleteNonCollapsedRange &&
!TopLevelEditSubActionDataRef().mDidDeleteEmptyParentBlocks) {
@ -833,8 +836,6 @@ nsresult HTMLEditRules::DidDoAction(EditSubActionInfo& aInfo,
case EditSubAction::eInsertLineBreak:
case EditSubAction::eInsertTextComingFromIME:
return NS_OK;
case EditSubAction::eDeleteSelectedContent:
return DidDeleteSelection();
case EditSubAction::eInsertElement:
case EditSubAction::eInsertQuotedText:
return NS_OK;
@ -842,6 +843,7 @@ nsresult HTMLEditRules::DidDoAction(EditSubActionInfo& aInfo,
case EditSubAction::eCreateOrChangeList:
case EditSubAction::eCreateOrRemoveBlock:
case EditSubAction::eDecreaseZIndex:
case EditSubAction::eDeleteSelectedContent:
case EditSubAction::eIncreaseZIndex:
case EditSubAction::eIndent:
case EditSubAction::eInsertHTMLSource:
@ -4058,57 +4060,48 @@ nsresult HTMLEditor::DeleteElementsExceptTableRelatedElements(nsINode& aNode) {
return NS_OK;
}
nsresult HTMLEditRules::DidDeleteSelection() {
MOZ_ASSERT(IsEditorDataAvailable());
nsresult HTMLEditor::DeleteMostAncestorMailCiteElementIfEmpty(
nsIContent& aContent) {
MOZ_ASSERT(IsEditActionDataAvailable());
// find where we are
EditorDOMPoint atStartOfSelection(
EditorBase::GetStartPoint(*SelectionRefPtr()));
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
return NS_ERROR_FAILURE;
// The element must be `<blockquote type="cite">` or
// `<span _moz_quote="true">`.
RefPtr<Element> mailCiteElement = GetMostAncestorMailCiteElement(aContent);
if (!mailCiteElement) {
return NS_OK;
}
// find any enclosing mailcite
RefPtr<Element> citeNode = HTMLEditorRef().GetMostAncestorMailCiteElement(
*atStartOfSelection.GetContainer());
if (citeNode) {
bool isEmpty = true, seenBR = false;
HTMLEditorRef().IsEmptyNodeImpl(citeNode, &isEmpty, true, true, false,
&seenBR);
if (isEmpty) {
EditorDOMPoint atCiteNode(citeNode);
{
AutoEditorDOMPointChildInvalidator lockOffset(atCiteNode);
nsresult rv =
MOZ_KnownLive(HTMLEditorRef()).DeleteNodeWithTransaction(*citeNode);
if (NS_WARN_IF(!CanHandleEditAction())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (atCiteNode.IsSet() && seenBR) {
RefPtr<Element> brElement =
MOZ_KnownLive(HTMLEditorRef())
.InsertBRElementWithTransaction(atCiteNode);
if (NS_WARN_IF(!CanHandleEditAction())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
IgnoredErrorResult error;
SelectionRefPtr()->Collapse(EditorRawDOMPoint(brElement), error);
if (NS_WARN_IF(!CanHandleEditAction())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
!error.Failed(),
"Failed to collapse selection at the new <br> element");
}
bool isEmpty = true, seenBR = false;
IsEmptyNodeImpl(mailCiteElement, &isEmpty, true, true, false, &seenBR);
EditorDOMPoint atEmptyMailCiteElement(mailCiteElement);
{
AutoEditorDOMPointChildInvalidator lockOffset(atEmptyMailCiteElement);
nsresult rv = DeleteNodeWithTransaction(*mailCiteElement);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (NS_WARN_IF(!atEmptyMailCiteElement.IsSet()) || !seenBR) {
return NS_OK;
}
RefPtr<Element> brElement =
InsertBRElementWithTransaction(atEmptyMailCiteElement);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
IgnoredErrorResult ignoredError;
SelectionRefPtr()->Collapse(EditorRawDOMPoint(brElement), ignoredError);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(!ignoredError.Failed(), "Selection::Collapse() failed");
return NS_OK;
}

View File

@ -106,13 +106,6 @@ class HTMLEditRules : public TextEditRules {
return mData->HTMLEditorRef();
}
/**
* Called after deleting selected content.
* This method removes unnecessary empty nodes and/or inserts <br> if
* necessary.
*/
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult DidDeleteSelection();
nsresult AppendInnerFormatNodes(nsTArray<OwningNonNull<nsINode>>& aArray,
nsINode* aNode);
nsresult GetFormatString(nsINode* aNode, nsAString& outFormat);

View File

@ -2274,6 +2274,16 @@ class HTMLEditor final : public TextEditor,
HandleDeleteSelection(nsIEditor::EDirection aDirectionAndAmount,
nsIEditor::EStripWrappers aStripWrappers);
/**
* DeleteMostAncestorMailCiteElementIfEmpty() deletes most ancestor
* mail cite element (`<blockquote type="cite">` or
* `<span _moz_quote="true">`, the former can be created with middle click
* paste with `Control` or `Command` even in the web) of aContent if it
* becomes empty.
*/
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
DeleteMostAncestorMailCiteElementIfEmpty(nsIContent& aContent);
/**
* LiftUpListItemElement() moves aListItemElement outside its parent.
* If it's in a middle of a list element, the parent list element is split

View File

@ -261,8 +261,6 @@ nsresult TextEditRules::DidDoAction(EditSubActionInfo& aInfo,
switch (aInfo.mEditSubAction) {
case EditSubAction::eDeleteSelectedContent:
MOZ_ASSERT(!mIsHTMLEditRules);
return NS_OK;
case EditSubAction::eInsertElement:
case EditSubAction::eUndo:
case EditSubAction::eRedo:

View File

@ -667,10 +667,22 @@ nsresult TextEditor::DeleteSelectionAsSubAction(EDirection aDirection,
if (!handled) {
rv = DeleteSelectionWithTransaction(aDirection, aStripWrappers);
}
// post-process
rv = rules->DidDoAction(subActionInfo, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
if (AsHTMLEditor()) {
EditorDOMPoint atNewStartOfSelection(
EditorBase::GetStartPoint(*SelectionRefPtr()));
if (NS_WARN_IF(!atNewStartOfSelection.IsSet())) {
return NS_ERROR_FAILURE;
}
if (atNewStartOfSelection.GetContainerAsContent()) {
nsresult rv =
MOZ_KnownLive(AsHTMLEditor())
->DeleteMostAncestorMailCiteElementIfEmpty(MOZ_KnownLive(
*atNewStartOfSelection.GetContainerAsContent()));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
}
// XXX This is odd. We just tries to remove empty text node here but we