Title: [291789] trunk
Revision
291789
Author
svil...@igalia.com
Date
2022-03-24 01:33:41 -0700 (Thu, 24 Mar 2022)

Log Message

Release assert in Document::updateLayout() via HTMLTextAreaElement::childrenChanged
https://bugs.webkit.org/show_bug.cgi?id=224471

Reviewed by Ryosuke Niwa.

Source/WebCore:

Executing some editing commands in a text area might force the recomputation of things
like caret or the visible selection position and extent. Under some circumstances (like
when the text area has no content and children) we might end up trying to update layout
when it is not safe as a side effect of updating the caret.

In order to fix that, we can switch to a model in which we update the selection asynchronously
in the case of having a non-user triggered change. That way we don't do it inside
a restricted layout scope.

The App Highlight restoration code had to be tuned as well (when restoring and scrolling to reveal
a Quick Note on iOS MacOS). It uses TemporarySelectionChange to select and scroll to reveal the highlight
range; the code assumed that this scrolling happens synchronously, since it reverts the selection to
the original range at the end of `AppHighlightStorage::attemptToRestoreHighlightAndScroll` when the
TemporarySelectionChange falls out of scope. That is however no longer the case. Actually no scrolling
happened after this patch because we end up only scheduling the appearance update timer before setting
the selection back to the original state with `SelectionRevealMode::DoNotReveal`. Since this only happens
when the user interacts in the Notes app, it seems sensible to consider it as a user triggered event.

* Modules/highlight/AppHighlightStorage.cpp:
(WebCore::AppHighlightStorage::attemptToRestoreHighlightAndScroll): Consider the selection change
as user triggered so scrolling actually happens.
* editing/Editor.cpp:
(WebCore::TemporarySelectionChange::setSelection): Check the UserTriggered flags for default options.
* editing/Editor.h: Added a new UserTriggered flag.
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::setSelection): Call scheduleAppearanceUpdateAfterStyleChange() for
!IsUserTriggered changes.
(WebCore::FrameSelection::updateSelectionAppearanceNow): Renamed from updateSelectionByUpdatingLayoutOrStyle.
It does not need the Document& attribute because it was always called with m_document.
(WebCore::FrameSelection::absoluteCaretBounds): Replaced updateSelectionByUpdatingLayoutOrStyle with
updateSelectionAppearanceNow().
(WebCore::FrameSelection::setCaretVisibility): Ditto.
(WebCore::FrameSelection::selectionBounds const): Ditto.
(WebCore::FrameSelection::revealSelection): Call updateSelectionAppearanceNow().
 (WebCore::FrameSelection::updateAppearanceIfRevealingSelectionIsNeeded): New method.
(WebCore::updateSelectionByUpdatingLayoutOrStyle): Deleted.
* editing/FrameSelection.h:
* page/EventHandler.cpp:
(WebCore::setSelectionIfNeeded): Set the UserTriggered flag for calling setSelection().
* page/Page.cpp:
(WebCore::Page::doAfterUpdateRendering): Call updateAppearanceAfterLayout().

LayoutTests:

Moved some tests out of the text-based-repaint.js model because selection is now updated
and revealed asynchronously in the case of non-user triggered changes. The problem is that
by the time the repaint rects are queried the update has not happened yet. That's why
the tests were modified so that we wait until the repaint happens.

Same situation for other tests that do not involve repaint rects but trigger accesibility
tree updates. We must ensure that we let the notification be thrown before checking whether or
not has been emited. As it's done asynchronously we must let the main thread run before checking.

Last but not least, some of the tests are using setTimeout() instead of requestAnimationFrame()
because the results with the latter were not as reliable under stress/debug conditions.

* accessibility/mac/selection-boundary-userinfo.html:
* accessibility/mac/selection-change-userinfo.html:
* accessibility/mac/selection-value-changes-for-aria-textbox.html:
* editing/selection-with-absolute-positioned-empty-content.html:
* fast/forms/textarea-scrolled-endline-caret.html:
* fast/repaint/selection-gap-absolute-child-expected.txt:
* fast/repaint/selection-gap-absolute-child.html:
* fast/repaint/selection-gap-flipped-absolute-child-expected.txt:
* fast/repaint/selection-gap-flipped-absolute-child.html:
* fast/repaint/selection-gap-transformed-absolute-child-expected.txt:
* fast/repaint/selection-gap-transformed-absolute-child.html:
* fast/repaint/selection-gap-transformed-fixed-child-expected.txt:
* fast/repaint/selection-gap-transformed-fixed-child.html:
* fast/repaint/selection-paint-invalidation-expected.txt:
* fast/repaint/selection-ruby-rl-expected.txt:
* fast/repaint/selection-ruby-rl.html:
* fast/repaint/text-selection-overflow-hidden-expected.txt:
* fast/repaint/text-selection-overflow-hidden.html:
* platform/gtk/TestExpectations:
* platform/gtk/fast/repaint/selection-ruby-rl-expected.txt: Copied from LayoutTests/fast/repaint/selection-ruby-rl-expected.txt.
* platform/gtk/fast/repaint/text-selection-overflow-hidden-expected.txt:
* platform/mac-catalina-wk1/fast/repaint/focus-setting-selection-syncronizing-not-clearing-expected.txt: Added.
* platform/mac-wk1/TestExpectations:
* platform/mac-wk1/fast/repaint/4776765-expected.txt: Added.
* platform/mac-wk1/accessibility/mac/focus-setting-selection-syncronizing-not-clearing-expected.txt: Added.
* platform/mac-wk1/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-005-expected.txt:
* platform/mac/TestExpectations:
* platform/win/fast/repaint/4776765-expected.txt: Added.
* platform/win/fast/repaint/selection-gap-fixed-child-expected.txt:
* platform/win/fast/repaint/selection-ruby-rl-expected.txt:
* platform/win/fast/repaint/text-selection-overflow-hidden-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (291788 => 291789)


