Title: [288674] trunk
Revision
288674
Author
tyle...@apple.com
Date
2022-01-27 08:51:29 -0800 (Thu, 27 Jan 2022)

Log Message

AX ITM: Defer to the tree when determining AX object loading progress
https://bugs.webkit.org/show_bug.cgi?id=235646

Reviewed by Andres Gonzalez.

Source/WebCore:

Currently, we set AXPropertyName::IsLoaded and AXPropertyName::EstimatedLoadingProgress
once in AXIsolatedObject::initializeAttributeData and never update it. This means that
if an object is created while the page is at some non-100% load percentage, AX clients
that request these attributes will always think the object isn't loaded.

This patch removes these two properties and instead defers to the isolated tree associated
with each object when determining the load percentage. Both of these properties were based
on the entire page / document load progress anyways, so it doesn't make sense to set the
same value for all of them.

We track loading progress by changing ProgressTracker to also notify
the page when progress changes, which in turn updates the associated
AXObjectCache with the new progress value.

Covered by accessibility/mac/document-attributes.html which verifies the AXLoad and
AXLoadingProgress attributes.

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::AXObjectCache):
(WebCore::AXObjectCache::updateLoadingProgress):
Added.
* accessibility/AXObjectCache.h:
(WebCore::AXObjectCache::loadingFinished):
(WebCore::AXObjectCache::loadingProgress const):
Added.
* accessibility/AccessibilityObject.h:
* accessibility/AccessibilityObjectInterface.h:
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::loadingProgress const):
(WebCore::AccessibilityRenderObject::estimatedLoadingProgress const):
Rename estimatedLoadingProgress methods to loadingProgress.
* accessibility/AccessibilityRenderObject.h:
* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::initializeAttributeData):
* accessibility/isolatedtree/AXIsolatedObject.h:
* accessibility/isolatedtree/AXIsolatedTree.cpp:
(WebCore::AXIsolatedTree::create):
(WebCore::AXIsolatedTree::updateLoadingProgress):
(WebCore::AXIsolatedTree::applyPendingChanges):
Apply m_pendingEstimatedLoadingProgress.
* accessibility/isolatedtree/AXIsolatedTree.h:
(WebCore::AXIsolatedTree::loadingProgress):
Added.
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
Handle rename of estimatedLoadingProgress methods to loadingProgress.
* loader/ProgressTracker.cpp:
(WebCore::ProgressTracker::ProgressTracker):
Store a reference to the associated page in new m_page member.
(WebCore::ProgressTracker::progressStarted):
(WebCore::ProgressTracker::progressEstimateChanged):
(WebCore::ProgressTracker::finalProgressComplete):
(WebCore::ProgressTracker::incrementProgress):
Notify the Page when progress changes or completes.
* loader/ProgressTracker.h:
* page/Page.cpp:
(WebCore::Page::Page):
(WebCore::Page::progressEstimateChanged const):
Added.
(WebCore::Page::progressFinished const):
Added.
* page/Page.h:

LayoutTests:

