⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 295139 in webkit


Ignore:
Timestamp:
Jun 2, 2022, 12:46:46 PM (4 years ago)
Author:
Andres Gonzalez
Message:

AX ITM: Cache several object relationships that were not cached in isolated tree mode.
​https://bugs.webkit.org/show_bug.cgi?id=240239

Reviewed by Chris Fleizach.

Instead of caching individual relations as separate Vectors of AXIsolatedObjects, this patch uses the new relationships implementation to cache a copy of the AXObjectCache::m_relations in the AXIsolatedTree. This data structure is updated when the AXObjectCache sets the flag m_relationsNeedUpdate and one of the relations properties is requested on the AX thread. This allows for a common implementation for all the methods to retrieve individual relationships, and the main two derived classes AXObject and AXIsolatedObject only override the relatedObjects method.

Canonical link: ​https://commits.webkit.org/251230@main

Location:
trunk/Source/WebCore/accessibility
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r295024 r295139  
    37723772    if (relationsIterator == m_relations.end()) {
    37733773        // No relations for this object, add the first one.
    3774         m_relations.add(origin->objectID(), Relations { { static_cast<uint8_t>(relationType), { target->objectID() } } });
     3774        m_relations.add(origin->objectID(), AXRelations { { static_cast<uint8_t>(relationType), { target->objectID() } } });
    37753775    } else if (auto targetsIterator = relationsIterator->value.find(static_cast<uint8_t>(relationType)); targetsIterator == relationsIterator->value.end()) {
    37763776        // No relation of this type for this object, add the first one.
    … …  
    38433843}
    38443844
    3845 std::optional<Vector<AXID>> AXObjectCache::relatedObjectsFor(const AXCoreObject& object, AXRelationType relationType)
     3845void AXObjectCache::relationsNeedUpdate(bool needUpdate)
     3846{
     3847    m_relationsNeedUpdate = needUpdate;
     3848
     3849#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
     3850    if (m_relationsNeedUpdate && m_pageID) {
     3851        if (auto tree = AXIsolatedTree::treeForPageID(*m_pageID))
     3852            tree->relationsNeedUpdate(true);
     3853    }
     3854#endif
     3855}
     3856
     3857HashMap<AXID, AXRelations> AXObjectCache::relations()
     3858{
     3859    updateRelationsIfNeeded();
     3860    return m_relations;
     3861}
     3862
     3863std::optional<Vector<AXID>> AXObjectCache::relatedObjectIDsFor(const AXCoreObject& object, AXRelationType relationType)
    38463864{
    38473865    updateRelationsIfNeeded();
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r294938 r295139  
    381381
    382382    // Returns the IDs of the objects that relate to the given object with the specified relationship.
    383     std::optional<Vector<AXID>> relatedObjectsFor(const AXCoreObject&, AXRelationType);
     383    std::optional<Vector<AXID>> relatedObjectIDsFor(const AXCoreObject&, AXRelationType);
    384384
    385385#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    … …  
    501501    void addRelation(AccessibilityObject*, AccessibilityObject*, AXRelationType, AddingSymmetricRelation = AddingSymmetricRelation::No);
    502502    void updateRelationsIfNeeded();
    503     void relationsNeedUpdate(bool needUpdate) { m_relationsNeedUpdate = needUpdate; }
     503    void relationsNeedUpdate(bool);
     504    HashMap<AXID, AXRelations> relations();
    504505
    505506    Document& m_document;
    … …  
    559560
    560561    // Relationships between objects.
    561     using Relations = HashMap<AXRelationType, Vector<AXID>, DefaultHash<uint8_t>, WTF::UnsignedWithZeroKeyHashTraits<uint8_t>>;
    562     HashMap<AXID, Relations> m_relations;
     562    HashMap<AXID, AXRelations> m_relations;
    563563    bool m_relationsNeedUpdate { true };
    564564
  • trunk/Source/WebCore/accessibility/AccessibilityObject.cpp

    r295090 r295139  
    39373937        return { };
    39383938
    3939     auto relatedObjectIDs = cache->relatedObjectsFor(*this, relationType);
     3939    auto relatedObjectIDs = cache->relatedObjectIDsFor(*this, relationType);
    39403940    if (!relatedObjectIDs)
    39413941        return { };
    … …  
    39523952
    39533953    return false;
    3954 }
    3955 
    3956 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::activeDescendantOfObjects() const
    3957 {
    3958     return relatedObjects(AXRelationType::ActiveDescendantOf);
    3959 }
    3960 
    3961 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::controlledObjects() const
    3962 {
    3963     return relatedObjects(AXRelationType::ControllerFor);
    3964 }
    3965 
    3966 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::controllers() const
    3967 {
    3968     return relatedObjects(AXRelationType::ControlledBy);
    3969 }
    3970 
    3971 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::describedByObjects() const
    3972 {
    3973     return relatedObjects(AXRelationType::DescribedBy);
    3974 }
    3975 
    3976 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::descriptionForObjects() const
    3977 {
    3978     return relatedObjects(AXRelationType::DescriptionFor);
    3979 }
    3980 
    3981 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::detailedByObjects() const
    3982 {
    3983     return relatedObjects(AXRelationType::Details);
    3984 }
    3985 
    3986 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::detailsForObjects() const
    3987 {
    3988     return relatedObjects(AXRelationType::DetailsFor);
    3989 }
    3990 
    3991 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::errorMessageObjects() const
    3992 {
    3993     return relatedObjects(AXRelationType::ErrorMessage);
    3994 }
    3995 
    3996 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::errorMessageForObjects() const
    3997 {
    3998     return relatedObjects(AXRelationType::ErrorMessageFor);
    3999 }
    4000 
    4001 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::flowToObjects() const
    4002 {
    4003     return relatedObjects(AXRelationType::FlowsTo);
    4004 }
    4005 
    4006 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::flowFromObjects() const
    4007 {
    4008     return relatedObjects(AXRelationType::FlowsFrom);
    4009 }
    4010 
    4011 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::labelledByObjects() const
    4012 {
    4013     return relatedObjects(AXRelationType::LabelledBy);
    4014 }
    4015 
    4016 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::labelForObjects() const
    4017 {
    4018     return relatedObjects(AXRelationType::LabelFor);
    4019 }
    4020 
    4021 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::ownedObjects() const
    4022 {
    4023     return relatedObjects(AXRelationType::OwnerFor);
    4024 }
    4025 
    4026 AXCoreObject::AccessibilityChildrenVector AccessibilityObject::owners() const
    4027 {
    4028     return relatedObjects(AXRelationType::OwnedBy);
    40293954}
    40303955
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r295090 r295139  
    305305    bool isActiveDescendantOfFocusedContainer() const override;
    306306
    307     AccessibilityChildrenVector activeDescendantOfObjects() const override;
    308     AccessibilityChildrenVector controlledObjects() const override;
    309     AccessibilityChildrenVector controllers() const override;
    310     AccessibilityChildrenVector describedByObjects() const override;
    311     AccessibilityChildrenVector descriptionForObjects() const override;
    312     AccessibilityChildrenVector detailedByObjects() const override;
    313     AccessibilityChildrenVector detailsForObjects() const override;
    314     AccessibilityChildrenVector errorMessageObjects() const override;
    315     AccessibilityChildrenVector errorMessageForObjects() const override;
    316     AccessibilityChildrenVector flowToObjects() const override;
    317     AccessibilityChildrenVector flowFromObjects() const override;
    318     AccessibilityChildrenVector labelledByObjects() const override;
    319     AccessibilityChildrenVector labelForObjects() const override;
    320     AccessibilityChildrenVector ownedObjects() const override;
    321     AccessibilityChildrenVector owners() const override;
    322 
    323307    bool hasPopup() const override { return false; }
    324308    String popupValue() const override;
    … …  
    788772    AccessibilityChildrenVector documentLinks() override { return AccessibilityChildrenVector(); }
    789773
    790     AccessibilityChildrenVector relatedObjects(AXRelationType) const;
     774    AccessibilityChildrenVector relatedObjects(AXRelationType) const override;
    791775protected:
    792776    AccessibilityObject() = default;
  • trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h

    r294878 r295139  
    799799    OwnerFor,
    800800};
     801using AXRelations = HashMap<AXRelationType, Vector<AXID>, DefaultHash<uint8_t>, WTF::UnsignedWithZeroKeyHashTraits<uint8_t>>;
    801802
    802803// Use this struct to store the isIgnored data that depends on the parents, so that in addChildren()
    … …  
    10741075
    10751076    // Retrieval of related objects.
    1076     virtual AccessibilityChildrenVector activeDescendantOfObjects() const = 0;
    1077     virtual AccessibilityChildrenVector controlledObjects() const = 0;
    1078     virtual AccessibilityChildrenVector controllers() const = 0;
    1079     virtual AccessibilityChildrenVector describedByObjects() const = 0;
    1080     virtual AccessibilityChildrenVector descriptionForObjects() const = 0;
    1081     virtual AccessibilityChildrenVector detailedByObjects() const = 0;
    1082     virtual AccessibilityChildrenVector detailsForObjects() const = 0;
    1083     virtual AccessibilityChildrenVector errorMessageObjects() const = 0;
    1084     virtual AccessibilityChildrenVector errorMessageForObjects() const = 0;
    1085     virtual AccessibilityChildrenVector flowToObjects() const = 0;
    1086     virtual AccessibilityChildrenVector flowFromObjects() const = 0;
    1087     virtual AccessibilityChildrenVector labelledByObjects() const = 0;
    1088     virtual AccessibilityChildrenVector labelForObjects() const = 0;
    1089     virtual AccessibilityChildrenVector ownedObjects() const = 0;
    1090     virtual AccessibilityChildrenVector owners() const = 0;
     1077    AccessibilityChildrenVector activeDescendantOfObjects() const { return relatedObjects(AXRelationType::ActiveDescendantOf); }
     1078    AccessibilityChildrenVector controlledObjects() const { return relatedObjects(AXRelationType::ControllerFor); }
     1079    AccessibilityChildrenVector controllers() const { return relatedObjects(AXRelationType::ControlledBy); }
     1080    AccessibilityChildrenVector describedByObjects() const { return relatedObjects(AXRelationType::DescribedBy); }
     1081    AccessibilityChildrenVector descriptionForObjects() const { return relatedObjects(AXRelationType::DescriptionFor); }
     1082    AccessibilityChildrenVector detailedByObjects() const { return relatedObjects(AXRelationType::Details); }
     1083    AccessibilityChildrenVector detailsForObjects() const { return relatedObjects(AXRelationType::DetailsFor); }
     1084    AccessibilityChildrenVector errorMessageObjects() const { return relatedObjects(AXRelationType::ErrorMessage); }
     1085    AccessibilityChildrenVector errorMessageForObjects() const { return relatedObjects(AXRelationType::ErrorMessageFor); }
     1086    AccessibilityChildrenVector flowToObjects() const { return relatedObjects(AXRelationType::FlowsTo); }
     1087    AccessibilityChildrenVector flowFromObjects() const { return relatedObjects(AXRelationType::FlowsFrom); }
     1088    AccessibilityChildrenVector labelledByObjects() const { return relatedObjects(AXRelationType::LabelledBy); }
     1089    AccessibilityChildrenVector labelForObjects() const { return relatedObjects(AXRelationType::LabelFor); }
     1090    AccessibilityChildrenVector ownedObjects() const { return relatedObjects(AXRelationType::OwnerFor); }
     1091    AccessibilityChildrenVector owners() const { return relatedObjects(AXRelationType::OwnedBy); }
     1092    virtual AccessibilityChildrenVector relatedObjects(AXRelationType) const = 0;
    10911093
    10921094    virtual bool hasPopup() const = 0;
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp

    r294328 r295139  
    329329    setObjectVectorProperty(AXPropertyName::LinkedObjects, object.linkedObjects());
    330330
    331     // Relations.
    332     setObjectVectorProperty(AXPropertyName::ControlledObjects, object.controlledObjects());
    333     setObjectVectorProperty(AXPropertyName::DetailedByObjects, object.detailedByObjects());
    334     setObjectVectorProperty(AXPropertyName::ErrorMessageObjects, object.errorMessageObjects());
    335     setObjectVectorProperty(AXPropertyName::FlowToObjects, object.flowToObjects());
    336     setObjectVectorProperty(AXPropertyName::OwnedObjects, object.ownedObjects());
    337 
    338331    // Spin button support.
    339332    setObjectProperty(AXPropertyName::DecrementButton, object.decrementButton());
    … …  
    18661859}
    18671860
    1868 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::activeDescendantOfObjects() const
    1869 {
    1870     ASSERT_NOT_REACHED();
    1871     return { };
    1872 }
    1873 
    1874 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::controllers() const
    1875 {
    1876     ASSERT_NOT_REACHED();
    1877     return { };
    1878 }
    1879 
    1880 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::describedByObjects() const
    1881 {
    1882     ASSERT_NOT_REACHED();
    1883     return { };
    1884 }
    1885 
    1886 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::descriptionForObjects() const
    1887 {
    1888     ASSERT_NOT_REACHED();
    1889     return { };
    1890 }
    1891 
    1892 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::detailsForObjects() const
    1893 {
    1894     ASSERT_NOT_REACHED();
    1895     return { };
    1896 }
    1897 
    1898 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::errorMessageForObjects() const
    1899 {
    1900     ASSERT_NOT_REACHED();
    1901     return { };
    1902 }
    1903 
    1904 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::flowFromObjects() const
    1905 {
    1906     ASSERT_NOT_REACHED();
    1907     return { };
    1908 }
    1909 
    1910 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::labelledByObjects() const
    1911 {
    1912     ASSERT_NOT_REACHED();
    1913     return { };
    1914 }
    1915 
    1916 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::labelForObjects() const
    1917 {
    1918     ASSERT_NOT_REACHED();
    1919     return { };
    1920 }
    1921 
    1922 AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::owners() const
    1923 {
    1924     ASSERT_NOT_REACHED();
    1925     return { };
    1926 }
    1927 
    19281861bool AXIsolatedObject::hasDatalist() const
    19291862{
    … …  
    21842117}
    21852118
     2119AXCoreObject::AccessibilityChildrenVector AXIsolatedObject::relatedObjects(AXRelationType relationType) const
     2120{
     2121    if (auto relatedObjectIDs = tree()->relatedObjectIDsFor(*this, relationType))
     2122        return tree()->objectsForIDs(*relatedObjectIDs);
     2123    return { };
     2124}
     2125
    21862126AXCoreObject* AXIsolatedObject::activeDescendant() const
    21872127{
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h

    r294328 r295139  
    542542    AXCoreObject* selectedListItem() override;
    543543
    544     AccessibilityChildrenVector activeDescendantOfObjects() const override;
    545     AccessibilityChildrenVector controlledObjects() const override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::ControlledObjects)); }
    546     AccessibilityChildrenVector controllers() const override;
    547     AccessibilityChildrenVector describedByObjects() const override;
    548     AccessibilityChildrenVector descriptionForObjects() const override;
    549     AccessibilityChildrenVector detailedByObjects() const override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::DetailedByObjects)); }
    550     AccessibilityChildrenVector detailsForObjects() const override;
    551     AccessibilityChildrenVector errorMessageObjects() const override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::ErrorMessageObjects)); }
    552     AccessibilityChildrenVector errorMessageForObjects() const override;
    553     AccessibilityChildrenVector flowToObjects() const override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::FlowToObjects)); }
    554     AccessibilityChildrenVector flowFromObjects() const override;
    555     AccessibilityChildrenVector labelledByObjects() const override;
    556     AccessibilityChildrenVector labelForObjects() const override;
    557     AccessibilityChildrenVector ownedObjects() const override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::OwnedObjects)); }
    558     AccessibilityChildrenVector owners() const override;
     544    AccessibilityChildrenVector relatedObjects(AXRelationType) const override;
    559545
    560546    bool hasDatalist() const override;
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp

    r294894 r295139  
    618618}
    619619
     620std::optional<Vector<AXID>> AXIsolatedTree::relatedObjectIDsFor(const AXCoreObject& object, AXRelationType relationType)
     621{
     622    ASSERT(!isMainThread());
     623
     624    if (m_relationsNeedUpdate) {
     625        m_relations = Accessibility::retrieveValueFromMainThread<HashMap<AXID, AXRelations>>([this] () -> HashMap<AXID, AXRelations> {
     626            if (auto* cache = axObjectCache())
     627                return cache->relations();
     628            return { };
     629        });
     630        m_relationsNeedUpdate = false;
     631    }
     632
     633    auto relationsIterator = m_relations.find(object.objectID());
     634    if (relationsIterator == m_relations.end())
     635        return std::nullopt;
     636
     637    auto targetsIterator = relationsIterator->value.find(static_cast<uint8_t>(relationType));
     638    if (targetsIterator == relationsIterator->value.end())
     639        return std::nullopt;
     640    return targetsIterator->value;
     641}
     642
    620643void AXIsolatedTree::applyPendingChanges()
    621644{
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h

    r294894 r295139  
    9393    ComputedRoleString,
    9494    Contents,
    95     ControlledObjects,
    9695    CurrentState,
    9796    CurrentValue,
    … …  
    9998    DecrementButton,
    10099    Description,
    101     DetailedByObjects,
    102100    DisclosedByRow,
    103101    DisclosedRows,
    … …  
    108106    EditableAncestor,
    109107    EmbeddedImageDescription,
    110     ErrorMessageObjects,
    111108    ExpandedTextValue,
    112109    FileUploadButtonReturnsValueInTitle,
    113     FlowToObjects,
    114110    FocusableAncestor,
    115111    HasARIAValueNow,
    … …  
    251247    MinValueForRange,
    252248    NameAttribute,
    253     OwnedObjects,
    254249    Orientation,
    255250    OuterHTML,
    … …  
    372367    void setFocusedNodeID(AXID);
    373368
     369    // Relationships between objects.
     370    std::optional<Vector<AXID>> relatedObjectIDsFor(const AXCoreObject&, AXRelationType);
     371    void relationsNeedUpdate(bool needUpdate) { m_relationsNeedUpdate = needUpdate; }
     372
    374373    // Called on AX thread from WebAccessibilityObjectWrapper methods.
    375374    // During layout tests, it is called on the main thread.
    … …  
    428427    AXID m_focusedNodeID;
    429428    std::atomic<double> m_loadingProgress { 0 };
     429
     430    // Relationships between objects.
     431    // Accessed only on the AX thread.
     432    HashMap<AXID, AXRelations> m_relations;
     433    // Set to true by the AXObjectCache on the main thread.
     434    // Set to false on the AX thread by relatedObjectIDsFor.
     435    std::atomic<bool> m_relationsNeedUpdate { true };
     436
    430437    Lock m_changeLogLock;
    431438};
Note: See TracChangeset for help on using the changeset viewer.