tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0f95ad06ca0c379a67165c493b2a8c36e659e814
parent 698333553765b352ff1b01264f5c7932e1b5b85b
Author: Masayuki Nakano <masayuki@d-toybox.com>
Date:   Fri, 31 Oct 2025 05:02:57 +0000

Bug 1996501 - part 3: Make `HTMLEditUtils` select proper `BlockInlineCheck` for the scanning direction automatically r=m_kato

In theory, the low level APIs of `HTMLEditUtils` should not choose
`BlockInlineCheck` value.  However, the callers may want if the
direction is changed in the API, e.g., when scanning siblings but then
climbing up. For preserving the low level API behavior, this patch
adds new `BlockInlineCheck` value, `Auto`.  Then, the `HTMLEditUtils`
APIs choose proper value for the direction automatically only when
`Auto` is specified.

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

Diffstat:
Meditor/libeditor/HTMLEditHelpers.h | 31++++++++++++++++++++-----------
Meditor/libeditor/HTMLEditUtils.cpp | 35++++++++++++++++++++++++-----------
Meditor/libeditor/HTMLEditUtils.h | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Meditor/libeditor/HTMLEditorDeleteHandler.cpp | 4+++-
Meditor/libeditor/WSRunScannerNestedClasses.cpp | 50++++++++++++++++++++++++++++++++------------------
5 files changed, 136 insertions(+), 68 deletions(-)