* accessibility/mac/document-attributes-expected.txt:
Associated test now uses js-test.js, so modify expectations to include
js-test output (e.g. test description()).
* accessibility/mac/document-attributes.html:
Wait asynchronously for loading to complete ("AXLoaded: 1").
* accessibility/parent-delete.html:
Don't output all attributes, since it's not necessary for the purpose
of the test (which is to ensure calling allAttributes() in this
scenario doesn't cause a crash). Previously, the test output contained
loading AX attributes, so rather than making this test wait for
loading to complete I decided to remove the output all together.
* platform/mac/accessibility/parent-delete-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (288673 => 288674)


--- trunk/LayoutTests/ChangeLog	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/LayoutTests/ChangeLog	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1,3 +1,23 @@
+2022-01-27  Tyler Wilcock  <tyle...@apple.com>
+
+        AX ITM: Defer to the tree when determining AX object loading progress
+        https://bugs.webkit.org/show_bug.cgi?id=235646
+
+        Reviewed by Andres Gonzalez.
+
+        * accessibility/mac/document-attributes-expected.txt:
+        Associated test now uses js-test.js, so modify expectations to include
+        js-test output (e.g. test description()).
+        * accessibility/mac/document-attributes.html:
+        Wait asynchronously for loading to complete ("AXLoaded: 1").
+        * accessibility/parent-delete.html:
+        Don't output all attributes, since it's not necessary for the purpose
+        of the test (which is to ensure calling allAttributes() in this
+        scenario doesn't cause a crash). Previously, the test output contained
+        loading AX attributes, so rather than making this test wait for
+        loading to complete I decided to remove the output all together.
+        * platform/mac/accessibility/parent-delete-expected.txt:
+
 2022-01-27  Gabriel Nava Marino  <gnavamar...@apple.com>
 
         jsc_fuz/wktr: crash with new XRReferenceSpaceEvent('', {referenceSpace})

Modified: trunk/LayoutTests/accessibility/mac/document-attributes-expected.txt (288673 => 288674)


--- trunk/LayoutTests/accessibility/mac/document-attributes-expected.txt	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/LayoutTests/accessibility/mac/document-attributes-expected.txt	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1,9 +1,14 @@
+This test provides a base snapshot of the root web area's attributes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
 AXHasDocumentRoleAncestor: 0
 AXHasWebApplicationAncestor: 0
 AXRole: AXWebArea
 AXRoleDescription: HTML content
-AXChildren: <array of size 0>
-AXChildrenInNavigationOrder: <array of size 0>
+AXChildren: <array of size 2>
+AXChildrenInNavigationOrder: <array of size 2>
 AXHelp:
 AXParent: <AXWebArea>
 AXSize: NSSize: {800, 600}
@@ -34,4 +39,7 @@
 AXWebSessionID: 2
 AXElementBusy: 0
 
+PASS successfullyParsed is true
 
+TEST COMPLETE
+

Modified: trunk/LayoutTests/accessibility/mac/document-attributes.html (288673 => 288674)


--- trunk/LayoutTests/accessibility/mac/document-attributes.html	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/LayoutTests/accessibility/mac/document-attributes.html	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1,24 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
+<script src=""
+<script src=""
+</head>
+<body>
+
 <script>
-    if (window.testRunner)
-        testRunner.dumpAsText();
+    description("This test provides a base snapshot of the root web area's attributes.");
 
-    var log = function(msg)
-    {
-        document.getElementById("console").appendChild(document.createTextNode(msg + "\n"));
-    }
+    if (window.accessibilityController) {
+        window.jsTestIsAsync = true;
 
-    _onload_ = function()
-    {
-        if (window.accessibilityController)
-            log(accessibilityController.focusedElement.allAttributes());
-        else
-            log("This test requires DumpRenderTree to run.")
+        setTimeout(async function() {
+            let allAttributes;
+            await waitFor(() => {
+                if (!accessibilityController.focusedElement)
+                    return false;
+                allAttributes = accessibilityController.focusedElement.allAttributes();
+                // Wait for the page to be fully loaded.
+                return allAttributes.includes("AXLoaded: 1");
+            });
+            debugEscaped(allAttributes);
+            finishJSTest();
+        }, 0);
     }
 </script>
-</head>
-<body>
-<pre id="console"></pre>
 </body>
 </html>

Modified: trunk/LayoutTests/accessibility/parent-delete.html (288673 => 288674)


--- trunk/LayoutTests/accessibility/parent-delete.html	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/LayoutTests/accessibility/parent-delete.html	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1,27 +1,22 @@
 <!DOCTYPE html>
 <html>
 <head>
+<script src=""
 <script>
-if (window.testRunner)
-    testRunner.dumpAsText();
-
 function runTest() {
-    var accessibilityElement;
-    {
-        var outer = document.getElementById("outer");
-        var inner = document.getElementById("inner");
-        var editable = document.getElementById("editable");
-        var result = document.getElementById("result");
-        editable.focus();
-        if (window.accessibilityController) {
-            var accessibilityElement = accessibilityController.focusedElement;
-        }
-        inner.removeChild(editable);
-        outer.removeChild(inner);
-    }
-    if (window.accessibilityController) {
-        result.innerText = accessibilityElement.allAttributes();
-    }
+    const outer = document.getElementById("outer");
+    const inner = document.getElementById("inner");
+    const editable = document.getElementById("editable");
+    const result = document.getElementById("result");
+    editable.focus();
+    let accessibilityElement;
+    if (window.accessibilityController)
+        accessibilityElement = accessibilityController.focusedElement;
+    inner.removeChild(editable);
+    outer.removeChild(inner);
+    // This should not cause a crash.
+    if (window.accessibilityController)
+        accessibilityElement.allAttributes();
 }
 </script>
 </head>

Modified: trunk/LayoutTests/platform/mac/accessibility/parent-delete-expected.txt (288673 => 288674)


--- trunk/LayoutTests/platform/mac/accessibility/parent-delete-expected.txt	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/LayoutTests/platform/mac/accessibility/parent-delete-expected.txt	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1,37 +1,5 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
 This test passes if there is no crash.
-AXHasDocumentRoleAncestor: 0
-AXHasWebApplicationAncestor: 0
-AXRole: AXWebArea
-AXRoleDescription: HTML content
-AXChildren: <array of size 1>
-AXChildrenInNavigationOrder: <array of size 1>
-AXHelp:
-AXParent: <AXWebArea>
-AXSize: NSSize: {800, 600}
-AXTitle:
-AXDescription:
-AXValue:
-AXFocused: 0
-AXEnabled: 1
-AXWindow: <AXWebArea>
-AXSelectedTextMarkerRange: (null)
-AXStartTextMarker: <AXWebArea>
-AXEndTextMarker: <AXWebArea>
-AXVisited: 0
-AXLinkedUIElements: <array of size 0>
-AXSelected: 0
-AXBlockQuoteLevel: 0
-AXTopLevelUIElement: <AXWebArea>
-AXLanguage:
-AXDOMIdentifier:
-AXDOMClassList: <array of size 0>
-AXLinkUIElements: <array of size 0>
-AXLoaded: 1
-AXLayoutCount: 2
-AXLoadingProgress: 1
-AXURL: LayoutTests/accessibility/parent-delete.html
-AXCaretBrowsingEnabled: 0
-AXPreventKeyboardDOMEventDispatch: 0
-AXWebSessionID: 2
-AXElementBusy: 0
 

Modified: trunk/Source/WebCore/ChangeLog (288673 => 288674)


--- trunk/Source/WebCore/ChangeLog	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/ChangeLog	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1,3 +1,73 @@
+2022-01-27  Tyler Wilcock  <tyle...@apple.com>
+
+        AX ITM: Defer to the tree when determining AX object loading progress
+        https://bugs.webkit.org/show_bug.cgi?id=235646
+
+        Reviewed by Andres Gonzalez.
+
+        Currently, we set AXPropertyName::IsLoaded and AXPropertyName::EstimatedLoadingProgress
+        once in AXIsolatedObject::initializeAttributeData and never update it. This means that
+        if an object is created while the page is at some non-100% load percentage, AX clients
+        that request these attributes will always think the object isn't loaded.
+
+        This patch removes these two properties and instead defers to the isolated tree associated
+        with each object when determining the load percentage. Both of these properties were based
+        on the entire page / document load progress anyways, so it doesn't make sense to set the
+        same value for all of them.
+
+        We track loading progress by changing ProgressTracker to also notify
+        the page when progress changes, which in turn updates the associated
+        AXObjectCache with the new progress value.
+
+        Covered by accessibility/mac/document-attributes.html which verifies the AXLoad and
+        AXLoadingProgress attributes.
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::AXObjectCache):
+        (WebCore::AXObjectCache::updateLoadingProgress):
+        Added.
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::loadingFinished):
+        (WebCore::AXObjectCache::loadingProgress const):
+        Added.
+        * accessibility/AccessibilityObject.h:
+        * accessibility/AccessibilityObjectInterface.h:
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::loadingProgress const):
+        (WebCore::AccessibilityRenderObject::estimatedLoadingProgress const):
+        Rename estimatedLoadingProgress methods to loadingProgress.
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::initializeAttributeData):
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+        * accessibility/isolatedtree/AXIsolatedTree.cpp:
+        (WebCore::AXIsolatedTree::create):
+        (WebCore::AXIsolatedTree::updateLoadingProgress):
+        (WebCore::AXIsolatedTree::applyPendingChanges):
+        Apply m_pendingEstimatedLoadingProgress.
+        * accessibility/isolatedtree/AXIsolatedTree.h:
+        (WebCore::AXIsolatedTree::loadingProgress):
+        Added.
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+        Handle rename of estimatedLoadingProgress methods to loadingProgress.
+        * loader/ProgressTracker.cpp:
+        (WebCore::ProgressTracker::ProgressTracker):
+        Store a reference to the associated page in new m_page member.
+        (WebCore::ProgressTracker::progressStarted):
+        (WebCore::ProgressTracker::progressEstimateChanged):
+        (WebCore::ProgressTracker::finalProgressComplete):
+        (WebCore::ProgressTracker::incrementProgress):
+        Notify the Page when progress changes or completes.
+        * loader/ProgressTracker.h:
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+        (WebCore::Page::progressEstimateChanged const):
+        Added.
+        (WebCore::Page::progressFinished const):
+        Added.
+        * page/Page.h:
+
 2022-01-27  Gabriel Nava Marino  <gnavamar...@apple.com>
 
         jsc_fuz/wktr: crash with new XRReferenceSpaceEvent('', {referenceSpace})

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (288673 => 288674)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-01-27 16:51:29 UTC (rev 288674)
@@ -89,6 +89,7 @@
 #include "InlineRunAndOffset.h"
 #include "MathMLElement.h"
 #include "Page.h"
