Title: [215233] trunk/Source
Revision
215233
Author
[email protected]
Date
2017-04-11 09:26:21 -0700 (Tue, 11 Apr 2017)

Log Message

AX: PDF plugin needs to support PDF-DOM Mode
https://bugs.webkit.org/show_bug.cgi?id=170589

Reviewed by Tim Horton.

Source/WebCore:

Provide WebCore support for accessibility connect to PDF document.
This includes the ability to connect a PDF annotation created node within WebKit to
 its PDFAnnotation parent (through use of shadowPluginParent).

* accessibility/AXObjectCache.h:
* accessibility/mac/AXObjectCacheMac.mm:
(WebCore::AXPostNotificationWithUserInfo):
* accessibility/mac/WebAccessibilityObjectWrapperMac.h:
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper shadowPluginParent]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
* html/HTMLAttributeNames.in:
* plugins/PluginViewBase.h:
(WebCore::PluginViewBase::accessibilityShadowPluginParentForElement):

Source/WebKit2:

Provide access to DOM objects with PDF document. This mean:
   1) Support a different set of attributes for WKPDFPluginAccessibilityObject.
        WKPDFPluginAccessibilityObject is now a group instead of forwarding attribute calls to the pdf layer.
   2) Connect the focused UI element to the active annotation if possible.
   3) Mark the PDF associated nodes with an attribute so they can be identified later so their correct parent can be found.

* WebProcess/Plugins/PDF/PDFLayerControllerSPI.h:
* WebProcess/Plugins/PDF/PDFPlugin.h:
* WebProcess/Plugins/PDF/PDFPlugin.mm:
(-[WKPDFPluginAccessibilityObject pdfLayerController]):
(-[WKPDFPluginAccessibilityObject setPdfLayerController:]):
(-[WKPDFPluginAccessibilityObject convertRectToScreenSpace:]):
(-[WKPDFPluginAccessibilityObject accessibilityAttributeValue:]):
(-[WKPDFPluginAccessibilityObject accessibilityAttributeNames]):
(-[WKPDFPluginAccessibilityObject accessibilityActionNames]):
(-[WKPDFPluginAccessibilityObject accessibilityParameterizedAttributeNames]):
(-[WKPDFPluginAccessibilityObject accessibilityFocusedUIElement]):
(-[WKPDFPluginAccessibilityObject accessibilityAssociatedControlForAnnotation:]):
(-[WKPDFPluginAccessibilityObject accessibilityHitTest:]):
(WebKit::PDFPlugin::convertFromRootViewToPDFView):
(WebKit::PDFPlugin::convertFromPDFViewToScreen):
(WebKit::PDFPlugin::pluginHandlesContentOffsetForAccessibilityHitTest):
(WebKit::PDFPlugin::axObjectCache):
(WebKit::PDFPlugin::accessibilityShadowPluginParentForElement):
* WebProcess/Plugins/PDF/PDFPluginAnnotation.mm:
(WebKit::PDFPluginAnnotation::attach):
* WebProcess/Plugins/Plugin.h:
(WebKit::Plugin::accessibilityShadowPluginParentForElement):
(WebKit::Plugin::pluginHandlesContentOffsetForAccessibilityHitTest):
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::accessibilityShadowPluginParentForElement):
* WebProcess/Plugins/PluginView.h:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm:
(-[WKAccessibilityWebPageObject accessibilityHitTest:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (215232 => 215233)


--- trunk/Source/WebCore/ChangeLog	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/ChangeLog	2017-04-11 16:26:21 UTC (rev 215233)
@@ -1,3 +1,25 @@
+2017-04-11  Chris Fleizach  <[email protected]>
+
+        AX: PDF plugin needs to support PDF-DOM Mode
+        https://bugs.webkit.org/show_bug.cgi?id=170589
+
+        Reviewed by Tim Horton.
+
+        Provide WebCore support for accessibility connect to PDF document.
+        This includes the ability to connect a PDF annotation created node within WebKit to 
+         its PDFAnnotation parent (through use of shadowPluginParent).
+
+        * accessibility/AXObjectCache.h:
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::AXPostNotificationWithUserInfo):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.h:
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper shadowPluginParent]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+        * html/HTMLAttributeNames.in:
+        * plugins/PluginViewBase.h:
+        (WebCore::PluginViewBase::accessibilityShadowPluginParentForElement):
+
 2017-04-11  Carlos Garcia Campos  <[email protected]>
 
         REGRESSION(r215153): Request Animation Frame broken when building without REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (215232 => 215233)


