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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 cur = ToLayoutInline(cur)->InlineElementContinuation(); | 170 cur = ToLayoutInline(cur)->InlineElementContinuation(); |
171 DCHECK(cur || !ToLayoutInline(prev)->Continuation()); | 171 DCHECK(cur || !ToLayoutInline(prev)->Continuation()); |
172 } else { | 172 } else { |
173 cur = ToLayoutBlockFlow(cur)->InlineElementContinuation(); | 173 cur = ToLayoutBlockFlow(cur)->InlineElementContinuation(); |
174 } | 174 } |
175 } | 175 } |
176 | 176 |
177 return prev; | 177 return prev; |
178 } | 178 } |
179 | 179 |
180 static inline bool LastChildHasContinuation(LayoutObject* layout_object) { | 180 static inline bool LastChildHasContinuation(LayoutObject* layoutObject) { |
181 LayoutObject* last_child = layout_object->SlowLastChild(); | 181 LayoutObject* last_child = layoutObject->SlowLastChild(); |
182 return last_child && IsInlineWithContinuation(last_child); | 182 return last_child && IsInlineWithContinuation(last_child); |
183 } | 183 } |
184 | 184 |
185 static LayoutBoxModelObject* NextContinuation(LayoutObject* layout_object) { | 185 static LayoutBoxModelObject* NextContinuation(LayoutObject* layout_object) { |
186 DCHECK(layout_object); | 186 DCHECK(layout_object); |
187 if (layout_object->IsLayoutInline() && !layout_object->IsAtomicInlineLevel()) | 187 if (layout_object->IsLayoutInline() && !layout_object->IsAtomicInlineLevel()) |
188 return ToLayoutInline(layout_object)->Continuation(); | 188 return ToLayoutInline(layout_object)->Continuation(); |
189 if (layout_object->IsLayoutBlockFlow()) | 189 if (layout_object->IsLayoutBlockFlow()) |
190 return ToLayoutBlockFlow(layout_object)->InlineElementContinuation(); | 190 return ToLayoutBlockFlow(layout_object)->InlineElementContinuation(); |
191 return 0; | 191 return 0; |
192 } | 192 } |
193 | 193 |
194 AXLayoutObject::AXLayoutObject(LayoutObject* layout_object, | 194 AXLayoutObject::AXLayoutObject(LayoutObject* layout_object, |
195 AXObjectCacheImpl& ax_object_cache) | 195 AXObjectCacheImpl& ax_object_cache) |
196 : AXNodeObject(layout_object->GetNode(), ax_object_cache), | 196 : AXNodeObject(layout_object->GetNode(), ax_object_cache), |
197 layout_object_(layout_object) { | 197 layout_object_(layout_object) { |
198 #if DCHECK_IS_ON() | 198 #if DCHECK_IS_ON() |
199 layout_object_->SetHasAXObject(true); | 199 m_layoutObject->setHasAXObject(true); |
200 #endif | 200 #endif |
201 } | 201 } |
202 | 202 |
203 AXLayoutObject* AXLayoutObject::Create(LayoutObject* layout_object, | 203 AXLayoutObject* AXLayoutObject::Create(LayoutObject* layout_object, |
204 AXObjectCacheImpl& ax_object_cache) { | 204 AXObjectCacheImpl& ax_object_cache) { |
205 return new AXLayoutObject(layout_object, ax_object_cache); | 205 return new AXLayoutObject(layout_object, ax_object_cache); |
206 } | 206 } |
207 | 207 |
208 AXLayoutObject::~AXLayoutObject() { | 208 AXLayoutObject::~AXLayoutObject() { |
209 DCHECK(IsDetached()); | 209 DCHECK(IsDetached()); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 void AXLayoutObject::Init() { | 309 void AXLayoutObject::Init() { |
310 AXNodeObject::Init(); | 310 AXNodeObject::Init(); |
311 } | 311 } |
312 | 312 |
313 void AXLayoutObject::Detach() { | 313 void AXLayoutObject::Detach() { |
314 AXNodeObject::Detach(); | 314 AXNodeObject::Detach(); |
315 | 315 |
316 DetachRemoteSVGRoot(); | 316 DetachRemoteSVGRoot(); |
317 | 317 |
318 #if DCHECK_IS_ON() | 318 #if DCHECK_IS_ON() |
319 if (layout_object_) | 319 if (m_layoutObject) |
320 layout_object_->SetHasAXObject(false); | 320 m_layoutObject->setHasAXObject(false); |
321 #endif | 321 #endif |
322 layout_object_ = 0; | 322 layout_object_ = 0; |
323 } | 323 } |
324 | 324 |
325 // | 325 // |
326 // Check object role or purpose. | 326 // Check object role or purpose. |
327 // | 327 // |
328 | 328 |
329 static bool IsLinkable(const AXObject& object) { | 329 static bool IsLinkable(const AXObject& object) { |
330 if (!object.GetLayoutObject()) | 330 if (!object.GetLayoutObject()) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 GetDocument()->GetFrame()->Selection().IsFocusedAndActive())) | 451 GetDocument()->GetFrame()->Selection().IsFocusedAndActive())) |
452 return true; | 452 return true; |
453 | 453 |
454 return false; | 454 return false; |
455 } | 455 } |
456 | 456 |
457 bool AXLayoutObject::IsSelected() const { | 457 bool AXLayoutObject::IsSelected() const { |
458 if (!GetLayoutObject() || !GetNode()) | 458 if (!GetLayoutObject() || !GetNode()) |
459 return false; | 459 return false; |
460 | 460 |
461 const AtomicString& aria_selected = GetAttribute(aria_selectedAttr); | 461 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kSelected)) |
462 if (EqualIgnoringASCIICase(aria_selected, "true")) | |
463 return true; | 462 return true; |
464 | 463 |
465 AXObject* focused_object = AxObjectCache().FocusedObject(); | 464 AXObject* focused_object = AxObjectCache().FocusedObject(); |
466 if (AriaRoleAttribute() == kListBoxOptionRole && focused_object && | 465 if (AriaRoleAttribute() == kListBoxOptionRole && focused_object && |
467 focused_object->ActiveDescendant() == this) { | 466 focused_object->ActiveDescendant() == this) { |
468 return true; | 467 return true; |
469 } | 468 } |
470 | 469 |
471 if (IsTabItem() && IsTabItemSelected()) | 470 if (IsTabItem() && IsTabItemSelected()) |
472 return true; | 471 return true; |
(...skipping 12 matching lines...) Expand all Loading... |
485 | 484 |
486 if (!layout_object_) { | 485 if (!layout_object_) { |
487 if (ignored_reasons) | 486 if (ignored_reasons) |
488 ignored_reasons->push_back(IgnoredReason(kAXNotRendered)); | 487 ignored_reasons->push_back(IgnoredReason(kAXNotRendered)); |
489 return kIgnoreObject; | 488 return kIgnoreObject; |
490 } | 489 } |
491 | 490 |
492 if (layout_object_->Style()->Visibility() != EVisibility::kVisible) { | 491 if (layout_object_->Style()->Visibility() != EVisibility::kVisible) { |
493 // aria-hidden is meant to override visibility as the determinant in AX | 492 // aria-hidden is meant to override visibility as the determinant in AX |
494 // hierarchy inclusion. | 493 // hierarchy inclusion. |
495 if (EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) | 494 if (AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden)) |
496 return kDefaultBehavior; | 495 return kDefaultBehavior; |
497 | 496 |
498 if (ignored_reasons) | 497 if (ignored_reasons) |
499 ignored_reasons->push_back(IgnoredReason(kAXNotVisible)); | 498 ignored_reasons->push_back(IgnoredReason(kAXNotVisible)); |
500 return kIgnoreObject; | 499 return kIgnoreObject; |
501 } | 500 } |
502 | 501 |
503 return AXObject::DefaultObjectInclusion(ignored_reasons); | 502 return AXObject::DefaultObjectInclusion(ignored_reasons); |
504 } | 503 } |
505 | 504 |
506 bool AXLayoutObject::ComputeAccessibilityIsIgnored( | 505 bool AXLayoutObject::ComputeAccessibilityIsIgnored( |
507 IgnoredReasons* ignored_reasons) const { | 506 IgnoredReasons* ignoredReasons) const { |
508 #if DCHECK_IS_ON() | 507 #if DCHECK_IS_ON() |
509 DCHECK(initialized_); | 508 DCHECK(m_initialized); |
510 #endif | 509 #endif |
511 | 510 |
512 if (!layout_object_) | 511 if (!layout_object_) |
513 return true; | 512 return true; |
514 | 513 |
515 // Check first if any of the common reasons cause this element to be ignored. | 514 // Check first if any of the common reasons cause this element to be ignored. |
516 // Then process other use cases that need to be applied to all the various | 515 // Then process other use cases that need to be applied to all the various |
517 // roles that AXLayoutObjects take on. | 516 // roles that AXLayoutObjects take on. |
518 AXObjectInclusion decision = DefaultObjectInclusion(ignored_reasons); | 517 AXObjectInclusion decision = DefaultObjectInclusion(ignoredReasons); |
519 if (decision == kIncludeObject) | 518 if (decision == kIncludeObject) |
520 return false; | 519 return false; |
521 if (decision == kIgnoreObject) | 520 if (decision == kIgnoreObject) |
522 return true; | 521 return true; |
523 | 522 |
524 if (layout_object_->IsAnonymousBlock()) | 523 if (layout_object_->IsAnonymousBlock()) |
525 return true; | 524 return true; |
526 | 525 |
527 // If this element is within a parent that cannot have children, it should not | 526 // If this element is within a parent that cannot have children, it should not |
528 // be exposed. | 527 // be exposed. |
529 if (IsDescendantOfLeafNode()) { | 528 if (IsDescendantOfLeafNode()) { |
530 if (ignored_reasons) | 529 if (ignoredReasons) |
531 ignored_reasons->push_back( | 530 ignoredReasons->push_back( |
532 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor())); | 531 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor())); |
533 return true; | 532 return true; |
534 } | 533 } |
535 | 534 |
536 if (RoleValue() == kIgnoredRole) { | 535 if (RoleValue() == kIgnoredRole) { |
537 if (ignored_reasons) | 536 if (ignoredReasons) |
538 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 537 ignoredReasons->push_back(IgnoredReason(kAXUninteresting)); |
539 return true; | 538 return true; |
540 } | 539 } |
541 | 540 |
542 if (HasInheritedPresentationalRole()) { | 541 if (HasInheritedPresentationalRole()) { |
543 if (ignored_reasons) { | 542 if (ignoredReasons) { |
544 const AXObject* inherits_from = InheritsPresentationalRoleFrom(); | 543 const AXObject* inherits_from = InheritsPresentationalRoleFrom(); |
545 if (inherits_from == this) | 544 if (inherits_from == this) |
546 ignored_reasons->push_back(IgnoredReason(kAXPresentationalRole)); | 545 ignoredReasons->push_back(IgnoredReason(kAXPresentationalRole)); |
547 else | 546 else |
548 ignored_reasons->push_back( | 547 ignoredReasons->push_back( |
549 IgnoredReason(kAXInheritsPresentation, inherits_from)); | 548 IgnoredReason(kAXInheritsPresentation, inherits_from)); |
550 } | 549 } |
551 return true; | 550 return true; |
552 } | 551 } |
553 | 552 |
554 // An ARIA tree can only have tree items and static text as children. | 553 // An ARIA tree can only have tree items and static text as children. |
555 if (AXObject* tree_ancestor = TreeAncestorDisallowingChild()) { | 554 if (AXObject* tree_ancestor = TreeAncestorDisallowingChild()) { |
556 if (ignored_reasons) | 555 if (ignoredReasons) |
557 ignored_reasons->push_back( | 556 ignoredReasons->push_back( |
558 IgnoredReason(kAXAncestorDisallowsChild, tree_ancestor)); | 557 IgnoredReason(kAXAncestorDisallowsChild, tree_ancestor)); |
559 return true; | 558 return true; |
560 } | 559 } |
561 | 560 |
562 // A LayoutPart is an iframe element or embedded object element or something | 561 // A LayoutPart is an iframe element or embedded object element or something |
563 // like that. We don't want to ignore those. | 562 // like that. We don't want to ignore those. |
564 if (layout_object_->IsLayoutPart()) | 563 if (layout_object_->IsLayoutPart()) |
565 return false; | 564 return false; |
566 | 565 |
567 // Make sure renderers with layers stay in the tree. | 566 // Make sure renderers with layers stay in the tree. |
568 if (GetLayoutObject() && GetLayoutObject()->HasLayer() && GetNode() && | 567 if (GetLayoutObject() && GetLayoutObject()->HasLayer() && GetNode() && |
569 GetNode()->hasChildren()) | 568 GetNode()->hasChildren()) |
570 return false; | 569 return false; |
571 | 570 |
572 // Find out if this element is inside of a label element. If so, it may be | 571 // Find out if this element is inside of a label element. If so, it may be |
573 // ignored because it's the label for a checkbox or radio button. | 572 // ignored because it's the label for a checkbox or radio button. |
574 AXObject* control_object = CorrespondingControlForLabelElement(); | 573 AXObject* control_object = CorrespondingControlForLabelElement(); |
575 if (control_object && control_object->IsCheckboxOrRadio() && | 574 if (control_object && control_object->IsCheckboxOrRadio() && |
576 control_object->NameFromLabelElement()) { | 575 control_object->NameFromLabelElement()) { |
577 if (ignored_reasons) { | 576 if (ignoredReasons) { |
578 HTMLLabelElement* label = LabelElementContainer(); | 577 HTMLLabelElement* label = LabelElementContainer(); |
579 if (label && label != GetNode()) { | 578 if (label && label != GetNode()) { |
580 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label); | 579 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label); |
581 ignored_reasons->push_back( | 580 ignoredReasons->push_back( |
582 IgnoredReason(kAXLabelContainer, label_ax_object)); | 581 IgnoredReason(kAXLabelContainer, label_ax_object)); |
583 } | 582 } |
584 | 583 |
585 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); | 584 ignoredReasons->push_back(IgnoredReason(kAXLabelFor, control_object)); |
586 } | 585 } |
587 return true; | 586 return true; |
588 } | 587 } |
589 | 588 |
590 if (layout_object_->IsBR()) | 589 if (layout_object_->IsBR()) |
591 return false; | 590 return false; |
592 | 591 |
593 if (IsLink()) | 592 if (IsLink()) |
594 return false; | 593 return false; |
595 | 594 |
596 if (IsInPageLinkTarget()) | 595 if (IsInPageLinkTarget()) |
597 return false; | 596 return false; |
598 | 597 |
599 if (layout_object_->IsText()) { | 598 if (layout_object_->IsText()) { |
600 // Static text beneath MenuItems and MenuButtons are just reported along | 599 // Static text beneath MenuItems and MenuButtons are just reported along |
601 // with the menu item, so it's ignored on an individual level. | 600 // with the menu item, so it's ignored on an individual level. |
602 AXObject* parent = ParentObjectUnignored(); | 601 AXObject* parent = ParentObjectUnignored(); |
603 if (parent && (parent->AriaRoleAttribute() == kMenuItemRole || | 602 if (parent && (parent->AriaRoleAttribute() == kMenuItemRole || |
604 parent->AriaRoleAttribute() == kMenuButtonRole)) { | 603 parent->AriaRoleAttribute() == kMenuButtonRole)) { |
605 if (ignored_reasons) | 604 if (ignoredReasons) |
606 ignored_reasons->push_back( | 605 ignoredReasons->push_back( |
607 IgnoredReason(kAXStaticTextUsedAsNameFor, parent)); | 606 IgnoredReason(kAXStaticTextUsedAsNameFor, parent)); |
608 return true; | 607 return true; |
609 } | 608 } |
610 LayoutText* layout_text = ToLayoutText(layout_object_); | 609 LayoutText* layout_text = ToLayoutText(layout_object_); |
611 if (!layout_text->HasTextBoxes()) { | 610 if (!layout_text->HasTextBoxes()) { |
612 if (ignored_reasons) | 611 if (ignoredReasons) |
613 ignored_reasons->push_back(IgnoredReason(kAXEmptyText)); | 612 ignoredReasons->push_back(IgnoredReason(kAXEmptyText)); |
614 return true; | 613 return true; |
615 } | 614 } |
616 | 615 |
617 // Don't ignore static text in editable text controls. | 616 // Don't ignore static text in editable text controls. |
618 for (AXObject* parent = ParentObject(); parent; | 617 for (AXObject* parent = ParentObject(); parent; |
619 parent = parent->ParentObject()) { | 618 parent = parent->ParentObject()) { |
620 if (parent->RoleValue() == kTextFieldRole) | 619 if (parent->RoleValue() == kTextFieldRole) |
621 return false; | 620 return false; |
622 } | 621 } |
623 | 622 |
624 // Text elements that are just empty whitespace should not be returned. | 623 // Text elements that are just empty whitespace should not be returned. |
625 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', | 624 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', |
626 // or similar... | 625 // or similar... |
627 if (layout_text->GetText().Impl()->ContainsOnlyWhitespace()) { | 626 if (layout_text->GetText().Impl()->ContainsOnlyWhitespace()) { |
628 if (ignored_reasons) | 627 if (ignoredReasons) |
629 ignored_reasons->push_back(IgnoredReason(kAXEmptyText)); | 628 ignoredReasons->push_back(IgnoredReason(kAXEmptyText)); |
630 return true; | 629 return true; |
631 } | 630 } |
632 return false; | 631 return false; |
633 } | 632 } |
634 | 633 |
635 if (IsHeading()) | 634 if (IsHeading()) |
636 return false; | 635 return false; |
637 | 636 |
638 if (IsLandmarkRelated()) | 637 if (IsLandmarkRelated()) |
639 return false; | 638 return false; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 | 709 |
711 // <span> tags are inline tags and not meant to convey information if they | 710 // <span> tags are inline tags and not meant to convey information if they |
712 // have no other aria information on them. If we don't ignore them, they may | 711 // have no other aria information on them. If we don't ignore them, they may |
713 // emit signals expected to come from their parent. In addition, because | 712 // emit signals expected to come from their parent. In addition, because |
714 // included spans are GroupRole objects, and GroupRole objects are often | 713 // included spans are GroupRole objects, and GroupRole objects are often |
715 // containers with meaningful information, the inclusion of a span can have | 714 // containers with meaningful information, the inclusion of a span can have |
716 // the side effect of causing the immediate parent accessible to be ignored. | 715 // the side effect of causing the immediate parent accessible to be ignored. |
717 // This is especially problematic for platforms which have distinct roles for | 716 // This is especially problematic for platforms which have distinct roles for |
718 // textual block elements. | 717 // textual block elements. |
719 if (isHTMLSpanElement(node)) { | 718 if (isHTMLSpanElement(node)) { |
720 if (ignored_reasons) | 719 if (ignoredReasons) |
721 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 720 ignoredReasons->push_back(IgnoredReason(kAXUninteresting)); |
722 return true; | 721 return true; |
723 } | 722 } |
724 | 723 |
725 if (IsImage()) | 724 if (IsImage()) |
726 return false; | 725 return false; |
727 | 726 |
728 if (IsCanvas()) { | 727 if (IsCanvas()) { |
729 if (CanvasHasFallbackContent()) | 728 if (CanvasHasFallbackContent()) |
730 return false; | 729 return false; |
731 LayoutHTMLCanvas* canvas = ToLayoutHTMLCanvas(layout_object_); | 730 LayoutHTMLCanvas* canvas = ToLayoutHTMLCanvas(layout_object_); |
732 if (canvas->Size().Height() <= 1 || canvas->Size().Width() <= 1) { | 731 if (canvas->Size().Height() <= 1 || canvas->Size().Width() <= 1) { |
733 if (ignored_reasons) | 732 if (ignoredReasons) |
734 ignored_reasons->push_back(IgnoredReason(kAXProbablyPresentational)); | 733 ignoredReasons->push_back(IgnoredReason(kAXProbablyPresentational)); |
735 return true; | 734 return true; |
736 } | 735 } |
737 // Otherwise fall through; use presence of help text, title, or description | 736 // Otherwise fall through; use presence of help text, title, or description |
738 // to decide. | 737 // to decide. |
739 } | 738 } |
740 | 739 |
741 if (IsWebArea() || layout_object_->IsListMarker()) | 740 if (IsWebArea() || layout_object_->IsListMarker()) |
742 return false; | 741 return false; |
743 | 742 |
744 // Using the help text, title or accessibility description (so we | 743 // Using the help text, title or accessibility description (so we |
(...skipping 23 matching lines...) Expand all Loading... |
768 if (layout_object_->IsLayoutBlockFlow() && layout_object_->ChildrenInline() && | 767 if (layout_object_->IsLayoutBlockFlow() && layout_object_->ChildrenInline() && |
769 !CanSetFocusAttribute()) { | 768 !CanSetFocusAttribute()) { |
770 // If the layout object has any plain text in it, that text will be | 769 // If the layout object has any plain text in it, that text will be |
771 // inside a LineBox, so the layout object will have a first LineBox. | 770 // inside a LineBox, so the layout object will have a first LineBox. |
772 bool has_any_text = !!ToLayoutBlockFlow(layout_object_)->FirstLineBox(); | 771 bool has_any_text = !!ToLayoutBlockFlow(layout_object_)->FirstLineBox(); |
773 | 772 |
774 // Always include interesting-looking objects. | 773 // Always include interesting-looking objects. |
775 if (has_any_text || MouseButtonListener()) | 774 if (has_any_text || MouseButtonListener()) |
776 return false; | 775 return false; |
777 | 776 |
778 if (ignored_reasons) | 777 if (ignoredReasons) |
779 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 778 ignoredReasons->push_back(IgnoredReason(kAXUninteresting)); |
780 return true; | 779 return true; |
781 } | 780 } |
782 | 781 |
783 // By default, objects should be ignored so that the AX hierarchy is not | 782 // By default, objects should be ignored so that the AX hierarchy is not |
784 // filled with unnecessary items. | 783 // filled with unnecessary items. |
785 if (ignored_reasons) | 784 if (ignoredReasons) |
786 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); | 785 ignoredReasons->push_back(IgnoredReason(kAXUninteresting)); |
787 return true; | 786 return true; |
788 } | 787 } |
789 | 788 |
790 // | 789 // |
791 // Properties of static elements. | 790 // Properties of static elements. |
792 // | 791 // |
793 | 792 |
794 const AtomicString& AXLayoutObject::AccessKey() const { | 793 const AtomicString& AXLayoutObject::AccessKey() const { |
795 Node* node = layout_object_->GetNode(); | 794 Node* node = layout_object_->GetNode(); |
796 if (!node) | 795 if (!node) |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1365 GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRelevant); | 1364 GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRelevant); |
1366 | 1365 |
1367 // Default aria-relevant = "additions text". | 1366 // Default aria-relevant = "additions text". |
1368 if (relevant.IsEmpty()) | 1367 if (relevant.IsEmpty()) |
1369 return default_live_region_relevant; | 1368 return default_live_region_relevant; |
1370 | 1369 |
1371 return relevant; | 1370 return relevant; |
1372 } | 1371 } |
1373 | 1372 |
1374 bool AXLayoutObject::LiveRegionAtomic() const { | 1373 bool AXLayoutObject::LiveRegionAtomic() const { |
| 1374 bool atomic = false; |
| 1375 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kAtomic, atomic)) |
| 1376 return atomic; |
| 1377 |
1375 // ARIA roles "alert" and "status" should have an implicit aria-atomic value | 1378 // ARIA roles "alert" and "status" should have an implicit aria-atomic value |
1376 // of true. | 1379 // of true. |
1377 if (GetAttribute(aria_atomicAttr).IsEmpty() && | 1380 return RoleValue() == kAlertRole || RoleValue() == kStatusRole; |
1378 (RoleValue() == kAlertRole || RoleValue() == kStatusRole)) { | |
1379 return true; | |
1380 } | |
1381 return ElementAttributeValue(aria_atomicAttr); | |
1382 } | 1381 } |
1383 | 1382 |
1384 bool AXLayoutObject::LiveRegionBusy() const { | 1383 bool AXLayoutObject::LiveRegionBusy() const { |
1385 return ElementAttributeValue(aria_busyAttr); | 1384 return AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kBusy); |
1386 } | 1385 } |
1387 | 1386 |
1388 // | 1387 // |
1389 // Hit testing. | 1388 // Hit testing. |
1390 // | 1389 // |
1391 | 1390 |
1392 AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const { | 1391 AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const { |
1393 if (!layout_object_ || !layout_object_->HasLayer()) | 1392 if (!layout_object_ || !layout_object_->HasLayer()) |
1394 return nullptr; | 1393 return nullptr; |
1395 | 1394 |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2008 if (anchor_visible_position.IsNull() || focus_visible_position.IsNull()) | 2007 if (anchor_visible_position.IsNull() || focus_visible_position.IsNull()) |
2009 return; | 2008 return; |
2010 | 2009 |
2011 frame->Selection().SetSelection( | 2010 frame->Selection().SetSelection( |
2012 SelectionInDOMTree::Builder() | 2011 SelectionInDOMTree::Builder() |
2013 .Collapse(anchor_visible_position.ToPositionWithAffinity()) | 2012 .Collapse(anchor_visible_position.ToPositionWithAffinity()) |
2014 .Extend(focus_visible_position.DeepEquivalent()) | 2013 .Extend(focus_visible_position.DeepEquivalent()) |
2015 .Build()); | 2014 .Build()); |
2016 } | 2015 } |
2017 | 2016 |
2018 bool AXLayoutObject::IsValidSelectionBound(const AXObject* bound_object) const { | 2017 bool AXLayoutObject::IsValidSelectionBound(const AXObject* boundObject) const { |
2019 return GetLayoutObject() && bound_object && !bound_object->IsDetached() && | 2018 return GetLayoutObject() && boundObject && !boundObject->IsDetached() && |
2020 bound_object->IsAXLayoutObject() && bound_object->GetLayoutObject() && | 2019 boundObject->IsAXLayoutObject() && boundObject->GetLayoutObject() && |
2021 bound_object->GetLayoutObject()->GetFrame() == | 2020 boundObject->GetLayoutObject()->GetFrame() == |
2022 GetLayoutObject()->GetFrame() && | 2021 GetLayoutObject()->GetFrame() && |
2023 &bound_object->AxObjectCache() == &AxObjectCache(); | 2022 &boundObject->AxObjectCache() == &AxObjectCache(); |
2024 } | 2023 } |
2025 | 2024 |
2026 void AXLayoutObject::SetValue(const String& string) { | 2025 void AXLayoutObject::SetValue(const String& string) { |
2027 if (!GetNode() || !GetNode()->IsElementNode()) | 2026 if (!GetNode() || !GetNode()->IsElementNode()) |
2028 return; | 2027 return; |
2029 if (!layout_object_ || !layout_object_->IsBoxModelObject()) | 2028 if (!layout_object_ || !layout_object_->IsBoxModelObject()) |
2030 return; | 2029 return; |
2031 | 2030 |
2032 LayoutBoxModelObject* layout_object = ToLayoutBoxModelObject(layout_object_); | 2031 LayoutBoxModelObject* layout_object = ToLayoutBoxModelObject(layout_object_); |
2033 if (layout_object->IsTextField() && isHTMLInputElement(*GetNode())) | 2032 if (layout_object->IsTextField() && isHTMLInputElement(*GetNode())) |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 | 2502 |
2504 if (root->AccessibilityIsIgnored()) { | 2503 if (root->AccessibilityIsIgnored()) { |
2505 for (const auto& child : root->Children()) | 2504 for (const auto& child : root->Children()) |
2506 children_.push_back(child); | 2505 children_.push_back(child); |
2507 } else { | 2506 } else { |
2508 children_.push_back(root); | 2507 children_.push_back(root); |
2509 } | 2508 } |
2510 } | 2509 } |
2511 | 2510 |
2512 bool AXLayoutObject::ElementAttributeValue( | 2511 bool AXLayoutObject::ElementAttributeValue( |
2513 const QualifiedName& attribute_name) const { | 2512 const QualifiedName& attributeName) const { |
2514 if (!layout_object_) | 2513 if (!layout_object_) |
2515 return false; | 2514 return false; |
2516 | 2515 |
2517 return EqualIgnoringASCIICase(GetAttribute(attribute_name), "true"); | 2516 return EqualIgnoringASCIICase(GetAttribute(attributeName), "true"); |
2518 } | 2517 } |
2519 | 2518 |
2520 } // namespace blink | 2519 } // namespace blink |
OLD | NEW |