Title: [228666] releases/WebKitGTK/webkit-2.20
Revision
228666
Author
carlo...@webkit.org
Date
2018-02-19 05:17:13 -0800 (Mon, 19 Feb 2018)

Log Message

Merge r228279 - AX: Defer attribute computation until needed.
https://bugs.webkit.org/show_bug.cgi?id=182386
<rdar://problem/37115277>

Reviewed by Zalan Bujtas.

Source/WebCore:

Accessibility is doing too much work when handling attribute changes. Here's how we can improve this:
   1) Defer attribute changes while the tree is dirty (and coalesce them).
   2) Don't create AXObjects when an attribute changes unnecessarily. If no client has requested an ax object, it's likely no work needs to be done
         (with the exception of a few attributes like aria-modal)
   3) Stop calculating the entire accessible ARIA label when trying to decide if an element should be ignored. That's generally wasteful and the
         consequence of including more AX elements in the tree is very minimal.

* accessibility/AXObjectCache.cpp:
(WebCore::rendererNeedsDeferredUpdate):
(WebCore::nodeAndRendererAreValid):
(WebCore::AXObjectCache::remove):
(WebCore::AXObjectCache::handleAriaExpandedChange):
(WebCore::AXObjectCache::handleAriaRoleChanged):
(WebCore::AXObjectCache::deferAttributeChangeIfNeeded):
(WebCore::AXObjectCache::shouldProcessAttributeChange):
(WebCore::AXObjectCache::handleAttributeChange):
(WebCore::AXObjectCache::prepareForDocumentDestruction):
(WebCore::AXObjectCache::performDeferredCacheUpdate):
(WebCore::AXObjectCache::deferRecomputeIsIgnoredIfNeeded):
(WebCore::AXObjectCache::deferRecomputeIsIgnored):
(WebCore::AXObjectCache::deferTextChangedIfNeeded):
(WebCore::AXObjectCache::deferSelectedChildrenChangedIfNeeded):
(WebCore::AXObjectCache::handleAttributeChanged): Deleted.
* accessibility/AXObjectCache.h:
(WebCore::AXObjectCache::deferAttributeChangeIfNeeded):
(WebCore::AXObjectCache::handleAttributeChanged): Deleted.
* accessibility/AccessibilityNodeObject.cpp:
(WebCore::AccessibilityNodeObject::hasAttributesRequiredForInclusion const):
* accessibility/AccessibleNode.cpp:
(WebCore::AccessibleNode::notifyAttributeChanged):
* dom/Element.cpp:
(WebCore::Element::attributeChanged):

LayoutTests:

Update tests to reflect new world of delayed attribute handling for accessibility.

* accessibility/canvas-fallback-content.html:
     Make test async so attributes can be checked after deferred handling.
* accessibility/mac/aria-expanded-notifications.html:
     Access elements through AX tree so attribute changes generate notifications.
* accessibility/mac/aria-listbox-selectedchildren-change.html:
     Make test async so attributes can be checked after deferred handling.
* accessibility/mac/aria-menu-item-selected-notification.html:
     Access menu item through AX tree so attribute changes generate notifications.
* accessibility/mac/aria-modal-auto-focus.html:
     Access buttons after delay so attributes have time to be deferred.
* accessibility/mac/element-busy-changed.html:
     Process second attribute change after delay so we generate two notifications.
* accessibility/mac/expanded-notification.html:
     Set attributes after a delay so they generate individual notifications.
