AX: IsolatedTree: Implement more attributes
authorcfleizach@apple.com <cfleizach@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Feb 2019 22:55:33 +0000 (22:55 +0000)
committercfleizach@apple.com <cfleizach@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Feb 2019 22:55:33 +0000 (22:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193911
<rdar://problem/47599217>

Reviewed by Daniel Bates.

Source/WebCore:

Make use of new HIServices SPI to use a secondary AX thread.
Store root node/focused node status in IsolatedTree rather than on the element.
Implement the following attributes: children, parent, isIgnored, isTree, isTreeItem, relativeFrame, speechHint, title, description.
Implement hit-testing using relative-frames.
Ensure that WKAccessibilityWebPageObject queries happen on main thread when they need to.

* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:
* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::generateIsolatedAccessibilityTree):
* accessibility/AXObjectCache.h:
(WebCore::AXObjectCache::focusedUIElementForPage):
* accessibility/AccessibilityAttachment.cpp:
(WebCore::AccessibilityAttachment::accessibilityText const):
(WebCore::AccessibilityAttachment::accessibilityText): Deleted.
* accessibility/AccessibilityAttachment.h:
* accessibility/AccessibilityImageMapLink.cpp:
(WebCore::AccessibilityImageMapLink::accessibilityText const):
(WebCore::AccessibilityImageMapLink::accessibilityText): Deleted.
* accessibility/AccessibilityImageMapLink.h:
* accessibility/AccessibilityMediaControls.cpp:
(WebCore::AccessibilityMediaControl::accessibilityText const):
(WebCore::AccessibilityMediaControl::accessibilityText): Deleted.
* accessibility/AccessibilityMediaControls.h:
* accessibility/AccessibilityNodeObject.cpp:
(WebCore::AccessibilityNodeObject::accessibilityText const):
(WebCore::AccessibilityNodeObject::accessibilityText): Deleted.
* accessibility/AccessibilityNodeObject.h:
* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::convertFrameToSpace const):
(WebCore::AccessibilityObject::relativeFrame const):
(WebCore::AccessibilityObject::elementAccessibilityHitTest const):
(WebCore::AccessibilityObject::focusedUIElement const):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::accessibilityText const):
(WebCore::AccessibilityObject::isLink const): Deleted.
(WebCore::AccessibilityObject::isImage const): Deleted.
(WebCore::AccessibilityObject::isAttachment const): Deleted.
(WebCore::AccessibilityObject::isFileUploadButton const): Deleted.
(WebCore::AccessibilityObject::isImageMapLink const): Deleted.
(WebCore::AccessibilityObject::isMediaControlLabel const): Deleted.
(WebCore::AccessibilityObject::isTree const): Deleted.
(WebCore::AccessibilityObject::isTreeItem const): Deleted.
(WebCore::AccessibilityObject::isScrollbar const): Deleted.
(WebCore::AccessibilityObject::accessibilityHitTest const): Deleted.
(WebCore::AccessibilityObject::accessibilityText): Deleted.
(WebCore::AccessibilityObject::roleValue const): Deleted.
(WebCore::AccessibilityObject::wrapper const): Deleted.
* accessibility/AccessibilityObjectInterface.h: Replaced.
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::isTabItemSelected const):
(WebCore::AccessibilityRenderObject::remoteSVGElementHitTest const):
(WebCore::AccessibilityRenderObject::elementAccessibilityHitTest const):
(WebCore::AccessibilityRenderObject::accessibilityHitTest const):
(WebCore::AccessibilityRenderObject::selectedChildren):
* accessibility/AccessibilityRenderObject.h:
* accessibility/AccessibilitySVGElement.cpp:
(WebCore::AccessibilitySVGElement::accessibilityText const):
(WebCore::AccessibilitySVGElement::accessibilityText): Deleted.
* accessibility/AccessibilitySVGElement.h:
* accessibility/AccessibilityScrollView.cpp:
(WebCore::AccessibilityScrollView::accessibilityHitTest const):
* accessibility/AccessibilityScrollView.h:
* accessibility/ios/AccessibilityObjectIOS.mm:
(WebCore::AccessibilityObject::fileUploadButtonReturnsValueInTitle const):
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper fileUploadButtonReturnsValueInTitle]): Deleted.
* accessibility/isolatedtree: Replaced.
* accessibility/isolatedtree/AXIsolatedTree.cpp: Added.
(WebCore::AXIsolatedTree::treePageCache):
(WebCore::AXIsolatedTree::AXIsolatedTree):
(WebCore::AXIsolatedTree::nodeInTreeForID):
(WebCore::AXIsolatedTree::nodeForID const):
(WebCore::AXIsolatedTree::focusedUIElement):
(WebCore::AXIsolatedTree::setRootNodeID):
(WebCore::AXIsolatedTree::setFocusedNodeID):
(WebCore::AXIsolatedTree::setInitialRequestInProgress):
(WebCore::AXIsolatedTree::applyPendingChanges):
* accessibility/isolatedtree/AXIsolatedTree.h: Added.
* accessibility/isolatedtree/AXIsolatedTreeNode.cpp: Added.
(WebCore::AXIsolatedTreeNode::AXIsolatedTreeNode):
(WebCore::AXIsolatedTreeNode::~AXIsolatedTreeNode):
(WebCore::AXIsolatedTreeNode::initializeAttributeData):
(WebCore::AXIsolatedTreeNode::setProperty):
(WebCore::AXIsolatedTreeNode::setParent):
(WebCore::AXIsolatedTreeNode::setTreeIdentifier):
(WebCore::AXIsolatedTreeNode::focusedUIElement const):
(WebCore::AXIsolatedTreeNode::parentObjectInterfaceUnignored const):
(WebCore::AXIsolatedTreeNode::accessibilityHitTest const):
(WebCore::AXIsolatedTreeNode::tree const):
(WebCore::AXIsolatedTreeNode::rectAttributeValue const):
(WebCore::AXIsolatedTreeNode::stringAttributeValue const):
* accessibility/isolatedtree/AXIsolatedTreeNode.h: Added.
* accessibility/mac/AXObjectCacheMac.mm:
(WebCore::AXObjectCache::associateIsolatedTreeNode):
* accessibility/mac/AccessibilityObjectBase.mm: Added.
(WebCore::AccessibilityObject::speechHintAttributeValue const):
(WebCore::AccessibilityObject::descriptionAttributeValue const):
(WebCore::AccessibilityObject::titleAttributeValue const):
(WebCore::AccessibilityObject::helpTextAttributeValue const):
* accessibility/mac/AccessibilityObjectMac.mm:
(WebCore::AccessibilityObject::fileUploadButtonReturnsValueInTitle const):
* accessibility/mac/WebAccessibilityObjectWrapperBase.h:
* accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
(addChildToArray):
(convertToNSArray):
(-[WebAccessibilityObjectWrapperBase isolatedTreeNode]):
(-[WebAccessibilityObjectWrapperBase detach]):
(-[WebAccessibilityObjectWrapperBase updateObjectBackingStore]):
(-[WebAccessibilityObjectWrapperBase accessibilityObject]):
(-[WebAccessibilityObjectWrapperBase baseAccessibilityTitle]):
(-[WebAccessibilityObjectWrapperBase axBackingObject]):
(-[WebAccessibilityObjectWrapperBase baseAccessibilityDescription]):
(-[WebAccessibilityObjectWrapperBase baseAccessibilitySpeechHint]):
(-[WebAccessibilityObjectWrapperBase baseAccessibilityHelpText]):
(convertPathToScreenSpaceFunction):
(-[WebAccessibilityObjectWrapperBase convertRectToSpace:space:]):
(-[WebAccessibilityObjectWrapperBase ariaLandmarkRoleDescription]):
(-[WebAccessibilityObjectWrapperBase titleTagShouldBeUsedInDescriptionField]): Deleted.
(-[WebAccessibilityObjectWrapperBase fileUploadButtonReturnsValueInTitle]): Deleted.
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper IGNORE_WARNINGS_END]):
(-[WebAccessibilityObjectWrapper childrenVectorSize]):
(-[WebAccessibilityObjectWrapper childrenVectorArray]):
(-[WebAccessibilityObjectWrapper position]):
(-[WebAccessibilityObjectWrapper subrole]):
(-[WebAccessibilityObjectWrapper roleDescription]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
(-[WebAccessibilityObjectWrapper accessibilityFocusedUIElement]):
(-[WebAccessibilityObjectWrapper accessibilityHitTest:]):
(-[WebAccessibilityObjectWrapper accessibilityIndexOfChild:]):
(-[WebAccessibilityObjectWrapper accessibilityArrayAttributeCount:]):
(-[WebAccessibilityObjectWrapper accessibilityArrayAttributeValues:index:maxCount:]):

Source/WebCore/PAL:

* pal/spi/mac/HIServicesSPI.h:

Source/WebKit:

* Platform/spi/mac/AccessibilityPrivSPI.h: Added.
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.h:
* WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.mm:
(-[WKAccessibilityWebPageObjectBase clientSupportsIsolatedTree]):
(-[WKAccessibilityWebPageObjectBase isolatedTreeRootObject]):
(-[WKAccessibilityWebPageObjectBase accessibilityRootObjectWrapper]):
* WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm:
(-[WKAccessibilityWebPageObject IGNORE_WARNINGS_END]):
(-[WKAccessibilityWebPageObject convertScreenPointToRootView:]):
(-[WKAccessibilityWebPageObject accessibilityAttributeValue:]):
(-[WKAccessibilityWebPageObject accessibilityAttributeSizeValue]):
(-[WKAccessibilityWebPageObject accessibilityAttributePositionValue]):
(-[WKAccessibilityWebPageObject accessibilityDataDetectorValue:point:]):
(-[WKAccessibilityWebPageObject accessibilityAttributeValue:forParameter:]):
(-[WKAccessibilityWebPageObject accessibilityHitTest:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241321 268f45cc-cd09-0410-ab3c-d52691b4dbfc

69 files changed:
Source/WebCore/ChangeLog
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/pal/spi/mac/HIServicesSPI.h
Source/WebCore/SourcesCocoa.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/accessibility/AXObjectCache.cpp
Source/WebCore/accessibility/AXObjectCache.h
Source/WebCore/accessibility/AccessibilityAttachment.cpp
Source/WebCore/accessibility/AccessibilityAttachment.h
Source/WebCore/accessibility/AccessibilityImageMapLink.cpp
Source/WebCore/accessibility/AccessibilityImageMapLink.h
Source/WebCore/accessibility/AccessibilityMediaControls.cpp
Source/WebCore/accessibility/AccessibilityMediaControls.h
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/accessibility/AccessibilityNodeObject.h
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityObjectInterface.h
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/AccessibilityRenderObject.h
Source/WebCore/accessibility/AccessibilitySVGElement.cpp
Source/WebCore/accessibility/AccessibilitySVGElement.h
Source/WebCore/accessibility/AccessibilityScrollView.cpp
Source/WebCore/accessibility/AccessibilityScrollView.h
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceComponent.cpp
Source/WebCore/accessibility/ios/AccessibilityObjectIOS.mm
Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp
Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h
Source/WebCore/accessibility/isolatedtree/AXIsolatedTreeNode.cpp
Source/WebCore/accessibility/isolatedtree/AXIsolatedTreeNode.h
Source/WebCore/accessibility/mac/AXObjectCacheMac.mm
Source/WebCore/accessibility/mac/AccessibilityObjectBase.mm [new file with mode: 0644]
Source/WebCore/accessibility/mac/AccessibilityObjectMac.mm
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.h
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
Source/WebCore/loader/EmptyClients.h
Source/WebCore/page/Chrome.cpp
Source/WebCore/page/Chrome.h
Source/WebCore/page/ChromeClient.h
Source/WebCore/platform/HostWindow.h
Source/WebKit/ChangeLog
Source/WebKit/Platform/spi/mac/AccessibilityPrivSPI.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp
Source/WebKit/UIProcess/API/gtk/PageClientImpl.h
Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp
Source/WebKit/UIProcess/API/wpe/PageClientImpl.h
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/UIProcess/mac/PageClientImplMac.h
Source/WebKit/UIProcess/mac/PageClientImplMac.mm
Source/WebKit/UIProcess/win/PageClientImpl.cpp
Source/WebKit/UIProcess/win/PageClientImpl.h
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.h
Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.mm
Source/WebKit/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm
Source/WebKitLegacy/win/AccessibleBase.cpp
Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.cpp
Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.h

index 4f32b97..7722a83 100644 (file)
@@ -1,3 +1,145 @@
+2019-02-12  Chris Fleizach  <cfleizach@apple.com>
+
+        AX: IsolatedTree: Implement more attributes
+        https://bugs.webkit.org/show_bug.cgi?id=193911
+        <rdar://problem/47599217>
+
+        Reviewed by Daniel Bates.
+
+        Make use of new HIServices SPI to use a secondary AX thread.
+        Store root node/focused node status in IsolatedTree rather than on the element.
+        Implement the following attributes: children, parent, isIgnored, isTree, isTreeItem, relativeFrame, speechHint, title, description.
+        Implement hit-testing using relative-frames.
+        Ensure that WKAccessibilityWebPageObject queries happen on main thread when they need to.
+
+        * SourcesCocoa.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::generateIsolatedAccessibilityTree):
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::focusedUIElementForPage):
+        * accessibility/AccessibilityAttachment.cpp:
+        (WebCore::AccessibilityAttachment::accessibilityText const):
+        (WebCore::AccessibilityAttachment::accessibilityText): Deleted.
+        * accessibility/AccessibilityAttachment.h:
+        * accessibility/AccessibilityImageMapLink.cpp:
+        (WebCore::AccessibilityImageMapLink::accessibilityText const):
+        (WebCore::AccessibilityImageMapLink::accessibilityText): Deleted.
+        * accessibility/AccessibilityImageMapLink.h:
+        * accessibility/AccessibilityMediaControls.cpp:
+        (WebCore::AccessibilityMediaControl::accessibilityText const):
+        (WebCore::AccessibilityMediaControl::accessibilityText): Deleted.
+        * accessibility/AccessibilityMediaControls.h:
+        * accessibility/AccessibilityNodeObject.cpp:
+        (WebCore::AccessibilityNodeObject::accessibilityText const):
+        (WebCore::AccessibilityNodeObject::accessibilityText): Deleted.
+        * accessibility/AccessibilityNodeObject.h:
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::convertFrameToSpace const):
+        (WebCore::AccessibilityObject::relativeFrame const):
+        (WebCore::AccessibilityObject::elementAccessibilityHitTest const):
+        (WebCore::AccessibilityObject::focusedUIElement const):
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::accessibilityText const):
+        (WebCore::AccessibilityObject::isLink const): Deleted.
+        (WebCore::AccessibilityObject::isImage const): Deleted.
+        (WebCore::AccessibilityObject::isAttachment const): Deleted.
+        (WebCore::AccessibilityObject::isFileUploadButton const): Deleted.
+        (WebCore::AccessibilityObject::isImageMapLink const): Deleted.
+        (WebCore::AccessibilityObject::isMediaControlLabel const): Deleted.
+        (WebCore::AccessibilityObject::isTree const): Deleted.
+        (WebCore::AccessibilityObject::isTreeItem const): Deleted.
+        (WebCore::AccessibilityObject::isScrollbar const): Deleted.
+        (WebCore::AccessibilityObject::accessibilityHitTest const): Deleted.
+        (WebCore::AccessibilityObject::accessibilityText): Deleted.
+        (WebCore::AccessibilityObject::roleValue const): Deleted.
+        (WebCore::AccessibilityObject::wrapper const): Deleted.
+        * accessibility/AccessibilityObjectInterface.h: Replaced.
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::isTabItemSelected const):
+        (WebCore::AccessibilityRenderObject::remoteSVGElementHitTest const):
+        (WebCore::AccessibilityRenderObject::elementAccessibilityHitTest const):
+        (WebCore::AccessibilityRenderObject::accessibilityHitTest const):
+        (WebCore::AccessibilityRenderObject::selectedChildren):
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/AccessibilitySVGElement.cpp:
+        (WebCore::AccessibilitySVGElement::accessibilityText const):
+        (WebCore::AccessibilitySVGElement::accessibilityText): Deleted.
+        * accessibility/AccessibilitySVGElement.h:
+        * accessibility/AccessibilityScrollView.cpp:
+        (WebCore::AccessibilityScrollView::accessibilityHitTest const):
+        * accessibility/AccessibilityScrollView.h:
+        * accessibility/ios/AccessibilityObjectIOS.mm:
+        (WebCore::AccessibilityObject::fileUploadButtonReturnsValueInTitle const):
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (-[WebAccessibilityObjectWrapper fileUploadButtonReturnsValueInTitle]): Deleted.
+        * accessibility/isolatedtree: Replaced.
+        * accessibility/isolatedtree/AXIsolatedTree.cpp: Added.
+        (WebCore::AXIsolatedTree::treePageCache):
+        (WebCore::AXIsolatedTree::AXIsolatedTree):
+        (WebCore::AXIsolatedTree::nodeInTreeForID):
+        (WebCore::AXIsolatedTree::nodeForID const):
+        (WebCore::AXIsolatedTree::focusedUIElement):
+        (WebCore::AXIsolatedTree::setRootNodeID):
+        (WebCore::AXIsolatedTree::setFocusedNodeID):
+        (WebCore::AXIsolatedTree::setInitialRequestInProgress):
+        (WebCore::AXIsolatedTree::applyPendingChanges):
+        * accessibility/isolatedtree/AXIsolatedTree.h: Added.
+        * accessibility/isolatedtree/AXIsolatedTreeNode.cpp: Added.
+        (WebCore::AXIsolatedTreeNode::AXIsolatedTreeNode):
+        (WebCore::AXIsolatedTreeNode::~AXIsolatedTreeNode):
+        (WebCore::AXIsolatedTreeNode::initializeAttributeData):
+        (WebCore::AXIsolatedTreeNode::setProperty):
+        (WebCore::AXIsolatedTreeNode::setParent):
+        (WebCore::AXIsolatedTreeNode::setTreeIdentifier):
+        (WebCore::AXIsolatedTreeNode::focusedUIElement const):
+        (WebCore::AXIsolatedTreeNode::parentObjectInterfaceUnignored const):
+        (WebCore::AXIsolatedTreeNode::accessibilityHitTest const):
+        (WebCore::AXIsolatedTreeNode::tree const):
+        (WebCore::AXIsolatedTreeNode::rectAttributeValue const):
+        (WebCore::AXIsolatedTreeNode::stringAttributeValue const):
+        * accessibility/isolatedtree/AXIsolatedTreeNode.h: Added.
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::AXObjectCache::associateIsolatedTreeNode):
+        * accessibility/mac/AccessibilityObjectBase.mm: Added.
+        (WebCore::AccessibilityObject::speechHintAttributeValue const):
+        (WebCore::AccessibilityObject::descriptionAttributeValue const):
+        (WebCore::AccessibilityObject::titleAttributeValue const):
+        (WebCore::AccessibilityObject::helpTextAttributeValue const):
+        * accessibility/mac/AccessibilityObjectMac.mm:
+        (WebCore::AccessibilityObject::fileUploadButtonReturnsValueInTitle const):
+        * accessibility/mac/WebAccessibilityObjectWrapperBase.h:
+        * accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
+        (addChildToArray):
+        (convertToNSArray):
+        (-[WebAccessibilityObjectWrapperBase isolatedTreeNode]):
+        (-[WebAccessibilityObjectWrapperBase detach]):
+        (-[WebAccessibilityObjectWrapperBase updateObjectBackingStore]):
+        (-[WebAccessibilityObjectWrapperBase accessibilityObject]):
+        (-[WebAccessibilityObjectWrapperBase baseAccessibilityTitle]):
+        (-[WebAccessibilityObjectWrapperBase axBackingObject]):
+        (-[WebAccessibilityObjectWrapperBase baseAccessibilityDescription]):
+        (-[WebAccessibilityObjectWrapperBase baseAccessibilitySpeechHint]):
+        (-[WebAccessibilityObjectWrapperBase baseAccessibilityHelpText]):
+        (convertPathToScreenSpaceFunction):
+        (-[WebAccessibilityObjectWrapperBase convertRectToSpace:space:]):
+        (-[WebAccessibilityObjectWrapperBase ariaLandmarkRoleDescription]):
+        (-[WebAccessibilityObjectWrapperBase titleTagShouldBeUsedInDescriptionField]): Deleted.
+        (-[WebAccessibilityObjectWrapperBase fileUploadButtonReturnsValueInTitle]): Deleted.
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper IGNORE_WARNINGS_END]):
+        (-[WebAccessibilityObjectWrapper childrenVectorSize]):
+        (-[WebAccessibilityObjectWrapper childrenVectorArray]):
+        (-[WebAccessibilityObjectWrapper position]):
+        (-[WebAccessibilityObjectWrapper subrole]):
+        (-[WebAccessibilityObjectWrapper roleDescription]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+        (-[WebAccessibilityObjectWrapper accessibilityFocusedUIElement]):
+        (-[WebAccessibilityObjectWrapper accessibilityHitTest:]):
+        (-[WebAccessibilityObjectWrapper accessibilityIndexOfChild:]):
+        (-[WebAccessibilityObjectWrapper accessibilityArrayAttributeCount:]):
+        (-[WebAccessibilityObjectWrapper accessibilityArrayAttributeValues:index:maxCount:]):
+
 2019-02-12  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Allow pages to trigger programmatic paste from script on iOS
index 51923df..af09be1 100644 (file)
@@ -1,3 +1,13 @@
+2019-02-12  Chris Fleizach  <cfleizach@apple.com>
+
+        AX: IsolatedTree: Implement more attributes
+        https://bugs.webkit.org/show_bug.cgi?id=193911
+        <rdar://problem/47599217>
+
+        Reviewed by Daniel Bates.
+
+        * pal/spi/mac/HIServicesSPI.h:
+
 2019-02-12  Andy Estes  <aestes@apple.com>
 
         [iOSMac] Enable Parental Controls Content Filtering
index edd9c57..6a0ff03 100644 (file)
@@ -123,6 +123,7 @@ CFTypeID AXTextMarkerRangeGetTypeID();
 CoreDragRef CoreDragGetCurrentDrag();
 OSStatus CoreDragSetImage(CoreDragRef, CGPoint imageOffset, CoreDragImageSpec*, CGSRegionObj imageShape, float overallAlpha);
 const UInt8* AXTextMarkerGetBytePtr(AXTextMarkerRef);
+bool _AXUIElementRequestServicedBySecondaryAXThread(void);
 OSStatus SetApplicationIsDaemon(Boolean);
 
 WTF_EXTERN_C_END
index 91496da..4be0f2c 100644 (file)
@@ -32,6 +32,7 @@ accessibility/ios/AXObjectCacheIOS.mm
 accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
 
 accessibility/mac/AXObjectCacheMac.mm
+accessibility/mac/AccessibilityObjectBase.mm
 accessibility/mac/AccessibilityObjectMac.mm
 accessibility/mac/WebAccessibilityObjectWrapperMac.mm @no-unify
 accessibility/mac/WebAccessibilityObjectWrapperBase.mm @no-unify
index 571fc37..9e58526 100644 (file)
                293EAE1E1356B2FE0067ACF9 /* RuntimeApplicationChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeApplicationChecks.h; sourceTree = "<group>"; };
                29489FC512C00F0300D83F0F /* AccessibilityScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityScrollView.h; sourceTree = "<group>"; };
                29498681195341940072D2BD /* TextUndoInsertionMarkupMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextUndoInsertionMarkupMac.mm; sourceTree = "<group>"; };
+               294BDAE621FF582A0051077B /* AccessibilityObjectBase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessibilityObjectBase.mm; sourceTree = "<group>"; };
                297BE3D916C043D8003316BD /* PlatformSpeechSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformSpeechSynthesizer.cpp; sourceTree = "<group>"; };
                2981ABC4131822EC00D12F2A /* AccessibilityMathMLElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityMathMLElement.cpp; sourceTree = "<group>"; };
                2981CA9D131822EC00D12F2A /* AccessibilityARIAGrid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityARIAGrid.cpp; sourceTree = "<group>"; };
                29A812050FBB9B5200510293 /* mac */ = {
                        isa = PBXGroup;
                        children = (
+                               294BDAE621FF582A0051077B /* AccessibilityObjectBase.mm */,
                                29A812440FBB9CA900510293 /* AccessibilityObjectMac.mm */,
                                29A812470FBB9CA900510293 /* AXObjectCacheMac.mm */,
                                29A812450FBB9CA900510293 /* WebAccessibilityObjectWrapperBase.h */,
index 238a500..f4225ee 100644 (file)
@@ -2948,7 +2948,7 @@ Ref<AXIsolatedTree> AXObjectCache::generateIsolatedAccessibilityTree()
     
     Vector<Ref<AXIsolatedTreeNode>> nodeChanges;
     auto root = createIsolatedAccessibilityTreeHierarchy(*rootObject(), InvalidAXID, *tree, nodeChanges);
-    root->setIsRootNode(true);
+    tree->setRootNodeID(root->identifier());
     tree->appendNodeChanges(nodeChanges);
 
     return makeRef(*tree);
index 1956e1c..3439fad 100644 (file)
@@ -501,7 +501,7 @@ inline void AccessibilityReplacedText::postTextStateChangeNotification(AXObjectC
 inline void AXComputedObjectAttributeCache::setIgnored(AXID, AccessibilityObjectInclusion) { }
 inline AXObjectCache::AXObjectCache(Document& document) : m_document(document), m_notificationPostTimer(*this, &AXObjectCache::notificationPostTimerFired), m_passwordNotificationPostTimer(*this, &AXObjectCache::passwordNotificationPostTimerFired), m_liveRegionChangedPostTimer(*this, &AXObjectCache::liveRegionChangedNotificationPostTimerFired), m_focusModalNodeTimer(*this, &AXObjectCache::focusModalNodeTimerFired), m_performCacheUpdateTimer(*this, &AXObjectCache::performCacheUpdateTimerFired) { }
 inline AXObjectCache::~AXObjectCache() { }
-inline AccessibilityObject* AXObjectCache::focusedUIElementForPage(const Page*) { return nullptr; }
+inline AccessibilityObjectInterface* AXObjectCache::focusedUIElementForPage(const Page*) { return nullptr; }
 inline AccessibilityObject* AXObjectCache::get(RenderObject*) { return nullptr; }
 inline AccessibilityObject* AXObjectCache::get(Node*) { return nullptr; }
 inline AccessibilityObject* AXObjectCache::get(Widget*) { return nullptr; }
index 92aa7f7..edbcb46 100644 (file)
@@ -84,7 +84,7 @@ bool AccessibilityAttachment::computeAccessibilityIsIgnored() const
     return false;
 }
     
-void AccessibilityAttachment::accessibilityText(Vector<AccessibilityText>& textOrder)
+void AccessibilityAttachment::accessibilityText(Vector<AccessibilityText>& textOrder) const
 {
     HTMLAttachmentElement* attachmentElement = this->attachmentElement();
     if (!attachmentElement)
index 06e1b32..4d355d8 100644 (file)
@@ -48,7 +48,7 @@ private:
     String roleDescription() const override;
     float valueForRange() const override;
     bool computeAccessibilityIsIgnored() const override;
-    void accessibilityText(Vector<AccessibilityText>&) override;
+    void accessibilityText(Vector<AccessibilityText>&) const override;
     explicit AccessibilityAttachment(RenderAttachment*);
 };
     
index 98c61a6..e303350 100644 (file)
@@ -93,7 +93,7 @@ URL AccessibilityImageMapLink::url() const
     return m_areaElement->href();
 }
 
-void AccessibilityImageMapLink::accessibilityText(Vector<AccessibilityText>& textOrder)
+void AccessibilityImageMapLink::accessibilityText(Vector<AccessibilityText>& textOrder) const
 {
     String description = accessibilityDescription();
     if (!description.isEmpty())
index d74e30c..b56df36 100644 (file)
@@ -70,7 +70,7 @@ private:
     void detachFromParent() override;
     Path elementPath() const override;
     RenderElement* imageMapLinkRenderer() const;
-    void accessibilityText(Vector<AccessibilityText>&) override;
+    void accessibilityText(Vector<AccessibilityText>&) const override;
     bool isImageMapLink() const override { return true; }
     bool supportsPath() const override { return true; }
 
index 24b8cf5..ea2d840 100644 (file)
@@ -138,7 +138,7 @@ const String& AccessibilityMediaControl::controlTypeName() const
     return nullAtom();
 }
 
-void AccessibilityMediaControl::accessibilityText(Vector<AccessibilityText>& textOrder)
+void AccessibilityMediaControl::accessibilityText(Vector<AccessibilityText>& textOrder) const
 {
     String description = accessibilityDescription();
     if (!description.isEmpty())
index 024cd04..148f076 100644 (file)
@@ -53,7 +53,7 @@ protected:
     bool computeAccessibilityIsIgnored() const override;
 
 private:
-    void accessibilityText(Vector<AccessibilityText>&) override;
+    void accessibilityText(Vector<AccessibilityText>&) const override;
 };
 
 
index 15bcb02..666c3e8 100644 (file)
@@ -1473,7 +1473,7 @@ void AccessibilityNodeObject::helpText(Vector<AccessibilityText>& textOrder) con
     }
 }
 
