Title: [216524] branches/safari-603-branch

Diff

Modified: branches/safari-603-branch/LayoutTests/ChangeLog (216523 => 216524)


--- branches/safari-603-branch/LayoutTests/ChangeLog	2017-05-09 18:05:14 UTC (rev 216523)
+++ branches/safari-603-branch/LayoutTests/ChangeLog	2017-05-09 18:05:19 UTC (rev 216524)
@@ -1,5 +1,20 @@
 2017-05-09  Matthew Hanson  <matthew_han...@apple.com>
 
+        Cherry-pick r216096. rdar://problem/31971264
+
+    2017-05-02  Zalan Bujtas  <za...@apple.com>
+
+            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-09  Matthew Hanson  <matthew_han...@apple.com>
+
         Cherry-pick r216023. rdar://problem/31971371
 
     2017-05-01  Chris Dumez  <cdu...@apple.com>

Added: branches/safari-603-branch/LayoutTests/accessibility/crash-while-adding-text-child-with-transform-expected.txt (0 => 216524)


--- branches/safari-603-branch/LayoutTests/accessibility/crash-while-adding-text-child-with-transform-expected.txt	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/accessibility/crash-while-adding-text-child-with-transform-expected.txt	2017-05-09 18:05:19 UTC (rev 216524)
@@ -0,0 +1,2 @@
+pass if no crash or assert.
+

Added: branches/safari-603-branch/LayoutTests/accessibility/crash-while-adding-text-child-with-transform.html (0 => 216524)


--- branches/safari-603-branch/LayoutTests/accessibility/crash-while-adding-text-child-with-transform.html	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/accessibility/crash-while-adding-text-child-with-transform.html	2017-05-09 18:05:19 UTC (rev 216524)
@@ -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: branches/safari-603-branch/Source/WebCore/ChangeLog (216523 => 216524)


--- branches/safari-603-branch/Source/WebCore/ChangeLog	2017-05-09 18:05:14 UTC (rev 216523)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog	2017-05-09 18:05:19 UTC (rev 216524)
@@ -1,5 +1,38 @@
 2017-05-09  Matthew Hanson  <matthew_han...@apple.com>
 
+        Cherry-pick r216096. rdar://problem/31971264
+
+    2017-05-02  Zalan Bujtas  <za...@apple.com>
+
+            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-09  Matthew Hanson  <matthew_han...@apple.com>
+
         Cherry-pick r216023. rdar://problem/31971371
 
     2017-05-01  Chris Dumez  <cdu...@apple.com>

Modified: branches/safari-603-branch/Source/WebCore/accessibility/AXObjectCache.cpp (216523 => 216524)


--- branches/safari-603-branch/Source/WebCore/accessibility/AXObjectCache.cpp	2017-05-09 18:05:14 UTC (rev 216523)
+++ branches/safari-603-branch/Source/WebCore/accessibility/AXObjectCache.cpp	2017-05-09 18:05:19 UTC (rev 216524)
@@ -708,8 +708,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)
@@ -2620,18 +2619,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: branches/safari-603-branch/Source/WebCore/accessibility/AXObjectCache.h (216523 => 216524)


--- branches/safari-603-branch/Source/WebCore/accessibility/AXObjectCache.h	2017-05-09 18:05:14 UTC (rev 216523)
+++ branches/safari-603-branch/Source/WebCore/accessibility/AXObjectCache.h	2017-05-09 18:05:19 UTC (rev 216524)
@@ -45,6 +45,7 @@
 class Page;
 class RenderBlock;
 class RenderObject;
+class RenderText;
 class ScrollView;
 class VisiblePosition;
 class Widget;
@@ -64,7 +65,7 @@
     int startIndex;
     int offset;
     int remainingOffset;
-    
+
     CharacterOffset(Node* n = nullptr, int startIndex = 0, int offset = 0, int remaining = 0)
         : node(n)
         , startIndex(startIndex)
@@ -71,7 +72,7 @@
         , offset(offset)
         , remainingOffset(remaining)
     { }
-    
+
     int remaining() const { return remainingOffset; }
     bool isNull() const { return !node; }
     bool isEqual(CharacterOffset& other) const
