| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 #include "modules/accessibility/AXTableColumn.h" | 78 #include "modules/accessibility/AXTableColumn.h" |
| 79 #include "modules/accessibility/AXTableHeaderContainer.h" | 79 #include "modules/accessibility/AXTableHeaderContainer.h" |
| 80 #include "modules/accessibility/AXTableRow.h" | 80 #include "modules/accessibility/AXTableRow.h" |
| 81 #include "wtf/PassRefPtr.h" | 81 #include "wtf/PassRefPtr.h" |
| 82 | 82 |
| 83 namespace blink { | 83 namespace blink { |
| 84 | 84 |
| 85 using namespace HTMLNames; | 85 using namespace HTMLNames; |
| 86 | 86 |
| 87 // static | 87 // static |
| 88 AXObjectCache* AXObjectCacheImpl::create(Document& document) | 88 PassOwnPtrWillBeRawPtr<AXObjectCache> AXObjectCacheImpl::create(Document& docume
nt) |
| 89 { | 89 { |
| 90 return new AXObjectCacheImpl(document); | 90 return adoptPtrWillBeNoop(new AXObjectCacheImpl(document)); |
| 91 } | 91 } |
| 92 | 92 |
| 93 AXObjectCacheImpl::AXObjectCacheImpl(Document& document) | 93 AXObjectCacheImpl::AXObjectCacheImpl(Document& document) |
| 94 : m_document(document) | 94 : m_document(document) |
| 95 , m_modificationCount(0) | 95 , m_modificationCount(0) |
| 96 , m_notificationPostTimer(this, &AXObjectCacheImpl::notificationPostTimerFir
ed) | 96 , m_notificationPostTimer(this, &AXObjectCacheImpl::notificationPostTimerFir
ed) |
| 97 { | 97 { |
| 98 } | 98 } |
| 99 | 99 |
| 100 AXObjectCacheImpl::~AXObjectCacheImpl() | 100 AXObjectCacheImpl::~AXObjectCacheImpl() |
| 101 { | 101 { |
| 102 } |
| 103 |
| 104 void AXObjectCacheImpl::dispose() |
| 105 { |
| 102 m_notificationPostTimer.stop(); | 106 m_notificationPostTimer.stop(); |
| 103 | 107 |
| 108 #if ENABLE(OILPAN) |
| 109 for (auto& entry : m_layoutObjectMapping) { |
| 110 entry.value->detach(); |
| 111 } |
| 112 m_layoutObjectMapping.clear(); |
| 113 |
| 114 HeapHashMap<AXID, WeakMember<AXObject>>::iterator end = m_objects.end(); |
| 115 for (HeapHashMap<AXID, WeakMember<AXObject>>::iterator it = m_objects.begin(
); it != end; ++it) { |
| 116 AXObject* obj = (*it).value.get(); |
| 117 obj->detach(); |
| 118 } |
| 119 #else |
| 104 HashMap<AXID, RefPtr<AXObject>>::iterator end = m_objects.end(); | 120 HashMap<AXID, RefPtr<AXObject>>::iterator end = m_objects.end(); |
| 105 for (HashMap<AXID, RefPtr<AXObject>>::iterator it = m_objects.begin(); it !=
end; ++it) { | 121 for (HashMap<AXID, RefPtr<AXObject>>::iterator it = m_objects.begin(); it !=
end; ++it) { |
| 106 AXObject* obj = (*it).value.get(); | 122 AXObject* obj = (*it).value.get(); |
| 107 obj->detach(); | 123 obj->detach(); |
| 108 removeAXID(obj); | 124 removeAXID(obj); |
| 109 } | 125 } |
| 126 #endif |
| 110 } | 127 } |
| 111 | 128 |
| 112 AXObject* AXObjectCacheImpl::root() | 129 AXObject* AXObjectCacheImpl::root() |
| 113 { | 130 { |
| 114 return getOrCreate(&m_document); | 131 return getOrCreate(&m_document); |
| 115 } | 132 } |
| 116 | 133 |
| 117 AXObject* AXObjectCacheImpl::focusedImageMapUIElement(HTMLAreaElement* areaEleme
nt) | 134 AXObject* AXObjectCacheImpl::focusedImageMapUIElement(HTMLAreaElement* areaEleme
nt) |
| 118 { | 135 { |
| 119 // Find the corresponding accessibility object for the HTMLAreaElement. This
should be | 136 // Find the corresponding accessibility object for the HTMLAreaElement. This
should be |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 obj = obj->parentObjectUnignored(); | 192 obj = obj->parentObjectUnignored(); |
| 176 | 193 |
| 177 return obj; | 194 return obj; |
| 178 } | 195 } |
| 179 | 196 |
| 180 AXObject* AXObjectCacheImpl::get(Widget* widget) | 197 AXObject* AXObjectCacheImpl::get(Widget* widget) |
| 181 { | 198 { |
| 182 if (!widget) | 199 if (!widget) |
| 183 return 0; | 200 return 0; |
| 184 | 201 |
| 202 #if ENABLE(OILPAN) |
| 203 return m_widgetObjectMapping.get(widget); |
| 204 #else |
| 185 AXID axID = m_widgetObjectMapping.get(widget); | 205 AXID axID = m_widgetObjectMapping.get(widget); |
| 186 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 206 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
| 187 if (!axID) | 207 if (!axID) |
| 188 return 0; | 208 return 0; |
| 189 | 209 |
| 190 return m_objects.get(axID); | 210 return m_objects.get(axID); |
| 211 #endif |
| 191 } | 212 } |
| 192 | 213 |
| 193 AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) | 214 AXObject* AXObjectCacheImpl::get(LayoutObject* layoutObject) |
| 194 { | 215 { |
| 195 if (!layoutObject) | 216 if (!layoutObject) |
| 196 return 0; | 217 return 0; |
| 197 | 218 |
| 219 #if ENABLE(OILPAN) |
| 220 return m_layoutObjectMapping.get(layoutObject); |
| 221 #else |
| 198 AXID axID = m_layoutObjectMapping.get(layoutObject); | 222 AXID axID = m_layoutObjectMapping.get(layoutObject); |
| 199 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 223 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
| 200 if (!axID) | 224 if (!axID) |
| 201 return 0; | 225 return 0; |
| 202 | 226 |
| 203 return m_objects.get(axID); | 227 return m_objects.get(axID); |
| 228 #endif |
| 204 } | 229 } |
| 205 | 230 |
| 206 // Returns true if |node| is an <option> element and its parent <select> | 231 // Returns true if |node| is an <option> element and its parent <select> |
| 207 // is a menu list (not a list box). | 232 // is a menu list (not a list box). |
| 208 static bool isMenuListOption(Node* node) | 233 static bool isMenuListOption(Node* node) |
| 209 { | 234 { |
| 210 if (!isHTMLOptionElement(node)) | 235 if (!isHTMLOptionElement(node)) |
| 211 return false; | 236 return false; |
| 212 Element* parent = node->parentElement(); | 237 Element* parent = node->parentElement(); |
| 213 if (isHTMLOptGroupElement(parent)) | 238 if (isHTMLOptGroupElement(parent)) |
| 214 parent = parent->parentElement(); | 239 parent = parent->parentElement(); |
| 215 if (!isHTMLSelectElement(parent)) | 240 if (!isHTMLSelectElement(parent)) |
| 216 return false; | 241 return false; |
| 217 LayoutObject* layoutObject = toHTMLSelectElement(parent)->layoutObject(); | 242 LayoutObject* layoutObject = toHTMLSelectElement(parent)->layoutObject(); |
| 218 return layoutObject && layoutObject->isMenuList(); | 243 return layoutObject && layoutObject->isMenuList(); |
| 219 } | 244 } |
| 220 | 245 |
| 221 AXObject* AXObjectCacheImpl::get(Node* node) | 246 AXObject* AXObjectCacheImpl::get(Node* node) |
| 222 { | 247 { |
| 223 if (!node) | 248 if (!node) |
| 224 return 0; | 249 return 0; |
| 225 | 250 |
| 251 #if ENABLE(OILPAN) |
| 252 AXObject* layoutAXObject = node->layoutObject() ? m_layoutObjectMapping.get
(node->layoutObject()) : nullptr; |
| 253 AXObject* nodeAXObject = m_nodeObjectMapping.get(node); |
| 254 if (node->layoutObject() && nodeAXObject && !layoutAXObject && !isMenuListOp
tion(node)) { |
| 255 // This can happen if an AXNodeObject is created for a node that's not |
| 256 // laid out, but later something changes and it gets a layoutObject (lik
e if it's |
| 257 // reparented). |
| 258 remove(nodeAXObject); |
| 259 return nullptr; |
| 260 } |
| 261 return layoutAXObject ? layoutAXObject : nodeAXObject; |
| 262 #else |
| 226 AXID layoutID = node->layoutObject() ? m_layoutObjectMapping.get(node->layou
tObject()) : 0; | 263 AXID layoutID = node->layoutObject() ? m_layoutObjectMapping.get(node->layou
tObject()) : 0; |
| 227 ASSERT(!HashTraits<AXID>::isDeletedValue(layoutID)); | 264 ASSERT(!HashTraits<AXID>::isDeletedValue(layoutID)); |
| 228 | 265 |
| 229 AXID nodeID = m_nodeObjectMapping.get(node); | 266 AXID nodeID = m_nodeObjectMapping.get(node); |
| 230 ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID)); | 267 ASSERT(!HashTraits<AXID>::isDeletedValue(nodeID)); |
| 231 | 268 |
| 232 if (node->layoutObject() && nodeID && !layoutID && !isMenuListOption(node))
{ | 269 if (node->layoutObject() && nodeID && !layoutID && !isMenuListOption(node))
{ |
| 233 // This can happen if an AXNodeObject is created for a node that's not | 270 // This can happen if an AXNodeObject is created for a node that's not |
| 234 // laid out, but later something changes and it gets a layoutObject (lik
e if it's | 271 // laid out, but later something changes and it gets a layoutObject (lik
e if it's |
| 235 // reparented). | 272 // reparented). |
| 236 remove(nodeID); | 273 remove(nodeID); |
| 237 return 0; | 274 return 0; |
| 238 } | 275 } |
| 239 | 276 |
| 240 if (layoutID) | 277 if (layoutID) |
| 241 return m_objects.get(layoutID); | 278 return m_objects.get(layoutID); |
| 242 | 279 |
| 243 if (!nodeID) | 280 if (!nodeID) |
| 244 return 0; | 281 return 0; |
| 245 | 282 |
| 246 return m_objects.get(nodeID); | 283 return m_objects.get(nodeID); |
| 284 #endif |
| 247 } | 285 } |
| 248 | 286 |
| 249 AXObject* AXObjectCacheImpl::get(AbstractInlineTextBox* inlineTextBox) | 287 AXObject* AXObjectCacheImpl::get(AbstractInlineTextBox* inlineTextBox) |
| 250 { | 288 { |
| 251 if (!inlineTextBox) | 289 if (!inlineTextBox) |
| 252 return 0; | 290 return 0; |
| 253 | 291 |
| 292 #if ENABLE(OILPAN) |
| 293 return m_inlineTextBoxObjectMapping.get(inlineTextBox); |
| 294 #else |
| 254 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); | 295 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); |
| 255 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); | 296 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
| 256 if (!axID) | 297 if (!axID) |
| 257 return 0; | 298 return 0; |
| 258 | 299 |
| 259 return m_objects.get(axID); | 300 return m_objects.get(axID); |
| 301 #endif |
| 260 } | 302 } |
| 261 | 303 |
| 262 // FIXME: This probably belongs on Node. | 304 // FIXME: This probably belongs on Node. |
| 263 // FIXME: This should take a const char*, but one caller passes nullAtom. | 305 // FIXME: This should take a const char*, but one caller passes nullAtom. |
| 264 bool nodeHasRole(Node* node, const String& role) | 306 bool nodeHasRole(Node* node, const String& role) |
| 265 { | 307 { |
| 266 if (!node || !node->isElementNode()) | 308 if (!node || !node->isElementNode()) |
| 267 return false; | 309 return false; |
| 268 | 310 |
| 269 return equalIgnoringCase(toElement(node)->getAttribute(roleAttr), role); | 311 return equalIgnoringCase(toElement(node)->getAttribute(roleAttr), role); |
| 270 } | 312 } |
| 271 | 313 |
| 272 PassRefPtr<AXObject> AXObjectCacheImpl::createFromRenderer(LayoutObject* layoutO
bject) | 314 PassRefPtrWillBeRawPtr<AXObject> AXObjectCacheImpl::createFromRenderer(LayoutObj
ect* layoutObject) |
| 273 { | 315 { |
| 274 // FIXME: How could layoutObject->node() ever not be an Element? | 316 // FIXME: How could layoutObject->node() ever not be an Element? |
| 275 Node* node = layoutObject->node(); | 317 Node* node = layoutObject->node(); |
| 276 | 318 |
| 277 // If the node is aria role="list" or the aria role is empty and its a | 319 // If the node is aria role="list" or the aria role is empty and its a |
| 278 // ul/ol/dl type (it shouldn't be a list if aria says otherwise). | 320 // ul/ol/dl type (it shouldn't be a list if aria says otherwise). |
| 279 if (nodeHasRole(node, "list") || nodeHasRole(node, "directory") | 321 if (nodeHasRole(node, "list") || nodeHasRole(node, "directory") |
| 280 || (nodeHasRole(node, nullAtom) && (isHTMLUListElement(node) || isHTMLOL
istElement(node) || isHTMLDListElement(node)))) | 322 || (nodeHasRole(node, nullAtom) && (isHTMLUListElement(node) || isHTMLOL
istElement(node) || isHTMLDListElement(node)))) |
| 281 return AXList::create(layoutObject, this); | 323 return AXList::create(layoutObject, this); |
| 282 | 324 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 return AXProgressIndicator::create(toLayoutProgress(cssBox), this); | 360 return AXProgressIndicator::create(toLayoutProgress(cssBox), this); |
| 319 | 361 |
| 320 // input type=range | 362 // input type=range |
| 321 if (cssBox->isSlider()) | 363 if (cssBox->isSlider()) |
| 322 return AXSlider::create(toLayoutSlider(cssBox), this); | 364 return AXSlider::create(toLayoutSlider(cssBox), this); |
| 323 } | 365 } |
| 324 | 366 |
| 325 return AXLayoutObject::create(layoutObject, this); | 367 return AXLayoutObject::create(layoutObject, this); |
| 326 } | 368 } |
| 327 | 369 |
| 328 PassRefPtr<AXObject> AXObjectCacheImpl::createFromNode(Node* node) | 370 PassRefPtrWillBeRawPtr<AXObject> AXObjectCacheImpl::createFromNode(Node* node) |
| 329 { | 371 { |
| 330 if (isMenuListOption(node)) | 372 if (isMenuListOption(node)) |
| 331 return AXMenuListOption::create(toHTMLOptionElement(node), this); | 373 return AXMenuListOption::create(toHTMLOptionElement(node), this); |
| 332 | 374 |
| 333 return AXNodeObject::create(node, this); | 375 return AXNodeObject::create(node, this); |
| 334 } | 376 } |
| 335 | 377 |
| 336 PassRefPtr<AXObject> AXObjectCacheImpl::createFromInlineTextBox(AbstractInlineTe
xtBox* inlineTextBox) | 378 PassRefPtrWillBeRawPtr<AXObject> AXObjectCacheImpl::createFromInlineTextBox(Abst
ractInlineTextBox* inlineTextBox) |
| 337 { | 379 { |
| 338 return AXInlineTextBox::create(inlineTextBox, this); | 380 return AXInlineTextBox::create(inlineTextBox, this); |
| 339 } | 381 } |
| 340 | 382 |
| 341 AXObject* AXObjectCacheImpl::getOrCreate(Widget* widget) | 383 AXObject* AXObjectCacheImpl::getOrCreate(Widget* widget) |
| 342 { | 384 { |
| 343 if (!widget) | 385 if (!widget) |
| 344 return 0; | 386 return 0; |
| 345 | 387 |
| 346 if (AXObject* obj = get(widget)) | 388 if (AXObject* obj = get(widget)) |
| 347 return obj; | 389 return obj; |
| 348 | 390 |
| 349 RefPtr<AXObject> newObj = nullptr; | 391 RefPtrWillBeRawPtr<AXObject> newObj = nullptr; |
| 350 if (widget->isFrameView()) | 392 if (widget->isFrameView()) |
| 351 newObj = AXScrollView::create(toFrameView(widget), this); | 393 newObj = AXScrollView::create(toFrameView(widget), this); |
| 352 else if (widget->isScrollbar()) | 394 else if (widget->isScrollbar()) |
| 353 newObj = AXScrollbar::create(toScrollbar(widget), this); | 395 newObj = AXScrollbar::create(toScrollbar(widget), this); |
| 354 | 396 |
| 355 // Will crash later if we have two objects for the same widget. | 397 // Will crash later if we have two objects for the same widget. |
| 356 ASSERT(!get(widget)); | 398 ASSERT(!get(widget)); |
| 357 | 399 |
| 358 // Catch the case if an (unsupported) widget type is used. Only FrameView an
d ScrollBar are supported now. | 400 // Catch the case if an (unsupported) widget type is used. Only FrameView an
d ScrollBar are supported now. |
| 359 ASSERT(newObj); | 401 ASSERT(newObj); |
| 360 if (!newObj) | 402 if (!newObj) |
| 361 return 0; | 403 return 0; |
| 362 | 404 |
| 363 getAXID(newObj.get()); | 405 getAXID(newObj.get()); |
| 364 | 406 |
| 407 #if ENABLE(OILPAN) |
| 408 m_widgetObjectMapping.set(widget, newObj); |
| 409 #else |
| 365 m_widgetObjectMapping.set(widget, newObj->axObjectID()); | 410 m_widgetObjectMapping.set(widget, newObj->axObjectID()); |
| 411 #endif |
| 366 m_objects.set(newObj->axObjectID(), newObj); | 412 m_objects.set(newObj->axObjectID(), newObj); |
| 367 newObj->init(); | 413 newObj->init(); |
| 368 return newObj.get(); | 414 return newObj.get(); |
| 369 } | 415 } |
| 370 | 416 |
| 371 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) | 417 AXObject* AXObjectCacheImpl::getOrCreate(Node* node) |
| 372 { | 418 { |
| 373 if (!node) | 419 if (!node) |
| 374 return 0; | 420 return 0; |
| 375 | 421 |
| 376 if (AXObject* obj = get(node)) | 422 if (AXObject* obj = get(node)) |
| 377 return obj; | 423 return obj; |
| 378 | 424 |
| 379 if (node->layoutObject()) | 425 if (node->layoutObject()) |
| 380 return getOrCreate(node->layoutObject()); | 426 return getOrCreate(node->layoutObject()); |
| 381 | 427 |
| 382 if (!node->parentElement()) | 428 if (!node->parentElement()) |
| 383 return 0; | 429 return 0; |
| 384 | 430 |
| 385 // It's only allowed to create an AXObject from a Node if it's in a canvas s
ubtree. | 431 // It's only allowed to create an AXObject from a Node if it's in a canvas s
ubtree. |
| 386 // Or if it's a hidden element, but we still want to expose it because of ot
her ARIA attributes. | 432 // Or if it's a hidden element, but we still want to expose it because of ot
her ARIA attributes. |
| 387 bool inCanvasSubtree = node->parentElement()->isInCanvasSubtree(); | 433 bool inCanvasSubtree = node->parentElement()->isInCanvasSubtree(); |
| 388 bool isHidden = !node->layoutObject() && isNodeAriaVisible(node); | 434 bool isHidden = !node->layoutObject() && isNodeAriaVisible(node); |
| 389 if (!inCanvasSubtree && !isHidden && !isMenuListOption(node)) | 435 if (!inCanvasSubtree && !isHidden && !isMenuListOption(node)) |
| 390 return 0; | 436 return 0; |
| 391 | 437 |
| 392 RefPtr<AXObject> newObj = createFromNode(node); | 438 RefPtrWillBeRawPtr<AXObject> newObj = createFromNode(node); |
| 393 | 439 |
| 394 // Will crash later if we have two objects for the same node. | 440 // Will crash later if we have two objects for the same node. |
| 395 ASSERT(!get(node)); | 441 ASSERT(!get(node)); |
| 396 | 442 |
| 397 getAXID(newObj.get()); | 443 getAXID(newObj.get()); |
| 398 | 444 |
| 445 #if ENABLE(OILPAN) |
| 446 m_nodeObjectMapping.set(node, newObj); |
| 447 #else |
| 399 m_nodeObjectMapping.set(node, newObj->axObjectID()); | 448 m_nodeObjectMapping.set(node, newObj->axObjectID()); |
| 449 #endif |
| 400 m_objects.set(newObj->axObjectID(), newObj); | 450 m_objects.set(newObj->axObjectID(), newObj); |
| 401 newObj->init(); | 451 newObj->init(); |
| 402 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); | 452 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); |
| 403 | 453 |
| 404 return newObj.get(); | 454 return newObj.get(); |
| 405 } | 455 } |
| 406 | 456 |
| 407 AXObject* AXObjectCacheImpl::getOrCreate(LayoutObject* layoutObject) | 457 AXObject* AXObjectCacheImpl::getOrCreate(LayoutObject* layoutObject) |
| 408 { | 458 { |
| 409 if (!layoutObject) | 459 if (!layoutObject) |
| 410 return 0; | 460 return 0; |
| 411 | 461 |
| 412 if (AXObject* obj = get(layoutObject)) | 462 if (AXObject* obj = get(layoutObject)) |
| 413 return obj; | 463 return obj; |
| 414 | 464 |
| 415 RefPtr<AXObject> newObj = createFromRenderer(layoutObject); | 465 RefPtrWillBeRawPtr<AXObject> newObj = createFromRenderer(layoutObject); |
| 416 | 466 |
| 417 // Will crash later if we have two objects for the same layoutObject. | 467 // Will crash later if we have two objects for the same layoutObject. |
| 418 ASSERT(!get(layoutObject)); | 468 ASSERT(!get(layoutObject)); |
| 419 | 469 |
| 420 getAXID(newObj.get()); | 470 getAXID(newObj.get()); |
| 421 | 471 |
| 472 #if ENABLE(OILPAN) |
| 473 m_layoutObjectMapping.set(layoutObject, newObj); |
| 474 #else |
| 422 m_layoutObjectMapping.set(layoutObject, newObj->axObjectID()); | 475 m_layoutObjectMapping.set(layoutObject, newObj->axObjectID()); |
| 476 #endif |
| 423 m_objects.set(newObj->axObjectID(), newObj); | 477 m_objects.set(newObj->axObjectID(), newObj); |
| 424 newObj->init(); | 478 newObj->init(); |
| 425 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); | 479 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); |
| 426 | 480 |
| 427 return newObj.get(); | 481 return newObj.get(); |
| 428 } | 482 } |
| 429 | 483 |
| 430 AXObject* AXObjectCacheImpl::getOrCreate(AbstractInlineTextBox* inlineTextBox) | 484 AXObject* AXObjectCacheImpl::getOrCreate(AbstractInlineTextBox* inlineTextBox) |
| 431 { | 485 { |
| 432 if (!inlineTextBox) | 486 if (!inlineTextBox) |
| 433 return 0; | 487 return 0; |
| 434 | 488 |
| 435 if (AXObject* obj = get(inlineTextBox)) | 489 if (AXObject* obj = get(inlineTextBox)) |
| 436 return obj; | 490 return obj; |
| 437 | 491 |
| 438 RefPtr<AXObject> newObj = createFromInlineTextBox(inlineTextBox); | 492 RefPtrWillBeRawPtr<AXObject> newObj = createFromInlineTextBox(inlineTextBox)
; |
| 439 | 493 |
| 440 // Will crash later if we have two objects for the same inlineTextBox. | 494 // Will crash later if we have two objects for the same inlineTextBox. |
| 441 ASSERT(!get(inlineTextBox)); | 495 ASSERT(!get(inlineTextBox)); |
| 442 | 496 |
| 443 getAXID(newObj.get()); | 497 getAXID(newObj.get()); |
| 444 | 498 |
| 499 #if ENABLE(OILPAN) |
| 500 m_inlineTextBoxObjectMapping.set(inlineTextBox, newObj); |
| 501 #else |
| 445 m_inlineTextBoxObjectMapping.set(inlineTextBox, newObj->axObjectID()); | 502 m_inlineTextBoxObjectMapping.set(inlineTextBox, newObj->axObjectID()); |
| 503 #endif |
| 446 m_objects.set(newObj->axObjectID(), newObj); | 504 m_objects.set(newObj->axObjectID(), newObj); |
| 447 newObj->init(); | 505 newObj->init(); |
| 448 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); | 506 newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored()); |
| 449 | 507 |
| 450 return newObj.get(); | 508 return newObj.get(); |
| 451 } | 509 } |
| 452 | 510 |
| 453 AXObject* AXObjectCacheImpl::rootObject() | 511 AXObject* AXObjectCacheImpl::rootObject() |
| 454 { | 512 { |
| 455 if (!accessibilityEnabled()) | 513 if (!accessibilityEnabled()) |
| 456 return 0; | 514 return 0; |
| 457 | 515 |
| 458 return getOrCreate(m_document.view()); | 516 return getOrCreate(m_document.view()); |
| 459 } | 517 } |
| 460 | 518 |
| 461 AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) | 519 AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role) |
| 462 { | 520 { |
| 463 RefPtr<AXObject> obj = nullptr; | 521 RefPtrWillBeRawPtr<AXObject> obj = nullptr; |
| 464 | 522 |
| 465 // will be filled in... | 523 // will be filled in... |
| 466 switch (role) { | 524 switch (role) { |
| 467 case ImageMapLinkRole: | 525 case ImageMapLinkRole: |
| 468 obj = AXImageMapLink::create(this); | 526 obj = AXImageMapLink::create(this); |
| 469 break; | 527 break; |
| 470 case ColumnRole: | 528 case ColumnRole: |
| 471 obj = AXTableColumn::create(this); | 529 obj = AXTableColumn::create(this); |
| 472 break; | 530 break; |
| 473 case TableHeaderContainerRole: | 531 case TableHeaderContainerRole: |
| (...skipping 18 matching lines...) Expand all Loading... |
| 492 if (obj) | 550 if (obj) |
| 493 getAXID(obj.get()); | 551 getAXID(obj.get()); |
| 494 else | 552 else |
| 495 return 0; | 553 return 0; |
| 496 | 554 |
| 497 m_objects.set(obj->axObjectID(), obj); | 555 m_objects.set(obj->axObjectID(), obj); |
| 498 obj->init(); | 556 obj->init(); |
| 499 return obj.get(); | 557 return obj.get(); |
| 500 } | 558 } |
| 501 | 559 |
| 560 #if ENABLE(OILPAN) |
| 561 void AXObjectCacheImpl::remove(AXObject* obj) |
| 562 { |
| 563 if (!obj) |
| 564 return; |
| 565 |
| 566 obj->detach(); |
| 567 } |
| 568 #else |
| 502 void AXObjectCacheImpl::remove(AXID axID) | 569 void AXObjectCacheImpl::remove(AXID axID) |
| 503 { | 570 { |
| 504 if (!axID) | 571 if (!axID) |
| 505 return; | 572 return; |
| 506 | 573 |
| 507 // first fetch object to operate some cleanup functions on it | 574 // first fetch object to operate some cleanup functions on it |
| 508 AXObject* obj = m_objects.get(axID); | 575 AXObject* obj = m_objects.get(axID); |
| 509 if (!obj) | 576 if (!obj) |
| 510 return; | 577 return; |
| 511 | 578 |
| 512 obj->detach(); | 579 obj->detach(); |
| 513 removeAXID(obj); | 580 removeAXID(obj); |
| 514 | 581 |
| 515 // finally remove the object | 582 // finally remove the object |
| 516 if (!m_objects.take(axID)) | 583 if (!m_objects.take(axID)) |
| 517 return; | 584 return; |
| 518 | 585 |
| 519 ASSERT(m_objects.size() >= m_idsInUse.size()); | 586 ASSERT(m_objects.size() >= m_idsInUse.size()); |
| 520 } | 587 } |
| 588 #endif |
| 521 | 589 |
| 522 void AXObjectCacheImpl::remove(LayoutObject* layoutObject) | 590 void AXObjectCacheImpl::remove(LayoutObject* layoutObject) |
| 523 { | 591 { |
| 524 if (!layoutObject) | 592 if (!layoutObject) |
| 525 return; | 593 return; |
| 526 | 594 |
| 595 #if ENABLE(OILPAN) |
| 596 AXObject* axLayoutObject = m_layoutObjectMapping.get(layoutObject); |
| 597 if (axLayoutObject) { |
| 598 axLayoutObject->detach(); |
| 599 remove(axLayoutObject); |
| 600 } |
| 601 #else |
| 527 AXID axID = m_layoutObjectMapping.get(layoutObject); | 602 AXID axID = m_layoutObjectMapping.get(layoutObject); |
| 528 remove(axID); | 603 remove(axID); |
| 604 #endif |
| 529 m_layoutObjectMapping.remove(layoutObject); | 605 m_layoutObjectMapping.remove(layoutObject); |
| 530 } | 606 } |
| 531 | 607 |
| 532 void AXObjectCacheImpl::remove(Node* node) | 608 void AXObjectCacheImpl::remove(Node* node) |
| 533 { | 609 { |
| 534 if (!node) | 610 if (!node) |
| 535 return; | 611 return; |
| 536 | 612 |
| 537 removeNodeForUse(node); | 613 removeNodeForUse(node); |
| 538 | 614 |
| 539 // This is all safe even if we didn't have a mapping. | 615 // This is all safe even if we didn't have a mapping. |
| 616 #if ENABLE(OILPAN) |
| 617 remove(m_nodeObjectMapping.get(node)); |
| 618 #else |
| 540 AXID axID = m_nodeObjectMapping.get(node); | 619 AXID axID = m_nodeObjectMapping.get(node); |
| 541 remove(axID); | 620 remove(axID); |
| 621 #endif |
| 542 m_nodeObjectMapping.remove(node); | 622 m_nodeObjectMapping.remove(node); |
| 543 | 623 |
| 544 if (node->layoutObject()) { | 624 if (node->layoutObject()) { |
| 545 remove(node->layoutObject()); | 625 remove(node->layoutObject()); |
| 546 return; | 626 return; |
| 547 } | 627 } |
| 548 } | 628 } |
| 549 | 629 |
| 550 void AXObjectCacheImpl::remove(Widget* view) | 630 void AXObjectCacheImpl::remove(Widget* view) |
| 551 { | 631 { |
| 552 if (!view) | 632 if (!view) |
| 553 return; | 633 return; |
| 554 | 634 |
| 635 #if ENABLE(OILPAN) |
| 636 remove(m_widgetObjectMapping.get(view)); |
| 637 #else |
| 555 AXID axID = m_widgetObjectMapping.get(view); | 638 AXID axID = m_widgetObjectMapping.get(view); |
| 556 remove(axID); | 639 remove(axID); |
| 640 #endif |
| 557 m_widgetObjectMapping.remove(view); | 641 m_widgetObjectMapping.remove(view); |
| 558 } | 642 } |
| 559 | 643 |
| 560 void AXObjectCacheImpl::remove(AbstractInlineTextBox* inlineTextBox) | 644 void AXObjectCacheImpl::remove(AbstractInlineTextBox* inlineTextBox) |
| 561 { | 645 { |
| 562 if (!inlineTextBox) | 646 if (!inlineTextBox) |
| 563 return; | 647 return; |
| 564 | 648 |
| 649 #if ENABLE(OILPAN) |
| 650 remove(m_inlineTextBoxObjectMapping.get(inlineTextBox)); |
| 651 #else |
| 565 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); | 652 AXID axID = m_inlineTextBoxObjectMapping.get(inlineTextBox); |
| 566 remove(axID); | 653 remove(axID); |
| 654 #endif |
| 567 m_inlineTextBoxObjectMapping.remove(inlineTextBox); | 655 m_inlineTextBoxObjectMapping.remove(inlineTextBox); |
| 568 } | 656 } |
| 569 | 657 |
| 570 // FIXME: Oilpan: Use a weak hashmap for this instead. | |
| 571 void AXObjectCacheImpl::clearWeakMembers(Visitor* visitor) | 658 void AXObjectCacheImpl::clearWeakMembers(Visitor* visitor) |
| 572 { | 659 { |
| 573 Vector<Node*> deadNodes; | 660 Vector<Node*> deadNodes; |
| 574 for (HashMap<Node*, AXID>::iterator it = m_nodeObjectMapping.begin(); it !=
m_nodeObjectMapping.end(); ++it) { | 661 for (auto& entry : m_nodeObjectMapping) { |
| 575 if (!visitor->isHeapObjectAlive(it->key)) | 662 if (!visitor->isHeapObjectAlive(entry.key)) |
| 576 deadNodes.append(it->key); | 663 deadNodes.append(entry.key); |
| 577 } | 664 } |
| 578 for (unsigned i = 0; i < deadNodes.size(); ++i) | 665 for (unsigned i = 0; i < deadNodes.size(); ++i) |
| 579 remove(deadNodes[i]); | 666 remove(deadNodes[i]); |
| 580 | 667 |
| 581 Vector<Widget*> deadWidgets; | 668 Vector<Widget*> deadWidgets; |
| 582 for (HashMap<Widget*, AXID>::iterator it = m_widgetObjectMapping.begin(); | 669 for (auto& entry : m_widgetObjectMapping) { |
| 583 it != m_widgetObjectMapping.end(); ++it) { | 670 if (!visitor->isHeapObjectAlive(entry.key)) |
| 584 if (!visitor->isHeapObjectAlive(it->key)) | 671 deadWidgets.append(entry.key); |
| 585 deadWidgets.append(it->key); | |
| 586 } | 672 } |
| 587 for (unsigned i = 0; i < deadWidgets.size(); ++i) | 673 for (unsigned i = 0; i < deadWidgets.size(); ++i) |
| 588 remove(deadWidgets[i]); | 674 remove(deadWidgets[i]); |
| 675 |
| 676 #if ENABLE(OILPAN) |
| 677 Vector<AXID> deadIds; |
| 678 for (auto& entry : m_objects) { |
| 679 if (entry.value) |
| 680 deadIds.append(entry.key); |
| 681 } |
| 682 for (auto& axID : deadIds) { |
| 683 m_objects.take(axID); |
| 684 } |
| 685 #endif |
| 589 } | 686 } |
| 590 | 687 |
| 591 AXID AXObjectCacheImpl::platformGenerateAXID() const | 688 AXID AXObjectCacheImpl::platformGenerateAXID() const |
| 592 { | 689 { |
| 593 static AXID lastUsedID = 0; | 690 static AXID lastUsedID = 0; |
| 594 | 691 |
| 595 // Generate a new ID. | 692 // Generate a new ID. |
| 596 AXID objID = lastUsedID; | 693 AXID objID = lastUsedID; |
| 597 do { | 694 do { |
| 598 ++objID; | 695 ++objID; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 613 } | 710 } |
| 614 | 711 |
| 615 objID = platformGenerateAXID(); | 712 objID = platformGenerateAXID(); |
| 616 | 713 |
| 617 m_idsInUse.add(objID); | 714 m_idsInUse.add(objID); |
| 618 obj->setAXObjectID(objID); | 715 obj->setAXObjectID(objID); |
| 619 | 716 |
| 620 return objID; | 717 return objID; |
| 621 } | 718 } |
| 622 | 719 |
| 720 #if !ENABLE(OILPAN) |
| 623 void AXObjectCacheImpl::removeAXID(AXObject* object) | 721 void AXObjectCacheImpl::removeAXID(AXObject* object) |
| 624 { | 722 { |
| 625 if (!object) | 723 if (!object) |
| 626 return; | 724 return; |
| 627 | 725 |
| 628 AXID objID = object->axObjectID(); | 726 AXID objID = object->axObjectID(); |
| 629 if (!objID) | 727 if (!objID) |
| 630 return; | 728 return; |
| 631 ASSERT(!HashTraits<AXID>::isDeletedValue(objID)); | 729 removeAXID(objID); |
| 632 ASSERT(m_idsInUse.contains(objID)); | |
| 633 object->setAXObjectID(0); | 730 object->setAXObjectID(0); |
| 634 m_idsInUse.remove(objID); | 731 } |
| 732 #endif |
| 733 |
| 734 void AXObjectCacheImpl::removeAXID(AXID axID) |
| 735 { |
| 736 if (!axID) |
| 737 return; |
| 738 ASSERT(!HashTraits<AXID>::isDeletedValue(axID)); |
| 739 ASSERT(m_idsInUse.contains(axID)); |
| 740 m_idsInUse.remove(axID); |
| 635 } | 741 } |
| 636 | 742 |
| 637 void AXObjectCacheImpl::selectionChanged(Node* node) | 743 void AXObjectCacheImpl::selectionChanged(Node* node) |
| 638 { | 744 { |
| 639 // Find the nearest ancestor that already has an accessibility object, since
we | 745 // Find the nearest ancestor that already has an accessibility object, since
we |
| 640 // might be in the middle of a layout. | 746 // might be in the middle of a layout. |
| 641 while (node) { | 747 while (node) { |
| 642 if (AXObject* obj = get(node)) { | 748 if (AXObject* obj = get(node)) { |
| 643 obj->selectionChanged(); | 749 obj->selectionChanged(); |
| 644 return; | 750 return; |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 | 1254 |
| 1149 void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect
& rect) | 1255 void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect
& rect) |
| 1150 { | 1256 { |
| 1151 AXObject* obj = getOrCreate(element); | 1257 AXObject* obj = getOrCreate(element); |
| 1152 if (!obj) | 1258 if (!obj) |
| 1153 return; | 1259 return; |
| 1154 | 1260 |
| 1155 obj->setElementRect(rect); | 1261 obj->setElementRect(rect); |
| 1156 } | 1262 } |
| 1157 | 1263 |
| 1264 DEFINE_TRACE(AXObjectCacheImpl) |
| 1265 { |
| 1266 AXObjectCache::trace(visitor); |
| 1267 #if ENABLE(OILPAN) |
| 1268 visitor->trace(m_objects); |
| 1269 visitor->trace(m_layoutObjectMapping); |
| 1270 visitor->trace(m_widgetObjectMapping); |
| 1271 visitor->trace(m_nodeObjectMapping); |
| 1272 visitor->trace(m_inlineTextBoxObjectMapping); |
| 1273 visitor->trace(m_notificationsToPost); |
| 1274 visitor->trace(m_textMarkerNodes); |
| 1275 #endif |
| 1276 } |
| 1277 |
| 1158 } // namespace blink | 1278 } // namespace blink |
| OLD | NEW |