-void AccessibilityNodeObject::accessibilityText(Vector<AccessibilityText>& textOrder)
+void AccessibilityNodeObject::accessibilityText(Vector<AccessibilityText>& textOrder) const
 {
     titleElementText(textOrder);
     alternativeText(textOrder);
index f80582d..29a53bf 100644 (file)
@@ -180,7 +180,7 @@ protected:
 
 private:
     bool isAccessibilityNodeObject() const final { return true; }
-    void accessibilityText(Vector<AccessibilityText>&) override;
+    void accessibilityText(Vector<AccessibilityText>&) const override;
     virtual void titleElementText(Vector<AccessibilityText>&) const;
     void alternativeText(Vector<AccessibilityText>&) const;
     void visibleText(Vector<AccessibilityText>&) const;
index aeed718..940afaf 100644 (file)
@@ -34,6 +34,8 @@
 #include "AccessibilityScrollView.h"
 #include "AccessibilityTable.h"
 #include "AccessibleSetValueEvent.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
 #include "DOMTokenList.h"
 #include "Editing.h"
 #include "Editor.h"
@@ -481,6 +483,39 @@ AccessibilityObject* AccessibilityObject::previousSiblingUnignored(int limit) co
     }
     return previous;
 }
+    
+FloatRect AccessibilityObject::convertFrameToSpace(const FloatRect& frameRect, AccessibilityConversionSpace conversionSpace) const
+{
+    ASSERT(isMainThread());
+    
+    // Find the appropriate scroll view to use to convert the contents to the window.
+    const auto parentAccessibilityScrollView = ancestorAccessibilityScrollView(false /* includeSelf */);
+    auto* parentScrollView = parentAccessibilityScrollView ? parentAccessibilityScrollView->scrollView() : nullptr;
+
+    auto snappedFrameRect = snappedIntRect(IntRect(frameRect));
+    if (parentScrollView)
+        snappedFrameRect = parentScrollView->contentsToRootView(snappedFrameRect);
+    
+    if (conversionSpace == AccessibilityConversionSpace::Screen) {
+        auto page = this->page();
+        if (!page)
+            return snappedFrameRect;
+
+        // If we have an empty chrome client (like SVG) then we should use the page
+        // of the scroll view parent to help us get to the screen rect.
+        if (parentAccessibilityScrollView && page->chrome().client().isEmptyChromeClient())
+            page = parentAccessibilityScrollView->page();
+        
+        snappedFrameRect = page->chrome().rootViewToAccessibilityScreen(snappedFrameRect);
+    }
+    
+    return snappedFrameRect;
+}
+    
+FloatRect AccessibilityObject::relativeFrame() const
+{
+    return convertFrameToSpace(elementRect(), AccessibilityConversionSpace::Page);
+}
 
 AccessibilityObject* AccessibilityObject::nextSiblingUnignored(int limit) const
 {
@@ -1793,13 +1828,18 @@ void AccessibilityObject::updateBackingStore()
     updateChildrenIfNecessary();
 }
 #endif
-    
-ScrollView* AccessibilityObject::scrollViewAncestor() const
+
+const AccessibilityScrollView* AccessibilityObject::ancestorAccessibilityScrollView(bool includeSelf) const
 {
-    if (const AccessibilityObject* scrollParent = AccessibilityObject::matchedParent(*this, true, [] (const AccessibilityObject& object) {
+    return downcast<AccessibilityScrollView>(AccessibilityObject::matchedParent(*this, includeSelf, [] (const auto& object) {
         return is<AccessibilityScrollView>(object);
-    }))
-        return downcast<AccessibilityScrollView>(*scrollParent).scrollView();
+    }));
+}
+
+ScrollView* AccessibilityObject::scrollViewAncestor() const
+{
+    if (auto parentScrollView = ancestorAccessibilityScrollView(true/* includeSelf */))
+        return parentScrollView->scrollView();
     
     return nullptr;
 }
@@ -2643,7 +2683,7 @@ bool AccessibilityObject::supportsLiveRegion(bool excludeIfOff) const
     return excludeIfOff ? liveRegionStatusIsEnabled(liveRegionStatusValue) : !liveRegionStatusValue.isEmpty();
 }
 