* accessibility/notification-listeners.html:
      Access elements through AX tree so attribute changes generate notifications.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/ChangeLog (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/ChangeLog	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/ChangeLog	2018-02-19 13:17:13 UTC (rev 228666)
@@ -1,3 +1,30 @@
+2018-02-08  Chris Fleizach  <cfleiz...@apple.com>
+
+        AX: Defer attribute computation until needed.
+        https://bugs.webkit.org/show_bug.cgi?id=182386
+        <rdar://problem/37115277>
+
+        Reviewed by Zalan Bujtas.
+
+        Update tests to reflect new world of delayed attribute handling for accessibility.
+
+        * accessibility/canvas-fallback-content.html:
+             Make test async so attributes can be checked after deferred handling.
+        * accessibility/mac/aria-expanded-notifications.html:
+             Access elements through AX tree so attribute changes generate notifications.
+        * accessibility/mac/aria-listbox-selectedchildren-change.html:
+             Make test async so attributes can be checked after deferred handling.
+        * accessibility/mac/aria-menu-item-selected-notification.html:
+             Access menu item through AX tree so attribute changes generate notifications.
+        * accessibility/mac/aria-modal-auto-focus.html:
+             Access buttons after delay so attributes have time to be deferred.
+        * accessibility/mac/element-busy-changed.html:
+             Process second attribute change after delay so we generate two notifications.
+        * accessibility/mac/expanded-notification.html:
+             Set attributes after a delay so they generate individual notifications.
+        * accessibility/notification-listeners.html:
+              Access elements through AX tree so attribute changes generate notifications.
+
 2018-02-08  Philippe Normand  <pnorm...@igalia.com>
 
         [GStreamer] LayoutTest webaudio/silent-audio-interrupted-in-background.html makes its subsequent test flaky crash

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/canvas-fallback-content.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/canvas-fallback-content.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/canvas-fallback-content.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -40,6 +40,7 @@
 description("This test makes sure that focusable elements in canvas fallback content are accessible.");
 
 if (window.testRunner && window.accessibilityController) {
+    window.jsTestIsAsync = true;
     window.testRunner.dumpAsText();
 
     function check(id, expectedRole) {
@@ -80,9 +81,15 @@
 
     // Check that the role is updated when the element changes.
     document.getElementById('focusable1').setAttribute('role', 'button');
-    check("focusable1", "AXRole: AXButton");
+    setTimeout(function() {
+        check("focusable1", "AXRole: AXButton");
+    }, 1);
+
     document.getElementById('focusable2').setAttribute('role', 'button');
-    check("focusable2", "AXRole: AXButton");
+    setTimeout(function() {
+        check("focusable2", "AXRole: AXButton");
+        finishJSTest();
+    }, 1);
 }
 
 </script>

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-expanded-notifications.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-expanded-notifications.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-expanded-notifications.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -58,6 +58,9 @@
         var addedNotification = accessibilityController.addNotificationListener(notifyCallback);
         shouldBe("addedNotification", "true");
 
+        accessibilityController.accessibleElementById("tree0");
+        accessibilityController.accessibleElementById("tree0_item0");
+
         // the first aria-expanded should generate row count, row collapsed.
         document.getElementById("tree0_item0").setAttribute("aria-expanded", "false");
 

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-listbox-selectedchildren-change.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-listbox-selectedchildren-change.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-listbox-selectedchildren-change.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -5,7 +5,7 @@
 </head>
 <body id="body">
 
-<div role="group" tabindex=0 id="listbox" role="listbox">
+<div tabindex=0 id="listbox" role="listbox">
 <div id="option1" role="option" aria-selected="true">Option</div>
 <div id="option2" role="option">Option</div>
 <div id="option3" role="option">Option</div>
@@ -35,8 +35,7 @@
     if (window.accessibilityController) {
         jsTestIsAsync = true;
 
-        document.getElementById("listbox").focus();
-        listbox = window.accessibilityController.focusedElement;
+        listbox = accessibilityController.accessibleElementById("listbox");
 
         var addedNotification = window.accessibilityController.addNotificationListener(ariaCallback);
         shouldBe("addedNotification", "true");
@@ -43,7 +42,9 @@
 
         // These should each trigger a notification that the selected children changed.
         document.getElementById("option2").setAttribute("aria-selected", "true");
-        document.getElementById("option2").setAttribute("aria-selected", "false");
+        setTimeout(function() {
+            document.getElementById("option2").setAttribute("aria-selected", "false");
+        }, 1);
     }
 
 </script>

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-menu-item-selected-notification.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-menu-item-selected-notification.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-menu-item-selected-notification.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -39,7 +39,7 @@
         window.jsTestIsAsync = true;
 
         var addedNotification = accessibilityController.addNotificationListener(ariaCallback);
-        accessibilityController.rootElement;
+        accessibilityController.accessibleElementById("menu");
 
         shouldBe("addedNotification", "true");
 

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-modal-auto-focus.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-modal-auto-focus.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/aria-modal-auto-focus.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -50,20 +50,20 @@
             
             // 2. Click the new button, dialog2 shows and focus should move to the close button.
             document.getElementById("new").click();
-            closeBtn = accessibilityController.accessibleElementById("close");
             setTimeout(function(){ 
+                closeBtn = accessibilityController.accessibleElementById("close");
                 shouldBeTrue("closeBtn.isFocused");
-                
+                  
                 // 3. Click the close button, dialog2 closes and focus should go back to the
                 // first focusable child of dialog1.
                 document.getElementById("close").click();
-                okBtn = accessibilityController.accessibleElementById("ok");
                 setTimeout(function(){
+                    okBtn = accessibilityController.accessibleElementById("ok");
                     shouldBeTrue("okBtn.isFocused");
                     finishJSTest();
-                }, 50);
-            }, 50);
-        }, 50);
+                }, 100);
+            }, 100);
+        }, 100);
     }
     
     function backgroundAccessible() {
@@ -92,4 +92,4 @@
 
 <script src=""
 </body>
-</html>
\ No newline at end of file
+</html>

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/element-busy-changed.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/element-busy-changed.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/element-busy-changed.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -33,7 +33,10 @@
         // Toggle through both busy state transitions.
         var busyElement = document.getElementById("body");
         busyElement.setAttribute("aria-busy", "true");
-        busyElement.setAttribute("aria-busy", "false");
+
+        setTimeout(function() {
+            busyElement.setAttribute("aria-busy", "false");
+        }, 1);
     }
 </script>
 

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/expanded-notification.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/expanded-notification.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/mac/expanded-notification.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -38,13 +38,13 @@
         window.jsTestIsAsync = true;
 
         var addedNotification = accessibilityController.addNotificationListener(ariaCallback);
