| 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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 // Whether objects are ignored, i.e. not included in the tree. | 476 // Whether objects are ignored, i.e. not included in the tree. |
| 477 // | 477 // |
| 478 | 478 |
| 479 AXObjectInclusion AXLayoutObject::defaultObjectInclusion( | 479 AXObjectInclusion AXLayoutObject::defaultObjectInclusion( |
| 480 IgnoredReasons* ignoredReasons) const { | 480 IgnoredReasons* ignoredReasons) const { |
| 481 // The following cases can apply to any element that's a subclass of | 481 // The following cases can apply to any element that's a subclass of |
| 482 // AXLayoutObject. | 482 // AXLayoutObject. |
| 483 | 483 |
| 484 if (!m_layoutObject) { | 484 if (!m_layoutObject) { |
| 485 if (ignoredReasons) | 485 if (ignoredReasons) |
| 486 ignoredReasons->append(IgnoredReason(AXNotRendered)); | 486 ignoredReasons->push_back(IgnoredReason(AXNotRendered)); |
| 487 return IgnoreObject; | 487 return IgnoreObject; |
| 488 } | 488 } |
| 489 | 489 |
| 490 if (m_layoutObject->style()->visibility() != EVisibility::Visible) { | 490 if (m_layoutObject->style()->visibility() != EVisibility::Visible) { |
| 491 // aria-hidden is meant to override visibility as the determinant in AX | 491 // aria-hidden is meant to override visibility as the determinant in AX |
| 492 // hierarchy inclusion. | 492 // hierarchy inclusion. |
| 493 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) | 493 if (equalIgnoringCase(getAttribute(aria_hiddenAttr), "false")) |
| 494 return DefaultBehavior; | 494 return DefaultBehavior; |
| 495 | 495 |
| 496 if (ignoredReasons) | 496 if (ignoredReasons) |
| 497 ignoredReasons->append(IgnoredReason(AXNotVisible)); | 497 ignoredReasons->push_back(IgnoredReason(AXNotVisible)); |
| 498 return IgnoreObject; | 498 return IgnoreObject; |
| 499 } | 499 } |
| 500 | 500 |
| 501 return AXObject::defaultObjectInclusion(ignoredReasons); | 501 return AXObject::defaultObjectInclusion(ignoredReasons); |
| 502 } | 502 } |
| 503 | 503 |
| 504 bool AXLayoutObject::computeAccessibilityIsIgnored( | 504 bool AXLayoutObject::computeAccessibilityIsIgnored( |
| 505 IgnoredReasons* ignoredReasons) const { | 505 IgnoredReasons* ignoredReasons) const { |
| 506 #if ENABLE(ASSERT) | 506 #if ENABLE(ASSERT) |
| 507 ASSERT(m_initialized); | 507 ASSERT(m_initialized); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 519 if (decision == IgnoreObject) | 519 if (decision == IgnoreObject) |
| 520 return true; | 520 return true; |
| 521 | 521 |
| 522 if (m_layoutObject->isAnonymousBlock()) | 522 if (m_layoutObject->isAnonymousBlock()) |
| 523 return true; | 523 return true; |
| 524 | 524 |
| 525 // If this element is within a parent that cannot have children, it should not | 525 // If this element is within a parent that cannot have children, it should not |
| 526 // be exposed. | 526 // be exposed. |
| 527 if (isDescendantOfLeafNode()) { | 527 if (isDescendantOfLeafNode()) { |
| 528 if (ignoredReasons) | 528 if (ignoredReasons) |
| 529 ignoredReasons->append( | 529 ignoredReasons->push_back( |
| 530 IgnoredReason(AXAncestorIsLeafNode, leafNodeAncestor())); | 530 IgnoredReason(AXAncestorIsLeafNode, leafNodeAncestor())); |
| 531 return true; | 531 return true; |
| 532 } | 532 } |
| 533 | 533 |
| 534 if (roleValue() == IgnoredRole) { | 534 if (roleValue() == IgnoredRole) { |
| 535 if (ignoredReasons) | 535 if (ignoredReasons) |
| 536 ignoredReasons->append(IgnoredReason(AXUninteresting)); | 536 ignoredReasons->push_back(IgnoredReason(AXUninteresting)); |
| 537 return true; | 537 return true; |
| 538 } | 538 } |
| 539 | 539 |
| 540 if (hasInheritedPresentationalRole()) { | 540 if (hasInheritedPresentationalRole()) { |
| 541 if (ignoredReasons) { | 541 if (ignoredReasons) { |
| 542 const AXObject* inheritsFrom = inheritsPresentationalRoleFrom(); | 542 const AXObject* inheritsFrom = inheritsPresentationalRoleFrom(); |
| 543 if (inheritsFrom == this) | 543 if (inheritsFrom == this) |
| 544 ignoredReasons->append(IgnoredReason(AXPresentationalRole)); | 544 ignoredReasons->push_back(IgnoredReason(AXPresentationalRole)); |
| 545 else | 545 else |
| 546 ignoredReasons->append( | 546 ignoredReasons->push_back( |
| 547 IgnoredReason(AXInheritsPresentation, inheritsFrom)); | 547 IgnoredReason(AXInheritsPresentation, inheritsFrom)); |
| 548 } | 548 } |
| 549 return true; | 549 return true; |
| 550 } | 550 } |
| 551 | 551 |
| 552 // An ARIA tree can only have tree items and static text as children. | 552 // An ARIA tree can only have tree items and static text as children. |
| 553 if (AXObject* treeAncestor = treeAncestorDisallowingChild()) { | 553 if (AXObject* treeAncestor = treeAncestorDisallowingChild()) { |
| 554 if (ignoredReasons) | 554 if (ignoredReasons) |
| 555 ignoredReasons->append( | 555 ignoredReasons->push_back( |
| 556 IgnoredReason(AXAncestorDisallowsChild, treeAncestor)); | 556 IgnoredReason(AXAncestorDisallowsChild, treeAncestor)); |
| 557 return true; | 557 return true; |
| 558 } | 558 } |
| 559 | 559 |
| 560 // A LayoutPart is an iframe element or embedded object element or something | 560 // A LayoutPart is an iframe element or embedded object element or something |
| 561 // like that. We don't want to ignore those. | 561 // like that. We don't want to ignore those. |
| 562 if (m_layoutObject->isLayoutPart()) | 562 if (m_layoutObject->isLayoutPart()) |
| 563 return false; | 563 return false; |
| 564 | 564 |
| 565 // Make sure renderers with layers stay in the tree. | 565 // Make sure renderers with layers stay in the tree. |
| 566 if (getLayoutObject() && getLayoutObject()->hasLayer() && getNode() && | 566 if (getLayoutObject() && getLayoutObject()->hasLayer() && getNode() && |
| 567 getNode()->hasChildren()) | 567 getNode()->hasChildren()) |
| 568 return false; | 568 return false; |
| 569 | 569 |
| 570 // Find out if this element is inside of a label element. If so, it may be | 570 // Find out if this element is inside of a label element. If so, it may be |
| 571 // ignored because it's the label for a checkbox or radio button. | 571 // ignored because it's the label for a checkbox or radio button. |
| 572 AXObject* controlObject = correspondingControlForLabelElement(); | 572 AXObject* controlObject = correspondingControlForLabelElement(); |
| 573 if (controlObject && controlObject->isCheckboxOrRadio() && | 573 if (controlObject && controlObject->isCheckboxOrRadio() && |
| 574 controlObject->nameFromLabelElement()) { | 574 controlObject->nameFromLabelElement()) { |
| 575 if (ignoredReasons) { | 575 if (ignoredReasons) { |
| 576 HTMLLabelElement* label = labelElementContainer(); | 576 HTMLLabelElement* label = labelElementContainer(); |
| 577 if (label && label != getNode()) { | 577 if (label && label != getNode()) { |
| 578 AXObject* labelAXObject = axObjectCache().getOrCreate(label); | 578 AXObject* labelAXObject = axObjectCache().getOrCreate(label); |
| 579 ignoredReasons->append(IgnoredReason(AXLabelContainer, labelAXObject)); | 579 ignoredReasons->push_back( |
| 580 IgnoredReason(AXLabelContainer, labelAXObject)); |
| 580 } | 581 } |
| 581 | 582 |
| 582 ignoredReasons->append(IgnoredReason(AXLabelFor, controlObject)); | 583 ignoredReasons->push_back(IgnoredReason(AXLabelFor, controlObject)); |
| 583 } | 584 } |
| 584 return true; | 585 return true; |
| 585 } | 586 } |
| 586 | 587 |
| 587 if (m_layoutObject->isBR()) | 588 if (m_layoutObject->isBR()) |
| 588 return false; | 589 return false; |
| 589 | 590 |
| 590 if (m_layoutObject->isText()) { | 591 if (m_layoutObject->isText()) { |
| 591 // Static text beneath MenuItems and MenuButtons are just reported along | 592 // Static text beneath MenuItems and MenuButtons are just reported along |
| 592 // with the menu item, so it's ignored on an individual level. | 593 // with the menu item, so it's ignored on an individual level. |
| 593 AXObject* parent = parentObjectUnignored(); | 594 AXObject* parent = parentObjectUnignored(); |
| 594 if (parent && (parent->ariaRoleAttribute() == MenuItemRole || | 595 if (parent && (parent->ariaRoleAttribute() == MenuItemRole || |
| 595 parent->ariaRoleAttribute() == MenuButtonRole)) { | 596 parent->ariaRoleAttribute() == MenuButtonRole)) { |
| 596 if (ignoredReasons) | 597 if (ignoredReasons) |
| 597 ignoredReasons->append( | 598 ignoredReasons->push_back( |
| 598 IgnoredReason(AXStaticTextUsedAsNameFor, parent)); | 599 IgnoredReason(AXStaticTextUsedAsNameFor, parent)); |
| 599 return true; | 600 return true; |
| 600 } | 601 } |
| 601 LayoutText* layoutText = toLayoutText(m_layoutObject); | 602 LayoutText* layoutText = toLayoutText(m_layoutObject); |
| 602 if (!layoutText->hasTextBoxes()) { | 603 if (!layoutText->hasTextBoxes()) { |
| 603 if (ignoredReasons) | 604 if (ignoredReasons) |
| 604 ignoredReasons->append(IgnoredReason(AXEmptyText)); | 605 ignoredReasons->push_back(IgnoredReason(AXEmptyText)); |
| 605 return true; | 606 return true; |
| 606 } | 607 } |
| 607 | 608 |
| 608 // Don't ignore static text in editable text controls. | 609 // Don't ignore static text in editable text controls. |
| 609 for (AXObject* parent = parentObject(); parent; | 610 for (AXObject* parent = parentObject(); parent; |
| 610 parent = parent->parentObject()) { | 611 parent = parent->parentObject()) { |
| 611 if (parent->roleValue() == TextFieldRole) | 612 if (parent->roleValue() == TextFieldRole) |
| 612 return false; | 613 return false; |
| 613 } | 614 } |
| 614 | 615 |
| 615 // Text elements that are just empty whitespace should not be returned. | 616 // Text elements that are just empty whitespace should not be returned. |
| 616 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', | 617 // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', |
| 617 // or similar... | 618 // or similar... |
| 618 if (layoutText->text().impl()->containsOnlyWhitespace()) { | 619 if (layoutText->text().impl()->containsOnlyWhitespace()) { |
| 619 if (ignoredReasons) | 620 if (ignoredReasons) |
| 620 ignoredReasons->append(IgnoredReason(AXEmptyText)); | 621 ignoredReasons->push_back(IgnoredReason(AXEmptyText)); |
| 621 return true; | 622 return true; |
| 622 } | 623 } |
| 623 return false; | 624 return false; |
| 624 } | 625 } |
| 625 | 626 |
| 626 if (isHeading()) | 627 if (isHeading()) |
| 627 return false; | 628 return false; |
| 628 | 629 |
| 629 if (isLandmarkRelated()) | 630 if (isLandmarkRelated()) |
| 630 return false; | 631 return false; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 // <span> tags are inline tags and not meant to convey information if they | 706 // <span> tags are inline tags and not meant to convey information if they |
| 706 // have no other aria information on them. If we don't ignore them, they may | 707 // have no other aria information on them. If we don't ignore them, they may |
| 707 // emit signals expected to come from their parent. In addition, because | 708 // emit signals expected to come from their parent. In addition, because |
| 708 // included spans are GroupRole objects, and GroupRole objects are often | 709 // included spans are GroupRole objects, and GroupRole objects are often |
| 709 // containers with meaningful information, the inclusion of a span can have | 710 // containers with meaningful information, the inclusion of a span can have |
| 710 // the side effect of causing the immediate parent accessible to be ignored. | 711 // the side effect of causing the immediate parent accessible to be ignored. |
| 711 // This is especially problematic for platforms which have distinct roles for | 712 // This is especially problematic for platforms which have distinct roles for |
| 712 // textual block elements. | 713 // textual block elements. |
| 713 if (isHTMLSpanElement(node)) { | 714 if (isHTMLSpanElement(node)) { |
| 714 if (ignoredReasons) | 715 if (ignoredReasons) |
| 715 ignoredReasons->append(IgnoredReason(AXUninteresting)); | 716 ignoredReasons->push_back(IgnoredReason(AXUninteresting)); |
| 716 return true; | 717 return true; |
| 717 } | 718 } |
| 718 | 719 |
| 719 if (isImage()) | 720 if (isImage()) |
| 720 return false; | 721 return false; |
| 721 | 722 |
| 722 if (isCanvas()) { | 723 if (isCanvas()) { |
| 723 if (canvasHasFallbackContent()) | 724 if (canvasHasFallbackContent()) |
| 724 return false; | 725 return false; |
| 725 LayoutHTMLCanvas* canvas = toLayoutHTMLCanvas(m_layoutObject); | 726 LayoutHTMLCanvas* canvas = toLayoutHTMLCanvas(m_layoutObject); |
| 726 if (canvas->size().height() <= 1 || canvas->size().width() <= 1) { | 727 if (canvas->size().height() <= 1 || canvas->size().width() <= 1) { |
| 727 if (ignoredReasons) | 728 if (ignoredReasons) |
| 728 ignoredReasons->append(IgnoredReason(AXProbablyPresentational)); | 729 ignoredReasons->push_back(IgnoredReason(AXProbablyPresentational)); |
| 729 return true; | 730 return true; |
| 730 } | 731 } |
| 731 // Otherwise fall through; use presence of help text, title, or description | 732 // Otherwise fall through; use presence of help text, title, or description |
| 732 // to decide. | 733 // to decide. |
| 733 } | 734 } |
| 734 | 735 |
| 735 if (isWebArea() || m_layoutObject->isListMarker()) | 736 if (isWebArea() || m_layoutObject->isListMarker()) |
| 736 return false; | 737 return false; |
| 737 | 738 |
| 738 // Using the help text, title or accessibility description (so we | 739 // Using the help text, title or accessibility description (so we |
| (...skipping 24 matching lines...) Expand all Loading... |
| 763 !canSetFocusAttribute()) { | 764 !canSetFocusAttribute()) { |
| 764 // If the layout object has any plain text in it, that text will be | 765 // If the layout object has any plain text in it, that text will be |
| 765 // inside a LineBox, so the layout object will have a first LineBox. | 766 // inside a LineBox, so the layout object will have a first LineBox. |
| 766 bool hasAnyText = !!toLayoutBlockFlow(m_layoutObject)->firstLineBox(); | 767 bool hasAnyText = !!toLayoutBlockFlow(m_layoutObject)->firstLineBox(); |
| 767 | 768 |
| 768 // Always include interesting-looking objects. | 769 // Always include interesting-looking objects. |
| 769 if (hasAnyText || mouseButtonListener()) | 770 if (hasAnyText || mouseButtonListener()) |
| 770 return false; | 771 return false; |
| 771 | 772 |
| 772 if (ignoredReasons) | 773 if (ignoredReasons) |
| 773 ignoredReasons->append(IgnoredReason(AXUninteresting)); | 774 ignoredReasons->push_back(IgnoredReason(AXUninteresting)); |
| 774 return true; | 775 return true; |
| 775 } | 776 } |
| 776 | 777 |
| 777 // By default, objects should be ignored so that the AX hierarchy is not | 778 // By default, objects should be ignored so that the AX hierarchy is not |
| 778 // filled with unnecessary items. | 779 // filled with unnecessary items. |
| 779 if (ignoredReasons) | 780 if (ignoredReasons) |
| 780 ignoredReasons->append(IgnoredReason(AXUninteresting)); | 781 ignoredReasons->push_back(IgnoredReason(AXUninteresting)); |
| 781 return true; | 782 return true; |
| 782 } | 783 } |
| 783 | 784 |
| 784 // | 785 // |
| 785 // Properties of static elements. | 786 // Properties of static elements. |
| 786 // | 787 // |
| 787 | 788 |
| 788 const AtomicString& AXLayoutObject::accessKey() const { | 789 const AtomicString& AXLayoutObject::accessKey() const { |
| 789 Node* node = m_layoutObject->node(); | 790 Node* node = m_layoutObject->node(); |
| 790 if (!node) | 791 if (!node) |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 textAlternative = layoutText->text(); | 1213 textAlternative = layoutText->text(); |
| 1213 foundTextAlternative = true; | 1214 foundTextAlternative = true; |
| 1214 } else if (m_layoutObject->isListMarker() && !recursive) { | 1215 } else if (m_layoutObject->isListMarker() && !recursive) { |
| 1215 textAlternative = toLayoutListMarker(m_layoutObject)->text(); | 1216 textAlternative = toLayoutListMarker(m_layoutObject)->text(); |
| 1216 foundTextAlternative = true; | 1217 foundTextAlternative = true; |
| 1217 } | 1218 } |
| 1218 | 1219 |
| 1219 if (foundTextAlternative) { | 1220 if (foundTextAlternative) { |
| 1220 nameFrom = AXNameFromContents; | 1221 nameFrom = AXNameFromContents; |
| 1221 if (nameSources) { | 1222 if (nameSources) { |
| 1222 nameSources->append(NameSource(false)); | 1223 nameSources->push_back(NameSource(false)); |
| 1223 nameSources->back().type = nameFrom; | 1224 nameSources->back().type = nameFrom; |
| 1224 nameSources->back().text = textAlternative; | 1225 nameSources->back().text = textAlternative; |
| 1225 } | 1226 } |
| 1226 return textAlternative; | 1227 return textAlternative; |
| 1227 } | 1228 } |
| 1228 } | 1229 } |
| 1229 | 1230 |
| 1230 return AXNodeObject::textAlternative(recursive, inAriaLabelledByTraversal, | 1231 return AXNodeObject::textAlternative(recursive, inAriaLabelledByTraversal, |
| 1231 visited, nameFrom, relatedObjects, | 1232 visited, nameFrom, relatedObjects, |
| 1232 nameSources); | 1233 nameSources); |
| (...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2151 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. | 2152 // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. |
| 2152 return; | 2153 return; |
| 2153 } | 2154 } |
| 2154 | 2155 |
| 2155 LayoutText* layoutText = toLayoutText(getLayoutObject()); | 2156 LayoutText* layoutText = toLayoutText(getLayoutObject()); |
| 2156 for (RefPtr<AbstractInlineTextBox> box = | 2157 for (RefPtr<AbstractInlineTextBox> box = |
| 2157 layoutText->firstAbstractInlineTextBox(); | 2158 layoutText->firstAbstractInlineTextBox(); |
| 2158 box.get(); box = box->nextInlineTextBox()) { | 2159 box.get(); box = box->nextInlineTextBox()) { |
| 2159 AXObject* axObject = axObjectCache().getOrCreate(box.get()); | 2160 AXObject* axObject = axObjectCache().getOrCreate(box.get()); |
| 2160 if (!axObject->accessibilityIsIgnored()) | 2161 if (!axObject->accessibilityIsIgnored()) |
| 2161 m_children.append(axObject); | 2162 m_children.push_back(axObject); |
| 2162 } | 2163 } |
| 2163 } | 2164 } |
| 2164 | 2165 |
| 2165 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const { | 2166 void AXLayoutObject::lineBreaks(Vector<int>& lineBreaks) const { |
| 2166 if (!isTextControl()) | 2167 if (!isTextControl()) |
| 2167 return; | 2168 return; |
| 2168 | 2169 |
| 2169 VisiblePosition visiblePos = visiblePositionForIndex(0); | 2170 VisiblePosition visiblePos = visiblePositionForIndex(0); |
| 2170 VisiblePosition prevVisiblePos = visiblePos; | 2171 VisiblePosition prevVisiblePos = visiblePos; |
| 2171 visiblePos = nextLinePosition(visiblePos, LayoutUnit(), HasEditableAXRole); | 2172 visiblePos = nextLinePosition(visiblePos, LayoutUnit(), HasEditableAXRole); |
| 2172 // nextLinePosition moves to the end of the current line when there are | 2173 // nextLinePosition moves to the end of the current line when there are |
| 2173 // no more lines. | 2174 // no more lines. |
| 2174 while (visiblePos.isNotNull() && !inSameLine(prevVisiblePos, visiblePos)) { | 2175 while (visiblePos.isNotNull() && !inSameLine(prevVisiblePos, visiblePos)) { |
| 2175 lineBreaks.append(indexForVisiblePosition(visiblePos)); | 2176 lineBreaks.push_back(indexForVisiblePosition(visiblePos)); |
| 2176 prevVisiblePos = visiblePos; | 2177 prevVisiblePos = visiblePos; |
| 2177 visiblePos = nextLinePosition(visiblePos, LayoutUnit(), HasEditableAXRole); | 2178 visiblePos = nextLinePosition(visiblePos, LayoutUnit(), HasEditableAXRole); |
| 2178 | 2179 |
| 2179 // Make sure we always make forward progress. | 2180 // Make sure we always make forward progress. |
| 2180 if (visiblePos.deepEquivalent().compareTo(prevVisiblePos.deepEquivalent()) < | 2181 if (visiblePos.deepEquivalent().compareTo(prevVisiblePos.deepEquivalent()) < |
| 2181 0) | 2182 0) |
| 2182 break; | 2183 break; |
| 2183 } | 2184 } |
| 2184 } | 2185 } |
| 2185 | 2186 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2417 HTMLInputElement& input = toHTMLInputElement(*node); | 2418 HTMLInputElement& input = toHTMLInputElement(*node); |
| 2418 Element* spinButtonElement = input.userAgentShadowRoot()->getElementById( | 2419 Element* spinButtonElement = input.userAgentShadowRoot()->getElementById( |
| 2419 ShadowElementNames::spinButton()); | 2420 ShadowElementNames::spinButton()); |
| 2420 if (!spinButtonElement || !spinButtonElement->isSpinButtonElement()) | 2421 if (!spinButtonElement || !spinButtonElement->isSpinButtonElement()) |
| 2421 return; | 2422 return; |
| 2422 | 2423 |
| 2423 AXSpinButton* axSpinButton = | 2424 AXSpinButton* axSpinButton = |
| 2424 toAXSpinButton(axObjectCache().getOrCreate(SpinButtonRole)); | 2425 toAXSpinButton(axObjectCache().getOrCreate(SpinButtonRole)); |
| 2425 axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement)); | 2426 axSpinButton->setSpinButtonElement(toSpinButtonElement(spinButtonElement)); |
| 2426 axSpinButton->setParent(this); | 2427 axSpinButton->setParent(this); |
| 2427 m_children.append(axSpinButton); | 2428 m_children.push_back(axSpinButton); |
| 2428 } | 2429 } |
| 2429 | 2430 |
| 2430 void AXLayoutObject::addImageMapChildren() { | 2431 void AXLayoutObject::addImageMapChildren() { |
| 2431 LayoutBoxModelObject* cssBox = getLayoutBoxModelObject(); | 2432 LayoutBoxModelObject* cssBox = getLayoutBoxModelObject(); |
| 2432 if (!cssBox || !cssBox->isLayoutImage()) | 2433 if (!cssBox || !cssBox->isLayoutImage()) |
| 2433 return; | 2434 return; |
| 2434 | 2435 |
| 2435 HTMLMapElement* map = toLayoutImage(cssBox)->imageMap(); | 2436 HTMLMapElement* map = toLayoutImage(cssBox)->imageMap(); |
| 2436 if (!map) | 2437 if (!map) |
| 2437 return; | 2438 return; |
| 2438 | 2439 |
| 2439 for (HTMLAreaElement& area : | 2440 for (HTMLAreaElement& area : |
| 2440 Traversal<HTMLAreaElement>::descendantsOf(*map)) { | 2441 Traversal<HTMLAreaElement>::descendantsOf(*map)) { |
| 2441 // add an <area> element for this child if it has a link | 2442 // add an <area> element for this child if it has a link |
| 2442 AXObject* obj = axObjectCache().getOrCreate(&area); | 2443 AXObject* obj = axObjectCache().getOrCreate(&area); |
| 2443 if (obj) { | 2444 if (obj) { |
| 2444 AXImageMapLink* areaObject = toAXImageMapLink(obj); | 2445 AXImageMapLink* areaObject = toAXImageMapLink(obj); |
| 2445 areaObject->setParent(this); | 2446 areaObject->setParent(this); |
| 2446 ASSERT(areaObject->axObjectID() != 0); | 2447 ASSERT(areaObject->axObjectID() != 0); |
| 2447 if (!areaObject->accessibilityIsIgnored()) | 2448 if (!areaObject->accessibilityIsIgnored()) |
| 2448 m_children.append(areaObject); | 2449 m_children.push_back(areaObject); |
| 2449 else | 2450 else |
| 2450 axObjectCache().remove(areaObject->axObjectID()); | 2451 axObjectCache().remove(areaObject->axObjectID()); |
| 2451 } | 2452 } |
| 2452 } | 2453 } |
| 2453 } | 2454 } |
| 2454 | 2455 |
| 2455 void AXLayoutObject::addCanvasChildren() { | 2456 void AXLayoutObject::addCanvasChildren() { |
| 2456 if (!isHTMLCanvasElement(getNode())) | 2457 if (!isHTMLCanvasElement(getNode())) |
| 2457 return; | 2458 return; |
| 2458 | 2459 |
| 2459 // If it's a canvas, it won't have laid out children, but it might have | 2460 // If it's a canvas, it won't have laid out children, but it might have |
| 2460 // accessible fallback content. Clear m_haveChildren because | 2461 // accessible fallback content. Clear m_haveChildren because |
| 2461 // AXNodeObject::addChildren will expect it to be false. | 2462 // AXNodeObject::addChildren will expect it to be false. |
| 2462 ASSERT(!m_children.size()); | 2463 ASSERT(!m_children.size()); |
| 2463 m_haveChildren = false; | 2464 m_haveChildren = false; |
| 2464 AXNodeObject::addChildren(); | 2465 AXNodeObject::addChildren(); |
| 2465 } | 2466 } |
| 2466 | 2467 |
| 2467 void AXLayoutObject::addPopupChildren() { | 2468 void AXLayoutObject::addPopupChildren() { |
| 2468 if (!isHTMLInputElement(getNode())) | 2469 if (!isHTMLInputElement(getNode())) |
| 2469 return; | 2470 return; |
| 2470 if (AXObject* axPopup = toHTMLInputElement(getNode())->popupRootAXObject()) | 2471 if (AXObject* axPopup = toHTMLInputElement(getNode())->popupRootAXObject()) |
| 2471 m_children.append(axPopup); | 2472 m_children.push_back(axPopup); |
| 2472 } | 2473 } |
| 2473 | 2474 |
| 2474 void AXLayoutObject::addRemoteSVGChildren() { | 2475 void AXLayoutObject::addRemoteSVGChildren() { |
| 2475 AXSVGRoot* root = remoteSVGRootElement(); | 2476 AXSVGRoot* root = remoteSVGRootElement(); |
| 2476 if (!root) | 2477 if (!root) |
| 2477 return; | 2478 return; |
| 2478 | 2479 |
| 2479 root->setParent(this); | 2480 root->setParent(this); |
| 2480 | 2481 |
| 2481 if (root->accessibilityIsIgnored()) { | 2482 if (root->accessibilityIsIgnored()) { |
| 2482 for (const auto& child : root->children()) | 2483 for (const auto& child : root->children()) |
| 2483 m_children.append(child); | 2484 m_children.push_back(child); |
| 2484 } else { | 2485 } else { |
| 2485 m_children.append(root); | 2486 m_children.push_back(root); |
| 2486 } | 2487 } |
| 2487 } | 2488 } |
| 2488 | 2489 |
| 2489 bool AXLayoutObject::elementAttributeValue( | 2490 bool AXLayoutObject::elementAttributeValue( |
| 2490 const QualifiedName& attributeName) const { | 2491 const QualifiedName& attributeName) const { |
| 2491 if (!m_layoutObject) | 2492 if (!m_layoutObject) |
| 2492 return false; | 2493 return false; |
| 2493 | 2494 |
| 2494 return equalIgnoringCase(getAttribute(attributeName), "true"); | 2495 return equalIgnoringCase(getAttribute(attributeName), "true"); |
| 2495 } | 2496 } |
| 2496 | 2497 |
| 2497 } // namespace blink | 2498 } // namespace blink |
| OLD | NEW |