-AccessibilityObject* AccessibilityObject::elementAccessibilityHitTest(const IntPoint& point) const
+AccessibilityObjectInterface* AccessibilityObject::elementAccessibilityHitTest(const IntPoint& point) const
 { 
     // Send the hit test back into the sub-frame if necessary.
     if (isAttachment()) {
@@ -2672,13 +2712,13 @@ AXObjectCache* AccessibilityObject::axObjectCache() const
     return nullptr;
 }
     
-AccessibilityObject* AccessibilityObject::focusedUIElement() const
+AccessibilityObjectInterface* AccessibilityObject::focusedUIElement() const
 {
-    Document* doc = document();
-    if (!doc)
+    Document* document = this->document();
+    if (!document)
         return nullptr;
     
-    Page* page = doc->page();
+    Page* page = document->page();
     if (!page)
         return nullptr;
     
index f7fb413..780f67f 100644 (file)
@@ -45,9 +45,6 @@
 
 #if PLATFORM(COCOA)
 #include <wtf/RetainPtr.h>
-#elif PLATFORM(WIN)
-#include "AccessibilityObjectWrapperWin.h"
-#include "COMPtr.h"
 #endif
 
 #if PLATFORM(COCOA)
@@ -61,22 +58,13 @@ OBJC_CLASS NSMutableAttributedString;
 OBJC_CLASS NSString;
 OBJC_CLASS NSValue;
 OBJC_CLASS NSView;
-OBJC_CLASS WebAccessibilityObjectWrapper;
-
-typedef WebAccessibilityObjectWrapper AccessibilityObjectWrapper;
 
-#elif PLATFORM(GTK)
-typedef struct _AtkObject AtkObject;
-typedef struct _AtkObject AccessibilityObjectWrapper;
-#elif PLATFORM(WPE)
-class AccessibilityObjectWrapper : public RefCounted<AccessibilityObjectWrapper> { };
-#else
-class AccessibilityObjectWrapper;
 #endif
 
 namespace WebCore {
 
 class AccessibilityObject;
+class AccessibilityScrollView;
 class AXObjectCache;
 class Element;
 class Frame;
@@ -338,7 +326,8 @@ enum class AccessibilityMathScriptObjectType { Subscript, Superscript };
 enum class AccessibilityMathMultiscriptObjectType { PreSubscript, PreSuperscript, PostSubscript, PostSuperscript };
 
 enum class AccessibilityCurrentState { False, True, Page, Step, Location, Date, Time };
-    
+enum class AccessibilityConversionSpace { Screen, Page };
+
 bool nodeHasPresentationRole(Node*);
     
 class AccessibilityObject : public RefCounted<AccessibilityObject>, public AccessibilityObjectInterface {
@@ -372,8 +361,8 @@ public:
 
     virtual bool isAttachmentElement() const { return false; }
     virtual bool isHeading() const { return false; }
-    virtual bool isLink() const { return false; }
-    virtual bool isImage() const { return false; }
+    bool isLink() const override { return false; }
+    bool isImage() const override { return false; }
     virtual bool isImageMap() const { return roleValue() == AccessibilityRole::ImageMap; }
     virtual bool isNativeImage() const { return false; }
     virtual bool isImageButton() const { return false; }
@@ -388,14 +377,14 @@ public:
     virtual bool isNativeListBox() const { return false; }
     bool isListBox() const { return roleValue() == AccessibilityRole::ListBox; }
     virtual bool isListBoxOption() const { return false; }
-    virtual bool isAttachment() const { return false; }
+    bool isAttachment() const override { return false; }
     virtual bool isMediaTimeline() const { return false; }
     virtual bool isMenuRelated() const { return false; }
     virtual bool isMenu() const { return false; }
     virtual bool isMenuBar() const { return false; }
     virtual bool isMenuButton() const { return false; }
     virtual bool isMenuItem() const { return false; }
-    virtual bool isFileUploadButton() const { return false; }
+    bool isFileUploadButton() const override { return false; }
     virtual bool isInputImage() const { return false; }
     virtual bool isProgressIndicator() const { return false; }
     virtual bool isSlider() const { return false; }
@@ -412,7 +401,7 @@ public:
     virtual bool isFieldset() const { return false; }
     virtual bool isGroup() const { return false; }
     virtual bool isARIATreeGridRow() const { return false; }
-    virtual bool isImageMapLink() const { return false; }
+    bool isImageMapLink() const override { return false; }
     virtual bool isMenuList() const { return false; }
     virtual bool isMenuListPopup() const { return false; }
     virtual bool isMenuListOption() const { return false; }
@@ -420,7 +409,7 @@ public:
     virtual bool isNativeSpinButton() const { return false; }
     virtual bool isSpinButtonPart() const { return false; }
     virtual bool isMockObject() const { return false; }
-    virtual bool isMediaControlLabel() const { return false; }
+    bool isMediaControlLabel() const override { return false; }
     virtual bool isMediaObject() const { return false; }
     bool isSwitch() const { return roleValue() == AccessibilityRole::Switch; }
     bool isToggleButton() const { return roleValue() == AccessibilityRole::ToggleButton; }
@@ -431,10 +420,10 @@ public:
     bool isTabItem() const { return roleValue() == AccessibilityRole::Tab; }
     bool isRadioGroup() const { return roleValue() == AccessibilityRole::RadioGroup; }
     bool isComboBox() const { return roleValue() == AccessibilityRole::ComboBox; }
-    bool isTree() const { return roleValue() == AccessibilityRole::Tree; }
+    bool isTree() const override { return roleValue() == AccessibilityRole::Tree; }
     bool isTreeGrid() const { return roleValue() == AccessibilityRole::TreeGrid; }
-    bool isTreeItem() const { return roleValue() == AccessibilityRole::TreeItem; }
-    bool isScrollbar() const { return roleValue() == AccessibilityRole::ScrollBar; }
+    bool isTreeItem() const override { return roleValue() == AccessibilityRole::TreeItem; }
+    bool isScrollbar() const override { return roleValue() == AccessibilityRole::ScrollBar; }
     bool isButton() const;
     bool isListItem() const { return roleValue() == AccessibilityRole::ListItem; }
     bool isCheckboxOrRadio() const { return isCheckbox() || isRadioButton(); }
@@ -474,6 +463,8 @@ public:
     virtual bool isVisible() const { return true; }
     virtual bool isCollapsed() const { return false; }
     virtual void setIsExpanded(bool) { }
+    FloatRect relativeFrame() const override;
+    FloatRect convertFrameToSpace(const FloatRect&, AccessibilityConversionSpace) const;
 
     // In a multi-select list, many items can be selected but only one is active at a time.
     virtual bool isSelectedOptionActive() const { return false; }
@@ -503,7 +494,7 @@ public:
     virtual Element* element() const;
     virtual Node* node() const { return nullptr; }
     virtual RenderObject* renderer() const { return nullptr; }
-    virtual bool accessibilityIsIgnored() const;
+    bool accessibilityIsIgnored() const override;
     virtual AccessibilityObjectInclusion defaultObjectInclusion() const;
     bool accessibilityIsIgnoredByDefault() const;
     
@@ -584,11 +575,11 @@ public:
     virtual Vector<String> determineARIADropEffects() { return { }; }
     
     // Called on the root AX object to return the deepest available element.
-    virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const { return nullptr; }
+    AccessibilityObjectInterface* accessibilityHitTest(const IntPoint&) const override { return nullptr; }
     // Called on the AX object after the render tree determines which is the right AccessibilityRenderObject.
-    virtual AccessibilityObject* elementAccessibilityHitTest(const IntPoint&) const;
+    virtual AccessibilityObjectInterface* elementAccessibilityHitTest(const IntPoint&) const;
 
-    virtual AccessibilityObject* focusedUIElement() const;
+    AccessibilityObjectInterface* focusedUIElement() const override;
 
     virtual AccessibilityObject* firstChild() const { return nullptr; }
     virtual AccessibilityObject* lastChild() const { return nullptr; }
@@ -598,6 +589,7 @@ public:
     virtual AccessibilityObject* previousSiblingUnignored(int limit) const;
     virtual AccessibilityObject* parentObject() const = 0;
     virtual AccessibilityObject* parentObjectUnignored() const;
+    AccessibilityObjectInterface* parentObjectInterfaceUnignored() const override { return parentObjectUnignored(); }
     virtual AccessibilityObject* parentObjectIfExists() const { return nullptr; }
     static AccessibilityObject* firstAccessibleObjectFromNode(const Node*);
     void findMatchingObjects(AccessibilitySearchCriteria*, AccessibilityChildrenVector&);
@@ -624,7 +616,7 @@ public:
     virtual bool inheritsPresentationalRole() const { return false; }
 
     // Accessibility Text
-    virtual void accessibilityText(Vector<AccessibilityText>&) { };
+    virtual void accessibilityText(Vector<AccessibilityText>&) const { };
     // A single method for getting a computed label for an AXObject. It condenses the nuances of accessibilityText. Used by Inspector.
     String computedLabel();
     
@@ -657,7 +649,7 @@ public:
     // Only if isColorWell()
     virtual void colorValue(int& r, int& g, int& b) const { r = 0; g = 0; b = 0; }
 
-    virtual AccessibilityRole roleValue() const { return m_role; }
+    AccessibilityRole roleValue() const override { return m_role; }
 
     virtual AXObjectCache* axObjectCache() const;
     AXID axObjectID() const { return m_id; }
@@ -727,7 +719,7 @@ public:
     
     virtual bool canHaveChildren() const { return true; }
     virtual bool hasChildren() const { return m_haveChildren; }
-    virtual void updateChildrenIfNecessary();
+    void updateChildrenIfNecessary() override;
     virtual void setNeedsToUpdateChildren() { }
     virtual void setNeedsToUpdateSubtree() { }
     virtual void clearChildren();
@@ -946,7 +938,7 @@ public:
     AccessibilityObjectWrapper* wrapper() const;
     void setWrapper(AccessibilityObjectWrapper*);
 #else
-    AccessibilityObjectWrapper* wrapper() const { return m_wrapper.get(); }
+    AccessibilityObjectWrapper* wrapper() const override { return m_wrapper.get(); }
     void setWrapper(AccessibilityObjectWrapper* wrapper) 
     {
         m_wrapper = wrapper;
@@ -984,6 +976,11 @@ public:
 #if PLATFORM(COCOA)
     bool preventKeyboardDOMEventDispatch() const;
     void setPreventKeyboardDOMEventDispatch(bool);
+    bool fileUploadButtonReturnsValueInTitle() const;
+    String speechHintAttributeValue() const override;
+    String descriptionAttributeValue() const override;
+    String helpTextAttributeValue() const override;
+    String titleAttributeValue() const override;
 #endif
     
 #if PLATFORM(COCOA) && !PLATFORM(IOS_FAMILY)
@@ -994,7 +991,8 @@ public:
     AccessibilityObject* focusableAncestor();
     AccessibilityObject* editableAncestor();
     AccessibilityObject* highestEditableAncestor();
-    
+
+    const AccessibilityScrollView* ancestorAccessibilityScrollView(bool includeSelf) const;
     static const AccessibilityObject* matchedParent(const AccessibilityObject&, bool includeSelf, const WTF::Function<bool(const AccessibilityObject&)>&);
     
     void clearIsIgnoredFromParentData() { m_isIgnoredFromParentData = AccessibilityIsIgnoredFromParentData(); }
@@ -1016,7 +1014,8 @@ protected:
     void setIsIgnoredFromParentData(AccessibilityIsIgnoredFromParentData& data) { m_isIgnoredFromParentData = data; }
 
     virtual bool computeAccessibilityIsIgnored() const { return true; }
-
+    bool isAccessibilityObject() const override { return true; }
+    
     // If this object itself scrolls, return its ScrollableArea.
     virtual ScrollableArea* getScrollableAreaIfScrollable() const { return nullptr; }
     virtual void scrollTo(const IntPoint&) const { }
@@ -1068,3 +1067,7 @@ inline void AccessibilityObject::updateBackingStore() { }
 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
     static bool isType(const WebCore::AccessibilityObject& object) { return object.predicate; } \
 SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::AccessibilityObject)
+static bool isType(const WebCore::AccessibilityObjectInterface& context) { return context.isAccessibilityObject(); }
+SPECIALIZE_TYPE_TRAITS_END()
index 7abd287..27c3321 100644 (file)
 
 #pragma once
 
+#include "LayoutRect.h"
+#include <wtf/RefCounted.h>
+
+#if PLATFORM(WIN)
+#include "AccessibilityObjectWrapperWin.h"
+#include "COMPtr.h"
+#endif
+
+#if PLATFORM(COCOA)
+OBJC_CLASS WebAccessibilityObjectWrapper;
+typedef WebAccessibilityObjectWrapper AccessibilityObjectWrapper;
+#elif PLATFORM(GTK)
+typedef struct _AtkObject AtkObject;
+typedef struct _AtkObject AccessibilityObjectWrapper;
+#elif PLATFORM(WPE)
+class AccessibilityObjectWrapper : public RefCounted<AccessibilityObjectWrapper> { };
+#else
+class AccessibilityObjectWrapper;
+#endif
+
 namespace WebCore {
 
 typedef unsigned AXID;
 extern const AXID InvalidAXID;
+typedef unsigned AXIsolatedTreeID;    
 
 enum class AccessibilityRole {
     Annotation = 1,
@@ -186,6 +207,29 @@ public:
     virtual bool isMediaControlLabel() const = 0;
     virtual AccessibilityRole roleValue() const = 0;
     virtual bool isAttachment() const = 0;
+    virtual bool isLink() const = 0;
+    virtual bool isImageMapLink() const = 0;
+    virtual bool isImage() const = 0;
+    virtual bool isFileUploadButton() const = 0;
+    virtual bool isTree() const = 0;
+    virtual bool isTreeItem() const = 0;
+    virtual bool isScrollbar() const = 0;
+    virtual bool accessibilityIsIgnored() const = 0;
+    virtual FloatRect relativeFrame() const = 0;
+    virtual AccessibilityObjectInterface* parentObjectInterfaceUnignored() const = 0;
+    virtual AccessibilityObjectInterface* focusedUIElement() const = 0;
+    virtual bool isAccessibilityObject() const { return false; }
+    
+#if PLATFORM(COCOA)
+    virtual String speechHintAttributeValue() const = 0;
+    virtual String descriptionAttributeValue() const = 0;
+    virtual String helpTextAttributeValue() const = 0;
+    virtual String titleAttributeValue() const = 0;
+#endif
+
+    virtual AccessibilityObjectWrapper* wrapper() const = 0;
+    virtual AccessibilityObjectInterface* accessibilityHitTest(const IntPoint&) const = 0;
+    virtual void updateChildrenIfNecessary() = 0;
 };
 
-}
+} // namespace WebCore
index 94233f0..4ca302d 100644 (file)
@@ -1660,7 +1660,7 @@ bool AccessibilityRenderObject::isTabItemSelected() const
     // The ARIA spec says a tab item can also be selected if it is aria-labeled by a tabpanel
     // that has keyboard focus inside of it, or if a tabpanel in its aria-controls list has KB
     // focus inside of it.
-    AccessibilityObject* focusedElement = focusedUIElement();
+    AccessibilityObject* focusedElement = static_cast<AccessibilityObject*>(focusedUIElement());
     if (!focusedElement)
         return false;
     
@@ -2335,7 +2335,7 @@ AccessibilityObject* AccessibilityRenderObject::accessibilityImageMapHitTest(HTM
     return nullptr;
 }
 
-AccessibilityObject* AccessibilityRenderObject::remoteSVGElementHitTest(const IntPoint& point) const
+AccessibilityObjectInterface* AccessibilityRenderObject::remoteSVGElementHitTest(const IntPoint& point) const
 {
     AccessibilityObject* remote = remoteSVGRootElement(Create);
     if (!remote)
@@ -2345,7 +2345,7 @@ AccessibilityObject* AccessibilityRenderObject::remoteSVGElementHitTest(const In
     return remote->accessibilityHitTest(IntPoint(offset));
 }
 
-AccessibilityObject* AccessibilityRenderObject::elementAccessibilityHitTest(const IntPoint& point) const
+AccessibilityObjectInterface* AccessibilityRenderObject::elementAccessibilityHitTest(const IntPoint& point) const
 {
     if (isSVGImage())
         return remoteSVGElementHitTest(point);
@@ -2359,7 +2359,7 @@ static bool shouldUseShadowHostForHitTesting(Node* shadowHost)
     return shadowHost && !shadowHost->hasTagName(videoTag);
 }
 
-AccessibilityObject* AccessibilityRenderObject::accessibilityHitTest(const IntPoint& point) const
+AccessibilityObjectInterface* AccessibilityRenderObject::accessibilityHitTest(const IntPoint& point) const
 {
     if (!m_renderer || !m_renderer->hasLayer())
         return nullptr;
@@ -2393,7 +2393,7 @@ AccessibilityObject* AccessibilityRenderObject::accessibilityHitTest(const IntPo
     result->updateChildrenIfNecessary();
 
     // Allow the element to perform any hit-testing it might need to do to reach non-render children.
-    result = result->elementAccessibilityHitTest(point);
+    result = static_cast<AccessibilityObject*>(result->elementAccessibilityHitTest(point));
     
     if (result && result->accessibilityIsIgnored()) {
         // If this element is the label of a control, a hit test should return the control.
@@ -3444,7 +3444,7 @@ void AccessibilityRenderObject::selectedChildren(AccessibilityChildrenVector& re
             result.append(descendant);
             return;
         }
-        if (AccessibilityObject* focusedElement = focusedUIElement()) {
+        if (AccessibilityObject* focusedElement = static_cast<AccessibilityObject*>(focusedUIElement())) {
             result.append(focusedElement);
             return;
         }
index 003f183..a47571c 100644 (file)
@@ -106,7 +106,7 @@ public:
     bool ariaRoleHasPresentationalChildren() const override;
     
     // Should be called on the root accessibility object to kick off a hit test.
-    AccessibilityObject* accessibilityHitTest(const IntPoint&) const override;
+    AccessibilityObjectInterface* accessibilityHitTest(const IntPoint&) const override;
 
     Element* anchorElement() const override;
     
@@ -239,7 +239,7 @@ private:
     AccessibilityObject* internalLinkElement() const;
     AccessibilityObject* accessibilityImageMapHitTest(HTMLAreaElement*, const IntPoint&) const;
     AccessibilityObject* accessibilityParentForImageMap(HTMLMapElement*) const;
-    AccessibilityObject* elementAccessibilityHitTest(const IntPoint&) const override;
+    AccessibilityObjectInterface* elementAccessibilityHitTest(const IntPoint&) const override;
 
     bool renderObjectIsObservable(RenderObject&) const;
     RenderObject* renderParentObject() const;
@@ -249,7 +249,7 @@ private:
     void detachRemoteSVGRoot();
     enum CreationChoice { Create, Retrieve };
     AccessibilitySVGRoot* remoteSVGRootElement(CreationChoice createIfNecessary) const;
-    AccessibilityObject* remoteSVGElementHitTest(const IntPoint&) const;
+    AccessibilityObjectInterface* remoteSVGElementHitTest(const IntPoint&) const;
     void offsetBoundingBoxForRemoteSVGElement(LayoutRect&) const;
     bool supportsPath() const override;
 
index 791bef0..745fefc 100644 (file)
@@ -106,7 +106,7 @@ Element* AccessibilitySVGElement::childElementWithMatchingLanguage(ChildrenType&
     return fallback;
 }
 
-void AccessibilitySVGElement::accessibilityText(Vector<AccessibilityText>& textOrder)
+void AccessibilitySVGElement::accessibilityText(Vector<AccessibilityText>& textOrder) const
 {
     String description = accessibilityDescription();
     if (!description.isEmpty())
index 0d1d28f..f3d14a6 100644 (file)
@@ -44,7 +44,7 @@ protected:
     explicit AccessibilitySVGElement(RenderObject*);
 
 private:
-    void accessibilityText(Vector<AccessibilityText>&) final;
+    void accessibilityText(Vector<AccessibilityText>&) const final;
     AccessibilityRole determineAccessibilityRole() final;
     AccessibilityRole determineAriaRoleAttribute() const final;
     bool inheritsPresentationalRole() const final;
index 2a62393..5178b9f 100644 (file)
@@ -199,7 +199,7 @@ AccessibilityObject* AccessibilityScrollView::webAreaObject() const
     return nullptr;
 }
 
-AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
+AccessibilityObjectInterface* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
 {
     AccessibilityObject* webArea = webAreaObject();
     if (!webArea)
index 9f452cb..66ff594 100644 (file)
@@ -59,7 +59,7 @@ private:
     AccessibilityObject* scrollBar(AccessibilityOrientation) override;
     void addChildren() override;
     void clearChildren() override;
-    AccessibilityObject* accessibilityHitTest(const IntPoint&) const override;
+    AccessibilityObjectInterface* accessibilityHitTest(const IntPoint&) const override;
     void updateChildrenIfNecessary() override;
     void setNeedsToUpdateChildren() override { m_childrenDirty = true; }
     void updateScrollbars();
index 439fe96..f6b754a 100644 (file)
@@ -77,7 +77,7 @@ static AtkObject* webkitAccessibleComponentRefAccessibleAtPoint(AtkComponent* co
 
     IntPoint pos = atkToContents(core(component), coordType, x, y);
 
-    AccessibilityObject* target = core(component)->accessibilityHitTest(pos);
+    AccessibilityObject* target = downcast<AccessibilityObject>(core(component)->accessibilityHitTest(pos));
     if (!target)
         return 0;
     g_object_ref(target->wrapper());
index 2f8583b..404e9e0 100644 (file)
@@ -41,6 +41,12 @@ void AccessibilityObject::detachFromParent()
 {
 }
 
+// On iOS, we don't have to return the value in the title. We can return the actual title, given the API.
+bool AccessibilityObject::fileUploadButtonReturnsValueInTitle() const
+{
+    return false;
+}
+
 void AccessibilityObject::overrideAttachmentParent(AccessibilityObject*)
 {
 }
index 69ed007..1487ddc 100644 (file)
@@ -388,7 +388,7 @@ static AccessibilityObjectWrapper* AccessibilityUnignoredAncestor(AccessibilityO
         return nil;
     
     // Try a fuzzy hit test first to find an accessible element.
-    RefPtr<AccessibilityObject> axObject;
+    AccessibilityObjectInterface *axObject = nullptr;
     {
         AXAttributeCacheEnabler enableCache(m_object->axObjectCache());
         axObject = m_object->accessibilityHitTest(IntPoint(point));
@@ -1056,11 +1056,6 @@ static AccessibilityObjectWrapper* AccessibilityUnignoredAncestor(AccessibilityO
     return YES;
 }
 
-- (BOOL)fileUploadButtonReturnsValueInTitle
-{
-    return NO;
-}
-
 static void appendStringToResult(NSMutableString *result, NSString *string)
 {
     ASSERT(result);
@@ -1520,7 +1515,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     
     auto floatPoint = FloatPoint(point);
     auto floatRect = FloatRect(floatPoint, FloatSize());
-    return [self convertRectToSpace:floatRect space:ScreenSpace].origin;
+    return [self convertRectToSpace:floatRect space:AccessibilityConversionSpace::Screen].origin;
 }
 
 - (BOOL)accessibilityPerformEscape
@@ -1584,7 +1579,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
 - (CGRect)_accessibilityRelativeFrame
 {
     auto rect = FloatRect(snappedIntRect(m_object->elementRect()));
-    return [self convertRectToSpace:rect space:PageSpace];
+    return [self convertRectToSpace:rect space:AccessibilityConversionSpace::Page];
 }
 
 // Used by UIKit accessibility bundle to help determine distance during a hit-test.
@@ -1606,7 +1601,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     if (!document || !document->view())
         return CGRectZero;
     auto rect = FloatRect(snappedIntRect(document->view()->unobscuredContentRect()));
-    return [self convertRectToSpace:rect space:ScreenSpace];
+    return [self convertRectToSpace:rect space:AccessibilityConversionSpace::Screen];
 }
 
 // The "center point" is where VoiceOver will "press" an object. This may not be the actual
@@ -1617,7 +1612,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
         return CGPointZero;
     
     auto rect = FloatRect(snappedIntRect(m_object->boundingBoxRect()));
-    CGRect cgRect = [self convertRectToSpace:rect space:ScreenSpace];
+    CGRect cgRect = [self convertRectToSpace:rect space:AccessibilityConversionSpace::Screen];
     return CGPointMake(CGRectGetMidX(cgRect), CGRectGetMidY(cgRect));
 }
 
@@ -1627,7 +1622,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
         return CGRectZero;
     
     auto rect = FloatRect(snappedIntRect(m_object->elementRect()));
-    return [self convertRectToSpace:rect space:ScreenSpace];
+    return [self convertRectToSpace:rect space:AccessibilityConversionSpace::Screen];
 }
 
 // Checks whether a link contains only static text and images (and has been divided unnaturally by <spans> and other nefarious mechanisms).
@@ -1690,7 +1685,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     if (![self _prepareAccessibilityCall])
         return nil;
     
-    AccessibilityObject* focusedObj = m_object->focusedUIElement();
+    AccessibilityObject* focusedObj = downcast<AccessibilityObject>(m_object->focusedUIElement());
     
     if (!focusedObj)
         return nil;
@@ -1997,7 +1992,7 @@ static RenderObject* rendererForView(WAKView* view)
     AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(parameters);
     AccessibilityObject::AccessibilityChildrenVector results;
     m_object->findMatchingObjects(&criteria, results);
-    return convertToNSArray(results);
+    return (NSArray *)convertToNSArray(results);
 }
 
 - (void)accessibilityElementDidBecomeFocused
@@ -2672,7 +2667,7 @@ static void AXAttributedStringAppendText(NSMutableAttributedString* attrString,
         return CGRectZero;
     
     auto rect = FloatRect(m_object->boundsForRange(range));
-    return [self convertRectToSpace:rect space:ScreenSpace];
+    return [self convertRectToSpace:rect space:AccessibilityConversionSpace::Screen];
 }
 
 - (RefPtr<Range>)rangeFromMarkers:(NSArray *)markers withText:(NSString *)text
@@ -2718,7 +2713,7 @@ static void AXAttributedStringAppendText(NSMutableAttributedString* attrString,
     for (unsigned i = 0; i < size; i++) {
         const WebCore::SelectionRect& coreRect = selectionRects[i];
         auto selectionRect = FloatRect(coreRect.rect());
-        CGRect rect = [self convertRectToSpace:selectionRect space:ScreenSpace];
+        CGRect rect = [self convertRectToSpace:selectionRect space:AccessibilityConversionSpace::Screen];
         [rects addObject:[NSValue valueWithRect:rect]];
     }
     
index 4fc15d7..c9c2f3a 100644 (file)
@@ -42,9 +42,9 @@ static unsigned newTreeID()
     return ++s_currentTreeID;
 }
 
-HashMap<AXIsolatedTreeID, Ref<AXIsolatedTree>>& AXIsolatedTree::treePageCache()
+HashMap<uint64_t, Ref<AXIsolatedTree>>& AXIsolatedTree::treePageCache()
 {
-    static NeverDestroyed<HashMap<AXIsolatedTreeID, Ref<AXIsolatedTree>>> map;
+    static NeverDestroyed<HashMap<uint64_t, Ref<AXIsolatedTree>>> map;
     return map;
 }
 
@@ -67,6 +67,21 @@ Ref<AXIsolatedTree> AXIsolatedTree::create()
     return adoptRef(*new AXIsolatedTree());
 }
 
+Ref<AXIsolatedTree> AXIsolatedTree::initializePageTreeForID(uint64_t pageID, AXObjectCache& cache)
+{
+    RELEASE_ASSERT(isMainThread());
+    auto tree = cache->generateIsolatedAccessibilityTree();
+    tree->setInitialRequestI\ 1nProgress(true);
+    tree->applyPendingChanges();
+    tree->setInitialRequestInProgress(false);
+    return tree;
+}
+
+RefPtr<AXIsolatedTreeNode> AXIsolatedTree::nodeInTreeForID(AXIsolatedTreeID treeID, AXID axID)
+{
+    return treeForID(treeID)->nodeForID(axID);
+}
+
 RefPtr<AXIsolatedTree> AXIsolatedTree::treeForID(AXIsolatedTreeID treeID)
 {
     return treeIDCache().get(treeID);
@@ -94,44 +109,69 @@ RefPtr<AXIsolatedTree> AXIsolatedTree::treeForPageID(uint64_t pageID)
 
 RefPtr<AXIsolatedTreeNode> AXIsolatedTree::nodeForID(AXID axID) const
 {
-    ASSERT(!isMainThread());
+    RELEASE_ASSERT(!isMainThread() || initialRequest);
     if (!axID)
         return nullptr;
     return m_readerThreadNodeMap.get(axID);
 }
 
+RefPtr<AXIsolatedTreeNode> AXIsolatedTree::focusedUIElement()
+{
+    return nodeForID(m_focusedNodeID);
+}
+    
 RefPtr<AXIsolatedTreeNode> AXIsolatedTree::rootNode()
 {
     return nodeForID(m_rootNodeID);
 }
 
+void AXIsolatedTree::setRootNodeID(AXID axID)
+{
+    LockHolder locker { m_changeLogLock };
+    m_pendingRootNodeID = axID;
+}
+    
+void AXIsolatedTree::setFocusedNodeID(AXID axID)
+{
+    LockHolder locker { m_changeLogLock };
+    m_pendingFocusedNodeID = axID;
+}
+    
 void AXIsolatedTree::removeNode(AXID axID)
 {
-    LockHolder locker(m_changeLogLock);
+    LockHolder locker { m_changeLogLock };
     m_pendingRemovals.append(axID);
 }
 
 void AXIsolatedTree::appendNodeChanges(Vector<Ref<AXIsolatedTreeNode>>& log)
 {
-    LockHolder locker(m_changeLogLock);
+    LockHolder locker { m_changeLogLock };
     for (auto& node : log)
         m_pendingAppends.append(node.copyRef());
 }
 
-void AXIsolatedTree::applyPendingChanges()
+void AXIsolatedTree::setInitialRequestInProgress(bool initialRequestInProgress)
 {
-    RELEASE_ASSERT(!isMainThread());
+    m_initialRequestInProgress = initialRequestInProgress;
+}
 
-    LockHolder locker(m_changeLogLock);
+void AXIsolatedTree::applyPendingChanges()
+{
+    RELEASE_ASSERT(!isMainThread() || initialRequest);
+    LockHolder locker { m_changeLogLock };
     Vector<Ref<AXIsolatedTreeNode>> appendCopy;
     std::swap(appendCopy, m_pendingAppends);
     Vector<AXID> removeCopy({ WTFMove(m_pendingRemovals) });
     locker.unlockEarly();
 
+    // 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_rootNodeID = m_pendingRootNodeID;
+    m_focusedNodeID = m_pendingFocusedNodeID;
+    
     for (auto& item : appendCopy) {
-        m_readerThreadNodeMap.add(item->identifier(), item.copyRef());
-        if (item->isRootNode())
-            m_rootNodeID = item->identifier();
+        item->setTreeIdentifier(m_treeID);
+        m_readerThreadNodeMap.add(item->identifier(), WTFMove(item));
     }
 
     for (auto item : removeCopy)
index 971f9ea..c075d5b 100644 (file)
@@ -36,48 +36,56 @@ namespace WebCore {
 
 class Page;
 
-typedef unsigned AXIsolatedTreeID;
-    
-class AXIsolatedTree : public ThreadSafeRefCounted<AXIsolatedTree> {
+class AXIsolatedTree : public ThreadSafeRefCounted<AXIsolatedTree>, public CanMakeWeakPtr<AXIsolatedTree> {
     WTF_MAKE_NONCOPYABLE(AXIsolatedTree); WTF_MAKE_FAST_ALLOCATED;
 
 public:
     static Ref<AXIsolatedTree> create();
     virtual ~AXIsolatedTree();
 
-    // Creation must happen on main thread.
     static Ref<AXIsolatedTree> createTreeForPageID(uint64_t pageID);
+    WEBCORE_EXPORT static Ref<AXIsolatedTree> initializePageTreeForID(uint64_t pageID, AXObjectCache&);
     WEBCORE_EXPORT static RefPtr<AXIsolatedTree> treeForPageID(uint64_t pageID);
     WEBCORE_EXPORT static RefPtr<AXIsolatedTree> treeForID(AXIsolatedTreeID);
 
     WEBCORE_EXPORT RefPtr<AXIsolatedTreeNode> rootNode();
+    WEBCORE_EXPORT RefPtr<AXIsolatedTreeNode> focusedUIElement();
     RefPtr<AXIsolatedTreeNode> nodeForID(AXID) const;
+    static RefPtr<AXIsolatedTreeNode> nodeInTreeForID(AXIsolatedTreeID, AXID);
 
     // Call on main thread
     void appendNodeChanges(Vector<Ref<AXIsolatedTreeNode>>&);
     void removeNode(AXID);
 
+    void setRootNodeID(AXID);
+    void setFocusedNodeID(AXID);
+    
     // Call on AX thread
     WEBCORE_EXPORT void applyPendingChanges();
 
+    WEBCORE_EXPORT void setInitialRequestInProgress(bool);
     AXIsolatedTreeID treeIdentifier() const { return m_treeID; }
 
 private:
     AXIsolatedTree();
 
     static HashMap<AXIsolatedTreeID, Ref<AXIsolatedTree>>& treeIDCache();
-    static HashMap<AXIsolatedTreeID, Ref<AXIsolatedTree>>& treePageCache();
-    
+    static HashMap<uint64_t, Ref<AXIsolatedTree>>& treePageCache();
+
     // Only access on AX thread requesting data.
     HashMap<AXID, Ref<AXIsolatedTreeNode>> m_readerThreadNodeMap;
 
     // Written to by main thread under lock, accessed and applied by AX thread.
     Vector<Ref<AXIsolatedTreeNode>> m_pendingAppends;
     Vector<AXID> m_pendingRemovals;
+    AXID m_pendingFocusedNodeID;
+    AXID m_pendingRootNodeID;
     Lock m_changeLogLock;
 
     AXIsolatedTreeID m_treeID;
-    AXID m_rootNodeID;
+    AXID m_rootNodeID { InvalidAXID };
+    AXID m_focusedNodeID { InvalidAXID };
+    bool m_initialRequestInProgress;
 };
 
 } // namespace WebCore
index 12bda1f..06248d3 100644 (file)
@@ -34,7 +34,6 @@ namespace WebCore {
 
 AXIsolatedTreeNode::AXIsolatedTreeNode(const AccessibilityObject& object)
     : m_identifier(object.axObjectID())
-    , m_initialized(false)
 {
     ASSERT(isMainThread());
     initializeAttributeData(object);
@@ -55,6 +54,18 @@ void AXIsolatedTreeNode::initializeAttributeData(const AccessibilityObject& obje
     setProperty(AXPropertyName::RoleValue, static_cast<int>(object.roleValue()));
     setProperty(AXPropertyName::IsAttachment, object.isAttachment());
     setProperty(AXPropertyName::IsMediaControlLabel, object.isMediaControlLabel());
+    setProperty(AXPropertyName::IsLink, object.isLink());
+    setProperty(AXPropertyName::IsImageMapLink, object.isImageMapLink());
+    setProperty(AXPropertyName::IsImage, object.isImage());
+    setProperty(AXPropertyName::IsFileUploadButton, object.isFileUploadButton());
+    setProperty(AXPropertyName::IsAccessibilityIgnored, object.accessibilityIsIgnored());
+    setProperty(AXPropertyName::IsTree, object.isTree());
+    setProperty(AXPropertyName::IsScrollbar, object.isScrollbar());
+    setProperty(AXPropertyName::RelativeFrame, object.relativeFrame());
+    setProperty(AXPropertyName::SpeechHint, object.speechHintAttributeValue().isolatedCopy());
+    setProperty(AXPropertyName::Title, object.titleAttributeValue().isolatedCopy());
+    setProperty(AXPropertyName::Description, object.descriptionAttributeValue().isolatedCopy());
+    setProperty(AXPropertyName::HelpText, object.helpTextAttributeValue().isolatedCopy());
 }
 
 void AXIsolatedTreeNode::setProperty(AXPropertyName propertyName, AttributeValueVariant&& value, bool shouldRemove)
@@ -74,56 +85,107 @@ void AXIsolatedTreeNode::appendChild(AXID axID)
     m_children.append(axID);
 }
 
+void AXIsolatedTreeNode::setParent(AXID parent)
+{
+    ASSERT(isMainThread());
+    m_parent = parent;
+}
+
+void AXIsolatedTreeNode::setTreeIdentifier(AXIsolatedTreeID treeIdentifier)
+{
+    m_treeIdentifier = treeIdentifier;
+    if (auto tree = AXIsolatedTree::treeForID(m_treeIdentifier))
+        m_cachedTree = makeWeakPtr(tree.get());
+}
+
+AccessibilityObjectInterface* AXIsolatedTreeNode::focusedUIElement() const
+{
+    if (auto focusedElement = tree()->focusedUIElement())
+        return focusedElement.get();
+    return nullptr;
+}
+    
+AccessibilityObjectInterface* AXIsolatedTreeNode::parentObjectInterfaceUnignored() const
+{
+    return tree()->nodeForID(parent()).get();
+}
+
+AccessibilityObjectInterface* AXIsolatedTreeNode::accessibilityHitTest(const IntPoint& point) const
+{
+    if (!relativeFrame().contains(point))
+        return nullptr;
+    for (auto childID : children()) {
+        auto child = tree()->nodeForID(childID);
+        ASSERT(child);
+        if (child && child->relativeFrame().contains(point))
+            return child->accessibilityHitTest(point);
+    }
+    return const_cast<AXIsolatedTreeNode*>(this);
+}
+
+AXIsolatedTree* AXIsolatedTreeNode::tree() const
+{
+    return m_cachedTree.get();
+}
+
+FloatRect AXIsolatedTreeNode::rectAttributeValue(AXPropertyName propertyName) const
+{
+    auto value = m_attributeMap.get(propertyName);
+    return WTF::switchOn(value,
+        [&zeroRect] (Optional<FloatRect> typedValue) {
+            if (!typedValue)
+                return FloatRect { };
+            return typedValue.value();
+        },
+        [] (auto&) { return FloatRect { }; }
+    );
+}
+
 double AXIsolatedTreeNode::doubleAttributeValue(AXPropertyName propertyName) const
 {
     auto value = m_attributeMap.get(propertyName);
-    return WTF::switchOn(value, [&] (double& typedValue) {
-        return typedValue;
-    }, [&] (auto&) {
-        return 0.0;
-    });
+    return WTF::switchOn(value,
+        [&] (double& typedValue) { return typedValue; },
+        [] (auto&) { return 0; }
+    );
 }
 
 unsigned AXIsolatedTreeNode::unsignedAttributeValue(AXPropertyName propertyName) const
 {
     auto value = m_attributeMap.get(propertyName);
-    return WTF::switchOn(value, [&] (unsigned& typedValue) {
-        return typedValue;
-    }, [&] (auto&) {
-        return 0;
-    });
+    return WTF::switchOn(value,
+        [&] (unsigned& typedValue) { return typedValue; },
+        [] (auto&) { return 0; }
+    );
 }
 
 bool AXIsolatedTreeNode::boolAttributeValue(AXPropertyName propertyName) const
 {
     auto value = m_attributeMap.get(propertyName);
-    return WTF::switchOn(value, [&] (bool& typedValue) {
-        return typedValue;
-    }, [&] (auto&) {
-        return false;
-    });
+    return WTF::switchOn(value,
+        [&] (bool& typedValue) { return typedValue; },
+        [] (auto&) { return false; }
+    );
 }
 
-const String& AXIsolatedTreeNode::stringAttributeValue(AXPropertyName propertyName) const
+const String AXIsolatedTreeNode::stringAttributeValue(AXPropertyName propertyName) const
 {
     auto value = m_attributeMap.get(propertyName);
-    return WTF::switchOn(value, [&] (String& typedValue) {
-        return typedValue;
-    }, [&] (auto&) {
-        return nullAtom();
-    });
+    return WTF::switchOn(value,
+        [&] (String& typedValue) { return typedValue; },
+        [] (auto&) { return emptyString(); }
+    );
 }
 
 int AXIsolatedTreeNode::intAttributeValue(AXPropertyName propertyName) const
 {
     auto value = m_attributeMap.get(propertyName);
-    return WTF::switchOn(value, [&] (int& typedValue) {
-        return typedValue;
-    }, [&] (auto&) {
-        return 0;
-    });
+    return WTF::switchOn(value,
+        [&] (int& typedValue) { return typedValue; },
+        [] (auto&) { return 0; }
+    );
 }
-    
+
 } // namespace WebCore
 
 #endif // ENABLE((ACCESSIBILITY_ISOLATED_TREE)
index dd3c34f..4374535 100644 (file)
 
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
 
+#include "AXIsolatedTree.h"
 #include "AccessibilityObjectInterface.h"
+#include "FloatRect.h"
+#include "IntPoint.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 #include <wtf/WeakPtr.h>
 
-#if PLATFORM(COCOA)
-OBJC_CLASS WebAccessibilityObjectWrapper;
-#endif
-
 namespace WebCore {
 
+class AXIsolatedTree;
 class AccessibilityObject;
 
 class AXIsolatedTreeNode final : public AccessibilityObjectInterface, public ThreadSafeRefCounted<AXIsolatedTreeNode>, public CanMakeWeakPtr<AXIsolatedTreeNode> {
@@ -50,36 +50,42 @@ class AXIsolatedTreeNode final : public AccessibilityObjectInterface, public Thr
 public:
     enum class AXPropertyName : uint8_t {
         None = 0,
-        RoleValue = 1,
+        HelpText,
+        IsAccessibilityIgnored,
         IsAttachment,
+        IsFileUploadButton,
+        IsImage,
+        IsImageMapLink,
+        IsLink,
         IsMediaControlLabel,
+        IsScrollbar,
+        IsTree,
+        IsTreeItem,
+        Description,
+        RelativeFrame,
+        RoleValue,
+        SpeechHint,
+        Title,
     };
 
     static Ref<AXIsolatedTreeNode> create(const AccessibilityObject&);
     virtual ~AXIsolatedTreeNode();
 
     AXID identifier() const { return m_identifier; }
-
-    bool isRootNode() const { return m_isRootNode; }
-    void setIsRootNode(bool value)
-    {
-        ASSERT(isMainThread());
-        m_isRootNode = value;
-    }
-
-    void setParent(AXID parent)
-    {
-        ASSERT(isMainThread());
-        m_parent = parent;
-    }
+    
+    void setParent(AXID);
     AXID parent() const { return m_parent; }
 
     void appendChild(AXID);
     const Vector<AXID>& children() const { return m_children; };
 
+    AXIsolatedTree* tree() const;
+    AXIsolatedTreeID treeIdentifier() const { return m_treeIdentifier; }
+    void setTreeIdentifier(AXIsolatedTreeID);
+
 #if PLATFORM(COCOA)
-    WebAccessibilityObjectWrapper* wrapper() const { return m_wrapper.get(); }
-    void setWrapper(WebAccessibilityObjectWrapper* wrapper) { m_wrapper = wrapper; }
+    AccessibilityObjectWrapper* wrapper() const override { return m_wrapper.get(); }
+    void setWrapper(AccessibilityObjectWrapper* wrapper) { m_wrapper = wrapper; }
 #endif
 
 protected:
@@ -89,23 +95,43 @@ private:
     AXIsolatedTreeNode(const AccessibilityObject&);
     void initializeAttributeData(const AccessibilityObject&);
 
+    AccessibilityObjectInterface* accessibilityHitTest(const IntPoint&) const override;
+    void updateChildrenIfNecessary() override { }
+
     bool isMediaControlLabel() const override { return boolAttributeValue(AXPropertyName::IsMediaControlLabel); }
     bool isAttachment() const override { return boolAttributeValue(AXPropertyName::IsAttachment); }
     AccessibilityRole roleValue() const override { return static_cast<AccessibilityRole>(intAttributeValue(AXPropertyName::RoleValue)); }
-
-    using AttributeValueVariant = Variant<std::nullptr_t, String, bool, int, unsigned, double>;
+    bool isLink() const override { return boolAttributeValue(AXPropertyName::IsLink); }
+    bool isImageMapLink() const override { return boolAttributeValue(AXPropertyName::IsImageMapLink); }
+    bool isImage() const override { return boolAttributeValue(AXPropertyName::IsImage); }
+    bool isFileUploadButton() const override { return boolAttributeValue(AXPropertyName::IsFileUploadButton); }
+    bool accessibilityIsIgnored() const override { return boolAttributeValue(AXPropertyName::IsAccessibilityIgnored); }
+    AccessibilityObjectInterface* parentObjectInterfaceUnignored() const override;
+    bool isTree() const override { return boolAttributeValue(AXPropertyName::IsTree); }
+    bool isTreeItem() const override { return boolAttributeValue(AXPropertyName::IsTreeItem); }
+    bool isScrollbar() const override { return boolAttributeValue(AXPropertyName::IsScrollbar); }
+    FloatRect relativeFrame() const override { return rectAttributeValue(AXPropertyName::RelativeFrame); }
+    String speechHintAttributeValue() const override { return stringAttributeValue(AXPropertyName::SpeechHint); }
+    String descriptionAttributeValue() const override { return stringAttributeValue(AXPropertyName::Description); }
+    String helpTextAttributeValue() const override { return stringAttributeValue(AXPropertyName::HelpText); }
+    String titleAttributeValue() const override { return stringAttributeValue(AXPropertyName::Title); }
+    AccessibilityObjectInterface* focusedUIElement() const override;
+
+    using AttributeValueVariant = Variant<std::nullptr_t, String, bool, int, unsigned, double, Optional<FloatRect>>;
     void setProperty(AXPropertyName, AttributeValueVariant&&, bool shouldRemove = false);
 
     bool boolAttributeValue(AXPropertyName) const;
-    const String& stringAttributeValue(AXPropertyName) const;
+    const String stringAttributeValue(AXPropertyName) const;
     int intAttributeValue(AXPropertyName) const;
     unsigned unsignedAttributeValue(AXPropertyName) const;
     double doubleAttributeValue(AXPropertyName) const;
+    FloatRect rectAttributeValue(AXPropertyName) const;
 
     AXID m_parent;
     AXID m_identifier;
-    bool m_isRootNode;
-    bool m_initialized;
+    bool m_initialized { false };
+    AXIsolatedTreeID m_treeIdentifier;
+    WeakPtr<AXIsolatedTree> m_cachedTree;
     Vector<AXID> m_children;
 
 #if PLATFORM(COCOA)
index f652db3..2d7f13d 100644 (file)
@@ -241,8 +241,10 @@ void AXObjectCache::detachWrapper(AccessibilityObject* obj, AccessibilityDetachm
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
 void AXObjectCache::associateIsolatedTreeNode(AccessibilityObject& object, AXIsolatedTreeNode& node, AXIsolatedTreeID treeID)
 {
-    object.wrapper().isolatedTreeIdentifier = treeID;
-    node.setWrapper(object.wrapper());
+    auto wrapper = object.wrapper();
+    ASSERT(wrapper);
+    wrapper.isolatedTreeIdentifier = treeID;
+    node.setWrapper(wrapper);
 }
 #endif
 
diff --git a/Source/WebCore/accessibility/mac/AccessibilityObjectBase.mm b/Source/WebCore/accessibility/mac/AccessibilityObjectBase.mm
new file mode 100644 (file)
index 0000000..aaf2dc9
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "AccessibilityObject.h"
+
+#if HAVE(ACCESSIBILITY) && PLATFORM(COCOA)
+
+#import "WebAccessibilityObjectWrapperBase.h"
+
+namespace WebCore {
+
+String AccessibilityObject::speechHintAttributeValue() const
+{
+    auto speak = speakAsProperty();
+    NSMutableArray<NSString *> *hints = [NSMutableArray array];
+    [hints addObject:(speak & SpeakAs::SpellOut) ? @"spell-out" : @"normal"];
+    if (speak & SpeakAs::Digits)
+        [hints addObject:@"digits"];
+    if (speak & SpeakAs::LiteralPunctuation)
+        [hints addObject:@"literal-punctuation"];
+    if (speak & SpeakAs::NoPunctuation)
+        [hints addObject:@"no-punctuation"];
+    return [hints componentsJoinedByString:@" "];
+}
+
+static bool isVisibleText(AccessibilityTextSource textSource)
+{
+    switch (textSource) {
+    case AccessibilityTextSource::Visible:
+    case AccessibilityTextSource::Children:
+    case AccessibilityTextSource::LabelByElement:
+        return true;
+    case AccessibilityTextSource::Alternative:
+    case AccessibilityTextSource::Summary:
+    case AccessibilityTextSource::Help:
+    case AccessibilityTextSource::TitleTag:
+    case AccessibilityTextSource::Placeholder:
+    case AccessibilityTextSource::Title:
+    case AccessibilityTextSource::Subtitle:
+    case AccessibilityTextSource::Action:
+        return false;
+    }
+}
+
+static bool isDescriptiveText(AccessibilityTextSource textSource)
+{
+    switch (textSource) {
+    case AccessibilityTextSource::Alternative:
+    case AccessibilityTextSource::Visible:
+    case AccessibilityTextSource::Children:
+    case AccessibilityTextSource::LabelByElement:
+        return true;
+    case AccessibilityTextSource::Summary:
+    case AccessibilityTextSource::Help:
+    case AccessibilityTextSource::TitleTag:
+    case AccessibilityTextSource::Placeholder:
+    case AccessibilityTextSource::Title:
+    case AccessibilityTextSource::Subtitle:
+    case AccessibilityTextSource::Action:
+        return false;
+    }
+}
+
+String AccessibilityObject::descriptionAttributeValue() const
+{
+    // Static text objects should not have a description. Its content is communicated in its AXValue.
+    // One exception is the media control labels that have a value and a description. Those are set programatically.
+    if (roleValue() == AccessibilityRole::StaticText && !isMediaControlLabel())
+        return { };
+
+    Vector<AccessibilityText> textOrder;
+    accessibilityText(textOrder);
+
+    // Determine if any visible text is available, which influences our usage of title tag.
+    bool visibleTextAvailable = false;
+    for (const auto& text : textOrder) {
+        if (isVisibleText(text.textSource)) {
+            visibleTextAvailable = true;
+            break;
+        }
+    }
+
+    NSMutableString *returnText = [NSMutableString string];
+    for (const auto& text : textOrder) {
+        if (text.textSource == AccessibilityTextSource::Alternative) {
+            [returnText appendString:text.text];
+            break;
+        }
+
+        switch (text.textSource) {
+        // These are sub-components of one element (Attachment) that are re-combined in OSX and iOS.
+        case AccessibilityTextSource::Title:
+        case AccessibilityTextSource::Subtitle:
+        case AccessibilityTextSource::Action: {
+            if (!text.text.length())
+                break;
+            if ([returnText length])
+                [returnText appendString:@", "];
+            [returnText appendString:text.text];
+            break;
+        }
+        default:
+            break;
+        }
+
+        if (text.textSource == AccessibilityTextSource::TitleTag && !visibleTextAvailable) {
+            [returnText appendString:text.text];
+            break;
+        }
+    }
+
+    return returnText;
+}
+
+String AccessibilityObject::titleAttributeValue() const
+{
+    // Static text objects should not have a title. Its content is communicated in its AXValue.
+    if (roleValue() == AccessibilityRole::StaticText)
+        return String();
+
+    // A file upload button presents a challenge because it has button text and a value, but the
+    // API doesn't support this paradigm.
+    // The compromise is to return the button type in the role description and the value of the file path in the title
+    if (isFileUploadButton() && fileUploadButtonReturnsValueInTitle())
+        return stringValue();
+
+    Vector<AccessibilityText> textOrder;
+    accessibilityText(textOrder);
+
+    for (const auto& text : textOrder) {
+        // If we have alternative text, then we should not expose a title.
+        if (text.textSource == AccessibilityTextSource::Alternative)
+            break;
+
+        // Once we encounter visible text, or the text from our children that should be used foremost.
+        if (text.textSource == AccessibilityTextSource::Visible || text.textSource == AccessibilityTextSource::Children)
+            return text.text;
+
+        // If there's an element that labels this object and it's not exposed, then we should use
+        // that text as our title.
+        if (text.textSource == AccessibilityTextSource::LabelByElement && !exposesTitleUIElement())
+            return text.text;
+    }
+
+    return { };
+}
+
+String AccessibilityObject::helpTextAttributeValue() const
+{
+    Vector<AccessibilityText> textOrder;
+    accessibilityText(textOrder);
+
+    // Determine if any descriptive text is available, which influences our usage of title tag.
+    bool descriptiveTextAvailable = false;
+    for (const auto& text : textOrder) {
+        if (isDescriptiveText(text.textSource)) {
+            descriptiveTextAvailable = true;
+            break;
+        }
+    }
+
+    for (const auto& text : textOrder) {
+        if (text.textSource == AccessibilityTextSource::Help || text.textSource == AccessibilityTextSource::Summary)
+            return text.text;
+
+        // If an element does NOT have other descriptive text the title tag should be used as its descriptive text.
+        // But, if those ARE available, then the title tag should be used for help text instead.
+        if (text.textSource == AccessibilityTextSource::TitleTag && descriptiveTextAvailable)
+            return text.text;
+    }
+
+    return { };
+}
+
+}; // namespace WebCore
+
+#endif // HAVE(ACCESSIBILITY) && PLATFORM(COCOA)
index 8d81721..3873179 100644 (file)
@@ -59,7 +59,13 @@ void AccessibilityObject::overrideAttachmentParent(AccessibilityObject* parent)
     [[wrapper() attachmentView] accessibilitySetOverrideValue:parentWrapper forAttribute:NSAccessibilityParentAttribute];
     ALLOW_DEPRECATED_DECLARATIONS_END
 }
-    
+
+// On iOS, we don't have to return the value in the title. We can return the actual title, given the API.
+bool AccessibilityObject::fileUploadButtonReturnsValueInTitle() const
+{
+    return true;
+}
+
 bool AccessibilityObject::accessibilityIgnoreAttachment() const
 {
     // FrameView attachments are now handled by AccessibilityScrollView, 
index 0cc4104..f086890 100644 (file)
@@ -30,6 +30,7 @@
 #define WebAccessibilityObjectWrapperBase_h
 
 #include "AXIsolatedTree.h"
+#include "AXIsolatedTreeNode.h"
 #include "AccessibilityObject.h"
 #include <CoreGraphics/CoreGraphics.h>
 #include <wtf/RefPtr.h>
@@ -52,6 +53,9 @@ class VisiblePosition;
 @interface WebAccessibilityObjectWrapperBase : NSObject {
     WebCore::AccessibilityObject* m_object;
     WebCore::AXID _identifier;
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    RefPtr<WebCore::AXIsolatedTreeNode> m_isolatedTreeNode;
+#endif
 }
  
 - (id)initWithAccessibilityObject:(WebCore::AccessibilityObject*)axObject;
@@ -86,15 +90,18 @@ class VisiblePosition;
 
 - (CGPathRef)convertPathToScreenSpace:(WebCore::Path &)path;
 
-enum ConversionSpace { ScreenSpace, PageSpace };
-- (CGRect)convertRectToSpace:(WebCore::FloatRect &)rect space:(ConversionSpace)space;
+- (CGRect)convertRectToSpace:(WebCore::FloatRect &)rect space:(WebCore::AccessibilityConversionSpace)space;
 
 // Math related functions
 - (NSArray *)accessibilityMathPostscriptPairs;
 - (NSArray *)accessibilityMathPrescriptPairs;
 
 extern WebCore::AccessibilitySearchCriteria accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(const NSDictionary *);
-extern NSArray *convertToNSArray(const WebCore::AccessibilityObject::AccessibilityChildrenVector&);
+
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+extern RetainPtr<NSArray> convertToNSArray(const Vector<RefPtr<WebCore::AXIsolatedTreeNode>>&);
+#endif
+extern RetainPtr<NSArray> convertToNSArray(const WebCore::AccessibilityObject::AccessibilityChildrenVector&);
 
 #if PLATFORM(IOS_FAMILY)
 - (id)_accessibilityWebDocumentView;
index 814e1a3..abe6ff7 100644 (file)
@@ -69,6 +69,7 @@
 #import "WAKView.h"
 #import "WAKWindow.h"
 #import "WebCoreFrameView.h"
+#import <pal/spi/mac/HIServicesSPI.h>
 
 using namespace WebCore;
 using namespace HTMLNames;
@@ -239,6 +240,8 @@ using namespace HTMLNames;
 #define NSAccessibilityImmediateDescendantsOnly @"AXImmediateDescendantsOnly"
 #endif
 
+#define _axBackingObject self.axBackingObject
+
 static NSArray *convertMathPairsToNSArray(const AccessibilityObject::AccessibilityMathMultiscriptPairs& pairs, NSString *subscriptKey, NSString *superscriptKey)
 {
     NSMutableArray *array = [NSMutableArray arrayWithCapacity:pairs.size()];
@@ -253,22 +256,33 @@ static NSArray *convertMathPairsToNSArray(const AccessibilityObject::Accessibili
     return array;
 }
 
-NSArray *convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector& vector)
+static void addChildToArray(AccessibilityObjectInterface& child, RetainPtr<NSMutableArray> array)
 {
-    NSMutableArray *array = [NSMutableArray arrayWithCapacity:vector.size()];
-    for (const auto& child : vector) {
-        auto wrapper = (WebAccessibilityObjectWrapperBase *)child->wrapper();
-        if (!wrapper)
-            continue;
+    WebAccessibilityObjectWrapper *wrapper = child.wrapper();
+    // We want to return the attachment view instead of the object representing the attachment,
+    // otherwise, we get palindrome errors in the AX hierarchy.
+    if (child.isAttachment() && [wrapper attachmentView])
+        [array.get() addObject:[wrapper attachmentView]];
+    else if (wrapper)
+        [array.get() addObject:wrapper];
+}
 
-        // We want to return the attachment view instead of the object representing the attachment,
-        // otherwise, we get palindrome errors in the AX hierarchy.
-        if (child->isAttachment() && [wrapper attachmentView])
-            [array addObject:[wrapper attachmentView]];
-        else
-            [array addObject:wrapper];
-    }
-    return [[array copy] autorelease];
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+RetainPtr<NSArray> convertToNSArray(const Vector<RefPtr<WebCore::AXIsolatedTreeNode>>& children)
+{
+    RetainPtr<NSMutableArray> result = [[NSMutableArray alloc] initWithCapacity:children.size()];
+    for (auto& child : children)
+        addChildToArray(*child, result)
+    return result;
+}
+#endif
+
+RetainPtr<NSArray> convertToNSArray(const WebCore::AccessibilityObject::AccessibilityChildrenVector& children)
+{
+    RetainPtr<NSMutableArray> result = [[NSMutableArray alloc] initWithCapacity:children.size()];
+    for (auto& child : children)
+        addChildToArray(*child, result);
+    return result;
 }
 
 @implementation WebAccessibilityObjectWrapperBase
@@ -293,7 +307,15 @@ NSArray *convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector
 - (RefPtr<WebCore::AXIsolatedTreeNode>)isolatedTreeNode
 {
     RELEASE_ASSERT(!isMainThread());
-    return AXIsolatedTree::treeForID(_isolatedTreeIdentifier)->nodeForID(_identifier);
+
+    if (!_identifier)
+        return nullptr;
+
+    if (m_isolatedTreeNode)
+        return m_isolatedTreeNode;
+
+    m_isolatedTreeNode = AXIsolatedTree::nodeInTreeForID(_isolatedTreeIdentifier, _identifier);
+    return m_isolatedTreeNode;
 }
 #endif
 
@@ -303,6 +325,7 @@ NSArray *convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector
     _identifier = 0;
 
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    m_isolatedTreeNode = nullptr;
     _isolatedTreeIdentifier = 0;
 #endif
 }
@@ -310,10 +333,16 @@ NSArray *convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector
 - (BOOL)updateObjectBackingStore
 {
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
-    RELEASE_ASSERT(!isMainThread());
-    AXIsolatedTree::treeForID(self.isolatedTreeIdentifier)->applyPendingChanges();
-    return _identifier;
-#else
+    if (_AXUIElementRequestServicedBySecondaryAXThread()) {
+        RELEASE_ASSERT(!isMainThread());
+        if (auto treeNode = self.isolatedTreeNode) {
+            if (auto tree = treeNode->tree())
+                tree->applyPendingChanges();
+        }
+        return _identifier;
+    }
+#endif
+    
     // Calling updateBackingStore() can invalidate this element so self must be retained.
     // If it does become invalidated, m_object will be nil.
     CFRetain((__bridge CFTypeRef)self);
@@ -327,7 +356,6 @@ NSArray *convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector
         return NO;
     
     return YES;
-#endif
 }
 
 - (id)attachmentView
@@ -337,163 +365,41 @@ NSArray *convertToNSArray(const AccessibilityObject::AccessibilityChildrenVector
 
 - (AccessibilityObject*)accessibilityObject
 {
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    ASSERT(!_AXUIElementRequestServicedBySecondaryAXThread());
+#endif
     return m_object;
 }
 
-// FIXME: Different kinds of elements are putting the title tag to use in different
-// AX fields. This should be rectified, but in the initial patch I want to achieve
-// parity with existing behavior.
-- (BOOL)titleTagShouldBeUsedInDescriptionField
-{
-    return (m_object->isLink() && !m_object->isImageMapLink()) || m_object->isImage();
-}
-
-// On iOS, we don't have to return the value in the title. We can return the actual title, given the API.
-- (BOOL)fileUploadButtonReturnsValueInTitle
-{
-    return YES;
-}
-
 // This should be the "visible" text that's actually on the screen if possible.
 // If there's alternative text, that can override the title.
 - (NSString *)baseAccessibilityTitle
 {
-    // Static text objects should not have a title. Its content is communicated in its AXValue.
-    if (m_object->roleValue() == AccessibilityRole::StaticText)
-        return [NSString string];
-
-    // A file upload button presents a challenge because it has button text and a value, but the
-    // API doesn't support this paradigm.
-    // The compromise is to return the button type in the role description and the value of the file path in the title
-    if (m_object->isFileUploadButton() && [self fileUploadButtonReturnsValueInTitle])
-        return m_object->stringValue();
-    
-    Vector<AccessibilityText> textOrder;
-    m_object->accessibilityText(textOrder);
-    
-    for (const auto& text : textOrder) {
-        // If we have alternative text, then we should not expose a title.
-        if (text.textSource == AccessibilityTextSource::Alternative)
-            break;
-        
-        // Once we encounter visible text, or the text from our children that should be used foremost.
-        if (text.textSource == AccessibilityTextSource::Visible || text.textSource == AccessibilityTextSource::Children)
-            return text.text;
-        
-        // If there's an element that labels this object and it's not exposed, then we should use
-        // that text as our title.
-        if (text.textSource == AccessibilityTextSource::LabelByElement && !m_object->exposesTitleUIElement())
-            return text.text;
-    }
-    
-    return [NSString string];
+    return _axBackingObject->titleAttributeValue();
 }
 
-#define _axBackingObject self.axBackingObject
 - (WebCore::AccessibilityObjectInterface*)axBackingObject
 {
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
-    return self.isolatedTreeNode.get();
-#else
-    return m_object;
+    if (_AXUIElementRequestServicedBySecondaryAXThread())
+        return self.isolatedTreeNode.get();
 #endif
+    return m_object;
 }
 
 - (NSString *)baseAccessibilityDescription
 {
-    // Static text objects should not have a description. Its content is communicated in its AXValue.
-    // One exception is the media control labels that have a value and a description. Those are set programatically.
-    if (_axBackingObject->roleValue() == AccessibilityRole::StaticText && !_axBackingObject->isMediaControlLabel())
-        return [NSString string];
-    
-    Vector<AccessibilityText> textOrder;
-    m_object->accessibilityText(textOrder);
-
-    NSMutableString *returnText = [NSMutableString string];
-    bool visibleTextAvailable = false;
-    for (const auto& text : textOrder) {
-        if (text.textSource == AccessibilityTextSource::Alternative) {
-            [returnText appendString:text.text];
-            break;
-        }
-        
-        switch (text.textSource) {
-        // These are sub-components of one element (Attachment) that are re-combined in OSX and iOS.
-        case AccessibilityTextSource::Title:
-        case AccessibilityTextSource::Subtitle:
-        case AccessibilityTextSource::Action: {
-            if (!text.text.length())
-                break;
-            if ([returnText length])
-                [returnText appendString:@", "];
-            [returnText appendString:text.text];
-            break;
-        }
-        case AccessibilityTextSource::Visible:
-        case AccessibilityTextSource::Children:
-        case AccessibilityTextSource::LabelByElement:
-            visibleTextAvailable = true;
-            break;
-        default:
-            break;
-        }
-        
-        if (text.textSource == AccessibilityTextSource::TitleTag && !visibleTextAvailable) {
-            [returnText appendString:text.text];
-            break;
-        }
-    }
-    
-    return returnText;
+    return _axBackingObject->descriptionAttributeValue();
 }
 
 - (NSArray<NSString *> *)baseAccessibilitySpeechHint
 {
-    auto speak = m_object->speakAsProperty();
-    NSMutableArray<NSString *> *hints = [NSMutableArray array];
-    if (speak & SpeakAs::SpellOut)
-        [hints addObject:@"spell-out"];
-    else
-        [hints addObject:@"normal"];
-
-    if (speak & SpeakAs::Digits)
-        [hints addObject:@"digits"];
-    if (speak & SpeakAs::LiteralPunctuation)
-        [hints addObject:@"literal-punctuation"];
-    if (speak & SpeakAs::NoPunctuation)
-        [hints addObject:@"no-punctuation"];
-    
-    return hints;
+    return [(NSString *)_axBackingObject->speechHintAttributeValue() componentsSeparatedByString:@" "];
 }
 
 - (NSString *)baseAccessibilityHelpText
 {
-    Vector<AccessibilityText> textOrder;
-    m_object->accessibilityText(textOrder);
-    
-    bool descriptiveTextAvailable = false;
-    for (const auto& text : textOrder) {
-        if (text.textSource == AccessibilityTextSource::Help || text.textSource == AccessibilityTextSource::Summary)
-            return text.text;
-        
-        // If an element does NOT have other descriptive text the title tag should be used as its descriptive text.
-        // But, if those ARE available, then the title tag should be used for help text instead.
-        switch (text.textSource) {
-        case AccessibilityTextSource::Alternative:
-        case AccessibilityTextSource::Visible:
-        case AccessibilityTextSource::Children:
-        case AccessibilityTextSource::LabelByElement:
-            descriptiveTextAvailable = true;
-            break;
-        default:
-            break;
-        }
-        
-        if (text.textSource == AccessibilityTextSource::TitleTag && descriptiveTextAvailable)
-            return text.text;
-    }
-    
-    return [NSString string];
+    return _axBackingObject->helpTextAttributeValue();
 }
 
 struct PathConversionInfo {
@@ -510,37 +416,37 @@ static void convertPathToScreenSpaceFunction(PathConversionInfo& conversion, con
     case PathElementMoveToPoint:
     {
         rect = FloatRect(element.points[0], FloatSize());
-        CGPoint newPoint = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
         CGPathMoveToPoint(newPath, nil, newPoint.x, newPoint.y);
         break;
     }
     case PathElementAddLineToPoint:
     {
         rect = FloatRect(element.points[0], FloatSize());
-        CGPoint newPoint = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
         CGPathAddLineToPoint(newPath, nil, newPoint.x, newPoint.y);
         break;
     }
     case PathElementAddQuadCurveToPoint:
     {
         rect = FloatRect(element.points[0], FloatSize());
-        CGPoint newPoint1 = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint1 = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
 
         rect = FloatRect(element.points[1], FloatSize());
-        CGPoint newPoint2 = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint2 = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
         CGPathAddQuadCurveToPoint(newPath, nil, newPoint1.x, newPoint1.y, newPoint2.x, newPoint2.y);
         break;
     }
     case PathElementAddCurveToPoint:
     {
         rect = FloatRect(element.points[0], FloatSize());
-        CGPoint newPoint1 = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint1 = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
 
         rect = FloatRect(element.points[1], FloatSize());
-        CGPoint newPoint2 = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint2 = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
 
         rect = FloatRect(element.points[2], FloatSize());
-        CGPoint newPoint3 = [wrapper convertRectToSpace:rect space:ScreenSpace].origin;
+        CGPoint newPoint3 = [wrapper convertRectToSpace:rect space:AccessibilityConversionSpace::Screen].origin;
         CGPathAddCurveToPoint(newPath, nil, newPoint1.x, newPoint1.y, newPoint2.x, newPoint2.y, newPoint3.x, newPoint3.y);
         break;
     }
@@ -569,7 +475,7 @@ static void convertPathToScreenSpaceFunction(PathConversionInfo& conversion, con
     return nil;
 }
 
-- (CGRect)convertRectToSpace:(WebCore::FloatRect &)rect space:(ConversionSpace)space
+- (CGRect)convertRectToSpace:(WebCore::FloatRect &)rect space:(AccessibilityConversionSpace)space
 {
     if (!m_object)
         return CGRectZero;
@@ -591,6 +497,7 @@ static void convertPathToScreenSpaceFunction(PathConversionInfo& conversion, con
         id webDocument = [self _accessibilityWebDocumentView];
         if (webDocument)
             cgRect = [webDocument convertRect:cgRect toView:nil];
+        return cgRect;
     }
 #else
     if (frameView && frameView->platformWidget()) {
@@ -599,48 +506,16 @@ static void convertPathToScreenSpaceFunction(PathConversionInfo& conversion, con
         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
         nsRect = [[view window] convertRectToScreen:[view convertRect:nsRect toView:nil]];
         ALLOW_DEPRECATED_DECLARATIONS_END
-        cgRect = NSRectToCGRect(nsRect);
+        return NSRectToCGRect(nsRect);
     }
 #endif
-    else {
-        // Find the appropriate scroll view to use to convert the contents to the window.
-        ScrollView* scrollView = nullptr;
-        const AccessibilityObject* parent = AccessibilityObject::matchedParent(*m_object, false, [] (const AccessibilityObject& object) {
-            return is<AccessibilityScrollView>(object);
-        });
-        if (parent)
-            scrollView = downcast<AccessibilityScrollView>(*parent).scrollView();
-        
-        auto intRect = snappedIntRect(IntRect(cgRect));
-        if (scrollView)
-            intRect = scrollView->contentsToRootView(intRect);
-        
-        if (space == ScreenSpace) {
-            auto page = m_object->page();
-            
-            // If we have an empty chrome client (like SVG) then we should use the page
-            // of the scroll view parent to help us get to the screen rect.
-            if (parent && page && page->chrome().client().isEmptyChromeClient())
-                page = parent->page();
-            
-            if (page) {
-#if PLATFORM(IOS_FAMILY)
-                intRect = page->chrome().rootViewToAccessibilityScreen(intRect);
-#else
-                intRect = page->chrome().rootViewToScreen(intRect);
-#endif
-            }
-        }
-        
-        cgRect = (CGRect)intRect;
-    }
-    
-    return cgRect;
+    else
+        return static_cast<CGRect>(m_object->convertFrameToSpace(rect, space));
 }
 
 - (NSString *)ariaLandmarkRoleDescription
 {
-    switch (m_object->roleValue()) {
+    switch (_axBackingObject->roleValue()) {
     case AccessibilityRole::LandmarkBanner:
         return AXARIAContentGroupText(@"ARIALandmarkBanner");
     case AccessibilityRole::LandmarkComplementary:
index 2c61541..f744591 100644 (file)
@@ -1609,7 +1609,7 @@ IGNORE_WARNINGS_END
     else if (m_object->isTextControl())
         objectAttributes = textAttrs;
     
-    else if (m_object->isLink() || m_object->isImage())
+    else if (_axBackingObject->isLink() || _axBackingObject->isImage())
         objectAttributes = anchorAttrs;
     
     else if (is<AccessibilityTable>(*m_object) && downcast<AccessibilityTable>(*m_object).isExposableThroughAccessibility())
@@ -1802,15 +1802,47 @@ static void WebTransformCGPathToNSBezierPath(void* info, const CGPathElement *el
     return [NSNumber numberWithFloat:screenRect.height()];
 }
 
+- (size_t)childrenVectorSize
+{
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    if (_AXUIElementRequestServicedBySecondaryAXThread())
+        return self.isolatedTreeNode->children().size();
+#endif
+    
+    return m_object->children().size();
+}
+
+- (NSArray<WebAccessibilityObjectWrapper *> *)childrenVectorArray
+{
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    if (_AXUIElementRequestServicedBySecondaryAXThread()) {
+        auto treeNode = self.isolatedTreeNode;
+        auto nodeChildren = treeNode->children();
+        Vector<RefPtr<AXIsolatedTreeNode>> children;
+        children.reserveInitialCapacity(nodeChildren.size());
+        auto tree = treeNode->tree();
+        for (auto childID : nodeChildren)
+            children.uncheckedAppend(tree->nodeForID(child));
+        return (NSArray *)convertToNSArray(children);
+    }
+#endif
+    return (NSArray *)convertToNSArray(m_object->children());
+}
+
 - (NSValue *)position
 {
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+    if (_AXUIElementRequestServicedBySecondaryAXThread())
+        return [NSValue valueWithPoint:(NSPoint)_axBackingObject->relativeFrame().location()];
+#endif
+        
     auto rect = snappedIntRect(m_object->elementRect());
     
     // The Cocoa accessibility API wants the lower-left corner.
     auto floatPoint = FloatPoint(rect.x(), rect.maxY());
 
     auto floatRect = FloatRect(floatPoint, FloatSize());
-    CGPoint cgPoint = [self convertRectToSpace:floatRect space:ScreenSpace].origin;
+    CGPoint cgPoint = [self convertRectToSpace:floatRect space:AccessibilityConversionSpace::Screen].origin;
     return [NSValue valueWithPoint:NSPointFromCGPoint(cgPoint)];
 }
 
@@ -2029,7 +2061,7 @@ ALLOW_DEPRECATED_DECLARATIONS_BEGIN
         return NSAccessibilityDecrementArrowSubrole;
     }
     
-    if (m_object->isFileUploadButton())
+    if (_axBackingObject->isFileUploadButton())
         return @"AXFileUploadButton";
     
     if (m_object->isTreeItem())
@@ -2309,7 +2341,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END
         }
     }
     
-    if (m_object->isFileUploadButton())
+    if (_axBackingObject->isFileUploadButton())
         return AXFileUploadButtonText();
     
     // Only returning for DL (not UL or OL) because description changed with HTML5 from 'definition list' to
@@ -2429,16 +2461,16 @@ IGNORE_WARNINGS_END
             return scrollViewParent;
         
         // Tree item (changed to AXRows) can only report the tree (AXOutline) as its parent.
-        if (m_object->isTreeItem()) {
-            AccessibilityObject* parent = m_object->parentObjectUnignored();
+        if (_axBackingObject->isTreeItem()) {
+            auto parent = _axBackingObject->parentObjectInterfaceUnignored();
             while (parent) {
                 if (parent->isTree())
                     return parent->wrapper();
-                parent = parent->parentObjectUnignored();
+                parent = parent->parentObjectInterfaceUnignored();
             }
         }
         
-        AccessibilityObject* parent = m_object->parentObjectUnignored();
+        auto parent = _axBackingObject->parentObjectInterfaceUnignored();
         if (!parent)
             return nil;
         
@@ -2451,7 +2483,7 @@ IGNORE_WARNINGS_END
     }
     
     if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) {
-        if (m_object->children().isEmpty()) {
+        if (!self.childrenVectorSize) {
             NSArray* children = [self renderWidgetChildren];
             if (children != nil)
                 return children;
@@ -2466,17 +2498,17 @@ IGNORE_WARNINGS_END
         if (m_object->isTreeItem()) {
             AccessibilityObject::AccessibilityChildrenVector contentCopy;
             m_object->ariaTreeItemContent(contentCopy);
-            return convertToNSArray(contentCopy);
+            return (NSArray *)convertToNSArray(contentCopy);
         }
         
-        return convertToNSArray(m_object->children());
+        return self.childrenVectorArray;
     }
     
     if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
         if (m_object->canHaveSelectedChildren()) {
             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
             m_object->selectedChildren(selectedChildrenCopy);
-            return convertToNSArray(selectedChildrenCopy);
+            return (NSArray *)convertToNSArray(selectedChildrenCopy);
         }
         return nil;
     }
@@ -2485,7 +2517,7 @@ IGNORE_WARNINGS_END
         if (m_object->isListBox()) {
             AccessibilityObject::AccessibilityChildrenVector visibleChildrenCopy;
             m_object->visibleChildren(visibleChildrenCopy);
-            return convertToNSArray(visibleChildrenCopy);
+            return (NSArray *)convertToNSArray(visibleChildrenCopy);
         }
         else if (m_object->isList())
             return [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
@@ -2498,7 +2530,7 @@ IGNORE_WARNINGS_END
         if ([attributeName isEqualToString:@"AXLinkUIElements"]) {
             AccessibilityObject::AccessibilityChildrenVector links;
             downcast<AccessibilityRenderObject>(*m_object).getDocumentLinks(links);
-            return convertToNSArray(links);
+            return (NSArray *)convertToNSArray(links);
         }
         if ([attributeName isEqualToString:@"AXLoaded"])
             return [NSNumber numberWithBool:m_object->isLoaded()];
@@ -2543,7 +2575,7 @@ IGNORE_WARNINGS_END
             if (m_object->isPasswordField() || m_object->selectionEnd() > 0)
                 return nil;
             
-            AccessibilityObject* focusedObject = m_object->focusedUIElement();
+            auto focusedObject = downcast<AccessibilityObject>(m_object->focusedUIElement());
             if (focusedObject != m_object)
                 return nil;
             
@@ -2716,56 +2748,60 @@ IGNORE_WARNINGS_END
         if (m_object->isTabList()) {
             AccessibilityObject::AccessibilityChildrenVector tabsChildren;
             m_object->tabChildren(tabsChildren);
-            return convertToNSArray(tabsChildren);
+            return (NSArray *)convertToNSArray(tabsChildren);
         }
     }
     
     if ([attributeName isEqualToString:NSAccessibilityContentsAttribute]) {
         // The contents of a tab list are all the children except the tabs.
         if (m_object->isTabList()) {
-            const auto& children = m_object->children();
-            AccessibilityObject::AccessibilityChildrenVector tabsChildren;
-            m_object->tabChildren(tabsChildren);
-            
-            AccessibilityObject::AccessibilityChildrenVector contents;
-            unsigned childrenSize = children.size();
-            for (unsigned k = 0; k < childrenSize; ++k) {
-                if (tabsChildren.find(children[k]) == WTF::notFound)
-                    contents.append(children[k]);
+            auto children = self.childrenVectorArray;
+            AccessibilityObject::AccessibilityChildrenVector tabs;
+            m_object->tabChildren(tabs);
+            auto tabsChildren = (NSArray *)convertToNSArray(tabs);
+
+            NSMutableArray *contents = [NSMutableArray array];
+            for (id childWrapper in children) {
+                if ([tabsChildren containsObject:childWrapper])
+                    [contents addObject:childWrapper];
             }
-            return convertToNSArray(contents);
+            return contents;
         } else if (m_object->isScrollView()) {
             // A scrollView's contents are everything except the scroll bars.
-            AccessibilityObject::AccessibilityChildrenVector contents;
-            for (const auto& child : m_object->children()) {
-                if (!child->isScrollbar())
-                    contents.append(child);
+            auto children = self.childrenVectorArray;
+            NSMutableArray *contents = [NSMutableArray array];
+
+            for (WebAccessibilityObjectWrapper *childWrapper in children) {
+                if (auto backingObject = [childWrapper axBackingObject]) {
+                    if (!backingObject->isScrollbar())
+                        [contents addObject:childWrapper];
+                }
             }
-            return convertToNSArray(contents);
+            return contents;
         }
     }
     
     if (is<AccessibilityTable>(*m_object) && downcast<AccessibilityTable>(*m_object).isExposableThroughAccessibility()) {
         auto& table = downcast<AccessibilityTable>(*m_object);
         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute])
-            return convertToNSArray(table.rows());
+            return (NSArray *)convertToNSArray(table.rows());
         
         if ([attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector visibleRows;
             table.visibleRows(visibleRows);
-            return convertToNSArray(visibleRows);
+            return (NSArray *)convertToNSArray(visibleRows);
         }
         
         // TODO: distinguish between visible and non-visible columns
         if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute] ||
             [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute]) {
-            return convertToNSArray(table.columns());
+            return (NSArray *)convertToNSArray(table.columns());
         }
         
         if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
             m_object->selectedChildren(selectedChildrenCopy);
-            return convertToNSArray(selectedChildrenCopy);
+            return (NSArray *)convertToNSArray(selectedChildrenCopy);
         }
         
         // HTML tables don't support these
@@ -2776,7 +2812,7 @@ IGNORE_WARNINGS_END
         if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector columnHeaders;
             table.columnHeaders(columnHeaders);
-            return convertToNSArray(columnHeaders);
+            return (NSArray *)convertToNSArray(columnHeaders);
         }
         
         if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
@@ -2789,13 +2825,13 @@ IGNORE_WARNINGS_END
         if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector rowHeaders;
             table.rowHeaders(rowHeaders);
-            return convertToNSArray(rowHeaders);
+            return (NSArray *)convertToNSArray(rowHeaders);
         }
         
         if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector cells;
             table.cells(cells);
-            return convertToNSArray(cells);
+            return (NSArray *)convertToNSArray(cells);
         }
         
         if ([attributeName isEqualToString:NSAccessibilityColumnCountAttribute])
@@ -2819,7 +2855,7 @@ IGNORE_WARNINGS_END
         // rows attribute for a column is the list of all the elements in that column at each row
         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
             [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
-            return convertToNSArray(column.children());
+            return (NSArray *)convertToNSArray(column.children());
         }
         if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
             AccessibilityObject* header = column.headerObject();
@@ -2844,12 +2880,12 @@ IGNORE_WARNINGS_END
         if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector columnHeaders;
             cell.columnHeaders(columnHeaders);
-            return convertToNSArray(columnHeaders);
+            return (NSArray *)convertToNSArray(columnHeaders);
         }
         if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector rowHeaders;
             cell.rowHeaders(rowHeaders);
-            return convertToNSArray(rowHeaders);
+            return (NSArray *)convertToNSArray(rowHeaders);
         }
         if ([attributeName isEqualToString:NSAccessibilityARIAColumnIndexAttribute])
             return @(cell.axColumnIndex());
@@ -2862,12 +2898,12 @@ IGNORE_WARNINGS_END
         if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
             m_object->selectedChildren(selectedChildrenCopy);
-            return convertToNSArray(selectedChildrenCopy);
+            return (NSArray *)convertToNSArray(selectedChildrenCopy);
         }
         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
             m_object->ariaTreeRows(rowsCopy);
-            return convertToNSArray(rowsCopy);
+            return (NSArray *)convertToNSArray(rowsCopy);
         }
         
         // TreeRoles do not support columns, but Mac AX expects to be able to ask about columns at the least.
@@ -2905,11 +2941,11 @@ IGNORE_WARNINGS_END
         if (m_object->isTreeItem()) {
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
             m_object->ariaTreeItemDisclosedRows(rowsCopy);
-            return convertToNSArray(rowsCopy);
+            return (NSArray *)convertToNSArray(rowsCopy);
         } else if (is<AccessibilityARIAGridRow>(*m_object)) {
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
             downcast<AccessibilityARIAGridRow>(*m_object).disclosedRows(rowsCopy);
-            return convertToNSArray(rowsCopy);
+            return (NSArray *)convertToNSArray(rowsCopy);
         }
     }
     
@@ -2965,7 +3001,7 @@ IGNORE_WARNINGS_END
     if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector linkedUIElements;
         m_object->linkedUIElements(linkedUIElements);
-        return convertToNSArray(linkedUIElements);
+        return (NSArray *)convertToNSArray(linkedUIElements);
     }
     
     if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
@@ -3046,7 +3082,7 @@ IGNORE_WARNINGS_END
     if ([attributeName isEqualToString:NSAccessibilityOwnsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector ariaOwns;
         m_object->ariaOwnsElements(ariaOwns);
-        return convertToNSArray(ariaOwns);
+        return (NSArray *)convertToNSArray(ariaOwns);
     }
     
     if ([attributeName isEqualToString:NSAccessibilityARIAPosInSetAttribute])
@@ -3188,18 +3224,16 @@ IGNORE_WARNINGS_END
     if ([attributeName isEqualToString:@"AXDetailsElements"]) {
         AccessibilityObject::AccessibilityChildrenVector details;
         m_object->ariaDetailsElements(details);
-        return convertToNSArray(details);
+        return (NSArray *)convertToNSArray(details);
     }
 
-    if ([attributeName isEqualToString:NSAccessibilityRelativeFrameAttribute]) {
-        auto rect = FloatRect(snappedIntRect(m_object->elementRect()));
-        return [NSValue valueWithRect:NSRectFromCGRect([self convertRectToSpace:rect space:PageSpace])];
-    }
-    
+    if ([attributeName isEqualToString:NSAccessibilityRelativeFrameAttribute])
+        return [NSValue valueWithRect:NSRectFromCGRect(_axBackingObject->relativeFrame())];
+
     if ([attributeName isEqualToString:@"AXErrorMessageElements"]) {
         AccessibilityObject::AccessibilityChildrenVector errorMessages;
         m_object->ariaErrorMessageElements(errorMessages);
-        return convertToNSArray(errorMessages);
+        return (NSArray *)convertToNSArray(errorMessages);
     }
 
     // Multi-selectable
@@ -3223,7 +3257,7 @@ IGNORE_WARNINGS_END
     if ([attributeName isEqualToString:NSAccessibilityAriaControlsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector ariaControls;
         m_object->ariaControlsElements(ariaControls);
-        return convertToNSArray(ariaControls);
+        return (NSArray *)convertToNSArray(ariaControls);
     }
 
     if ([attributeName isEqualToString:NSAccessibilityFocusableAncestorAttribute]) {
@@ -3259,12 +3293,11 @@ IGNORE_WARNINGS_END
     if (![self updateObjectBackingStore])
         return nil;
     
-    RefPtr<AccessibilityObject> focusedObj = m_object->focusedUIElement();
-    
-    if (!focusedObj)
+    auto focusedObject = _axBackingObject->focusedUIElement();
+    if (!focusedObject)
         return nil;
     
-    return focusedObj->wrapper();
+    return focusedObject->wrapper();
 }
 
 - (id)accessibilityHitTest:(NSPoint)point
@@ -3272,8 +3305,8 @@ IGNORE_WARNINGS_END
     if (![self updateObjectBackingStore])
         return nil;
     
-    m_object->updateChildrenIfNecessary();
-    RefPtr<AccessibilityObject> axObject = m_object->accessibilityHitTest(IntPoint(point));
+    _axBackingObject->updateChildrenIfNecessary();
+    AccessibilityObjectInterface* axObject = _axBackingObject->accessibilityHitTest(IntPoint(point));
     if (axObject) {
         if (axObject->isAttachment() && [axObject->wrapper() attachmentView])
             return [axObject->wrapper() attachmentView];
@@ -3344,9 +3377,9 @@ IGNORE_WARNINGS_END
     if (![self updateObjectBackingStore])
         return YES;
     
-    if (m_object->isAttachment())
+    if (_axBackingObject->isAttachment())
         return [[self attachmentView] accessibilityIsIgnored];
-    return m_object->accessibilityIsIgnored();
+    return _axBackingObject->accessibilityIsIgnored();
 }
 
 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
@@ -3959,7 +3992,7 @@ IGNORE_WARNINGS_END
         AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
         AccessibilityObject::AccessibilityChildrenVector results;
         m_object->findMatchingObjects(&criteria, results);
-        return convertToNSArray(results);
+        return (NSArray *)convertToNSArray(results);
     }
     
     if ([attribute isEqualToString:NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute]) {
@@ -4317,16 +4350,19 @@ IGNORE_WARNINGS_END
     if (m_object->isTree())
         return [super accessibilityIndexOfChild:child];
     
-    const auto& children = m_object->children();
-    
-    if (children.isEmpty())
+    NSArray *children = self.childrenVectorArray;
+    if (!children.count)
         return [[self renderWidgetChildren] indexOfObject:child];
     
-    unsigned count = children.size();
-    for (unsigned k = 0; k < count; ++k) {
-        WebAccessibilityObjectWrapper* wrapper = children[k]->wrapper();
-        if (wrapper == child || (children[k]->isAttachment() && [wrapper attachmentView] == child))
-            return k;
+    NSUInteger count = [children count];
+    for (NSUInteger i = 0; i < count; ++i) {
+        WebAccessibilityObjectWrapper *wrapper = children[i];
+        auto backingObject = [wrapper axBackingObject];
+        if (!backingObject)
+            continue;
+
+        if (wrapper == child || (backingObject->isAttachment() && [wrapper attachmentView] == child))
+            return i;
     }
     
     return NSNotFound;
@@ -4344,11 +4380,11 @@ ALLOW_DEPRECATED_DECLARATIONS_BEGIN
         if (m_object->isTree() || m_object->isTreeItem())
             return [[self accessibilityAttributeValue:NSAccessibilityChildrenAttribute] count];
         
-        const auto& children = m_object->children();
-        if (children.isEmpty())
+        auto childrenSize = self.childrenVectorSize;
+        if (!childrenSize)
             return [[self renderWidgetChildren] count];
         
-        return children.size();
+        return childrenSize;
     }
     
     return [super accessibilityArrayAttributeCount:attribute];
@@ -4361,7 +4397,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END
         return nil;
     
     if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
-        if (m_object->children().isEmpty()) {
+        if (!self.childrenVectorSize) {
             NSArray *children = [self renderWidgetChildren];
             if (!children)
                 return nil;
@@ -4372,14 +4408,16 @@ ALLOW_DEPRECATED_DECLARATIONS_END
             
             NSUInteger arrayLength = std::min(childCount - index, maxCount);
             return [children subarrayWithRange:NSMakeRange(index, arrayLength)];
-        } else if (m_object->isTree() || m_object->isTreeItem()) {
+        }
+
+        if (_axBackingObject->isTree() || _axBackingObject->isTreeItem()) {
             // Tree objects return their rows as their children & tree items return their contents sans rows.
             // We can use the original method in this case.
             return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
         }
         
-        const auto& children = m_object->children();
-        unsigned childCount = children.size();
+        auto children = self.childrenVectorArray;
+        unsigned childCount = [children count];
         if (index >= childCount)
             return nil;
         
@@ -4387,14 +4425,10 @@ ALLOW_DEPRECATED_DECLARATIONS_END
         
         NSMutableArray *subarray = [NSMutableArray arrayWithCapacity:available];
         for (unsigned added = 0; added < available; ++index, ++added) {
-            WebAccessibilityObjectWrapper* wrapper = children[index]->wrapper();
-            if (wrapper) {
-                // The attachment view should be returned, otherwise AX palindrome errors occur.
-                if (children[index]->isAttachment() && [wrapper attachmentView])
-                    [subarray addObject:[wrapper attachmentView]];
-                else
-                    [subarray addObject:wrapper];
-            }
+            WebAccessibilityObjectWrapper* wrapper = children[index];
+            // The attachment view should be returned, otherwise AX palindrome errors occur.
+            BOOL isAttachment = [wrapper isKindOfClass:[WebAccessibilityObjectWrapper class]] && wrapper.axBackingObject->isAttachment() && [wrapper attachmentView];
+            [subarray addObject:isAttachment ? [wrapper attachmentView] : wrapper];
         }
         
         return subarray;
index f054763..3338b6d 100644 (file)
@@ -108,11 +108,8 @@ class EmptyChromeClient : public ChromeClient {
 
     IntPoint screenToRootView(const IntPoint& p) const final { return p; }
     IntRect rootViewToScreen(const IntRect& r) const final { return r; }
-
-#if PLATFORM(IOS_FAMILY)
     IntPoint accessibilityScreenToRootView(const IntPoint& p) const final { return p; };
     IntRect rootViewToAccessibilityScreen(const IntRect& r) const final { return r; };
-#endif
 
     PlatformPageClient platformPageClient() const final { return 0; }
     void contentsSizeChanged(Frame&, const IntSize&) const final { }
index 8d0001d..d6e542e 100644 (file)
@@ -111,8 +111,6 @@ IntRect Chrome::rootViewToScreen(const IntRect& rect) const
     return m_client.rootViewToScreen(rect);
 }
     
-#if PLATFORM(IOS_FAMILY)
-
 IntPoint Chrome::accessibilityScreenToRootView(const IntPoint& point) const
 {
     return m_client.accessibilityScreenToRootView(point);
@@ -123,8 +121,6 @@ IntRect Chrome::rootViewToAccessibilityScreen(const IntRect& rect) const
     return m_client.rootViewToAccessibilityScreen(rect);
 }
 
-#endif
-
 PlatformPageClient Chrome::platformPageClient() const
 {
     return m_client.platformPageClient();
index 52335cf..398b4a1 100644 (file)
@@ -77,10 +77,8 @@ public:
     void scroll(const IntSize&, const IntRect&, const IntRect&) override;
     IntPoint screenToRootView(const IntPoint&) const override;
     IntRect rootViewToScreen(const IntRect&) const override;
-#if PLATFORM(IOS_FAMILY)
     IntPoint accessibilityScreenToRootView(const IntPoint&) const override;
     IntRect rootViewToAccessibilityScreen(const IntRect&) const override;
-#endif
     PlatformPageClient platformPageClient() const override;
     void setCursor(const Cursor&) override;
     void setCursorHiddenUntilMouseMoves(bool) override;
index 4cb98c0..8d6f1d5 100644 (file)
@@ -174,11 +174,8 @@ public:
 
     virtual IntPoint screenToRootView(const IntPoint&) const = 0;
     virtual IntRect rootViewToScreen(const IntRect&) const = 0;
-
-#if PLATFORM(IOS_FAMILY)
     virtual IntPoint accessibilityScreenToRootView(const IntPoint&) const = 0;
     virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const = 0;
-#endif    
 
     virtual PlatformPageClient platformPageClient() const = 0;
 
index 9defcc8..2cfecad 100644 (file)
@@ -53,10 +53,8 @@ public:
     // Methods for doing coordinate conversions to and from screen coordinates.
     virtual IntPoint screenToRootView(const IntPoint&) const = 0;
     virtual IntRect rootViewToScreen(const IntRect&) const = 0;
-#if PLATFORM(IOS_FAMILY)
     virtual IntPoint accessibilityScreenToRootView(const IntPoint&) const = 0;
     virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const = 0;
-#endif
     
     // Method for retrieving the native client of the page.
     virtual PlatformPageClient platformPageClient() const = 0;
index a4b597e..918f154 100644 (file)
@@ -1,3 +1,28 @@
+2019-02-12  Chris Fleizach  <cfleizach@apple.com>
+
+        AX: IsolatedTree: Implement more attributes
+        https://bugs.webkit.org/show_bug.cgi?id=193911
+        <rdar://problem/47599217>
+
+        Reviewed by Daniel Bates.
+
+        * Platform/spi/mac/AccessibilityPrivSPI.h: Added.
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.h:
+        * WebProcess/WebPage/mac/WKAccessibilityWebPageObjectBase.mm:
+        (-[WKAccessibilityWebPageObjectBase clientSupportsIsolatedTree]):
+        (-[WKAccessibilityWebPageObjectBase isolatedTreeRootObject]):
+        (-[WKAccessibilityWebPageObjectBase accessibilityRootObjectWrapper]):
+        * WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm:
+        (-[WKAccessibilityWebPageObject IGNORE_WARNINGS_END]):
+        (-[WKAccessibilityWebPageObject convertScreenPointToRootView:]):
+        (-[WKAccessibilityWebPageObject accessibilityAttributeValue:]):
+        (-[WKAccessibilityWebPageObject accessibilityAttributeSizeValue]):
+        (-[WKAccessibilityWebPageObject accessibilityAttributePositionValue]):
+        (-[WKAccessibilityWebPageObject accessibilityDataDetectorValue:point:]):
+        (-[WKAccessibilityWebPageObject accessibilityAttributeValue:forParameter:]):
+        (-[WKAccessibilityWebPageObject accessibilityHitTest:]):
+
 2019-02-12  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Allow pages to trigger programmatic paste from script on iOS
diff --git a/Source/WebKit/Platform/spi/mac/AccessibilityPrivSPI.h b/Source/WebKit/Platform/spi/mac/AccessibilityPrivSPI.h
new file mode 100644 (file)
index 0000000..bbf9177
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundef"
+#include <HIServices/AccessibilityPriv.h>
+#pragma clang diagnostic pop
+
+#else
+
+typedef CF_ENUM(int32_t, AXClientType)
+{
+    kAXClientTypeNoActiveRequestFound  = 0,
+    kAXClientTypeUnknown,
+    kAXClientTypeRaft,
+    kAXClientTypeXCUITest,
+    kAXClientTypeXCTest,
+    kAXClientTypeScripter2,
+    kAXClientTypeSystemEvents,
+    kAXClientTypeVoiceOver,
+    kAXClientTypeAssistiveControl,
+    kAXClientTypeFullKeyboardAccess,
+    kAXClientTypeDictation,
+};
+
+extern AXClientType _AXGetClientForCurrentRequestUntrusted(void);
+
+#endif // PLATFORM(APPLE_INTERNAL_SDK)
index 0fb8802..721ec1e 100644 (file)
@@ -203,6 +203,16 @@ IntRect PageClientImpl::rootViewToScreen(const IntRect& rect)
     return IntRect(convertWidgetPointToScreenPoint(m_viewWidget, rect.location()), rect.size());
 }
 
+WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::IntPoint& point)
+{
+    return screenToRootView(point);
+}
+
+WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)    
+{
+    return rootViewToScreen(rect);
+}
+
 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled)
 {
     if (wasEventHandled)
index c7dd6f2..b90ac5a 100644 (file)
@@ -81,6 +81,8 @@ private:
     WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override;
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) override;
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override;
+    WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) override;
+    WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) override;
     void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override;
     RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) override;
     Ref<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, ContextMenuContextData&&, const UserData&) override;
index 74548d9..2c1c6ee 100644 (file)
@@ -182,6 +182,16 @@ WebCore::IntRect PageClientImpl::rootViewToScreen(const WebCore::IntRect& rect)
     return rect;
 }
 
+WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::IntPoint& point)
+{
+    return screenToRootView(point);
+}
+
+WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)
+{
+    return rootViewToScreen(rect);    
+}
+
 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool)
 {
 }