@@ -139,7 +140,7 @@
     WEBCORE_EXPORT AccessibilityObject* rootObject();
     // Returns the root object for a specific frame.
     WEBCORE_EXPORT AccessibilityObject* rootObjectForFrame(Frame*);
-    
+
     // For AX objects with elements that back them.
     AccessibilityObject* getOrCreate(RenderObject*);
     AccessibilityObject* getOrCreate(Widget*);
@@ -147,12 +148,12 @@
 
     // used for objects without backing elements
     AccessibilityObject* getOrCreate(AccessibilityRole);
-    
+
     // will only return the AccessibilityObject if it already exists
     AccessibilityObject* get(RenderObject*);
     AccessibilityObject* get(Widget*);
     AccessibilityObject* get(Node*);
-    
+
     void remove(RenderObject*);
     void remove(Node*);
     void remove(Widget*);
@@ -178,7 +179,7 @@
     void handleScrolledToAnchor(const Node* anchorNode);
     void handleAriaExpandedChange(Node*);
     void handleScrollbarUpdate(ScrollView*);
-    
+
     void handleAriaModalChange(Node*);
     Node* ariaModalNode();
 
@@ -191,7 +192,7 @@
 
     // Enhanced user interface accessibility can be toggled by the assistive technology.
     WEBCORE_EXPORT static void setEnhancedUserInterfaceAccessibility(bool flag);
-    
+
     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
     static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; }
 #else
@@ -218,7 +219,7 @@
     void textMarkerDataForPreviousCharacterOffset(TextMarkerData&, const CharacterOffset&);
     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
     CharacterOffset characterOffsetForTextMarkerData(TextMarkerData&);
-    // Use ignoreNextNodeStart/ignorePreviousNodeEnd to determine the behavior when we are at node boundary. 
+    // Use ignoreNextNodeStart/ignorePreviousNodeEnd to determine the behavior when we are at node boundary.
     CharacterOffset nextCharacterOffset(const CharacterOffset&, bool ignoreNextNodeStart = true);
     CharacterOffset previousCharacterOffset(const CharacterOffset&, bool ignorePreviousNodeEnd = true);
     void startOrEndTextMarkerDataForRange(TextMarkerData&, RefPtr<Range>, bool);
@@ -227,32 +228,32 @@
     RefPtr<Range> rangeForUnorderedCharacterOffsets(const CharacterOffset&, const CharacterOffset&);
     static RefPtr<Range> rangeForNodeContents(Node*);
     static int lengthForRange(Range*);
-    
+
     // Word boundary
     CharacterOffset nextWordEndCharacterOffset(const CharacterOffset&);
     CharacterOffset previousWordStartCharacterOffset(const CharacterOffset&);
     RefPtr<Range> leftWordRange(const CharacterOffset&);
     RefPtr<Range> rightWordRange(const CharacterOffset&);
-    
+
     // Paragraph
     RefPtr<Range> paragraphForCharacterOffset(const CharacterOffset&);
     CharacterOffset nextParagraphEndCharacterOffset(const CharacterOffset&);
     CharacterOffset previousParagraphStartCharacterOffset(const CharacterOffset&);
-    
+
     // Sentence
     RefPtr<Range> sentenceForCharacterOffset(const CharacterOffset&);
     CharacterOffset nextSentenceEndCharacterOffset(const CharacterOffset&);
     CharacterOffset previousSentenceStartCharacterOffset(const CharacterOffset&);
-    
+
     // Bounds
     CharacterOffset characterOffsetForPoint(const IntPoint&, AccessibilityObject*);
     IntRect absoluteCaretBoundsForCharacterOffset(const CharacterOffset&);
     CharacterOffset characterOffsetForBounds(const IntRect&, bool);
-    
+
     // Lines
     CharacterOffset endCharacterOffsetOfLine(const CharacterOffset&);
     CharacterOffset startCharacterOffsetOfLine(const CharacterOffset&);
-    
+
     // Index
     CharacterOffset characterOffsetForIndex(int, const AccessibilityObject*);
     int indexForCharacterOffset(const CharacterOffset&, AccessibilityObject*);
