| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 #include "modules/accessibility/AXLayoutObject.h" | 59 #include "modules/accessibility/AXLayoutObject.h" |
| 60 #include "modules/accessibility/AXList.h" | 60 #include "modules/accessibility/AXList.h" |
| 61 #include "modules/accessibility/AXListBox.h" | 61 #include "modules/accessibility/AXListBox.h" |
| 62 #include "modules/accessibility/AXListBoxOption.h" | 62 #include "modules/accessibility/AXListBoxOption.h" |
| 63 #include "modules/accessibility/AXMediaControls.h" | 63 #include "modules/accessibility/AXMediaControls.h" |
| 64 #include "modules/accessibility/AXMenuList.h" | 64 #include "modules/accessibility/AXMenuList.h" |
| 65 #include "modules/accessibility/AXMenuListOption.h" | 65 #include "modules/accessibility/AXMenuListOption.h" |
| 66 #include "modules/accessibility/AXMenuListPopup.h" | 66 #include "modules/accessibility/AXMenuListPopup.h" |
| 67 #include "modules/accessibility/AXProgressIndicator.h" | 67 #include "modules/accessibility/AXProgressIndicator.h" |
| 68 #include "modules/accessibility/AXSVGRoot.h" | 68 #include "modules/accessibility/AXSVGRoot.h" |
| 69 #include "modules/accessibility/AXScrollView.h" | |
| 70 #include "modules/accessibility/AXScrollbar.h" | |
| 71 #include "modules/accessibility/AXSlider.h" | 69 #include "modules/accessibility/AXSlider.h" |
| 72 #include "modules/accessibility/AXSpinButton.h" | 70 #include "modules/accessibility/AXSpinButton.h" |
| 73 #include "modules/accessibility/AXTable.h" | 71 #include "modules/accessibility/AXTable.h" |
| 74 #include "modules/accessibility/AXTableCell.h" | 72 #include "modules/accessibility/AXTableCell.h" |
| 75 #include "modules/accessibility/AXTableColumn.h" | 73 #include "modules/accessibility/AXTableColumn.h" |
| 76 #include "modules/accessibility/AXTableHeaderContainer.h" | 74 #include "modules/accessibility/AXTableHeaderContainer.h" |
| 77 #include "modules/accessibility/AXTableRow.h" | 75 #include "modules/accessibility/AXTableRow.h" |
| 78 #include "wtf/PassRefPtr.h" | 76 #include "wtf/PassRefPtr.h" |
| 79 | 77 |
| 80 namespace blink { | 78 namespace blink { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 obj = descendant; | 176 obj = descendant; |
| 179 } | 177 } |
| 180 | 178 |
| 181 // the HTML element, for example, is focusable but has an AX object that is
ignored | 179 // the HTML element, for example, is focusable but has an AX object that is
ignored |
| 182 if (obj->accessibilityIsIgnored()) | 180 if (obj->accessibilityIsIgnored()) |
| 183 obj = obj->parentObjectUnignored(); | 181 obj = obj->parentObjectUnignored(); |
| 184 | 182 |
| 185 return obj; | 183 return obj; |
| 186 } | 184 } |
| 187 | 185 |
| 188 AXObject* AXObjectCacheImpl::get(Widget* widget) | |
| 189 { | |
| 190 if (!widget) | |
| 191 return 0; | |
| 192 | |
| 193 AXID axID = m_widgetObjectMapping.get(widget); | |
| 194 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | |
| 195 if (!axID) | |
| 196 return 0; | |
| 197 | |
| 198 return m_objects.get(axID); | |
| 199 } | |
| 200 | |
| 201 AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) | 186 AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) |
| 202 { | 187 { |
| 203 if (!layoutObject) | 188 if (!layoutObject) |
| 204 return 0; | 189 return 0; |
| 205 | 190 |
| 206 AXID axID = m_layoutObjectMapping.get(layoutObject); | 191 AXID axID = m_layoutObjectMapping.get(layoutObject); |
| 207 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 192 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
| 208 if (!axID) | 193 if (!axID) |
| 209 return 0; | 194 return 0; |
| 210 | 195 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 return AXImageMapLink::create(toHTMLAreaElement(node), *this); | 330 return AXImageMapLink::create(toHTMLAreaElement(node), *this); |
| 346 | 331 |
| 347 return AXNodeObject::create(node, *this); | 332 return AXNodeObject::create(node, *this); |
| 348 } | 333 } |
| 349 | 334 |
| 350 AXObject* AXObjectCacheImpl::createFromInlineTextBox(AbstractInlineTextBox* inli
neTextBox) | 335 AXObject* AXObjectCacheImpl::createFromInlineTextBox(AbstractInlineTextBox* inli
neTextBox) |
| 351 { | 336 { |
| 352 return AXInlineTextBox::create(inlineTextBox, *this); | 337 return AXInlineTextBox::create(inlineTextBox, *this); |
| 353 } | 338 } |
| 354 | 339 |
| 355 AXObject* AXObjectCacheImpl::getOrCreate(Widget* widget) | |
| 356 { | |
| 357 if (!widget) | |
| 358 return 0; | |
| 359 | |
| 360 if (AXObject* obj = get(widget)) | |
| 361 return obj; | |
| 362 | |
| 363 AXObject* newObj = nullptr; | |
| 364 if (widget->isFrameView()) { | |
| 365 FrameView* frameView = toFrameView(widget); | |
| 366 | |
| 367 // Don't create an AXScrollView for a FrameView that isn't attached to a
frame, | |
| 368 // for example if it's in the process of being disposed. | |
| 369 if (frameView->frame().view() != frameView || !frameView->layoutView()) | |
| 370 return 0; | |
| 371 | |
| 372 newObj = AXScrollView::create(toFrameView(widget), *this); | |
| 373 } else if (widget->isScrollbar()) { | |
| 374 newObj = AXScrollbar::create(toScrollbar(widget), *this); | |
| 375 } | |
| 376 | |
| 377 // Will crash later if we have two objects for the same widget. | |
| 378 ASSERT(!get(widget)); | |
| 379 | |
| 380 // Catch the case if an (unsupported) widget type is used. Only FrameView an
d ScrollBar are supported now. | |
| 381 ASSERT(newObj); | |
| 382 if (!newObj) | |
| 383 return 0; | |
| 384 | |
| 385 getAXID(newObj); | |
| 386 | |
| 387 m_widgetObjectMapping.set(widget, newObj->axObjectID()); | |
| 388 m_objects.set(newObj->axObjectID(), newObj); | |
| 389 newObj->init(); | |
| 390 return newObj; | |
| 391 } | |
| 392 | |
| 393 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) | 340 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) |
| 394 { | 341 { |
| 395 if (!node) | 342 if (!node) |
| 396 return 0; | 343 return 0; |
| 397 | 344 |
| 398 if (AXObject* obj = get(node)) | 345 if (AXObject* obj = get(node)) |
| 399 return obj; | 346 return obj; |
| 400 | 347 |
| 401 // If the node has a layout object, prefer using that as the primary key for
the AXObject, | 348 // If the node has a layout object, prefer using that as the primary key for
the AXObject, |
| 402 // with the exception of an HTMLAreaElement, which is created based on its n
ode. | 349 // with the exception of an HTMLAreaElement, which is created based on its n
ode. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); | 418 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); |
| 472 | 419 |
| 473 return newObj; | 420 return newObj; |
| 474 } | 421 } |
| 475 | 422 |
| 476 AXObject* AXObjectCacheImpl::rootObject() | 423 AXObject* AXObjectCacheImpl::rootObject() |
| 477 { | 424 { |
| 478 if (!accessibilityEnabled()) | 425 if (!accessibilityEnabled()) |
| 479 return 0; | 426 return 0; |
| 480 | 427 |
| 481 return getOrCreate(m_document->view()); | 428 return getOrCreate(m_document); |
| 482 } | 429 } |
| 483 | 430 |
| 484 AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) | 431 AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) |
| 485 { | 432 { |
| 486 AXObject* obj = nullptr; | 433 AXObject* obj = nullptr; |
| 487 | 434 |
| 488 // will be filled in... | 435 // will be filled in... |
| 489 switch (role) { | 436 switch (role) { |
| 490 case ColumnRole: | 437 case ColumnRole: |
| 491 obj = AXTableColumn::create(*this); | 438 obj = AXTableColumn::create(*this); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 AXID axID = m_nodeObjectMapping.get(node); | 505 AXID axID = m_nodeObjectMapping.get(node); |
| 559 remove(axID); | 506 remove(axID); |
| 560 m_nodeObjectMapping.remove(node); | 507 m_nodeObjectMapping.remove(node); |
| 561 | 508 |
| 562 if (node->layoutObject()) { | 509 if (node->layoutObject()) { |
| 563 remove(node->layoutObject()); | 510 remove(node->layoutObject()); |
| 564 return; | 511 return; |
| 565 } | 512 } |
| 566 } | 513 } |
| 567 | 514 |
| 568 void AXObjectCacheImpl::remove(Widget* view) | |
| 569 { | |
| 570 if (!view) | |
| 571 return; | |
| 572 | |
| 573 AXID axID = m_widgetObjectMapping.get(view); | |
| 574 remove(axID); | |
| 575 m_widgetObjectMapping.remove(view); | |
| 576 } | |
| 577 | |
| 578 void AXObjectCacheImpl::remove(AbstractInlineTextBox* inlineTextBox) | 515 void AXObjectCacheImpl::remove(AbstractInlineTextBox* inlineTextBox) |
| 579 { | 516 { |
| 580 if (!inlineTextBox) | 517 if (!inlineTextBox) |
| 581 return; | 518 return; |
| 582 | 519 |
| 583 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); | 520 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); |
| 584 remove(axID); | 521 remove(axID); |
| 585 m_inlineTextBoxObjectMapping.remove(inlineTextBox); | 522 m_inlineTextBoxObjectMapping.remove(inlineTextBox); |
| 586 } | 523 } |
| 587 | 524 |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 | 901 |
| 965 void AXObjectCacheImpl::listboxActiveIndexChanged(HTMLSelectElement* select) | 902 void AXObjectCacheImpl::listboxActiveIndexChanged(HTMLSelectElement* select) |
| 966 { | 903 { |
| 967 AXObject* obj = get(select); | 904 AXObject* obj = get(select); |
| 968 if (!obj || !obj->isAXListBox()) | 905 if (!obj || !obj->isAXListBox()) |
| 969 return; | 906 return; |
| 970 | 907 |
| 971 toAXListBox(obj)->activeIndexChanged(); | 908 toAXListBox(obj)->activeIndexChanged(); |
| 972 } | 909 } |
| 973 | 910 |
| 974 void AXObjectCacheImpl::handleScrollbarUpdate(FrameView* view) | |
| 975 { | |
| 976 if (!view) | |
| 977 return; | |
| 978 | |
| 979 // We don't want to create a scroll view from this method, only update an ex
isting one. | |
| 980 if (AXObject* scrollViewObject = get(view)) { | |
| 981 m_modificationCount++; | |
| 982 scrollViewObject->updateChildrenIfNecessary(); | |
| 983 } | |
| 984 } | |
| 985 | |
| 986 void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) | 911 void AXObjectCacheImpl::handleLayoutComplete(LayoutObject* layoutObject) |
| 987 { | 912 { |
| 988 if (!layoutObject) | 913 if (!layoutObject) |
| 989 return; | 914 return; |
| 990 | 915 |
| 991 m_modificationCount++; | 916 m_modificationCount++; |
| 992 | 917 |
| 993 // Create the AXObject if it didn't yet exist - that's always safe at the en
d of a layout, and it | 918 // Create the AXObject if it didn't yet exist - that's always safe at the en
d of a layout, and it |
| 994 // allows an AX notification to be sent when a page has its first layout, ra
ther than when the | 919 // allows an AX notification to be sent when a page has its first layout, ra
ther than when the |
| 995 // document first loads. | 920 // document first loads. |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1157 return false; | 1082 return false; |
| 1158 | 1083 |
| 1159 if (!node->isElementNode()) | 1084 if (!node->isElementNode()) |
| 1160 return false; | 1085 return false; |
| 1161 | 1086 |
| 1162 return equalIgnoringCase(toElement(node)->getAttribute(aria_hiddenAttr), "fa
lse"); | 1087 return equalIgnoringCase(toElement(node)->getAttribute(aria_hiddenAttr), "fa
lse"); |
| 1163 } | 1088 } |
| 1164 | 1089 |
| 1165 void AXObjectCacheImpl::postPlatformNotification(AXObject* obj, AXNotification n
otification) | 1090 void AXObjectCacheImpl::postPlatformNotification(AXObject* obj, AXNotification n
otification) |
| 1166 { | 1091 { |
| 1167 if (obj && obj->isAXScrollbar() && notification == AXValueChanged) { | |
| 1168 // Send document value changed on scrollbar value changed notification. | |
| 1169 Scrollbar* scrollBar = toAXScrollbar(obj)->scrollbar(); | |
| 1170 if (!scrollBar || !scrollBar->parent() || !scrollBar->parent()->isFrameV
iew()) | |
| 1171 return; | |
| 1172 Document* document = toFrameView(scrollBar->parent())->frame().document(
); | |
| 1173 if (document != document->topDocument()) | |
| 1174 return; | |
| 1175 obj = get(document->layoutView()); | |
| 1176 } | |
| 1177 | |
| 1178 if (!obj || !obj->document() || !obj->documentFrameView() || !obj->documentF
rameView()->frame().page()) | 1092 if (!obj || !obj->document() || !obj->documentFrameView() || !obj->documentF
rameView()->frame().page()) |
| 1179 return; | 1093 return; |
| 1180 | 1094 |
| 1181 ChromeClient& client = obj->document()->axObjectCacheOwner().page()->chromeC
lient(); | 1095 ChromeClient& client = obj->document()->axObjectCacheOwner().page()->chromeC
lient(); |
| 1182 | 1096 |
| 1183 if (notification == AXActiveDescendantChanged | 1097 if (notification == AXActiveDescendantChanged |
| 1184 && obj->document()->focusedElement() | 1098 && obj->document()->focusedElement() |
| 1185 && obj->node() == obj->document()->focusedElement()) { | 1099 && obj->node() == obj->document()->focusedElement()) { |
| 1186 // Calling handleFocusedUIElementChanged will focus the new active | 1100 // Calling handleFocusedUIElementChanged will focus the new active |
| 1187 // descendant and send the AXFocusedUIElementChanged notification. | 1101 // descendant and send the AXFocusedUIElementChanged notification. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 | 1186 |
| 1273 void AXObjectCacheImpl::handleScrolledToAnchor(const Node* anchorNode) | 1187 void AXObjectCacheImpl::handleScrolledToAnchor(const Node* anchorNode) |
| 1274 { | 1188 { |
| 1275 // The anchor node may not be accessible. Post the notification for the | 1189 // The anchor node may not be accessible. Post the notification for the |
| 1276 // first accessible object. | 1190 // first accessible object. |
| 1277 postPlatformNotification(firstAccessibleObjectFromNode(anchorNode), AXScroll
edToAnchor); | 1191 postPlatformNotification(firstAccessibleObjectFromNode(anchorNode), AXScroll
edToAnchor); |
| 1278 } | 1192 } |
| 1279 | 1193 |
| 1280 void AXObjectCacheImpl::handleScrollPositionChanged(FrameView* frameView) | 1194 void AXObjectCacheImpl::handleScrollPositionChanged(FrameView* frameView) |
| 1281 { | 1195 { |
| 1282 // Prefer to fire the scroll position changed event on the frame view's chil
d web area, if possible. | 1196 AXObject* targetAXObject = getOrCreate(frameView->frame().document()); |
| 1283 AXObject* targetAXObject = getOrCreate(frameView); | |
| 1284 if (targetAXObject && !targetAXObject->children().isEmpty()) | |
| 1285 targetAXObject = targetAXObject->children()[0].get(); | |
| 1286 postPlatformNotification(targetAXObject, AXScrollPositionChanged); | 1197 postPlatformNotification(targetAXObject, AXScrollPositionChanged); |
| 1287 } | 1198 } |
| 1288 | 1199 |
| 1289 void AXObjectCacheImpl::handleScrollPositionChanged(LayoutObject* layoutObject) | 1200 void AXObjectCacheImpl::handleScrollPositionChanged(LayoutObject* layoutObject) |
| 1290 { | 1201 { |
| 1291 postPlatformNotification(getOrCreate(layoutObject), AXScrollPositionChanged)
; | 1202 postPlatformNotification(getOrCreate(layoutObject), AXScrollPositionChanged)
; |
| 1292 } | 1203 } |
| 1293 | 1204 |
| 1294 const AtomicString& AXObjectCacheImpl::computedRoleForNode(Node* node) | 1205 const AtomicString& AXObjectCacheImpl::computedRoleForNode(Node* node) |
| 1295 { | 1206 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1321 if (!obj) | 1232 if (!obj) |
| 1322 return; | 1233 return; |
| 1323 | 1234 |
| 1324 obj->setElementRect(rect); | 1235 obj->setElementRect(rect); |
| 1325 } | 1236 } |
| 1326 | 1237 |
| 1327 DEFINE_TRACE(AXObjectCacheImpl) | 1238 DEFINE_TRACE(AXObjectCacheImpl) |
| 1328 { | 1239 { |
| 1329 #if ENABLE(OILPAN) | 1240 #if ENABLE(OILPAN) |
| 1330 visitor->trace(m_document); | 1241 visitor->trace(m_document); |
| 1331 visitor->trace(m_widgetObjectMapping); | |
| 1332 visitor->trace(m_nodeObjectMapping); | 1242 visitor->trace(m_nodeObjectMapping); |
| 1333 #endif | 1243 #endif |
| 1334 | 1244 |
| 1335 visitor->trace(m_objects); | 1245 visitor->trace(m_objects); |
| 1336 visitor->trace(m_notificationsToPost); | 1246 visitor->trace(m_notificationsToPost); |
| 1337 | 1247 |
| 1338 AXObjectCache::trace(visitor); | 1248 AXObjectCache::trace(visitor); |
| 1339 } | 1249 } |
| 1340 | 1250 |
| 1341 } // namespace blink | 1251 } // namespace blink |
| OLD | NEW |