--- trunk/Source/WebCore/accessibility/AXObjectCache.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -143,7 +143,7 @@
     // For AX objects with elements that back them.
     AccessibilityObject* getOrCreate(RenderObject*);
     AccessibilityObject* getOrCreate(Widget*);
-    AccessibilityObject* getOrCreate(Node*);
+    WEBCORE_EXPORT AccessibilityObject* getOrCreate(Node*);
 
     // used for objects without backing elements
     AccessibilityObject* getOrCreate(AccessibilityRole);

Modified: trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm (215232 => 215233)


--- trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm	2017-04-11 16:26:21 UTC (rev 215233)
@@ -250,8 +250,11 @@
     axShouldRepostNotificationsForTests = value;
 }
 
-static void AXPostNotificationWithUserInfo(id object, NSString *notification, id userInfo)
+static void AXPostNotificationWithUserInfo(AccessibilityObjectWrapper *object, NSString *notification, id userInfo)
 {
+    if (id associatedPluginParent = [object associatedPluginParent])
+        object = associatedPluginParent;
+    
     NSAccessibilityPostNotificationWithUserInfo(object, notification, userInfo);
     // To simplify monitoring for notifications in tests, repost as a simple NSNotification instead of forcing test infrastucture to setup an IPC client and do all the translation between WebCore types and platform specific IPC types and back
     if (UNLIKELY(axShouldRepostNotificationsForTests))

Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.h (215232 => 215233)


--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -35,4 +35,7 @@
 - (id)textMarkerRangeFromVisiblePositions:(const WebCore::VisiblePosition&)startPosition endPosition:(const WebCore::VisiblePosition&)endPosition;
 - (id)textMarkerForVisiblePosition:(const WebCore::VisiblePosition&)visiblePos;
 
+// When a plugin uses a WebKit control to act as a surrogate view (e.g. PDF use WebKit to create text fields).
+- (id)associatedPluginParent;
+
 @end

Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (215232 => 215233)


--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2017-04-11 16:26:21 UTC (rev 215233)
@@ -63,6 +63,8 @@
 #import "LocalizedStrings.h"
 #import "MainFrame.h"
 #import "Page.h"
+#import "PluginDocument.h"
+#import "PluginViewBase.h"
 #import "RenderTextControl.h"
 #import "RenderView.h"
 #import "RenderWidget.h"
@@ -1682,6 +1684,21 @@
     return [self textMarkerRangeFromVisiblePositions:selection.visibleStart() endPosition:selection.visibleEnd()];
 }
 
+- (id)associatedPluginParent
+{
+    if (!m_object || !m_object->hasAttribute(x_apple_pdf_annotationAttr))
+        return nil;
+    
+    if (!m_object->document()->isPluginDocument())
+        return nil;
+        
+    Widget* pluginWidget = static_cast<PluginDocument*>(m_object->document())->pluginWidget();
+    if (!pluginWidget || !pluginWidget->isPluginViewBase())
+        return nil;
+
+    return static_cast<PluginViewBase*>(pluginWidget)->accessibilityAssociatedPluginParentForElement(m_object->element());
+}
+
 - (CGPoint)convertPointToScreenSpace:(FloatPoint &)point
 {
     FrameView* frameView = m_object->documentFrameView();
@@ -3083,6 +3100,10 @@
         return convertStringsToNSArray(classList);
     }
     
+    // This allows us to connect to a plugin that creates a shadow node for editing (like PDFs).
+    if ([attributeName isEqualToString:@"_AXAssociatedPluginParent"])
+        return [self associatedPluginParent];
+    
     // this is used only by DumpRenderTree for testing
     if ([attributeName isEqualToString:@"AXClickPoint"])
         return [NSValue valueWithPoint:m_object->clickPoint()];

Modified: trunk/Source/WebCore/html/HTMLAttributeNames.in (215232 => 215233)


--- trunk/Source/WebCore/html/HTMLAttributeNames.in	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/html/HTMLAttributeNames.in	2017-04-11 16:26:21 UTC (rev 215233)
@@ -392,3 +392,5 @@
 x-apple-data-detectors
 x-apple-data-detectors-type
 x-apple-data-detectors-result