@@ -325,7 +326,8 @@
     static void setShouldRepostNotificationsForTests(bool value);
 #endif
     void recomputeDeferredIsIgnored(RenderBlock& renderer);
-    void performDeferredIsIgnoredChange();
+    void deferTextChanged(RenderText& renderer);
+    void performDeferredCacheUpdate();
 
 protected:
     void postPlatformNotification(AccessibilityObject*, AXNotification);
@@ -348,7 +350,7 @@
     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
-    
+
     // CharacterOffset functions.
     enum TraverseOption { TraverseOptionDefault = 1 << 0, TraverseOptionToNodeEnd = 1 << 1, TraverseOptionIncludeStart = 1 << 2, TraverseOptionValidateOffset = 1 << 3 };
     Node* nextNode(Node*) const;
@@ -391,7 +393,7 @@
     void handleMenuOpened(Node*);
     void handleLiveRegionCreated(Node*);
     void handleMenuItemSelected(Node*);
-    
+
     // aria-modal related
     void findAriaModalNodes();
     void updateCurrentAriaModalNode();
@@ -415,16 +417,16 @@
     Timer m_passwordNotificationPostTimer;
 
     ListHashSet<RefPtr<AccessibilityObject>> m_passwordNotificationsToPost;
-    
+
     Timer m_liveRegionChangedPostTimer;
     ListHashSet<RefPtr<AccessibilityObject>> m_liveRegionObjectsSet;
-    
+
     Node* m_currentAriaModalNode;
     ListHashSet<Node*> m_ariaModalNodesSet;
 
     AXTextStateChangeIntent m_textSelectionIntent;
     bool m_isSynchronizingSelection { false };
-    ListHashSet<RenderBlock*> m_deferredIsIgnoredChangeList;
+    ListHashSet<RenderObject*> m_deferredCacheUpdateList;
 };
 
 class AXAttributeCacheEnabler
@@ -442,7 +444,7 @@
 bool nodeHasRole(Node*, const String& role);
 // This will let you know if aria-hidden was explicitly set to false.
 bool isNodeAriaVisible(Node*);
-    
+
 #if !HAVE(ACCESSIBILITY)
 inline AccessibilityObjectInclusion AXComputedObjectAttributeCache::getIgnored(AXID) const { return DefaultBehavior; }
 inline AccessibilityReplacedText::AccessibilityReplacedText(const VisibleSelection&) { }
@@ -486,6 +488,8 @@
 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
 inline void AXObjectCache::handleAttributeChanged(const QualifiedName&, Element*) { }
 inline void AXObjectCache::recomputeIsIgnored(RenderObject*) { }
+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: branches/safari-603-branch/Source/WebCore/page/FrameView.cpp (216523 => 216524)


--- branches/safari-603-branch/Source/WebCore/page/FrameView.cpp	2017-05-09 18:05:14 UTC (rev 216523)
+++ branches/safari-603-branch/Source/WebCore/page/FrameView.cpp	2017-05-09 18:05:19 UTC (rev 216524)
@@ -3514,7 +3514,7 @@
     updateScrollSnapState();
 
     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
-        cache->performDeferredIsIgnoredChange();
+        cache->performDeferredCacheUpdate();
 }
 
 IntSize FrameView::sizeForResizeEvent() const

Modified: branches/safari-603-branch/Source/WebCore/rendering/RenderText.cpp (216523 => 216524)


--- branches/safari-603-branch/Source/WebCore/rendering/RenderText.cpp	2017-05-09 18:05:14 UTC (rev 216523)
+++ branches/safari-603-branch/Source/WebCore/rendering/RenderText.cpp	2017-05-09 18:05:19 UTC (rev 216524)
@@ -1243,7 +1243,7 @@
         downcast<RenderBlockFlow>(*parent()).invalidateLineLayoutPath();
     
     if (AXObjectCache* cache = document().existingAXObjectCache())
-        cache->textChanged(this);
+        cache->deferTextChanged(*this);
 }
 
 String RenderText::textWithoutConvertingBackslashToYenSymbol() const
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to