-        debug("Initial expanded status: " + accessibilityController.accessibleElementById("button").isExpanded);
+        var button = accessibilityController.accessibleElementById("button");
+        debug("Initial expanded status: " + button.isExpanded);
 
+        document.getElementById("button").setAttribute("aria-expanded", "true");
+
         setTimeout(function() {
-            document.getElementById("button").setAttribute("aria-expanded", "true");
-            setTimeout(function() {
-                document.getElementById("button").setAttribute("aria-expanded", "false");
-            }, 10);
+            document.getElementById("button").setAttribute("aria-expanded", "false");
         }, 10);
     }
 

Modified: releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/notification-listeners.html (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/notification-listeners.html	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/LayoutTests/accessibility/notification-listeners.html	2018-02-19 13:17:13 UTC (rev 228666)
@@ -45,6 +45,10 @@
         });
     }
 
+    // Ensure these elements exist in the AX tree otherwise notifications won't be generated.
+    accessibilityController.accessibleElementById("select");
+    accessibilityController.accessibleElementById("slider");
+
     // This should trigger a "invalid status changed" notification on the select.
     document.getElementById("select").setAttribute("aria-invalid", "true");
 

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/ChangeLog	2018-02-19 13:17:13 UTC (rev 228666)
@@ -1,3 +1,44 @@
+2018-02-08  Chris Fleizach  <cfleiz...@apple.com>
+
+        AX: Defer attribute computation until needed.
+        https://bugs.webkit.org/show_bug.cgi?id=182386
+        <rdar://problem/37115277>
+
+        Reviewed by Zalan Bujtas.
+
+        Accessibility is doing too much work when handling attribute changes. Here's how we can improve this:
+           1) Defer attribute changes while the tree is dirty (and coalesce them). 
+           2) Don't create AXObjects when an attribute changes unnecessarily. If no client has requested an ax object, it's likely no work needs to be done
+                 (with the exception of a few attributes like aria-modal)
+           3) Stop calculating the entire accessible ARIA label when trying to decide if an element should be ignored. That's generally wasteful and the
+                 consequence of including more AX elements in the tree is very minimal.
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::rendererNeedsDeferredUpdate):
+        (WebCore::nodeAndRendererAreValid):
+        (WebCore::AXObjectCache::remove):
+        (WebCore::AXObjectCache::handleAriaExpandedChange):
+        (WebCore::AXObjectCache::handleAriaRoleChanged):
+        (WebCore::AXObjectCache::deferAttributeChangeIfNeeded):
+        (WebCore::AXObjectCache::shouldProcessAttributeChange):
+        (WebCore::AXObjectCache::handleAttributeChange):
+        (WebCore::AXObjectCache::prepareForDocumentDestruction):
+        (WebCore::AXObjectCache::performDeferredCacheUpdate):
+        (WebCore::AXObjectCache::deferRecomputeIsIgnoredIfNeeded):
+        (WebCore::AXObjectCache::deferRecomputeIsIgnored):
+        (WebCore::AXObjectCache::deferTextChangedIfNeeded):
+        (WebCore::AXObjectCache::deferSelectedChildrenChangedIfNeeded):
+        (WebCore::AXObjectCache::handleAttributeChanged): Deleted.
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::deferAttributeChangeIfNeeded):
+        (WebCore::AXObjectCache::handleAttributeChanged): Deleted.
+        * accessibility/AccessibilityNodeObject.cpp:
+        (WebCore::AccessibilityNodeObject::hasAttributesRequiredForInclusion const):
+        * accessibility/AccessibleNode.cpp:
+        (WebCore::AccessibleNode::notifyAttributeChanged):
+        * dom/Element.cpp:
+        (WebCore::Element::attributeChanged): 
+
 2018-02-08  Zalan Bujtas  <za...@apple.com>
 
         [RenderTreeBuilder] Move RenderElement::removeAnonymousWrappersForInlinesIfNecessary to RenderTreeBuilder

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AXObjectCache.cpp (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AXObjectCache.cpp	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AXObjectCache.cpp	2018-02-19 13:17:13 UTC (rev 228666)
@@ -120,7 +120,23 @@
 static const Seconds accessibilityPasswordValueChangeNotificationInterval { 25_ms };
 static const Seconds accessibilityLiveRegionChangedNotificationInterval { 20_ms };
 static const Seconds accessibilityFocusModalNodeNotificationInterval { 50_ms };
+    
+static bool rendererNeedsDeferredUpdate(const RenderObject& renderer)
+{
+    ASSERT(!renderer.beingDestroyed());
+    auto& document = renderer.document();
+    return renderer.needsLayout() || document.needsStyleRecalc() || document.inRenderTreeUpdate() || (document.view() && document.view()->layoutContext().isInRenderTreeLayout());
+}
 
+static bool nodeAndRendererAreValid(Node* node)
+{
+    if (!node)
+        return false;
+    
+    auto* renderer = node->renderer();
+    return renderer && !renderer->beingDestroyed();
+}
+    
 AccessibilityObjectInclusion AXComputedObjectAttributeCache::getIgnored(AXID id) const
 {
     auto it = m_idMapping.find(id);
@@ -723,6 +739,7 @@
         m_deferredRecomputeIsIgnoredList.remove(downcast<Element>(&node));
         m_deferredSelectedChildredChangedList.remove(downcast<Element>(&node));
         m_deferredTextFormControlValue.remove(downcast<Element>(&node));
+        m_deferredAttributeChange.remove(downcast<Element>(&node));
     }
     m_deferredTextChangedList.remove(&node);
     removeNodeForUse(node);
@@ -1402,7 +1419,7 @@
     
 void AXObjectCache::handleAriaExpandedChange(Node* node)
 {
-    if (AccessibilityObject* obj = getOrCreate(node))
+    if (AccessibilityObject* obj = get(node))
         obj->handleAriaExpandedChanged();
 }
     
@@ -1416,18 +1433,48 @@
 {
     stopCachingComputedObjectAttributes();
 
-    if (AccessibilityObject* obj = getOrCreate(node)) {
+    // Don't make an AX object unless it's needed
+    if (AccessibilityObject* obj = get(node)) {
         obj->updateAccessibilityRole();
         obj->notifyIfIgnoredValueChanged();
     }
 }
 
-void AXObjectCache::handleAttributeChanged(const QualifiedName& attrName, Element* element)
+void AXObjectCache::deferAttributeChangeIfNeeded(const QualifiedName& attrName, Element* element)
 {
+    if (nodeAndRendererAreValid(element) && rendererNeedsDeferredUpdate(*element->renderer()))
+        m_deferredAttributeChange.add(element, attrName);
+    else
+        handleAttributeChange(attrName, element);
+}
+    
+bool AXObjectCache::shouldProcessAttributeChange(const QualifiedName& attrName, Element* element)
+{
+    if (!element)
+        return false;
+    
+    // aria-modal ends up affecting sub-trees that are being shown/hidden so it's likely that
+    // an AT would not have accessed this node yet.
+    if (attrName == aria_modalAttr)
+        return true;
+    
+    // If an AXObject has yet to be created, then there's no need to process attribute changes.
+    // Some of these notifications are processed on the parent, so allow that to proceed as well
+    if (get(element) || get(element->parentNode()))
+        return true;
+
+    return false;
+}
+    
+void AXObjectCache::handleAttributeChange(const QualifiedName& attrName, Element* element)
+{
+    if (!shouldProcessAttributeChange(attrName, element))
+        return;
+    
     if (attrName == roleAttr)
         handleAriaRoleChanged(element);
     else if (attrName == altAttr || attrName == titleAttr)
-        deferTextChangedIfNeeded(element);
+        textChanged(element);
     else if (attrName == forAttr && is<HTMLLabelElement>(*element))
         labelChanged(element);
 
@@ -1441,7 +1488,7 @@
     else if (attrName == aria_valuenowAttr || attrName == aria_valuetextAttr)
         postNotification(element, AXObjectCache::AXValueChanged);
     else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || attrName == aria_labelledbyAttr)
-        deferTextChangedIfNeeded(element);
+        textChanged(element);
     else if (attrName == aria_checkedAttr)
         checkedStateChanged(element);
     else if (attrName == aria_selectedAttr)
@@ -2760,6 +2807,7 @@
     filterListForRemoval(m_deferredTextChangedList, document, nodesToRemove);
     filterListForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
     filterMapForRemoval(m_deferredTextFormControlValue, document, nodesToRemove);
+    filterMapForRemoval(m_deferredAttributeChange, document, nodesToRemove);
 
     for (auto* node : nodesToRemove)
         remove(*node);
@@ -2799,52 +2847,38 @@
         postTextReplacementNotificationForTextControl(textFormControlElement, deferredFormControlContext.value, textFormControlElement.innerTextValue());
     }
     m_deferredTextFormControlValue.clear();
-}
 