+#include "ProgressTracker.h"
 #include "Range.h"
 #include "RenderAttachment.h"
 #include "RenderImage.h"
@@ -224,6 +225,13 @@
     , m_performCacheUpdateTimer(*this, &AXObjectCache::performCacheUpdateTimerFired)
 {
     ASSERT(isMainThread());
+
+    // If loading completed before the cache was created, loading progress will have been reset to zero.
+    // Consider loading progress to be 100% in this case.
+    double loadingProgress = document.page() ? document.page()->progress().estimatedProgress() : 1;
+    if (loadingProgress <= 0)
+        loadingProgress = 1;
+    m_loadingProgress = loadingProgress;
 }
 
 AXObjectCache::~AXObjectCache()
@@ -971,6 +979,22 @@
     get(node);
 }
 
+void AXObjectCache::updateLoadingProgress(double newProgressValue)
+{
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    ASSERT_WITH_MESSAGE(newProgressValue >= 0 && newProgressValue <= 1, "unexpected loading progress value: %f", newProgressValue);
+    if (m_pageID) {
+        // Sometimes the isolated tree hasn't been created by the time we get loading progress updates,
+        // so cache this value in the AXObjectCache too so we can give it to the tree upon creation.
+        m_loadingProgress = newProgressValue;
+        if (auto tree = AXIsolatedTree::treeForPageID(*m_pageID))
+            tree->updateLoadingProgress(newProgressValue);
+    }
+#else
+    UNUSED_PARAM(newProgressValue);
+#endif
+}
+
 void AXObjectCache::handleChildrenChanged(AccessibilityObject& object)
 {
     // Handle MenuLists and MenuListPopups as special cases.

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (288673 => 288674)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -187,6 +187,9 @@
     void checkedStateChanged(Node*);
     // Called when a node has just been attached, so we can make sure we have the right subclass of AccessibilityObject.
     void updateCacheAfterNodeIsAttached(Node*);
+    void updateLoadingProgress(double);
+    void loadingFinished() { updateLoadingProgress(1); }
+    double loadingProgress() const { return m_loadingProgress; }
 
     void deferFocusedUIElementChangeIfNeeded(Node* oldFocusedNode, Node* newFocusedNode);
     void deferModalChange(Element*);
@@ -523,6 +526,7 @@
     Vector<std::pair<Node*, Node*>> m_deferredFocusedNodeChange;
     bool m_isSynchronizingSelection { false };
     bool m_performingDeferredCacheUpdate { false };
+    double m_loadingProgress { 0 };
 
 #if USE(ATK)
     ListHashSet<RefPtr<AccessibilityObject>> m_deferredAttachedWrapperObjectList;

Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (288673 => 288674)


--- trunk/Source/WebCore/accessibility/AccessibilityObject.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -295,7 +295,7 @@
     AXCoreObject* selectedTabItem() override { return nullptr; }
     AXCoreObject* selectedListItem() override;
     int layoutCount() const override { return 0; }
-    double estimatedLoadingProgress() const override { return 0; }
+    double loadingProgress() const override { return 0; }
     WEBCORE_EXPORT static bool isARIAControl(AccessibilityRole);
     bool supportsCheckedState() const override;
     

Modified: trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h (288673 => 288674)


--- trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1047,7 +1047,7 @@
     virtual AXCoreObject* selectedTabItem() = 0;
     virtual AXCoreObject* selectedListItem() = 0;
     virtual int layoutCount() const = 0;
-    virtual double estimatedLoadingProgress() const = 0;
+    virtual double loadingProgress() const = 0;
     virtual String brailleLabel() const = 0;
     virtual String brailleRoleDescription() const = 0;
     virtual String embeddedImageDescription() const = 0;

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (288673 => 288674)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2022-01-27 16:51:29 UTC (rev 288674)
@@ -1536,7 +1536,7 @@
     return m_renderer ? !m_renderer->document().parser() : false;
 }
 
