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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 #include "core/paint/DeprecatedPaintLayer.h" | 64 #include "core/paint/DeprecatedPaintLayer.h" |
| 65 #include "core/svg/SVGDocumentExtensions.h" | 65 #include "core/svg/SVGDocumentExtensions.h" |
| 66 #include "core/svg/SVGSVGElement.h" | 66 #include "core/svg/SVGSVGElement.h" |
| 67 #include "core/svg/graphics/SVGImage.h" | 67 #include "core/svg/graphics/SVGImage.h" |
| 68 #include "modules/accessibility/AXImageMapLink.h" | 68 #include "modules/accessibility/AXImageMapLink.h" |
| 69 #include "modules/accessibility/AXInlineTextBox.h" | 69 #include "modules/accessibility/AXInlineTextBox.h" |
| 70 #include "modules/accessibility/AXObjectCacheImpl.h" | 70 #include "modules/accessibility/AXObjectCacheImpl.h" |
| 71 #include "modules/accessibility/AXSVGRoot.h" | 71 #include "modules/accessibility/AXSVGRoot.h" |
| 72 #include "modules/accessibility/AXSpinButton.h" | 72 #include "modules/accessibility/AXSpinButton.h" |
| 73 #include "modules/accessibility/AXTable.h" | 73 #include "modules/accessibility/AXTable.h" |
| 74 #include "modules/accessibility/InspectorTypeBuilderHelper.h" | |
| 74 #include "platform/text/PlatformLocale.h" | 75 #include "platform/text/PlatformLocale.h" |
| 75 #include "wtf/StdLibExtras.h" | 76 #include "wtf/StdLibExtras.h" |
| 76 | 77 |
| 77 using blink::WebLocalizedString; | 78 using blink::WebLocalizedString; |
| 78 | 79 |
| 79 namespace blink { | 80 namespace blink { |
| 80 | 81 |
| 81 using namespace HTMLNames; | 82 using namespace HTMLNames; |
| 82 | 83 |
| 84 using TypeBuilder::Accessibility::AXIgnoredReasons; | |
| 85 | |
| 83 static inline LayoutObject* firstChildInContinuation(const LayoutInline& layoutO bject) | 86 static inline LayoutObject* firstChildInContinuation(const LayoutInline& layoutO bject) |
| 84 { | 87 { |
| 85 LayoutBoxModelObject* r = layoutObject.continuation(); | 88 LayoutBoxModelObject* r = layoutObject.continuation(); |
| 86 | 89 |
| 87 while (r) { | 90 while (r) { |
| 88 if (r->isLayoutBlock()) | 91 if (r->isLayoutBlock()) |
| 89 return r; | 92 return r; |
| 90 if (LayoutObject* child = r->slowFirstChild()) | 93 if (LayoutObject* child = r->slowFirstChild()) |
| 91 return child; | 94 return child; |
| 92 r = toLayoutInline(r)->continuation(); | 95 r = toLayoutInline(r)->continuation(); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 if (isTabItem() && isTabItemSelected()) | 460 if (isTabItem() && isTabItemSelected()) |
| 458 return true; | 461 return true; |
| 459 | 462 |
| 460 return false; | 463 return false; |
| 461 } | 464 } |
| 462 | 465 |
| 463 // | 466 // |
| 464 // Whether objects are ignored, i.e. not included in the tree. | 467 // Whether objects are ignored, i.e. not included in the tree. |
| 465 // | 468 // |
| 466 | 469 |
| 467 AXObjectInclusion AXLayoutObject::defaultObjectInclusion() const | 470 AXObjectInclusion AXLayoutObject::defaultObjectInclusion(PassRefPtr<TypeBuilder: :Array<TypeBuilder::Accessibility::AXProperty>> passIgnoredReasons) const |
| 468 { | 471 { |
| 469 // The following cases can apply to any element that's a subclass of AXLayou tObject. | 472 // The following cases can apply to any element that's a subclass of AXLayou tObject. |
| 470 | 473 |
| 471 if (!m_layoutObject) | 474 RefPtr<TypeBuilder::Array<TypeBuilder::Accessibility::AXProperty>> ignoredRe asons = passIgnoredReasons; |
| 475 | |
| 476 if (!m_layoutObject) { | |
| 477 if (ignoredReasons) | |
| 478 ignoredReasons->addItem(createProperty(AXIgnoredReasons::NotRendered , createBooleanValue(true))); | |
| 472 return IgnoreObject; | 479 return IgnoreObject; |
| 480 } | |
| 473 | 481 |
| 474 if (m_layoutObject->style()->visibility() != VISIBLE) { | 482 if (m_layoutObject->style()->visibility() != VISIBLE) { |
| 475 // aria-hidden is meant to override visibility as the determinant in AX hierarchy inclusion. | 483 // aria-hidden is meant to override visibility as the determinant in AX hierarchy inclusion. |
| 476 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) | 484 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) |
| 477 return DefaultBehavior; | 485 return DefaultBehavior; |
| 478 | 486 |
| 487 if (ignoredReasons) | |
| 488 ignoredReasons->addItem(createProperty(AXIgnoredReasons::NotVisible, createBooleanValue(true))); | |
| 479 return IgnoreObject; | 489 return IgnoreObject; |
| 480 } | 490 } |
| 481 | 491 |
| 482 return AXObject::defaultObjectInclusion(); | 492 return AXObject::defaultObjectInclusion(ignoredReasons); |
| 483 } | 493 } |
| 484 | 494 |
| 485 bool AXLayoutObject::computeAccessibilityIsIgnored() const | 495 bool AXLayoutObject::computeAccessibilityIsIgnored(PassRefPtr<TypeBuilder::Array <TypeBuilder::Accessibility::AXProperty>> passIgnoredReasons) const |
| 486 { | 496 { |
| 487 #if ENABLE(ASSERT) | 497 #if ENABLE(ASSERT) |
| 488 ASSERT(m_initialized); | 498 ASSERT(m_initialized); |
| 489 #endif | 499 #endif |
| 490 | 500 |
| 501 RefPtr<TypeBuilder::Array<TypeBuilder::Accessibility::AXProperty>> ignoredRe asons = passIgnoredReasons; | |
| 502 | |
| 491 // Check first if any of the common reasons cause this element to be ignored . | 503 // Check first if any of the common reasons cause this element to be ignored . |
| 492 // Then process other use cases that need to be applied to all the various r oles | 504 // Then process other use cases that need to be applied to all the various r oles |
| 493 // that AXLayoutObjects take on. | 505 // that AXLayoutObjects take on. |
| 494 AXObjectInclusion decision = defaultObjectInclusion(); | 506 AXObjectInclusion decision = defaultObjectInclusion(ignoredReasons); |
| 495 if (decision == IncludeObject) | 507 if (decision == IncludeObject) |
| 496 return false; | 508 return false; |
| 497 if (decision == IgnoreObject) | 509 if (decision == IgnoreObject) |
| 498 return true; | 510 return true; |
| 499 | 511 |
| 500 // If this element is within a parent that cannot have children, it should n ot be exposed. | 512 // If this element is within a parent that cannot have children, it should n ot be exposed |
| 501 if (isDescendantOfBarrenParent()) | 513 if (isDescendantOfLeafNode()) { |
| 514 if (ignoredReasons) | |
| 515 ignoredReasons->addItem(createProperty(AXIgnoredReasons::AncestorIsL eafNode, createRelatedNodeValue(leafNodeAncestor()))); | |
|
dmazzoni
2015/04/15 17:00:02
Perhaps you could add a helper function for this.
aboxhall
2015/04/15 17:55:46
I feel silly for not thinking of this. Done.
aboxhall
2015/04/15 17:55:46
Great idea, done.
| |
| 502 return true; | 516 return true; |
| 517 } | |
| 503 | 518 |
| 504 if (roleValue() == IgnoredRole) | 519 if (roleValue() == IgnoredRole) { |
| 520 if (ignoredReasons) { | |
| 521 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Uninteresti ng, createBooleanValue(true))); | |
| 522 } | |
| 505 return true; | 523 return true; |
| 524 } | |
| 506 | 525 |
| 507 if (hasInheritedPresentationalRole()) | 526 if (hasInheritedPresentationalRole()) { |
| 527 if (ignoredReasons) | |
| 528 ignoredReasons->addItem(createProperty(AXIgnoredReasons::InheritsPre sentation, createRelatedNodeValue(inheritsPresentationalRoleFrom()))); | |
| 508 return true; | 529 return true; |
| 530 } | |
| 509 | 531 |
| 510 // An ARIA tree can only have tree items and static text as children. | 532 // An ARIA tree can only have tree items and static text as children. |
| 511 if (!isAllowedChildOfTree()) | 533 if (AXObject* treeAncestor = treeAncestorDisallowingChild()) { |
| 534 if (ignoredReasons) | |
| 535 ignoredReasons->addItem(createProperty(AXIgnoredReasons::AncestorDis allowsChild, createRelatedNodeValue(treeAncestor))); | |
| 512 return true; | 536 return true; |
| 537 } | |
| 513 | 538 |
| 514 // TODO: we should refactor this - but right now this is necessary to make | 539 // TODO: we should refactor this - but right now this is necessary to make |
| 515 // sure scroll areas stay in the tree. | 540 // sure scroll areas stay in the tree. |
| 516 if (isAttachment()) | 541 if (isAttachment()) |
| 517 return false; | 542 return false; |
| 518 | 543 |
| 519 // ignore popup menu items because AppKit does | 544 // ignore popup menu items because AppKit does |
| 520 for (LayoutObject* parent = m_layoutObject->parent(); parent; parent = paren t->parent()) { | 545 for (LayoutObject* parent = m_layoutObject->parent(); parent; parent = paren t->parent()) { |
| 521 if (parent->isBoxModelObject() && toLayoutBoxModelObject(parent)->isMenu List()) | 546 if (parent->isBoxModelObject() && toLayoutBoxModelObject(parent)->isMenu List()) { |
| 547 if (ignoredReasons) { | |
| 548 AXObject* parentObject = axObjectCache()->getOrCreate(parent); | |
| 549 if (parentObject) | |
| 550 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Anc estorDisallowsChild, createRelatedNodeValue(parentObject))); | |
| 551 } | |
| 522 return true; | 552 return true; |
| 553 } | |
| 523 } | 554 } |
| 524 | 555 |
| 525 // find out if this element is inside of a label element. | 556 // find out if this element is inside of a label element. |
| 526 // if so, it may be ignored because it's the label for a checkbox or radio b utton | 557 // if so, it may be ignored because it's the label for a checkbox or radio b utton |
| 527 AXObject* controlObject = correspondingControlForLabelElement(); | 558 AXObject* controlObject = correspondingControlForLabelElement(); |
| 528 if (controlObject && !controlObject->deprecatedExposesTitleUIElement() && co ntrolObject->isCheckboxOrRadio()) | 559 if (controlObject && !controlObject->deprecatedExposesTitleUIElement() && co ntrolObject->isCheckboxOrRadio()) { |
| 560 if (ignoredReasons) { | |
| 561 HTMLLabelElement* label = labelElementContainer(); | |
| 562 if (label && !label->isSameNode(node())) { | |
| 563 AXObject* labelAXObject = axObjectCache()->getOrCreate(label); | |
| 564 ignoredReasons->addItem(createProperty(AXIgnoredReasons::LabelCo ntainer, createRelatedNodeValue(labelAXObject))); | |
| 565 } | |
| 566 | |
| 567 ignoredReasons->addItem(createProperty(AXIgnoredReasons::LabelFor, c reateRelatedNodeValue(controlObject))); | |
| 568 } | |
| 529 return true; | 569 return true; |
| 570 } | |
| 530 | 571 |
| 531 if (m_layoutObject->isBR()) | 572 if (m_layoutObject->isBR()) |
| 532 return false; | 573 return false; |
| 533 | 574 |
| 534 // NOTE: BRs always have text boxes now, so the text box check here can be r emoved | |
| 535 if (m_layoutObject->isText()) { | 575 if (m_layoutObject->isText()) { |
| 536 // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level | 576 // static text beneath MenuItems and MenuButtons are just reported along with the menu item, so it's ignored on an individual level |
| 537 AXObject* parent = parentObjectUnignored(); | 577 AXObject* parent = parentObjectUnignored(); |
| 538 if (parent && (parent->ariaRoleAttribute() == MenuItemRole || parent->ar iaRoleAttribute() == MenuButtonRole)) | 578 if (parent && (parent->ariaRoleAttribute() == MenuItemRole || parent->ar iaRoleAttribute() == MenuButtonRole)) { |
| 579 if (ignoredReasons) | |
| 580 ignoredReasons->addItem(createProperty(AXIgnoredReasons::StaticT extUsedAsNameFor, createRelatedNodeValue(parent))); | |
| 539 return true; | 581 return true; |
| 582 } | |
| 540 LayoutText* layoutText = toLayoutText(m_layoutObject); | 583 LayoutText* layoutText = toLayoutText(m_layoutObject); |
| 541 if (m_layoutObject->isBR() || !layoutText->firstTextBox()) | 584 if (!layoutText->firstTextBox()) { |
| 585 if (ignoredReasons) | |
| 586 ignoredReasons->addItem(createProperty(AXIgnoredReasons::EmptyTe xt, createBooleanValue(true))); | |
| 542 return true; | 587 return true; |
| 588 } | |
| 543 | 589 |
| 544 // Don't ignore static text in editable text controls. | 590 // Don't ignore static text in editable text controls. |
| 545 for (AXObject* parent = parentObject(); parent; parent = parent->parentO bject()) { | 591 for (AXObject* parent = parentObject(); parent; parent = parent->parentO bject()) { |
| 546 if (parent->roleValue() == TextFieldRole) | 592 if (parent->roleValue() == TextFieldRole) |
| 547 return false; | 593 return false; |
| 548 } | 594 } |
| 549 | 595 |
| 550 // text elements that are just empty whitespace should not be returned | 596 // text elements that are just empty whitespace should not be returned |
| 551 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'p re', or similar... | 597 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'p re', or similar... |
| 552 return layoutText->text().impl()->containsOnlyWhitespace(); | 598 if (layoutText->text().impl()->containsOnlyWhitespace()) { |
| 599 if (ignoredReasons) | |
| 600 ignoredReasons->addItem(createProperty(AXIgnoredReasons::EmptyTe xt, createBooleanValue(true))); | |
| 601 return true; | |
| 602 } | |
| 603 return false; | |
| 553 } | 604 } |
| 554 | 605 |
| 555 if (isHeading()) | 606 if (isHeading()) |
| 556 return false; | 607 return false; |
| 557 | 608 |
| 558 if (isLandmarkRelated()) | 609 if (isLandmarkRelated()) |
| 559 return false; | 610 return false; |
| 560 | 611 |
| 561 if (isLink()) | 612 if (isLink()) |
| 562 return false; | 613 return false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 610 // if this element has aria attributes on it, it should not be ignored. | 661 // if this element has aria attributes on it, it should not be ignored. |
| 611 if (supportsARIAAttributes()) | 662 if (supportsARIAAttributes()) |
| 612 return false; | 663 return false; |
| 613 | 664 |
| 614 // <span> tags are inline tags and not meant to convey information if they h ave no other aria | 665 // <span> tags are inline tags and not meant to convey information if they h ave no other aria |
| 615 // information on them. If we don't ignore them, they may emit signals expec ted to come from | 666 // information on them. If we don't ignore them, they may emit signals expec ted to come from |
| 616 // their parent. In addition, because included spans are GroupRole objects, and GroupRole | 667 // their parent. In addition, because included spans are GroupRole objects, and GroupRole |
| 617 // objects are often containers with meaningful information, the inclusion o f a span can have | 668 // objects are often containers with meaningful information, the inclusion o f a span can have |
| 618 // the side effect of causing the immediate parent accessible to be ignored. This is especially | 669 // the side effect of causing the immediate parent accessible to be ignored. This is especially |
| 619 // problematic for platforms which have distinct roles for textual block ele ments. | 670 // problematic for platforms which have distinct roles for textual block ele ments. |
| 620 if (isHTMLSpanElement(node)) | 671 if (isHTMLSpanElement(node)) { |
| 672 if (ignoredReasons) | |
| 673 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Uninteresti ng, createBooleanValue(true))); | |
| 621 return true; | 674 return true; |
| 675 } | |
| 622 | 676 |
| 623 if (m_layoutObject->isLayoutBlockFlow() && m_layoutObject->childrenInline() && !canSetFocusAttribute()) | 677 if (m_layoutObject->isLayoutBlockFlow() && m_layoutObject->childrenInline() && !canSetFocusAttribute()) { |
| 624 return !toLayoutBlockFlow(m_layoutObject)->firstLineBox() && !mouseButto nListener(); | 678 if (toLayoutBlockFlow(m_layoutObject)->firstLineBox() || mouseButtonList ener()) |
| 679 return false; | |
| 680 | |
| 681 if (ignoredReasons) | |
| 682 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Uninteresti ng, createBooleanValue(true))); | |
| 683 return true; | |
| 684 } | |
| 625 | 685 |
| 626 // ignore images seemingly used as spacers | 686 // ignore images seemingly used as spacers |
| 627 if (isImage()) { | 687 if (isImage()) { |
| 628 | 688 |
| 629 // If the image can take focus, it should not be ignored, lest the user not be able to interact with something important. | 689 // If the image can take focus, it should not be ignored, lest the user not be able to interact with something important. |
| 630 if (canSetFocusAttribute()) | 690 if (canSetFocusAttribute()) |
| 631 return false; | 691 return false; |
| 632 | 692 |
| 633 if (node && node->isElementNode()) { | 693 if (node && node->isElementNode()) { |
| 634 Element* elt = toElement(node); | 694 Element* elt = toElement(node); |
| 635 const AtomicString& alt = elt->getAttribute(altAttr); | 695 const AtomicString& alt = elt->getAttribute(altAttr); |
| 636 // don't ignore an image that has an alt tag | 696 // don't ignore an image that has an alt tag |
| 637 if (!alt.string().containsOnlyWhitespace()) | 697 if (!alt.string().containsOnlyWhitespace()) |
| 638 return false; | 698 return false; |
| 639 // informal standard is to ignore images with zero-length alt string s | 699 // informal standard is to ignore images with zero-length alt string s |
| 640 if (!alt.isNull()) | 700 if (!alt.isNull()) { |
| 701 if (ignoredReasons) | |
| 702 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Emp tyAlt, createBooleanValue(true))); | |
| 641 return true; | 703 return true; |
| 704 } | |
| 642 } | 705 } |
| 643 | 706 |
| 644 if (isNativeImage() && m_layoutObject->isImage()) { | 707 if (isNativeImage() && m_layoutObject->isImage()) { |
| 645 // check for one-dimensional image | 708 // check for one-dimensional image |
| 646 LayoutImage* image = toLayoutImage(m_layoutObject); | 709 LayoutImage* image = toLayoutImage(m_layoutObject); |
| 647 if (image->size().height() <= 1 || image->size().width() <= 1) | 710 if (image->size().height() <= 1 || image->size().width() <= 1) { |
| 711 if (ignoredReasons) | |
| 712 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Pro bablyPresentational, createBooleanValue(true))); | |
| 648 return true; | 713 return true; |
| 714 } | |
| 649 | 715 |
| 650 // check whether laid out image was stretched from one-dimensional f ile image | 716 // check whether laid out image was stretched from one-dimensional f ile image |
| 651 if (image->cachedImage()) { | 717 if (image->cachedImage()) { |
| 652 LayoutSize imageSize = image->cachedImage()->imageSizeForLayoutO bject(m_layoutObject, image->view()->zoomFactor()); | 718 LayoutSize imageSize = image->cachedImage()->imageSizeForLayoutO bject(m_layoutObject, image->view()->zoomFactor()); |
| 653 return imageSize.height() <= 1 || imageSize.width() <= 1; | 719 if (imageSize.height() <= 1 || imageSize.width() <= 1) { |
| 720 if (ignoredReasons) | |
| 721 ignoredReasons->addItem(createProperty(AXIgnoredReasons: :ProbablyPresentational, createBooleanValue(true))); | |
| 722 return true; | |
| 723 } | |
| 724 return false; | |
| 654 } | 725 } |
| 655 } | 726 } |
| 656 return false; | 727 return false; |
| 657 } | 728 } |
| 658 | 729 |
| 659 if (isCanvas()) { | 730 if (isCanvas()) { |
| 660 if (canvasHasFallbackContent()) | 731 if (canvasHasFallbackContent()) |
| 661 return false; | 732 return false; |
| 662 LayoutHTMLCanvas* canvas = toLayoutHTMLCanvas(m_layoutObject); | 733 LayoutHTMLCanvas* canvas = toLayoutHTMLCanvas(m_layoutObject); |
| 663 if (canvas->size().height() <= 1 || canvas->size().width() <= 1) | 734 if (canvas->size().height() <= 1 || canvas->size().width() <= 1) { |
| 735 if (ignoredReasons) | |
| 736 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Probabl yPresentational, createBooleanValue(true))); | |
| 664 return true; | 737 return true; |
| 738 } | |
| 665 // Otherwise fall through; use presence of help text, title, or descript ion to decide. | 739 // Otherwise fall through; use presence of help text, title, or descript ion to decide. |
| 666 } | 740 } |
| 667 | 741 |
| 668 if (isWebArea() || m_layoutObject->isListMarker()) | 742 if (isWebArea() || m_layoutObject->isListMarker()) |
| 669 return false; | 743 return false; |
| 670 | 744 |
| 671 // Using the help text, title or accessibility description (so we | 745 // Using the help text, title or accessibility description (so we |
| 672 // check if there's some kind of accessible name for the element) | 746 // check if there's some kind of accessible name for the element) |
| 673 // to decide an element's visibility is not as definitive as | 747 // to decide an element's visibility is not as definitive as |
| 674 // previous checks, so this should remain as one of the last. | 748 // previous checks, so this should remain as one of the last. |
| 675 // | 749 // |
| 676 // These checks are simplified in the interest of execution speed; | 750 // These checks are simplified in the interest of execution speed; |
| 677 // for example, any element having an alt attribute will make it | 751 // for example, any element having an alt attribute will make it |
| 678 // not ignored, rather than just images. | 752 // not ignored, rather than just images. |
| 679 if (!getAttribute(aria_helpAttr).isEmpty() || !getAttribute(aria_describedby Attr).isEmpty() || !getAttribute(altAttr).isEmpty() || !getAttribute(titleAttr). isEmpty()) | 753 if (!getAttribute(aria_helpAttr).isEmpty() || !getAttribute(aria_describedby Attr).isEmpty() || !getAttribute(altAttr).isEmpty() || !getAttribute(titleAttr). isEmpty()) |
| 680 return false; | 754 return false; |
| 681 | 755 |
| 682 // Don't ignore generic focusable elements like <div tabindex=0> | 756 // Don't ignore generic focusable elements like <div tabindex=0> |
| 683 // unless they're completely empty, with no children. | 757 // unless they're completely empty, with no children. |
| 684 if (isGenericFocusableElement() && node->hasChildren()) | 758 if (isGenericFocusableElement() && node->hasChildren()) |
| 685 return false; | 759 return false; |
| 686 | 760 |
| 687 if (!ariaAccessibilityDescription().isEmpty()) | 761 if (!ariaAccessibilityDescription().isEmpty()) |
| 688 return false; | 762 return false; |
| 689 | 763 |
| 690 // By default, objects should be ignored so that the AX hierarchy is not | 764 // By default, objects should be ignored so that the AX hierarchy is not |
| 691 // filled with unnecessary items. | 765 // filled with unnecessary items. |
| 766 if (ignoredReasons) | |
| 767 ignoredReasons->addItem(createProperty(AXIgnoredReasons::Uninteresting, createBooleanValue(true))); | |
| 692 return true; | 768 return true; |
| 693 } | 769 } |
| 694 | 770 |
| 695 // | 771 // |
| 696 // Properties of static elements. | 772 // Properties of static elements. |
| 697 // | 773 // |
| 698 | 774 |
| 699 const AtomicString& AXLayoutObject::accessKey() const | 775 const AtomicString& AXLayoutObject::accessKey() const |
| 700 { | 776 { |
| 701 Node* node = m_layoutObject->node(); | 777 Node* node = m_layoutObject->node(); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1005 case ImageRole: | 1081 case ImageRole: |
| 1006 case ProgressIndicatorRole: | 1082 case ProgressIndicatorRole: |
| 1007 case SpinButtonRole: | 1083 case SpinButtonRole: |
| 1008 // case SeparatorRole: | 1084 // case SeparatorRole: |
| 1009 return true; | 1085 return true; |
| 1010 default: | 1086 default: |
| 1011 return false; | 1087 return false; |
| 1012 } | 1088 } |
| 1013 } | 1089 } |
| 1014 | 1090 |
| 1015 bool AXLayoutObject::isPresentationalChildOfAriaRole() const | 1091 AXObject* AXLayoutObject::ancestorForWhichThisIsAPresentationalChild() const |
| 1016 { | 1092 { |
| 1017 // Walk the parent chain looking for a parent that has presentational childr en | 1093 // Walk the parent chain looking for a parent that has presentational childr en |
| 1018 AXObject* parent; | 1094 AXObject* parent; |
| 1019 for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalCh ildren(); parent = parent->parentObject()) | 1095 for (parent = parentObject(); parent && !parent->ariaRoleHasPresentationalCh ildren(); parent = parent->parentObject()) |
| 1020 { } | 1096 { } |
| 1021 | 1097 |
| 1022 return parent; | 1098 return parent; |
| 1023 } | 1099 } |
| 1024 | 1100 |
| 1025 bool AXLayoutObject::shouldFocusActiveDescendant() const | 1101 bool AXLayoutObject::shouldFocusActiveDescendant() const |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1834 lineBreaks.append(indexForVisiblePosition(visiblePos)); | 1910 lineBreaks.append(indexForVisiblePosition(visiblePos)); |
| 1835 savedVisiblePos = visiblePos; | 1911 savedVisiblePos = visiblePos; |
| 1836 visiblePos = nextLinePosition(visiblePos, 0); | 1912 visiblePos = nextLinePosition(visiblePos, 0); |
| 1837 } | 1913 } |
| 1838 } | 1914 } |
| 1839 | 1915 |
| 1840 // | 1916 // |
| 1841 // Private. | 1917 // Private. |
| 1842 // | 1918 // |
| 1843 | 1919 |
| 1844 bool AXLayoutObject::isAllowedChildOfTree() const | 1920 AXObject* AXLayoutObject::treeAncestorDisallowingChild() const |
| 1845 { | 1921 { |
| 1846 // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline. | 1922 // Determine if this is in a tree. If so, we apply special behavior to make it work like an AXOutline. |
| 1847 AXObject* axObj = parentObject(); | 1923 AXObject* axObj = parentObject(); |
| 1848 bool isInTree = false; | 1924 AXObject* treeAncestor = 0; |
| 1849 while (axObj) { | 1925 while (axObj) { |
| 1850 if (axObj->isTree()) { | 1926 if (axObj->isTree()) { |
| 1851 isInTree = true; | 1927 treeAncestor = axObj; |
| 1852 break; | 1928 break; |
| 1853 } | 1929 } |
| 1854 axObj = axObj->parentObject(); | 1930 axObj = axObj->parentObject(); |
| 1855 } | 1931 } |
| 1856 | 1932 |
| 1857 // If the object is in a tree, only tree items should be exposed (and the ch ildren of tree items). | 1933 // If the object is in a tree, only tree items should be exposed (and the ch ildren of tree items). |
| 1858 if (isInTree) { | 1934 if (treeAncestor) { |
| 1859 AccessibilityRole role = roleValue(); | 1935 AccessibilityRole role = roleValue(); |
| 1860 if (role != TreeItemRole && role != StaticTextRole) | 1936 if (role != TreeItemRole && role != StaticTextRole) |
| 1861 return false; | 1937 return treeAncestor; |
| 1862 } | 1938 } |
| 1863 return true; | 1939 return 0; |
| 1864 } | 1940 } |
| 1865 | 1941 |
| 1866 void AXLayoutObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& re sult) | 1942 void AXLayoutObject::ariaListboxSelectedChildren(AccessibilityChildrenVector& re sult) |
| 1867 { | 1943 { |
| 1868 bool isMulti = isMultiSelectable(); | 1944 bool isMulti = isMultiSelectable(); |
| 1869 | 1945 |
| 1870 for (const auto& child : children()) { | 1946 for (const auto& child : children()) { |
| 1871 // Every child should have aria-role option, and if so, check for select ed attribute/state. | 1947 // Every child should have aria-role option, and if so, check for select ed attribute/state. |
| 1872 if (child->isSelected() && child->ariaRoleAttribute() == ListBoxOptionRo le) { | 1948 if (child->isSelected() && child->ariaRoleAttribute() == ListBoxOptionRo le) { |
| 1873 result.append(child); | 1949 result.append(child); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2268 if (label && label->layoutObject()) { | 2344 if (label && label->layoutObject()) { |
| 2269 LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementR ect(); | 2345 LayoutRect labelRect = axObjectCache()->getOrCreate(label)->elementR ect(); |
| 2270 result.unite(labelRect); | 2346 result.unite(labelRect); |
| 2271 } | 2347 } |
| 2272 } | 2348 } |
| 2273 | 2349 |
| 2274 return result; | 2350 return result; |
| 2275 } | 2351 } |
| 2276 | 2352 |
| 2277 } // namespace blink | 2353 } // namespace blink |
| OLD | NEW |