Diff
Modified: trunk/Source/WebCore/ChangeLog (256441 => 256442)
--- trunk/Source/WebCore/ChangeLog 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/ChangeLog 2020-02-12 17:31:03 UTC (rev 256442)
@@ -1,3 +1,49 @@
+2020-02-12 Andres Gonzalez <[email protected]>
+
+ Support event notifications in IsolatedTree mode.
+ https://bugs.webkit.org/show_bug.cgi?id=207581
+
+ Reviewed by Chris Fleizach.
+
+ - DOM/Render trees notifications are listened to by AXObjectCache and
+ the corresponding IsolatedTree is updated.
+ - The update is now happening for state, value and children change
+ notifications.
+ - AXObjectCache::updateIsolatedTree re-generates the subtree rooted at
+ the node receiving the notification.
+ - Consolidated creation of AXIsolatedObjects by passing treeID and
+ parentID to the create method and constructor.
+ - Changes to the IsolatedTree are set on the main thread using the
+ NodeChange structure, and applied to the tree on the AX thread.
+ - The updated IsolatedObjects are attached to their corresponding
+ platform wrappers on the AX thread, so that after creation they are only
+ accessed on the secondary thread.
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::postNotification): Invokes updateIsolatedTree.
+ (WebCore::createIsolatedTreeHierarchy):
+ (WebCore::AXObjectCache::generateIsolatedTree):
+ (WebCore::AXObjectCache::updateIsolatedTree):
+ (WebCore::AXObjectCache::createIsolatedTreeHierarchy): Became a static helper function.
+ * accessibility/AXObjectCache.h:
+ * accessibility/AccessibilityObjectInterface.h:
+ * accessibility/isolatedtree/AXIsolatedObject.cpp:
+ (WebCore::AXIsolatedObject::AXIsolatedObject):
+ (WebCore::AXIsolatedObject::create):
+ (WebCore::AXIsolatedObject::setProperty):
+ (WebCore::AXIsolatedObject::setParent):
+ (WebCore::AXIsolatedObject::detachFromParent):
+ (WebCore::AXIsolatedObject::setTreeIdentifier): Deleted, the tree identifier is set in the constructor.
+ * accessibility/isolatedtree/AXIsolatedObject.h:
+ * accessibility/isolatedtree/AXIsolatedTree.cpp:
+ (WebCore::AXIsolatedTree::NodeChange::NodeChange):
+ (WebCore::AXIsolatedTree::appendNodeChanges):
+ (WebCore::AXIsolatedTree::applyPendingChanges):
+ * accessibility/isolatedtree/AXIsolatedTree.h:
+ * accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm:
+ (WebCore::AXIsolatedObject::attachPlatformWrapper):
+ * accessibility/mac/AXObjectCacheMac.mm:
+
2020-02-12 Zalan Bujtas <[email protected]>
[LFC][IFC] Rename Display::Run::TextContext to TextContent
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (256441 => 256442)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2020-02-12 17:31:03 UTC (rev 256442)
@@ -1118,6 +1118,10 @@
if (!object)
return;
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+ updateIsolatedTree(object, notification);
+#endif
+
if (postType == PostAsynchronously) {
m_notificationsToPost.append(std::make_pair(object, notification));
if (!m_notificationPostTimer.isActive())
@@ -3068,21 +3072,19 @@
}
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
-Ref<AXIsolatedObject> AXObjectCache::createIsolatedTreeHierarchy(AXCoreObject& object, AXID parentID, AXObjectCache* axObjectCache, AXIsolatedTree& tree, Vector<Ref<AXIsolatedObject>>& nodeChanges, bool isRoot)
+static Ref<AXIsolatedObject> createIsolatedTreeHierarchy(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID, bool attachWrapper, Vector<AXIsolatedTree::NodeChange>& nodeChanges)
{
- auto isolatedTreeNode = AXIsolatedObject::create(object, isRoot);
- nodeChanges.append(isolatedTreeNode.copyRef());
+ auto isolatedObject = AXIsolatedObject::create(object, treeID, parentID);
+ nodeChanges.append(AXIsolatedTree::NodeChange(isolatedObject, object.wrapper()));
+ if (attachWrapper)
+ isolatedObject->attachPlatformWrapper(object.wrapper());
- isolatedTreeNode->setTreeIdentifier(tree.treeIdentifier());
- isolatedTreeNode->setParent(parentID);
- axObjectCache->attachWrapper(&isolatedTreeNode.get(), object.wrapper());
-
for (const auto& child : object.children()) {
- auto staticChild = createIsolatedTreeHierarchy(*child, isolatedTreeNode->objectID(), axObjectCache, tree, nodeChanges, false);
- isolatedTreeNode->appendChild(staticChild->objectID());
+ auto staticChild = createIsolatedTreeHierarchy(*child, treeID, isolatedObject->objectID(), attachWrapper, nodeChanges);
+ isolatedObject->appendChild(staticChild->objectID());
}
- return isolatedTreeNode;
+ return isolatedObject;
}
Ref<AXIsolatedTree> AXObjectCache::generateIsolatedTree(PageIdentifier pageID, Document& document)
@@ -3100,8 +3102,8 @@
auto* axRoot = axObjectCache->getOrCreate(document.view());
if (axRoot) {
- Vector<Ref<AXIsolatedObject>> nodeChanges;
- auto isolatedRoot = createIsolatedTreeHierarchy(*axRoot, InvalidAXID, axObjectCache, *tree, nodeChanges, true);
+ Vector<AXIsolatedTree::NodeChange> nodeChanges;
+ auto isolatedRoot = createIsolatedTreeHierarchy(*axRoot, tree->treeIdentifier(), InvalidAXID, true, nodeChanges);
tree->setRootNode(isolatedRoot);
tree->appendNodeChanges(nodeChanges);
}
@@ -3112,6 +3114,32 @@
return makeRef(*tree);
}
+
+void AXObjectCache::updateIsolatedTree(AXCoreObject* object, AXNotification notification)
+{
+ if (!m_pageID)
+ return;
+
+ auto tree = AXIsolatedTree::treeForPageID(*m_pageID);
+ if (!tree)
+ return;
+
+ switch (notification) {
+ case AXCheckedStateChanged:
+ case AXChildrenChanged:
+ case AXValueChanged: {
+ tree->removeNode(object->objectID());
+ auto* parent = object->parentObject();
+ AXID parentID = parent ? parent->objectID() : InvalidAXID;
+ Vector<AXIsolatedTree::NodeChange> nodeChanges;
+ auto isolatedObject = createIsolatedTreeHierarchy(*object, tree->treeIdentifier(), parentID, false, nodeChanges);
+ tree->appendNodeChanges(nodeChanges);
+ break;
+ }
+ default:
+ break;
+ }
+}
#endif
void AXObjectCache::deferRecomputeIsIgnoredIfNeeded(Element* element)
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (256441 => 256442)
--- trunk/Source/WebCore/accessibility/AXObjectCache.h 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h 2020-02-12 17:31:03 UTC (rev 256442)
@@ -25,6 +25,7 @@
#pragma once
+#include "AXIsolatedTree.h"
#include "AXTextStateChangeIntent.h"
#include "AccessibilityObject.h"
#include "Range.h"
@@ -43,10 +44,6 @@
namespace WebCore {
-#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
-class AXIsolatedObject;
-class AXIsolatedTree;
-#endif
class Document;
class HTMLAreaElement;
class HTMLTextFormControlElement;
@@ -178,9 +175,6 @@
using DOMObjectVariant = Variant<std::nullptr_t, RenderObject*, Node*, Widget*>;
void cacheAndInitializeWrapper(AccessibilityObject*, DOMObjectVariant = nullptr);
void attachWrapper(AXCoreObject*);
-#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
- void attachWrapper(AXIsolatedObject*, WebAccessibilityObjectWrapper*);
-#endif
public:
void childrenChanged(Node*, Node* newChild = nullptr);
@@ -199,17 +193,6 @@
void deferAttributeChangeIfNeeded(const QualifiedName&, Element*);
void recomputeIsIgnored(RenderObject* renderer);
-#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
- WEBCORE_EXPORT static bool clientSupportsIsolatedTree();
-private:
- AXCoreObject* isolatedTreeRootObject();
- static AXCoreObject* isolatedTreeFocusedObject(Document&);
- void setIsolatedTreeFocusedObject(Node*);
- static Ref<AXIsolatedTree> generateIsolatedTree(PageIdentifier, Document&);
- static Ref<AXIsolatedObject> createIsolatedTreeHierarchy(AXCoreObject&, AXID, AXObjectCache*, AXIsolatedTree&, Vector<Ref<AXIsolatedObject>>&, bool isRoot);
-#endif
-
-public:
WEBCORE_EXPORT bool canUseSecondaryAXThread();
#if ENABLE(ACCESSIBILITY)
@@ -367,8 +350,17 @@
void deferTextReplacementNotificationForTextControl(HTMLTextFormControlElement&, const String& previousValue);
RefPtr<Range> rangeMatchesTextNearRange(RefPtr<Range>, const String&);
-
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+ WEBCORE_EXPORT static bool clientSupportsIsolatedTree();
+private:
+ AXCoreObject* isolatedTreeRootObject();
+ static AXCoreObject* isolatedTreeFocusedObject(Document&);
+ void setIsolatedTreeFocusedObject(Node*);
+ static Ref<AXIsolatedTree> generateIsolatedTree(PageIdentifier, Document&);
+ void updateIsolatedTree(AXCoreObject*, AXNotification);
+#endif
+
protected:
void postPlatformNotification(AXCoreObject*, AXNotification);
void platformHandleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
Modified: trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h (256441 => 256442)
--- trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h 2020-02-12 17:31:03 UTC (rev 256442)
@@ -70,7 +70,6 @@
typedef unsigned AXID;
extern const AXID InvalidAXID;
-typedef unsigned AXIsolatedTreeID;
enum class AccessibilityRole {
Annotation = 1,
Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (256441 => 256442)
--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp 2020-02-12 17:31:03 UTC (rev 256442)
@@ -32,17 +32,20 @@
namespace WebCore {
-AXIsolatedObject::AXIsolatedObject(AXCoreObject& object, bool isRoot)
- : m_id(object.objectID())
+AXIsolatedObject::AXIsolatedObject(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID)
+ : m_treeID(treeID)
+ , m_parentID(parentID)
+ , m_id(object.objectID())
{
ASSERT(isMainThread());
- initializeAttributeData(object, isRoot);
- m_initialized = true;
+ if (auto tree = AXIsolatedTree::treeForID(m_treeID))
+ m_cachedTree = tree;
+ initializeAttributeData(object, parentID == InvalidAXID);
}
-Ref<AXIsolatedObject> AXIsolatedObject::create(AXCoreObject& object, bool isRoot)
+Ref<AXIsolatedObject> AXIsolatedObject::create(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID)
{
- return adoptRef(*new AXIsolatedObject(object, isRoot));
+ return adoptRef(*new AXIsolatedObject(object, treeID, parentID));
}
AXIsolatedObject::~AXIsolatedObject() = default;
@@ -386,7 +389,6 @@
void AXIsolatedObject::setProperty(AXPropertyName propertyName, AttributeValueVariant&& value, bool shouldRemove)
{
- ASSERT(!m_initialized);
ASSERT(isMainThread());
if (shouldRemove)
@@ -404,7 +406,7 @@
void AXIsolatedObject::setParent(AXID parent)
{
ASSERT(isMainThread());
- m_parent = parent;
+ m_parentID = parent;
}
void AXIsolatedObject::detachRemoteParts(AccessibilityDetachmentType detachmentType)
@@ -425,16 +427,9 @@
void AXIsolatedObject::detachFromParent()
{
- m_parent = InvalidAXID;
+ m_parentID = InvalidAXID;
}
-void AXIsolatedObject::setTreeIdentifier(AXIsolatedTreeID treeIdentifier)
-{
- m_treeIdentifier = treeIdentifier;
- if (auto tree = AXIsolatedTree::treeForID(m_treeIdentifier))
- m_cachedTree = tree;
-}
-
const AXCoreObject::AccessibilityChildrenVector& AXIsolatedObject::children(bool)
{
if (!isMainThread()) {
Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (256441 => 256442)
--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h 2020-02-12 17:31:03 UTC (rev 256442)
@@ -47,7 +47,7 @@
class AXIsolatedObject final : public AXCoreObject {
public:
- static Ref<AXIsolatedObject> create(AXCoreObject&, bool isRoot);
+ static Ref<AXIsolatedObject> create(AXCoreObject&, AXIsolatedTreeID, AXID parentID);
~AXIsolatedObject();
void setObjectID(AXID id) override { m_id = id; }
@@ -54,9 +54,9 @@
AXID objectID() const override { return m_id; }
void init() override { }
+ void attachPlatformWrapper(AccessibilityObjectWrapper*);
bool isDetached() const override;
- void setTreeIdentifier(AXIsolatedTreeID);
void setParent(AXID);
void appendChild(AXID);
@@ -64,13 +64,13 @@
void detachRemoteParts(AccessibilityDetachmentType) override;
void detachPlatformWrapper(AccessibilityDetachmentType) override;
- AXID parent() const { return m_parent; }
+ AXID parent() const { return m_parentID; }
- AXIsolatedTreeID treeIdentifier() const { return m_treeIdentifier; }
+ AXIsolatedTreeID treeIdentifier() const { return m_treeID; }
AXIsolatedTree* tree() const { return m_cachedTree.get(); }
AXIsolatedObject() = default;
- AXIsolatedObject(AXCoreObject&, bool isRoot);
+ AXIsolatedObject(AXCoreObject&, AXIsolatedTreeID, AXID parentID);
void initializeAttributeData(AXCoreObject&, bool isRoot);
AXCoreObject* associatedAXObject() const
{
@@ -821,11 +821,10 @@
void updateBackingStore() override;
- AXID m_parent { InvalidAXID };
+ AXIsolatedTreeID m_treeID;
+ RefPtr<AXIsolatedTree> m_cachedTree;
+ AXID m_parentID { InvalidAXID };
AXID m_id { InvalidAXID };
- bool m_initialized { false };
- AXIsolatedTreeID m_treeIdentifier;
- RefPtr<AXIsolatedTree> m_cachedTree;
Vector<AXID> m_childrenIDs;
Vector<RefPtr<AXCoreObject>> m_children;
Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp (256441 => 256442)
--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp 2020-02-12 17:31:03 UTC (rev 256442)
@@ -42,6 +42,18 @@
return ++s_currentTreeID;
}
+AXIsolatedTree::NodeChange::NodeChange(const Ref<AXIsolatedObject>& isolatedObject, AccessibilityObjectWrapper* wrapper)
+ : m_isolatedObject(isolatedObject.copyRef())
+ , m_wrapper(wrapper)
+{
+}
+
+AXIsolatedTree::NodeChange::NodeChange(const NodeChange& other)
+ : m_isolatedObject(other.m_isolatedObject.copyRef())
+ , m_wrapper(other.m_wrapper)
+{
+}
+
HashMap<PageIdentifier, Ref<AXIsolatedTree>>& AXIsolatedTree::treePageCache()
{
static NeverDestroyed<HashMap<PageIdentifier, Ref<AXIsolatedTree>>> map;
@@ -155,11 +167,11 @@
m_pendingRemovals.append(axID);
}
-void AXIsolatedTree::appendNodeChanges(Vector<Ref<AXIsolatedObject>>& log)
+void AXIsolatedTree::appendNodeChanges(const Vector<NodeChange>& log)
{
LockHolder locker { m_changeLogLock };
- for (auto& node : log)
- m_pendingAppends.append(node.copyRef());
+ for (const auto& node : log)
+ m_pendingAppends.append(node);
}
void AXIsolatedTree::applyPendingChanges()
@@ -167,22 +179,23 @@
RELEASE_ASSERT(!isMainThread());
LockHolder locker { m_changeLogLock };
- // We don't clear the pending IDs beacause if the next round of updates does not modify them, then they stay the same
- // value without extra bookkeeping.
m_focusedNodeID = m_pendingFocusedNodeID;
- for (auto& item : m_pendingAppends)
- m_readerThreadNodeMap.add(item->objectID(), WTFMove(item));
- m_pendingAppends.clear();
-
- for (auto& item : m_pendingRemovals) {
+ for (const auto& item : m_pendingRemovals) {
if (auto object = nodeForID(item))
object->detach(AccessibilityDetachmentType::ElementDestroyed);
m_readerThreadNodeMap.remove(item);
}
m_pendingRemovals.clear();
+
+ for (auto& item : m_pendingAppends) {
+ ASSERT(item.m_wrapper);
+ item.m_isolatedObject->attachPlatformWrapper(item.m_wrapper);
+ m_readerThreadNodeMap.add(item.m_isolatedObject->objectID(), item.m_isolatedObject.copyRef());
+ }
+ m_pendingAppends.clear();
}
-
+
} // namespace WebCore
#endif // ENABLE(ACCESSIBILITY_ISOLATED_TREE)
Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h (256441 => 256442)
--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h 2020-02-12 17:31:03 UTC (rev 256442)
@@ -27,6 +27,7 @@
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+#include "AccessibilityObjectInterface.h"
#include "PageIdentifier.h"
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
@@ -34,8 +35,12 @@
namespace WebCore {
+class AXIsolatedObject;
+class AXObjectCache;
class Page;
+typedef unsigned AXIsolatedTreeID;
+
class AXIsolatedTree : public ThreadSafeRefCounted<AXIsolatedTree> {
WTF_MAKE_NONCOPYABLE(AXIsolatedTree); WTF_MAKE_FAST_ALLOCATED;
@@ -56,8 +61,15 @@
RefPtr<AXIsolatedObject> nodeForID(AXID) const;
static RefPtr<AXIsolatedObject> nodeInTreeForID(AXIsolatedTreeID, AXID);
+ struct NodeChange {
+ Ref<AXIsolatedObject> m_isolatedObject;
+ AccessibilityObjectWrapper* m_wrapper;
+ NodeChange(const Ref<AXIsolatedObject>&, AccessibilityObjectWrapper*);
+ NodeChange(const NodeChange&);
+ };
+
// Call on main thread
- void appendNodeChanges(Vector<Ref<AXIsolatedObject>>&);
+ void appendNodeChanges(const Vector<NodeChange>&);
void removeNode(AXID);
void setRootNode(Ref<AXIsolatedObject>&);
@@ -80,7 +92,7 @@
HashMap<AXID, Ref<AXIsolatedObject>> m_readerThreadNodeMap;
// Written to by main thread under lock, accessed and applied by AX thread.
- Vector<Ref<AXIsolatedObject>> m_pendingAppends;
+ Vector<NodeChange> m_pendingAppends;
Vector<AXID> m_pendingRemovals;
AXID m_pendingFocusedNodeID;
Lock m_changeLogLock;
Modified: trunk/Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm (256441 => 256442)
--- trunk/Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm 2020-02-12 17:31:03 UTC (rev 256442)
@@ -32,6 +32,12 @@
namespace WebCore {
+void AXIsolatedObject::attachPlatformWrapper(AccessibilityObjectWrapper* wrapper)
+{
+ [wrapper attachIsolatedObject:this];
+ setWrapper(wrapper);
+}
+
void AXIsolatedObject::detachPlatformWrapper(AccessibilityDetachmentType)
{
[wrapper() detach];
Modified: trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm (256441 => 256442)
--- trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm 2020-02-12 17:27:48 UTC (rev 256441)
+++ trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm 2020-02-12 17:31:03 UTC (rev 256442)
@@ -238,14 +238,6 @@
obj->setWrapper(wrapper.get());
}
-#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
-void AXObjectCache::attachWrapper(AXIsolatedObject* isolatedObject, WebAccessibilityObjectWrapper* wrapper)
-{
- [wrapper attachIsolatedObject:(AXCoreObject*)isolatedObject];
- isolatedObject->setWrapper(wrapper);
-}
-#endif
-
static BOOL axShouldRepostNotificationsForTests = false;
void AXObjectCache::setShouldRepostNotificationsForTests(bool value)