Title: [280585] trunk/Source/WebCore
Revision
280585
Author
[email protected]
Date
2021-08-02 23:54:03 -0700 (Mon, 02 Aug 2021)

Log Message

Align implementation of PositionIterator::isCandidate() on Position::isCandidate()
https://bugs.webkit.org/show_bug.cgi?id=228635

Patch by Frédéric Wang <[email protected]> on 2021-08-02
Reviewed by Darin Adler.

The bug fixed in r280381 was due to the fact that PositionIterator::isCandidate() and
Position::isCandidate() had gone out of sync. To prevent future bugs of this kind, this patch
modifies PositionIterator::isCandidate() so that it is aligned with
PositionIterator::isCandidate() (except when an m_anchorType check is needed) and add code
comments in both functions to ensure the same changes are always applied to them.

* dom/Position.cpp:
(WebCore::Position::isCandidate const): Add a comment to make sure we update PositionIterator
when changing that function. Also use auto for a local variable like in PositionIterator.
* dom/PositionIterator.cpp:
(WebCore::PositionIterator::isCandidate const): Add a comment to make sure we update Position
when changing that function. Rearrange the code to use positionBeforeOrAfterNodeIsCandidate
and early return when the node is a <html> element (these are not behavior changes). For
block flow / grid / flexbox renderers, add a special handling when the anchor node is a root
editable element ; also change the fallback value returned at the end of the function (these
are two behavior changes).

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (280584 => 280585)


--- trunk/Source/WebCore/ChangeLog	2021-08-03 04:21:47 UTC (rev 280584)
+++ trunk/Source/WebCore/ChangeLog	2021-08-03 06:54:03 UTC (rev 280585)
@@ -1,3 +1,27 @@
+2021-08-02  Frédéric Wang  <[email protected]>
+
+        Align implementation of PositionIterator::isCandidate() on Position::isCandidate()
+        https://bugs.webkit.org/show_bug.cgi?id=228635
+
+        Reviewed by Darin Adler.
+
+        The bug fixed in r280381 was due to the fact that PositionIterator::isCandidate() and
+        Position::isCandidate() had gone out of sync. To prevent future bugs of this kind, this patch
+        modifies PositionIterator::isCandidate() so that it is aligned with
+        PositionIterator::isCandidate() (except when an m_anchorType check is needed) and add code
+        comments in both functions to ensure the same changes are always applied to them.
+
+        * dom/Position.cpp:
+        (WebCore::Position::isCandidate const): Add a comment to make sure we update PositionIterator
+        when changing that function. Also use auto for a local variable like in PositionIterator.
+        * dom/PositionIterator.cpp:
+        (WebCore::PositionIterator::isCandidate const): Add a comment to make sure we update Position
+        when changing that function. Rearrange the code to use positionBeforeOrAfterNodeIsCandidate
+        and early return when the node is a <html> element (these are not behavior changes). For
+        block flow / grid / flexbox renderers, add a special handling when the anchor node is a root
+        editable element ; also change the fallback value returned at the end of the function (these
+        are two behavior changes).
+
 2021-08-02  Jean-Yves Avenard  <[email protected]>
 
         [WebAudio] webm; properly trim frames according to the codec delay information

Modified: trunk/Source/WebCore/dom/Position.cpp (280584 => 280585)


--- trunk/Source/WebCore/dom/Position.cpp	2021-08-03 04:21:47 UTC (rev 280584)
+++ trunk/Source/WebCore/dom/Position.cpp	2021-08-03 06:54:03 UTC (rev 280585)
@@ -967,6 +967,7 @@
     return candidateRoot;
 }
 
+// This function should be kept in sync with PositionIterator::isCandidate().
 bool Position::isCandidate() const
 {
     if (isNull())
@@ -997,7 +998,7 @@
         return false;
 
     if (is<RenderBlockFlow>(*renderer) || is<RenderGrid>(*renderer) || is<RenderFlexibleBox>(*renderer)) {
-        RenderBlock& block = downcast<RenderBlock>(*renderer);
+        auto& block = downcast<RenderBlock>(*renderer);
         if (block.logicalHeight() || is<HTMLBodyElement>(*m_anchorNode) || m_anchorNode->isRootEditableElement()) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(block))
                 return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());

Modified: trunk/Source/WebCore/dom/PositionIterator.cpp (280584 => 280585)


--- trunk/Source/WebCore/dom/PositionIterator.cpp	2021-08-03 04:21:47 UTC (rev 280584)
+++ trunk/Source/WebCore/dom/PositionIterator.cpp	2021-08-03 06:54:03 UTC (rev 280585)
@@ -145,6 +145,7 @@
     return m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(*m_anchorNode);
 }
 
+// This function should be kept in sync with Position::isCandidate().
 bool PositionIterator::isCandidate() const
 {
     if (!m_anchorNode)
@@ -163,19 +164,23 @@
     if (is<RenderText>(*renderer))
         return !Position::nodeIsUserSelectNone(m_anchorNode) && downcast<RenderText>(*renderer).containsCaretOffset(m_offsetInAnchor);
 
-    if (isRenderedTable(m_anchorNode) || editingIgnoresContent(*m_anchorNode))
+    if (positionBeforeOrAfterNodeIsCandidate(*m_anchorNode))
         return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
 
-    if (!is<HTMLHtmlElement>(*m_anchorNode) && (is<RenderBlockFlow>(*renderer) || is<RenderGrid>(*renderer) || is<RenderFlexibleBox>(*renderer))) {
+    if (is<HTMLHtmlElement>(*m_anchorNode))
+        return false;
+
+    if (is<RenderBlockFlow>(*renderer) || is<RenderGrid>(*renderer) || is<RenderFlexibleBox>(*renderer)) {
         auto& block = downcast<RenderBlock>(*renderer);
-        if (block.logicalHeight() || is<HTMLBodyElement>(*m_anchorNode)) {
+        if (block.logicalHeight() || is<HTMLBodyElement>(*m_anchorNode) || m_anchorNode->isRootEditableElement()) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(block))
                 return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
             return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
         }
+        return false;
     }
 
-    return false;
+    return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
 }
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to