Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple 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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 if (layout_object_) | 320 if (layout_object_) |
| 321 layout_object_->SetHasAXObject(false); | 321 layout_object_->SetHasAXObject(false); |
| 322 #endif | 322 #endif |
| 323 layout_object_ = 0; | 323 layout_object_ = 0; |
| 324 } | 324 } |
| 325 | 325 |
| 326 // | 326 // |
| 327 // Check object role or purpose. | 327 // Check object role or purpose. |
| 328 // | 328 // |
| 329 | 329 |
| 330 static bool IsLinkable(const AXObject& object) { | 330 static bool IsLinkable(const AXObjectImpl& object) { |
| 331 if (!object.GetLayoutObject()) | 331 if (!object.GetLayoutObject()) |
| 332 return false; | 332 return false; |
| 333 | 333 |
| 334 // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the elements | 334 // See https://wiki.mozilla.org/Accessibility/AT-Windows-API for the elements |
| 335 // Mozilla considers linkable. | 335 // Mozilla considers linkable. |
| 336 return object.IsLink() || object.IsImage() || | 336 return object.IsLink() || object.IsImage() || |
| 337 object.GetLayoutObject()->IsText(); | 337 object.GetLayoutObject()->IsText(); |
| 338 } | 338 } |
| 339 | 339 |
| 340 // Requires layoutObject to be present because it relies on style | 340 // Requires layoutObject to be present because it relies on style |
| 341 // user-modify. Don't move this logic to AXNodeObject. | 341 // user-modify. Don't move this logic to AXNodeObject. |
| 342 bool AXLayoutObject::IsEditable() const { | 342 bool AXLayoutObject::IsEditable() const { |
| 343 if (GetLayoutObject() && GetLayoutObject()->IsTextControl()) | 343 if (GetLayoutObject() && GetLayoutObject()->IsTextControl()) |
| 344 return true; | 344 return true; |
| 345 | 345 |
| 346 if (GetNode() && HasEditableStyle(*GetNode())) | 346 if (GetNode() && HasEditableStyle(*GetNode())) |
| 347 return true; | 347 return true; |
| 348 | 348 |
| 349 if (IsWebArea()) { | 349 if (IsWebArea()) { |
| 350 Document& document = GetLayoutObject()->GetDocument(); | 350 Document& document = GetLayoutObject()->GetDocument(); |
| 351 HTMLElement* body = document.body(); | 351 HTMLElement* body = document.body(); |
| 352 if (body && HasEditableStyle(*body)) { | 352 if (body && HasEditableStyle(*body)) { |
| 353 AXObject* ax_body = AxObjectCache().GetOrCreate(body); | 353 AXObjectImpl* ax_body = AxObjectCache().GetOrCreate(body); |
| 354 return ax_body && ax_body != ax_body->AriaHiddenRoot(); | 354 return ax_body && ax_body != ax_body->AriaHiddenRoot(); |
| 355 } | 355 } |
| 356 | 356 |
| 357 return HasEditableStyle(document); | 357 return HasEditableStyle(document); |
| 358 } | 358 } |
| 359 | 359 |
| 360 return AXNodeObject::IsEditable(); | 360 return AXNodeObject::IsEditable(); |
| 361 } | 361 } |
| 362 | 362 |
| 363 // Requires layoutObject to be present because it relies on style | 363 // Requires layoutObject to be present because it relies on style |
| 364 // user-modify. Don't move this logic to AXNodeObject. | 364 // user-modify. Don't move this logic to AXNodeObject. |
| 365 bool AXLayoutObject::IsRichlyEditable() const { | 365 bool AXLayoutObject::IsRichlyEditable() const { |
| 366 if (GetNode() && HasRichlyEditableStyle(*GetNode())) | 366 if (GetNode() && HasRichlyEditableStyle(*GetNode())) |
| 367 return true; | 367 return true; |
| 368 | 368 |
| 369 if (IsWebArea()) { | 369 if (IsWebArea()) { |
| 370 Document& document = layout_object_->GetDocument(); | 370 Document& document = layout_object_->GetDocument(); |
| 371 HTMLElement* body = document.body(); | 371 HTMLElement* body = document.body(); |
| 372 if (body && HasRichlyEditableStyle(*body)) { | 372 if (body && HasRichlyEditableStyle(*body)) { |
| 373 AXObject* ax_body = AxObjectCache().GetOrCreate(body); | 373 AXObjectImpl* ax_body = AxObjectCache().GetOrCreate(body); |
| 374 return ax_body && ax_body != ax_body->AriaHiddenRoot(); | 374 return ax_body && ax_body != ax_body->AriaHiddenRoot(); |
| 375 } | 375 } |
| 376 | 376 |
| 377 return HasRichlyEditableStyle(document); | 377 return HasRichlyEditableStyle(document); |
| 378 } | 378 } |
| 379 | 379 |
| 380 return AXNodeObject::IsRichlyEditable(); | 380 return AXNodeObject::IsRichlyEditable(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 bool AXLayoutObject::IsLinked() const { | 383 bool AXLayoutObject::IsLinked() const { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 405 return view_rect.IsEmpty(); | 405 return view_rect.IsEmpty(); |
| 406 } | 406 } |
| 407 | 407 |
| 408 bool AXLayoutObject::IsReadOnly() const { | 408 bool AXLayoutObject::IsReadOnly() const { |
| 409 DCHECK(layout_object_); | 409 DCHECK(layout_object_); |
| 410 | 410 |
| 411 if (IsWebArea()) { | 411 if (IsWebArea()) { |
| 412 Document& document = layout_object_->GetDocument(); | 412 Document& document = layout_object_->GetDocument(); |
| 413 HTMLElement* body = document.body(); | 413 HTMLElement* body = document.body(); |
| 414 if (body && HasEditableStyle(*body)) { | 414 if (body && HasEditableStyle(*body)) { |
| 415 AXObject* ax_body = AxObjectCache().GetOrCreate(body); | 415 AXObjectImpl* ax_body = AxObjectCache().GetOrCreate(body); |
| 416 return !ax_body || ax_body == ax_body->AriaHiddenRoot(); | 416 return !ax_body || ax_body == ax_body->AriaHiddenRoot(); |
| 417 } | 417 } |
| 418 | 418 |
| 419 return !HasEditableStyle(document); | 419 return !HasEditableStyle(document); |
| 420 } | 420 } |
| 421 | 421 |
| 422 return AXNodeObject::IsReadOnly(); | 422 return AXNodeObject::IsReadOnly(); |
| 423 } | 423 } |
| 424 | 424 |
| 425 bool AXLayoutObject::IsVisited() const { | 425 bool AXLayoutObject::IsVisited() const { |
| 426 // FIXME: Is it a privacy violation to expose visited information to | 426 // FIXME: Is it a privacy violation to expose visited information to |
| 427 // accessibility APIs? | 427 // accessibility APIs? |
| 428 return layout_object_->Style()->IsLink() && | 428 return layout_object_->Style()->IsLink() && |
| 429 layout_object_->Style()->InsideLink() == | 429 layout_object_->Style()->InsideLink() == |
| 430 EInsideLink::kInsideVisitedLink; | 430 EInsideLink::kInsideVisitedLink; |
| 431 } | 431 } |
| 432 | 432 |
| 433 // | 433 // |
| 434 // Check object state. | 434 // Check object state. |
| 435 // | 435 // |
| 436 | 436 |
| 437 bool AXLayoutObject::IsFocused() const { | 437 bool AXLayoutObject::IsFocused() const { |
| 438 if (!GetDocument()) | 438 if (!GetDocument()) |
| 439 return false; | 439 return false; |
| 440 | 440 |
| 441 Element* focused_element = GetDocument()->FocusedElement(); | 441 Element* focused_element = GetDocument()->FocusedElement(); |
| 442 if (!focused_element) | 442 if (!focused_element) |
| 443 return false; | 443 return false; |
| 444 AXObject* focused_object = AxObjectCache().GetOrCreate(focused_element); | 444 AXObjectImpl* focused_object = AxObjectCache().GetOrCreate(focused_element); |
| 445 if (!focused_object || !focused_object->IsAXLayoutObject()) | 445 if (!focused_object || !focused_object->IsAXLayoutObject()) |
| 446 return false; | 446 return false; |
| 447 | 447 |
| 448 // A web area is represented by the Document node in the DOM tree, which isn't | 448 // A web area is represented by the Document node in the DOM tree, which isn't |
| 449 // focusable. Check instead if the frame's selection controller is focused | 449 // focusable. Check instead if the frame's selection controller is focused |
| 450 if (focused_object == this || | 450 if (focused_object == this || |
| 451 (RoleValue() == kWebAreaRole && | 451 (RoleValue() == kWebAreaRole && |
| 452 GetDocument()->GetFrame()->Selection().IsFocusedAndActive())) | 452 GetDocument()->GetFrame()->Selection().IsFocusedAndActive())) |
| 453 return true; | 453 return true; |
| 454 | 454 |
| 455 return false; | 455 return false; |
| 456 } | 456 } |
| 457 | 457 |
| 458 bool AXLayoutObject::IsSelected() const { | 458 bool AXLayoutObject::IsSelected() const { |
| 459 if (!GetLayoutObject() || !GetNode()) | 459 if (!GetLayoutObject() || !GetNode()) |
| 460 return false; | 460 return false; |
| 461 | 461 |
| 462 const AtomicString& aria_selected = GetAttribute(aria_selectedAttr); | 462 const AtomicString& aria_selected = GetAttribute(aria_selectedAttr); |
| 463 if (EqualIgnoringASCIICase(aria_selected, "true")) | 463 if (EqualIgnoringASCIICase(aria_selected, "true")) |
| 464 return true; | 464 return true; |
| 465 | 465 |
| 466 AXObject* focused_object = AxObjectCache().FocusedObject(); | 466 AXObjectImpl* focused_object = AxObjectCache().FocusedObject(); |
| 467 if (AriaRoleAttribute() == kListBoxOptionRole && focused_object && | 467 if (AriaRoleAttribute() == kListBoxOptionRole && focused_object && |
| 468 focused_object->ActiveDescendant() == this) { | 468 focused_object->ActiveDescendant() == this) { |
| 469 return true; | 469 return true; |
| 470 } | 470 } |
| 471 | 471 |
| 472 if (IsTabItem() && IsTabItemSelected()) | 472 if (IsTabItem() && IsTabItemSelected()) |
| 473 return true; | 473 return true; |
| 474 | 474 |
| 475 return false; | 475 return false; |
| 476 } | 476 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 494 // aria-hidden is meant to override visibility as the determinant in AX | 494 // aria-hidden is meant to override visibility as the determinant in AX |
| 495 // hierarchy inclusion. | 495 // hierarchy inclusion. |
| 496 if (EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) | 496 if (EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) |
| 497 return kDefaultBehavior; | 497 return kDefaultBehavior; |
| 498 | 498 |
| 499 if (ignored_reasons) | 499 if (ignored_reasons) |
| 500 ignored_reasons->push_back(IgnoredReason(kAXNotVisible)); | 500 ignored_reasons->push_back(IgnoredReason(kAXNotVisible)); |
| 501 return kIgnoreObject; | 501 return kIgnoreObject; |
| 502 } | 502 } |
| 503 | 503 |
| 504 return AXObject::DefaultObjectInclusion(ignored_reasons); | 504 return AXObjectImpl::DefaultObjectInclusion(ignored_reasons); |
| 505 } | 505 } |
| 506 | 506 |
| 507 bool AXLayoutObject::ComputeAccessibilityIsIgnored( | 507 bool AXLayoutObject::ComputeAccessibilityIsIgnored( |
| 508 IgnoredReasons* ignored_reasons) const { | 508 IgnoredReasons* ignored_reasons) const { |
| 509 #if DCHECK_IS_ON() | 509 #if DCHECK_IS_ON() |
| 510 DCHECK(initialized_); | 510 DCHECK(initialized_); |
| 511 #endif | 511 #endif |
| 512 | 512 |
| 513 if (!layout_object_) | 513 if (!layout_object_) |
| 514 return true; | 514 return true; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 535 } | 535 } |
| 536 | 536 |
| 537 if (RoleValue() == kIgnoredRole) { | 537 if (RoleValue() == kIgnoredRole) { |
| 538 if (ignored_reasons) | 538 if (ignored_reasons) |
| 539 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 539 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); |
| 540 return true; | 540 return true; |
| 541 } | 541 } |
| 542 | 542 |
| 543 if (HasInheritedPresentationalRole()) { | 543 if (HasInheritedPresentationalRole()) { |
| 544 if (ignored_reasons) { | 544 if (ignored_reasons) { |
| 545 const AXObject* inherits_from = InheritsPresentationalRoleFrom(); | 545 const AXObjectImpl* inherits_from = InheritsPresentationalRoleFrom(); |
| 546 if (inherits_from == this) | 546 if (inherits_from == this) |
| 547 ignored_reasons->push_back(IgnoredReason(kAXPresentationalRole)); | 547 ignored_reasons->push_back(IgnoredReason(kAXPresentationalRole)); |
| 548 else | 548 else |
| 549 ignored_reasons->push_back( | 549 ignored_reasons->push_back( |
| 550 IgnoredReason(kAXInheritsPresentation, inherits_from)); | 550 IgnoredReason(kAXInheritsPresentation, inherits_from)); |
| 551 } | 551 } |
| 552 return true; | 552 return true; |
| 553 } | 553 } |
| 554 | 554 |
| 555 // An ARIA tree can only have tree items and static text as children. | 555 // An ARIA tree can only have tree items and static text as children. |
| 556 if (AXObject* tree_ancestor = TreeAncestorDisallowingChild()) { | 556 if (AXObjectImpl* tree_ancestor = TreeAncestorDisallowingChild()) { |
| 557 if (ignored_reasons) | 557 if (ignored_reasons) |
| 558 ignored_reasons->push_back( | 558 ignored_reasons->push_back( |
| 559 IgnoredReason(kAXAncestorDisallowsChild, tree_ancestor)); | 559 IgnoredReason(kAXAncestorDisallowsChild, tree_ancestor)); |
| 560 return true; | 560 return true; |
| 561 } | 561 } |
| 562 | 562 |
| 563 // A LayoutPart is an iframe element or embedded object element or something | 563 // A LayoutPart is an iframe element or embedded object element or something |
| 564 // like that. We don't want to ignore those. | 564 // like that. We don't want to ignore those. |
| 565 if (layout_object_->IsLayoutPart()) | 565 if (layout_object_->IsLayoutPart()) |
| 566 return false; | 566 return false; |
| 567 | 567 |
| 568 // Make sure renderers with layers stay in the tree. | 568 // Make sure renderers with layers stay in the tree. |
| 569 if (GetLayoutObject() && GetLayoutObject()->HasLayer() && GetNode() && | 569 if (GetLayoutObject() && GetLayoutObject()->HasLayer() && GetNode() && |
| 570 GetNode()->hasChildren()) | 570 GetNode()->hasChildren()) |
| 571 return false; | 571 return false; |
| 572 | 572 |
| 573 // Find out if this element is inside of a label element. If so, it may be | 573 // Find out if this element is inside of a label element. If so, it may be |
| 574 // ignored because it's the label for a checkbox or radio button. | 574 // ignored because it's the label for a checkbox or radio button. |
| 575 AXObject* control_object = CorrespondingControlForLabelElement(); | 575 AXObjectImpl* control_object = CorrespondingControlForLabelElement(); |
| 576 if (control_object && control_object->IsCheckboxOrRadio() && | 576 if (control_object && control_object->IsCheckboxOrRadio() && |
| 577 control_object->NameFromLabelElement()) { | 577 control_object->NameFromLabelElement()) { |
| 578 if (ignored_reasons) { | 578 if (ignored_reasons) { |
| 579 HTMLLabelElement* label = LabelElementContainer(); | 579 HTMLLabelElement* label = LabelElementContainer(); |
| 580 if (label && label != GetNode()) { | 580 if (label && label != GetNode()) { |
| 581 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label); | 581 AXObjectImpl* label_ax_object = AxObjectCache().GetOrCreate(label); |
| 582 ignored_reasons->push_back( | 582 ignored_reasons->push_back( |
| 583 IgnoredReason(kAXLabelContainer, label_ax_object)); | 583 IgnoredReason(kAXLabelContainer, label_ax_object)); |
| 584 } | 584 } |
| 585 | 585 |
| 586 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); | 586 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); |
| 587 } | 587 } |
| 588 return true; | 588 return true; |
| 589 } | 589 } |
| 590 | 590 |
| 591 if (layout_object_->IsBR()) | 591 if (layout_object_->IsBR()) |
| 592 return false; | 592 return false; |
| 593 | 593 |
| 594 if (IsLink()) | 594 if (IsLink()) |
| 595 return false; | 595 return false; |
| 596 | 596 |
| 597 if (IsInPageLinkTarget()) | 597 if (IsInPageLinkTarget()) |
| 598 return false; | 598 return false; |
| 599 | 599 |
| 600 if (layout_object_->IsText()) { | 600 if (layout_object_->IsText()) { |
| 601 // Static text beneath MenuItems and MenuButtons are just reported along | 601 // Static text beneath MenuItems and MenuButtons are just reported along |
| 602 // with the menu item, so it's ignored on an individual level. | 602 // with the menu item, so it's ignored on an individual level. |
| 603 AXObject* parent = ParentObjectUnignored(); | 603 AXObjectImpl* parent = ParentObjectUnignored(); |
| 604 if (parent && (parent->AriaRoleAttribute() == kMenuItemRole || | 604 if (parent && (parent->AriaRoleAttribute() == kMenuItemRole || |
| 605 parent->AriaRoleAttribute() == kMenuButtonRole)) { | 605 parent->AriaRoleAttribute() == kMenuButtonRole)) { |
| 606 if (ignored_reasons) | 606 if (ignored_reasons) |
| 607 ignored_reasons->push_back( | 607 ignored_reasons->push_back( |
| 608 IgnoredReason(kAXStaticTextUsedAsNameFor, parent)); | 608 IgnoredReason(kAXStaticTextUsedAsNameFor, parent)); |
| 609 return true; | 609 return true; |
| 610 } | 610 } |
| 611 LayoutText* layout_text = ToLayoutText(layout_object_); | 611 LayoutText* layout_text = ToLayoutText(layout_object_); |
| 612 if (!layout_text->HasTextBoxes()) { | 612 if (!layout_text->HasTextBoxes()) { |
| 613 if (ignored_reasons) | 613 if (ignored_reasons) |
| 614 ignored_reasons->push_back(IgnoredReason(kAXEmptyText)); | 614 ignored_reasons->push_back(IgnoredReason(kAXEmptyText)); |
| 615 return true; | 615 return true; |
| 616 } | 616 } |
| 617 | 617 |
| 618 // Don't ignore static text in editable text controls. | 618 // Don't ignore static text in editable text controls. |
| 619 for (AXObject* parent = ParentObject(); parent; | 619 for (AXObjectImpl* parent = ParentObject(); parent; |
| 620 parent = parent->ParentObject()) { | 620 parent = parent->ParentObject()) { |
| 621 if (parent->RoleValue() == kTextFieldRole) | 621 if (parent->RoleValue() == kTextFieldRole) |
| 622 return false; | 622 return false; |
| 623 } | 623 } |
| 624 | 624 |
| 625 // Text elements that are just empty whitespace should not be returned. | 625 // Text elements that are just empty whitespace should not be returned. |
| 626 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', | 626 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', |
| 627 // or similar... | 627 // or similar... |
| 628 if (layout_text->GetText().Impl()->ContainsOnlyWhitespace()) { | 628 if (layout_text->GetText().Impl()->ContainsOnlyWhitespace()) { |
| 629 if (ignored_reasons) | 629 if (ignored_reasons) |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 802 } | 802 } |
| 803 | 803 |
| 804 RGBA32 AXLayoutObject::ComputeBackgroundColor() const { | 804 RGBA32 AXLayoutObject::ComputeBackgroundColor() const { |
| 805 if (!GetLayoutObject()) | 805 if (!GetLayoutObject()) |
| 806 return AXNodeObject::BackgroundColor(); | 806 return AXNodeObject::BackgroundColor(); |
| 807 | 807 |
| 808 Color blended_color = Color::kTransparent; | 808 Color blended_color = Color::kTransparent; |
| 809 // Color::blend should be called like this: background.blend(foreground). | 809 // Color::blend should be called like this: background.blend(foreground). |
| 810 for (LayoutObject* layout_object = GetLayoutObject(); layout_object; | 810 for (LayoutObject* layout_object = GetLayoutObject(); layout_object; |
| 811 layout_object = layout_object->Parent()) { | 811 layout_object = layout_object->Parent()) { |
| 812 const AXObject* ax_parent = AxObjectCache().GetOrCreate(layout_object); | 812 const AXObjectImpl* ax_parent = AxObjectCache().GetOrCreate(layout_object); |
| 813 if (ax_parent && ax_parent != this) { | 813 if (ax_parent && ax_parent != this) { |
| 814 Color parent_color = ax_parent->BackgroundColor(); | 814 Color parent_color = ax_parent->BackgroundColor(); |
| 815 blended_color = parent_color.Blend(blended_color); | 815 blended_color = parent_color.Blend(blended_color); |
| 816 return blended_color.Rgb(); | 816 return blended_color.Rgb(); |
| 817 } | 817 } |
| 818 | 818 |
| 819 const ComputedStyle* style = layout_object->Style(); | 819 const ComputedStyle* style = layout_object->Style(); |
| 820 if (!style || !style->HasBackground()) | 820 if (!style || !style->HasBackground()) |
| 821 continue; | 821 continue; |
| 822 | 822 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1073 ClearChildren(); | 1073 ClearChildren(); |
| 1074 AddInlineTextBoxChildren(true); | 1074 AddInlineTextBoxChildren(true); |
| 1075 return; | 1075 return; |
| 1076 } | 1076 } |
| 1077 | 1077 |
| 1078 for (const auto& child : children_) { | 1078 for (const auto& child : children_) { |
| 1079 child->LoadInlineTextBoxes(); | 1079 child->LoadInlineTextBoxes(); |
| 1080 } | 1080 } |
| 1081 } | 1081 } |
| 1082 | 1082 |
| 1083 AXObject* AXLayoutObject::NextOnLine() const { | 1083 AXObjectImpl* AXLayoutObject::NextOnLine() const { |
| 1084 if (!GetLayoutObject()) | 1084 if (!GetLayoutObject()) |
| 1085 return nullptr; | 1085 return nullptr; |
| 1086 | 1086 |
| 1087 InlineBox* inline_box = nullptr; | 1087 InlineBox* inline_box = nullptr; |
| 1088 if (GetLayoutObject()->IsLayoutInline()) | 1088 if (GetLayoutObject()->IsLayoutInline()) |
| 1089 inline_box = ToLayoutInline(GetLayoutObject())->LastLineBox(); | 1089 inline_box = ToLayoutInline(GetLayoutObject())->LastLineBox(); |
| 1090 else if (GetLayoutObject()->IsText()) | 1090 else if (GetLayoutObject()->IsText()) |
| 1091 inline_box = ToLayoutText(GetLayoutObject())->LastTextBox(); | 1091 inline_box = ToLayoutText(GetLayoutObject())->LastTextBox(); |
| 1092 | 1092 |
| 1093 if (!inline_box) | 1093 if (!inline_box) |
| 1094 return nullptr; | 1094 return nullptr; |
| 1095 | 1095 |
| 1096 AXObject* result = nullptr; | 1096 AXObjectImpl* result = nullptr; |
| 1097 for (InlineBox* next = inline_box->NextOnLine(); next; | 1097 for (InlineBox* next = inline_box->NextOnLine(); next; |
| 1098 next = next->NextOnLine()) { | 1098 next = next->NextOnLine()) { |
| 1099 LayoutObject* layout_object = | 1099 LayoutObject* layout_object = |
| 1100 LineLayoutAPIShim::LayoutObjectFrom(next->GetLineLayoutItem()); | 1100 LineLayoutAPIShim::LayoutObjectFrom(next->GetLineLayoutItem()); |
| 1101 result = AxObjectCache().GetOrCreate(layout_object); | 1101 result = AxObjectCache().GetOrCreate(layout_object); |
| 1102 if (result) | 1102 if (result) |
| 1103 break; | 1103 break; |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 // A static text node might span multiple lines. Try to return the first | 1106 // A static text node might span multiple lines. Try to return the first |
| 1107 // inline text box within that static text if possible. | 1107 // inline text box within that static text if possible. |
| 1108 if (result && result->RoleValue() == kStaticTextRole && | 1108 if (result && result->RoleValue() == kStaticTextRole && |
| 1109 result->Children().size()) | 1109 result->Children().size()) |
| 1110 result = result->Children()[0].Get(); | 1110 result = result->Children()[0].Get(); |
| 1111 | 1111 |
| 1112 return result; | 1112 return result; |
| 1113 } | 1113 } |
| 1114 | 1114 |
| 1115 AXObject* AXLayoutObject::PreviousOnLine() const { | 1115 AXObjectImpl* AXLayoutObject::PreviousOnLine() const { |
| 1116 if (!GetLayoutObject()) | 1116 if (!GetLayoutObject()) |
| 1117 return nullptr; | 1117 return nullptr; |
| 1118 | 1118 |
| 1119 InlineBox* inline_box = nullptr; | 1119 InlineBox* inline_box = nullptr; |
| 1120 if (GetLayoutObject()->IsLayoutInline()) | 1120 if (GetLayoutObject()->IsLayoutInline()) |
| 1121 inline_box = ToLayoutInline(GetLayoutObject())->FirstLineBox(); | 1121 inline_box = ToLayoutInline(GetLayoutObject())->FirstLineBox(); |
| 1122 else if (GetLayoutObject()->IsText()) | 1122 else if (GetLayoutObject()->IsText()) |
| 1123 inline_box = ToLayoutText(GetLayoutObject())->FirstTextBox(); | 1123 inline_box = ToLayoutText(GetLayoutObject())->FirstTextBox(); |
| 1124 | 1124 |
| 1125 if (!inline_box) | 1125 if (!inline_box) |
| 1126 return nullptr; | 1126 return nullptr; |
| 1127 | 1127 |
| 1128 AXObject* result = nullptr; | 1128 AXObjectImpl* result = nullptr; |
| 1129 for (InlineBox* prev = inline_box->PrevOnLine(); prev; | 1129 for (InlineBox* prev = inline_box->PrevOnLine(); prev; |
| 1130 prev = prev->PrevOnLine()) { | 1130 prev = prev->PrevOnLine()) { |
| 1131 LayoutObject* layout_object = | 1131 LayoutObject* layout_object = |
| 1132 LineLayoutAPIShim::LayoutObjectFrom(prev->GetLineLayoutItem()); | 1132 LineLayoutAPIShim::LayoutObjectFrom(prev->GetLineLayoutItem()); |
| 1133 result = AxObjectCache().GetOrCreate(layout_object); | 1133 result = AxObjectCache().GetOrCreate(layout_object); |
| 1134 if (result) | 1134 if (result) |
| 1135 break; | 1135 break; |
| 1136 } | 1136 } |
| 1137 | 1137 |
| 1138 // A static text node might span multiple lines. Try to return the last inline | 1138 // A static text node might span multiple lines. Try to return the last inline |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 case kImageRole: | 1277 case kImageRole: |
| 1278 case kProgressIndicatorRole: | 1278 case kProgressIndicatorRole: |
| 1279 case kSpinButtonRole: | 1279 case kSpinButtonRole: |
| 1280 // case SeparatorRole: | 1280 // case SeparatorRole: |
| 1281 return true; | 1281 return true; |
| 1282 default: | 1282 default: |
| 1283 return false; | 1283 return false; |
| 1284 } | 1284 } |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 AXObject* AXLayoutObject::AncestorForWhichThisIsAPresentationalChild() const { | 1287 AXObjectImpl* AXLayoutObject::AncestorForWhichThisIsAPresentationalChild() |
| 1288 const { | |
| 1288 // Walk the parent chain looking for a parent that has presentational children | 1289 // Walk the parent chain looking for a parent that has presentational children |
| 1289 AXObject* parent = ParentObjectIfExists(); | 1290 AXObjectImpl* parent = ParentObjectIfExists(); |
| 1290 while (parent) { | 1291 while (parent) { |
| 1291 if (parent->AriaRoleHasPresentationalChildren()) | 1292 if (parent->AriaRoleHasPresentationalChildren()) |
| 1292 break; | 1293 break; |
| 1293 | 1294 |
| 1294 // The descendants of a AXMenuList that are AXLayoutObjects are all | 1295 // The descendants of a AXMenuList that are AXLayoutObjects are all |
| 1295 // presentational. (The real descendants are an AXMenuListPopup and | 1296 // presentational. (The real descendants are an AXMenuListPopup and |
| 1296 // AXMenuListOptions, which are not AXLayoutObjects.) | 1297 // AXMenuListOptions, which are not AXLayoutObjects.) |
| 1297 if (parent->IsMenuList()) | 1298 if (parent->IsMenuList()) |
| 1298 break; | 1299 break; |
| 1299 | 1300 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1383 } | 1384 } |
| 1384 | 1385 |
| 1385 bool AXLayoutObject::LiveRegionBusy() const { | 1386 bool AXLayoutObject::LiveRegionBusy() const { |
| 1386 return ElementAttributeValue(aria_busyAttr); | 1387 return ElementAttributeValue(aria_busyAttr); |
| 1387 } | 1388 } |
| 1388 | 1389 |
| 1389 // | 1390 // |
| 1390 // Hit testing. | 1391 // Hit testing. |
| 1391 // | 1392 // |
| 1392 | 1393 |
| 1393 AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const { | 1394 AXObjectImpl* AXLayoutObject::AccessibilityHitTest( |
| 1395 const IntPoint& point) const { | |
| 1394 if (!layout_object_ || !layout_object_->HasLayer()) | 1396 if (!layout_object_ || !layout_object_->HasLayer()) |
| 1395 return nullptr; | 1397 return nullptr; |
| 1396 | 1398 |
| 1397 PaintLayer* layer = ToLayoutBox(layout_object_)->Layer(); | 1399 PaintLayer* layer = ToLayoutBox(layout_object_)->Layer(); |
| 1398 | 1400 |
| 1399 HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive); | 1401 HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive); |
| 1400 HitTestResult hit_test_result = HitTestResult(request, point); | 1402 HitTestResult hit_test_result = HitTestResult(request, point); |
| 1401 layer->HitTest(hit_test_result); | 1403 layer->HitTest(hit_test_result); |
| 1402 | 1404 |
| 1403 Node* node = hit_test_result.InnerNode(); | 1405 Node* node = hit_test_result.InnerNode(); |
| 1404 if (!node) | 1406 if (!node) |
| 1405 return nullptr; | 1407 return nullptr; |
| 1406 | 1408 |
| 1407 if (isHTMLAreaElement(node)) | 1409 if (isHTMLAreaElement(node)) |
| 1408 return AccessibilityImageMapHitTest(toHTMLAreaElement(node), point); | 1410 return AccessibilityImageMapHitTest(toHTMLAreaElement(node), point); |
| 1409 | 1411 |
| 1410 if (isHTMLOptionElement(node)) { | 1412 if (isHTMLOptionElement(node)) { |
| 1411 node = toHTMLOptionElement(*node).OwnerSelectElement(); | 1413 node = toHTMLOptionElement(*node).OwnerSelectElement(); |
| 1412 if (!node) | 1414 if (!node) |
| 1413 return nullptr; | 1415 return nullptr; |
| 1414 } | 1416 } |
| 1415 | 1417 |
| 1416 LayoutObject* obj = node->GetLayoutObject(); | 1418 LayoutObject* obj = node->GetLayoutObject(); |
| 1417 if (!obj) | 1419 if (!obj) |
| 1418 return nullptr; | 1420 return nullptr; |
| 1419 | 1421 |
| 1420 AXObject* result = AxObjectCache().GetOrCreate(obj); | 1422 AXObjectImpl* result = AxObjectCache().GetOrCreate(obj); |
| 1421 result->UpdateChildrenIfNecessary(); | 1423 result->UpdateChildrenIfNecessary(); |
| 1422 | 1424 |
| 1423 // Allow the element to perform any hit-testing it might need to do to reach | 1425 // Allow the element to perform any hit-testing it might need to do to reach |
| 1424 // non-layout children. | 1426 // non-layout children. |
| 1425 result = result->ElementAccessibilityHitTest(point); | 1427 result = result->ElementAccessibilityHitTest(point); |
| 1426 if (result && result->AccessibilityIsIgnored()) { | 1428 if (result && result->AccessibilityIsIgnored()) { |
| 1427 // If this element is the label of a control, a hit test should return the | 1429 // If this element is the label of a control, a hit test should return the |
| 1428 // control. | 1430 // control. |
| 1429 if (result->IsAXLayoutObject()) { | 1431 if (result->IsAXLayoutObject()) { |
| 1430 AXObject* control_object = | 1432 AXObjectImpl* control_object = |
| 1431 ToAXLayoutObject(result)->CorrespondingControlForLabelElement(); | 1433 ToAXLayoutObject(result)->CorrespondingControlForLabelElement(); |
| 1432 if (control_object && control_object->NameFromLabelElement()) | 1434 if (control_object && control_object->NameFromLabelElement()) |
| 1433 return control_object; | 1435 return control_object; |
| 1434 } | 1436 } |
| 1435 | 1437 |
| 1436 result = result->ParentObjectUnignored(); | 1438 result = result->ParentObjectUnignored(); |
| 1437 } | 1439 } |
| 1438 | 1440 |
| 1439 return result; | 1441 return result; |
| 1440 } | 1442 } |
| 1441 | 1443 |
| 1442 AXObject* AXLayoutObject::ElementAccessibilityHitTest( | 1444 AXObjectImpl* AXLayoutObject::ElementAccessibilityHitTest( |
| 1443 const IntPoint& point) const { | 1445 const IntPoint& point) const { |
| 1444 if (IsSVGImage()) | 1446 if (IsSVGImage()) |
| 1445 return RemoteSVGElementHitTest(point); | 1447 return RemoteSVGElementHitTest(point); |
| 1446 | 1448 |
| 1447 return AXObject::ElementAccessibilityHitTest(point); | 1449 return AXObjectImpl::ElementAccessibilityHitTest(point); |
| 1448 } | 1450 } |
| 1449 | 1451 |
| 1450 // | 1452 // |
| 1451 // High-level accessibility tree access. | 1453 // High-level accessibility tree access. |
| 1452 // | 1454 // |
| 1453 | 1455 |
| 1454 AXObject* AXLayoutObject::ComputeParent() const { | 1456 AXObjectImpl* AXLayoutObject::ComputeParent() const { |
| 1455 DCHECK(!IsDetached()); | 1457 DCHECK(!IsDetached()); |
| 1456 if (!layout_object_) | 1458 if (!layout_object_) |
| 1457 return 0; | 1459 return 0; |
| 1458 | 1460 |
| 1459 if (AriaRoleAttribute() == kMenuBarRole) | 1461 if (AriaRoleAttribute() == kMenuBarRole) |
| 1460 return AxObjectCache().GetOrCreate(layout_object_->Parent()); | 1462 return AxObjectCache().GetOrCreate(layout_object_->Parent()); |
| 1461 | 1463 |
| 1462 // menuButton and its corresponding menu are DOM siblings, but Accessibility | 1464 // menuButton and its corresponding menu are DOM siblings, but Accessibility |
| 1463 // needs them to be parent/child. | 1465 // needs them to be parent/child. |
| 1464 if (AriaRoleAttribute() == kMenuRole) { | 1466 if (AriaRoleAttribute() == kMenuRole) { |
| 1465 AXObject* parent = MenuButtonForMenu(); | 1467 AXObjectImpl* parent = MenuButtonForMenu(); |
| 1466 if (parent) | 1468 if (parent) |
| 1467 return parent; | 1469 return parent; |
| 1468 } | 1470 } |
| 1469 | 1471 |
| 1470 LayoutObject* parent_obj = LayoutParentObject(); | 1472 LayoutObject* parent_obj = LayoutParentObject(); |
| 1471 if (parent_obj) | 1473 if (parent_obj) |
| 1472 return AxObjectCache().GetOrCreate(parent_obj); | 1474 return AxObjectCache().GetOrCreate(parent_obj); |
| 1473 | 1475 |
| 1474 // A WebArea's parent should be the page popup owner, if any, otherwise null. | 1476 // A WebArea's parent should be the page popup owner, if any, otherwise null. |
| 1475 if (IsWebArea()) { | 1477 if (IsWebArea()) { |
| 1476 LocalFrame* frame = layout_object_->GetFrame(); | 1478 LocalFrame* frame = layout_object_->GetFrame(); |
| 1477 return AxObjectCache().GetOrCreate(frame->PagePopupOwner()); | 1479 return AxObjectCache().GetOrCreate(frame->PagePopupOwner()); |
| 1478 } | 1480 } |
| 1479 | 1481 |
| 1480 return 0; | 1482 return 0; |
| 1481 } | 1483 } |
| 1482 | 1484 |
| 1483 AXObject* AXLayoutObject::ComputeParentIfExists() const { | 1485 AXObjectImpl* AXLayoutObject::ComputeParentIfExists() const { |
| 1484 if (!layout_object_) | 1486 if (!layout_object_) |
| 1485 return 0; | 1487 return 0; |
| 1486 | 1488 |
| 1487 if (AriaRoleAttribute() == kMenuBarRole) | 1489 if (AriaRoleAttribute() == kMenuBarRole) |
| 1488 return AxObjectCache().Get(layout_object_->Parent()); | 1490 return AxObjectCache().Get(layout_object_->Parent()); |
| 1489 | 1491 |
| 1490 // menuButton and its corresponding menu are DOM siblings, but Accessibility | 1492 // menuButton and its corresponding menu are DOM siblings, but Accessibility |
| 1491 // needs them to be parent/child. | 1493 // needs them to be parent/child. |
| 1492 if (AriaRoleAttribute() == kMenuRole) { | 1494 if (AriaRoleAttribute() == kMenuRole) { |
| 1493 AXObject* parent = MenuButtonForMenu(); | 1495 AXObjectImpl* parent = MenuButtonForMenu(); |
| 1494 if (parent) | 1496 if (parent) |
| 1495 return parent; | 1497 return parent; |
| 1496 } | 1498 } |
| 1497 | 1499 |
| 1498 LayoutObject* parent_obj = LayoutParentObject(); | 1500 LayoutObject* parent_obj = LayoutParentObject(); |
| 1499 if (parent_obj) | 1501 if (parent_obj) |
| 1500 return AxObjectCache().Get(parent_obj); | 1502 return AxObjectCache().Get(parent_obj); |
| 1501 | 1503 |
| 1502 // A WebArea's parent should be the page popup owner, if any, otherwise null. | 1504 // A WebArea's parent should be the page popup owner, if any, otherwise null. |
| 1503 if (IsWebArea()) { | 1505 if (IsWebArea()) { |
| 1504 LocalFrame* frame = layout_object_->GetFrame(); | 1506 LocalFrame* frame = layout_object_->GetFrame(); |
| 1505 return AxObjectCache().Get(frame->PagePopupOwner()); | 1507 return AxObjectCache().Get(frame->PagePopupOwner()); |
| 1506 } | 1508 } |
| 1507 | 1509 |
| 1508 return 0; | 1510 return 0; |
| 1509 } | 1511 } |
| 1510 | 1512 |
| 1511 // | 1513 // |
| 1512 // Low-level accessibility tree exploration, only for use within the | 1514 // Low-level accessibility tree exploration, only for use within the |
| 1513 // accessibility module. | 1515 // accessibility module. |
| 1514 // | 1516 // |
| 1515 | 1517 |
| 1516 AXObject* AXLayoutObject::RawFirstChild() const { | 1518 AXObjectImpl* AXLayoutObject::RawFirstChild() const { |
| 1517 if (!layout_object_) | 1519 if (!layout_object_) |
| 1518 return 0; | 1520 return 0; |
| 1519 | 1521 |
| 1520 LayoutObject* first_child = FirstChildConsideringContinuation(layout_object_); | 1522 LayoutObject* first_child = FirstChildConsideringContinuation(layout_object_); |
| 1521 | 1523 |
| 1522 if (!first_child) | 1524 if (!first_child) |
| 1523 return 0; | 1525 return 0; |
| 1524 | 1526 |
| 1525 return AxObjectCache().GetOrCreate(first_child); | 1527 return AxObjectCache().GetOrCreate(first_child); |
| 1526 } | 1528 } |
| 1527 | 1529 |
| 1528 AXObject* AXLayoutObject::RawNextSibling() const { | 1530 AXObjectImpl* AXLayoutObject::RawNextSibling() const { |
| 1529 if (!layout_object_) | 1531 if (!layout_object_) |
| 1530 return 0; | 1532 return 0; |
| 1531 | 1533 |
| 1532 LayoutObject* next_sibling = 0; | 1534 LayoutObject* next_sibling = 0; |
| 1533 | 1535 |
| 1534 LayoutInline* inline_continuation = | 1536 LayoutInline* inline_continuation = |
| 1535 layout_object_->IsLayoutBlockFlow() | 1537 layout_object_->IsLayoutBlockFlow() |
| 1536 ? ToLayoutBlockFlow(layout_object_)->InlineElementContinuation() | 1538 ? ToLayoutBlockFlow(layout_object_)->InlineElementContinuation() |
| 1537 : nullptr; | 1539 : nullptr; |
| 1538 if (inline_continuation) { | 1540 if (inline_continuation) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1586 // If the need to add more children in addition to existing children arises, | 1588 // If the need to add more children in addition to existing children arises, |
| 1587 // childrenChanged should have been called, leaving the object with no | 1589 // childrenChanged should have been called, leaving the object with no |
| 1588 // children. | 1590 // children. |
| 1589 DCHECK(!have_children_); | 1591 DCHECK(!have_children_); |
| 1590 | 1592 |
| 1591 have_children_ = true; | 1593 have_children_ = true; |
| 1592 | 1594 |
| 1593 if (!CanHaveChildren()) | 1595 if (!CanHaveChildren()) |
| 1594 return; | 1596 return; |
| 1595 | 1597 |
| 1596 HeapVector<Member<AXObject>> owned_children; | 1598 HeapVector<Member<AXObjectImpl>> owned_children; |
| 1597 ComputeAriaOwnsChildren(owned_children); | 1599 ComputeAriaOwnsChildren(owned_children); |
| 1598 | 1600 |
| 1599 for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) { | 1601 for (AXObjectImpl* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) { |
| 1600 if (!AxObjectCache().IsAriaOwned(obj)) { | 1602 if (!AxObjectCache().IsAriaOwned(obj)) { |
| 1601 obj->SetParent(this); | 1603 obj->SetParent(this); |
| 1602 AddChild(obj); | 1604 AddChild(obj); |
| 1603 } | 1605 } |
| 1604 } | 1606 } |
| 1605 | 1607 |
| 1606 AddHiddenChildren(); | 1608 AddHiddenChildren(); |
| 1607 AddPopupChildren(); | 1609 AddPopupChildren(); |
| 1608 AddImageMapChildren(); | 1610 AddImageMapChildren(); |
| 1609 AddTextFieldChildren(); | 1611 AddTextFieldChildren(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1624 if (!layout_object_) | 1626 if (!layout_object_) |
| 1625 return false; | 1627 return false; |
| 1626 | 1628 |
| 1627 return AXNodeObject::CanHaveChildren(); | 1629 return AXNodeObject::CanHaveChildren(); |
| 1628 } | 1630 } |
| 1629 | 1631 |
| 1630 void AXLayoutObject::UpdateChildrenIfNecessary() { | 1632 void AXLayoutObject::UpdateChildrenIfNecessary() { |
| 1631 if (NeedsToUpdateChildren()) | 1633 if (NeedsToUpdateChildren()) |
| 1632 ClearChildren(); | 1634 ClearChildren(); |
| 1633 | 1635 |
| 1634 AXObject::UpdateChildrenIfNecessary(); | 1636 AXObjectImpl::UpdateChildrenIfNecessary(); |
| 1635 } | 1637 } |
| 1636 | 1638 |
| 1637 void AXLayoutObject::ClearChildren() { | 1639 void AXLayoutObject::ClearChildren() { |
| 1638 AXObject::ClearChildren(); | 1640 AXObjectImpl::ClearChildren(); |
| 1639 children_dirty_ = false; | 1641 children_dirty_ = false; |
| 1640 } | 1642 } |
| 1641 | 1643 |
| 1642 // | 1644 // |
| 1643 // Properties of the object's owning document or page. | 1645 // Properties of the object's owning document or page. |
| 1644 // | 1646 // |
| 1645 | 1647 |
| 1646 double AXLayoutObject::EstimatedLoadingProgress() const { | 1648 double AXLayoutObject::EstimatedLoadingProgress() const { |
| 1647 if (!layout_object_) | 1649 if (!layout_object_) |
| 1648 return 0; | 1650 return 0; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1715 return ToElement(&runner); | 1717 return ToElement(&runner); |
| 1716 } | 1718 } |
| 1717 | 1719 |
| 1718 return 0; | 1720 return 0; |
| 1719 } | 1721 } |
| 1720 | 1722 |
| 1721 // | 1723 // |
| 1722 // Functions that retrieve the current selection. | 1724 // Functions that retrieve the current selection. |
| 1723 // | 1725 // |
| 1724 | 1726 |
| 1725 AXObject::AXRange AXLayoutObject::Selection() const { | 1727 AXObjectImpl::AXRange AXLayoutObject::Selection() const { |
| 1726 AXRange text_selection = TextControlSelection(); | 1728 AXRange text_selection = TextControlSelection(); |
| 1727 if (text_selection.IsValid()) | 1729 if (text_selection.IsValid()) |
| 1728 return text_selection; | 1730 return text_selection; |
| 1729 | 1731 |
| 1730 if (!GetLayoutObject() || !GetLayoutObject()->GetFrame()) | 1732 if (!GetLayoutObject() || !GetLayoutObject()->GetFrame()) |
| 1731 return AXRange(); | 1733 return AXRange(); |
| 1732 | 1734 |
| 1733 VisibleSelection selection = | 1735 VisibleSelection selection = |
| 1734 GetLayoutObject() | 1736 GetLayoutObject() |
| 1735 ->GetFrame() | 1737 ->GetFrame() |
| 1736 ->Selection() | 1738 ->Selection() |
| 1737 .ComputeVisibleSelectionInDOMTreeDeprecated(); | 1739 .ComputeVisibleSelectionInDOMTreeDeprecated(); |
| 1738 if (selection.IsNone()) | 1740 if (selection.IsNone()) |
| 1739 return AXRange(); | 1741 return AXRange(); |
| 1740 | 1742 |
| 1741 VisiblePosition visible_start = selection.VisibleStart(); | 1743 VisiblePosition visible_start = selection.VisibleStart(); |
| 1742 Position start = visible_start.ToParentAnchoredPosition(); | 1744 Position start = visible_start.ToParentAnchoredPosition(); |
| 1743 TextAffinity start_affinity = visible_start.Affinity(); | 1745 TextAffinity start_affinity = visible_start.Affinity(); |
| 1744 VisiblePosition visible_end = selection.VisibleEnd(); | 1746 VisiblePosition visible_end = selection.VisibleEnd(); |
| 1745 Position end = visible_end.ToParentAnchoredPosition(); | 1747 Position end = visible_end.ToParentAnchoredPosition(); |
| 1746 TextAffinity end_affinity = visible_end.Affinity(); | 1748 TextAffinity end_affinity = visible_end.Affinity(); |
| 1747 | 1749 |
| 1748 Node* anchor_node = start.AnchorNode(); | 1750 Node* anchor_node = start.AnchorNode(); |
| 1749 DCHECK(anchor_node); | 1751 DCHECK(anchor_node); |
| 1750 | 1752 |
| 1751 AXLayoutObject* anchor_object = nullptr; | 1753 AXLayoutObject* anchor_object = nullptr; |
| 1752 // Find the closest node that has a corresponding AXObject. | 1754 // Find the closest node that has a corresponding AXObjectImpl. |
| 1753 // This is because some nodes may be aria hidden or might not even have | 1755 // This is because some nodes may be aria hidden or might not even have |
| 1754 // a layout object if they are part of the shadow DOM. | 1756 // a layout object if they are part of the shadow DOM. |
| 1755 while (anchor_node) { | 1757 while (anchor_node) { |
| 1756 anchor_object = GetUnignoredObjectFromNode(*anchor_node); | 1758 anchor_object = GetUnignoredObjectFromNode(*anchor_node); |
| 1757 if (anchor_object) | 1759 if (anchor_object) |
| 1758 break; | 1760 break; |
| 1759 | 1761 |
| 1760 if (anchor_node->nextSibling()) | 1762 if (anchor_node->nextSibling()) |
| 1761 anchor_node = anchor_node->nextSibling(); | 1763 anchor_node = anchor_node->nextSibling(); |
| 1762 else | 1764 else |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1785 DCHECK_GE(anchor_offset, 0); | 1787 DCHECK_GE(anchor_offset, 0); |
| 1786 int focus_offset = focus_object->IndexForVisiblePosition(visible_end); | 1788 int focus_offset = focus_object->IndexForVisiblePosition(visible_end); |
| 1787 DCHECK_GE(focus_offset, 0); | 1789 DCHECK_GE(focus_offset, 0); |
| 1788 return AXRange(anchor_object, anchor_offset, start_affinity, focus_object, | 1790 return AXRange(anchor_object, anchor_offset, start_affinity, focus_object, |
| 1789 focus_offset, end_affinity); | 1791 focus_offset, end_affinity); |
| 1790 } | 1792 } |
| 1791 | 1793 |
| 1792 // Gets only the start and end offsets of the selection computed using the | 1794 // Gets only the start and end offsets of the selection computed using the |
| 1793 // current object as the starting point. Returns a null selection if there is | 1795 // current object as the starting point. Returns a null selection if there is |
| 1794 // no selection in the subtree rooted at this object. | 1796 // no selection in the subtree rooted at this object. |
| 1795 AXObject::AXRange AXLayoutObject::SelectionUnderObject() const { | 1797 AXObjectImpl::AXRange AXLayoutObject::SelectionUnderObject() const { |
| 1796 AXRange text_selection = TextControlSelection(); | 1798 AXRange text_selection = TextControlSelection(); |
| 1797 if (text_selection.IsValid()) | 1799 if (text_selection.IsValid()) |
| 1798 return text_selection; | 1800 return text_selection; |
| 1799 | 1801 |
| 1800 if (!GetNode() || !GetLayoutObject()->GetFrame()) | 1802 if (!GetNode() || !GetLayoutObject()->GetFrame()) |
| 1801 return AXRange(); | 1803 return AXRange(); |
| 1802 | 1804 |
| 1803 VisibleSelection selection = | 1805 VisibleSelection selection = |
| 1804 GetLayoutObject() | 1806 GetLayoutObject() |
| 1805 ->GetFrame() | 1807 ->GetFrame() |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1819 } | 1821 } |
| 1820 | 1822 |
| 1821 int start = IndexForVisiblePosition(selection.VisibleStart()); | 1823 int start = IndexForVisiblePosition(selection.VisibleStart()); |
| 1822 DCHECK_GE(start, 0); | 1824 DCHECK_GE(start, 0); |
| 1823 int end = IndexForVisiblePosition(selection.VisibleEnd()); | 1825 int end = IndexForVisiblePosition(selection.VisibleEnd()); |
| 1824 DCHECK_GE(end, 0); | 1826 DCHECK_GE(end, 0); |
| 1825 | 1827 |
| 1826 return AXRange(start, end); | 1828 return AXRange(start, end); |
| 1827 } | 1829 } |
| 1828 | 1830 |
| 1829 AXObject::AXRange AXLayoutObject::TextControlSelection() const { | 1831 AXObjectImpl::AXRange AXLayoutObject::TextControlSelection() const { |
| 1830 if (!GetLayoutObject()) | 1832 if (!GetLayoutObject()) |
| 1831 return AXRange(); | 1833 return AXRange(); |
| 1832 | 1834 |
| 1833 LayoutObject* layout = nullptr; | 1835 LayoutObject* layout = nullptr; |
| 1834 if (GetLayoutObject()->IsTextControl()) { | 1836 if (GetLayoutObject()->IsTextControl()) { |
| 1835 layout = GetLayoutObject(); | 1837 layout = GetLayoutObject(); |
| 1836 } else { | 1838 } else { |
| 1837 Element* focused_element = GetDocument()->FocusedElement(); | 1839 Element* focused_element = GetDocument()->FocusedElement(); |
| 1838 if (focused_element && focused_element->GetLayoutObject() && | 1840 if (focused_element && focused_element->GetLayoutObject() && |
| 1839 focused_element->GetLayoutObject()->IsTextControl()) | 1841 focused_element->GetLayoutObject()->IsTextControl()) |
| 1840 layout = focused_element->GetLayoutObject(); | 1842 layout = focused_element->GetLayoutObject(); |
| 1841 } | 1843 } |
| 1842 | 1844 |
| 1843 if (!layout) | 1845 if (!layout) |
| 1844 return AXRange(); | 1846 return AXRange(); |
| 1845 | 1847 |
| 1846 AXObject* ax_object = AxObjectCache().GetOrCreate(layout); | 1848 AXObjectImpl* ax_object = AxObjectCache().GetOrCreate(layout); |
| 1847 if (!ax_object || !ax_object->IsAXLayoutObject()) | 1849 if (!ax_object || !ax_object->IsAXLayoutObject()) |
| 1848 return AXRange(); | 1850 return AXRange(); |
| 1849 | 1851 |
| 1850 VisibleSelection selection = | 1852 VisibleSelection selection = |
| 1851 layout->GetFrame() | 1853 layout->GetFrame() |
| 1852 ->Selection() | 1854 ->Selection() |
| 1853 .ComputeVisibleSelectionInDOMTreeDeprecated(); | 1855 .ComputeVisibleSelectionInDOMTreeDeprecated(); |
| 1854 TextControlElement* text_control = | 1856 TextControlElement* text_control = |
| 1855 ToLayoutTextControl(layout)->GetTextControlElement(); | 1857 ToLayoutTextControl(layout)->GetTextControlElement(); |
| 1856 DCHECK(text_control); | 1858 DCHECK(text_control); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1881 range->setEnd(index_position, IGNORE_EXCEPTION_FOR_TESTING); | 1883 range->setEnd(index_position, IGNORE_EXCEPTION_FOR_TESTING); |
| 1882 | 1884 |
| 1883 return TextIterator::RangeLength(range->StartPosition(), | 1885 return TextIterator::RangeLength(range->StartPosition(), |
| 1884 range->EndPosition()); | 1886 range->EndPosition()); |
| 1885 } | 1887 } |
| 1886 | 1888 |
| 1887 AXLayoutObject* AXLayoutObject::GetUnignoredObjectFromNode(Node& node) const { | 1889 AXLayoutObject* AXLayoutObject::GetUnignoredObjectFromNode(Node& node) const { |
| 1888 if (IsDetached()) | 1890 if (IsDetached()) |
| 1889 return nullptr; | 1891 return nullptr; |
| 1890 | 1892 |
| 1891 AXObject* ax_object = AxObjectCache().GetOrCreate(&node); | 1893 AXObjectImpl* ax_object = AxObjectCache().GetOrCreate(&node); |
| 1892 if (!ax_object) | 1894 if (!ax_object) |
| 1893 return nullptr; | 1895 return nullptr; |
| 1894 | 1896 |
| 1895 if (ax_object->IsAXLayoutObject() && !ax_object->AccessibilityIsIgnored()) | 1897 if (ax_object->IsAXLayoutObject() && !ax_object->AccessibilityIsIgnored()) |
| 1896 return ToAXLayoutObject(ax_object); | 1898 return ToAXLayoutObject(ax_object); |
| 1897 | 1899 |
| 1898 return nullptr; | 1900 return nullptr; |
| 1899 } | 1901 } |
| 1900 | 1902 |
| 1901 // | 1903 // |
| 1902 // Modify or take an action on an object. | 1904 // Modify or take an action on an object. |
| 1903 // | 1905 // |
| 1904 | 1906 |
| 1905 // Convert from an accessible object and offset to a VisiblePosition. | 1907 // Convert from an accessible object and offset to a VisiblePosition. |
| 1906 static VisiblePosition ToVisiblePosition(AXObject* obj, int offset) { | 1908 static VisiblePosition ToVisiblePosition(AXObjectImpl* obj, int offset) { |
| 1907 if (!obj->GetNode()) | 1909 if (!obj->GetNode()) |
| 1908 return VisiblePosition(); | 1910 return VisiblePosition(); |
| 1909 | 1911 |
| 1910 Node* node = obj->GetNode(); | 1912 Node* node = obj->GetNode(); |
| 1911 if (!node->IsTextNode()) { | 1913 if (!node->IsTextNode()) { |
| 1912 int child_count = obj->Children().size(); | 1914 int child_count = obj->Children().size(); |
| 1913 | 1915 |
| 1914 // Place position immediately before the container node, if there was no | 1916 // Place position immediately before the container node, if there was no |
| 1915 // children. | 1917 // children. |
| 1916 if (child_count == 0) { | 1918 if (child_count == 0) { |
| 1917 if (!obj->ParentObject()) | 1919 if (!obj->ParentObject()) |
| 1918 return VisiblePosition(); | 1920 return VisiblePosition(); |
| 1919 return ToVisiblePosition(obj->ParentObject(), obj->IndexInParent()); | 1921 return ToVisiblePosition(obj->ParentObject(), obj->IndexInParent()); |
| 1920 } | 1922 } |
| 1921 | 1923 |
| 1922 // The offsets are child offsets over the AX tree. Note that we allow | 1924 // The offsets are child offsets over the AX tree. Note that we allow |
| 1923 // for the offset to equal the number of children as |Range| does. | 1925 // for the offset to equal the number of children as |Range| does. |
| 1924 if (offset < 0 || offset > child_count) | 1926 if (offset < 0 || offset > child_count) |
| 1925 return VisiblePosition(); | 1927 return VisiblePosition(); |
| 1926 | 1928 |
| 1927 // Clamp to between 0 and child count - 1. | 1929 // Clamp to between 0 and child count - 1. |
| 1928 int clamped_offset = | 1930 int clamped_offset = |
| 1929 static_cast<unsigned>(offset) > (obj->Children().size() - 1) | 1931 static_cast<unsigned>(offset) > (obj->Children().size() - 1) |
| 1930 ? offset - 1 | 1932 ? offset - 1 |
| 1931 : offset; | 1933 : offset; |
| 1932 AXObject* child_obj = obj->Children()[clamped_offset]; | 1934 AXObjectImpl* child_obj = obj->Children()[clamped_offset]; |
| 1933 Node* child_node = child_obj->GetNode(); | 1935 Node* child_node = child_obj->GetNode(); |
| 1934 if (!child_node || !child_node->parentNode()) | 1936 if (!child_node || !child_node->parentNode()) |
| 1935 return VisiblePosition(); | 1937 return VisiblePosition(); |
| 1936 | 1938 |
| 1937 // The index in parent. | 1939 // The index in parent. |
| 1938 int adjusted_offset = child_node->NodeIndex(); | 1940 int adjusted_offset = child_node->NodeIndex(); |
| 1939 | 1941 |
| 1940 // If we had to clamp the offset above, the client wants to select the | 1942 // If we had to clamp the offset above, the client wants to select the |
| 1941 // end of the node. | 1943 // end of the node. |
| 1942 if (clamped_offset != offset) | 1944 if (clamped_offset != offset) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1955 | 1957 |
| 1956 VisiblePosition node_position = blink::VisiblePositionBeforeNode(*node); | 1958 VisiblePosition node_position = blink::VisiblePositionBeforeNode(*node); |
| 1957 int node_index = blink::IndexForVisiblePosition(node_position, parent); | 1959 int node_index = blink::IndexForVisiblePosition(node_position, parent); |
| 1958 return blink::VisiblePositionForIndex(node_index + offset, parent); | 1960 return blink::VisiblePositionForIndex(node_index + offset, parent); |
| 1959 } | 1961 } |
| 1960 | 1962 |
| 1961 void AXLayoutObject::SetSelection(const AXRange& selection) { | 1963 void AXLayoutObject::SetSelection(const AXRange& selection) { |
| 1962 if (!GetLayoutObject() || !selection.IsValid()) | 1964 if (!GetLayoutObject() || !selection.IsValid()) |
| 1963 return; | 1965 return; |
| 1964 | 1966 |
| 1965 AXObject* anchor_object = | 1967 AXObjectImpl* anchor_object = |
| 1966 selection.anchor_object ? selection.anchor_object.Get() : this; | 1968 selection.anchor_object ? selection.anchor_object.Get() : this; |
| 1967 AXObject* focus_object = | 1969 AXObjectImpl* focus_object = |
| 1968 selection.focus_object ? selection.focus_object.Get() : this; | 1970 selection.focus_object ? selection.focus_object.Get() : this; |
| 1969 | 1971 |
| 1970 if (!IsValidSelectionBound(anchor_object) || | 1972 if (!IsValidSelectionBound(anchor_object) || |
| 1971 !IsValidSelectionBound(focus_object)) { | 1973 !IsValidSelectionBound(focus_object)) { |
| 1972 return; | 1974 return; |
| 1973 } | 1975 } |
| 1974 | 1976 |
| 1975 // The selection offsets are offsets into the accessible value. | 1977 // The selection offsets are offsets into the accessible value. |
| 1976 if (anchor_object == focus_object && | 1978 if (anchor_object == focus_object && |
| 1977 anchor_object->GetLayoutObject()->IsTextControl()) { | 1979 anchor_object->GetLayoutObject()->IsTextControl()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2009 if (anchor_visible_position.IsNull() || focus_visible_position.IsNull()) | 2011 if (anchor_visible_position.IsNull() || focus_visible_position.IsNull()) |
| 2010 return; | 2012 return; |
| 2011 | 2013 |
| 2012 frame->Selection().SetSelection( | 2014 frame->Selection().SetSelection( |
| 2013 SelectionInDOMTree::Builder() | 2015 SelectionInDOMTree::Builder() |
| 2014 .Collapse(anchor_visible_position.ToPositionWithAffinity()) | 2016 .Collapse(anchor_visible_position.ToPositionWithAffinity()) |
| 2015 .Extend(focus_visible_position.DeepEquivalent()) | 2017 .Extend(focus_visible_position.DeepEquivalent()) |
| 2016 .Build()); | 2018 .Build()); |
| 2017 } | 2019 } |
| 2018 | 2020 |
| 2019 bool AXLayoutObject::IsValidSelectionBound(const AXObject* bound_object) const { | 2021 bool AXLayoutObject::IsValidSelectionBound( |
| 2022 const AXObjectImpl* bound_object) const { | |
| 2020 return GetLayoutObject() && bound_object && !bound_object->IsDetached() && | 2023 return GetLayoutObject() && bound_object && !bound_object->IsDetached() && |
| 2021 bound_object->IsAXLayoutObject() && bound_object->GetLayoutObject() && | 2024 bound_object->IsAXLayoutObject() && bound_object->GetLayoutObject() && |
| 2022 bound_object->GetLayoutObject()->GetFrame() == | 2025 bound_object->GetLayoutObject()->GetFrame() == |
| 2023 GetLayoutObject()->GetFrame() && | 2026 GetLayoutObject()->GetFrame() && |
| 2024 &bound_object->AxObjectCache() == &AxObjectCache(); | 2027 &bound_object->AxObjectCache() == &AxObjectCache(); |
| 2025 } | 2028 } |
| 2026 | 2029 |
| 2027 void AXLayoutObject::SetValue(const String& string) { | 2030 void AXLayoutObject::SetValue(const String& string) { |
| 2028 if (!GetNode() || !GetNode()->IsElementNode()) | 2031 if (!GetNode() || !GetNode()->IsElementNode()) |
| 2029 return; | 2032 return; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2040 } | 2043 } |
| 2041 | 2044 |
| 2042 // | 2045 // |
| 2043 // Notifications that this object may have changed. | 2046 // Notifications that this object may have changed. |
| 2044 // | 2047 // |
| 2045 | 2048 |
| 2046 void AXLayoutObject::HandleActiveDescendantChanged() { | 2049 void AXLayoutObject::HandleActiveDescendantChanged() { |
| 2047 if (!GetLayoutObject()) | 2050 if (!GetLayoutObject()) |
| 2048 return; | 2051 return; |
| 2049 | 2052 |
| 2050 AXObject* focused_object = AxObjectCache().FocusedObject(); | 2053 AXObjectImpl* focused_object = AxObjectCache().FocusedObject(); |
| 2051 if (focused_object == this && SupportsActiveDescendant()) { | 2054 if (focused_object == this && SupportsActiveDescendant()) { |
| 2052 AxObjectCache().PostNotification( | 2055 AxObjectCache().PostNotification( |
| 2053 GetLayoutObject(), AXObjectCacheImpl::kAXActiveDescendantChanged); | 2056 GetLayoutObject(), AXObjectCacheImpl::kAXActiveDescendantChanged); |
| 2054 } | 2057 } |
| 2055 } | 2058 } |
| 2056 | 2059 |
| 2057 void AXLayoutObject::HandleAriaExpandedChanged() { | 2060 void AXLayoutObject::HandleAriaExpandedChanged() { |
| 2058 // Find if a parent of this object should handle aria-expanded changes. | 2061 // Find if a parent of this object should handle aria-expanded changes. |
| 2059 AXObject* container_parent = this->ParentObject(); | 2062 AXObjectImpl* container_parent = this->ParentObject(); |
| 2060 while (container_parent) { | 2063 while (container_parent) { |
| 2061 bool found_parent = false; | 2064 bool found_parent = false; |
| 2062 | 2065 |
| 2063 switch (container_parent->RoleValue()) { | 2066 switch (container_parent->RoleValue()) { |
| 2064 case kTreeRole: | 2067 case kTreeRole: |
| 2065 case kTreeGridRole: | 2068 case kTreeGridRole: |
| 2066 case kGridRole: | 2069 case kGridRole: |
| 2067 case kTableRole: | 2070 case kTableRole: |
| 2068 found_parent = true; | 2071 found_parent = true; |
| 2069 break; | 2072 break; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2169 // If a LayoutText needs layout, its inline text boxes are either | 2172 // If a LayoutText needs layout, its inline text boxes are either |
| 2170 // nonexistent or invalid, so defer until the layout happens and | 2173 // nonexistent or invalid, so defer until the layout happens and |
| 2171 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. | 2174 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. |
| 2172 return; | 2175 return; |
| 2173 } | 2176 } |
| 2174 | 2177 |
| 2175 LayoutText* layout_text = ToLayoutText(GetLayoutObject()); | 2178 LayoutText* layout_text = ToLayoutText(GetLayoutObject()); |
| 2176 for (RefPtr<AbstractInlineTextBox> box = | 2179 for (RefPtr<AbstractInlineTextBox> box = |
| 2177 layout_text->FirstAbstractInlineTextBox(); | 2180 layout_text->FirstAbstractInlineTextBox(); |
| 2178 box.Get(); box = box->NextInlineTextBox()) { | 2181 box.Get(); box = box->NextInlineTextBox()) { |
| 2179 AXObject* ax_object = AxObjectCache().GetOrCreate(box.Get()); | 2182 AXObjectImpl* ax_object = AxObjectCache().GetOrCreate(box.Get()); |
| 2180 if (!ax_object->AccessibilityIsIgnored()) | 2183 if (!ax_object->AccessibilityIsIgnored()) |
| 2181 children_.push_back(ax_object); | 2184 children_.push_back(ax_object); |
| 2182 } | 2185 } |
| 2183 } | 2186 } |
| 2184 | 2187 |
| 2185 void AXLayoutObject::LineBreaks(Vector<int>& line_breaks) const { | 2188 void AXLayoutObject::LineBreaks(Vector<int>& line_breaks) const { |
| 2186 if (!IsTextControl()) | 2189 if (!IsTextControl()) |
| 2187 return; | 2190 return; |
| 2188 | 2191 |
| 2189 VisiblePosition visible_pos = VisiblePositionForIndex(0); | 2192 VisiblePosition visible_pos = VisiblePositionForIndex(0); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2202 if (visible_pos.DeepEquivalent().CompareTo( | 2205 if (visible_pos.DeepEquivalent().CompareTo( |
| 2203 prev_visible_pos.DeepEquivalent()) < 0) | 2206 prev_visible_pos.DeepEquivalent()) < 0) |
| 2204 break; | 2207 break; |
| 2205 } | 2208 } |
| 2206 } | 2209 } |
| 2207 | 2210 |
| 2208 // | 2211 // |
| 2209 // Private. | 2212 // Private. |
| 2210 // | 2213 // |
| 2211 | 2214 |
| 2212 AXObject* AXLayoutObject::TreeAncestorDisallowingChild() const { | 2215 AXObjectImpl* AXLayoutObject::TreeAncestorDisallowingChild() const { |
| 2213 // Determine if this is in a tree. If so, we apply special behavior to make it | 2216 // Determine if this is in a tree. If so, we apply special behavior to make it |
| 2214 // work like an AXOutline. | 2217 // work like an AXOutline. |
| 2215 AXObject* ax_obj = ParentObject(); | 2218 AXObjectImpl* ax_obj = ParentObject(); |
| 2216 AXObject* tree_ancestor = 0; | 2219 AXObjectImpl* tree_ancestor = 0; |
| 2217 while (ax_obj) { | 2220 while (ax_obj) { |
| 2218 if (ax_obj->IsTree()) { | 2221 if (ax_obj->IsTree()) { |
| 2219 tree_ancestor = ax_obj; | 2222 tree_ancestor = ax_obj; |
| 2220 break; | 2223 break; |
| 2221 } | 2224 } |
| 2222 ax_obj = ax_obj->ParentObject(); | 2225 ax_obj = ax_obj->ParentObject(); |
| 2223 } | 2226 } |
| 2224 | 2227 |
| 2225 // If the object is in a tree, only tree items should be exposed (and the | 2228 // If the object is in a tree, only tree items should be exposed (and the |
| 2226 // children of tree items). | 2229 // children of tree items). |
| 2227 if (tree_ancestor) { | 2230 if (tree_ancestor) { |
| 2228 AccessibilityRole role = RoleValue(); | 2231 AccessibilityRole role = RoleValue(); |
| 2229 if (role != kTreeItemRole && role != kStaticTextRole) | 2232 if (role != kTreeItemRole && role != kStaticTextRole) |
| 2230 return tree_ancestor; | 2233 return tree_ancestor; |
| 2231 } | 2234 } |
| 2232 return 0; | 2235 return 0; |
| 2233 } | 2236 } |
| 2234 | 2237 |
| 2235 bool AXLayoutObject::IsTabItemSelected() const { | 2238 bool AXLayoutObject::IsTabItemSelected() const { |
| 2236 if (!IsTabItem() || !GetLayoutObject()) | 2239 if (!IsTabItem() || !GetLayoutObject()) |
| 2237 return false; | 2240 return false; |
| 2238 | 2241 |
| 2239 Node* node = GetNode(); | 2242 Node* node = GetNode(); |
| 2240 if (!node || !node->IsElementNode()) | 2243 if (!node || !node->IsElementNode()) |
| 2241 return false; | 2244 return false; |
| 2242 | 2245 |
| 2243 // The ARIA spec says a tab item can also be selected if it is aria-labeled by | 2246 // The ARIA spec says a tab item can also be selected if it is aria-labeled by |
| 2244 // a tabpanel that has keyboard focus inside of it, or if a tabpanel in its | 2247 // a tabpanel that has keyboard focus inside of it, or if a tabpanel in its |
| 2245 // aria-controls list has KB focus inside of it. | 2248 // aria-controls list has KB focus inside of it. |
| 2246 AXObject* focused_element = AxObjectCache().FocusedObject(); | 2249 AXObjectImpl* focused_element = AxObjectCache().FocusedObject(); |
| 2247 if (!focused_element) | 2250 if (!focused_element) |
| 2248 return false; | 2251 return false; |
| 2249 | 2252 |
| 2250 HeapVector<Member<Element>> elements; | 2253 HeapVector<Member<Element>> elements; |
| 2251 ElementsFromAttribute(elements, aria_controlsAttr); | 2254 ElementsFromAttribute(elements, aria_controlsAttr); |
| 2252 | 2255 |
| 2253 for (const auto& element : elements) { | 2256 for (const auto& element : elements) { |
| 2254 AXObject* tab_panel = AxObjectCache().GetOrCreate(element); | 2257 AXObjectImpl* tab_panel = AxObjectCache().GetOrCreate(element); |
| 2255 | 2258 |
| 2256 // A tab item should only control tab panels. | 2259 // A tab item should only control tab panels. |
| 2257 if (!tab_panel || tab_panel->RoleValue() != kTabPanelRole) | 2260 if (!tab_panel || tab_panel->RoleValue() != kTabPanelRole) |
| 2258 continue; | 2261 continue; |
| 2259 | 2262 |
| 2260 AXObject* check_focus_element = focused_element; | 2263 AXObjectImpl* check_focus_element = focused_element; |
| 2261 // Check if the focused element is a descendant of the element controlled by | 2264 // Check if the focused element is a descendant of the element controlled by |
| 2262 // the tab item. | 2265 // the tab item. |
| 2263 while (check_focus_element) { | 2266 while (check_focus_element) { |
| 2264 if (tab_panel == check_focus_element) | 2267 if (tab_panel == check_focus_element) |
| 2265 return true; | 2268 return true; |
| 2266 check_focus_element = check_focus_element->ParentObject(); | 2269 check_focus_element = check_focus_element->ParentObject(); |
| 2267 } | 2270 } |
| 2268 } | 2271 } |
| 2269 | 2272 |
| 2270 return false; | 2273 return false; |
| 2271 } | 2274 } |
| 2272 | 2275 |
| 2273 AXObject* AXLayoutObject::AccessibilityImageMapHitTest( | 2276 AXObjectImpl* AXLayoutObject::AccessibilityImageMapHitTest( |
| 2274 HTMLAreaElement* area, | 2277 HTMLAreaElement* area, |
| 2275 const IntPoint& point) const { | 2278 const IntPoint& point) const { |
| 2276 if (!area) | 2279 if (!area) |
| 2277 return 0; | 2280 return 0; |
| 2278 | 2281 |
| 2279 AXObject* parent = AxObjectCache().GetOrCreate(area->ImageElement()); | 2282 AXObjectImpl* parent = AxObjectCache().GetOrCreate(area->ImageElement()); |
| 2280 if (!parent) | 2283 if (!parent) |
| 2281 return 0; | 2284 return 0; |
| 2282 | 2285 |
| 2283 for (const auto& child : parent->Children()) { | 2286 for (const auto& child : parent->Children()) { |
| 2284 if (child->GetBoundsInFrameCoordinates().Contains(point)) | 2287 if (child->GetBoundsInFrameCoordinates().Contains(point)) |
| 2285 return child.Get(); | 2288 return child.Get(); |
| 2286 } | 2289 } |
| 2287 | 2290 |
| 2288 return 0; | 2291 return 0; |
| 2289 } | 2292 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2347 root->SetParent(0); | 2350 root->SetParent(0); |
| 2348 } | 2351 } |
| 2349 | 2352 |
| 2350 AXSVGRoot* AXLayoutObject::RemoteSVGRootElement() const { | 2353 AXSVGRoot* AXLayoutObject::RemoteSVGRootElement() const { |
| 2351 // FIXME(dmazzoni): none of this code properly handled multiple references to | 2354 // FIXME(dmazzoni): none of this code properly handled multiple references to |
| 2352 // the same remote SVG document. I'm disabling this support until it can be | 2355 // the same remote SVG document. I'm disabling this support until it can be |
| 2353 // fixed properly. | 2356 // fixed properly. |
| 2354 return 0; | 2357 return 0; |
| 2355 } | 2358 } |
| 2356 | 2359 |
| 2357 AXObject* AXLayoutObject::RemoteSVGElementHitTest(const IntPoint& point) const { | 2360 AXObjectImpl* AXLayoutObject::RemoteSVGElementHitTest( |
| 2358 AXObject* remote = RemoteSVGRootElement(); | 2361 const IntPoint& point) const { |
| 2362 AXObjectImpl* remote = RemoteSVGRootElement(); | |
| 2359 if (!remote) | 2363 if (!remote) |
| 2360 return 0; | 2364 return 0; |
| 2361 | 2365 |
| 2362 IntSize offset = | 2366 IntSize offset = |
| 2363 point - RoundedIntPoint(GetBoundsInFrameCoordinates().Location()); | 2367 point - RoundedIntPoint(GetBoundsInFrameCoordinates().Location()); |
| 2364 return remote->AccessibilityHitTest(IntPoint(offset)); | 2368 return remote->AccessibilityHitTest(IntPoint(offset)); |
| 2365 } | 2369 } |
| 2366 | 2370 |
| 2367 // The boundingBox for elements within the remote SVG element needs to be offset | 2371 // The boundingBox for elements within the remote SVG element needs to be offset |
| 2368 // by its position within the parent page, otherwise they are in relative | 2372 // by its position within the parent page, otherwise they are in relative |
| 2369 // coordinates only. | 2373 // coordinates only. |
| 2370 void AXLayoutObject::OffsetBoundingBoxForRemoteSVGElement( | 2374 void AXLayoutObject::OffsetBoundingBoxForRemoteSVGElement( |
| 2371 LayoutRect& rect) const { | 2375 LayoutRect& rect) const { |
| 2372 for (AXObject* parent = ParentObject(); parent; | 2376 for (AXObjectImpl* parent = ParentObject(); parent; |
| 2373 parent = parent->ParentObject()) { | 2377 parent = parent->ParentObject()) { |
| 2374 if (parent->IsAXSVGRoot()) { | 2378 if (parent->IsAXSVGRoot()) { |
| 2375 rect.MoveBy( | 2379 rect.MoveBy( |
| 2376 parent->ParentObject()->GetBoundsInFrameCoordinates().Location()); | 2380 parent->ParentObject()->GetBoundsInFrameCoordinates().Location()); |
| 2377 break; | 2381 break; |
| 2378 } | 2382 } |
| 2379 } | 2383 } |
| 2380 } | 2384 } |
| 2381 | 2385 |
| 2382 // Hidden children are those that are not laid out or visible, but are | 2386 // Hidden children are those that are not laid out or visible, but are |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2401 if (!should_insert_hidden_nodes) | 2405 if (!should_insert_hidden_nodes) |
| 2402 return; | 2406 return; |
| 2403 | 2407 |
| 2404 // Iterate through all of the children, including those that may have already | 2408 // Iterate through all of the children, including those that may have already |
| 2405 // been added, and try to insert hidden nodes in the correct place in the DOM | 2409 // been added, and try to insert hidden nodes in the correct place in the DOM |
| 2406 // order. | 2410 // order. |
| 2407 unsigned insertion_index = 0; | 2411 unsigned insertion_index = 0; |
| 2408 for (Node& child : NodeTraversal::ChildrenOf(*node)) { | 2412 for (Node& child : NodeTraversal::ChildrenOf(*node)) { |
| 2409 if (child.GetLayoutObject()) { | 2413 if (child.GetLayoutObject()) { |
| 2410 // Find out where the last layout sibling is located within m_children. | 2414 // Find out where the last layout sibling is located within m_children. |
| 2411 if (AXObject* child_object = | 2415 if (AXObjectImpl* child_object = |
| 2412 AxObjectCache().Get(child.GetLayoutObject())) { | 2416 AxObjectCache().Get(child.GetLayoutObject())) { |
| 2413 if (child_object->AccessibilityIsIgnored()) { | 2417 if (child_object->AccessibilityIsIgnored()) { |
| 2414 const auto& children = child_object->Children(); | 2418 const auto& children = child_object->Children(); |
| 2415 child_object = children.size() ? children.back().Get() : 0; | 2419 child_object = children.size() ? children.back().Get() : 0; |
| 2416 } | 2420 } |
| 2417 if (child_object) | 2421 if (child_object) |
| 2418 insertion_index = children_.Find(child_object) + 1; | 2422 insertion_index = children_.Find(child_object) + 1; |
| 2419 continue; | 2423 continue; |
| 2420 } | 2424 } |
| 2421 } | 2425 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2456 if (!css_box || !css_box->IsLayoutImage()) | 2460 if (!css_box || !css_box->IsLayoutImage()) |
| 2457 return; | 2461 return; |
| 2458 | 2462 |
| 2459 HTMLMapElement* map = ToLayoutImage(css_box)->ImageMap(); | 2463 HTMLMapElement* map = ToLayoutImage(css_box)->ImageMap(); |
| 2460 if (!map) | 2464 if (!map) |
| 2461 return; | 2465 return; |
| 2462 | 2466 |
| 2463 for (HTMLAreaElement& area : | 2467 for (HTMLAreaElement& area : |
| 2464 Traversal<HTMLAreaElement>::DescendantsOf(*map)) { | 2468 Traversal<HTMLAreaElement>::DescendantsOf(*map)) { |
| 2465 // add an <area> element for this child if it has a link | 2469 // add an <area> element for this child if it has a link |
| 2466 AXObject* obj = AxObjectCache().GetOrCreate(&area); | 2470 AXObjectImpl* obj = AxObjectCache().GetOrCreate(&area); |
| 2467 if (obj) { | 2471 if (obj) { |
| 2468 AXImageMapLink* area_object = ToAXImageMapLink(obj); | 2472 AXImageMapLink* area_object = ToAXImageMapLink(obj); |
| 2469 area_object->SetParent(this); | 2473 area_object->SetParent(this); |
| 2470 DCHECK(area_object->AxObjectID() != 0); | 2474 DCHECK(area_object->AxObjectID() != 0); |
| 2471 if (!area_object->AccessibilityIsIgnored()) | 2475 if (!area_object->AccessibilityIsIgnored()) |
| 2472 children_.push_back(area_object); | 2476 children_.push_back(area_object); |
| 2473 else | 2477 else |
| 2474 AxObjectCache().Remove(area_object->AxObjectID()); | 2478 AxObjectCache().Remove(area_object->AxObjectID()); |
| 2475 } | 2479 } |
| 2476 } | 2480 } |
| 2477 } | 2481 } |
| 2478 | 2482 |
| 2479 void AXLayoutObject::AddCanvasChildren() { | 2483 void AXLayoutObject::AddCanvasChildren() { |
| 2480 if (!isHTMLCanvasElement(GetNode())) | 2484 if (!isHTMLCanvasElement(GetNode())) |
| 2481 return; | 2485 return; |
| 2482 | 2486 |
| 2483 // If it's a canvas, it won't have laid out children, but it might have | 2487 // If it's a canvas, it won't have laid out children, but it might have |
| 2484 // accessible fallback content. Clear m_haveChildren because | 2488 // accessible fallback content. Clear m_haveChildren because |
| 2485 // AXNodeObject::addChildren will expect it to be false. | 2489 // AXNodeObject::addChildren will expect it to be false. |
| 2486 DCHECK(!children_.size()); | 2490 DCHECK(!children_.size()); |
| 2487 have_children_ = false; | 2491 have_children_ = false; |
| 2488 AXNodeObject::AddChildren(); | 2492 AXNodeObject::AddChildren(); |
| 2489 } | 2493 } |
| 2490 | 2494 |
| 2491 void AXLayoutObject::AddPopupChildren() { | 2495 void AXLayoutObject::AddPopupChildren() { |
| 2492 if (!isHTMLInputElement(GetNode())) | 2496 if (!isHTMLInputElement(GetNode())) |
| 2493 return; | 2497 return; |
| 2494 if (AXObject* ax_popup = toHTMLInputElement(GetNode())->PopupRootAXObject()) | 2498 if (AXObjectImpl* ax_popup = |
| 2499 ToAXObjectImpl(toHTMLInputElement(GetNode())->PopupRootAXObject())) | |
|
sashab
2017/05/08 23:58:34
Although this code is in modules/, it's using a pu
aboxhall
2017/05/09 02:01:02
This seems ok to me. Dominic, what do you think?
dmazzoni
2017/05/09 05:07:07
Yes, this seems fine. This is a reasonable use of
sashab
2017/05/10 04:24:43
Sgtm :)
| |
| 2495 children_.push_back(ax_popup); | 2500 children_.push_back(ax_popup); |
| 2496 } | 2501 } |
| 2497 | 2502 |
| 2498 void AXLayoutObject::AddRemoteSVGChildren() { | 2503 void AXLayoutObject::AddRemoteSVGChildren() { |
| 2499 AXSVGRoot* root = RemoteSVGRootElement(); | 2504 AXSVGRoot* root = RemoteSVGRootElement(); |
| 2500 if (!root) | 2505 if (!root) |
| 2501 return; | 2506 return; |
| 2502 | 2507 |
| 2503 root->SetParent(this); | 2508 root->SetParent(this); |
| 2504 | 2509 |
| 2505 if (root->AccessibilityIsIgnored()) { | 2510 if (root->AccessibilityIsIgnored()) { |
| 2506 for (const auto& child : root->Children()) | 2511 for (const auto& child : root->Children()) |
| 2507 children_.push_back(child); | 2512 children_.push_back(child); |
| 2508 } else { | 2513 } else { |
| 2509 children_.push_back(root); | 2514 children_.push_back(root); |
| 2510 } | 2515 } |
| 2511 } | 2516 } |
| 2512 | 2517 |
| 2513 bool AXLayoutObject::ElementAttributeValue( | 2518 bool AXLayoutObject::ElementAttributeValue( |
| 2514 const QualifiedName& attribute_name) const { | 2519 const QualifiedName& attribute_name) const { |
| 2515 if (!layout_object_) | 2520 if (!layout_object_) |
| 2516 return false; | 2521 return false; |
| 2517 | 2522 |
| 2518 return EqualIgnoringASCIICase(GetAttribute(attribute_name), "true"); | 2523 return EqualIgnoringASCIICase(GetAttribute(attribute_name), "true"); |
| 2519 } | 2524 } |
| 2520 | 2525 |
| 2521 } // namespace blink | 2526 } // namespace blink |
| OLD | NEW |