OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008, 2009, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2011 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 11 matching lines...) Expand all Loading... |
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 */ | 27 */ |
28 | 28 |
29 #include "modules/accessibility/AXObject.h" | 29 #include "modules/accessibility/AXObject.h" |
30 | 30 |
31 #include "SkMatrix44.h" | 31 #include "SkMatrix44.h" |
| 32 #include "base/debug/stack_trace.h" |
32 #include "core/InputTypeNames.h" | 33 #include "core/InputTypeNames.h" |
33 #include "core/css/resolver/StyleResolver.h" | 34 #include "core/css/resolver/StyleResolver.h" |
34 #include "core/dom/AccessibleNode.h" | 35 #include "core/dom/AccessibleNode.h" |
35 #include "core/dom/DocumentUserGestureToken.h" | 36 #include "core/dom/DocumentUserGestureToken.h" |
36 #include "core/editing/EditingUtilities.h" | 37 #include "core/editing/EditingUtilities.h" |
37 #include "core/editing/VisibleUnits.h" | 38 #include "core/editing/VisibleUnits.h" |
38 #include "core/frame/FrameView.h" | 39 #include "core/frame/FrameView.h" |
39 #include "core/frame/LocalFrame.h" | 40 #include "core/frame/LocalFrame.h" |
40 #include "core/frame/Settings.h" | 41 #include "core/frame/Settings.h" |
41 #include "core/html/HTMLDialogElement.h" | 42 #include "core/html/HTMLDialogElement.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 case kSpinButtonRole: | 527 case kSpinButtonRole: |
527 case kTabRole: | 528 case kTabRole: |
528 case kTextFieldRole: | 529 case kTextFieldRole: |
529 case kToggleButtonRole: | 530 case kToggleButtonRole: |
530 return true; | 531 return true; |
531 default: | 532 default: |
532 return false; | 533 return false; |
533 } | 534 } |
534 } | 535 } |
535 | 536 |
536 bool AXObject::AccessibilityIsIgnored() const { | 537 bool AXObject::AccessibilityIsIgnored() { |
| 538 Document* document = GetDocument(); |
| 539 if (!document) { |
| 540 LOG(INFO) << "no document"; |
| 541 } |
| 542 while (document) { |
| 543 document->UpdateDistribution(); |
| 544 if (!document->ownerDocument() && document->LocalOwner()) |
| 545 document = document->LocalOwner()->ownerDocument(); |
| 546 else |
| 547 document = nullptr; // Only walk up the chain for <object> |
| 548 } |
| 549 |
537 UpdateCachedAttributeValuesIfNeeded(); | 550 UpdateCachedAttributeValuesIfNeeded(); |
538 return cached_is_ignored_; | 551 return cached_is_ignored_; |
539 } | 552 } |
540 | 553 |
541 void AXObject::UpdateCachedAttributeValuesIfNeeded() const { | 554 void AXObject::UpdateCachedAttributeValuesIfNeeded() const { |
542 if (IsDetached()) | 555 if (IsDetached()) |
543 return; | 556 return; |
544 | 557 |
545 AXObjectCacheImpl& cache = AxObjectCache(); | 558 AXObjectCacheImpl& cache = AxObjectCache(); |
546 | 559 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 if (GetNode()) { | 621 if (GetNode()) { |
609 if (GetNode()->IsInert()) { | 622 if (GetNode()->IsInert()) { |
610 if (ignored_reasons) { | 623 if (ignored_reasons) { |
611 HTMLDialogElement* dialog = GetActiveDialogElement(GetNode()); | 624 HTMLDialogElement* dialog = GetActiveDialogElement(GetNode()); |
612 if (dialog) { | 625 if (dialog) { |
613 AXObject* dialog_object = AxObjectCache().GetOrCreate(dialog); | 626 AXObject* dialog_object = AxObjectCache().GetOrCreate(dialog); |
614 if (dialog_object) | 627 if (dialog_object) |
615 ignored_reasons->push_back( | 628 ignored_reasons->push_back( |
616 IgnoredReason(kAXActiveModalDialog, dialog_object)); | 629 IgnoredReason(kAXActiveModalDialog, dialog_object)); |
617 else | 630 else |
618 ignored_reasons->push_back(IgnoredReason(kAXInert)); | 631 ignored_reasons->push_back(IgnoredReason(kAXInertElement)); |
619 } else { | 632 } else { |
620 // TODO(aboxhall): handle inert attribute if it eventuates | 633 const AXObject* inert_root_el = InertRoot(); |
621 ignored_reasons->push_back(IgnoredReason(kAXInert)); | 634 if (inert_root_el == this) { |
| 635 ignored_reasons->push_back(IgnoredReason(kAXInertElement)); |
| 636 } else { |
| 637 ignored_reasons->push_back( |
| 638 IgnoredReason(kAXInertSubtree, inert_root_el)); |
| 639 } |
622 } | 640 } |
623 } | 641 } |
624 return true; | 642 return true; |
625 } | 643 } |
626 } else { | 644 } else { |
627 AXObject* parent = ParentObject(); | 645 AXObject* parent = ParentObject(); |
628 if (parent && parent->IsInertOrAriaHidden()) { | 646 if (parent && parent->IsInertOrAriaHidden()) { |
629 if (ignored_reasons) | 647 if (ignored_reasons) |
630 parent->ComputeIsInertOrAriaHidden(ignored_reasons); | 648 parent->ComputeIsInertOrAriaHidden(ignored_reasons); |
631 return true; | 649 return true; |
632 } | 650 } |
633 } | 651 } |
634 | 652 |
635 const AXObject* hidden_root = AriaHiddenRoot(); | 653 const AXObject* hidden_root = AriaHiddenRoot(); |
636 if (hidden_root) { | 654 if (hidden_root) { |
637 if (ignored_reasons) { | 655 if (ignored_reasons) { |
638 if (hidden_root == this) | 656 if (hidden_root == this) { |
639 ignored_reasons->push_back(IgnoredReason(kAXAriaHidden)); | 657 ignored_reasons->push_back(IgnoredReason(kAXAriaHiddenElement)); |
640 else | 658 } else { |
641 ignored_reasons->push_back( | 659 ignored_reasons->push_back( |
642 IgnoredReason(kAXAriaHiddenRoot, hidden_root)); | 660 IgnoredReason(kAXAriaHiddenSubtree, hidden_root)); |
| 661 } |
643 } | 662 } |
644 return true; | 663 return true; |
645 } | 664 } |
646 | 665 |
647 return false; | 666 return false; |
648 } | 667 } |
649 | 668 |
650 bool AXObject::IsDescendantOfLeafNode() const { | 669 bool AXObject::IsDescendantOfLeafNode() const { |
651 UpdateCachedAttributeValuesIfNeeded(); | 670 UpdateCachedAttributeValuesIfNeeded(); |
652 return cached_is_descendant_of_leaf_node_; | 671 return cached_is_descendant_of_leaf_node_; |
(...skipping 12 matching lines...) Expand all Loading... |
665 | 684 |
666 const AXObject* AXObject::AriaHiddenRoot() const { | 685 const AXObject* AXObject::AriaHiddenRoot() const { |
667 for (const AXObject* object = this; object; object = object->ParentObject()) { | 686 for (const AXObject* object = this; object; object = object->ParentObject()) { |
668 if (EqualIgnoringASCIICase(object->GetAttribute(aria_hiddenAttr), "true")) | 687 if (EqualIgnoringASCIICase(object->GetAttribute(aria_hiddenAttr), "true")) |
669 return object; | 688 return object; |
670 } | 689 } |
671 | 690 |
672 return 0; | 691 return 0; |
673 } | 692 } |
674 | 693 |
| 694 const AXObject* AXObject::InertRoot() const { |
| 695 const AXObject* object = this; |
| 696 if (!RuntimeEnabledFeatures::inertAttributeEnabled()) |
| 697 return 0; |
| 698 |
| 699 while (object && !object->IsAXNodeObject()) |
| 700 object = object->ParentObject(); |
| 701 Node* node = object->GetNode(); |
| 702 Element* element = node->IsElementNode() |
| 703 ? ToElement(node) |
| 704 : FlatTreeTraversal::ParentElement(*node); |
| 705 while (element) { |
| 706 if (element->hasAttribute(inertAttr)) |
| 707 return AxObjectCache().GetOrCreate(element); |
| 708 element = FlatTreeTraversal::ParentElement(*element); |
| 709 } |
| 710 |
| 711 return 0; |
| 712 } |
| 713 |
675 bool AXObject::IsDescendantOfDisabledNode() const { | 714 bool AXObject::IsDescendantOfDisabledNode() const { |
676 UpdateCachedAttributeValuesIfNeeded(); | 715 UpdateCachedAttributeValuesIfNeeded(); |
677 return cached_is_descendant_of_disabled_node_; | 716 return cached_is_descendant_of_disabled_node_; |
678 } | 717 } |
679 | 718 |
680 const AXObject* AXObject::DisabledAncestor() const { | 719 const AXObject* AXObject::DisabledAncestor() const { |
681 const AtomicString& disabled = GetAttribute(aria_disabledAttr); | 720 const AtomicString& disabled = GetAttribute(aria_disabledAttr); |
682 if (EqualIgnoringASCIICase(disabled, "true")) | 721 if (EqualIgnoringASCIICase(disabled, "true")) |
683 return this; | 722 return this; |
684 if (EqualIgnoringASCIICase(disabled, "false")) | 723 if (EqualIgnoringASCIICase(disabled, "false")) |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 Document* AXObject::GetDocument() const { | 1257 Document* AXObject::GetDocument() const { |
1219 FrameView* frame_view = DocumentFrameView(); | 1258 FrameView* frame_view = DocumentFrameView(); |
1220 if (!frame_view) | 1259 if (!frame_view) |
1221 return 0; | 1260 return 0; |
1222 | 1261 |
1223 return frame_view->GetFrame().GetDocument(); | 1262 return frame_view->GetFrame().GetDocument(); |
1224 } | 1263 } |
1225 | 1264 |
1226 FrameView* AXObject::DocumentFrameView() const { | 1265 FrameView* AXObject::DocumentFrameView() const { |
1227 const AXObject* object = this; | 1266 const AXObject* object = this; |
1228 while (object && !object->IsAXLayoutObject()) | 1267 LOG(INFO) << "DocumentFrameView for " << RoleName(RoleValue()).Utf8().data(); |
| 1268 base::debug::StackTrace trace; |
| 1269 trace.Print(); |
| 1270 |
| 1271 while (object && !object->IsAXLayoutObject()) { |
1229 object = object->ParentObject(); | 1272 object = object->ParentObject(); |
| 1273 LOG(INFO) << "parent: " << (object ? RoleName(object->RoleValue()).Utf8().da
ta() : "null"); |
| 1274 } |
1230 | 1275 |
1231 if (!object) | 1276 if (!object) { |
| 1277 LOG(INFO) << "No candidate layout object in parent hierarchy"; |
1232 return 0; | 1278 return 0; |
| 1279 } |
1233 | 1280 |
1234 return object->DocumentFrameView(); | 1281 return object->DocumentFrameView(); |
1235 } | 1282 } |
1236 | 1283 |
1237 String AXObject::Language() const { | 1284 String AXObject::Language() const { |
1238 const AtomicString& lang = GetAttribute(langAttr); | 1285 const AtomicString& lang = GetAttribute(langAttr); |
1239 if (!lang.IsEmpty()) | 1286 if (!lang.IsEmpty()) |
1240 return lang; | 1287 return lang; |
1241 | 1288 |
1242 AXObject* parent = ParentObject(); | 1289 AXObject* parent = ParentObject(); |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 return internal_role_name_vector->at(role); | 1908 return internal_role_name_vector->at(role); |
1862 } | 1909 } |
1863 | 1910 |
1864 DEFINE_TRACE(AXObject) { | 1911 DEFINE_TRACE(AXObject) { |
1865 visitor->Trace(children_); | 1912 visitor->Trace(children_); |
1866 visitor->Trace(parent_); | 1913 visitor->Trace(parent_); |
1867 visitor->Trace(cached_live_region_root_); | 1914 visitor->Trace(cached_live_region_root_); |
1868 visitor->Trace(ax_object_cache_); | 1915 visitor->Trace(ax_object_cache_); |
1869 } | 1916 } |
1870 | 1917 |
| 1918 |
1871 } // namespace blink | 1919 } // namespace blink |
OLD | NEW |