--- trunk/LayoutTests/ChangeLog	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/ChangeLog	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,3 +1,54 @@
+2021-11-02  Sergio Villar Senin  <svil...@igalia.com>
+
+        Release assert in Document::updateLayout() via HTMLTextAreaElement::childrenChanged
+        https://bugs.webkit.org/show_bug.cgi?id=224471
+
+        Reviewed by Ryosuke Niwa.
+
+        Moved some tests out of the text-based-repaint.js model because selection is now updated
+        and revealed asynchronously in the case of non-user triggered changes. The problem is that
+        by the time the repaint rects are queried the update has not happened yet. That's why
+        the tests were modified so that we wait until the repaint happens.
+
+        Same situation for other tests that do not involve repaint rects but trigger accesibility
+        tree updates. We must ensure that we let the notification be thrown before checking whether or
+        not has been emited. As it's done asynchronously we must let the main thread run before checking.
+
+        Last but not least, some of the tests are using setTimeout() instead of requestAnimationFrame()
+        because the results with the latter were not as reliable under stress/debug conditions.
+
+        * accessibility/mac/selection-boundary-userinfo.html:
+        * accessibility/mac/selection-change-userinfo.html:
+        * accessibility/mac/selection-value-changes-for-aria-textbox.html:
+        * editing/selection-with-absolute-positioned-empty-content.html:
+        * fast/forms/textarea-scrolled-endline-caret.html:
+        * fast/repaint/selection-gap-absolute-child-expected.txt:
+        * fast/repaint/selection-gap-absolute-child.html:
+        * fast/repaint/selection-gap-flipped-absolute-child-expected.txt:
+        * fast/repaint/selection-gap-flipped-absolute-child.html:
+        * fast/repaint/selection-gap-transformed-absolute-child-expected.txt:
+        * fast/repaint/selection-gap-transformed-absolute-child.html:
+        * fast/repaint/selection-gap-transformed-fixed-child-expected.txt:
+        * fast/repaint/selection-gap-transformed-fixed-child.html:
+        * fast/repaint/selection-paint-invalidation-expected.txt:
+        * fast/repaint/selection-ruby-rl-expected.txt:
+        * fast/repaint/selection-ruby-rl.html:
+        * fast/repaint/text-selection-overflow-hidden-expected.txt:
+        * fast/repaint/text-selection-overflow-hidden.html:
+        * platform/gtk/TestExpectations:
+        * platform/gtk/fast/repaint/selection-ruby-rl-expected.txt: Copied from LayoutTests/fast/repaint/selection-ruby-rl-expected.txt.
+        * platform/gtk/fast/repaint/text-selection-overflow-hidden-expected.txt:
+        * platform/mac-catalina-wk1/fast/repaint/focus-setting-selection-syncronizing-not-clearing-expected.txt: Added.
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac-wk1/fast/repaint/4776765-expected.txt: Added.
+        * platform/mac-wk1/accessibility/mac/focus-setting-selection-syncronizing-not-clearing-expected.txt: Added.
+        * platform/mac-wk1/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-005-expected.txt:
+        * platform/mac/TestExpectations:
+        * platform/win/fast/repaint/4776765-expected.txt: Added.
+        * platform/win/fast/repaint/selection-gap-fixed-child-expected.txt:
+        * platform/win/fast/repaint/selection-ruby-rl-expected.txt:
+        * platform/win/fast/repaint/text-selection-overflow-hidden-expected.txt:
+
 2022-03-23  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [iOS] Mail compose web view no longer scrolls to reveal selection upon showing the keyboard

Modified: trunk/LayoutTests/accessibility/mac/selection-boundary-userinfo.html (291788 => 291789)


--- trunk/LayoutTests/accessibility/mac/selection-boundary-userinfo.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/accessibility/mac/selection-boundary-userinfo.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -162,20 +162,31 @@
         var addedNotification = webArea.addNotificationListener(notificationCallback);
         shouldBe("addedNotification", "true");
 
-        textbox = document.getElementById("textbox");
-        textbox.focus();
+        function waitForAnimationFrame() {
+            return new Promise(function(resolve, reject) {
+                requestAnimationFrame(resolve);
+            });
+        }
 
-        move(true);
+        function focusElement(elementId) {
+            element = document.getElementById(elementId);
+            element.focus();
+            return waitForAnimationFrame();
+        }
 
-        textbox = document.getElementById("input");
-        textbox.focus();
+        function moveAsync(isVertical) {
+            move(isVertical);
+            return waitForAnimationFrame();
+        }
 
-        move(false);
-
-        textbox = document.getElementById("textarea");
-        textbox.focus();
-
-        move(true);
+        (async function () {
+            await focusElement("textbox");
+            await moveAsync(true);
+            await focusElement("input");
+            await moveAsync(false);
+            await focusElement("textarea");
+            await moveAsync(true);
+        })();
     }
 
 </script>

Modified: trunk/LayoutTests/accessibility/mac/selection-change-userinfo.html (291788 => 291789)


--- trunk/LayoutTests/accessibility/mac/selection-change-userinfo.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/accessibility/mac/selection-change-userinfo.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -195,19 +195,87 @@
         shouldBe("addedNotification", "true");
 
         textbox = document.getElementById("textbox");
-        textbox.focus();
 
         // Trigger selection changes.
         var s = window.getSelection();
