Title: [216096] trunk
Revision
216096
Author
[email protected]
Date
2017-05-02 14:29:13 -0700 (Tue, 02 May 2017)

Log Message

Defer AX cache update when text content changes until after layout is finished.
https://bugs.webkit.org/show_bug.cgi?id=171429
<rdar://problem/31885984>

Reviewed by Simon Fraser.

Source/WebCore:

When the content of the RenderText changes (even as the result of a text-transform change)
instead of updating the AX cache eagerly (and trigger layout on a half-backed render tree)
we should just defer it until after the subsequent layout is done.

Test: accessibility/crash-while-adding-text-child-with-transform.html

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::remove):
(WebCore::AXObjectCache::performDeferredCacheUpdate):
(WebCore::AXObjectCache::recomputeDeferredIsIgnored):
(WebCore::AXObjectCache::deferTextChanged):
(WebCore::AXObjectCache::performDeferredIsIgnoredChange): Deleted.
* accessibility/AXObjectCache.h:
(WebCore::AXObjectCache::deferTextChanged):
(WebCore::AXObjectCache::performDeferredCacheUpdate):
(WebCore::AXObjectCache::performDeferredIsIgnoredChange): Deleted.
* page/FrameView.cpp:
(WebCore::FrameView::performPostLayoutTasks):
* rendering/RenderText.cpp:
(WebCore::RenderText::setText):

LayoutTests:

* accessibility/crash-while-adding-text-child-with-transform-expected.txt: Added.
* accessibility/crash-while-adding-text-child-with-transform.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (216095 => 216096)


--- trunk/LayoutTests/ChangeLog	2017-05-02 21:24:58 UTC (rev 216095)
+++ trunk/LayoutTests/ChangeLog	2017-05-02 21:29:13 UTC (rev 216096)
@@ -1,3 +1,14 @@
+2017-05-02  Zalan Bujtas  <[email protected]>
+
+        Defer AX cache update when text content changes until after layout is finished.
+        https://bugs.webkit.org/show_bug.cgi?id=171429
+        <rdar://problem/31885984>
+
+        Reviewed by Simon Fraser.
+
+        * accessibility/crash-while-adding-text-child-with-transform-expected.txt: Added.
+        * accessibility/crash-while-adding-text-child-with-transform.html: Added.
+
 2017-05-02  David Kilzer  <[email protected]>
 
         check-webkit-style should keep _javascript_ test functions in sync

Added: trunk/LayoutTests/accessibility/crash-while-adding-text-child-with-transform-expected.txt (0 => 216096)


--- trunk/LayoutTests/accessibility/crash-while-adding-text-child-with-transform-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/accessibility/crash-while-adding-text-child-with-transform-expected.txt	2017-05-02 21:29:13 UTC (rev 216096)
@@ -0,0 +1,2 @@
+pass if no crash or assert.
+

Added: trunk/LayoutTests/accessibility/crash-while-adding-text-child-with-transform.html (0 => 216096)


--- trunk/LayoutTests/accessibility/crash-while-adding-text-child-with-transform.html	                        (rev 0)
+++ trunk/LayoutTests/accessibility/crash-while-adding-text-child-with-transform.html	2017-05-02 21:29:13 UTC (rev 216096)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that AX can manage text content changes while inside tree mutation.</title>
+<style>
+#foobar {
+    text-transform: lowercase;
+}
+
+#foobar::first-letter {
+	margin: 1px;
+}
+</style>
+<script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+    if (window.accessibilityController)
+        accessibilityController.accessibleElementById("foobar");
+</script>
+</head>
+<body>
+<div id=foobar>Pass if no crash or assert.</div><span aria-labeledby=foobar id=newParent></span><script>
+    newParent.appendChild(foobar);
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (216095 => 216096)


--- trunk/Source/WebCore/ChangeLog	2017-05-02 21:24:58 UTC (rev 216095)
+++ trunk/Source/WebCore/ChangeLog	2017-05-02 21:29:13 UTC (rev 216096)
@@ -1,3 +1,32 @@
+2017-05-02  Zalan Bujtas  <[email protected]>
+
+        Defer AX cache update when text content changes until after layout is finished.
+        https://bugs.webkit.org/show_bug.cgi?id=171429
+        <rdar://problem/31885984>
+
+        Reviewed by Simon Fraser.
+
+        When the content of the RenderText changes (even as the result of a text-transform change)
+        instead of updating the AX cache eagerly (and trigger layout on a half-backed render tree)
+        we should just defer it until after the subsequent layout is done. 
+
+        Test: accessibility/crash-while-adding-text-child-with-transform.html
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::remove):
+        (WebCore::AXObjectCache::performDeferredCacheUpdate):
+        (WebCore::AXObjectCache::recomputeDeferredIsIgnored):
+        (WebCore::AXObjectCache::deferTextChanged):
+        (WebCore::AXObjectCache::performDeferredIsIgnoredChange): Deleted.
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::deferTextChanged):
+        (WebCore::AXObjectCache::performDeferredCacheUpdate):
+        (WebCore::AXObjectCache::performDeferredIsIgnoredChange): Deleted.
+        * page/FrameView.cpp:
+        (WebCore::FrameView::performPostLayoutTasks):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::setText):
+
 2017-05-02  Wenson Hsieh  <[email protected]>
 
         Remove an extraneous call to dispatch_group_async in WebItemProviderPasteboard.mm

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (216095 => 216096)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2017-05-02 21:24:58 UTC (rev 216095)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2017-05-02 21:29:13 UTC (rev 216096)
@@ -711,8 +711,7 @@
     AXID axID = m_renderObjectMapping.get(renderer);
     remove(axID);
     m_renderObjectMapping.remove(renderer);