+
+x-apple-pdf-annotation

Modified: trunk/Source/WebCore/plugins/PluginViewBase.h (215232 => 215233)


--- trunk/Source/WebCore/plugins/PluginViewBase.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebCore/plugins/PluginViewBase.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -31,6 +31,10 @@
 #include "Widget.h"
 #include <wtf/text/WTFString.h>
 
+#if PLATFORM(COCOA)
+typedef struct objc_object* id;
+#endif
+
 namespace JSC {
     class ExecState;
     class JSGlobalObject;
@@ -83,6 +87,10 @@
     
     virtual void willDetatchRenderer() { }
 
+#if PLATFORM(COCOA)
+    virtual id accessibilityAssociatedPluginParentForElement(Element*) const { return nullptr; }
+#endif
+    
 protected:
     explicit PluginViewBase(PlatformWidget widget = 0) : Widget(widget) { }
 };

Modified: trunk/Source/WebKit2/ChangeLog (215232 => 215233)


--- trunk/Source/WebKit2/ChangeLog	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/ChangeLog	2017-04-11 16:26:21 UTC (rev 215233)
@@ -1,3 +1,46 @@
+2017-04-11  Chris Fleizach  <[email protected]>
+
+        AX: PDF plugin needs to support PDF-DOM Mode
+        https://bugs.webkit.org/show_bug.cgi?id=170589
+
+        Reviewed by Tim Horton.
+
+        Provide access to DOM objects with PDF document. This mean:
+           1) Support a different set of attributes for WKPDFPluginAccessibilityObject.
+                WKPDFPluginAccessibilityObject is now a group instead of forwarding attribute calls to the pdf layer.
+           2) Connect the focused UI element to the active annotation if possible.
+           3) Mark the PDF associated nodes with an attribute so they can be identified later so their correct parent can be found.
+
+        * WebProcess/Plugins/PDF/PDFLayerControllerSPI.h:
+        * WebProcess/Plugins/PDF/PDFPlugin.h:
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (-[WKPDFPluginAccessibilityObject pdfLayerController]):
+        (-[WKPDFPluginAccessibilityObject setPdfLayerController:]):
+        (-[WKPDFPluginAccessibilityObject convertRectToScreenSpace:]):
+        (-[WKPDFPluginAccessibilityObject accessibilityAttributeValue:]):
+        (-[WKPDFPluginAccessibilityObject accessibilityAttributeNames]):
+        (-[WKPDFPluginAccessibilityObject accessibilityActionNames]):
+        (-[WKPDFPluginAccessibilityObject accessibilityParameterizedAttributeNames]):
+        (-[WKPDFPluginAccessibilityObject accessibilityFocusedUIElement]):
+        (-[WKPDFPluginAccessibilityObject accessibilityAssociatedControlForAnnotation:]):
+        (-[WKPDFPluginAccessibilityObject accessibilityHitTest:]):
+        (WebKit::PDFPlugin::convertFromRootViewToPDFView):
+        (WebKit::PDFPlugin::convertFromPDFViewToScreen):
+        (WebKit::PDFPlugin::pluginHandlesContentOffsetForAccessibilityHitTest):
+        (WebKit::PDFPlugin::axObjectCache):
+        (WebKit::PDFPlugin::accessibilityShadowPluginParentForElement):
+        * WebProcess/Plugins/PDF/PDFPluginAnnotation.mm:
+        (WebKit::PDFPluginAnnotation::attach):
+        * WebProcess/Plugins/Plugin.h:
+        (WebKit::Plugin::accessibilityShadowPluginParentForElement):
+        (WebKit::Plugin::pluginHandlesContentOffsetForAccessibilityHitTest):
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::accessibilityShadowPluginParentForElement):
+        * WebProcess/Plugins/PluginView.h:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm:
+        (-[WKAccessibilityWebPageObject accessibilityHitTest:]):
+
 2017-04-11  Adrian Perez de Castro  <[email protected]>
 
         [GTK] Attach popup menu to web view widget

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -158,9 +158,20 @@
 - (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter;
 - (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter;
 - (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter;
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+- (NSArray *)accessibilityChildren;
+- (void)setAccessibilityParent:(id)parent;
+- (id)accessibilityElementForAnnotation:(PDFAnnotation *)annotation;
+#endif
 
 @end
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+@interface PDFAnnotation (AccessibilityPrivate)
+- (id)accessibilityNode;
+@end
 #endif
 
+#endif
+
 #endif // PDFLayerControllerSPI_h

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -33,6 +33,7 @@
 #include "Plugin.h"
 #include "WebEvent.h"
 #include "WebHitTestResultData.h"
+#include <WebCore/AXObjectCache.h>
 #include <WebCore/AffineTransform.h>
 #include <WebCore/FindOptions.h>
 #include <WebCore/ScrollableArea.h>
@@ -57,6 +58,7 @@
 }
 
 namespace WebCore {
+class AXObjectCache;
 class Element;
 struct PluginInfo;
 }
@@ -103,6 +105,7 @@
     void attemptToUnlockPDF(const String& password);
 
     WebCore::FloatRect convertFromPDFViewToScreen(const WebCore::FloatRect&) const;
+    WebCore::IntPoint convertFromRootViewToPDFView(const WebCore::IntPoint&) const;
     WebCore::IntRect boundsOnScreen() const;
     
     bool showContextMenuAtPoint(const WebCore::IntPoint&);
@@ -114,6 +117,9 @@
 
     bool shouldPlaceBlockDirectionScrollbarOnLeft() const override { return false; }
 
+    PDFPluginAnnotation* activeAnnotation() const { return m_activeAnnotation.get(); }
+    WebCore::AXObjectCache* axObjectCache() const;
+    
 private:
     explicit PDFPlugin(WebFrame*);
 
@@ -168,11 +174,13 @@
     bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override;
     RefPtr<WebCore::SharedBuffer> liveResourceData() const override;
     void willDetatchRenderer() override;
-
+    bool pluginHandlesContentOffsetForAccessibilityHitTest() const override;
+    
     bool isBeingAsynchronouslyInitialized() const override { return false; }
 
     RetainPtr<PDFDocument> pdfDocumentForPrinting() const override { return m_pdfDocument; }
     NSObject *accessibilityObject() const override;
+    id accessibilityAssociatedPluginParentForElement(WebCore::Element*) const override;
 
     unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) override;
     bool findString(const String& target, WebCore::FindOptions, unsigned maxMatchCount) override;

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm	2017-04-11 16:26:21 UTC (rev 215233)
@@ -50,6 +50,7 @@
 #import <_javascript_Core/JSStringRefCF.h>
 #import <PDFKit/PDFKit.h>
 #import <QuartzCore/QuartzCore.h>
+#import <WebCore/AXObjectCache.h>
 #import <WebCore/ArchiveResource.h>
 #import <WebCore/Chrome.h>
 #import <WebCore/Cursor.h>
@@ -132,7 +133,6 @@
 
 @implementation WKPDFPluginAccessibilityObject
 
-@synthesize pdfLayerController=_pdfLayerController;
 @synthesize parent=_parent;
 @synthesize pdfPlugin=_pdfPlugin;
 
@@ -146,15 +146,51 @@
     return self;
 }
 