index 469d015..5aae0f2 100644 (file)
@@ -87,6 +87,8 @@ private:
     WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override;
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) override;
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override;
+    WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) override;
+    WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) override;
 
     void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool) override;
 #if ENABLE(TOUCH_EVENTS)
index 4135184..cd7ac05 100644 (file)
@@ -272,12 +272,12 @@ public:
     virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) = 0;
     virtual WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) = 0;
     virtual WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) = 0;
+    virtual WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) = 0;
+    virtual WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) = 0;
 #if PLATFORM(MAC)
     virtual WebCore::IntRect rootViewToWindow(const WebCore::IntRect&) = 0;
 #endif
 #if PLATFORM(IOS_FAMILY)
-    virtual WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) = 0;
-    virtual WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) = 0;
     virtual void didNotHandleTapAsClick(const WebCore::IntPoint&) = 0;
     virtual void didCompleteSyntheticClick() = 0;
 #endif
index 7a3f352..45a8b97 100644 (file)
@@ -5062,7 +5062,6 @@ IntRect WebPageProxy::syncRootViewToScreen(const IntRect& viewRect)
     return pageClient().rootViewToScreen(viewRect);
 }
 
-#if PLATFORM(IOS_FAMILY)
 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
 {
     windowPoint = pageClient().accessibilityScreenToRootView(screenPoint);
@@ -5072,7 +5071,6 @@ void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRec
 {
     result = pageClient().rootViewToAccessibilityScreen(viewRect);
 }
-#endif
 
 void WebPageProxy::runBeforeUnloadConfirmPanel(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply&& reply)
 {
index 9740e5d..139dd16 100644 (file)
@@ -1587,10 +1587,8 @@ private:
     void setIsResizable(bool isResizable);
     void screenToRootView(const WebCore::IntPoint& screenPoint, Messages::WebPageProxy::ScreenToRootView::DelayedReply&&);
     void rootViewToScreen(const WebCore::IntRect& viewRect, Messages::WebPageProxy::RootViewToScreen::DelayedReply&&);
-#if PLATFORM(IOS_FAMILY)
     void accessibilityScreenToRootView(const WebCore::IntPoint& screenPoint, WebCore::IntPoint& windowPoint);
     void rootViewToAccessibilityScreen(const WebCore::IntRect& viewRect, WebCore::IntRect& result);
-#endif
     void runBeforeUnloadConfirmPanel(uint64_t frameID, const WebCore::SecurityOriginData&, const String& message, Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply&&);
     void didChangeViewportProperties(const WebCore::ViewportAttributes&);
     void pageDidScroll();
index b984ea3..08ce9e5 100644 (file)
@@ -61,17 +61,14 @@ messages -> WebPageProxy {
     GetWindowFrame() -> (WebCore::FloatRect windowFrame) Delayed
     ScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint) Delayed
     RootViewToScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame) Delayed
+    AccessibilityScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint) LegacySync
+    RootViewToAccessibilityScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame) LegacySync
 
 #if PLATFORM(COCOA)
     ShowValidationMessage(WebCore::IntRect anchorRect, String message)
     HideValidationMessage()
 #endif
 