-double AccessibilityRenderObject::estimatedLoadingProgress() const
+double AccessibilityRenderObject::loadingProgress() const
 {
     if (!m_renderer)
         return 0;

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h (288673 => 288674)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -83,7 +83,7 @@
     AccessibilityObjectInclusion defaultObjectInclusion() const override;
     
     int layoutCount() const override;
-    double estimatedLoadingProgress() const override;
+    double loadingProgress() const override;
     
     AccessibilityObject* firstChild() const override;
     AccessibilityObject* lastChild() const override;

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (288673 => 288674)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2022-01-27 16:51:29 UTC (rev 288674)
@@ -110,7 +110,6 @@
     setProperty(AXPropertyName::IsLink, object.isLink());
     setProperty(AXPropertyName::IsLinked, object.isLinked());
     setProperty(AXPropertyName::IsList, object.isList());
-    setProperty(AXPropertyName::IsLoaded, object.isLoaded());
     setProperty(AXPropertyName::IsMediaTimeline, object.isMediaTimeline());
     setProperty(AXPropertyName::IsMenu, object.isMenu());
     setProperty(AXPropertyName::IsMenuBar, object.isMenuBar());
@@ -171,7 +170,6 @@
     setObjectProperty(AXPropertyName::SelectedRadioButton, object.selectedRadioButton());
     setObjectProperty(AXPropertyName::SelectedTabItem, object.selectedTabItem());
     setProperty(AXPropertyName::LayoutCount, object.layoutCount());
-    setProperty(AXPropertyName::EstimatedLoadingProgress, object.estimatedLoadingProgress());
     setProperty(AXPropertyName::SupportsARIAOwns, object.supportsARIAOwns());
     setProperty(AXPropertyName::HasPopup, object.hasPopup());
     setProperty(AXPropertyName::PopupValue, object.popupValue().isolatedCopy());

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (288673 => 288674)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -221,7 +221,7 @@
     AXCoreObject* selectedRadioButton() override { return objectAttributeValue(AXPropertyName::SelectedRadioButton); }
     AXCoreObject* selectedTabItem() override { return objectAttributeValue(AXPropertyName::SelectedTabItem); }
     int layoutCount() const override { return intAttributeValue(AXPropertyName::LayoutCount); }
-    double estimatedLoadingProgress() const override { return doubleAttributeValue(AXPropertyName::EstimatedLoadingProgress); }
+    double loadingProgress() const override { return tree()->loadingProgress(); }
     bool supportsARIAOwns() const override { return boolAttributeValue(AXPropertyName::SupportsARIAOwns); }
     bool isActiveDescendantOfFocusedContainer() const override { return boolAttributeValue(AXPropertyName::IsActiveDescendantOfFocusedContainer); }
     void ariaControlsElements(AccessibilityChildrenVector& children) const override { fillChildrenVectorForProperty(AXPropertyName::ARIAControlsElements, children); }
@@ -513,7 +513,7 @@
     bool isFigureElement() const override;
     bool isHovered() const override;
     bool isIndeterminate() const override;
-    bool isLoaded() const override { return boolAttributeValue(AXPropertyName::IsLoaded); }
+    bool isLoaded() const override { return loadingProgress() >= 1; }
     bool isOnScreen() const override;
     bool isOffScreen() const override;
     bool isPressed() const override;

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp (288673 => 288674)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp	2022-01-27 16:51:29 UTC (rev 288674)
@@ -118,6 +118,7 @@
     ASSERT(!treePageCache().contains(*pageID));
     treePageCache().set(*pageID, tree.copyRef());
     treeIDCache().set(tree->treeID(), tree.copyRef());
+    tree->updateLoadingProgress(axObjectCache->loadingProgress());
 
     return tree;
 }
