https://bugs.webkit.org/show_bug.cgi?id=113817
Reviewed by David Kilzer.
Source/WebCore:
This allows bounding paths to be returned for some web elements (image map areas and SVG shapes).
This provides more accuracy when assistive technologies highlight elements.
The Mac and iOS platforms share some code to help transform paths to their screen coordinates.
Tests: platform/iphone-simulator/accessibility/element-paths.html
platform/mac/accessibility/element-paths.html
* accessibility/AccessibilityImageMapLink.cpp:
(WebCore::AccessibilityImageMapLink::imageMapLinkRenderer):
(WebCore):
(WebCore::AccessibilityImageMapLink::elementPath):
(WebCore::AccessibilityImageMapLink::elementRect):
* accessibility/AccessibilityImageMapLink.h:
(AccessibilityImageMapLink):
(WebCore::AccessibilityImageMapLink::supportsPath):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::elementPath):
(WebCore::AccessibilityObject::supportsPath):
* accessibility/AccessibilityRenderObject.cpp:
(WebCore):
(WebCore::AccessibilityRenderObject::supportsPath):
(WebCore::AccessibilityRenderObject::elementPath):
* accessibility/AccessibilityRenderObject.h:
(AccessibilityRenderObject):
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper _accessibilityPath]):
(-[WebAccessibilityObjectWrapper convertPointToScreenSpace:]):
(-[WebAccessibilityObjectWrapper convertRectToScreenSpace:]):
(-[WebAccessibilityObjectWrapper accessibilityActivationPoint]):
(-[WebAccessibilityObjectWrapper accessibilityFrame]):
(-[WebAccessibilityObjectWrapper frameForTextMarkers:]):
* accessibility/mac/WebAccessibilityObjectWrapperBase.h:
(WebCore):
* accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
(PathConversionInfo):
(ConvertPathToScreenSpaceFunction):
(-[WebAccessibilityObjectWrapperBase convertPathToScreenSpace:]):
(-[WebAccessibilityObjectWrapperBase convertPointToScreenSpace:]):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper additionalAccessibilityAttributeNames]):
(-[WebAccessibilityObjectWrapper convertPointToScreenSpace:]):
(WebTransformCGPathToNSBezierPath):
(-[WebAccessibilityObjectWrapper bezierPathFromPath:]):
(-[WebAccessibilityObjectWrapper path]):
(-[WebAccessibilityObjectWrapper position]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
Tools:
Add a pathDescription property for testing so that it's possible
to verify that a path is being returned correctly.
* DumpRenderTree/AccessibilityUIElement.cpp:
(getPathDescriptionCallback):
(AccessibilityUIElement::pathDescription):
(AccessibilityUIElement::getJSClass):
* DumpRenderTree/AccessibilityUIElement.h:
(AccessibilityUIElement):
* DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
(_CGPathEnumerationIteration):
(AccessibilityUIElement::pathDescription):
* DumpRenderTree/mac/AccessibilityUIElementMac.mm:
(AccessibilityUIElement::pathDescription):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
(WTR::AccessibilityUIElement::pathDescription):
(WTR):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
(AccessibilityUIElement):
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::AccessibilityUIElement::pathDescription):
(WTR):
LayoutTests:
Add new tests for Mac and iOS to verify that path output works.
Modify existing tests to indicate that there is a new AXAttribute, AXPath.
* platform/iphone-simulator/accessibility/element-paths-expected.txt: Added.
* platform/iphone-simulator/accessibility/element-paths.html: Added.
* platform/mac/accessibility/document-links-expected.txt:
* platform/mac/accessibility/element-paths-expected.txt: Added.
* platform/mac/accessibility/element-paths.html: Added.
* platform/mac/accessibility/image-map2-expected.txt:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@148033
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2013-04-09 Chris Fleizach <cfleizach@apple.com>
+
+ AX: The bounding paths should be made available through accessibility
+ https://bugs.webkit.org/show_bug.cgi?id=113817
+
+ Reviewed by David Kilzer.
+
+ Add new tests for Mac and iOS to verify that path output works.
+ Modify existing tests to indicate that there is a new AXAttribute, AXPath.
+
+ * platform/iphone-simulator/accessibility/element-paths-expected.txt: Added.
+ * platform/iphone-simulator/accessibility/element-paths.html: Added.
+ * platform/mac/accessibility/document-links-expected.txt:
+ * platform/mac/accessibility/element-paths-expected.txt: Added.
+ * platform/mac/accessibility/element-paths.html: Added.
+ * platform/mac/accessibility/image-map2-expected.txt:
+
2013-04-09 Arnaud Renevier <a.renevier@sisa.samsung.com>
Whitespace in particular source code changes rendering; does not in Firefox
--- /dev/null
+
+This tests SVG group elements are accessible and that the svg:title element is returned properly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+SVG path description
+Start Path
+ Move to point
+ Line to
+ Line to
+ Close
+
+Map1 path description
+Start Path
+ Move to point
+ Line to
+ Line to
+ Line to
+ Line to
+ Close
+
+Map2 path description
+Start Path
+ Move to point
+ Curve to
+ Curve to
+ Curve to
+ Curve to
+ Close
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <path role="button" id="svg" d="M150 0 L75 200 L225 200 Z" />
+</svg>
+
+<map name="imagemap1">
+ <AREA id="map1" shape="polygon" coords="90,25,162,26,163,96,89,25,90,24" href="triangle.html">
+ <AREA id="map2" shape="circle" coords="130,304,110" href="circle.html">
+</map>
+
+<img src="resources/cake.png" border="0" align="left" usemap="#imagemap1" vspace="1">
+
+<div id="console"></div>
+
+<script>
+
+ description("This tests SVG group elements are accessible and that the svg:title element is returned properly.");
+
+ if (window.accessibilityController) {
+
+ var svg = accessibilityController.accessibleElementById("svg");
+ debug("SVG path description" + svg.pathDescription);
+
+ var map1 = accessibilityController.accessibleElementById("map1");
+ debug("Map1 path description" + map1.pathDescription);
+
+ var map2 = accessibilityController.accessibleElementById("map2");
+ debug("Map2 path description" + map2.pathDescription);
+ }
+
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
AXURL: http://www.apple.com/
AXAccessKey: (null)
AXARIABusy: 0
+AXPath: <AXLink: 'Link1'>
------------
AXRole: AXLink
AXURL: http://www.apple.com/
AXAccessKey: (null)
AXARIABusy: 0
+AXPath: <AXLink: 'Link2'>
------------
AXRole: AXLink
--- /dev/null
+
+This tests SVG group elements are accessible and that the svg:title element is returned properly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS svg.isAttributeSupported('AXPath') is true
+SVG path description
+Start Path
+ Move to point
+ Line to
+ Line to
+ Close
+ Move to point
+
+PASS map1.isAttributeSupported('AXPath') is true
+Map1 path description
+Start Path
+ Move to point
+ Line to
+ Line to
+ Line to
+ Line to
+ Close
+ Move to point
+
+PASS map2.isAttributeSupported('AXPath') is true
+Map2 path description
+Start Path
+ Move to point
+ Curve to
+ Curve to
+ Curve to
+ Curve to
+ Close
+ Move to point
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <path role="button" id="svg" d="M150 0 L75 200 L225 200 Z" />
+</svg>
+
+<map name="imagemap1">
+ <AREA id="map1" shape="polygon" coords="90,25,162,26,163,96,89,25,90,24" href="triangle.html">
+ <AREA id="map2" shape="circle" coords="130,304,110" href="circle.html">
+</map>
+
+<img src="resources/cake.png" border="1" align="left" usemap="#imagemap1" vspace="1">
+
+<div id="console"></div>
+
+<script>
+
+ description("This tests SVG group elements are accessible and that the svg:title element is returned properly.");
+
+ if (window.accessibilityController) {
+
+ var svg = accessibilityController.accessibleElementById("svg");
+ shouldBeTrue("svg.isAttributeSupported('AXPath')");
+ debug("SVG path description" + svg.pathDescription);
+
+ var map1 = accessibilityController.accessibleElementById("map1");
+ shouldBeTrue("map1.isAttributeSupported('AXPath')");
+ debug("Map1 path description" + map1.pathDescription);
+
+ var map2 = accessibilityController.accessibleElementById("map2");
+ shouldBeTrue("map2.isAttributeSupported('AXPath')");
+ debug("Map2 path description" + map2.pathDescription);
+ }
+
+</script>
+
+<script src="../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
AXURL: http://www.apple.com/
AXAccessKey: (null)
AXARIABusy: 0
+AXPath: <AXLink>
------------
AXRole: AXLink
AXURL: http://www.apple.com/
AXAccessKey: (null)
AXARIABusy: 0
+AXPath: <AXLink>
------------
+2013-04-09 Chris Fleizach <cfleizach@apple.com>
+
+ AX: The bounding paths should be made available through accessibility
+ https://bugs.webkit.org/show_bug.cgi?id=113817
+
+ Reviewed by David Kilzer.
+
+ This allows bounding paths to be returned for some web elements (image map areas and SVG shapes).
+ This provides more accuracy when assistive technologies highlight elements.
+ The Mac and iOS platforms share some code to help transform paths to their screen coordinates.
+
+ Tests: platform/iphone-simulator/accessibility/element-paths.html
+ platform/mac/accessibility/element-paths.html
+
+ * accessibility/AccessibilityImageMapLink.cpp:
+ (WebCore::AccessibilityImageMapLink::imageMapLinkRenderer):
+ (WebCore):
+ (WebCore::AccessibilityImageMapLink::elementPath):
+ (WebCore::AccessibilityImageMapLink::elementRect):
+ * accessibility/AccessibilityImageMapLink.h:
+ (AccessibilityImageMapLink):
+ (WebCore::AccessibilityImageMapLink::supportsPath):
+ * accessibility/AccessibilityObject.h:
+ (WebCore::AccessibilityObject::elementPath):
+ (WebCore::AccessibilityObject::supportsPath):
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore):
+ (WebCore::AccessibilityRenderObject::supportsPath):
+ (WebCore::AccessibilityRenderObject::elementPath):
+ * accessibility/AccessibilityRenderObject.h:
+ (AccessibilityRenderObject):
+ * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+ (-[WebAccessibilityObjectWrapper _accessibilityPath]):
+ (-[WebAccessibilityObjectWrapper convertPointToScreenSpace:]):
+ (-[WebAccessibilityObjectWrapper convertRectToScreenSpace:]):
+ (-[WebAccessibilityObjectWrapper accessibilityActivationPoint]):
+ (-[WebAccessibilityObjectWrapper accessibilityFrame]):
+ (-[WebAccessibilityObjectWrapper frameForTextMarkers:]):
+ * accessibility/mac/WebAccessibilityObjectWrapperBase.h:
+ (WebCore):
+ * accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
+ (PathConversionInfo):
+ (ConvertPathToScreenSpaceFunction):
+ (-[WebAccessibilityObjectWrapperBase convertPathToScreenSpace:]):
+ (-[WebAccessibilityObjectWrapperBase convertPointToScreenSpace:]):
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper additionalAccessibilityAttributeNames]):
+ (-[WebAccessibilityObjectWrapper convertPointToScreenSpace:]):
+ (WebTransformCGPathToNSBezierPath):
+ (-[WebAccessibilityObjectWrapper bezierPathFromPath:]):
+ (-[WebAccessibilityObjectWrapper path]):
+ (-[WebAccessibilityObjectWrapper position]):
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+
2013-04-09 Benjamin Poulain <bpoulain@apple.com>
Remove the WebKit copy of GLU and the file using it
return String();
}
-LayoutRect AccessibilityImageMapLink::elementRect() const
+RenderObject* AccessibilityImageMapLink::imageMapLinkRenderer() const
{
if (!m_mapElement.get() || !m_areaElement.get())
- return LayoutRect();
+ return 0;
- RenderObject* renderer;
+ RenderObject* renderer = 0;
if (m_parent && m_parent->isAccessibilityRenderObject())
renderer = static_cast<AccessibilityRenderObject*>(m_parent)->renderer();
else
renderer = m_mapElement->renderer();
+ return renderer;
+}
+
+Path AccessibilityImageMapLink::elementPath() const
+{
+ RenderObject* renderer = imageMapLinkRenderer();
+ if (!renderer)
+ return Path();
+
+ return m_areaElement->computePath(renderer);
+}
+
+LayoutRect AccessibilityImageMapLink::elementRect() const
+{
+ RenderObject* renderer = imageMapLinkRenderer();
if (!renderer)
return LayoutRect();
RefPtr<HTMLAreaElement> m_areaElement;
RefPtr<HTMLMapElement> m_mapElement;
+ virtual Path elementPath() const;
+ RenderObject* imageMapLinkRenderer() const;
virtual void accessibilityText(Vector<AccessibilityText>&);
virtual bool isImageMapLink() const { return true; }
+ virtual bool supportsPath() const { return true; }
};
} // namespace WebCore
#include "FloatQuad.h"
#include "LayoutRect.h"
+#include "Path.h"
#include "TextIterator.h"
#include "VisiblePosition.h"
#include "VisibleSelection.h"
IntSize pixelSnappedSize() const { return elementRect().pixelSnappedSize(); }
virtual IntPoint clickPoint();
static IntRect boundingBoxForQuads(RenderObject*, const Vector<FloatQuad>&);
+ virtual Path elementPath() const { return Path(); }
+ virtual bool supportsPath() const { return false; }
TextIteratorBehavior textIteratorBehaviorForTextRange() const;
virtual PlainTextRange selectedTextRange() const { return PlainTextRange(); }
bool isDescendantOfObject(const AccessibilityObject*) const;
bool isAncestorOfObject(const AccessibilityObject*) const;
AccessibilityObject* firstAnonymousBlockChild() const;
-
+
static AccessibilityRole ariaRoleToWebCoreRole(const String&);
bool hasAttribute(const QualifiedName&) const;
const AtomicString& getAttribute(const QualifiedName&) const;
return boundingBoxRect();
}
+
+bool AccessibilityRenderObject::supportsPath() const
+{
+#if ENABLE(SVG)
+ if (m_renderer && m_renderer->isSVGShape())
+ return true;
+#endif
+
+ return false;
+}
+
+Path AccessibilityRenderObject::elementPath() const
+{
+#if ENABLE(SVG)
+ if (m_renderer && m_renderer->isSVGShape())
+ return toRenderSVGShape(m_renderer)->path();
+#endif
+
+ return Path();
+}
IntPoint AccessibilityRenderObject::clickPoint()
{
Element* rootEditableElementForPosition(const Position&) const;
bool nodeIsTextControl(const Node*) const;
virtual void setNeedsToUpdateChildren() { m_childrenDirty = true; }
-
+ virtual Path elementPath() const;
+
bool isTabItemSelected() const;
LayoutRect checkboxOrRadioRect() const;
void addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const;
AccessibilitySVGRoot* remoteSVGRootElement() const;
AccessibilityObject* remoteSVGElementHitTest(const IntPoint&) const;
void offsetBoundingBoxForRemoteSVGElement(LayoutRect&) const;
-
+ virtual bool supportsPath() const;
+
void addHiddenChildren();
void addTextFieldChildren();
void addImageMapChildren();
virtual const AtomicString& ariaLiveRegionRelevant() const;
virtual bool ariaLiveRegionAtomic() const;
virtual bool ariaLiveRegionBusy() const;
-
+
bool inheritsPresentationalRole() const;
#if ENABLE(MATHML)
return NSNotFound;
}
+- (CGPathRef)_accessibilityPath
+{
+ if (![self _prepareAccessibilityCall])
+ return NULL;
+
+ if (!m_object->supportsPath())
+ return NULL;
+
+ Path path = m_object->elementPath();
+ if (path.isEmpty())
+ return NULL;
+
+ Path transformedPath = [self convertPathToScreenSpace:path];
+ return transformedPath.platformPath();
+}
+
- (NSString *)accessibilityLanguage
{
if (![self _prepareAccessibilityCall])
return (NSURL*)url;
}
-- (CGRect)_convertIntRectToScreenCoordinates:(IntRect)rect
+- (CGPoint)convertPointToScreenSpace:(FloatPoint &)point
+{
+ if (!m_object)
+ return CGPointZero;
+
+ CGPoint cgPoint = CGPointMake(point.x(), point.y());
+
+ FrameView* frameView = m_object->documentFrameView();
+ if (frameView) {
+ WAKView* view = frameView->documentView();
+ cgPoint = [view convertPoint:cgPoint toView:nil];
+ }
+
+ // we need the web document view to give us our final screen coordinates
+ // because that can take account of the scroller
+ id webDocument = [self _accessibilityWebDocumentView];
+ if (webDocument)
+ cgPoint = [webDocument convertPoint:cgPoint toView:nil];
+
+ return cgPoint;
+}
+
+- (CGRect)convertRectToScreenSpace:(IntRect &)rect
{
if (!m_object)
return CGRectZero;
return CGPointZero;
IntRect rect = pixelSnappedIntRect(m_object->boundingBoxRect());
- CGRect cgRect = [self _convertIntRectToScreenCoordinates:rect];
+ CGRect cgRect = [self convertRectToScreenSpace:rect];
return CGPointMake(CGRectGetMidX(cgRect), CGRectGetMidY(cgRect));
}
return CGRectZero;
IntRect rect = pixelSnappedIntRect(m_object->elementRect());
- return [self _convertIntRectToScreenCoordinates:rect];
+ return [self convertRectToScreenSpace:rect];
}
// Checks whether a link contains only static text and images (and has been divided unnaturally by <spans> and other nefarious mechanisms).
return CGRectZero;
IntRect rect = m_object->boundsForVisiblePositionRange(VisiblePositionRange([startMarker visiblePosition], [endMarker visiblePosition]));
- return [self _convertIntRectToScreenCoordinates:rect];
+ return [self convertRectToScreenSpace:rect];
}
- (WebAccessibilityTextMarker *)textMarkerForPoint:(CGPoint)point
namespace WebCore {
class AccessibilityObject;
+class IntRect;
+class FloatPoint;
+class Path;
class VisiblePosition;
}
// Used to inform an element when a notification is posted for it. Used by DRT.
- (void)accessibilityPostedNotification:(NSString *)notificationName;
+- (CGPathRef)convertPathToScreenSpace:(WebCore::Path &)path;
+- (CGPoint)convertPointToScreenSpace:(WebCore::FloatPoint &)point;
+
@end
#endif // WebAccessibilityObjectWrapperBase_h
return [NSString string];
}
+struct PathConversionInfo {
+ WebAccessibilityObjectWrapperBase *wrapper;
+ CGMutablePathRef path;
+};
+
+static void ConvertPathToScreenSpaceFunction(void* info, const PathElement* element)
+{
+ PathConversionInfo* conversion = (PathConversionInfo*)info;
+ WebAccessibilityObjectWrapperBase *wrapper = conversion->wrapper;
+ CGMutablePathRef newPath = conversion->path;
+ switch (element->type) {
+ case PathElementMoveToPoint:
+ {
+ CGPoint newPoint = [wrapper convertPointToScreenSpace:element->points[0]];
+ CGPathMoveToPoint(newPath, nil, newPoint.x, newPoint.y);
+ break;
+ }
+ case PathElementAddLineToPoint:
+ {
+ CGPoint newPoint = [wrapper convertPointToScreenSpace:element->points[0]];
+ CGPathAddLineToPoint(newPath, nil, newPoint.x, newPoint.y);
+ break;
+ }
+ case PathElementAddQuadCurveToPoint:
+ {
+ CGPoint newPoint1 = [wrapper convertPointToScreenSpace:element->points[0]];
+ CGPoint newPoint2 = [wrapper convertPointToScreenSpace:element->points[1]];
+ CGPathAddQuadCurveToPoint(newPath, nil, newPoint1.x, newPoint1.y, newPoint2.x, newPoint2.y);
+ break;
+ }
+ case PathElementAddCurveToPoint:
+ {
+ CGPoint newPoint1 = [wrapper convertPointToScreenSpace:element->points[0]];
+ CGPoint newPoint2 = [wrapper convertPointToScreenSpace:element->points[1]];
+ CGPoint newPoint3 = [wrapper convertPointToScreenSpace:element->points[2]];
+ CGPathAddCurveToPoint(newPath, nil, newPoint1.x, newPoint1.y, newPoint2.x, newPoint2.y, newPoint3.x, newPoint3.y);
+ break;
+ }
+ case PathElementCloseSubpath:
+ {
+ CGPathCloseSubpath(newPath);
+ break;
+ }
+ }
+}
+
+- (CGPathRef)convertPathToScreenSpace:(Path &)path
+{
+ PathConversionInfo conversion = { self, CGPathCreateMutable() };
+ path.apply(&conversion, ConvertPathToScreenSpaceFunction);
+ return (CGPathRef)[(id)conversion.path autorelease];
+}
+
+- (CGPoint)convertPointToScreenSpace:(FloatPoint &)point
+{
+ UNUSED_PARAM(point);
+ ASSERT_NOT_REACHED();
+ return CGPointZero;
+}
+
// This is set by DRT when it wants to listen for notifications.
static BOOL accessibilityShouldRepostNotifications;
+ (void)accessibilitySetShouldRepostNotifications:(BOOL)repost
#define NSAccessibilityScrollToVisibleAction @"AXScrollToVisible"
#endif
+#ifndef NSAccessibilityPathAttribute
+#define NSAccessibilityPathAttribute @"AXPath"
+#endif
+
// Math attributes
#define NSAccessibilityMathRootRadicandAttribute @"AXMathRootRadicand"
#define NSAccessibilityMathRootIndexAttribute @"AXMathRootIndex"
[additional addObject:NSAccessibilityMathFencedCloseAttribute];
}
+ if (m_object->supportsPath())
+ [additional addObject:NSAccessibilityPathAttribute];
+
return additional;
}
return [self textMarkerRangeFromVisiblePositions:selection.visibleStart() endPosition:selection.visibleEnd()];
}
-- (NSValue *)position
+- (CGPoint)convertPointToScreenSpace:(FloatPoint &)point
{
- IntRect rect = pixelSnappedIntRect(m_object->elementRect());
- NSPoint point;
-
FrameView* frameView = m_object->documentFrameView();
// WebKit1 code path... platformWidget() exists.
if (frameView && frameView->platformWidget()) {
- // The Cocoa accessibility API wants the lower-left corner.
- point = NSMakePoint(rect.x(), rect.maxY());
-
- if (frameView) {
- NSView* view = frameView->documentView();
- point = [[view window] convertBaseToScreen:[view convertPoint: point toView:nil]];
- }
+ NSPoint nsPoint = (NSPoint)point;
+ NSView* view = frameView->documentView();
+ nsPoint = [[view window] convertBaseToScreen:[view convertPoint:nsPoint toView:nil]];
+ return CGPointMake(nsPoint.x, nsPoint.y);
+
} else {
// Find the appropriate scroll view to use to convert the contents to the window.
}
}
+ IntPoint intPoint = (IntPoint)point;
if (scrollView)
- rect = scrollView->contentsToRootView(rect);
+ intPoint = scrollView->contentsToRootView(intPoint);
Page* page = m_object->page();
if (parent && page && page->chrome()->client()->isEmptyChromeClient())
page = parent->page();
- if (page)
- point = page->chrome()->rootViewToScreen(rect).location();
- else
- point = rect.location();
+ if (page) {
+ IntRect rect = IntRect(intPoint, IntSize(0, 0));
+ intPoint = page->chrome()->rootViewToScreen(rect).location();
+ }
+
+ return intPoint;
+ }
+}
+
+static void WebTransformCGPathToNSBezierPath(void *info, const CGPathElement *element)
+{
+ NSBezierPath *bezierPath = (NSBezierPath *)info;
+ switch (element->type) {
+ case kCGPathElementMoveToPoint:
+ [bezierPath moveToPoint:element->points[0]];
+ break;
+ case kCGPathElementAddLineToPoint:
+ [bezierPath lineToPoint:element->points[0]];
+ break;
+ case kCGPathElementAddCurveToPoint:
+ [bezierPath curveToPoint:element->points[0] controlPoint1:element->points[1] controlPoint2:element->points[2]];
+ break;
+ case kCGPathElementCloseSubpath:
+ [bezierPath closePath];
+ break;
+ default:
+ break;
}
+}
+
+- (NSBezierPath *)bezierPathFromPath:(CGPathRef)path
+{
+ NSBezierPath *bezierPath = [NSBezierPath bezierPath];
+ CGPathApply(path, bezierPath, WebTransformCGPathToNSBezierPath);
+ return bezierPath;
+}
+
+- (NSBezierPath *)path
+{
+ Path path = m_object->elementPath();
+ if (path.isEmpty())
+ return NULL;
+
+ CGPathRef transformedPath = [self convertPathToScreenSpace:path];
+ return [self bezierPathFromPath:transformedPath];
+}
+
+- (NSValue *)position
+{
+ IntRect rect = pixelSnappedIntRect(m_object->elementRect());
+
+ // The Cocoa accessibility API wants the lower-left corner.
+ FloatPoint floatPoint = FloatPoint(rect.x(), rect.maxY());
+
+ CGPoint cgPoint = [self convertPointToScreenSpace:floatPoint];
- return [NSValue valueWithPoint:point];
+ return [NSValue valueWithPoint:NSMakePoint(cgPoint.x, cgPoint.y)];
}
typedef HashMap<int, NSString*> AccessibilityRoleMap;
if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
return [self position];
+ if ([attributeName isEqualToString:NSAccessibilityPathAttribute])
+ return [self path];
if ([attributeName isEqualToString: NSAccessibilityWindowAttribute] ||
[attributeName isEqualToString: NSAccessibilityTopLevelUIElementAttribute]) {
+2013-04-09 Chris Fleizach <cfleizach@apple.com>
+
+ AX: The bounding paths should be made available through accessibility
+ https://bugs.webkit.org/show_bug.cgi?id=113817
+
+ Reviewed by David Kilzer.
+
+ Add a pathDescription property for testing so that it's possible
+ to verify that a path is being returned correctly.
+
+ * DumpRenderTree/AccessibilityUIElement.cpp:
+ (getPathDescriptionCallback):
+ (AccessibilityUIElement::pathDescription):
+ (AccessibilityUIElement::getJSClass):
+ * DumpRenderTree/AccessibilityUIElement.h:
+ (AccessibilityUIElement):
+ * DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
+ (_CGPathEnumerationIteration):
+ (AccessibilityUIElement::pathDescription):
+ * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+ (AccessibilityUIElement::pathDescription):
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
+ (WTR::AccessibilityUIElement::pathDescription):
+ (WTR):
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+ (AccessibilityUIElement):
+ * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+ (WTR::AccessibilityUIElement::pathDescription):
+ (WTR):
+
2013-04-09 Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
[EFL] Declare TEST_THEME_DIR in a single place.
return JSValueMakeNumber(context, toAXElement(thisObject)->insertionPointLineNumber());
}
+static JSValueRef getPathDescriptionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ JSRetainPtr<JSStringRef> pathDescription(Adopt, toAXElement(thisObject)->pathDescription());
+ return JSValueMakeString(context, pathDescription.get());
+}
+
static JSValueRef getSelectedTextRangeCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
{
JSRetainPtr<JSStringRef> selectedTextRange(Adopt, toAXElement(thisObject)->selectedTextRange());
AccessibilityUIElement AccessibilityUIElement::uiElementAttributeValue(JSStringRef) const { return 0; }
#endif
+#if !PLATFORM(MAC) && !PLATFORM(IOS)
+JSStringRef AccessibilityUIElement::pathDescription() const { return 0; }
+#endif
+
#if !PLATFORM(WIN)
bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
{
{ "intValue", getIntValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "minValue", getMinValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "maxValue", getMaxValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "pathDescription", getPathDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "childrenCount", getChildrenCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "rowCount", rowCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "columnCount", columnCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
double intValue() const;
double minValue();
double maxValue();
+ JSStringRef pathDescription() const;
JSStringRef valueDescription();
int insertionPointLineNumber();
JSStringRef selectedTextRange();
}
}
+static void _CGPathEnumerationIteration(void *info, const CGPathElement *element)
+{
+ NSMutableString *result = (NSMutableString *)info;
+ CGPoint* points = element->points;
+ switch (element->type) {
+ case kCGPathElementMoveToPoint:
+ [result appendString:@"\tMove to point\n"];
+ break;
+
+ case kCGPathElementAddLineToPoint:
+ [result appendString:@"\tLine to\n"];
+ break;
+
+ case kCGPathElementAddQuadCurveToPoint:
+ [result appendString:@"\tQuad curve to\n"];
+ break;
+
+ case kCGPathElementAddCurveToPoint:
+ [result appendString:@"\tCurve to\n"];
+ break;
+
+ case kCGPathElementCloseSubpath:
+ [result appendString:@"\tClose\n"];
+ break;
+ }
+}
+
+JSStringRef AccessibilityUIElement::pathDescription() const
+{
+ NSMutableString *result = [NSMutableString stringWithString:@"\nStart Path\n"];
+ CGPathRef pathRef = [m_element _accessibilityPath];
+
+ CGPathApply(pathRef, result, _CGPathEnumerationIteration);
+
+ return [result createJSStringRef];
+}
+
#pragma mark Unused
void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
#define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
#endif
+#ifndef NSAccessibilityPathAttribute
+#define NSAccessibilityPathAttribute @"AXPath"
+#endif
+
typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);
@interface NSObject (WebKitAccessibilityAdditions)
return 0;
}
+JSStringRef AccessibilityUIElement::pathDescription() const
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ NSMutableString *result = [NSMutableString stringWithString:@"\nStart Path\n"];
+ NSBezierPath *bezierPath = [m_element accessibilityAttributeValue:NSAccessibilityPathAttribute];
+
+ NSUInteger elementCount = [bezierPath elementCount];
+ for (NSUInteger i = 0; i < elementCount; i++) {
+ switch ([bezierPath elementAtIndex:i]) {
+ case NSMoveToBezierPathElement:
+ [result appendString:@"\tMove to point\n"];
+ break;
+
+ case NSLineToBezierPathElement:
+ [result appendString:@"\tLine to\n"];
+ break;
+
+ case NSCurveToBezierPathElement:
+ [result appendString:@"\tCurve to\n"];
+ break;
+
+ case NSClosePathBezierPathElement:
+ [result appendString:@"\tClose\n"];
+ break;
+ }
+ }
+
+ return [result createJSStringRef];
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
JSStringRef AccessibilityUIElement::selectedTextRange()
{
NSRange range = NSMakeRange(NSNotFound, 0);
PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int) { return 0; }
void AccessibilityUIElement::scrollToMakeVisible() { }
JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const { return 0; }
+JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const { return 0; }
+
#endif
} // namespace WTR
// Returns an ordered list of supported actions for an element.
JSRetainPtr<JSStringRef> supportedActions() const;
+ JSRetainPtr<JSStringRef> pathDescription() const;
+
// Notifications
// Function callback should take one argument, the name of the notification.
bool addNotificationListener(JSValueRef functionCallback);
// Returns an ordered list of supported actions for an element.
readonly attribute DOMString supportedActions;
+ readonly attribute DOMString pathDescription;
+
// Notification support.
boolean addNotificationListener(in object callbackFunction);
boolean removeNotificationListener();
#define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
#endif
+#ifndef NSAccessibilityPathAttribute
+#define NSAccessibilityPathAttribute @"AXPath"
+#endif
+
typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);
@interface NSObject (WebKitAccessibilityAdditions)
return 0;
}
+JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ NSMutableString *result = [NSMutableString stringWithString:@"\nStart Path\n"];
+ NSBezierPath *bezierPath = [m_element accessibilityAttributeValue:NSAccessibilityPathAttribute];
+
+ NSUInteger elementCount = [bezierPath elementCount];
+ NSPoint points[3];
+ for (NSUInteger i = 0; i < elementCount; i++) {
+ switch ([bezierPath elementAtIndex:i associatedPoints:points]) {
+ case NSMoveToBezierPathElement:
+ [result appendString:@"\tMove to point\n"];
+ break;
+
+ case NSLineToBezierPathElement:
+ [result appendString:@"\tLine to\n"];
+ break;
+
+ case NSCurveToBezierPathElement:
+ [result appendString:@"\tCurve to\n"];
+ break;
+
+ case NSClosePathBezierPathElement:
+ [result appendString:@"\tClose\n"];
+ break;
+ }
+ }
+
+ return [result createJSStringRef];
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
{
BEGIN_AX_OBJC_EXCEPTIONS