- 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