OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <execinfo.h> | 5 #include <execinfo.h> |
6 | 6 |
| 7 #import "chrome/browser/cocoa/browser_accessibility.h" |
| 8 |
7 #include "base/string16.h" | 9 #include "base/string16.h" |
8 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
9 #include "chrome/browser/cocoa/browser_accessibility.h" | |
10 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 11 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
11 #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" | 12 #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" |
12 | 13 |
13 using webkit_glue::WebAccessibility; | 14 using webkit_glue::WebAccessibility; |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 // Returns an autoreleased copy of the WebAccessibility's attribute. | 18 // Returns an autoreleased copy of the WebAccessibility's attribute. |
18 NSString* NSStringForWebAccessibilityAttribute( | 19 NSString* NSStringForWebAccessibilityAttribute( |
19 std::map<int32, string16>& attributes, | 20 const std::map<int32, string16>& attributes, |
20 WebAccessibility::Attribute attribute) { | 21 WebAccessibility::Attribute attribute) { |
21 std::map<int32, string16>::iterator iter = | 22 std::map<int32, string16>::const_iterator iter = |
22 attributes.find(attribute); | 23 attributes.find(attribute); |
23 NSString* returnValue = @""; | 24 NSString* returnValue = @""; |
24 if (iter != attributes.end()) { | 25 if (iter != attributes.end()) { |
25 returnValue = base::SysUTF16ToNSString(iter->second); | 26 returnValue = base::SysUTF16ToNSString(iter->second); |
26 } | 27 } |
27 return returnValue; | 28 return returnValue; |
28 } | 29 } |
29 | 30 |
30 struct RoleEntry { | 31 struct RoleEntry { |
31 WebAccessibility::Role value; | 32 WebAccessibility::Role value; |
(...skipping 15 matching lines...) Expand all Loading... |
47 { WebAccessibility::ROLE_RADIO_GROUP, NSAccessibilityRadioGroupRole}, | 48 { WebAccessibility::ROLE_RADIO_GROUP, NSAccessibilityRadioGroupRole}, |
48 { WebAccessibility::ROLE_TABLE, NSAccessibilityTableRole}, | 49 { WebAccessibility::ROLE_TABLE, NSAccessibilityTableRole}, |
49 { WebAccessibility::ROLE_TAB_GROUP, NSAccessibilityTabGroupRole}, | 50 { WebAccessibility::ROLE_TAB_GROUP, NSAccessibilityTabGroupRole}, |
50 { WebAccessibility::ROLE_IGNORED, NSAccessibilityUnknownRole}, | 51 { WebAccessibility::ROLE_IGNORED, NSAccessibilityUnknownRole}, |
51 { WebAccessibility::ROLE_WEB_AREA, @"AXWebArea"}, | 52 { WebAccessibility::ROLE_WEB_AREA, @"AXWebArea"}, |
52 { WebAccessibility::ROLE_GROUP, NSAccessibilityGroupRole}, | 53 { WebAccessibility::ROLE_GROUP, NSAccessibilityGroupRole}, |
53 { WebAccessibility::ROLE_GRID, NSAccessibilityGridRole}, | 54 { WebAccessibility::ROLE_GRID, NSAccessibilityGridRole}, |
54 { WebAccessibility::ROLE_WEBCORE_LINK, NSAccessibilityLinkRole}, | 55 { WebAccessibility::ROLE_WEBCORE_LINK, NSAccessibilityLinkRole}, |
55 }; | 56 }; |
56 | 57 |
| 58 // GetState checks the bitmask used in webaccessibility.h to check |
| 59 // if the given state was set on the accessibility object. |
57 bool GetState(WebAccessibility accessibility, int state) { | 60 bool GetState(WebAccessibility accessibility, int state) { |
58 return ((accessibility.state >> state) & 1); | 61 return ((accessibility.state >> state) & 1); |
59 } | 62 } |
60 | 63 |
61 } // anonymous namespace | 64 } // namespace |
62 | 65 |
63 @implementation BrowserAccessibility | 66 @implementation BrowserAccessibility |
64 | 67 |
65 - (id)initWithObject:(const WebAccessibility)accessibility | 68 - (id)initWithObject:(const WebAccessibility&)accessibility |
66 delegate:(id<BrowserAccessibilityDelegate>)delegate | 69 delegate:(id<BrowserAccessibilityDelegate>)delegate |
67 parent:(id)parent { | 70 parent:(id)parent { |
68 if ((self = [super init])) { | 71 if ((self = [super init])) { |
69 webAccessibility_ = accessibility; | 72 webAccessibility_ = accessibility; |
70 parent_ = parent; | 73 parent_ = parent; |
71 delegate_ = delegate; | 74 delegate_ = delegate; |
72 } | 75 } |
73 return self; | 76 return self; |
74 } | 77 } |
75 | 78 |
| 79 // Returns an array of BrowserAccessibility objects, representing the |
| 80 // accessibility children of this object. |
76 - (NSArray*)children { | 81 - (NSArray*)children { |
77 if (!children_.get()) { | 82 if (!children_.get()) { |
78 const std::vector<WebAccessibility>& accessibilityChildren = | 83 const std::vector<WebAccessibility>& accessibilityChildren = |
79 webAccessibility_.children; | 84 webAccessibility_.children; |
80 children_.reset( | 85 children_.reset( |
81 [[NSMutableArray alloc] | 86 [[NSMutableArray alloc] |
82 initWithCapacity:accessibilityChildren.size()]); | 87 initWithCapacity:accessibilityChildren.size()]); |
83 std::vector<WebAccessibility>::const_iterator iterator; | 88 std::vector<WebAccessibility>::const_iterator iterator; |
84 for (iterator = accessibilityChildren.begin(); | 89 for (iterator = accessibilityChildren.begin(); |
85 iterator != accessibilityChildren.end(); | 90 iterator != accessibilityChildren.end(); |
86 iterator++) { | 91 ++iterator) { |
87 BrowserAccessibility* child = | 92 scoped_nsobject<BrowserAccessibility> child( |
88 [[BrowserAccessibility alloc] | 93 [[BrowserAccessibility alloc] |
89 initWithObject:*iterator | 94 initWithObject:*iterator |
90 delegate:delegate_ | 95 delegate:delegate_ |
91 parent:self]; | 96 parent:self]); |
92 [child autorelease]; | |
93 [children_ addObject:child]; | 97 [children_ addObject:child]; |
94 } | 98 } |
95 } | 99 } |
96 return children_; | 100 return children_; |
97 } | 101 } |
98 | 102 |
| 103 // Returns whether or not this node should be ignored in the |
| 104 // accessibility tree. |
99 - (BOOL)isIgnored { | 105 - (BOOL)isIgnored { |
100 return webAccessibility_.role == WebAccessibility::ROLE_IGNORED; | 106 return webAccessibility_.role == WebAccessibility::ROLE_IGNORED; |
101 } | 107 } |
102 | 108 |
| 109 // The origin of this accessibility object in the page's document. |
| 110 // This is relative to webkit's top-left origin, not Cocoa's |
| 111 // bottom-left origin. |
103 - (NSPoint)origin { | 112 - (NSPoint)origin { |
104 return NSMakePoint(webAccessibility_.location.x, | 113 return NSMakePoint(webAccessibility_.location.x, |
105 webAccessibility_.location.y); | 114 webAccessibility_.location.y); |
106 } | 115 } |
107 | 116 |
| 117 // Returns a string indicating the role of this object. |
108 - (NSString*)role { | 118 - (NSString*)role { |
109 NSString* role = NSAccessibilityUnknownRole; | 119 NSString* role = NSAccessibilityUnknownRole; |
110 WebAccessibility::Role value = webAccessibility_.role; | 120 WebAccessibility::Role value = webAccessibility_.role; |
111 const size_t numRoles = sizeof(roles) / sizeof(roles[0]); | 121 const size_t numRoles = sizeof(roles) / sizeof(roles[0]); |
112 for (size_t i = 0; i < numRoles; ++i) { | 122 for (size_t i = 0; i < numRoles; ++i) { |
113 if (roles[i].value == value) { | 123 if (roles[i].value == value) { |
114 role = roles[i].string; | 124 role = roles[i].string; |
115 break; | 125 break; |
116 } | 126 } |
117 } | 127 } |
118 return role; | 128 return role; |
119 } | 129 } |
120 | 130 |
| 131 // Returns the size of this object. |
121 - (NSSize)size { | 132 - (NSSize)size { |
122 return NSMakeSize(webAccessibility_.location.width, | 133 return NSMakeSize(webAccessibility_.location.width, |
123 webAccessibility_.location.height); | 134 webAccessibility_.location.height); |
124 } | 135 } |
125 | 136 |
126 - (id)accessibilityAttributeValue:(NSString *)attribute { | 137 // Returns the accessibility value for the given attribute. If the value isn't |
| 138 // supported this will return nil. |
| 139 - (id)accessibilityAttributeValue:(NSString*)attribute { |
127 if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { | 140 if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { |
128 return [self role]; | 141 return [self role]; |
129 } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { | 142 } |
| 143 if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { |
130 return NSStringForWebAccessibilityAttribute(webAccessibility_.attributes, | 144 return NSStringForWebAccessibilityAttribute(webAccessibility_.attributes, |
131 WebAccessibility::ATTR_DESCRIPTION); | 145 WebAccessibility::ATTR_DESCRIPTION); |
132 } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { | 146 } |
| 147 if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { |
133 return [NSValue valueWithPoint:[delegate_ accessibilityPointInScreen:self]]; | 148 return [NSValue valueWithPoint:[delegate_ accessibilityPointInScreen:self]]; |
134 } else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { | 149 } |
| 150 if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { |
135 return [NSValue valueWithSize:[self size]]; | 151 return [NSValue valueWithSize:[self size]]; |
136 } else if ( | 152 } |
137 [attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute] || | 153 if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute] || |
138 [attribute isEqualToString:NSAccessibilityWindowAttribute]) { | 154 [attribute isEqualToString:NSAccessibilityWindowAttribute]) { |
139 return [delegate_ window]; | 155 return [delegate_ window]; |
140 } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { | 156 } |
| 157 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { |
141 return [self children]; | 158 return [self children]; |
142 } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { | 159 } |
| 160 if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { |
143 if (parent_) { | 161 if (parent_) { |
144 return NSAccessibilityUnignoredAncestor(parent_); | 162 return NSAccessibilityUnignoredAncestor(parent_); |
145 } | 163 } |
146 } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) { | 164 } |
| 165 if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) { |
147 return base::SysUTF16ToNSString(webAccessibility_.name); | 166 return base::SysUTF16ToNSString(webAccessibility_.name); |
148 } else if ([attribute isEqualToString:NSAccessibilityHelpAttribute]) { | 167 } |
| 168 if ([attribute isEqualToString:NSAccessibilityHelpAttribute]) { |
149 return NSStringForWebAccessibilityAttribute(webAccessibility_.attributes, | 169 return NSStringForWebAccessibilityAttribute(webAccessibility_.attributes, |
150 WebAccessibility::ATTR_HELP); | 170 WebAccessibility::ATTR_HELP); |
151 } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { | 171 } |
| 172 if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { |
152 return base::SysUTF16ToNSString(webAccessibility_.value); | 173 return base::SysUTF16ToNSString(webAccessibility_.value); |
153 } else if ( | 174 } |
154 [attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { | 175 if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { |
155 return NSAccessibilityRoleDescription([self role], nil); | 176 return NSAccessibilityRoleDescription([self role], nil); |
156 } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { | 177 } |
| 178 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { |
157 NSNumber* ret = [NSNumber numberWithBool: | 179 NSNumber* ret = [NSNumber numberWithBool: |
158 GetState(webAccessibility_, WebAccessibility::STATE_FOCUSED)]; | 180 GetState(webAccessibility_, WebAccessibility::STATE_FOCUSED)]; |
159 return ret; | 181 return ret; |
160 } else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute] || | 182 } |
| 183 if ([attribute isEqualToString:NSAccessibilityEnabledAttribute] || |
161 [attribute isEqualToString:@"AXVisited"] || | 184 [attribute isEqualToString:@"AXVisited"] || |
162 [attribute isEqualToString:@"AXLoaded"]) { | 185 [attribute isEqualToString:@"AXLoaded"]) { |
163 return [NSNumber numberWithBool:YES]; | 186 return [NSNumber numberWithBool:YES]; |
164 } | 187 } |
165 return nil; | 188 return nil; |
166 } | 189 } |
167 | 190 |
168 - (NSArray *)accessibilityActionNames { | 191 // Returns an array of action names that this object will respond to. |
| 192 - (NSArray*)accessibilityActionNames { |
169 return [NSArray arrayWithObjects: | 193 return [NSArray arrayWithObjects: |
170 NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil]; | 194 NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil]; |
171 } | 195 } |
172 | 196 |
173 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute | 197 // Returns a sub-array of values for the given attribute value, starting at |
174 index:(NSUInteger)index | 198 // index, with up to maxCount items. If the given index is out of bounds, |
175 maxCount:(NSUInteger)maxCount { | 199 // or there are no values for the given attribute, it will return nil. |
| 200 // This method is used for querying subsets of values, without having to |
| 201 // return a large set of data, such as elements with a large number of |
| 202 // children. |
| 203 - (NSArray*)accessibilityArrayAttributeValues:(NSString*)attribute |
| 204 index:(NSUInteger)index |
| 205 maxCount:(NSUInteger)maxCount { |
176 NSArray* fullArray = [self accessibilityAttributeValue:attribute]; | 206 NSArray* fullArray = [self accessibilityAttributeValue:attribute]; |
177 if (!fullArray) | 207 if (!fullArray) |
178 return nil; | 208 return nil; |
179 NSUInteger arrayCount = [fullArray count]; | 209 NSUInteger arrayCount = [fullArray count]; |
180 if (index >= arrayCount) | 210 if (index >= arrayCount) |
181 return nil; | 211 return nil; |
182 NSRange subRange; | 212 NSRange subRange; |
183 if ((index + maxCount) > arrayCount) { | 213 if ((index + maxCount) > arrayCount) { |
184 subRange = NSMakeRange(index, arrayCount - index); | 214 subRange = NSMakeRange(index, arrayCount - index); |
185 } else { | 215 } else { |
186 subRange = NSMakeRange(index, maxCount); | 216 subRange = NSMakeRange(index, maxCount); |
187 } | 217 } |
188 return [fullArray subarrayWithRange:subRange]; | 218 return [fullArray subarrayWithRange:subRange]; |
189 } | 219 } |
190 | 220 |
191 - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute { | 221 // Returns the count of the specified accessibility array attribute. |
| 222 - (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute { |
192 NSArray* fullArray = [self accessibilityAttributeValue:attribute]; | 223 NSArray* fullArray = [self accessibilityAttributeValue:attribute]; |
193 return [fullArray count]; | 224 return [fullArray count]; |
194 } | 225 } |
195 | 226 |
196 - (NSArray *)accessibilityAttributeNames { | 227 // Returns the list of accessibility attributes that this object supports. |
| 228 - (NSArray*)accessibilityAttributeNames { |
197 return [NSArray arrayWithObjects: | 229 return [NSArray arrayWithObjects: |
198 NSAccessibilityRoleAttribute, | |
199 NSAccessibilityRoleDescriptionAttribute, | |
200 NSAccessibilityChildrenAttribute, | 230 NSAccessibilityChildrenAttribute, |
| 231 NSAccessibilityDescriptionAttribute, |
| 232 NSAccessibilityEnabledAttribute, |
| 233 NSAccessibilityFocusedAttribute, |
201 NSAccessibilityHelpAttribute, | 234 NSAccessibilityHelpAttribute, |
202 NSAccessibilityParentAttribute, | 235 NSAccessibilityParentAttribute, |
203 NSAccessibilityPositionAttribute, | 236 NSAccessibilityPositionAttribute, |
| 237 NSAccessibilityRoleAttribute, |
| 238 NSAccessibilityRoleDescriptionAttribute, |
204 NSAccessibilitySizeAttribute, | 239 NSAccessibilitySizeAttribute, |
205 NSAccessibilityTitleAttribute, | 240 NSAccessibilityTitleAttribute, |
206 NSAccessibilityDescriptionAttribute, | 241 NSAccessibilityTopLevelUIElementAttribute, |
207 NSAccessibilityValueAttribute, | 242 NSAccessibilityValueAttribute, |
208 NSAccessibilityFocusedAttribute, | |
209 NSAccessibilityEnabledAttribute, | |
210 NSAccessibilityWindowAttribute, | 243 NSAccessibilityWindowAttribute, |
211 NSAccessibilityTopLevelUIElementAttribute, | |
212 nil]; | 244 nil]; |
213 } | 245 } |
214 | 246 |
| 247 // Returns the deepest child that has user focus. |
| 248 // TODO(feldstein): This does not work yet. |
215 - (id)accessibilityFocusedUIElement { | 249 - (id)accessibilityFocusedUIElement { |
216 return self; | 250 return self; |
217 } | 251 } |
218 | 252 |
| 253 // Returns the index of the child in this objects array of children. |
219 - (NSUInteger)accessibilityIndexOfChild:(id)child { | 254 - (NSUInteger)accessibilityIndexOfChild:(id)child { |
220 NSUInteger index = 0; | 255 NSUInteger index = 0; |
221 for (BrowserAccessibility* childToCheck in [self children]) { | 256 for (BrowserAccessibility* childToCheck in [self children]) { |
222 if ([child isEqual:childToCheck]) | 257 if ([child isEqual:childToCheck]) |
223 return index; | 258 return index; |
224 if (![childToCheck isIgnored]) | 259 if (![childToCheck isIgnored]) |
225 ++index; | 260 ++index; |
226 } | 261 } |
227 return NSNotFound; | 262 return NSNotFound; |
228 } | 263 } |
229 | 264 |
230 - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { | 265 // Returns whether or not the specified attribute can be set by the |
231 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { | 266 // accessibility API via |accessibilitySetValue:forAttribute:|. |
| 267 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute { |
| 268 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) |
232 return GetState(webAccessibility_, WebAccessibility::STATE_FOCUSABLE); | 269 return GetState(webAccessibility_, WebAccessibility::STATE_FOCUSABLE); |
233 } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { | 270 if ([attribute isEqualToString:NSAccessibilityValueAttribute]) |
234 return !GetState(webAccessibility_, WebAccessibility::STATE_READONLY); | 271 return !GetState(webAccessibility_, WebAccessibility::STATE_READONLY); |
235 } | |
236 return NO; | 272 return NO; |
237 } | 273 } |
238 | 274 |
| 275 // Returns whether or not this object should be ignored in the accessibilty |
| 276 // tree. |
239 - (BOOL)accessibilityIsIgnored { | 277 - (BOOL)accessibilityIsIgnored { |
240 return [self isIgnored]; | 278 return [self isIgnored]; |
241 } | 279 } |
242 | 280 |
243 - (void)accessibilityPerformAction:(NSString *)action { | 281 // Performs the given accessibilty action on the webkit accessibility object |
| 282 // that backs this object. |
| 283 - (void)accessibilityPerformAction:(NSString*)action { |
244 // TODO(feldstein): Support more actions. | 284 // TODO(feldstein): Support more actions. |
245 [delegate_ doDefaultAction:webAccessibility_.id]; | 285 [delegate_ doDefaultAction:webAccessibility_.id]; |
246 } | 286 } |
247 | 287 |
| 288 // Returns the description of the given action. |
248 - (NSString*)accessibilityActionDescription:(NSString*)action { | 289 - (NSString*)accessibilityActionDescription:(NSString*)action { |
249 return NSAccessibilityActionDescription(action); | 290 return NSAccessibilityActionDescription(action); |
250 } | 291 } |
251 | 292 |
| 293 // Sets an override value for a specific accessibility attribute. |
| 294 // This class does not support this. |
252 - (BOOL)accessibilitySetOverrideValue:(id)value | 295 - (BOOL)accessibilitySetOverrideValue:(id)value |
253 forAttribute:(NSString *)attribute { | 296 forAttribute:(NSString*)attribute { |
254 return NO; | 297 return NO; |
255 } | 298 } |
256 | 299 |
257 - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { | 300 // Sets the value for an accessibility attribute via the accessibility API. |
| 301 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute { |
258 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { | 302 if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { |
259 NSNumber* focusedNumber = value; | 303 NSNumber* focusedNumber = value; |
260 BOOL focused = [focusedNumber intValue]; | 304 BOOL focused = [focusedNumber intValue]; |
261 [delegate_ setAccessibilityFocus:focused | 305 [delegate_ setAccessibilityFocus:focused |
262 accessibilityId:webAccessibility_.id]; | 306 accessibilityId:webAccessibility_.id]; |
263 } | 307 } |
264 } | 308 } |
265 | 309 |
| 310 // Returns the deepest accessibility child that should not be ignored. |
| 311 // It is assumed that the hit test has been narrowed down to this object |
| 312 // or one of its children, so this will never return nil. |
266 - (id)accessibilityHitTest:(NSPoint)point { | 313 - (id)accessibilityHitTest:(NSPoint)point { |
267 id hit = self; | 314 id hit = self; |
268 for (id child in [self children]) { | 315 for (id child in [self children]) { |
269 NSPoint origin = [child origin]; | 316 NSPoint origin = [child origin]; |
270 NSSize size = [child size]; | 317 NSSize size = [child size]; |
271 NSRect rect; | 318 NSRect rect; |
272 rect.origin = origin; | 319 rect.origin = origin; |
273 rect.size = size; | 320 rect.size = size; |
274 if (NSPointInRect(point, rect)) { | 321 if (NSPointInRect(point, rect)) { |
275 hit = child; | 322 hit = child; |
(...skipping 12 matching lines...) Expand all Loading... |
288 return NO; | 335 return NO; |
289 return ([self hash] == [object hash]); | 336 return ([self hash] == [object hash]); |
290 } | 337 } |
291 | 338 |
292 - (NSUInteger)hash { | 339 - (NSUInteger)hash { |
293 return webAccessibility_.id; | 340 return webAccessibility_.id; |
294 } | 341 } |
295 | 342 |
296 @end | 343 @end |
297 | 344 |
OLD | NEW |