+- (PDFLayerController *)pdfLayerController
+{
+    return _pdfLayerController;
+}
+
+- (void)setPdfLayerController:(PDFLayerController *)pdfLayerController
+{
+    _pdfLayerController = pdfLayerController;
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    [_pdfLayerController setAccessibilityParent:self];
+#endif
+}
+
 - (BOOL)accessibilityIsIgnored
 {
     return NO;
 }
 
+// This is called by PDFAccessibilityNodes from inside PDFKit to get final bounds.
+- (NSRect)convertRectToScreenSpace:(NSRect)rect
+{
+    return _pdfPlugin->convertFromPDFViewToScreen(rect);
+}
+
 - (id)accessibilityAttributeValue:(NSString *)attribute
 {
     if ([attribute isEqualToString:NSAccessibilityParentAttribute])
         return _parent;
+    if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
+        return [_parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+    if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
+        return [_parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+    if ([attribute isEqualToString:NSAccessibilitySizeAttribute])
+        return [NSValue valueWithSize:_pdfPlugin->boundsOnScreen().size()];
+    if ([attribute isEqualToString:NSAccessibilityEnabledAttribute])
+        return [_parent accessibilityAttributeValue:NSAccessibilityEnabledAttribute];
+    if ([attribute isEqualToString:NSAccessibilityPositionAttribute])
+        return [NSValue valueWithPoint:_pdfPlugin->boundsOnScreen().location()];
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
+        return @[ _pdfLayerController ];
+    if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
+        return NSAccessibilityGroupRole;
+#else
     if ([attribute isEqualToString:NSAccessibilityValueAttribute])
         return [_pdfLayerController accessibilityValueAttribute];
     if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
@@ -165,22 +201,13 @@
         return [_pdfLayerController accessibilityNumberOfCharactersAttribute];
     if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
         return [_pdfLayerController accessibilityVisibleCharacterRangeAttribute];
-    if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
-        return [_parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
     if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
         return [_pdfLayerController accessibilityRoleAttribute];
     if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
         return [_pdfLayerController accessibilityRoleDescriptionAttribute];
-    if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
-        return [_parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
-    if ([attribute isEqualToString:NSAccessibilitySizeAttribute])
-        return [NSValue valueWithSize:_pdfPlugin->boundsOnScreen().size()];
     if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
         return [_parent accessibilityAttributeValue:NSAccessibilityFocusedAttribute];
-    if ([attribute isEqualToString:NSAccessibilityEnabledAttribute])
-        return [_parent accessibilityAttributeValue:NSAccessibilityEnabledAttribute];
-    if ([attribute isEqualToString:NSAccessibilityPositionAttribute])
-        return [NSValue valueWithPoint:_pdfPlugin->boundsOnScreen().location()];
+#endif
 
     return 0;
 }
@@ -213,20 +240,27 @@
     static NSArray *attributeNames = 0;
 
     if (!attributeNames) {
-        attributeNames = @[NSAccessibilityValueAttribute,
-            NSAccessibilitySelectedTextAttribute,
-            NSAccessibilitySelectedTextRangeAttribute,
-            NSAccessibilityNumberOfCharactersAttribute,
-            NSAccessibilityVisibleCharacterRangeAttribute,
+        attributeNames = @[
             NSAccessibilityParentAttribute,
-            NSAccessibilityRoleAttribute,
             NSAccessibilityWindowAttribute,
             NSAccessibilityTopLevelUIElementAttribute,
             NSAccessibilityRoleDescriptionAttribute,
             NSAccessibilitySizeAttribute,
+            NSAccessibilityEnabledAttribute,
+            NSAccessibilityPositionAttribute,
             NSAccessibilityFocusedAttribute,
-            NSAccessibilityEnabledAttribute,
-            NSAccessibilityPositionAttribute];
+            // PDFLayerController has its own accessibilityChildren.
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+            NSAccessibilityChildrenAttribute
+#else
+            NSAccessibilityRoleAttribute,
+            NSAccessibilityValueAttribute,
+            NSAccessibilitySelectedTextAttribute,
+            NSAccessibilitySelectedTextRangeAttribute,
+            NSAccessibilityNumberOfCharactersAttribute,
+            NSAccessibilityVisibleCharacterRangeAttribute
+#endif
+            ];
         [attributeNames retain];
     }
 
@@ -235,6 +269,9 @@
 
 - (NSArray *)accessibilityActionNames
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    return nil;
+#else
     static NSArray *actionNames = 0;
     
     if (!actionNames)
@@ -241,6 +278,7 @@
         actionNames = [[NSArray arrayWithObject:NSAccessibilityShowMenuAction] retain];
     
     return actionNames;
+#endif
 }
 
 - (void)accessibilityPerformAction:(NSString *)action
@@ -261,17 +299,59 @@
 
 - (NSArray *)accessibilityParameterizedAttributeNames
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    return nil;
+#else
     return [_pdfLayerController accessibilityParameterizedAttributeNames];
+#endif
 }
 
 - (id)accessibilityFocusedUIElement
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    if (WebKit::PDFPluginAnnotation* activeAnnotation = _pdfPlugin->activeAnnotation()) {
+        if (AXObjectCache* existingCache = _pdfPlugin->axObjectCache()) {
+            if (AccessibilityObject* object = existingCache->getOrCreate(activeAnnotation->element()))
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+                return [object->wrapper() accessibilityAttributeValue:@"_AXAssociatedPluginParent"];
+#pragma clang diagnostic pop
+        }
+    }
+    return nil;
+#else
     return self;
+#endif
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+- (id)accessibilityAssociatedControlForAnnotation:(PDFAnnotation *)annotation
+{
+    // Only active annotations seem to have their associated controls available.
+    WebKit::PDFPluginAnnotation* activeAnnotation = _pdfPlugin->activeAnnotation();
+    if (!activeAnnotation || ![activeAnnotation->annotation() isEqual:annotation])
+        return nil;
+    
+    AXObjectCache* cache = _pdfPlugin->axObjectCache();
+    if (!cache)
+        return nil;
+    
+    AccessibilityObject* object = cache->getOrCreate(activeAnnotation->element());
+    if (!object)
+        return nil;
+
+    return object->wrapper();
+}
+#endif
+
 - (id)accessibilityHitTest:(NSPoint)point
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    point = _pdfPlugin->convertFromRootViewToPDFView(IntPoint(point));
+    return [_pdfLayerController accessibilityHitTest:point];
+#else
     return self;
+#endif
 }
 
 @end
@@ -1206,6 +1286,12 @@
     IntPoint pointInPluginCoordinates(point.x(), size().height() - point.y());
     return m_rootViewToPluginTransform.inverse().value_or(AffineTransform()).mapPoint(pointInPluginCoordinates);
 }