-#if PLATFORM(IOS_FAMILY)
-    AccessibilityScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint) LegacySync
-    RootViewToAccessibilityScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame) LegacySync
-#endif
-
     RunBeforeUnloadConfirmPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message) -> (bool shouldClose) Delayed
     PageDidScroll()
     RunOpenPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebCore::FileChooserSettings parameters)
index d242c05..42101ab 100644 (file)
@@ -121,10 +121,8 @@ private:
 #if PLATFORM(MAC)
     WebCore::IntRect rootViewToWindow(const WebCore::IntRect&) override;
 #endif
-#if PLATFORM(IOS_FAMILY)
-    virtual WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) = 0;
-    virtual WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) = 0;
-#endif
+    WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) override;
+    WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) override;
 
     void pinnedStateWillChange() final;
     void pinnedStateDidChange() final;
index 97b1435..de6f2d5 100644 (file)
@@ -453,6 +453,16 @@ IntRect PageClientImpl::rootViewToWindow(const WebCore::IntRect& rect)
     return enclosingIntRect(tempRect);
 }
 
+IntPoint PageClientImpl::accessibilityScreenToRootView(const IntPoint& point)
+{
+    return screenToRootView(point);
+}
+
+IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect)
+{
+    return rootViewToScreen(rect);
+}
+
 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled)
 {
     m_impl->doneWithKeyEvent(event.nativeEvent(), eventWasHandled);
index 912b4a9..ca5023e 100644 (file)
@@ -163,6 +163,16 @@ IntRect PageClientImpl::rootViewToScreen(const IntRect& rect)
     return IntRect();
 }
 
+WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::IntPoint& point)
+{
+    return screenToRootView(point);
+}
+
+WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect)    
+{
+    return rootViewToScreen(rect);
+}
+
 void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled)
 {
     notImplemented();
index e8426c9..7396d39 100644 (file)
@@ -78,6 +78,8 @@ private:
     WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override;
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) override;
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override;
+    WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) override;
+    WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) override;
     void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override;
     RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) override;
     Ref<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, ContextMenuContextData&&, const UserData&) override;
index 70f12c5..5c247f1 100644 (file)
                29AD3097164B4E210072DEA9 /* LegacyCustomProtocolManagerProxy.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LegacyCustomProtocolManagerProxy.messages.in; path = CustomProtocols/LegacyCustomProtocolManagerProxy.messages.in; sourceTree = "<group>"; };
                29CD55A8128E294F00133C85 /* WKAccessibilityWebPageObjectBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKAccessibilityWebPageObjectBase.h; sourceTree = "<group>"; };
                29CD55A9128E294F00133C85 /* WKAccessibilityWebPageObjectBase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKAccessibilityWebPageObjectBase.mm; sourceTree = "<group>"; };
+               29D04E2821F7C73D0076741D /* AccessibilityPrivSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibilityPrivSPI.h; sourceTree = "<group>"; };
                2D0035221BC7414800DA8716 /* PDFPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDFPlugin.h; path = PDF/PDFPlugin.h; sourceTree = "<group>"; };
                2D0035231BC7414800DA8716 /* PDFPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PDFPlugin.mm; path = PDF/PDFPlugin.mm; sourceTree = "<group>"; };
                2D10875E1D2C573E00B85F82 /* LoadParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadParameters.cpp; sourceTree = "<group>"; };
                        children = (
                                F48D2A8421583A0200C6752B /* AppKitSPI.h */,
                                A1E6886F1F6E2BAB007006A6 /* QuarantineSPI.h */,
