OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2014, Google Inc. All rights reserved. | 2 * Copyright (C) 2014, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 170 |
171 // the HTML element, for example, is focusable but has an AX object that is
ignored | 171 // the HTML element, for example, is focusable but has an AX object that is
ignored |
172 if (obj->accessibilityIsIgnored()) | 172 if (obj->accessibilityIsIgnored()) |
173 obj = obj->parentObjectUnignored(); | 173 obj = obj->parentObjectUnignored(); |
174 | 174 |
175 return obj; | 175 return obj; |
176 } | 176 } |
177 | 177 |
178 AXObject* AXObjectCacheImpl::get(Widget* widget) | 178 AXObject* AXObjectCacheImpl::get(Widget* widget) |
179 { | 179 { |
| 180 fprintf(stderr, "AXObjectCacheImpl.get(widget)\n"); |
180 if (!widget) | 181 if (!widget) |
181 return 0; | 182 return 0; |
182 | 183 |
| 184 fprintf(stderr, "about to call m_widgetObjectMapping(%p)\n", widget); |
183 AXID axID = m_widgetObjectMapping.get(widget); | 185 AXID axID = m_widgetObjectMapping.get(widget); |
184 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 186 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
185 if (!axID) | 187 if (!axID) |
186 return 0; | 188 return 0; |
187 | 189 |
| 190 fprintf(stderr, "about to call m_objects.get(%d)\n", axID); |
188 return m_objects.get(axID); | 191 return m_objects.get(axID); |
189 } | 192 } |
190 | 193 |
191 AXObject* AXObjectCacheImpl::get(RenderObject* renderer) | 194 AXObject* AXObjectCacheImpl::get(RenderObject* renderer) |
192 { | 195 { |
| 196 fprintf(stderr, "AXObjectCacheImpl::get(renderer)\n"); |
193 if (!renderer) | 197 if (!renderer) |
194 return 0; | 198 return 0; |
195 | 199 |
| 200 fprintf(stderr, "about to call m_renderObjectMapping.get(%p)\n", renderer); |
196 AXID axID = m_renderObjectMapping.get(renderer); | 201 AXID axID = m_renderObjectMapping.get(renderer); |
197 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 202 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
198 if (!axID) | 203 if (!axID) |
199 return 0; | 204 return 0; |
200 | 205 |
| 206 fprintf(stderr, "about to call m_objects.get(%d)\n", axID); |
201 return m_objects.get(axID); | 207 return m_objects.get(axID); |
202 } | 208 } |
203 | 209 |
204 AXObject* AXObjectCacheImpl::get(Node* node) | 210 AXObject* AXObjectCacheImpl::get(Node* node) |
205 { | 211 { |
| 212 fprintf(stderr, "AXObjectCacheImpl.get(node)\n"); |
206 if (!node) | 213 if (!node) |
207 return 0; | 214 return 0; |
208 | 215 |
| 216 fprintf(stderr, "about to call m_renderObjectMapping(%p)\n", node->renderer(
)); |
209 AXID renderID = node->renderer() ? m_renderObjectMapping.get(node->renderer(
)) : 0; | 217 AXID renderID = node->renderer() ? m_renderObjectMapping.get(node->renderer(
)) : 0; |
| 218 fprintf(stderr, "got renderID: %d\n", renderID); |
210 ASSERT(!HashTraits<AXID>::isDeletedValue(renderID)); | 219 ASSERT(!HashTraits<AXID>::isDeletedValue(renderID)); |
211 | 220 |
| 221 fprintf(stderr, "about to call m_nodeObjectMapping(%p)\n", node); |
212 AXID nodeID = m_nodeObjectMapping.get(node); | 222 AXID nodeID = m_nodeObjectMapping.get(node); |
| 223 fprintf(stderr, "got nodeID %d\n", nodeID); |
213 ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID)); | 224 ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID)); |
| 225 fprintf(stderr, "Assert passed\n"); |
214 | 226 |
215 if (node->renderer() && nodeID && !renderID) { | 227 if (node->renderer() && nodeID && !renderID) { |
| 228 fprintf(stderr, "about to call remove(%d)\n", nodeID); |
216 // This can happen if an AXNodeObject is created for a node that's not | 229 // This can happen if an AXNodeObject is created for a node that's not |
217 // rendered, but later something changes and it gets a renderer (like if
it's | 230 // rendered, but later something changes and it gets a renderer (like if
it's |
218 // reparented). | 231 // reparented). |
219 remove(nodeID); | 232 remove(nodeID); |
220 return 0; | 233 return 0; |
| 234 } else { |
| 235 fprintf(stderr, "not removing nodeID\n"); |
221 } | 236 } |
222 | 237 |
223 if (renderID) | 238 if (renderID) { |
| 239 fprintf(stderr, "about to call m_objects.get(%d)\n", renderID); |
224 return m_objects.get(renderID); | 240 return m_objects.get(renderID); |
| 241 } |
| 242 fprintf(stderr, "%d was false\n", renderID); |
225 | 243 |
226 if (!nodeID) | 244 if (!nodeID) { |
| 245 fprintf(stderr, "returning 0\n"); |
227 return 0; | 246 return 0; |
| 247 } |
| 248 fprintf(stderr, "!%d was false\n", nodeID); |
228 | 249 |
| 250 fprintf(stderr, "about to call m_objects.get(%d)\n", nodeID); |
229 return m_objects.get(nodeID); | 251 return m_objects.get(nodeID); |
230 } | 252 } |
231 | 253 |
232 AXObject* AXObjectCacheImpl::get(AbstractInlineTextBox* inlineTextBox) | 254 AXObject* AXObjectCacheImpl::get(AbstractInlineTextBox* inlineTextBox) |
233 { | 255 { |
| 256 fprintf(stderr, "get(AbstractInlineTextBox)\n"); |
234 if (!inlineTextBox) | 257 if (!inlineTextBox) |
235 return 0; | 258 return 0; |
236 | 259 |
237 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); | 260 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); |
238 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 261 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
239 if (!axID) | 262 if (!axID) |
240 return 0; | 263 return 0; |
241 | 264 |
242 return m_objects.get(axID); | 265 return m_objects.get(axID); |
243 } | 266 } |
244 | 267 |
245 // FIXME: This probably belongs on Node. | 268 // FIXME: This probably belongs on Node. |
246 // FIXME: This should take a const char*, but one caller passes nullAtom. | 269 // FIXME: This should take a const char*, but one caller passes nullAtom. |
247 bool nodeHasRole(Node* node, const String& role) | 270 bool nodeHasRole(Node* node, const String& role) |
248 { | 271 { |
249 if (!node || !node->isElementNode()) | 272 if (!node || !node->isElementNode()) |
250 return false; | 273 return false; |
251 | 274 |
252 return equalIgnoringCase(toElement(node)->getAttribute(roleAttr), role); | 275 return equalIgnoringCase(toElement(node)->getAttribute(roleAttr), role); |
253 } | 276 } |
254 | 277 |
255 static PassRefPtr<AXObject> createFromRenderer(RenderObject* renderer) | 278 PassRefPtr<AXObject> AXObjectCacheImpl::createFromRenderer(RenderObject* rendere
r) |
256 { | 279 { |
257 // FIXME: How could renderer->node() ever not be an Element? | 280 // FIXME: How could renderer->node() ever not be an Element? |
258 Node* node = renderer->node(); | 281 Node* node = renderer->node(); |
259 | 282 |
260 // If the node is aria role="list" or the aria role is empty and its a | 283 // If the node is aria role="list" or the aria role is empty and its a |
261 // ul/ol/dl type (it shouldn't be a list if aria says otherwise). | 284 // ul/ol/dl type (it shouldn't be a list if aria says otherwise). |
262 if (node && ((nodeHasRole(node, "list") || nodeHasRole(node, "directory")) | 285 if (node && ((nodeHasRole(node, "list") || nodeHasRole(node, "directory")) |
263 || (nodeHasRole(node, nullAtom) && (isHTMLUListElement(*node) || isHTMLO
ListElement(*node) || isHTMLDListElement(*node))))) | 286 || (nodeHasRole(node, nullAtom) && (isHTMLUListElement(*node) || isHTMLO
ListElement(*node) || isHTMLDListElement(*node))))) |
264 return AXList::create(renderer); | 287 return AXList::create(renderer, this); |
265 | 288 |
266 // aria tables | 289 // aria tables |
267 if (nodeHasRole(node, "grid") || nodeHasRole(node, "treegrid")) | 290 if (nodeHasRole(node, "grid") || nodeHasRole(node, "treegrid")) |
268 return AXARIAGrid::create(renderer); | 291 return AXARIAGrid::create(renderer, this); |
269 if (nodeHasRole(node, "row")) | 292 if (nodeHasRole(node, "row")) |
270 return AXARIAGridRow::create(renderer); | 293 return AXARIAGridRow::create(renderer, this); |
271 if (nodeHasRole(node, "gridcell") || nodeHasRole(node, "columnheader") || no
deHasRole(node, "rowheader")) | 294 if (nodeHasRole(node, "gridcell") || nodeHasRole(node, "columnheader") || no
deHasRole(node, "rowheader")) |
272 return AXARIAGridCell::create(renderer); | 295 return AXARIAGridCell::create(renderer, this); |
273 | 296 |
274 // media controls | 297 // media controls |
275 if (node && node->isMediaControlElement()) | 298 if (node && node->isMediaControlElement()) |
276 return AccessibilityMediaControl::create(renderer); | 299 return AccessibilityMediaControl::create(renderer, this); |
277 | 300 |
278 if (isHTMLOptionElement(node)) | 301 if (isHTMLOptionElement(node)) |
279 return AXListBoxOption::create(renderer); | 302 return AXListBoxOption::create(renderer, this); |
280 | 303 |
281 if (renderer->isSVGRoot()) | 304 if (renderer->isSVGRoot()) |
282 return AXSVGRoot::create(renderer); | 305 return AXSVGRoot::create(renderer, this); |
283 | 306 |
284 if (renderer->isBoxModelObject()) { | 307 if (renderer->isBoxModelObject()) { |
285 RenderBoxModelObject* cssBox = toRenderBoxModelObject(renderer); | 308 RenderBoxModelObject* cssBox = toRenderBoxModelObject(renderer); |
286 if (cssBox->isListBox()) | 309 if (cssBox->isListBox()) |
287 return AXListBox::create(toRenderListBox(cssBox)); | 310 return AXListBox::create(toRenderListBox(cssBox), this); |
288 if (cssBox->isMenuList()) | 311 if (cssBox->isMenuList()) |
289 return AXMenuList::create(toRenderMenuList(cssBox)); | 312 return AXMenuList::create(toRenderMenuList(cssBox), this); |
290 | 313 |
291 // standard tables | 314 // standard tables |
292 if (cssBox->isTable()) | 315 if (cssBox->isTable()) |
293 return AXTable::create(toRenderTable(cssBox)); | 316 return AXTable::create(toRenderTable(cssBox), this); |
294 if (cssBox->isTableRow()) | 317 if (cssBox->isTableRow()) |
295 return AXTableRow::create(toRenderTableRow(cssBox)); | 318 return AXTableRow::create(toRenderTableRow(cssBox), this); |
296 if (cssBox->isTableCell()) | 319 if (cssBox->isTableCell()) |
297 return AXTableCell::create(toRenderTableCell(cssBox)); | 320 return AXTableCell::create(toRenderTableCell(cssBox), this); |
298 | 321 |
299 // progress bar | 322 // progress bar |
300 if (cssBox->isProgress()) | 323 if (cssBox->isProgress()) |
301 return AXProgressIndicator::create(toRenderProgress(cssBox)); | 324 return AXProgressIndicator::create(toRenderProgress(cssBox), this); |
302 | 325 |
303 // input type=range | 326 // input type=range |
304 if (cssBox->isSlider()) | 327 if (cssBox->isSlider()) |
305 return AXSlider::create(toRenderSlider(cssBox)); | 328 return AXSlider::create(toRenderSlider(cssBox), this); |
306 } | 329 } |
307 | 330 |
308 return AXRenderObject::create(renderer); | 331 return AXRenderObject::create(renderer, this); |
309 } | 332 } |
310 | 333 |
311 static PassRefPtr<AXObject> createFromNode(Node* node) | 334 PassRefPtr<AXObject> AXObjectCacheImpl::createFromNode(Node* node) |
312 { | 335 { |
313 return AXNodeObject::create(node); | 336 return AXNodeObject::create(node, this); |
314 } | 337 } |
315 | 338 |
316 static PassRefPtr<AXObject> createFromInlineTextBox(AbstractInlineTextBox* inlin
eTextBox) | 339 PassRefPtr<AXObject> AXObjectCacheImpl::createFromInlineTextBox(AbstractInlineTe
xtBox* inlineTextBox) |
317 { | 340 { |
318 return AXInlineTextBox::create(inlineTextBox); | 341 return AXInlineTextBox::create(inlineTextBox, this); |
319 } | 342 } |
320 | 343 |
321 AXObject* AXObjectCacheImpl::getOrCreate(Widget* widget) | 344 AXObject* AXObjectCacheImpl::getOrCreate(Widget* widget) |
322 { | 345 { |
323 if (!widget) | 346 if (!widget) |
324 return 0; | 347 return 0; |
325 | 348 |
326 if (AXObject* obj = get(widget)) | 349 if (AXObject* obj = get(widget)) |
327 return obj; | 350 return obj; |
328 | 351 |
329 RefPtr<AXObject> newObj = nullptr; | 352 RefPtr<AXObject> newObj = nullptr; |
330 if (widget->isFrameView()) | 353 if (widget->isFrameView()) |
331 newObj = AXScrollView::create(toFrameView(widget)); | 354 newObj = AXScrollView::create(toFrameView(widget), this); |
332 else if (widget->isScrollbar()) | 355 else if (widget->isScrollbar()) |
333 newObj = AXScrollbar::create(toScrollbar(widget)); | 356 newObj = AXScrollbar::create(toScrollbar(widget), this); |
334 | 357 |
335 // Will crash later if we have two objects for the same widget. | 358 // Will crash later if we have two objects for the same widget. |
336 ASSERT(!get(widget)); | 359 ASSERT(!get(widget)); |
337 | 360 |
338 // Catch the case if an (unsupported) widget type is used. Only FrameView an
d ScrollBar are supported now. | 361 // Catch the case if an (unsupported) widget type is used. Only FrameView an
d ScrollBar are supported now. |
339 ASSERT(newObj); | 362 ASSERT(newObj); |
340 if (!newObj) | 363 if (!newObj) |
341 return 0; | 364 return 0; |
342 | 365 |
343 getAXID(newObj.get()); | 366 getAXID(newObj.get()); |
344 | 367 |
345 m_widgetObjectMapping.set(widget, newObj->axObjectID()); | 368 m_widgetObjectMapping.set(widget, newObj->axObjectID()); |
346 m_objects.set(newObj->axObjectID(), newObj); | 369 m_objects.set(newObj->axObjectID(), newObj); |
347 newObj->init(); | 370 newObj->init(); |
348 return newObj.get(); | 371 return newObj.get(); |
349 } | 372 } |
350 | 373 |
351 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) | 374 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) |
352 { | 375 { |
353 if (!node) | 376 if (!node) |
354 return 0; | 377 return 0; |
355 | 378 |
356 if (AXObject* obj = get(node)) | 379 if (AXObject* obj = get(node)) |
357 return obj; | 380 return obj; |
358 | 381 |
359 if (node->renderer()) | 382 fprintf(stderr, "get(node) returned nil\n"); |
| 383 |
| 384 if (node->renderer()) { |
| 385 fprintf(stderr, "calling getOrCreate(Renderer)\n"); |
360 return getOrCreate(node->renderer()); | 386 return getOrCreate(node->renderer()); |
| 387 } |
| 388 fprintf(stderr, "renderer was null\n"); |
361 | 389 |
362 if (!node->parentElement()) | 390 if (!node->parentElement()) |
363 return 0; | 391 return 0; |
364 | 392 |
365 // It's only allowed to create an AXObject from a Node if it's in a canvas s
ubtree. | 393 // It's only allowed to create an AXObject from a Node if it's in a canvas s
ubtree. |
366 // Or if it's a hidden element, but we still want to expose it because of ot
her ARIA attributes. | 394 // Or if it's a hidden element, but we still want to expose it because of ot
her ARIA attributes. |
367 bool inCanvasSubtree = node->parentElement()->isInCanvasSubtree(); | 395 bool inCanvasSubtree = node->parentElement()->isInCanvasSubtree(); |
368 bool isHidden = !node->renderer() && isNodeAriaVisible(node); | 396 bool isHidden = !node->renderer() && isNodeAriaVisible(node); |
369 if (!inCanvasSubtree && !isHidden) | 397 if (!inCanvasSubtree && !isHidden) |
370 return 0; | 398 return 0; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 return getOrCreate(m_document.view()); | 466 return getOrCreate(m_document.view()); |
439 } | 467 } |
440 | 468 |
441 AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) | 469 AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) |
442 { | 470 { |
443 RefPtr<AXObject> obj = nullptr; | 471 RefPtr<AXObject> obj = nullptr; |
444 | 472 |
445 // will be filled in... | 473 // will be filled in... |
446 switch (role) { | 474 switch (role) { |
447 case ImageMapLinkRole: | 475 case ImageMapLinkRole: |
448 obj = AXImageMapLink::create(); | 476 obj = AXImageMapLink::create(this); |
449 break; | 477 break; |
450 case ColumnRole: | 478 case ColumnRole: |
451 obj = AXTableColumn::create(); | 479 obj = AXTableColumn::create(this); |
452 break; | 480 break; |
453 case TableHeaderContainerRole: | 481 case TableHeaderContainerRole: |
454 obj = AXTableHeaderContainer::create(); | 482 obj = AXTableHeaderContainer::create(this); |
455 break; | 483 break; |
456 case SliderThumbRole: | 484 case SliderThumbRole: |
457 obj = AXSliderThumb::create(); | 485 obj = AXSliderThumb::create(this); |
458 break; | 486 break; |
459 case MenuListPopupRole: | 487 case MenuListPopupRole: |
460 obj = AXMenuListPopup::create(); | 488 obj = AXMenuListPopup::create(this); |
461 break; | 489 break; |
462 case MenuListOptionRole: | 490 case MenuListOptionRole: |
463 obj = AXMenuListOption::create(); | 491 obj = AXMenuListOption::create(this); |
464 break; | 492 break; |
465 case SpinButtonRole: | 493 case SpinButtonRole: |
466 obj = AXSpinButton::create(); | 494 obj = AXSpinButton::create(this); |
467 break; | 495 break; |
468 case SpinButtonPartRole: | 496 case SpinButtonPartRole: |
469 obj = AXSpinButtonPart::create(); | 497 obj = AXSpinButtonPart::create(this); |
470 break; | 498 break; |
471 default: | 499 default: |
472 obj = nullptr; | 500 obj = nullptr; |
473 } | 501 } |
474 | 502 |
475 if (obj) | 503 if (obj) |
476 getAXID(obj.get()); | 504 getAXID(obj.get()); |
477 else | 505 else |
478 return 0; | 506 return 0; |
479 | 507 |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 if (targetAXObject && !targetAXObject->children().isEmpty()) | 1074 if (targetAXObject && !targetAXObject->children().isEmpty()) |
1047 targetAXObject = targetAXObject->children()[0].get(); | 1075 targetAXObject = targetAXObject->children()[0].get(); |
1048 postPlatformNotification(targetAXObject, AXScrollPositionChanged); | 1076 postPlatformNotification(targetAXObject, AXScrollPositionChanged); |
1049 } | 1077 } |
1050 | 1078 |
1051 void AXObjectCacheImpl::handleScrollPositionChanged(RenderObject* renderObject) | 1079 void AXObjectCacheImpl::handleScrollPositionChanged(RenderObject* renderObject) |
1052 { | 1080 { |
1053 postPlatformNotification(getOrCreate(renderObject), AXScrollPositionChanged)
; | 1081 postPlatformNotification(getOrCreate(renderObject), AXScrollPositionChanged)
; |
1054 } | 1082 } |
1055 | 1083 |
| 1084 PublicAXObject* AXObjectCacheImpl::publicAXObjectForNode(Node* node) |
| 1085 { |
| 1086 fprintf(stderr, "publicAXObjectForNode(%p)\n", node); |
| 1087 AXObject* obj = getOrCreate(node); |
| 1088 fprintf(stderr, "Got AXObject %p\n", obj); |
| 1089 return new PublicAXObjectImpl(obj); |
| 1090 } |
| 1091 |
1056 void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect
& rect) | 1092 void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect
& rect) |
1057 { | 1093 { |
1058 AXObject* obj = getOrCreate(element); | 1094 AXObject* obj = getOrCreate(element); |
1059 if (!obj) | 1095 if (!obj) |
1060 return; | 1096 return; |
1061 | 1097 |
1062 obj->setElementRect(rect); | 1098 obj->setElementRect(rect); |
1063 } | 1099 } |
1064 | 1100 |
| 1101 PublicAXObjectImpl::PublicAXObjectImpl(AXObject* axObject) |
| 1102 : m_object(axObject) |
| 1103 { |
| 1104 fprintf(stderr, "PublicAXObjectImpl constructor\n"); |
| 1105 } |
| 1106 |
| 1107 PublicAXObjectImpl::~PublicAXObjectImpl() { } |
| 1108 |
| 1109 const AtomicString& PublicAXObjectImpl::computedRole() |
| 1110 { |
| 1111 fprintf(stderr, "computedRole()\n"); |
| 1112 if (!m_object) |
| 1113 return AXObject::roleName(NoRole); |
| 1114 |
| 1115 AccessibilityRole role = m_object->roleValue(); |
| 1116 return AXObject::roleName(role); |
| 1117 } |
| 1118 |
| 1119 const String PublicAXObjectImpl::computedText() |
| 1120 { |
| 1121 fprintf(stderr, "publicaxobjectimpl::computedText()\n"); |
| 1122 if (!m_object) { |
| 1123 fprintf(stderr, "!m_object\n"); |
| 1124 return ""; |
| 1125 } |
| 1126 return m_object->title(); |
| 1127 } |
| 1128 |
1065 } // namespace blink | 1129 } // namespace blink |
OLD | NEW |