+    
+IntPoint PDFPlugin::convertFromRootViewToPDFView(const IntPoint& point) const
+{
+    IntPoint pointInPluginCoordinates = m_rootViewToPluginTransform.mapPoint(point);
+    return IntPoint(pointInPluginCoordinates.x(), size().height() - pointInPluginCoordinates.y());
+}
 
 FloatRect PDFPlugin::convertFromPDFViewToScreen(const FloatRect& rect) const
 {
@@ -1214,10 +1300,9 @@
     if (!frameView)
         return FloatRect();
 
-    FloatPoint originInPluginCoordinates(rect.x(), size().height() - rect.y() - rect.height());
-    FloatRect rectInRootViewCoordinates = m_rootViewToPluginTransform.inverse().value_or(AffineTransform()).mapRect(FloatRect(originInPluginCoordinates, rect.size()));
-
-    return frameView->contentsToScreen(enclosingIntRect(rectInRootViewCoordinates));
+    FloatRect updatedRect = rect;
+    updatedRect.setLocation(convertFromPDFViewToRootView(IntPoint(updatedRect.location())));
+    return webFrame()->coreFrame()->page()->chrome().rootViewToScreen(enclosingIntRect(updatedRect));
 }
 
 IntRect PDFPlugin::boundsOnScreen() const