+                               29D04E2821F7C73D0076741D /* AccessibilityPrivSPI.h */,
                        );
                        path = mac;
                        sourceTree = "<group>";
index 830cb44..3e1e1a8 100644 (file)
@@ -570,7 +570,6 @@ IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const
     return m_page.rootViewToScreen(rect);
 }
     
-#if PLATFORM(IOS_FAMILY)
 IntPoint WebChromeClient::accessibilityScreenToRootView(const IntPoint& point) const
 {
     return m_page.accessibilityScreenToRootView(point);
@@ -580,7 +579,6 @@ IntRect WebChromeClient::rootViewToAccessibilityScreen(const IntRect& rect) cons
 {
     return m_page.rootViewToAccessibilityScreen(rect);
 }
-#endif
 
 PlatformPageClient WebChromeClient::platformPageClient() const
 {
index 9d07505..91e6da2 100644 (file)
@@ -112,10 +112,8 @@ private:
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) const final;
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) const final;
 
-#if PLATFORM(IOS_FAMILY)
     WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final;
     WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final;
-#endif
 
     PlatformPageClient platformPageClient() const final;
     void contentsSizeChanged(WebCore::Frame&, const WebCore::IntSize&) const final;
index dfaab22..79729f5 100644 (file)
@@ -3186,7 +3186,6 @@ IntRect WebPage::rootViewToScreen(const IntRect& rect)
     return screenRect;
 }
     
