Bug 1627175 - part 59: Move HTMLEditor::GetMostAncestorInlineElement() to HTMLEditUtils r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D115168
This commit is contained in:
Masayuki Nakano 2021-05-17 21:58:10 +00:00
parent e0baad182c
commit 796828cb75
4 changed files with 63 additions and 52 deletions

View File

@ -6225,9 +6225,16 @@ nsresult HTMLEditor::SplitParentInlineElementsAtRangeEdges(
RangeItem& aRangeItem) {
MOZ_ASSERT(IsEditActionDataAvailable());
if (!aRangeItem.IsCollapsed()) {
RefPtr<Element> editingHost = GetActiveEditingHost();
if (NS_WARN_IF(!editingHost)) {
return NS_OK;
}
if (!aRangeItem.IsCollapsed() && aRangeItem.mEndContainer &&
aRangeItem.mEndContainer->IsContent()) {
nsCOMPtr<nsIContent> mostAncestorInlineContentAtEnd =
GetMostAncestorInlineElement(*aRangeItem.mEndContainer);
HTMLEditUtils::GetMostDistantAncestorInlineElement(
*aRangeItem.mEndContainer->AsContent(), editingHost);
if (mostAncestorInlineContentAtEnd) {
SplitNodeResult splitEndInlineResult = SplitNodeDeepWithTransaction(
@ -6242,6 +6249,12 @@ nsresult HTMLEditor::SplitParentInlineElementsAtRangeEdges(
"eDoNotCreateEmptyContainer) failed");
return splitEndInlineResult.Rv();
}
if (editingHost != GetActiveEditingHost()) {
NS_WARNING(
"HTMLEditor::SplitNodeDeepWithTransaction(SplitAtEdges::"
"eDoNotCreateEmptyContainer) caused changing editing host");
return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE;
}
EditorRawDOMPoint splitPointAtEnd(splitEndInlineResult.SplitPoint());
if (!splitPointAtEnd.IsSet()) {
NS_WARNING(
@ -6254,8 +6267,13 @@ nsresult HTMLEditor::SplitParentInlineElementsAtRangeEdges(
}
}
if (!aRangeItem.mStartContainer || !aRangeItem.mStartContainer->IsContent()) {
return NS_OK;
}
nsCOMPtr<nsIContent> mostAncestorInlineContentAtStart =
GetMostAncestorInlineElement(*aRangeItem.mStartContainer);
HTMLEditUtils::GetMostDistantAncestorInlineElement(
*aRangeItem.mStartContainer->AsContent(), editingHost);
if (mostAncestorInlineContentAtStart) {
SplitNodeResult splitStartInlineResult = SplitNodeDeepWithTransaction(
@ -6350,47 +6368,6 @@ nsresult HTMLEditor::SplitElementsAtEveryBRElement(
return NS_OK;
}
nsIContent* HTMLEditor::GetMostAncestorInlineElement(nsINode& aNode) const {
MOZ_ASSERT(IsEditActionDataAvailable());
if (!aNode.IsContent() || HTMLEditUtils::IsBlockElement(*aNode.AsContent())) {
return nullptr;
}
Element* host = GetActiveEditingHost();
if (NS_WARN_IF(!host)) {
return nullptr;
}
// If aNode is the editing host itself, there is no modifiable inline
// parent.
if (&aNode == host) {
return nullptr;
}
// If aNode is outside of the <body> element, we don't support to edit
// such elements for now.
// XXX This should be MOZ_ASSERT after fixing bug 1413131 for avoiding
// calling this expensive method.
if (NS_WARN_IF(!EditorUtils::IsDescendantOf(aNode, *host))) {
return nullptr;
}
if (!aNode.GetParent()) {
return aNode.AsContent();
}
// Looks for the highest inline parent in the editing host.
nsIContent* topMostInlineContent = aNode.AsContent();
for (nsIContent* content : aNode.AncestorsOfType<nsIContent>()) {
if (content == host || !HTMLEditUtils::IsInlineElement(*content)) {
break;
}
topMostInlineContent = content;
}
return topMostInlineContent;
}
// static
void HTMLEditor::MakeTransitionList(
const nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents,

View File

@ -395,7 +395,7 @@ bool HTMLEditUtils::IsVisibleTextNode(
}
WSScanResult nextWSScanResult =
WSRunScanner::ScanNextVisibleNodeOrBlockBoundary(
const_cast<Element*>(aEditingHost), EditorRawDOMPoint(&aText, 0));
aEditingHost, EditorRawDOMPoint(&aText, 0));
return nextWSScanResult.InNormalWhiteSpacesOrText() &&
nextWSScanResult.TextPtr() == &aText;
}

View File

@ -1094,6 +1094,47 @@ class HTMLEditUtils final {
static Element* GetClosestAncestorAnyListElement(const nsIContent& aContent);
/**
* GetMostDistantAncestorInlineElement() returns the most distant ancestor
* inline element between aContent and the aEditingHost. Even if aEditingHost
* is an inline element, this method never returns aEditingHost as the result.
*/
static nsIContent* GetMostDistantAncestorInlineElement(
const nsIContent& aContent, const Element* aEditingHost = nullptr) {
if (HTMLEditUtils::IsBlockElement(aContent)) {
return nullptr;
}
// If aNode is the editing host itself, there is no modifiable inline
// parent.
if (&aContent == aEditingHost) {
return nullptr;
}
// If aNode is outside of the <body> element, we don't support to edit
// such elements for now.
// XXX This should be MOZ_ASSERT after fixing bug 1413131 for avoiding
// calling this expensive method.
if (aEditingHost && !aContent.IsInclusiveDescendantOf(aEditingHost)) {
return nullptr;
}
if (!aContent.GetParent()) {
return const_cast<nsIContent*>(&aContent);
}
// Looks for the highest inline parent in the editing host.
nsIContent* topMostInlineContent = const_cast<nsIContent*>(&aContent);
for (nsIContent* content : aContent.AncestorsOfType<nsIContent>()) {
if (content == aEditingHost ||
!HTMLEditUtils::IsInlineElement(*content)) {
break;
}
topMostInlineContent = content;
}
return topMostInlineContent;
}
/**
* GetMostDistantAnscestorEditableEmptyInlineElement() returns most distant
* ancestor which only has aEmptyContent or its ancestor, editable and

View File

@ -1096,13 +1096,6 @@ class HTMLEditor final : public TextEditor,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
InsertBRElement(const EditorDOMPoint& aInsertToBreak);
/**
* GetMostAncestorInlineElement() returns the most ancestor inline element
* between aNode and the editing host. Even if the editing host is an inline
* element, this method never returns the editing host as the result.
*/
nsIContent* GetMostAncestorInlineElement(nsINode& aNode) const;
/**
* SplitParentInlineElementsAtRangeEdges() splits parent inline nodes at both
* start and end of aRangeItem. If this splits at every point, this modifies