@@ -1674,6 +1759,17 @@
     return SharedBuffer::wrapNSData(pdfData);
 }
 
+bool PDFPlugin::pluginHandlesContentOffsetForAccessibilityHitTest() const
+{
+    // The PDF plugin handles the scroll view offset natively as part of the layer conversions.
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    return true;
+#else
+    return false;
+#endif
+}
+
+    
 void PDFPlugin::saveToPDF()
 {
     // FIXME: We should probably notify the user that they can't save before the document is finished loading.
@@ -2014,6 +2110,11 @@
 
     return NSRectFromCGRect(newRect);
 }
+    
+WebCore::AXObjectCache* PDFPlugin::axObjectCache() const
+{
+    return webFrame()->coreFrame()->document()->axObjectCache();
+}
 
 WebCore::FloatRect PDFPlugin::rectForSelectionInRootView(PDFSelection *selection) const
 {
@@ -2103,6 +2204,21 @@
     return rawData();
 }
 
+id PDFPlugin::accessibilityAssociatedPluginParentForElement(WebCore::Element* element) const
+{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
+    if (!m_activeAnnotation)
+        return nil;
+    
+    if (m_activeAnnotation->element() != element)
+        return nil;
+    
+    return [m_activeAnnotation->annotation() accessibilityNode];
+#else
+    return nil;
+#endif
+}
+    
 NSObject *PDFPlugin::accessibilityObject() const
 {
     return m_accessibilityObject.get();

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm	2017-04-11 16:26:21 UTC (rev 215233)
@@ -70,6 +70,7 @@
     m_element = createAnnotationElement();
 
     m_element->setAttributeWithoutSynchronization(classAttr, AtomicString("annotation", AtomicString::ConstructFromLiteral));
+    m_element->setAttributeWithoutSynchronization(x_apple_pdf_annotationAttr, AtomicString("true", AtomicString::ConstructFromLiteral));
     m_element->addEventListener(eventNames().changeEvent, *m_eventListener, false);
     m_element->addEventListener(eventNames().blurEvent, *m_eventListener, false);
 

Modified: trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -37,6 +37,7 @@
 
 #if PLATFORM(COCOA)
 #include "LayerHostingContext.h"
+typedef struct objc_object* id;
 
 OBJC_CLASS NSDictionary;
 OBJC_CLASS NSObject;
@@ -274,6 +275,7 @@
 #if PLATFORM(COCOA)
     virtual RetainPtr<PDFDocument> pdfDocumentForPrinting() const { return 0; }
     virtual NSObject *accessibilityObject() const { return 0; }
+    virtual id accessibilityAssociatedPluginParentForElement(WebCore::Element*) const { return nullptr; }
 #endif
 
     virtual unsigned countFindMatches(const String& target, WebCore::FindOptions, unsigned maxMatchCount) = 0;
@@ -300,6 +302,8 @@
 
     virtual void willDetatchRenderer() { }
 
+    virtual bool pluginHandlesContentOffsetForAccessibilityHitTest() const { return false; }
+
 protected:
     Plugin(PluginType);
 

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp	2017-04-11 16:26:21 UTC (rev 215233)
@@ -555,6 +555,13 @@
     return true;
 }
     