-        s.setPosition(textbox, 0);
-        for (var i in gran) {
-            s.modify("move", "forward", gran[i]);
-            s.modify("move", "backward", gran[i]);
+
+        function focusTextBox() {
+            return new Promise(function(resolve, reject) {
+                setTimeout(() => {
+                    textbox.focus();
+                    resolve();
+                }, 0);
+            });
         }
-        for (var i in gran) {
-            s.setPosition(textbox, 0);
-            s.modify("extend", "forward", gran[i]);
+
+        function moveSelection(direction, granularity) {
+            return new Promise(function(resolve, reject) {
+                setTimeout(function() {
+                    s.modify("move", direction, granularity);
+                    resolve();
+                }, 0);
+            });
         }
+
+        function extendSelection(granularity) {
+            return new Promise(function(resolve, reject) {
+                setTimeout(function() {
+                    s.modify("extend", "forward", granularity);
+                    resolve();
+                }, 0);
+            });
+        }
+
+        function resetPosition() {
+            return new Promise(function(resolve, reject) {
+                setTimeout(function() {
+                    s = window.getSelection();
+                    s.setPosition(textbox, 0);
+                    resolve();
+                }, 0);
+            });
+        }
+
+        (async function() {
+            await focusTextBox();
+            await resetPosition();
+            await moveSelection("forward", gran[0]);
+            await moveSelection("backward", gran[0]);
+            await moveSelection("forward", gran[1]);
+            await moveSelection("backward", gran[1]);
+            await moveSelection("forward", gran[2]);
+            await moveSelection("backward", gran[2]);
+            await moveSelection("forward", gran[3]);
+            await moveSelection("backward", gran[3]);
+            await moveSelection("forward", gran[4]);
+            await moveSelection("backward", gran[4]);
+            await moveSelection("forward", gran[5]);
+            await moveSelection("backward", gran[5]);
+            await moveSelection("forward", gran[6]);
+            await moveSelection("backward", gran[6]);
+            await moveSelection("forward", gran[7]);
+            await moveSelection("backward", gran[7]);
+            await moveSelection("forward", gran[8]);
+            await moveSelection("backward", gran[8]);
+            await resetPosition();
+            await extendSelection(gran[0]);
+            await resetPosition();
+            await extendSelection(gran[1]);
+            await resetPosition();
+            await extendSelection(gran[2]);
+            await resetPosition();
+            await extendSelection(gran[3]);
+            await resetPosition();
+            await extendSelection(gran[4]);
+            await resetPosition();
+            await extendSelection(gran[5]);
+            await resetPosition();
+            await extendSelection(gran[6]);
+            await resetPosition();
+            await extendSelection(gran[7]);
+            await resetPosition();
+            await extendSelection(gran[8]);
+          })();
     }
 
 </script>

Modified: trunk/LayoutTests/accessibility/mac/selection-value-changes-for-aria-textbox.html (291788 => 291789)


--- trunk/LayoutTests/accessibility/mac/selection-value-changes-for-aria-textbox.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/accessibility/mac/selection-value-changes-for-aria-textbox.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -43,12 +43,17 @@
         // Trigger selection changes.
         var s = window.getSelection();
         s.setPosition(textbox, 0);
-        for (var k = 0; k < 3; k++) {
+        requestAnimationFrame(() => {
             s.modify("move", "forward", "character");
-        }
-
-        // Trigger value change.
-        document.execCommand("InsertText", false, "hello ");
+            requestAnimationFrame(() => {
+                s.modify("move", "forward", "character");
+                requestAnimationFrame(() => {
+                    s.modify("move", "forward", "character");
+                    // Trigger value change.
+                    document.execCommand("InsertText", false, "hello ");
+                });
+            });
+        });
     }
 
 </script>

Modified: trunk/LayoutTests/editing/selection-with-absolute-positioned-empty-content.html (291788 => 291789)


--- trunk/LayoutTests/editing/selection-with-absolute-positioned-empty-content.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/editing/selection-with-absolute-positioned-empty-content.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -14,13 +14,17 @@
 <script>
 if (window.internals)
   internals.startTrackingRepaints();
-if (window.testRunner)
+if (window.testRunner) {
   testRunner.dumpAsText();
-
+  testRunner.waitUntilDone();
+}
 window.getSelection().selectAllChildren(foobar);
-
-if (window.internals) {
-  result.innerText = internals.repaintRectsAsText();
-  internals.stopTrackingRepaints();
-}
-</script>
\ No newline at end of file
+setTimeout(() => {
+  if (window.internals) {
+    result.innerText = internals.repaintRectsAsText();
+    internals.stopTrackingRepaints();
+  }
+  if (window.testRunner)
+  testRunner.notifyDone();
+}, 0);
+</script>

Modified: trunk/LayoutTests/fast/forms/textarea-scrolled-endline-caret.html (291788 => 291789)