diff --git a/editor/libeditor/HTMLEditHelpers.h b/editor/libeditor/HTMLEditHelpers.h @@ -52,33 +52,42 @@ enum class BlockInlineCheck : uint8_t { // * Looking for whether a padding <br> is required // * Looking for a caret position UseComputedDisplayStyle, + // UseComputedDisplayOutsideStyle if referring siblings or children. + // UseComputedDisplayStyle if referring ancestors. + Auto, }; -/** - * Even if the caller wants block boundary caused by display-inline: flow-root - * like inline-block, because it's required only when scanning from in it. - * I.e., if scanning needs to go to siblings, we don't want to treat - * inline-block siblings as inline. - */ -[[nodiscard]] inline BlockInlineCheck IgnoreInsideBlockBoundary( +[[nodiscard]] inline BlockInlineCheck PreferDisplayOutsideIfUsingDisplay( BlockInlineCheck aBlockInlineCheck) { return aBlockInlineCheck == BlockInlineCheck::UseComputedDisplayStyle ? BlockInlineCheck::UseComputedDisplayOutsideStyle : aBlockInlineCheck; } -[[nodiscard]] inline BlockInlineCheck RespectChildBlockBoundary( +[[nodiscard]] inline BlockInlineCheck PreferDisplayIfUsingDisplayOutside( BlockInlineCheck aBlockInlineCheck) { - return IgnoreInsideBlockBoundary(aBlockInlineCheck); + return aBlockInlineCheck == BlockInlineCheck::UseComputedDisplayOutsideStyle + ? BlockInlineCheck::UseComputedDisplayStyle + : aBlockInlineCheck; } -[[nodiscard]] inline BlockInlineCheck RespectParentBlockBoundary( +[[nodiscard]] inline BlockInlineCheck UseComputedDisplayStyleIfAuto( BlockInlineCheck aBlockInlineCheck) { - return aBlockInlineCheck == BlockInlineCheck::UseComputedDisplayOutsideStyle + return aBlockInlineCheck == BlockInlineCheck::Auto + // Treat flow-root as a block such as inline-block. ? BlockInlineCheck::UseComputedDisplayStyle : aBlockInlineCheck; } +[[nodiscard]] inline BlockInlineCheck UseComputedDisplayOutsideStyleIfAuto( + BlockInlineCheck aBlockInlineCheck) { + return aBlockInlineCheck == BlockInlineCheck::Auto + // Use display-outside for checking a sibling or child element as a + // block. + ? BlockInlineCheck::UseComputedDisplayOutsideStyle + : aBlockInlineCheck; +} + enum class WithTransaction { No, Yes }; inline std::ostream& operator<<(std::ostream& aStream, WithTransaction aWithTransaction) { diff --git a/editor/libeditor/HTMLEditUtils.cpp b/editor/libeditor/HTMLEditUtils.cpp @@ -276,6 +276,7 @@ static bool IsHTMLBlockElementByDefault(const nsIContent& aContent) { bool HTMLEditUtils::IsBlockElement(const nsIContent& aContent, BlockInlineCheck aBlockInlineCheck) { MOZ_ASSERT(aBlockInlineCheck != BlockInlineCheck::Unused); + MOZ_ASSERT(aBlockInlineCheck != BlockInlineCheck::Auto); if (MOZ_UNLIKELY(!aContent.IsElement())) { return false; @@ -328,6 +329,7 @@ bool HTMLEditUtils::IsBlockElement(const nsIContent& aContent, bool HTMLEditUtils::IsInlineContent(const nsIContent& aContent, BlockInlineCheck aBlockInlineCheck) { MOZ_ASSERT(aBlockInlineCheck != BlockInlineCheck::Unused); + MOZ_ASSERT(aBlockInlineCheck != BlockInlineCheck::Auto); if (!aContent.IsElement()) { return true; @@ -826,8 +828,7 @@ EditorDOMPoint HTMLEditUtils::LineRequiresPaddingLineBreakToBeVisible( nsIContent* const previousVisibleLeafOrChildBlock = HTMLEditUtils::GetPreviousNonEmptyLeafContentOrPreviousBlockElement( preferredPaddingLineBreakPoint, - {LeafNodeType::LeafNodeOrChildBlock}, - BlockInlineCheck::UseComputedDisplayOutsideStyle); + {LeafNodeType::LeafNodeOrChildBlock}, BlockInlineCheck::Auto); if (!previousVisibleLeafOrChildBlock) { // Reached current block. return true; @@ -1892,7 +1893,8 @@ nsIContent* HTMLEditUtils::GetPreviousContent( if (aOptions.contains(WalkTreeOption::StopAtBlockBoundary) && aPoint.IsInContentNode() && HTMLEditUtils::IsBlockElement( - *aPoint.template ContainerAs<nsIContent>(), aBlockInlineCheck)) { + *aPoint.template ContainerAs<nsIContent>(), + UseComputedDisplayStyleIfAuto(aBlockInlineCheck))) { // If we aren't allowed to cross blocks, don't look before this block. return nullptr; } @@ -1951,7 +1953,9 @@ nsIContent* HTMLEditUtils::GetNextContent( if (point.GetChild()) { if (aOptions.contains(WalkTreeOption::StopAtBlockBoundary) && - HTMLEditUtils::IsBlockElement(*point.GetChild(), aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *point.GetChild(), + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { return point.GetChild(); } @@ -1986,8 +1990,9 @@ nsIContent* HTMLEditUtils::GetNextContent( // and want the next one. if (aOptions.contains(WalkTreeOption::StopAtBlockBoundary) && point.IsInContentNode() && - HTMLEditUtils::IsBlockElement(*point.template ContainerAs<nsIContent>(), - aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *point.template ContainerAs<nsIContent>(), + UseComputedDisplayStyleIfAuto(aBlockInlineCheck))) { // don't cross out of parent block return nullptr; } @@ -2016,9 +2021,11 @@ nsIContent* HTMLEditUtils::GetAdjacentLeafContent( if (sibling) { // XXX If `sibling` belongs to siblings of inclusive ancestors of aNode, // perhaps, we need to use - // IgnoreInsideBlockBoundary(aBlockInlineCheck) here. + // PreferDisplayOutsideIfUsingDisplay(aBlockInlineCheck) here. if (aOptions.contains(WalkTreeOption::StopAtBlockBoundary) && - HTMLEditUtils::IsBlockElement(*sibling, aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *sibling, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { // don't look inside previous sibling, since it is a block return sibling; } @@ -2042,7 +2049,8 @@ nsIContent* HTMLEditUtils::GetAdjacentLeafContent( if (parent == aAncestorLimiter || (aOptions.contains(WalkTreeOption::StopAtBlockBoundary) && - HTMLEditUtils::IsBlockElement(*parent, aBlockInlineCheck))) { + HTMLEditUtils::IsBlockElement( + *parent, UseComputedDisplayStyleIfAuto(aBlockInlineCheck)))) { return nullptr; } @@ -2332,6 +2340,8 @@ Element* HTMLEditUtils::GetAncestorElement( aAncestorTypes.contains(AncestorType::ClosestButtonElement), !aAncestorTypes.contains(AncestorType::StopAtClosestButtonElement)); + aBlockInlineCheck = UseComputedDisplayStyleIfAuto(aBlockInlineCheck); + const Element* theBodyElement = aContent.OwnerDoc()->GetBody(); const Element* theDocumentElement = aContent.OwnerDoc()->GetDocumentElement(); Element* lastAncestorElement = nullptr; @@ -2459,6 +2469,8 @@ Element* HTMLEditUtils::GetInclusiveAncestorElement( aAncestorTypes.contains(AncestorType::ClosestButtonElement), !aAncestorTypes.contains(AncestorType::StopAtClosestButtonElement)); + aBlockInlineCheck = UseComputedDisplayStyleIfAuto(aBlockInlineCheck); + const Element* theBodyElement = aContent.OwnerDoc()->GetBody(); const Element* theDocumentElement = aContent.OwnerDoc()->GetDocumentElement(); const bool editableElementOnly = @@ -2952,8 +2964,9 @@ size_t HTMLEditUtils::CollectEmptyInlineContainerDescendants( const EmptyCheckOptions& aOptions, BlockInlineCheck aBlockInlineCheck) { size_t numberOfFoundElements = 0; for (Element* element = aNode.GetFirstElementChild(); element;) { - if (HTMLEditUtils::IsEmptyInlineContainer(*element, aOptions, - aBlockInlineCheck)) { + if (HTMLEditUtils::IsEmptyInlineContainer( + *element, aOptions, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { aOutArrayOfContents.AppendElement(*element); numberOfFoundElements++; nsIContent* nextContent = element->GetNextNonChildNode(&aNode); diff --git a/editor/libeditor/HTMLEditUtils.h b/editor/libeditor/HTMLEditUtils.h @@ -194,7 +194,7 @@ class HTMLEditUtils final { BlockInlineCheck aBlockInlineCheck); /** - * This is designed to check elements or non-element nodes which are layed out + * This is designed to check elements or non-element nodes which are laid out * as inline. Therefore, inline-block etc and ruby are treated as inline. * Note that invisible non-element nodes like comment nodes are also treated * as inline. @@ -660,7 +660,8 @@ class HTMLEditUtils final { */ template <typename EditorDOMPointType> [[nodiscard]] static bool RangeIsAcrossStartBlockBoundary( - const EditorDOMRangeBase<EditorDOMPointType>& aRange) { + const EditorDOMRangeBase<EditorDOMPointType>& aRange, + BlockInlineCheck aBlockInlineCheck) { MOZ_ASSERT(aRange.IsPositionedAndValid()); if (MOZ_UNLIKELY(!aRange.StartRef().IsInContentNode())) { return false; @@ -669,7 +670,7 @@ class HTMLEditUtils final { HTMLEditUtils::GetInclusiveAncestorElement( *aRange.StartRef().template ContainerAs<nsIContent>(), ClosestBlockElement, - BlockInlineCheck::UseComputedDisplayOutsideStyle); + UseComputedDisplayStyleIfAuto(aBlockInlineCheck)); if (MOZ_UNLIKELY(!startBlockElement)) { return false; } @@ -1101,6 +1102,7 @@ class HTMLEditUtils final { static nsIContent* GetPreviousSibling( const nsIContent& aContent, const WalkTreeOptions& aOptions, BlockInlineCheck aBlockInlineCheck = BlockInlineCheck::Unused) { + aBlockInlineCheck = UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck); for (nsIContent* sibling = aContent.GetPreviousSibling(); sibling; sibling = sibling->GetPreviousSibling()) { if (HTMLEditUtils::IsContentIgnored(*sibling, aOptions)) { @@ -1125,6 +1127,7 @@ class HTMLEditUtils final { static nsIContent* GetNextSibling( const nsIContent& aContent, const WalkTreeOptions& aOptions, BlockInlineCheck aBlockInlineCheck = BlockInlineCheck::Unused) { + aBlockInlineCheck = UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck); for (nsIContent* sibling = aContent.GetNextSibling(); sibling; sibling = sibling->GetNextSibling()) { if (HTMLEditUtils::IsContentIgnored(*sibling, aOptions)) { @@ -1148,6 +1151,7 @@ class HTMLEditUtils final { static nsIContent* GetLastChild( const nsINode& aNode, const WalkTreeOptions& aOptions, BlockInlineCheck aBlockInlineCheck = BlockInlineCheck::Unused) { + aBlockInlineCheck = UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck); for (nsIContent* child = aNode.GetLastChild(); child; child = child->GetPreviousSibling()) { if (HTMLEditUtils::IsContentIgnored(*child, aOptions)) { @@ -1171,6 +1175,7 @@ class HTMLEditUtils final { static nsIContent* GetFirstChild( const nsINode& aNode, const WalkTreeOptions& aOptions, BlockInlineCheck aBlockInlineCheck = BlockInlineCheck::Unused) { + aBlockInlineCheck = UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck); for (nsIContent* child = aNode.GetFirstChild(); child; child = child->GetNextSibling()) { if (HTMLEditUtils::IsContentIgnored(*child, aOptions)) { @@ -1242,14 +1247,14 @@ class HTMLEditUtils final { if (aWalkTreeDirection == WalkTreeDirection::Backward) { editableContent = HTMLEditUtils::GetPreviousContent( aPoint, {WalkTreeOption::IgnoreNonEditableNode}, - BlockInlineCheck::UseComputedDisplayStyle, &aEditingHost); + BlockInlineCheck::Auto, &aEditingHost); if (!editableContent) { return nullptr; // Not illegal. } } else { editableContent = HTMLEditUtils::GetNextContent( aPoint, {WalkTreeOption::IgnoreNonEditableNode}, - BlockInlineCheck::UseComputedDisplayStyle, &aEditingHost); + BlockInlineCheck::Auto, &aEditingHost); if (NS_WARN_IF(!editableContent)) { // Perhaps, illegal because the node pointed by aPoint isn't editable // and nobody of previous nodes is editable. @@ -1267,14 +1272,14 @@ class HTMLEditUtils final { if (aWalkTreeDirection == WalkTreeDirection::Backward) { editableContent = HTMLEditUtils::GetPreviousContent( *editableContent, {WalkTreeOption::IgnoreNonEditableNode}, - BlockInlineCheck::UseComputedDisplayStyle, &aEditingHost); + BlockInlineCheck::Auto, &aEditingHost); if (NS_WARN_IF(!editableContent)) { return nullptr; } } else { editableContent = HTMLEditUtils::GetNextContent( *editableContent, {WalkTreeOption::IgnoreNonEditableNode}, - BlockInlineCheck::UseComputedDisplayStyle, &aEditingHost); + BlockInlineCheck::Auto, &aEditingHost); if (NS_WARN_IF(!editableContent)) { return nullptr; } @@ -1341,7 +1346,9 @@ class HTMLEditUtils final { continue; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrChildBlock) && - HTMLEditUtils::IsBlockElement(*content, aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *content, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { return content; } if (!content->HasChildren() || @@ -1389,7 +1396,9 @@ class HTMLEditUtils final { continue; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrChildBlock) && - HTMLEditUtils::IsBlockElement(*content, aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *content, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { return content; } if (!content->HasChildren() || @@ -1434,7 +1443,9 @@ class HTMLEditUtils final { } for (Element* parentElement : aStartContent.AncestorsOfType<Element>()) { if (parentElement == aAncestorLimiter || - HTMLEditUtils::IsBlockElement(*parentElement, aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *parentElement, + UseComputedDisplayStyleIfAuto(aBlockInlineCheck))) { return nullptr; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1451,11 +1462,13 @@ class HTMLEditUtils final { } } MOZ_ASSERT(nextContent); - aBlockInlineCheck = IgnoreInsideBlockBoundary(aBlockInlineCheck); } // We have a next content. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*nextContent, aBlockInlineCheck)) { + if (HTMLEditUtils::IsBlockElement( + *nextContent, + PreferDisplayOutsideIfUsingDisplay( + UseComputedDisplayStyleIfAuto(aBlockInlineCheck)))) { return nextContent; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1509,7 +1522,7 @@ class HTMLEditUtils final { if (aStartPoint.GetContainer() == aAncestorLimiter || HTMLEditUtils::IsBlockElement( *aStartPoint.template ContainerAs<nsIContent>(), - aBlockInlineCheck)) { + UseComputedDisplayStyleIfAuto(aBlockInlineCheck))) { // We are at end of the block. return nullptr; } @@ -1517,11 +1530,14 @@ class HTMLEditUtils final { // We are at end of non-block container return HTMLEditUtils::GetNextLeafContentOrNextBlockElement( *aStartPoint.template ContainerAs<nsIContent>(), aLeafNodeTypes, - IgnoreInsideBlockBoundary(aBlockInlineCheck), aAncestorLimiter); + PreferDisplayOutsideIfUsingDisplay(aBlockInlineCheck), + aAncestorLimiter); } // We have a next node. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*nextContent, aBlockInlineCheck)) { + if (HTMLEditUtils::IsBlockElement( + *nextContent, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { return nextContent; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1532,7 +1548,7 @@ class HTMLEditUtils final { // else if it's a container, get deep leftmost child if (nsIContent* child = HTMLEditUtils::GetFirstLeafContent( *nextContent, aLeafNodeTypes, - IgnoreInsideBlockBoundary(aBlockInlineCheck))) { + PreferDisplayOutsideIfUsingDisplay(aBlockInlineCheck))) { return child; } } @@ -1572,7 +1588,9 @@ class HTMLEditUtils final { } for (Element* parentElement : aStartContent.AncestorsOfType<Element>()) { if (parentElement == aAncestorLimiter || - HTMLEditUtils::IsBlockElement(*parentElement, aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *parentElement, + UseComputedDisplayStyleIfAuto(aBlockInlineCheck))) { return nullptr; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1589,11 +1607,13 @@ class HTMLEditUtils final { } } MOZ_ASSERT(previousContent); - aBlockInlineCheck = IgnoreInsideBlockBoundary(aBlockInlineCheck); } // We have a next content. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*previousContent, aBlockInlineCheck)) { + if (HTMLEditUtils::IsBlockElement( + *previousContent, + PreferDisplayOutsideIfUsingDisplay( + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck)))) { return previousContent; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1603,7 +1623,8 @@ class HTMLEditUtils final { if (HTMLEditUtils::IsContainerNode(*previousContent)) { // Else if it's a container, get deep rightmost child if (nsIContent* child = HTMLEditUtils::GetLastLeafContent( - *previousContent, aLeafNodeTypes, aBlockInlineCheck)) { + *previousContent, aLeafNodeTypes, + PreferDisplayOutsideIfUsingDisplay(aBlockInlineCheck))) { return child; } } @@ -1646,7 +1667,7 @@ class HTMLEditUtils final { if (aStartPoint.GetContainer() == aAncestorLimiter || HTMLEditUtils::IsBlockElement( *aStartPoint.template ContainerAs<nsIContent>(), - aBlockInlineCheck)) { + UseComputedDisplayStyleIfAuto(aBlockInlineCheck))) { // We are at start of the block. return nullptr; } @@ -1654,7 +1675,8 @@ class HTMLEditUtils final { // We are at start of non-block container return HTMLEditUtils::GetPreviousLeafContentOrPreviousBlockElement( *aStartPoint.template ContainerAs<nsIContent>(), aLeafNodeTypes, - IgnoreInsideBlockBoundary(aBlockInlineCheck), aAncestorLimiter); + PreferDisplayOutsideIfUsingDisplay(aBlockInlineCheck), + aAncestorLimiter); } nsCOMPtr<nsIContent> previousContent = @@ -1664,7 +1686,9 @@ class HTMLEditUtils final { } // We have a prior node. If it's a block, return it. - if (HTMLEditUtils::IsBlockElement(*previousContent, aBlockInlineCheck)) { + if (HTMLEditUtils::IsBlockElement( + *previousContent, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { return previousContent; } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1675,7 +1699,7 @@ class HTMLEditUtils final { // Else if it's a container, get deep rightmost child if (nsIContent* child = HTMLEditUtils::GetLastLeafContent( *previousContent, aLeafNodeTypes, - IgnoreInsideBlockBoundary(aBlockInlineCheck))) { + PreferDisplayOutsideIfUsingDisplay(aBlockInlineCheck))) { return child; } } @@ -1706,7 +1730,8 @@ class HTMLEditUtils final { if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrChildBlock) && HTMLEditUtils::IsBlockElement( *previousContent, - BlockInlineCheck::UseComputedDisplayOutsideStyle)) { + PreferDisplayOutsideIfUsingDisplay( + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck)))) { return previousContent; // Reached block element } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -1752,7 +1777,8 @@ class HTMLEditUtils final { if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrChildBlock) && HTMLEditUtils::IsBlockElement( *previousContent, - BlockInlineCheck::UseComputedDisplayOutsideStyle)) { + PreferDisplayOutsideIfUsingDisplay( + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck)))) { return previousContent; // Reached block element } if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && @@ -2089,6 +2115,7 @@ class HTMLEditUtils final { const nsIContent& aContent, BlockInlineCheck aBlockInlineCheck, const Element* aEditingHost = nullptr, const nsIContent* aAncestorLimiter = nullptr) { + aBlockInlineCheck = UseComputedDisplayStyleIfAuto(aBlockInlineCheck); if (HTMLEditUtils::IsBlockElement(aContent, aBlockInlineCheck)) { return nullptr; } @@ -2135,6 +2162,7 @@ class HTMLEditUtils final { if (&aEmptyContent == aEditingHost || &aEmptyContent == aAncestorLimiter) { return nullptr; } + aBlockInlineCheck = UseComputedDisplayStyleIfAuto(aBlockInlineCheck); nsIContent* lastEmptyContent = const_cast<nsIContent*>(&aEmptyContent); for (Element* element : aEmptyContent.AncestorsOfType<Element>()) { if (element == aEditingHost || element == aAncestorLimiter) { @@ -3085,7 +3113,9 @@ class HTMLEditUtils final { continue; } if (aOptions.contains(WalkTreeOption::StopAtBlockBoundary) && - HTMLEditUtils::IsBlockElement(*child, aBlockInlineCheck)) { + HTMLEditUtils::IsBlockElement( + *child, + UseComputedDisplayOutsideStyleIfAuto(aBlockInlineCheck))) { break; } ++count; diff --git a/editor/libeditor/HTMLEditorDeleteHandler.cpp b/editor/libeditor/HTMLEditorDeleteHandler.cpp @@ -4616,7 +4616,9 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler:: return false; } if (!HTMLEditUtils::RangeIsAcrossStartBlockBoundary( - deleteContentResult.DeleteRangeRef())) { + deleteContentResult.DeleteRangeRef(), + // XXX UseComputedDisplayStyle? + BlockInlineCheck::UseComputedDisplayOutsideStyle)) { return false; } WSScanResult nextThing = diff --git a/editor/libeditor/WSRunScannerNestedClasses.cpp b/editor/libeditor/WSRunScannerNestedClasses.cpp @@ -244,7 +244,7 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData:: const BlockInlineCheck blockInlineCheck = aOptions.contains(Option::ReferHTMLDefaultStyle) ? BlockInlineCheck::UseHTMLDefaultStyle - : BlockInlineCheck::UseComputedDisplayOutsideStyle; + : BlockInlineCheck::Auto; // Then, we need to check previous leaf node. const auto leafNodeTypes = aOptions.contains(Option::OnlyEditableNodes) @@ -258,13 +258,14 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData:: return BoundaryData( aPoint, const_cast<Element&>(aAncestorLimiter), HTMLEditUtils::IsBlockElement( - aAncestorLimiter, RespectParentBlockBoundary(blockInlineCheck)) + aAncestorLimiter, UseComputedDisplayStyleIfAuto(blockInlineCheck)) ? WSType::CurrentBlockBoundary : WSType::InlineEditingHostBoundary); } - if (HTMLEditUtils::IsBlockElement(*previousLeafContentOrBlock, - blockInlineCheck)) { + if (HTMLEditUtils::IsBlockElement( + *previousLeafContentOrBlock, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck))) { return BoundaryData(aPoint, *previousLeafContentOrBlock, WSType::OtherBlockBoundary); } @@ -399,7 +400,7 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( const BlockInlineCheck blockInlineCheck = aOptions.contains(Option::ReferHTMLDefaultStyle) ? BlockInlineCheck::UseHTMLDefaultStyle - : BlockInlineCheck::UseComputedDisplayOutsideStyle; + : BlockInlineCheck::Auto; // Then, we need to check next leaf node. const auto leafNodeTypes = @@ -415,13 +416,14 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( aPoint.template To<EditorDOMPoint>(), const_cast<Element&>(aAncestorLimiter), HTMLEditUtils::IsBlockElement( - aAncestorLimiter, RespectParentBlockBoundary(blockInlineCheck)) + aAncestorLimiter, UseComputedDisplayStyleIfAuto(blockInlineCheck)) ? WSType::CurrentBlockBoundary : WSType::InlineEditingHostBoundary); } - if (HTMLEditUtils::IsBlockElement(*nextLeafContentOrBlock, - blockInlineCheck)) { + if (HTMLEditUtils::IsBlockElement( + *nextLeafContentOrBlock, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck))) { // we encountered a new block. therefore no more ws. return BoundaryData(aPoint, *nextLeafContentOrBlock, WSType::OtherBlockBoundary); @@ -859,11 +861,13 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetInclusiveNextCharPoint( const BlockInlineCheck blockInlineCheck = static_cast<bool>(aReferHTMLDefaultStyle) ? BlockInlineCheck::UseHTMLDefaultStyle - : BlockInlineCheck::UseComputedDisplayOutsideStyle; + : BlockInlineCheck::Auto; const EditorRawDOMPoint point = [&]() MOZ_NEVER_INLINE_DEBUG { nsIContent* const child = aPoint.CanContainerHaveChildren() ? aPoint.GetChild() : nullptr; - if (!child || HTMLEditUtils::IsBlockElement(*child, blockInlineCheck) || + if (!child || + HTMLEditUtils::IsBlockElement( + *child, UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck)) || HTMLEditUtils::IsVisibleElementEvenIfLeafNode(*child)) { return aPoint.template To<EditorRawDOMPoint>(); } @@ -878,7 +882,9 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetInclusiveNextCharPoint( nsIContent* const leafContent = HTMLEditUtils::GetFirstLeafContent( *child, {LeafNodeType::LeafNodeOrChildBlock}, blockInlineCheck); if (NS_WARN_IF(!leafContent) || - HTMLEditUtils::IsBlockElement(*leafContent, blockInlineCheck) || + HTMLEditUtils::IsBlockElement( + *leafContent, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck)) || HTMLEditUtils::IsVisibleElementEvenIfLeafNode(*leafContent)) { return EditorRawDOMPoint(); } @@ -910,7 +916,7 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetInclusiveNextCharPoint( *aPoint.template ContainerAs<nsIContent>()) ? kScanEditableRootAncestorTypes : kScanAnyRootAncestorTypes, - RespectParentBlockBoundary(blockInlineCheck)); + blockInlineCheck); if (NS_WARN_IF( !editableBlockElementOrInlineEditingHostOrNonEditableRootElement)) { return EditorDOMPointType(); @@ -934,7 +940,9 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetInclusiveNextCharPoint( (aIgnoreNonEditableNodes == IgnoreNonEditableNodes::Yes && !HTMLEditUtils::IsSimplyEditableNode(*nextContent))) { if (nextContent == aFollowingLimiterContent || - HTMLEditUtils::IsBlockElement(*nextContent, blockInlineCheck) || + HTMLEditUtils::IsBlockElement( + *nextContent, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck)) || HTMLEditUtils::IsVisibleElementEvenIfLeafNode(*nextContent)) { break; // Reached end of current runs. } @@ -961,13 +969,15 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetPreviousCharPoint( const BlockInlineCheck blockInlineCheck = static_cast<bool>(aReferHTMLDefaultStyle) ? BlockInlineCheck::UseHTMLDefaultStyle - : BlockInlineCheck::UseComputedDisplayOutsideStyle; + : BlockInlineCheck::Auto; const EditorRawDOMPoint point = [&]() MOZ_NEVER_INLINE_DEBUG { nsIContent* const previousChild = aPoint.CanContainerHaveChildren() ? aPoint.GetPreviousSiblingOfChild() : nullptr; if (!previousChild || - HTMLEditUtils::IsBlockElement(*previousChild, blockInlineCheck) || + HTMLEditUtils::IsBlockElement( + *previousChild, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck)) || HTMLEditUtils::IsVisibleElementEvenIfLeafNode(*previousChild)) { return aPoint.template To<EditorRawDOMPoint>(); } @@ -982,7 +992,9 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetPreviousCharPoint( nsIContent* const leafContent = HTMLEditUtils::GetLastLeafContent( *previousChild, {LeafNodeType::LeafNodeOrChildBlock}, blockInlineCheck); if (NS_WARN_IF(!leafContent) || - HTMLEditUtils::IsBlockElement(*leafContent, blockInlineCheck) || + HTMLEditUtils::IsBlockElement( + *leafContent, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck)) || HTMLEditUtils::IsVisibleElementEvenIfLeafNode(*leafContent)) { return EditorRawDOMPoint(); } @@ -1015,7 +1027,7 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetPreviousCharPoint( *aPoint.template ContainerAs<nsIContent>()) ? kScanEditableRootAncestorTypes : kScanAnyRootAncestorTypes, - RespectParentBlockBoundary(blockInlineCheck)); + blockInlineCheck); if (NS_WARN_IF( !editableBlockElementOrInlineEditingHostOrNonEditableRootElement)) { return EditorDOMPointType(); @@ -1040,7 +1052,9 @@ EditorDOMPointType WSRunScanner::TextFragmentData::GetPreviousCharPoint( (aIgnoreNonEditableNodes == IgnoreNonEditableNodes::Yes && !HTMLEditUtils::IsSimplyEditableNode(*previousContent))) { if (previousContent == aPrecedingLimiterContent || - HTMLEditUtils::IsBlockElement(*previousContent, blockInlineCheck) || + HTMLEditUtils::IsBlockElement( + *previousContent, + UseComputedDisplayOutsideStyleIfAuto(blockInlineCheck)) || HTMLEditUtils::IsVisibleElementEvenIfLeafNode(*previousContent)) { break; // Reached start of current runs. }