+id PluginView::accessibilityAssociatedPluginParentForElement(Element* element) const
+{
+    if (!m_plugin)
+        return nil;
+    return m_plugin->accessibilityAssociatedPluginParentForElement(element);
+}
+    
 NSObject *PluginView::accessibilityObject() const
 {
     if (!m_isInitialized || !m_plugin)

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -86,6 +86,7 @@
     bool sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
     RetainPtr<PDFDocument> pdfDocumentForPrinting() const { return m_plugin->pdfDocumentForPrinting(); }
     NSObject *accessibilityObject() const;
+    id accessibilityAssociatedPluginParentForElement(WebCore::Element*) const override;
 #endif
 
     WebCore::HTMLPlugInElement* pluginElement() const { return m_pluginElement.get(); }

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2017-04-11 16:26:21 UTC (rev 215233)
@@ -972,6 +972,8 @@
     WebURLSchemeHandlerProxy* urlSchemeHandlerForScheme(const String&);
     std::optional<double> backgroundCPULimit() const { return m_backgroundCPULimit; }
 
+    static PluginView* pluginViewForFrame(WebCore::Frame*);
+
 private:
     WebPage(uint64_t pageID, WebPageCreationParameters&&);
 
@@ -1212,7 +1214,6 @@
     static bool platformCanHandleRequest(const WebCore::ResourceRequest&);
 
     static PluginView* focusedPluginViewForFrame(WebCore::Frame&);
-    static PluginView* pluginViewForFrame(WebCore::Frame*);
 
     static RefPtr<WebCore::Range> rangeFromEditingRange(WebCore::Frame&, const EditingRange&, EditingRangeIsRelativeTo = EditingRangeIsRelativeTo::EditableRoot);
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm (215232 => 215233)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm	2017-04-11 15:59:47 UTC (rev 215232)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObjectMac.mm	2017-04-11 16:26:21 UTC (rev 215233)
@@ -28,6 +28,7 @@
 
 #if PLATFORM(MAC)
 
+#import "PluginView.h"
 #import "WebFrame.h"
 #import "WebPage.h"
 #import "WKArray.h"
@@ -193,13 +194,21 @@
 {
     if (!m_page)
         return nil;
-    
+
     IntPoint convertedPoint = m_page->screenToRootView(IntPoint(point));
-    if (WebCore::FrameView* frameView = m_page->mainFrameView())
-        convertedPoint.moveBy(frameView->scrollPosition());
-    if (WebCore::Page* page = m_page->corePage())
-        convertedPoint.move(0, -page->topContentInset());
     
+    // Some plugins may be able to figure out the scroll position and inset on their own.
+    bool applyContentOffset = true;
+    if (auto pluginView = m_page->pluginViewForFrame(m_page->mainFrame()))
+        applyContentOffset = !pluginView->plugin()->pluginHandlesContentOffsetForAccessibilityHitTest();
+
+    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 [[self accessibilityRootObjectWrapper] accessibilityHitTest:convertedPoint];
 }
 #pragma clang diagnostic pop
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to