-static bool rendererNeedsDeferredUpdate(RenderObject& renderer)
-{
-    ASSERT(!renderer.beingDestroyed());
-    auto& document = renderer.document();
-    return renderer.needsLayout() || document.needsStyleRecalc() || document.inRenderTreeUpdate() || (document.view() && document.view()->layoutContext().isInRenderTreeLayout());
+    for (auto& deferredAttributeChangeContext : m_deferredAttributeChange)
+        handleAttributeChange(deferredAttributeChangeContext.value, deferredAttributeChangeContext.key);
+    m_deferredAttributeChange.clear();
 }
-
+    
 void AXObjectCache::deferRecomputeIsIgnoredIfNeeded(Element* element)
 {
-    if (!element)
+    if (!nodeAndRendererAreValid(element))
         return;
-
-    auto* renderer = element->renderer();
-    if (!renderer || renderer->beingDestroyed())
-        return;
-
-    if (rendererNeedsDeferredUpdate(*renderer)) {
+    
+    if (rendererNeedsDeferredUpdate(*element->renderer())) {
         m_deferredRecomputeIsIgnoredList.add(element);
         return;
     }
-    recomputeIsIgnored(renderer);
+    recomputeIsIgnored(element->renderer());
 }
 
 void AXObjectCache::deferRecomputeIsIgnored(Element* element)
 {
-    if (!element)
+    if (!nodeAndRendererAreValid(element))
         return;
 
-    if (element->renderer() && element->renderer()->beingDestroyed())
-        return;
-
     m_deferredRecomputeIsIgnoredList.add(element);
 }
 
 void AXObjectCache::deferTextChangedIfNeeded(Node* node)
 {
-    if (!node)
+    if (!nodeAndRendererAreValid(node))
         return;
 
-    auto* renderer = node->renderer();
-    if (renderer && renderer->beingDestroyed())
-        return;
-
-    if (renderer && rendererNeedsDeferredUpdate(*renderer)) {
+    if (rendererNeedsDeferredUpdate(*node->renderer())) {
         m_deferredTextChangedList.add(node);
         return;
     }
@@ -2853,11 +2887,10 @@
 
 void AXObjectCache::deferSelectedChildrenChangedIfNeeded(Element& selectElement)
 {
-    auto* renderer = selectElement.renderer();
-    if (renderer && renderer->beingDestroyed())
+    if (!nodeAndRendererAreValid(&selectElement))
         return;
-    
-    if (renderer && rendererNeedsDeferredUpdate(*renderer)) {
+
+    if (rendererNeedsDeferredUpdate(*selectElement.renderer())) {
         m_deferredSelectedChildredChangedList.add(&selectElement);
         return;
     }

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AXObjectCache.h (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AXObjectCache.h	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AXObjectCache.h	2018-02-19 13:17:13 UTC (rev 228666)
@@ -185,7 +185,7 @@
     void handleModalChange(Node*);
     Node* modalNode();
 
-    void handleAttributeChanged(const QualifiedName& attrName, Element*);
+    void deferAttributeChangeIfNeeded(const QualifiedName&, Element*);
     void recomputeIsIgnored(RenderObject* renderer);
 
 #if HAVE(ACCESSIBILITY)
@@ -409,6 +409,8 @@
     void handleMenuOpened(Node*);
     void handleLiveRegionCreated(Node*);
     void handleMenuItemSelected(Node*);
+    void handleAttributeChange(const QualifiedName&, Element*);
+    bool shouldProcessAttributeChange(const QualifiedName&, Element*);
     
     // aria-modal related
     void findModalNodes();
@@ -446,6 +448,7 @@
     ListHashSet<Node*> m_deferredTextChangedList;
     ListHashSet<Element*> m_deferredSelectedChildredChangedList;
     HashMap<Element*, String> m_deferredTextFormControlValue;
+    HashMap<Element*, QualifiedName> m_deferredAttributeChange;
     bool m_isSynchronizingSelection { false };
     bool m_performingDeferredCacheUpdate { false };
 };
@@ -507,7 +510,9 @@
 inline void AXObjectCache::handleAriaExpandedChange(Node*) { }
 inline void AXObjectCache::handleModalChange(Node*) { }
 inline void AXObjectCache::handleAriaRoleChanged(Node*) { }
-inline void AXObjectCache::handleAttributeChanged(const QualifiedName&, Element*) { }
+inline void AXObjectCache::deferAttributeChangeIfNeeded(const QualifiedName&, Element*) { }
+inline void AXObjectCache::handleAttributeChange(const QualifiedName&, Element*) { }
+inline bool AXObjectCache::shouldProcessAttributeChange(const QualifiedName&, Element*) { return false; }
 inline void AXObjectCache::handleFocusedUIElementChanged(Node*, Node*) { }
 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AccessibilityNodeObject.cpp (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AccessibilityNodeObject.cpp	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AccessibilityNodeObject.cpp	2018-02-19 13:17:13 UTC (rev 228666)
@@ -2017,7 +2017,9 @@
     if (AccessibilityObject::hasAttributesRequiredForInclusion())
         return true;
 
-    if (!ariaAccessibilityDescription().isEmpty())
+    // Avoid calculating the actual description here, which is expensive.
+    // This means there might be more accessible elements in the tree if the labelledBy points to invalid elements, but that shouldn't cause any real problems.
+    if (getAttribute(aria_labelledbyAttr).length() || getAttribute(aria_labeledbyAttr).length() || getAttribute(aria_labelAttr).length())
         return true;
 
     return false;

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AccessibleNode.cpp (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AccessibleNode.cpp	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/accessibility/AccessibleNode.cpp	2018-02-19 13:17:13 UTC (rev 228666)
@@ -379,7 +379,7 @@
 void AccessibleNode::notifyAttributeChanged(const WebCore::QualifiedName& name)
 {
     if (AXObjectCache* cache = m_ownerElement.document().axObjectCache())
-        cache->handleAttributeChanged(name, &m_ownerElement);
+        cache->deferAttributeChangeIfNeeded(name, &m_ownerElement);
 }
 
 RefPtr<AccessibleNode> AccessibleNode::activeDescendant() const

Modified: releases/WebKitGTK/webkit-2.20/Source/WebCore/dom/Element.cpp (228665 => 228666)


--- releases/WebKitGTK/webkit-2.20/Source/WebCore/dom/Element.cpp	2018-02-19 13:17:03 UTC (rev 228665)
+++ releases/WebKitGTK/webkit-2.20/Source/WebCore/dom/Element.cpp	2018-02-19 13:17:13 UTC (rev 228666)
@@ -1389,7 +1389,7 @@
     invalidateNodeListAndCollectionCachesInAncestorsForAttribute(name);
 
     if (AXObjectCache* cache = document().existingAXObjectCache())
-        cache->handleAttributeChanged(name, this);
+        cache->deferAttributeChangeIfNeeded(name, this);
 }
 
 template <typename CharacterType>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to