@@ -439,6 +440,16 @@
     m_pendingPropertyChanges.append({ axID, propertyMap });
 }
 
+void AXIsolatedTree::updateLoadingProgress(double newProgressValue)
+{
+    AXTRACE("AXIsolatedTree::updateLoadingProgress");
+    AXLOG(makeString("Queueing loading progress update to ", newProgressValue, " for treeID ", treeID()));
+    ASSERT(isMainThread());
+
+    Locker locker { m_changeLogLock };
+    m_pendingLoadingProgress = newProgressValue;
+}
+
 void AXIsolatedTree::removeNode(AXID axID)
 {
     AXTRACE("AXIsolatedTree::removeNode");
@@ -484,6 +495,8 @@
 
     Locker locker { m_changeLogLock };
 
+    m_loadingProgress = m_pendingLoadingProgress;
+
     if (m_pendingFocusedNodeID != m_focusedNodeID) {
         AXLOG(makeString("focusedNodeID ", m_focusedNodeID.loggingString(), " pendingFocusedNodeID ", m_pendingFocusedNodeID.loggingString()));
 

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h (288673 => 288674)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -111,7 +111,6 @@
     EditableAncestor,
     ElementRect,
     EmbeddedImageDescription,
-    EstimatedLoadingProgress,
     ExpandedTextValue,
     FileUploadButtonReturnsValueInTitle,
     FocusableAncestor,
@@ -168,7 +167,6 @@
     IsLinked,
     IsList,
     IsListBox,
-    IsLoaded,
     IsMathElement,
     IsMathFraction,
     IsMathFenced,
@@ -361,6 +359,9 @@
     void updateSubtree(AXCoreObject&);
     void updateChildren(AXCoreObject&);
 
+    double loadingProgress() { return m_loadingProgress; }
+    void updateLoadingProgress(double);
+
     // Removes the given node leaving all descendants alone.
     void removeNode(AXID);
     // Removes the given node and all its descendants.
@@ -411,6 +412,8 @@
     Vector<std::pair<AXID, Vector<AXID>>> m_pendingChildrenUpdates WTF_GUARDED_BY_LOCK(m_changeLogLock);
     AXID m_pendingFocusedNodeID WTF_GUARDED_BY_LOCK(m_changeLogLock);
     AXID m_focusedNodeID;
+    double m_pendingLoadingProgress WTF_GUARDED_BY_LOCK(m_changeLogLock) { 0 };
+    double m_loadingProgress { 0 };
     Lock m_changeLogLock;
 
     bool m_creatingSubtree { false };

Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (288673 => 288674)


--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2022-01-27 16:51:29 UTC (rev 288674)
@@ -2033,7 +2033,7 @@
         if ([attributeName isEqualToString:@"AXLayoutCount"])
             return @(backingObject->layoutCount());
         if ([attributeName isEqualToString:NSAccessibilityLoadingProgressAttribute])
-            return @(backingObject->estimatedLoadingProgress());
+            return @(backingObject->loadingProgress());
         if ([attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
             return [NSNumber numberWithBool:backingObject->preventKeyboardDOMEventDispatch()];
         if ([attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])

Modified: trunk/Source/WebCore/loader/ProgressTracker.cpp (288673 => 288674)


--- trunk/Source/WebCore/loader/ProgressTracker.cpp	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/loader/ProgressTracker.cpp	2022-01-27 16:51:29 UTC (rev 288674)
@@ -75,8 +75,9 @@
     long long estimatedLength;
 };
 
-ProgressTracker::ProgressTracker(UniqueRef<ProgressTrackerClient>&& client)
-    : m_client(WTFMove(client))
+ProgressTracker::ProgressTracker(Page& page, UniqueRef<ProgressTrackerClient>&& client)
+    : m_page(page)
+    , m_client(WTFMove(client))
     , m_progressHeartbeatTimer(*this, &ProgressTracker::progressHeartbeatTimerFired)
 {
 }
@@ -129,6 +130,7 @@
         m_isMainLoad = isMainFrame || elapsedTimeSinceMainLoadComplete < subframePartOfMainLoadThreshold;
 
         m_client->progressStarted(*m_originatingProgressFrame);
+        m_page.progressEstimateChanged(*m_originatingProgressFrame);
     }
     m_numProgressTrackedFrames++;
 
@@ -138,6 +140,12 @@
     InspectorInstrumentation::frameStartedLoading(frame);
 }
 
+void ProgressTracker::progressEstimateChanged(Frame& frame)
+{
+    m_client->progressEstimateChanged(frame);
+    m_page.progressEstimateChanged(frame);
+}
+
 void ProgressTracker::progressCompleted(Frame& frame)
 {
     LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, &frame, frame.tree().uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
@@ -166,7 +174,7 @@
     // with final progress value.
     if (!m_finalProgressChangedSent) {
         m_progressValue = 1;
-        m_client->progressEstimateChanged(*frame);
+        progressEstimateChanged(*frame);
     }
 
     reset();
@@ -176,6 +184,7 @@
 
     frame->loader().client().setMainFrameDocumentReady(true);
     m_client->progressFinished(*frame);
+    m_page.progressFinished(*frame);
     frame->loader().loadProgressingStatusChanged();
 
     InspectorInstrumentation::frameStoppedLoading(*frame);
@@ -254,7 +263,7 @@
             if (m_progressValue == 1)
                 m_finalProgressChangedSent = true;
 
-            m_client->progressEstimateChanged(*frame);
+            progressEstimateChanged(*frame);
 
             m_lastNotifiedProgressValue = m_progressValue;
             m_lastNotifiedProgressTime = now;

Modified: trunk/Source/WebCore/loader/ProgressTracker.h (288673 => 288674)


--- trunk/Source/WebCore/loader/ProgressTracker.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/loader/ProgressTracker.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -44,7 +44,7 @@
     WTF_MAKE_NONCOPYABLE(ProgressTracker);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit ProgressTracker(UniqueRef<ProgressTrackerClient>&&);
+    explicit ProgressTracker(Page&, UniqueRef<ProgressTrackerClient>&&);
     ~ProgressTracker();
 
     ProgressTrackerClient& client() { return m_client.get(); }
@@ -66,9 +66,11 @@
 private:
     void reset();
     void finalProgressComplete();
+    void progressEstimateChanged(Frame&);
 
     void progressHeartbeatTimerFired();
 
+    Page& m_page;
     UniqueRef<ProgressTrackerClient> m_client;
     RefPtr<Frame> m_originatingProgressFrame;
     HashMap<ResourceLoaderIdentifier, std::unique_ptr<ProgressItem>> m_progressItems;

Modified: trunk/Source/WebCore/page/Page.cpp (288673 => 288674)


--- trunk/Source/WebCore/page/Page.cpp	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/page/Page.cpp	2022-01-27 16:51:29 UTC (rev 288674)
@@ -48,6 +48,7 @@
 #include "DiagnosticLoggingClient.h"
 #include "DiagnosticLoggingKeys.h"
 #include "DisplayRefreshMonitorManager.h"
+#include "DocumentInlines.h"
 #include "DocumentLoader.h"
 #include "DocumentMarkerController.h"
 #include "DocumentTimeline.h"
@@ -274,7 +275,7 @@
     , m_pointerLockController(makeUnique<PointerLockController>(*this))
 #endif
     , m_settings(Settings::create(this))
-    , m_progress(makeUnique<ProgressTracker>(WTFMove(pageConfiguration.progressTrackerClient)))
+    , m_progress(makeUnique<ProgressTracker>(*this, WTFMove(pageConfiguration.progressTrackerClient)))
     , m_backForwardController(makeUnique<BackForwardController>(*this, WTFMove(pageConfiguration.backForwardClient)))
     , m_mainFrame(Frame::create(this, nullptr, WTFMove(pageConfiguration.loaderClientForMainFrame)))
     , m_editorClient(WTFMove(pageConfiguration.editorClient))
@@ -583,6 +584,22 @@
 #endif
 }
 
+void Page::progressEstimateChanged(Frame& frameWithProgressUpdate) const
+{
+    if (auto* document = frameWithProgressUpdate.document()) {
+        if (auto* axObjectCache = document->existingAXObjectCache())
+            axObjectCache->updateLoadingProgress(progress().estimatedProgress());
+    }
+}
+
+void Page::progressFinished(Frame& frameWithCompletedProgress) const
+{
+    if (auto* document = frameWithCompletedProgress.document()) {
+        if (auto* axObjectCache = document->existingAXObjectCache())
+            axObjectCache->loadingFinished();
+    }
+}
+
 bool Page::openedByDOM() const
 {
     return m_openedByDOM;

Modified: trunk/Source/WebCore/page/Page.h (288673 => 288674)


--- trunk/Source/WebCore/page/Page.h	2022-01-27 16:03:29 UTC (rev 288673)
+++ trunk/Source/WebCore/page/Page.h	2022-01-27 16:51:29 UTC (rev 288674)
@@ -361,6 +361,8 @@
 
     Settings& settings() const { return *m_settings; }
     ProgressTracker& progress() const { return *m_progress; }
+    void progressEstimateChanged(Frame&) const;
+    void progressFinished(Frame&) const;
     BackForwardController& backForward() const { return *m_backForwardController; }
 
     Seconds domTimerAlignmentInterval() const { return m_domTimerAlignmentInterval; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to