--- trunk/LayoutTests/fast/forms/textarea-scrolled-endline-caret.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/forms/textarea-scrolled-endline-caret.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -15,13 +15,17 @@
     ta.focus();
     // click
     if (window.eventSender) {
-        eventSender.mouseMoveTo(90, 20);
-        eventSender.mouseDown();
-        eventSender.mouseUp();
-        if (ta.selectionEnd == 17)
-            res.innerHTML = "Test Succeeded";
-        else
-            res.innerHTML = "Test Failed: caret is at " + ta.selectionEnd;
+        testRunner.waitUntilDone();
+        requestAnimationFrame(() => {
+            eventSender.mouseMoveTo(90, 20);
+            eventSender.mouseDown();
+            eventSender.mouseUp();
+            if (ta.selectionEnd == 17)
+                res.innerHTML = "Test Succeeded";
+            else
+                res.innerHTML = "Test Failed: caret is at " + ta.selectionEnd;
+            testRunner.notifyDone();
+        });
     } else {
         res.innerHTML = "Test can't run without event sender (part of DumpRenderTree). "
             + "To test manually, click at the middle of the line marked 9 and check that the caret appears after the 9.";

Modified: trunk/LayoutTests/fast/repaint/selection-gap-absolute-child-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-absolute-child-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-absolute-child-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2,7 +2,4 @@
 This tests that absolute elements are invalidated correctly. The box will be competely green if the selected area was invalidated correctly.
 
 
-(repaint rects
-  (rect 0 0 100 100)
-)
-
+(repaint rects (rect 0 0 100 100) )

Modified: trunk/LayoutTests/fast/repaint/selection-gap-absolute-child.html (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-absolute-child.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-absolute-child.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,11 +1,27 @@
 <!doctype html>
 <head>
-    <script src=""
     <script>
-    function repaintTest()
+    if (window.testRunner) {
+        testRunner.dumpAsText(false);
+        testRunner.waitUntilDone();
+    }
+    function runRepaintTest()
     {
+        if (window.internals)
+            internals.startTrackingRepaints();
+
         var target = document.getElementById("target");
         getSelection().setBaseAndExtent(target, 0, target.nextSibling, 0);
+
+        setTimeout(function() {
+            if (window.internals) {
+                document.querySelector('#repaints').innerHTML = window.internals.repaintRectsAsText();
+                internals.stopTrackingRepaints();
+            }
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
     }
     </script>
     <style>
@@ -21,4 +37,5 @@
     <div>
         <div id="target" style="background-color: red; width: 100px; height: 100px; position: absolute;"><br/></div><br/>
     </div>
+    <div id="repaints"></div>
 </body>

Modified: trunk/LayoutTests/fast/repaint/selection-gap-flipped-absolute-child-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-flipped-absolute-child-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-flipped-absolute-child-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2,7 +2,4 @@
 This tests that absolute elements that get flipped are invalidated correctly. The box will be competely green if the selected area was invalidated correctly.
 
 
-(repaint rects
-  (rect 0 0 100 100)
-)
-
+(repaint rects (rect 0 0 100 100) )

Modified: trunk/LayoutTests/fast/repaint/selection-gap-flipped-absolute-child.html (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-flipped-absolute-child.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-flipped-absolute-child.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,11 +1,28 @@
 <!doctype html>
 <head>
-    <script src=""
     <script>
-    function repaintTest()
+    if (window.testRunner) {
+        testRunner.dumpAsText(false);
+        testRunner.waitUntilDone();
+    }
+    function runRepaintTest()
     {
+        if (window.internals)
+            internals.startTrackingRepaints();
+
         var target = document.getElementById("target");
         getSelection().setBaseAndExtent(target, 0, target.nextSibling, 0);
+
+        // requestAnimationFrame produces flacky results.
+        setTimeout(function() {
+            if (window.internals) {
+                document.querySelector('#repaints').innerHTML = window.internals.repaintRectsAsText();
+                internals.stopTrackingRepaints();
+            }
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
     }
     </script>
     <style>
@@ -21,4 +38,5 @@
     <div style="-webkit-writing-mode: vertical-rl">
         <div id="target" style="background-color: red; width: 100px; height: 100px; position: absolute;"><br/></div><br/>
     </div>
+    <div id="repaints"></div>
 </body>

Modified: trunk/LayoutTests/fast/repaint/selection-gap-transformed-absolute-child-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-transformed-absolute-child-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-transformed-absolute-child-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2,7 +2,4 @@
 This tests that absolute elements that get transformed are invalidated correctly. The box will be completely green if the selected area was invalidated correctly.
 
 
-(repaint rects
-  (rect 50 50 100 100)
-)
-
+(repaint rects (rect 50 50 100 100) )

Modified: trunk/LayoutTests/fast/repaint/selection-gap-transformed-absolute-child.html (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-transformed-absolute-child.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-transformed-absolute-child.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,11 +1,28 @@
 <!doctype html>
 <head>
-    <script src=""
     <script>
-    function repaintTest()
+    if (window.testRunner) {
+        testRunner.dumpAsText(false);
+        testRunner.waitUntilDone();
+    }
+    function runRepaintTest()
     {
+        if (window.internals)
+            internals.startTrackingRepaints();
+
         var target = document.getElementById("target");
         getSelection().setBaseAndExtent(target, 0, target.nextSibling, 0);
+
+        // requestAnimationFrame produces flacky results.
+        setTimeout(function() {
+            if (window.internals) {
+                document.querySelector('#repaints').innerHTML = window.internals.repaintRectsAsText();
+                internals.stopTrackingRepaints();
+            }
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
     }
     </script>
     <style>
@@ -21,4 +38,5 @@
     <div style="-webkit-transform: translate(50px, 50px);">
         <div id="target" style="background-color: red; width: 100px; height: 100px; position: absolute;"><br/></div><br/>
     </div>
+    <div id="repaints"></div>
 </body>

Modified: trunk/LayoutTests/fast/repaint/selection-gap-transformed-fixed-child-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-transformed-fixed-child-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-transformed-fixed-child-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2,7 +2,4 @@
 This tests that fixed elements that get transformed are invalidated correctly. The box will be competely green if the selected area was invalidated correctly.
 
 
-(repaint rects
-  (rect 50 50 100 100)
-)
-
+(repaint rects (rect 50 50 100 100) )

Modified: trunk/LayoutTests/fast/repaint/selection-gap-transformed-fixed-child.html (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-gap-transformed-fixed-child.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-gap-transformed-fixed-child.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,11 +1,28 @@
 <!doctype html>
 <head>
-    <script src=""
     <script>
-    function repaintTest()
+    if (window.testRunner) {
+        testRunner.dumpAsText(false);
+        testRunner.waitUntilDone();
+    }
+    function runRepaintTest()
     {
+        if (window.internals)
+            internals.startTrackingRepaints();
+
         var target = document.getElementById("target");
         getSelection().setBaseAndExtent(target, 0, target.nextSibling, 0);
+
+        // requestAnimationFrame produces flacky results.
+        setTimeout(function() {
+            if (window.internals) {
+                document.querySelector('#repaints').innerHTML = window.internals.repaintRectsAsText();
+                internals.stopTrackingRepaints();
+            }
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
     }
     </script>
     <style>
@@ -21,4 +38,5 @@
     <div style="-webkit-transform: translate(50px, 50px);">
         <div id="target" style="background-color: red; width: 100px; height: 100px; position: fixed;"><br/></div><br/>
     </div>
+    <div id="repaints"></div>
 </body>

Modified: trunk/LayoutTests/fast/repaint/selection-paint-invalidation-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-paint-invalidation-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-paint-invalidation-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2,6 +2,5 @@
 A
 (repaint rects
   (rect 8 68 20 100)
-  (rect 8 68 20 100)
 )
 

Modified: trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -8,7 +8,4 @@
 Testing both hit testing and painting of selection.
 Testing both hit testing and painting of selection.
 Testing both hit testing and painting of selection.
-(repaint rects
-  (rect 774 38 18 79)
-)
-
+(repaint rects (rect 774 38 18 79) )

Modified: trunk/LayoutTests/fast/repaint/selection-ruby-rl.html (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/selection-ruby-rl.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/selection-ruby-rl.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -3,7 +3,15 @@
 <head>
 <script src=""
 <script>
-function repaintTest() {
+if (window.testRunner) {
+    testRunner.dumpAsText(false);
+    testRunner.waitUntilDone();
+}
+
+function runRepaintTest() {
+    if (window.internals)
+        internals.startTrackingRepaints();
+
     if (eventSender) {
         eventSender.mouseMoveTo(790, 40);
         eventSender.mouseDown();
@@ -11,6 +19,17 @@
         eventSender.mouseMoveTo(790, 120);
         eventSender.mouseUp();
     }
+
+    // requestAnimationFrame produces flacky results.
+    setTimeout(function() {
+        if (window.internals) {
+            document.querySelector('#repaints').innerHTML = window.internals.repaintRectsAsText();
+            internals.stopTrackingRepaints();
+        }
+
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }, 0);
 }
 </script>
 
@@ -26,4 +45,5 @@
 Testing both hit testing and painting of selection.<br>
 Testing both hit testing and painting of selection.<br>
 Testing both hit testing and painting of selection.<br>
+<div id="repaints"></div>
 </body>

Modified: trunk/LayoutTests/fast/repaint/text-selection-overflow-hidden-expected.txt (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/text-selection-overflow-hidden-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/text-selection-overflow-hidden-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,6 +1,3 @@
 Should have green background
 
-(repaint rects
-  (rect 8 16 199 18)
-)
-
+(repaint rects (rect 8 16 199 18) )

Modified: trunk/LayoutTests/fast/repaint/text-selection-overflow-hidden.html (291788 => 291789)


--- trunk/LayoutTests/fast/repaint/text-selection-overflow-hidden.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/repaint/text-selection-overflow-hidden.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,5 +1,4 @@
 <!DOCTYPE html>
-<script src="" type="text/_javascript_"></script>
 <style>
 #test {
     background-color: red;
@@ -12,11 +11,30 @@
 }
 </style>
 <script>
-    function repaintTest() {
+    if (window.testRunner) {
+        testRunner.dumpAsText(false);
+        testRunner.waitUntilDone();
+    }
+
+    function runRepaintTest() {
+        if (window.internals)
+            internals.startTrackingRepaints();
+
         getSelection().setBaseAndExtent(test, 0, test, 1);
+
+        setTimeout(function() {
+            if (window.internals) {
+                document.querySelector('#repaints').innerHTML = window.internals.repaintRectsAsText();
+                internals.stopTrackingRepaints();
+            }
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }, 0);
     };
 </script>
 
 <body _onload_="runRepaintTest()">
     <p id="test">Should have green background</p>
+    <div id="repaints"></div>
 </body>

Modified: trunk/LayoutTests/fast/text/incorrect-deselection-across-multiple-elements.html (291788 => 291789)


--- trunk/LayoutTests/fast/text/incorrect-deselection-across-multiple-elements.html	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/fast/text/incorrect-deselection-across-multiple-elements.html	2022-03-24 08:33:41 UTC (rev 291789)
@@ -20,11 +20,13 @@
   if (window.internals)
     internals.startTrackingRepaints();
   window.getSelection().selectAllChildren(second);
-  if (window.internals) {
-    result.innerText = internals.repaintRectsAsText().indexOf("784 70") == -1 ? "FAIL" : "PASS";
-    internals.stopTrackingRepaints();
-  }
-  if (window.testRunner)
-    testRunner.notifyDone();
+  setTimeout(function() {
+    if (window.internals) {
+      result.innerText = internals.repaintRectsAsText().indexOf("784 70") == -1 ? "FAIL" : "PASS";
+      internals.stopTrackingRepaints();
+    }
+    if (window.testRunner)
+      testRunner.notifyDone();
+  }, 0);
 }, 0);
 </script>
\ No newline at end of file

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (291788 => 291789)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1532,8 +1532,6 @@
 # Incomplete implementation of eventSender causes this test to fail
 webkit.org/b/42194 fast/scrolling/scroll-select-list.html [ ImageOnlyFailure ]
 
-webkit.org/b/139354 fast/repaint/selection-ruby-rl.html [ Failure ]
-
 # Missing glyph symbol is not rendered properly.
 webkit.org/b/140252 fast/css/line-height-determined-by-primary-font.html [ Failure ]
 webkit.org/b/140252 fast/text/decorations-with-text-combine.html [ Failure ]

Copied: trunk/LayoutTests/platform/gtk/fast/repaint/selection-ruby-rl-expected.txt (from rev 291788, trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt) (0 => 291789)


--- trunk/LayoutTests/platform/gtk/fast/repaint/selection-ruby-rl-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/gtk/fast/repaint/selection-ruby-rl-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -0,0 +1,11 @@
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.Some ruby
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+(repaint rects (rect 775 37 17 84) )

Modified: trunk/LayoutTests/platform/gtk/fast/repaint/text-selection-overflow-hidden-expected.txt (291788 => 291789)


--- trunk/LayoutTests/platform/gtk/fast/repaint/text-selection-overflow-hidden-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/gtk/fast/repaint/text-selection-overflow-hidden-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,6 +1,3 @@
 Should have green background
 
-(repaint rects
-  (rect 8 16 197 17)
-)
-
+(repaint rects (rect 8 16 197 17) )

Modified: trunk/LayoutTests/platform/mac/TestExpectations (291788 => 291789)


--- trunk/LayoutTests/platform/mac/TestExpectations	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2410,3 +2410,4 @@
 
 webkit.org/b/237166 [ BigSur+ ] webgl/pending/conformance/textures/misc/tex-image-video-repeated.html [ Pass Timeout ]
 
+webkit.org/b/231298 accessibility/mac/selection-sync.html [ Skip ] # Timeout

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (291788 => 291789)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1804,4 +1804,7 @@
 imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_pointercapture_in_frame.html [ Pass Failure ]
 imported/w3c/web-platform-tests/pointerevents/pointerevent_pointercapture-in-custom-element.html [ Pass Failure ]
 
-webkit.org/b/236128 imported/w3c/web-platform-tests/html/user-activation/activation-trigger-mouse-right.html [ Skip ]
\ No newline at end of file
+webkit.org/b/236128 imported/w3c/web-platform-tests/html/user-activation/activation-trigger-mouse-right.html [ Skip ]
+
+webkit.org/b/231298 accessibility/mac/selection-boundary-userinfo.html [ Failure ]
+webkit.org/b/232630 fast/forms/autofocus-opera-003.html [ Failure ]

Added: trunk/LayoutTests/platform/mac-wk1/accessibility/mac/focus-setting-selection-syncronizing-not-clearing-expected.txt (0 => 291789)


--- trunk/LayoutTests/platform/mac-wk1/accessibility/mac/focus-setting-selection-syncronizing-not-clearing-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk1/accessibility/mac/focus-setting-selection-syncronizing-not-clearing-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -0,0 +1,17 @@
+
+ 1
+ 2
+This tests that calling focus on a render object when it doesn't result in a selection change won't leave isSynchronizingSelection set to true.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS addedNotification is true
+PASS accessibilityController.focusedElement.isEqual(accessibilityController.accessibleElementById("1")) is true
+PASS axTextStateSyncOne is undefined
+PASS accessibilityController.accessibleElementById("1").isFocusable is true
+PASS axTextStateSyncTwo is undefined
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/platform/mac-wk1/accessibility/mac/focus-setting-selection-syncronizing-not-clearing-expected.txt
___________________________________________________________________

Added: svn:eol-style

+LF \ No newline at end of property

Added: trunk/LayoutTests/platform/mac-wk1/fast/repaint/4776765-expected.txt (0 => 291789)


--- trunk/LayoutTests/platform/mac-wk1/fast/repaint/4776765-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk1/fast/repaint/4776765-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -0,0 +1,14 @@
+
+
+
+(repaint rects
+  (rect 1 19 15 32)
+  (rect 8 26 1 18)
+  (rect 1 19 15 32)
+  (rect 8 26 1 18)
+  (rect 1 37 798 32)
+  (rect 8 44 784 18)
+  (rect 1 51 798 18)
+  (rect 1 44 798 7)
+)
+
Property changes on: trunk/LayoutTests/platform/mac-wk1/fast/repaint/4776765-expected.txt
___________________________________________________________________

Added: svn:eol-style

+LF \ No newline at end of property

Modified: trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-005-expected.txt (291788 => 291789)


--- trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-005-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-margin-005-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,4 +1,4 @@
 
 
-FAIL scroll-margin on input widget assert_between_exclusive: Should honor date input scroll-margin expected a number greater than 4750 and less than 4850 but got 4720
+FAIL scroll-margin on input widget assert_between_exclusive: Should honor date input scroll-margin expected a number greater than 4750 and less than 4850 but got 9439
 

Added: trunk/LayoutTests/platform/win/fast/repaint/4776765-expected.txt (0 => 291789)


--- trunk/LayoutTests/platform/win/fast/repaint/4776765-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/win/fast/repaint/4776765-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -0,0 +1,10 @@
+
+
+
+(repaint rects
+  (rect 1 37 798 32)
+  (rect 8 44 784 18)
+  (rect 1 51 798 18)
+  (rect 1 44 798 7)
+)
+
Property changes on: trunk/LayoutTests/platform/win/fast/repaint/4776765-expected.txt
___________________________________________________________________

Added: svn:eol-style

+LF \ No newline at end of property

Modified: trunk/LayoutTests/platform/win/fast/repaint/selection-gap-fixed-child-expected.txt (291788 => 291789)


--- trunk/LayoutTests/platform/win/fast/repaint/selection-gap-fixed-child-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/win/fast/repaint/selection-gap-fixed-child-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -2,7 +2,4 @@
 This tests that fixed elements are invalidated correctly. The box will be competely green if the selected area was invalidated correctly.
 
 
-(repaint rects
-  (rect 0 0 100 100)
-)
 

Modified: trunk/LayoutTests/platform/win/fast/repaint/selection-ruby-rl-expected.txt (291788 => 291789)


--- trunk/LayoutTests/platform/win/fast/repaint/selection-ruby-rl-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/win/fast/repaint/selection-ruby-rl-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -8,7 +8,4 @@
 Testing both hit testing and painting of selection.
 Testing both hit testing and painting of selection.
 Testing both hit testing and painting of selection.
-(repaint rects
-  (rect 774 39 18 83)
-)
-
+(repaint rects (rect 774 39 18 83) )

Modified: trunk/LayoutTests/platform/win/fast/repaint/text-selection-overflow-hidden-expected.txt (291788 => 291789)


--- trunk/LayoutTests/platform/win/fast/repaint/text-selection-overflow-hidden-expected.txt	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/LayoutTests/platform/win/fast/repaint/text-selection-overflow-hidden-expected.txt	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,6 +1,3 @@
 Should have green background
 
-(repaint rects
-  (rect 8 16 197 18)
-)
-
+(repaint rects (rect 8 16 197 18) )

Modified: trunk/Source/WebCore/ChangeLog (291788 => 291789)


--- trunk/Source/WebCore/ChangeLog	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/ChangeLog	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1,3 +1,52 @@
+2022-03-09  Sergio Villar Senin  <svil...@igalia.com>
+
+        Release assert in Document::updateLayout() via HTMLTextAreaElement::childrenChanged
+        https://bugs.webkit.org/show_bug.cgi?id=224471
+
+        Reviewed by Ryosuke Niwa.
+
+        Executing some editing commands in a text area might force the recomputation of things
+        like caret or the visible selection position and extent. Under some circumstances (like
+        when the text area has no content and children) we might end up trying to update layout
+        when it is not safe as a side effect of updating the caret.
+
+        In order to fix that, we can switch to a model in which we update the selection asynchronously
+        in the case of having a non-user triggered change. That way we don't do it inside
+        a restricted layout scope.
+
+        The App Highlight restoration code had to be tuned as well (when restoring and scrolling to reveal
+        a Quick Note on iOS MacOS). It uses TemporarySelectionChange to select and scroll to reveal the highlight
+        range; the code assumed that this scrolling happens synchronously, since it reverts the selection to
+        the original range at the end of `AppHighlightStorage::attemptToRestoreHighlightAndScroll` when the
+        TemporarySelectionChange falls out of scope. That is however no longer the case. Actually no scrolling
+        happened after this patch because we end up only scheduling the appearance update timer before setting
+        the selection back to the original state with `SelectionRevealMode::DoNotReveal`. Since this only happens
+        when the user interacts in the Notes app, it seems sensible to consider it as a user triggered event.
+
+        * Modules/highlight/AppHighlightStorage.cpp:
+        (WebCore::AppHighlightStorage::attemptToRestoreHighlightAndScroll): Consider the selection change
+        as user triggered so scrolling actually happens.
+        * editing/Editor.cpp:
+        (WebCore::TemporarySelectionChange::setSelection): Check the UserTriggered flags for default options.
+        * editing/Editor.h: Added a new UserTriggered flag.
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setSelection): Call scheduleAppearanceUpdateAfterStyleChange() for
+        !IsUserTriggered changes.
+        (WebCore::FrameSelection::updateSelectionAppearanceNow): Renamed from updateSelectionByUpdatingLayoutOrStyle.
+        It does not need the Document& attribute because it was always called with m_document.
+        (WebCore::FrameSelection::absoluteCaretBounds): Replaced updateSelectionByUpdatingLayoutOrStyle with
+        updateSelectionAppearanceNow().
+        (WebCore::FrameSelection::setCaretVisibility): Ditto.
+        (WebCore::FrameSelection::selectionBounds const): Ditto.
+        (WebCore::FrameSelection::revealSelection): Call updateSelectionAppearanceNow().
+         (WebCore::FrameSelection::updateAppearanceIfRevealingSelectionIsNeeded): New method.
+        (WebCore::updateSelectionByUpdatingLayoutOrStyle): Deleted.
+        * editing/FrameSelection.h:
+        * page/EventHandler.cpp:
+        (WebCore::setSelectionIfNeeded): Set the UserTriggered flag for calling setSelection().
+        * page/Page.cpp:
+        (WebCore::Page::doAfterUpdateRendering): Call updateAppearanceAfterLayout().
+
 2022-03-23  Rob Buis  <rb...@igalia.com>
 
         setNeedsLayout() should not be called when changing the SVG properties

Modified: trunk/Source/WebCore/Modules/highlight/AppHighlightStorage.cpp (291788 => 291789)


--- trunk/Source/WebCore/Modules/highlight/AppHighlightStorage.cpp	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/Modules/highlight/AppHighlightStorage.cpp	2022-03-24 08:33:41 UTC (rev 291789)
@@ -272,7 +272,7 @@
         if (textIndicator)
             m_document->page()->chrome().client().setTextIndicator(textIndicator->data());
 
-        TemporarySelectionChange selectionChange(*strongDocument, { range.value() }, { TemporarySelectionOption::DelegateMainFrameScroll, TemporarySelectionOption::SmoothScroll, TemporarySelectionOption::RevealSelectionBounds });
+        TemporarySelectionChange selectionChange(*strongDocument, { *range }, { TemporarySelectionOption::DelegateMainFrameScroll, TemporarySelectionOption::SmoothScroll, TemporarySelectionOption::RevealSelectionBounds, TemporarySelectionOption::UserTriggered });
     }
 
     return true;

Modified: trunk/Source/WebCore/editing/Editor.cpp (291788 => 291789)


--- trunk/Source/WebCore/editing/Editor.cpp	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/editing/Editor.cpp	2022-03-24 08:33:41 UTC (rev 291789)
@@ -252,7 +252,7 @@
 
 void TemporarySelectionChange::setSelection(const VisibleSelection& selection, IsTemporarySelection isTemporarySelection)
 {
-    auto options = FrameSelection::defaultSetSelectionOptions();
+    auto options = FrameSelection::defaultSetSelectionOptions(m_options.contains(TemporarySelectionOption::UserTriggered) ? UserTriggered : NotUserTriggered);
     if (m_options & TemporarySelectionOption::DoNotSetFocus)
         options.add(FrameSelection::DoNotSetFocus);
 

Modified: trunk/Source/WebCore/editing/Editor.h (291788 => 291789)


--- trunk/Source/WebCore/editing/Editor.h	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/editing/Editor.h	2022-03-24 08:33:41 UTC (rev 291789)
@@ -125,6 +125,8 @@
     DelegateMainFrameScroll = 1 << 5,
     
     RevealSelectionBounds = 1 << 6,
+
+    UserTriggered = 1 << 7,
 };
 
 class TemporarySelectionChange {

Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (291788 => 291789)


--- trunk/Source/WebCore/editing/FrameSelection.cpp	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp	2022-03-24 08:33:41 UTC (rev 291789)
@@ -454,6 +454,11 @@
     if (frameView && frameView->layoutContext().isLayoutPending())
         return;
 
+    if (!(options & IsUserTriggered)) {
+        scheduleAppearanceUpdateAfterStyleChange();
+        return;
+    }
+
     updateAndRevealSelection(intent, options.contains(SmoothScroll) ? ScrollBehavior::Smooth : ScrollBehavior::Instant, options.contains(RevealSelectionBounds) ? RevealExtentOption::DoNotRevealExtent : RevealExtentOption::RevealExtent);
 
     if (options & IsUserTriggered) {
@@ -462,13 +467,16 @@
     }
 }
 
-static void updateSelectionByUpdatingLayoutOrStyle(Document& document)
+void FrameSelection::updateSelectionAppearanceNow()
 {
+    Ref document = *m_document;
 #if ENABLE(TEXT_CARET)
-    document.updateLayoutIgnorePendingStylesheets();
+    document->updateLayoutIgnorePendingStylesheets();
 #else
-    document.updateStyleIfNeeded();
+    document->updateStyleIfNeeded();
 #endif
+    if (m_pendingSelectionUpdate)
+        updateAppearance();
 }
 
 void FrameSelection::setNeedsSelectionUpdate(RevealSelectionAfterUpdate revealMode)
@@ -1701,7 +1709,7 @@
 {
     if (!m_document)
         return IntRect();
-    updateSelectionByUpdatingLayoutOrStyle(*m_document);
+    updateSelectionAppearanceNow();
     recomputeCaretRect();
     if (insideFixed)
         *insideFixed = m_caretInsidePositionFixed;
@@ -2259,7 +2267,7 @@
 
     // FIXME: We shouldn't trigger a synchronous layout here.
     if (doAppearanceUpdate == ShouldUpdateAppearance::Yes && m_document)
-        updateSelectionByUpdatingLayoutOrStyle(*m_document);
+        updateSelectionAppearanceNow();
 
 #if ENABLE(TEXT_CARET)
     if (m_caretPaint) {
@@ -2367,7 +2375,7 @@
     if (!m_document)
         return LayoutRect();
 
-    updateSelectionByUpdatingLayoutOrStyle(*m_document);
+    const_cast<FrameSelection&>(*this).updateSelectionAppearanceNow();
     auto* renderView = m_document->renderView();
     if (!renderView)
         return LayoutRect();
@@ -2463,6 +2471,8 @@
     if (isNone())
         return;
 
+    updateSelectionAppearanceNow();
+
     LayoutRect rect;
     bool insideFixed = false;
     if (isCaret())
@@ -2534,6 +2544,13 @@
     updateAppearance();
 }
 
+void FrameSelection::updateAppearanceIfRevealingSelectionIsNeeded()
+{
+    if (!m_pendingSelectionUpdate || m_selectionRevealMode == SelectionRevealMode::DoNotReveal)
+        return;
+    updateSelectionAppearanceNow();
+}
+
 void FrameSelection::updateAppearanceAfterLayout()
 {
     m_appearanceUpdateTimer.stop();

Modified: trunk/Source/WebCore/editing/FrameSelection.h (291788 => 291789)


--- trunk/Source/WebCore/editing/FrameSelection.h	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/editing/FrameSelection.h	2022-03-24 08:33:41 UTC (rev 291789)
@@ -151,6 +151,7 @@
     WEBCORE_EXPORT void clear();
     void willBeRemovedFromFrame();
 
+    void updateAppearanceIfRevealingSelectionIsNeeded();
     void updateAppearanceAfterLayout();
     void scheduleAppearanceUpdateAfterStyleChange();
 
@@ -267,6 +268,7 @@
     void updateFromAssociatedLiveRange();
 
 private:
+    void updateSelectionAppearanceNow();
     void updateAndRevealSelection(const AXTextStateChangeIntent&, ScrollBehavior = ScrollBehavior::Instant, RevealExtentOption = RevealExtentOption::RevealExtent);
     void updateDataDetectorsForSelection();
 

Modified: trunk/Source/WebCore/page/EventHandler.cpp (291788 => 291789)


--- trunk/Source/WebCore/page/EventHandler.cpp	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2022-03-24 08:33:41 UTC (rev 291789)
@@ -443,7 +443,7 @@
 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
 {
     if (selection.selection() != newSelection && selection.shouldChangeSelection(newSelection))
-        selection.setSelection(newSelection);
+        selection.setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(UserTriggered));
 }
 
 static inline bool dispatchSelectStart(Node* node)

Modified: trunk/Source/WebCore/page/Page.cpp (291788 => 291789)


--- trunk/Source/WebCore/page/Page.cpp	2022-03-24 06:32:33 UTC (rev 291788)
+++ trunk/Source/WebCore/page/Page.cpp	2022-03-24 08:33:41 UTC (rev 291789)
@@ -1712,6 +1712,10 @@
     });
 
     forEachDocument([] (Document& document) {
+        document.selection().updateAppearanceAfterLayout();
+    });
+
+    forEachDocument([] (Document& document) {
         document.updateHighlightPositions();
     });
 #if ENABLE(APP_HIGHLIGHTS)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to