-#if PLATFORM(IOS_FAMILY)
 IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point)
 {
     IntPoint windowPoint;
@@ -3200,7 +3199,6 @@ IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect)
     sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect), Messages::WebPageProxy::RootViewToAccessibilityScreen::Reply(screenRect));
     return screenRect;
 }
-#endif
 
 KeyboardUIMode WebPage::keyboardUIMode()
 {
index 4a99b91..ba949ba 100644 (file)
@@ -561,11 +561,8 @@ public:
 
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&);
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&);
-    
-#if PLATFORM(IOS_FAMILY)
     WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&);
     WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&);
-#endif
     
     RefPtr<WebImage> scaledSnapshotWithOptions(const WebCore::IntRect&, double additionalScaleFactor, SnapshotOptions);
 
index bb47ab3..6ec1300 100644 (file)
@@ -43,6 +43,10 @@ class WebPage;
 - (id)accessibilityRootObjectWrapper;
 - (id)accessibilityFocusedUIElement;
 
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+- (BOOL)clientSupportsIsolatedTree;
+#endif
+
 @end
 
 #endif // WKAccessibilityWebPageObjectBase_h
index 60f7f1d..94cca7f 100644 (file)
@@ -86,6 +86,37 @@ using namespace WebKit;
     return retrieveBlock();
 }
 
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+- (BOOL)clientSupportsIsolatedTree
+{
+    AXClientType type = _AXGetClientForCurrentRequestUntrusted();
+    // FIXME: Remove unknown client before enabling ACCESSIBILITY_ISOLATED_TREE.
+    return type == kAXClientTypeVoiceOver || type == kAXClientTypeUnknown;
+}
+
+- (id)isolatedTreeRootObject
+{
+    if (isMainThread()) {
+        if (auto cache = [self axObjectCache]) {
+            auto tree = AXIsolatedTree::initializeTreeForPageId(m_pageID, *cache);
+
+            // Now that we have created our tree, initialize the secondary thread,
+            // so future requests come in on the other thread.
+            _AXUIElementUseSecondaryAXThread(true);
+            if (auto rootNode = tree->rootNode())
+                return rootNode->wrapper();
+        }
+    } else {
+        auto tree = AXIsolatedTree::treeForPageID(m_pageID);
+        tree->applyPendingChanges();
+        if (auto rootNode = tree->rootNode())
+            return rootNode->wrapper();
+    }
+
+    return nil;
+}
+#endif
+
 - (id)accessibilityRootObjectWrapper
 {
     if (!WebCore::AXObjectCache::accessibilityEnabled())
@@ -95,36 +126,17 @@ using namespace WebKit;
         return self.accessibilityPluginObject;
 
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
-    auto generateBlock = [&] {
-        auto dispatchBlock = [&self] {
-            if (auto cache = [self axObjectCache])
-                cache->generateIsolatedAccessibilityTree();
-        };
-
-        if (isMainThread())
-            dispatchBlock();
-        else {
-            callOnMainThreadAndWait([&dispatchBlock] {
-                dispatchBlock();
-            });
-        }
-    };
-
-    auto tree = AXIsolatedTree::treeForPageID(m_pageID);
-    if (!tree)
-        generateBlock();
+    // If VoiceOver is on, ensure subsequent requests are now handled on the secondary AX thread.
+    bool clientSupportsIsolatedTree = [self clientSupportsIsolatedTree];
+    if (clientSupportsIsolatedTree)
+        return [self isolatedTreeRootObject];
+#endif
 
-    if ((tree = AXIsolatedTree::treeForPageID(m_pageID))) {
-        ASSERT(!isMainThread());
-        tree->applyPendingChanges();
-        return tree->rootNode()->wrapper();
-    }
-#else
     if (AXObjectCache* cache = [self axObjectCache]) {
         if (WebCore::AccessibilityObject* root = cache->rootObject())
             return root->wrapper();
     }
-#endif
+
     return nil;
 }
 
index 5c41a39..92d28b6 100644 (file)
@@ -78,19 +78,29 @@ IGNORE_WARNINGS_END
     return m_attributeNames.get();
 }
 
+template<typename T, typename U> inline T retrieveAccessibilityValueFromMainThread(U&& lambda)
+{
+    if (isMainThread())
+        return lambda();
+
+    T value;
+    callOnMainThreadAndWait([&value, &lambda] {
+        value = lambda();
+    });
+    return value;
+}
+
 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
 - (NSArray *)accessibilityParameterizedAttributeNames
 IGNORE_WARNINGS_END
 {
-    Vector<String> result = m_page->corePage()->pageOverlayController().copyAccessibilityAttributesNames(true);
-    if (result.isEmpty())
-        return nil;
-    
-    NSMutableArray *names = [NSMutableArray array];
-    for (auto& name : result)
-        [names addObject:(NSString *)name];
-    
-    return names;
+    return retrieveAccessibilityValueFromMainThread<id>([&self] () -> id {
+        NSMutableArray *names = [NSMutableArray array];
+        auto result = m_page->corePage()->pageOverlayController().copyAccessibilityAttributesNames(true);
+        for (auto& name : result)
+            [names addObject:(NSString *)name];
+        return names;
+    });
 }
 
 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
@@ -108,7 +118,9 @@ IGNORE_WARNINGS_END
 
 - (NSPoint)convertScreenPointToRootView:(NSPoint)point
 {
-    return m_page->screenToRootView(IntPoint(point.x, point.y));
+    return retrieveAccessibilityValueFromMainThread<NSPoint>([&self, &point] () -> NSPoint {
+        return m_page->screenToRootView(IntPoint(point.x, point.y));
+    });
 }
 
 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
@@ -152,21 +164,17 @@ IGNORE_WARNINGS_END
     if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
         return @NO;
     
-    if (!m_page)
+    if (!m_pageID)
         return nil;
     
-    if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
-        const WebCore::FloatPoint& point = m_page->accessibilityPosition();
-        return [NSValue valueWithPoint:NSMakePoint(point.x(), point.y())];
-    }
+    if ([attribute isEqualToString:NSAccessibilityPositionAttribute])
+        return [self accessibilityAttributePositionValue];
     
     if ([attribute isEqualToString:NSAccessibilityPrimaryScreenHeightAttribute])
         return [[self accessibilityRootObjectWrapper] accessibilityAttributeValue:attribute];
     
-    if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
-        const IntSize& s = m_page->size();
-        return [NSValue valueWithSize:NSMakeSize(s.width(), s.height())];
-    }
+    if ([attribute isEqualToString:NSAccessibilitySizeAttribute])
+        return [self accessibilityAttributeSizeValue];
     
     if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
         return [self accessibilityChildren];
@@ -174,6 +182,38 @@ IGNORE_WARNINGS_END
     return nil;
 }
 
+- (NSValue *)accessibilityAttributeSizeValue
+{
+    return retrieveAccessibilityValueFromMainThread<id>([&self] () -> id {
+        return [NSValue valueWithSize:(NSSize)m_page->size()];
+    });
+}
+
+- (NSValue *)accessibilityAttributePositionValue
+{
+    return retrieveAccessibilityValueFromMainThread<id>([&self] () -> id {
+        return [NSValue valueWithPoint:(NSPoint)m_page->accessibilityPosition()];
+    });
+}
+
+- (id)accessibilityDataDetectorValue:(NSString *)attribute point:(WebCore::FloatPoint&)point
+{
+    return retrieveAccessibilityValueFromMainThread<id>([&self, &attribute, &point] () -> id {
+        id value = nil;
+        if ([attribute isEqualToString:@"AXDataDetectorExistsAtPoint"] || [attribute isEqualToString:@"AXDidShowDataDetectorMenuAtPoint"]) {
+            bool boolValue;
+            if (m_page->corePage()->pageOverlayController().copyAccessibilityAttributeBoolValueForPoint(attribute, point, boolValue))
+                value = [NSNumber numberWithBool:boolValue];
+        }
+        if ([attribute isEqualToString:@"AXDataDetectorTypeAtPoint"]) {
+            String stringValue;
+            if (m_page->corePage()->pageOverlayController().copyAccessibilityAttributeStringValueForPoint(attribute, point, stringValue))
+                value = [NSString stringWithString:stringValue];
+        }
+        return value;
+    });
+}
+
 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
 - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter
 IGNORE_WARNINGS_END
@@ -184,19 +224,8 @@ IGNORE_WARNINGS_END
     else
         return nil;
 
-    if ([attribute isEqualToString:@"AXDataDetectorExistsAtPoint"] || [attribute isEqualToString:@"AXDidShowDataDetectorMenuAtPoint"]) {
-        bool value;
-        if (!m_page->corePage()->pageOverlayController().copyAccessibilityAttributeBoolValueForPoint(attribute, pageOverlayPoint, value))
-            return nil;
-        return [NSNumber numberWithBool:value];
-    }
-
-    if ([attribute isEqualToString:@"AXDataDetectorTypeAtPoint"]) {
-        String value;
-        if (!m_page->corePage()->pageOverlayController().copyAccessibilityAttributeStringValueForPoint(attribute, pageOverlayPoint, value))
-            return nil;
-        return [NSString stringWithString:value];
-    }
+    if ([attribute isEqualToString:@"AXDataDetectorExistsAtPoint"] || [attribute isEqualToString:@"AXDidShowDataDetectorMenuAtPoint"] || [attribute isEqualToString:@"AXDataDetectorTypeAtPoint"])
+        return [self accessibilityDataDetectorValue:attribute point:pageOverlayPoint];
 
     return nil;
 }
@@ -209,23 +238,33 @@ IGNORE_WARNINGS_END
 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
 - (id)accessibilityHitTest:(NSPoint)point
 {
-    if (!m_page)
-        return nil;
+    auto convertedPoint = retrieveAccessibilityValueFromMainThread<IntPoint>([&self, &point] () -> IntPoint {
+        if (!m_page)
+            return IntPoint(point);
+        
+        auto convertedPoint = m_page->screenToRootView(IntPoint(point));
+        
+        // Some plugins may be able to figure out the scroll position and inset on their own.
+        bool applyContentOffset = true;
 
-    IntPoint convertedPoint = m_page->screenToRootView(IntPoint(point));
-    
-    // Some plugins may be able to figure out the scroll position and inset on their own.
-    bool applyContentOffset = true;
-    if (auto pluginView = WebKit::WebPage::pluginViewForFrame(m_page->mainFrame()))
-        applyContentOffset = !pluginView->plugin()->pluginHandlesContentOffsetForAccessibilityHitTest();
+        // Isolated tree frames have the offset encoded into them so we don't need to undo here.
+#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
+        bool queryingIsolatedTree = [self clientSupportsIsolatedTree] && _AXUIElementRequestServicedBySecondaryAXThread();
+        applyContentOffset = !queryingIsolatedTree;
+#endif
+        if (auto pluginView = WebKit::WebPage::pluginViewForFrame(m_page->mainFrame()))
+            applyContentOffset = !pluginView->plugin()->pluginHandlesContentOffsetForAccessibilityHitTest();
+        
+        if (!applyContentOffset)
+            return convertedPoint;
 
-    if (applyContentOffset) {
         if (WebCore::FrameView* frameView = m_page->mainFrameView())
             convertedPoint.moveBy(frameView->scrollPosition());
         if (WebCore::Page* page = m_page->corePage())
             convertedPoint.move(0, -page->topContentInset());
-    }
-
+        return convertedPoint;
+    });
+    
     return [[self accessibilityRootObjectWrapper] accessibilityHitTest:convertedPoint];
 }
 ALLOW_DEPRECATED_DECLARATIONS_END
index febb01b..b8e20c6 100644 (file)
@@ -99,10 +99,8 @@ private:
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) const final;
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) const final;
 
-#if PLATFORM(IOS_FAMILY)
     WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final;
     WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final;
-#endif
 
     PlatformPageClient platformPageClient() const final;
     void contentsSizeChanged(WebCore::Frame&, const WebCore::IntSize&) const final;
index cb030d2..167a3bf 100644 (file)
@@ -596,17 +596,15 @@ IntRect WebChromeClient::rootViewToScreen(const IntRect& r) const
     return r;
 }
 
-#if PLATFORM(IOS_FAMILY)
 IntPoint WebChromeClient::accessibilityScreenToRootView(const IntPoint& p) const
 {
-    return p;
+    return screenToRootView(p);
 }
 
 IntRect WebChromeClient::rootViewToAccessibilityScreen(const IntRect& r) const
 {
-    return r;
+    return rootViewToScreen(r);
 }
-#endif
 
 PlatformPageClient WebChromeClient::platformPageClient() const
 {
index bbf53e9..542477a 100644 (file)
@@ -684,18 +684,18 @@ HRESULT AccessibleBase::get_accFocus(_Out_ VARIANT* pvFocusedChild)
     if (!m_object)
         return E_FAIL;
 
-    AccessibilityObject* focusedObj = m_object->focusedUIElement();
-    if (!focusedObj)
+    auto focusedObject = downcast<AccessibilityObject>(m_object->focusedUIElement());
+    if (!focusedObject)
         return S_FALSE;
 
-    if (focusedObj == m_object) {
+    if (focusedObject == m_object) {
         V_VT(pvFocusedChild) = VT_I4;
         V_I4(pvFocusedChild) = CHILDID_SELF;
         return S_OK;
     }
 
     V_VT(pvFocusedChild) = VT_DISPATCH;
-    V_DISPATCH(pvFocusedChild) = wrapper(focusedObj);
+    V_DISPATCH(pvFocusedChild) = wrapper(focusedObject);
     V_DISPATCH(pvFocusedChild)->AddRef();
     return S_OK;
 }
@@ -810,22 +810,22 @@ HRESULT AccessibleBase::accHitTest(long x, long y, _Out_ VARIANT* pvChildAtPoint
         return E_FAIL;
 
     IntPoint point = m_object->documentFrameView()->screenToContents(IntPoint(x, y));
-    AccessibilityObject* childObj = m_object->accessibilityHitTest(point);
+    auto childObject = downcast<AccessibilityObject>(m_object->accessibilityHitTest(point));
 
-    if (!childObj) {
+    if (!childObject) {
         // If we did not hit any child objects, test whether the point hit us, and
         // report that.
         if (!m_object->boundingBoxRect().contains(point))
             return S_FALSE;
-        childObj = m_object;
+        childObject = m_object;
     }
 
-    if (childObj == m_object) {
+    if (childObject == m_object) {
         V_VT(pvChildAtPoint) = VT_I4;
         V_I4(pvChildAtPoint) = CHILDID_SELF;
     } else {
         V_VT(pvChildAtPoint) = VT_DISPATCH;
-        V_DISPATCH(pvChildAtPoint) = static_cast<IDispatch*>(wrapper(childObj));
+        V_DISPATCH(pvChildAtPoint) = static_cast<IDispatch*>(wrapper(childObject));
         V_DISPATCH(pvChildAtPoint)->AddRef();
     }
     return S_OK;
index 0fcb912..8331ca9 100644 (file)
@@ -471,6 +471,16 @@ void WebChromeClient::scroll(const IntSize& delta, const IntRect& scrollViewRect
     m_webView->scrollBackingStore(core(m_webView->topLevelFrame())->view(), delta.width(), delta.height(), scrollViewRect, clipRect);
 }
 
+IntPoint WebChromeClient::accessibilityScreenToRootView(const WebCore::IntPoint& point) const
+{
+    return screenToRootView(point);
+}
+
+IntRect WebChromeClient::rootViewToAccessibilityScreen(const WebCore::IntRect& rect) const
+{
+    return rootViewToScreen(rect);
+}
+
 IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const
 {
     HWND viewWindow;
index cc41d42..7ebe56b 100644 (file)
@@ -98,6 +98,8 @@ public:
 
     WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) const final;
     WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) const final;
+    WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final;
+    WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final;
     PlatformPageClient platformPageClient() const final;
     void contentsSizeChanged(WebCore::Frame&, const WebCore::IntSize&) const final;