-    if (is<RenderBlock>(*renderer))
-        m_deferredIsIgnoredChangeList.remove(downcast<RenderBlock>(renderer));
+    m_deferredCacheUpdateList.remove(renderer);
 }
 
 void AXObjectCache::remove(Node* node)
@@ -2700,18 +2699,29 @@
     return axObject && axObject->isTextControl();
 }
     
-void AXObjectCache::performDeferredIsIgnoredChange()
+void AXObjectCache::performDeferredCacheUpdate()
 {
-    for (auto* renderer : m_deferredIsIgnoredChangeList)
-        recomputeIsIgnored(renderer);
-    m_deferredIsIgnoredChangeList.clear();
+    for (auto* renderer : m_deferredCacheUpdateList) {
+        if (is<RenderBlock>(*renderer))
+            recomputeIsIgnored(renderer);
+        else if (is<RenderText>(*renderer))
+            textChanged(renderer);
+        else
+            ASSERT_NOT_REACHED();
+    }
+    m_deferredCacheUpdateList.clear();
 }
 
 void AXObjectCache::recomputeDeferredIsIgnored(RenderBlock& renderer)
 {
-    m_deferredIsIgnoredChangeList.add(&renderer);
+    m_deferredCacheUpdateList.add(&renderer);
 }
 
+void AXObjectCache::deferTextChanged(RenderText& renderer)
+{
+    m_deferredCacheUpdateList.add(&renderer);
+}
+
 bool isNodeAriaVisible(Node* node)
 {
     if (!node)

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (216095 => 216096)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2017-05-02 21:24:58 UTC (rev 216095)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2017-05-02 21:29:13 UTC (rev 216096)
@@ -45,6 +45,7 @@
 class Page;
 class RenderBlock;
 class RenderObject;
+class RenderText;
 class ScrollView;
 class VisiblePosition;
 class Widget;
@@ -327,7 +328,8 @@
     static void setShouldRepostNotificationsForTests(bool value);
 #endif
     void recomputeDeferredIsIgnored(RenderBlock& renderer);
-    void performDeferredIsIgnoredChange();
+    void deferTextChanged(RenderText& renderer);
+    void performDeferredCacheUpdate();
 
 protected:
     void postPlatformNotification(AccessibilityObject*, AXNotification);
@@ -429,7 +431,7 @@
 
     AXTextStateChangeIntent m_textSelectionIntent;
     bool m_isSynchronizingSelection { false };
-    ListHashSet<RenderBlock*> m_deferredIsIgnoredChangeList;
+    ListHashSet<RenderObject*> m_deferredCacheUpdateList;
 };
 
 class AXAttributeCacheEnabler
@@ -492,7 +494,8 @@
 inline void AXObjectCache::handleAttributeChanged(const QualifiedName&, Element*) { }
 inline void AXObjectCache::recomputeIsIgnored(RenderObject*) { }
 inline void AXObjectCache::recomputeDeferredIsIgnored(RenderBlock&) { }
-inline void AXObjectCache::performDeferredIsIgnoredChange() { }
+inline void AXObjectCache::deferTextChanged(RenderText&) { }
+inline void AXObjectCache::performDeferredCacheUpdate() { }
 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
 inline void AXObjectCache::postTextStateChangeNotification(Node*, const AXTextStateChangeIntent&, const VisibleSelection&) { }
 inline void AXObjectCache::postTextStateChangeNotification(Node*, AXTextEditType, const String&, const VisiblePosition&) { }

Modified: trunk/Source/WebCore/page/FrameView.cpp (216095 => 216096)


--- trunk/Source/WebCore/page/FrameView.cpp	2017-05-02 21:24:58 UTC (rev 216095)
+++ trunk/Source/WebCore/page/FrameView.cpp	2017-05-02 21:29:13 UTC (rev 216096)
@@ -3553,7 +3553,7 @@
     updateScrollSnapState();
 
     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
-        cache->performDeferredIsIgnoredChange();
+        cache->performDeferredCacheUpdate();
 }
 
 IntSize FrameView::sizeForResizeEvent() const

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (216095 => 216096)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2017-05-02 21:24:58 UTC (rev 216095)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2017-05-02 21:29:13 UTC (rev 216096)
@@ -1281,7 +1281,7 @@
         downcast<RenderBlockFlow>(*parent()).invalidateLineLayoutPath();
     
     if (AXObjectCache* cache = document().existingAXObjectCache())
-        cache->textChanged(this);
+        cache->deferTextChanged(*this);
 }
 
 String RenderText::textWithoutConvertingBackslashToYenSymbol() const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to