• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#import "config.h"
27#import "AccessibilityWebPageObject.h"
28
29#import "WebFrame.h"
30#import "WebPage.h"
31#import <WebCore/AXObjectCache.h>
32#import <WebCore/Frame.h>
33#import <WebCore/FrameView.h>
34#import <WebCore/ScrollView.h>
35#import <WebCore/Scrollbar.h>
36#import <WebKitSystemInterface.h>
37
38using namespace WebCore;
39using namespace WebKit;
40
41@implementation AccessibilityWebPageObject
42
43- (id)accessibilityRootObjectWrapper
44{
45    WebCore::Page* page = m_page->corePage();
46    if (!page)
47        return nil;
48
49    WebCore::Frame* core = page->mainFrame();
50    if (!core || !core->document())
51        return nil;
52
53    AccessibilityObject* root = core->document()->axObjectCache()->rootObject();
54    if (!root)
55        return nil;
56
57    return root->wrapper();
58}
59
60- (void)setWebPage:(WebPage*)page
61{
62    m_page = page;
63}
64
65- (void)setRemoteParent:(id)parent
66{
67    if (parent != m_parent) {
68        [m_parent release];
69        m_parent = [parent retain];
70    }
71}
72
73- (void)dealloc
74{
75    WKUnregisterUniqueIdForElement(self);
76    [m_accessibilityChildren release];
77    [m_attributeNames release];
78    [m_parent release];
79    [super dealloc];
80}
81
82- (BOOL)accessibilityIsIgnored
83{
84    return NO;
85}
86
87- (NSArray *)accessibilityAttributeNames
88{
89    if (!m_attributeNames)
90        m_attributeNames = [[NSArray alloc] initWithObjects:
91                           NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityFocusedAttribute,
92                           NSAccessibilityParentAttribute, NSAccessibilityWindowAttribute, NSAccessibilityTopLevelUIElementAttribute,
93                           NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, NSAccessibilityChildrenAttribute, nil];
94
95    return m_attributeNames;
96}
97
98- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute
99{
100    return NO;
101}
102
103- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
104{
105    return;
106}
107
108- (NSArray *)accessibilityActionNames
109{
110    return [NSArray array];
111}
112
113- (NSArray *)accessibilityChildren
114{
115    id wrapper = [self accessibilityRootObjectWrapper];
116    if (!wrapper)
117        return [NSArray array];
118
119    return [NSArray arrayWithObject:wrapper];
120}
121
122- (id)accessibilityAttributeValue:(NSString *)attribute
123{
124    if (!WebCore::AXObjectCache::accessibilityEnabled())
125        WebCore::AXObjectCache::enableAccessibility();
126
127    if ([attribute isEqualToString:NSAccessibilityParentAttribute])
128        return m_parent;
129    if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
130        return [m_parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
131    if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
132        return [m_parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
133    if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
134        return NSAccessibilityGroupRole;
135    if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
136        return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, nil);
137    if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
138        return [NSNumber numberWithBool:NO];
139
140    if (!m_page)
141        return nil;
142
143    if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
144        WebCore::IntPoint point = m_page->accessibilityPosition();
145        return [NSValue valueWithPoint:NSMakePoint(point.x(), point.y())];
146    }
147    if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
148        const IntSize& s = m_page->size();
149        return [NSValue valueWithSize:NSMakeSize(s.width(), s.height())];
150    }
151    if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
152        return [self accessibilityChildren];
153
154    return [super accessibilityAttributeValue:attribute];
155}
156
157- (BOOL)accessibilityShouldUseUniqueId
158{
159    return YES;
160}
161
162- (id)accessibilityHitTest:(NSPoint)point
163{
164    // Hit-test point comes in as bottom-screen coordinates. Needs to be normalized to the frame of the web page.
165    NSPoint remotePosition = [[self accessibilityAttributeValue:NSAccessibilityPositionAttribute] pointValue];
166    NSSize remoteSize = [[self accessibilityAttributeValue:NSAccessibilitySizeAttribute] sizeValue];
167
168    // Get the y position of the WKView (we have to screen-flip and go from bottom left to top left).
169    CGFloat screenHeight = [[[NSScreen screens] objectAtIndex:0] frame].size.height;
170    remotePosition.y = (screenHeight - remotePosition.y) - remoteSize.height;
171
172    point.y = screenHeight - point.y;
173
174    // Re-center point into the web page's frame.
175    point.y -= remotePosition.y;
176    point.x -= remotePosition.x;
177
178    if (m_page && m_page->mainFrame() && m_page->mainFrame()->coreFrame()) {
179        WebCore::FrameView* fv = m_page->mainFrame()->coreFrame()->view();
180        if (fv) {
181            point.y += fv->scrollPosition().y();
182            point.x += fv->scrollPosition().x();
183        }
184    }
185
186    return [[self accessibilityRootObjectWrapper] accessibilityHitTest:point];
187}
188
189- (id)accessibilityFocusedUIElement
190{
191    return [[self accessibilityRootObjectWrapper] accessibilityFocusedUIElement];
192}
193
194
195@end
196