Changeset 128353 in webkit
- Timestamp:
- Sep 12, 2012 1:13:47 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r128348 r128353 1 2012-09-12 Sheriff Bot <webkit.review.bot@gmail.com> 2 3 Unreviewed, rolling out r128318 and r128332. 4 http://trac.webkit.org/changeset/128318 5 http://trac.webkit.org/changeset/128332 6 https://bugs.webkit.org/show_bug.cgi?id=96547 7 8 Caused accessibility test failures on snow leopard (Requested 9 by jamesr_ on #webkit). 10 11 * accessibility/canvas-fallback-content-2-expected.txt: Removed. 12 * accessibility/canvas-fallback-content-2.html: Removed. 13 1 14 2012-09-12 Alex Sakhartchouk <alexst@chromium.org> 2 15 -
trunk/Source/WebCore/ChangeLog
r128350 r128353 1 2012-09-12 Sheriff Bot <webkit.review.bot@gmail.com> 2 3 Unreviewed, rolling out r128318 and r128332. 4 http://trac.webkit.org/changeset/128318 5 http://trac.webkit.org/changeset/128332 6 https://bugs.webkit.org/show_bug.cgi?id=96547 7 8 Caused accessibility test failures on snow leopard (Requested 9 by jamesr_ on #webkit). 10 11 * accessibility/AccessibilityNodeObject.cpp: 12 (WebCore::AccessibilityNodeObject::determineAccessibilityRole): 13 (WebCore::AccessibilityNodeObject::accessibilityIsIgnored): 14 (WebCore::AccessibilityNodeObject::canSetFocusAttribute): 15 * accessibility/AccessibilityNodeObject.h: 16 (AccessibilityNodeObject): 17 (WebCore::AccessibilityNodeObject::node): 18 * accessibility/AccessibilityRenderObject.cpp: 19 (WebCore): 20 (WebCore::AccessibilityRenderObject::isWebArea): 21 (WebCore::AccessibilityRenderObject::isImageButton): 22 (WebCore::AccessibilityRenderObject::isAnchor): 23 (WebCore::AccessibilityRenderObject::isNativeTextControl): 24 (WebCore::AccessibilityRenderObject::isSearchField): 25 (WebCore::AccessibilityRenderObject::isNativeImage): 26 (WebCore::AccessibilityRenderObject::isImage): 27 (WebCore::AccessibilityRenderObject::isPasswordField): 28 (WebCore::AccessibilityRenderObject::isInputImage): 29 (WebCore::AccessibilityRenderObject::isProgressIndicator): 30 (WebCore::AccessibilityRenderObject::isSlider): 31 (WebCore::AccessibilityRenderObject::isMenuRelated): 32 (WebCore::AccessibilityRenderObject::isMenu): 33 (WebCore::AccessibilityRenderObject::isMenuBar): 34 (WebCore::AccessibilityRenderObject::isMenuButton): 35 (WebCore::AccessibilityRenderObject::isMenuItem): 36 (WebCore::AccessibilityRenderObject::isPressed): 37 (WebCore::AccessibilityRenderObject::isIndeterminate): 38 (WebCore::AccessibilityRenderObject::isNativeCheckboxOrRadio): 39 (WebCore::AccessibilityRenderObject::isChecked): 40 (WebCore::AccessibilityRenderObject::isHovered): 41 (WebCore::AccessibilityRenderObject::isMultiSelectable): 42 (WebCore::AccessibilityRenderObject::isReadOnly): 43 (WebCore::AccessibilityRenderObject::headingLevel): 44 (WebCore::AccessibilityRenderObject::isHeading): 45 (WebCore::AccessibilityRenderObject::isLink): 46 (WebCore::AccessibilityRenderObject::isControl): 47 (WebCore::AccessibilityRenderObject::isFieldset): 48 (WebCore::AccessibilityRenderObject::isGroup): 49 (WebCore::AccessibilityRenderObject::selectedRadioButton): 50 (WebCore::AccessibilityRenderObject::selectedTabItem): 51 (WebCore::AccessibilityRenderObject::actionElement): 52 (WebCore::AccessibilityRenderObject::mouseButtonListener): 53 (WebCore::AccessibilityRenderObject::alterSliderValue): 54 (WebCore::AccessibilityRenderObject::increment): 55 (WebCore::AccessibilityRenderObject::decrement): 56 (WebCore::siblingWithAriaRole): 57 (WebCore::AccessibilityRenderObject::menuElementForMenuButton): 58 (WebCore::AccessibilityRenderObject::menuForMenuButton): 59 (WebCore::AccessibilityRenderObject::menuItemElementForMenu): 60 (WebCore::AccessibilityRenderObject::menuButtonForMenu): 61 (WebCore::AccessibilityRenderObject::hierarchicalLevel): 62 (WebCore::AccessibilityRenderObject::checkboxOrRadioValue): 63 (WebCore::AccessibilityRenderObject::valueDescription): 64 (WebCore::AccessibilityRenderObject::stepValueForRange): 65 (WebCore::AccessibilityRenderObject::isARIARange): 66 (WebCore::AccessibilityRenderObject::valueForRange): 67 (WebCore::AccessibilityRenderObject::maxValueForRange): 68 (WebCore::AccessibilityRenderObject::minValueForRange): 69 (WebCore::accessibleNameForNode): 70 (WebCore::AccessibilityRenderObject::accessibilityDescriptionForElements): 71 (WebCore::AccessibilityRenderObject::elementsFromAttribute): 72 (WebCore::AccessibilityRenderObject::ariaLabeledByElements): 73 (WebCore::AccessibilityRenderObject::ariaLabeledByAttribute): 74 (WebCore::labelForElement): 75 (WebCore::AccessibilityRenderObject::title): 76 (WebCore::AccessibilityRenderObject::ariaAccessibilityDescription): 77 (WebCore::AccessibilityRenderObject::accessibilityDescription): 78 (WebCore::AccessibilityRenderObject::isDescendantOfBarrenParent): 79 (WebCore::AccessibilityRenderObject::text): 80 (WebCore::AccessibilityRenderObject::isRequired): 81 (WebCore::AccessibilityRenderObject::changeValueByStep): 82 (WebCore::AccessibilityRenderObject::changeValueByPercent): 83 (WebCore::AccessibilityRenderObject::isEnabled): 84 (WebCore::AccessibilityRenderObject::isGenericFocusableElement): 85 (WebCore::AccessibilityRenderObject::canHaveChildren): 86 * accessibility/AccessibilityRenderObject.h: 87 (AccessibilityRenderObject): 88 1 89 2012-09-12 Christophe Dumez <christophe.dumez@intel.com> 2 90 -
trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp
r128332 r128353 260 260 if (input->isTextButton()) 261 261 return buttonRoleType(); 262 if (input->isRangeControl())263 return SliderRole;264 262 return TextFieldRole; 265 263 } 266 264 if (node()->hasTagName(selectTag)) { 267 265 HTMLSelectElement* selectElement = toHTMLSelectElement(node()); 268 return selectElement->multiple() ? ListBoxRole : PopUpButtonRole; 269 } 270 if (node()->hasTagName(textareaTag)) 271 return TextAreaRole; 272 if (headingLevel()) 273 return HeadingRole; 274 if (node()->hasTagName(divTag)) 275 return DivRole; 276 if (node()->hasTagName(pTag)) 277 return ParagraphRole; 278 if (node()->hasTagName(labelTag)) 279 return LabelRole; 266 return selectElement->multiple() ? ListRole : PopUpButtonRole; 267 } 280 268 if (node()->isFocusable()) 281 269 return GroupRole; … … 314 302 } 315 303 316 bool AccessibilityNodeObject::canHaveChildren() const317 {318 // If this is an AccessibilityRenderObject, then it's okay if this object319 // doesn't have a node - there are some renderers that don't have associated320 // nodes, like scroll areas and css-generated text.321 if (!node() && !isAccessibilityRenderObject())322 return false;323 324 // Elements that should not have children325 switch (roleValue()) {326 case ImageRole:327 case ButtonRole:328 case PopUpButtonRole:329 case CheckBoxRole:330 case RadioButtonRole:331 case TabRole:332 case ToggleButtonRole:333 case StaticTextRole:334 case ListBoxOptionRole:335 case ScrollBarRole:336 return false;337 default:338 return true;339 }340 }341 342 304 bool AccessibilityNodeObject::accessibilityIsIgnored() const 343 305 { 344 // If this element is within a parent that cannot have children, it should not be exposed.345 if (isDescendantOfBarrenParent())346 return true;347 348 306 return m_role == UnknownRole; 349 307 } … … 366 324 } 367 325 368 bool AccessibilityNodeObject::isWebArea() const 369 { 370 return roleValue() == WebAreaRole; 371 } 372 373 bool AccessibilityNodeObject::isImageButton() const 374 { 375 return isNativeImage() && roleValue() == ButtonRole; 376 } 377 378 bool AccessibilityNodeObject::isAnchor() const 379 { 380 return !isNativeImage() && isLink(); 381 } 382 383 bool AccessibilityNodeObject::isNativeTextControl() const 326 bool AccessibilityNodeObject::canSetFocusAttribute() const 384 327 { 385 328 Node* node = this->node(); 386 if (!node)387 return false;388 389 if (node->hasTagName(textareaTag))390 return true;391 392 if (node->hasTagName(inputTag)) {393 HTMLInputElement* input = static_cast<HTMLInputElement*>(node);394 return input->isText() || input->isNumberField();395 }396 397 return false;398 }399 400 bool AccessibilityNodeObject::isSearchField() const401 {402 Node* node = this->node();403 if (!node)404 return false;405 406 HTMLInputElement* inputElement = node->toInputElement();407 if (!inputElement)408 return false;409 410 if (inputElement->isSearchField())411 return true;412 413 // Some websites don't label their search fields as such. However, they will414 // use the word "search" in either the form or input type. This won't catch every case,415 // but it will catch google.com for example.416 417 // Check the node name of the input type, sometimes it's "search".418 const AtomicString& nameAttribute = getAttribute(nameAttr);419 if (nameAttribute.contains("search", false))420 return true;421 422 // Check the form action and the name, which will sometimes be "search".423 HTMLFormElement* form = inputElement->form();424 if (form && (form->name().contains("search", false) || form->action().contains("search", false)))425 return true;426 427 return false;428 }429 430 bool AccessibilityNodeObject::isNativeImage() const431 {432 Node* node = this->node();433 if (!node)434 return false;435 436 if (node->hasTagName(imgTag))437 return true;438 439 if (node->hasTagName(appletTag) || node->hasTagName(embedTag) || node->hasTagName(objectTag))440 return true;441 442 if (node->hasTagName(inputTag)) {443 HTMLInputElement* input = static_cast<HTMLInputElement*>(node);444 return input->isImageButton();445 }446 447 return false;448 }449 450 bool AccessibilityNodeObject::isImage() const451 {452 return roleValue() == ImageRole;453 }454 455 bool AccessibilityNodeObject::isPasswordField() const456 {457 Node* node = this->node();458 if (!node || !node->isHTMLElement())459 return false;460 461 if (ariaRoleAttribute() != UnknownRole)462 return false;463 464 HTMLInputElement* inputElement = node->toInputElement();465 if (!inputElement)466 return false;467 468 return inputElement->isPasswordField();469 }470 471 bool AccessibilityNodeObject::isInputImage() const472 {473 Node* node = this->node();474 if (!node)475 return false;476 477 if (roleValue() == ButtonRole && node->hasTagName(inputTag)) {478 HTMLInputElement* input = static_cast<HTMLInputElement*>(node);479 return input->isImageButton();480 }481 482 return false;483 }484 485 bool AccessibilityNodeObject::isProgressIndicator() const486 {487 return roleValue() == ProgressIndicatorRole;488 }489 490 bool AccessibilityNodeObject::isSlider() const491 {492 return roleValue() == SliderRole;493 }494 495 bool AccessibilityNodeObject::isMenuRelated() const496 {497 switch (roleValue()) {498 case MenuRole:499 case MenuBarRole:500 case MenuButtonRole:501 case MenuItemRole:502 return true;503 default:504 return false;505 }506 }507 508 bool AccessibilityNodeObject::isMenu() const509 {510 return roleValue() == MenuRole;511 }512 513 bool AccessibilityNodeObject::isMenuBar() const514 {515 return roleValue() == MenuBarRole;516 }517 518 bool AccessibilityNodeObject::isMenuButton() const519 {520 return roleValue() == MenuButtonRole;521 }522 523 bool AccessibilityNodeObject::isMenuItem() const524 {525 return roleValue() == MenuItemRole;526 }527 528 bool AccessibilityNodeObject::isNativeCheckboxOrRadio() const529 {530 Node* node = this->node();531 if (!node)532 return false;533 534 HTMLInputElement* input = node->toInputElement();535 if (input)536 return input->isCheckbox() || input->isRadioButton();537 538 return false;539 }540 541 bool AccessibilityNodeObject::isEnabled() const542 {543 if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))544 return false;545 546 Node* node = this->node();547 if (!node || !node->isElementNode())548 return true;549 550 return toElement(node)->isEnabledFormControl();551 }552 553 bool AccessibilityNodeObject::isIndeterminate() const554 {555 Node* node = this->node();556 if (!node)557 return false;558 559 HTMLInputElement* inputElement = node->toInputElement();560 if (!inputElement)561 return false;562 563 return inputElement->isIndeterminate();564 }565 566 bool AccessibilityNodeObject::isPressed() const567 {568 if (roleValue() != ButtonRole)569 return false;570 571 Node* node = this->node();572 if (!node)573 return false;574 575 // If this is an ARIA button, check the aria-pressed attribute rather than node()->active()576 if (ariaRoleAttribute() == ButtonRole) {577 if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true"))578 return true;579 return false;580 }581 582 return node->active();583 }584 585 bool AccessibilityNodeObject::isChecked() const586 {587 Node* node = this->node();588 if (!node)589 return false;590 591 // First test for native checkedness semantics592 HTMLInputElement* inputElement = node->toInputElement();593 if (inputElement)594 return inputElement->shouldAppearChecked();595 596 // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute597 AccessibilityRole ariaRole = ariaRoleAttribute();598 if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) {599 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true"))600 return true;601 return false;602 }603 604 // Otherwise it's not checked605 return false;606 }607 608 bool AccessibilityNodeObject::isHovered() const609 {610 Node* node = this->node();611 if (!node)612 return false;613 614 return node->hovered();615 }616 617 bool AccessibilityNodeObject::isMultiSelectable() const618 {619 const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableAttr);620 if (equalIgnoringCase(ariaMultiSelectable, "true"))621 return true;622 if (equalIgnoringCase(ariaMultiSelectable, "false"))623 return false;624 625 return node() && node()->hasTagName(selectTag) && toHTMLSelectElement(node())->multiple();626 }627 628 bool AccessibilityNodeObject::isReadOnly() const629 {630 Node* node = this->node();631 if (!node)632 return true;633 634 if (node->hasTagName(textareaTag))635 return static_cast<HTMLTextAreaElement*>(node)->readOnly();636 637 if (node->hasTagName(inputTag))638 return static_cast<HTMLInputElement*>(node)->readOnly();639 640 return !node->rendererIsEditable();641 }642 643 bool AccessibilityNodeObject::isRequired() const644 {645 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true"))646 return true;647 648 Node* n = this->node();649 if (n && (n->isElementNode() && toElement(n)->isFormControlElement()))650 return static_cast<HTMLFormControlElement*>(n)->required();651 652 return false;653 }654 655 int AccessibilityNodeObject::headingLevel() const656 {657 // headings can be in block flow and non-block flow658 Node* node = this->node();659 if (!node)660 return false;661 662 if (ariaRoleAttribute() == HeadingRole)663 return getAttribute(aria_levelAttr).toInt();664 665 if (node->hasTagName(h1Tag))666 return 1;667 668 if (node->hasTagName(h2Tag))669 return 2;670 671 if (node->hasTagName(h3Tag))672 return 3;673 674 if (node->hasTagName(h4Tag))675 return 4;676 677 if (node->hasTagName(h5Tag))678 return 5;679 680 if (node->hasTagName(h6Tag))681 return 6;682 683 return 0;684 }685 686 String AccessibilityNodeObject::valueDescription() const687 {688 if (!isARIARange())689 return String();690 691 return getAttribute(aria_valuetextAttr).string();692 }693 694 bool AccessibilityNodeObject::isARIARange() const695 {696 switch (m_ariaRole) {697 case ProgressIndicatorRole:698 case SliderRole:699 case ScrollBarRole:700 case SpinButtonRole:701 return true;702 default:703 return false;704 }705 }706 707 float AccessibilityNodeObject::valueForRange() const708 {709 if (node() && node()->hasTagName(inputTag)) {710 HTMLInputElement* input = static_cast<HTMLInputElement*>(node());711 if (input->isRangeControl())712 return input->valueAsNumber();713 }714 715 if (!isARIARange())716 return 0.0f;717 718 return getAttribute(aria_valuenowAttr).toFloat();719 }720 721 float AccessibilityNodeObject::maxValueForRange() const722 {723 if (node() && node()->hasTagName(inputTag)) {724 HTMLInputElement* input = static_cast<HTMLInputElement*>(node());725 if (input->isRangeControl())726 return input->maximum();727 }728 729 if (!isARIARange())730 return 0.0f;731 732 return getAttribute(aria_valuemaxAttr).toFloat();733 }734 735 float AccessibilityNodeObject::minValueForRange() const736 {737 if (node() && node()->hasTagName(inputTag)) {738 HTMLInputElement* input = static_cast<HTMLInputElement*>(node());739 if (input->isRangeControl())740 return input->minimum();741 }742 743 if (!isARIARange())744 return 0.0f;745 746 return getAttribute(aria_valueminAttr).toFloat();747 }748 749 float AccessibilityNodeObject::stepValueForRange() const750 {751 return getAttribute(stepAttr).toFloat();752 }753 754 bool AccessibilityNodeObject::isHeading() const755 {756 return roleValue() == HeadingRole;757 }758 759 bool AccessibilityNodeObject::isLink() const760 {761 return roleValue() == WebCoreLinkRole;762 }763 764 bool AccessibilityNodeObject::isControl() const765 {766 Node* node = this->node();767 if (!node)768 return false;769 770 return ((node->isElementNode() && toElement(node)->isFormControlElement())771 || AccessibilityObject::isARIAControl(ariaRoleAttribute()));772 }773 774 bool AccessibilityNodeObject::isFieldset() const775 {776 Node* node = this->node();777 if (!node)778 return false;779 780 return node->hasTagName(fieldsetTag);781 }782 783 bool AccessibilityNodeObject::isGroup() const784 {785 return roleValue() == GroupRole;786 }787 788 AccessibilityObject* AccessibilityNodeObject::selectedRadioButton()789 {790 if (!isRadioGroup())791 return 0;792 793 AccessibilityObject::AccessibilityChildrenVector children = this->children();794 795 // Find the child radio button that is selected (ie. the intValue == 1).796 size_t size = children.size();797 for (size_t i = 0; i < size; ++i) {798 AccessibilityObject* object = children[i].get();799 if (object->roleValue() == RadioButtonRole && object->checkboxOrRadioValue() == ButtonStateOn)800 return object;801 }802 return 0;803 }804 805 AccessibilityObject* AccessibilityNodeObject::selectedTabItem()806 {807 if (!isTabList())808 return 0;809 810 // Find the child tab item that is selected (ie. the intValue == 1).811 AccessibilityObject::AccessibilityChildrenVector tabs;812 tabChildren(tabs);813 814 AccessibilityObject::AccessibilityChildrenVector children = this->children();815 size_t size = tabs.size();816 for (size_t i = 0; i < size; ++i) {817 AccessibilityObject* object = children[i].get();818 if (object->isTabItem() && object->isChecked())819 return object;820 }821 return 0;822 }823 824 AccessibilityButtonState AccessibilityNodeObject::checkboxOrRadioValue() const825 {826 if (isNativeCheckboxOrRadio())827 return isChecked() ? ButtonStateOn : ButtonStateOff;828 829 return AccessibilityObject::checkboxOrRadioValue();830 }831 832 Element* AccessibilityNodeObject::anchorElement() const833 {834 Node* node = this->node();835 if (!node)836 return 0;837 838 AXObjectCache* cache = axObjectCache();839 840 // search up the DOM tree for an anchor element841 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement842 for ( ; node; node = node->parentNode()) {843 if (node->hasTagName(aTag) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))844 return toElement(node);845 }846 847 return 0;848 }849 850 Element* AccessibilityNodeObject::actionElement() const851 {852 Node* node = this->node();853 if (!node)854 return 0;855 856 if (node->hasTagName(inputTag)) {857 HTMLInputElement* input = static_cast<HTMLInputElement*>(node);858 if (!input->disabled() && (isCheckboxOrRadio() || input->isTextButton()))859 return input;860 } else if (node->hasTagName(buttonTag))861 return toElement(node);862 863 if (isFileUploadButton())864 return toElement(node);865 866 if (AccessibilityObject::isARIAInput(ariaRoleAttribute()))867 return toElement(node);868 869 if (isImageButton())870 return toElement(node);871 872 if (node->hasTagName(selectTag))873 return toElement(node);874 875 switch (roleValue()) {876 case ButtonRole:877 case PopUpButtonRole:878 case TabRole:879 case MenuItemRole:880 case ListItemRole:881 return toElement(node);882 default:883 break;884 }885 886 Element* elt = anchorElement();887 if (!elt)888 elt = mouseButtonListener();889 return elt;890 }891 892 Element* AccessibilityNodeObject::mouseButtonListener() const893 {894 Node* node = this->node();895 if (!node)896 return 0;897 898 // check if our parent is a mouse button listener899 while (node && !node->isElementNode())900 node = node->parentNode();901 902 if (!node)903 return 0;904 905 // FIXME: Do the continuation search like anchorElement does906 for (Element* element = toElement(node); element; element = element->parentElement()) {907 if (element->getAttributeEventListener(eventNames().clickEvent) || element->getAttributeEventListener(eventNames().mousedownEvent) || element->getAttributeEventListener(eventNames().mouseupEvent))908 return element;909 }910 911 return 0;912 }913 914 bool AccessibilityNodeObject::isDescendantOfBarrenParent() const915 {916 for (AccessibilityObject* object = parentObject(); object; object = object->parentObject()) {917 if (!object->canHaveChildren())918 return true;919 }920 921 return false;922 }923 924 void AccessibilityNodeObject::alterSliderValue(bool increase)925 {926 if (roleValue() != SliderRole)927 return;928 929 if (!getAttribute(stepAttr).isEmpty())930 changeValueByStep(increase);931 else932 changeValueByPercent(increase ? 5 : -5);933 }934 935 void AccessibilityNodeObject::increment()936 {937 alterSliderValue(true);938 }939 940 void AccessibilityNodeObject::decrement()941 {942 alterSliderValue(false);943 }944 945 void AccessibilityNodeObject::changeValueByStep(bool increase)946 {947 float step = stepValueForRange();948 float value = valueForRange();949 950 value += increase ? step : -step;951 952 setValue(String::number(value));953 954 axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, true);955 }956 957 void AccessibilityNodeObject::changeValueByPercent(float percentChange)958 {959 float range = maxValueForRange() - minValueForRange();960 float value = valueForRange();961 962 value += range * (percentChange / 100);963 setValue(String::number(value));964 965 axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, true);966 }967 968 bool AccessibilityNodeObject::isGenericFocusableElement() const969 {970 if (!canSetFocusAttribute())971 return false;972 973 // If it's a control, it's not generic.974 if (isControl())975 return false;976 977 // If it has an aria role, it's not generic.978 if (m_ariaRole != UnknownRole)979 return false;980 981 // If the content editable attribute is set on this element, that's the reason982 // it's focusable, and existing logic should handle this case already - so it's not a983 // generic focusable element.984 985 if (hasContentEditableAttributeSet())986 return false;987 988 // The web area and body element are both focusable, but existing logic handles these989 // cases already, so we don't need to include them here.990 if (roleValue() == WebAreaRole)991 return false;992 if (node() && node()->hasTagName(bodyTag))993 return false;994 995 return true;996 }997 998 HTMLLabelElement* AccessibilityNodeObject::labelForElement(Element* element) const999 {1000 RefPtr<NodeList> list = element->document()->getElementsByTagName("label");1001 unsigned len = list->length();1002 for (unsigned i = 0; i < len; i++) {1003 if (list->item(i)->hasTagName(labelTag)) {1004 HTMLLabelElement* label = static_cast<HTMLLabelElement*>(list->item(i));1005 if (label->control() == element)1006 return label;1007 }1008 }1009 1010 return 0;1011 }1012 1013 String AccessibilityNodeObject::ariaAccessibilityDescription() const1014 {1015 String ariaLabeledBy = ariaLabeledByAttribute();1016 if (!ariaLabeledBy.isEmpty())1017 return ariaLabeledBy;1018 1019 const AtomicString& ariaLabel = getAttribute(aria_labelAttr);1020 if (!ariaLabel.isEmpty())1021 return ariaLabel;1022 1023 return String();1024 }1025 1026 static Element* siblingWithAriaRole(String role, Node* node)1027 {1028 for (Node* sibling = node->parentNode()->firstChild(); sibling; sibling = sibling->nextSibling()) {1029 if (sibling->isElementNode()) {1030 const AtomicString& siblingAriaRole = toElement(sibling)->getAttribute(roleAttr);1031 if (equalIgnoringCase(siblingAriaRole, role))1032 return toElement(sibling);1033 }1034 }1035 1036 return 0;1037 }1038 1039 Element* AccessibilityNodeObject::menuElementForMenuButton() const1040 {1041 if (ariaRoleAttribute() != MenuButtonRole)1042 return 0;1043 1044 return siblingWithAriaRole("menu", node());1045 }1046 1047 AccessibilityObject* AccessibilityNodeObject::menuForMenuButton() const1048 {1049 return axObjectCache()->getOrCreate(menuElementForMenuButton());1050 }1051 1052 Element* AccessibilityNodeObject::menuItemElementForMenu() const1053 {1054 if (ariaRoleAttribute() != MenuRole)1055 return 0;1056 1057 return siblingWithAriaRole("menuitem", node());1058 }1059 1060 AccessibilityObject* AccessibilityNodeObject::menuButtonForMenu() const1061 {1062 Element* menuItem = menuItemElementForMenu();1063 1064 if (menuItem) {1065 // ARIA just has generic menu items. AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem1066 AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem);1067 if (menuItemAX->isMenuButton())1068 return menuItemAX;1069 }1070 return 0;1071 }1072 1073 String AccessibilityNodeObject::accessibilityDescription() const1074 {1075 // Static text should not have a description, it should only have a stringValue.1076 if (roleValue() == StaticTextRole)1077 return String();1078 1079 String ariaDescription = ariaAccessibilityDescription();1080 if (!ariaDescription.isEmpty())1081 return ariaDescription;1082 1083 if (isImage() || isInputImage() || isNativeImage() || isCanvas()) {1084 // Images should use alt as long as the attribute is present, even if empty.1085 // Otherwise, it should fallback to other methods, like the title attribute.1086 const AtomicString& alt = getAttribute(altAttr);1087 if (!alt.isNull())1088 return alt;1089 }1090 1091 #if ENABLE(MATHML)1092 Node* node = this->node();1093 if (node && node->isElementNode() && toElement(node)->isMathMLElement())1094 return getAttribute(MathMLNames::alttextAttr);1095 #endif1096 1097 // An element's descriptive text is comprised of title() (what's visible on the screen) and accessibilityDescription() (other descriptive text).1098 // Both are used to generate what a screen reader speaks.1099 // If this point is reached (i.e. there's no accessibilityDescription) and there's no title(), we should fallback to using the title attribute.1100 // The title attribute is normally used as help text (because it is a tooltip), but if there is nothing else available, this should be used (according to ARIA).1101 if (title().isEmpty())1102 return getAttribute(titleAttr);1103 1104 return String();1105 }1106 1107 String AccessibilityNodeObject::helpText() const1108 {1109 Node* node = this->node();1110 if (!node)1111 return String();1112 1113 const AtomicString& ariaHelp = getAttribute(aria_helpAttr);1114 if (!ariaHelp.isEmpty())1115 return ariaHelp;1116 1117 String describedBy = ariaDescribedByAttribute();1118 if (!describedBy.isEmpty())1119 return describedBy;1120 1121 String description = accessibilityDescription();1122 for (Node* curr = node; curr; curr = curr->parentNode()) {1123 if (curr->isHTMLElement()) {1124 const AtomicString& summary = toElement(curr)->getAttribute(summaryAttr);1125 if (!summary.isEmpty())1126 return summary;1127 1128 // The title attribute should be used as help text unless it is already being used as descriptive text.1129 const AtomicString& title = toElement(curr)->getAttribute(titleAttr);1130 if (!title.isEmpty() && description != title)1131 return title;1132 }1133 1134 // Only take help text from an ancestor element if its a group or an unknown role. If help was1135 // added to those kinds of elements, it is likely it was meant for a child element.1136 AccessibilityObject* axObj = axObjectCache()->getOrCreate(curr);1137 if (axObj) {1138 AccessibilityRole role = axObj->roleValue();1139 if (role != GroupRole && role != UnknownRole)1140 break;1141 }1142 }1143 1144 return String();1145 }1146 1147 unsigned AccessibilityNodeObject::hierarchicalLevel() const1148 {1149 Node* node = this->node();1150 if (!node || !node->isElementNode())1151 return 0;1152 Element* element = toElement(node);1153 String ariaLevel = element->getAttribute(aria_levelAttr);1154 if (!ariaLevel.isEmpty())1155 return ariaLevel.toInt();1156 1157 // Only tree item will calculate its level through the DOM currently.1158 if (roleValue() != TreeItemRole)1159 return 0;1160 1161 // Hierarchy leveling starts at 0.1162 // We measure tree hierarchy by the number of groups that the item is within.1163 unsigned level = 0;1164 for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {1165 AccessibilityRole parentRole = parent->roleValue();1166 if (parentRole == GroupRole)1167 level++;1168 else if (parentRole == TreeRole)1169 break;1170 }1171 1172 return level;1173 }1174 1175 String AccessibilityNodeObject::textUnderElement() const1176 {1177 Node* node = this->node();1178 if (!node)1179 return String();1180 1181 // Note: TextIterator doesn't return any text for nodes that don't have renderers.1182 // If this could be fixed, it'd be more accurate use TextIterator here.1183 if (node->isElementNode())1184 return toElement(node)->innerText();1185 1186 return String();1187 }1188 1189 String AccessibilityNodeObject::title() const1190 {1191 Node* node = this->node();1192 if (!node)1193 return String();1194 1195 bool isInputTag = node->hasTagName(inputTag);1196 if (isInputTag) {1197 HTMLInputElement* input = static_cast<HTMLInputElement*>(node);1198 if (input->isTextButton())1199 return input->valueWithDefault();1200 }1201 1202 if (isInputTag || AccessibilityObject::isARIAInput(ariaRoleAttribute()) || isControl()) {1203 HTMLLabelElement* label = labelForElement(toElement(node));1204 if (label && !exposesTitleUIElement())1205 return label->innerText();1206 }1207 1208 // If this node isn't rendered, there's no inner text we can extract from a select element.1209 if (!isAccessibilityRenderObject() && node->hasTagName(selectTag))1210 return String();1211 1212 switch (roleValue()) {1213 case PopUpButtonRole:1214 case ButtonRole:1215 case CheckBoxRole:1216 case ListBoxOptionRole:1217 case MenuButtonRole:1218 case MenuItemRole:1219 case RadioButtonRole:1220 case TabRole:1221 return textUnderElement();1222 default:1223 break;1224 }1225 1226 if (isHeading() || isLink())1227 return textUnderElement();1228 1229 // If it's focusable but it's not content editable or a known control type, then it will appear to1230 // the user as a single atomic object, so we should use its text as the default title.1231 if (isGenericFocusableElement())1232 return textUnderElement();1233 1234 return String();1235 }1236 1237 String AccessibilityNodeObject::text() const1238 {1239 // If this is a user defined static text, use the accessible name computation.1240 if (ariaRoleAttribute() == StaticTextRole)1241 return ariaAccessibilityDescription();1242 1243 if (!isTextControl())1244 return String();1245 1246 Node* node = this->node();1247 if (!node)1248 return String();1249 1250 if (isNativeTextControl()) {1251 if (node->hasTagName(textareaTag))1252 return static_cast<HTMLTextAreaElement*>(node)->value();1253 if (node->hasTagName(inputTag))1254 return node->toInputElement()->value();1255 }1256 1257 if (!node->isElementNode())1258 return String();1259 1260 return toElement(node)->innerText();1261 }1262 1263 String AccessibilityNodeObject::stringValue() const1264 {1265 Node* node = this->node();1266 if (!node)1267 return String();1268 1269 if (ariaRoleAttribute() == StaticTextRole) {1270 String staticText = text();1271 if (!staticText.length())1272 staticText = textUnderElement();1273 return staticText;1274 }1275 1276 if (node->isTextNode())1277 return textUnderElement();1278 1279 if (node->hasTagName(selectTag)) {1280 HTMLSelectElement* selectElement = toHTMLSelectElement(node);1281 int selectedIndex = selectElement->selectedIndex();1282 const Vector<HTMLElement*> listItems = selectElement->listItems();1283 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {1284 const AtomicString& overriddenDescription = listItems[selectedIndex]->fastGetAttribute(aria_labelAttr);1285 if (!overriddenDescription.isNull())1286 return overriddenDescription;1287 }1288 if (!selectElement->multiple())1289 return selectElement->value();1290 return String();1291 }1292 1293 if (isTextControl())1294 return text();1295 1296 // FIXME: We might need to implement a value here for more types1297 // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one;1298 // this would require subclassing or making accessibilityAttributeNames do something other than return a1299 // single static array.1300 return String();1301 }1302 1303 // This function implements the ARIA accessible name as described by the Mozilla1304 // ARIA Implementer's Guide.1305 static String accessibleNameForNode(Node* node)1306 {1307 if (node->isTextNode())1308 return toText(node)->data();1309 1310 if (node->hasTagName(inputTag))1311 return static_cast<HTMLInputElement*>(node)->value();1312 1313 if (node->isHTMLElement()) {1314 const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);1315 if (!alt.isEmpty())1316 return alt;1317 }1318 1319 return String();1320 }1321 1322 String AccessibilityNodeObject::accessibilityDescriptionForElements(Vector<Element*> &elements) const1323 {1324 StringBuilder builder;1325 unsigned size = elements.size();1326 for (unsigned i = 0; i < size; ++i) {1327 Element* idElement = elements[i];1328 1329 builder.append(accessibleNameForNode(idElement));1330 for (Node* n = idElement->firstChild(); n; n = n->traverseNextNode(idElement))1331 builder.append(accessibleNameForNode(n));1332 1333 if (i != size - 1)1334 builder.append(' ');1335 }1336 return builder.toString();1337 }1338 1339 void AccessibilityNodeObject::elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& attribute) const1340 {1341 Node* node = this->node();1342 if (!node || !node->isElementNode())1343 return;1344 1345 TreeScope* scope = node->treeScope();1346 if (!scope)1347 return;1348 1349 String idList = getAttribute(attribute).string();1350 if (idList.isEmpty())1351 return;1352 1353 idList.replace('\n', ' ');1354 Vector<String> idVector;1355 idList.split(' ', idVector);1356 1357 unsigned size = idVector.size();1358 for (unsigned i = 0; i < size; ++i) {1359 AtomicString idName(idVector[i]);1360 Element* idElement = scope->getElementById(idName);1361 if (idElement)1362 elements.append(idElement);1363 }1364 }1365 1366 1367 void AccessibilityNodeObject::ariaLabeledByElements(Vector<Element*>& elements) const1368 {1369 elementsFromAttribute(elements, aria_labeledbyAttr);1370 if (!elements.size())1371 elementsFromAttribute(elements, aria_labelledbyAttr);1372 }1373 1374 1375 String AccessibilityNodeObject::ariaLabeledByAttribute() const1376 {1377 Vector<Element*> elements;1378 ariaLabeledByElements(elements);1379 1380 return accessibilityDescriptionForElements(elements);1381 }1382 1383 bool AccessibilityNodeObject::canSetFocusAttribute() const1384 {1385 Node* node = this->node();1386 if (!node)1387 return false;1388 329 1389 330 if (isWebArea()) … … 1396 337 return false; 1397 338 1398 if (node->isElementNode() && ! toElement(node)->isEnabledFormControl())339 if (node->isElementNode() && !static_cast<Element*>(node)->isEnabledFormControl()) 1399 340 return false; 1400 341 -
trunk/Source/WebCore/accessibility/AccessibilityNodeObject.h
r128318 r128353 69 69 virtual bool canvasHasFallbackContent() const; 70 70 71 virtual bool isAnchor() const;72 virtual bool isControl() const;73 virtual bool isFieldset() const;74 virtual bool isGroup() const;75 virtual bool isHeading() const;76 virtual bool isHovered() const;77 virtual bool isImage() const;78 virtual bool isImageButton() const;79 virtual bool isInputImage() const;80 virtual bool isLink() const;81 virtual bool isMenu() const;82 virtual bool isMenuBar() const;83 virtual bool isMenuButton() const;84 virtual bool isMenuItem() const;85 virtual bool isMenuRelated() const;86 virtual bool isMultiSelectable() const;87 virtual bool isNativeCheckboxOrRadio() const;88 virtual bool isNativeImage() const;89 virtual bool isNativeTextControl() const;90 virtual bool isPasswordField() const;91 virtual bool isProgressIndicator() const;92 virtual bool isSearchField() const;93 virtual bool isSlider() const;94 virtual bool isWebArea() const;95 96 virtual bool isChecked() const;97 virtual bool isEnabled() const;98 virtual bool isIndeterminate() const;99 virtual bool isPressed() const;100 virtual bool isReadOnly() const;101 virtual bool isRequired() const;102 103 void setNode(Node*);104 virtual Node* node() const { return m_node; }105 virtual Document* document() const;106 107 71 virtual bool canSetFocusAttribute() const; 108 virtual int headingLevel() const; 109 110 virtual String valueDescription() const; 111 virtual float valueForRange() const; 112 virtual float maxValueForRange() const; 113 virtual float minValueForRange() const; 114 virtual float stepValueForRange() const; 115 116 virtual AccessibilityObject* selectedRadioButton(); 117 virtual AccessibilityObject* selectedTabItem(); 118 virtual AccessibilityButtonState checkboxOrRadioValue() const; 119 120 virtual unsigned hierarchicalLevel() const; 121 virtual String textUnderElement() const; 122 virtual String accessibilityDescription() const; 123 virtual String helpText() const; 124 virtual String title() const; 125 virtual String text() const; 126 virtual String stringValue() const; 127 virtual String ariaLabeledByAttribute() const; 128 129 virtual Element* actionElement() const; 130 Element* mouseButtonListener() const; 131 virtual Element* anchorElement() const; 132 AccessibilityObject* menuForMenuButton() const; 133 134 virtual void changeValueByPercent(float percentChange); 135 72 136 73 virtual AccessibilityObject* firstChild() const; 137 74 virtual AccessibilityObject* lastChild() const; … … 141 78 virtual AccessibilityObject* parentObjectIfExists() const; 142 79 80 void setNode(Node*); 81 virtual Node* node() const { return m_node; } 82 virtual Document* document() const; 83 143 84 virtual void detach(); 144 85 virtual void childrenChanged(); 145 86 virtual void updateAccessibilityRole(); 146 147 virtual void increment();148 virtual void decrement();149 87 150 88 virtual LayoutRect elementRect() const; … … 159 97 virtual AccessibilityRole determineAccessibilityRole(); 160 98 virtual void addChildren(); 161 virtual bool canHaveChildren() const;162 99 virtual bool accessibilityIsIgnored() const; 163 100 AccessibilityRole ariaRoleAttribute() const; … … 165 102 AccessibilityRole remapAriaRoleDueToParent(AccessibilityRole) const; 166 103 bool hasContentEditableAttributeSet() const; 167 bool isDescendantOfBarrenParent() const;168 void alterSliderValue(bool increase);169 void changeValueByStep(bool increase);170 bool isARIARange() const;171 bool isGenericFocusableElement() const;172 HTMLLabelElement* labelForElement(Element*) const;173 String ariaAccessibilityDescription() const;174 void ariaLabeledByElements(Vector<Element*>& elements) const;175 String accessibilityDescriptionForElements(Vector<Element*> &elements) const;176 void elementsFromAttribute(Vector<Element*>& elements, const QualifiedName&) const;177 178 Element* menuElementForMenuButton() const;179 Element* menuItemElementForMenu() const;180 AccessibilityObject* menuButtonForMenu() const;181 104 182 105 private: -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
r128318 r128353 478 478 return 0; 479 479 } 480 480 481 bool AccessibilityRenderObject::isWebArea() const 482 { 483 return roleValue() == WebAreaRole; 484 } 485 486 bool AccessibilityRenderObject::isImageButton() const 487 { 488 return isNativeImage() && roleValue() == ButtonRole; 489 } 490 491 bool AccessibilityRenderObject::isAnchor() const 492 { 493 return !isNativeImage() && isLink(); 494 } 495 496 bool AccessibilityRenderObject::isNativeTextControl() const 497 { 498 return m_renderer->isTextControl(); 499 } 500 501 bool AccessibilityRenderObject::isSearchField() const 502 { 503 if (!node()) 504 return false; 505 506 HTMLInputElement* inputElement = node()->toInputElement(); 507 if (!inputElement) 508 return false; 509 510 if (inputElement->isSearchField()) 511 return true; 512 513 // Some websites don't label their search fields as such. However, they will 514 // use the word "search" in either the form or input type. This won't catch every case, 515 // but it will catch google.com for example. 516 517 // Check the node name of the input type, sometimes it's "search". 518 const AtomicString& nameAttribute = getAttribute(nameAttr); 519 if (nameAttribute.contains("search", false)) 520 return true; 521 522 // Check the form action and the name, which will sometimes be "search". 523 HTMLFormElement* form = inputElement->form(); 524 if (form && (form->name().contains("search", false) || form->action().contains("search", false))) 525 return true; 526 527 return false; 528 } 529 530 bool AccessibilityRenderObject::isNativeImage() const 531 { 532 return m_renderer->isBoxModelObject() && toRenderBoxModelObject(m_renderer)->isImage(); 533 } 534 535 bool AccessibilityRenderObject::isImage() const 536 { 537 return roleValue() == ImageRole; 538 } 539 481 540 bool AccessibilityRenderObject::isAttachment() const 482 541 { … … 490 549 } 491 550 551 bool AccessibilityRenderObject::isPasswordField() const 552 { 553 ASSERT(m_renderer); 554 if (!m_renderer->node() || !m_renderer->node()->isHTMLElement()) 555 return false; 556 if (ariaRoleAttribute() != UnknownRole) 557 return false; 558 559 HTMLInputElement* inputElement = m_renderer->node()->toInputElement(); 560 if (!inputElement) 561 return false; 562 563 return inputElement->isPasswordField(); 564 } 565 492 566 bool AccessibilityRenderObject::isFileUploadButton() const 493 567 { … … 500 574 } 501 575 576 bool AccessibilityRenderObject::isInputImage() const 577 { 578 Node* elementNode = node(); 579 if (roleValue() == ButtonRole && elementNode && elementNode->hasTagName(inputTag)) { 580 HTMLInputElement* input = static_cast<HTMLInputElement*>(elementNode); 581 return input->isImageButton(); 582 } 583 584 return false; 585 } 586 587 bool AccessibilityRenderObject::isProgressIndicator() const 588 { 589 return roleValue() == ProgressIndicatorRole; 590 } 591 592 bool AccessibilityRenderObject::isSlider() const 593 { 594 return roleValue() == SliderRole; 595 } 596 597 bool AccessibilityRenderObject::isMenuRelated() const 598 { 599 AccessibilityRole role = roleValue(); 600 return role == MenuRole 601 || role == MenuBarRole 602 || role == MenuButtonRole 603 || role == MenuItemRole; 604 } 605 606 bool AccessibilityRenderObject::isMenu() const 607 { 608 return roleValue() == MenuRole; 609 } 610 611 bool AccessibilityRenderObject::isMenuBar() const 612 { 613 return roleValue() == MenuBarRole; 614 } 615 616 bool AccessibilityRenderObject::isMenuButton() const 617 { 618 return roleValue() == MenuButtonRole; 619 } 620 621 bool AccessibilityRenderObject::isMenuItem() const 622 { 623 return roleValue() == MenuItemRole; 624 } 625 626 bool AccessibilityRenderObject::isPressed() const 627 { 628 ASSERT(m_renderer); 629 if (roleValue() != ButtonRole) 630 return false; 631 632 Node* node = m_renderer->node(); 633 if (!node) 634 return false; 635 636 // If this is an ARIA button, check the aria-pressed attribute rather than node()->active() 637 if (ariaRoleAttribute() == ButtonRole) { 638 if (equalIgnoringCase(getAttribute(aria_pressedAttr), "true")) 639 return true; 640 return false; 641 } 642 643 return node->active(); 644 } 645 646 bool AccessibilityRenderObject::isIndeterminate() const 647 { 648 ASSERT(m_renderer); 649 if (!m_renderer->node()) 650 return false; 651 652 HTMLInputElement* inputElement = m_renderer->node()->toInputElement(); 653 if (!inputElement) 654 return false; 655 656 return inputElement->isIndeterminate(); 657 } 658 659 bool AccessibilityRenderObject::isNativeCheckboxOrRadio() const 660 { 661 Node* elementNode = node(); 662 if (elementNode) { 663 HTMLInputElement* input = elementNode->toInputElement(); 664 if (input) 665 return input->isCheckbox() || input->isRadioButton(); 666 } 667 668 return false; 669 } 670 671 bool AccessibilityRenderObject::isChecked() const 672 { 673 ASSERT(m_renderer); 674 675 Node* node = this->node(); 676 if (!node) 677 return false; 678 679 // First test for native checkedness semantics 680 HTMLInputElement* inputElement = node->toInputElement(); 681 if (inputElement) 682 return inputElement->shouldAppearChecked(); 683 684 // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute 685 AccessibilityRole ariaRole = ariaRoleAttribute(); 686 if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) { 687 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) 688 return true; 689 return false; 690 } 691 692 // Otherwise it's not checked 693 return false; 694 } 695 696 bool AccessibilityRenderObject::isHovered() const 697 { 698 ASSERT(m_renderer); 699 return m_renderer->node() && m_renderer->node()->hovered(); 700 } 701 702 bool AccessibilityRenderObject::isMultiSelectable() const 703 { 704 ASSERT(m_renderer); 705 706 const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableAttr); 707 if (equalIgnoringCase(ariaMultiSelectable, "true")) 708 return true; 709 if (equalIgnoringCase(ariaMultiSelectable, "false")) 710 return false; 711 712 if (!m_renderer->isBoxModelObject() || !toRenderBoxModelObject(m_renderer)->isListBox()) 713 return false; 714 return m_renderer->node() && toHTMLSelectElement(m_renderer->node())->multiple(); 715 } 716 502 717 bool AccessibilityRenderObject::isReadOnly() const 503 718 { … … 516 731 } 517 732 518 return AccessibilityNodeObject::isReadOnly(); 733 if (m_renderer->isBoxModelObject()) { 734 RenderBoxModelObject* box = toRenderBoxModelObject(m_renderer); 735 if (box->isTextField()) 736 return static_cast<HTMLInputElement*>(box->node())->readOnly(); 737 if (box->isTextArea()) 738 return static_cast<HTMLTextAreaElement*>(box->node())->readOnly(); 739 } 740 741 return !m_renderer->node() || !m_renderer->node()->rendererIsEditable(); 519 742 } 520 743 … … 527 750 viewRect.intersect(contentRect); 528 751 return viewRect.isEmpty(); 752 } 753 754 int AccessibilityRenderObject::headingLevel() const 755 { 756 // headings can be in block flow and non-block flow 757 Node* element = node(); 758 if (!element) 759 return 0; 760 761 if (ariaRoleAttribute() == HeadingRole) 762 return getAttribute(aria_levelAttr).toInt(); 763 764 if (element->hasTagName(h1Tag)) 765 return 1; 766 767 if (element->hasTagName(h2Tag)) 768 return 2; 769 770 if (element->hasTagName(h3Tag)) 771 return 3; 772 773 if (element->hasTagName(h4Tag)) 774 return 4; 775 776 if (element->hasTagName(h5Tag)) 777 return 5; 778 779 if (element->hasTagName(h6Tag)) 780 return 6; 781 782 return 0; 783 } 784 785 bool AccessibilityRenderObject::isHeading() const 786 { 787 return roleValue() == HeadingRole; 788 } 789 790 bool AccessibilityRenderObject::isLink() const 791 { 792 return roleValue() == WebCoreLinkRole; 793 } 794 795 bool AccessibilityRenderObject::isControl() const 796 { 797 if (!m_renderer) 798 return false; 799 800 Node* node = m_renderer->node(); 801 return node && ((node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()) 802 || AccessibilityObject::isARIAControl(ariaRoleAttribute())); 803 } 804 805 bool AccessibilityRenderObject::isFieldset() const 806 { 807 RenderBoxModelObject* renderer = renderBoxModelObject(); 808 if (!renderer) 809 return false; 810 return renderer->isFieldset(); 811 } 812 813 bool AccessibilityRenderObject::isGroup() const 814 { 815 return roleValue() == GroupRole; 816 } 817 818 AccessibilityObject* AccessibilityRenderObject::selectedRadioButton() 819 { 820 if (!isRadioGroup()) 821 return 0; 822 823 AccessibilityObject::AccessibilityChildrenVector children = this->children(); 824 825 // Find the child radio button that is selected (ie. the intValue == 1). 826 size_t size = children.size(); 827 for (size_t i = 0; i < size; ++i) { 828 AccessibilityObject* object = children[i].get(); 829 if (object->roleValue() == RadioButtonRole && object->checkboxOrRadioValue() == ButtonStateOn) 830 return object; 831 } 832 return 0; 833 } 834 835 AccessibilityObject* AccessibilityRenderObject::selectedTabItem() 836 { 837 if (!isTabList()) 838 return 0; 839 840 // Find the child tab item that is selected (ie. the intValue == 1). 841 AccessibilityObject::AccessibilityChildrenVector tabs; 842 tabChildren(tabs); 843 844 AccessibilityObject::AccessibilityChildrenVector children = this->children(); 845 846 size_t size = tabs.size(); 847 for (size_t i = 0; i < size; ++i) { 848 AccessibilityObject* object = children[i].get(); 849 if (object->isTabItem() && object->isChecked()) 850 return object; 851 } 852 return 0; 529 853 } 530 854 … … 558 882 } 559 883 884 return 0; 885 } 886 887 Element* AccessibilityRenderObject::actionElement() const 888 { 889 if (!m_renderer) 890 return 0; 891 892 Node* node = m_renderer->node(); 893 if (node) { 894 if (node->hasTagName(inputTag)) { 895 HTMLInputElement* input = static_cast<HTMLInputElement*>(node); 896 if (!input->disabled() && (isCheckboxOrRadio() || input->isTextButton())) 897 return input; 898 } else if (node->hasTagName(buttonTag)) 899 return toElement(node); 900 } 901 902 if (isFileUploadButton()) 903 return toElement(m_renderer->node()); 904 905 if (AccessibilityObject::isARIAInput(ariaRoleAttribute())) 906 return toElement(m_renderer->node()); 907 908 if (isImageButton()) 909 return toElement(m_renderer->node()); 910 911 if (m_renderer->isBoxModelObject() && toRenderBoxModelObject(m_renderer)->isMenuList()) 912 return toElement(m_renderer->node()); 913 914 switch (roleValue()) { 915 case ButtonRole: 916 case PopUpButtonRole: 917 case TabRole: 918 case MenuItemRole: 919 case ListItemRole: 920 return toElement(m_renderer->node()); 921 default: 922 break; 923 } 924 925 Element* elt = anchorElement(); 926 if (!elt) 927 elt = mouseButtonListener(); 928 return elt; 929 } 930 931 Element* AccessibilityRenderObject::mouseButtonListener() const 932 { 933 Node* node = m_renderer->node(); 934 if (!node) 935 return 0; 936 937 // check if our parent is a mouse button listener 938 while (node && !node->isElementNode()) 939 node = node->parentNode(); 940 941 if (!node) 942 return 0; 943 944 // FIXME: Do the continuation search like anchorElement does 945 for (Element* element = static_cast<Element*>(node); element; element = element->parentElement()) { 946 if (element->getAttributeEventListener(eventNames().clickEvent) || element->getAttributeEventListener(eventNames().mousedownEvent) || element->getAttributeEventListener(eventNames().mouseupEvent)) 947 return element; 948 } 949 950 return 0; 951 } 952 953 void AccessibilityRenderObject::alterSliderValue(bool increase) 954 { 955 if (roleValue() != SliderRole) 956 return; 957 958 if (!getAttribute(stepAttr).isEmpty()) 959 changeValueByStep(increase); 960 else 961 changeValueByPercent(increase ? 5 : -5); 962 } 963 964 void AccessibilityRenderObject::increment() 965 { 966 alterSliderValue(true); 967 } 968 969 void AccessibilityRenderObject::decrement() 970 { 971 alterSliderValue(false); 972 } 973 974 static Element* siblingWithAriaRole(String role, Node* node) 975 { 976 Node* sibling = node->parentNode()->firstChild(); 977 while (sibling) { 978 if (sibling->isElementNode()) { 979 const AtomicString& siblingAriaRole = static_cast<Element*>(sibling)->getAttribute(roleAttr); 980 if (equalIgnoringCase(siblingAriaRole, role)) 981 return static_cast<Element*>(sibling); 982 } 983 sibling = sibling->nextSibling(); 984 } 985 986 return 0; 987 } 988 989 Element* AccessibilityRenderObject::menuElementForMenuButton() const 990 { 991 if (ariaRoleAttribute() != MenuButtonRole) 992 return 0; 993 994 return siblingWithAriaRole("menu", renderer()->node()); 995 } 996 997 AccessibilityObject* AccessibilityRenderObject::menuForMenuButton() const 998 { 999 Element* menu = menuElementForMenuButton(); 1000 if (menu && menu->renderer()) 1001 return axObjectCache()->getOrCreate(menu); 1002 return 0; 1003 } 1004 1005 Element* AccessibilityRenderObject::menuItemElementForMenu() const 1006 { 1007 if (ariaRoleAttribute() != MenuRole) 1008 return 0; 1009 1010 return siblingWithAriaRole("menuitem", renderer()->node()); 1011 } 1012 1013 AccessibilityObject* AccessibilityRenderObject::menuButtonForMenu() const 1014 { 1015 Element* menuItem = menuItemElementForMenu(); 1016 1017 if (menuItem && menuItem->renderer()) { 1018 // ARIA just has generic menu items. AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem 1019 AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem); 1020 if (menuItemAX->isMenuButton()) 1021 return menuItemAX; 1022 } 560 1023 return 0; 561 1024 } … … 599 1062 return String(); 600 1063 } 1064 1065 unsigned AccessibilityRenderObject::hierarchicalLevel() const 1066 { 1067 if (!m_renderer) 1068 return 0; 1069 1070 Node* node = m_renderer->node(); 1071 if (!node || !node->isElementNode()) 1072 return 0; 1073 Element* element = static_cast<Element*>(node); 1074 String ariaLevel = element->getAttribute(aria_levelAttr); 1075 if (!ariaLevel.isEmpty()) 1076 return ariaLevel.toInt(); 1077 1078 // Only tree item will calculate its level through the DOM currently. 1079 if (roleValue() != TreeItemRole) 1080 return 0; 1081 1082 // Hierarchy leveling starts at 0. 1083 // We measure tree hierarchy by the number of groups that the item is within. 1084 unsigned level = 0; 1085 AccessibilityObject* parent = parentObject(); 1086 while (parent) { 1087 AccessibilityRole parentRole = parent->roleValue(); 1088 if (parentRole == GroupRole) 1089 level++; 1090 else if (parentRole == TreeRole) 1091 break; 1092 1093 parent = parent->parentObject(); 1094 } 1095 1096 return level; 1097 } 601 1098 602 1099 static TextIteratorBehavior textIteratorBehaviorForTextRange() … … 650 1147 } 651 1148 1149 AccessibilityButtonState AccessibilityRenderObject::checkboxOrRadioValue() const 1150 { 1151 if (isNativeCheckboxOrRadio()) 1152 return isChecked() ? ButtonStateOn : ButtonStateOff; 1153 1154 return AccessibilityObject::checkboxOrRadioValue(); 1155 } 1156 1157 String AccessibilityRenderObject::valueDescription() const 1158 { 1159 if (!isARIARange()) 1160 return String(); 1161 1162 return getAttribute(aria_valuetextAttr).string(); 1163 } 1164 1165 float AccessibilityRenderObject::stepValueForRange() const 1166 { 1167 return getAttribute(stepAttr).toFloat(); 1168 } 1169 1170 bool AccessibilityRenderObject::isARIARange() const 1171 { 1172 return m_ariaRole == ProgressIndicatorRole 1173 || m_ariaRole == SliderRole 1174 || m_ariaRole == ScrollBarRole 1175 || m_ariaRole == SpinButtonRole; 1176 } 1177 1178 float AccessibilityRenderObject::valueForRange() const 1179 { 1180 if (!isARIARange()) 1181 return 0.0f; 1182 1183 return getAttribute(aria_valuenowAttr).toFloat(); 1184 } 1185 1186 float AccessibilityRenderObject::maxValueForRange() const 1187 { 1188 if (!isARIARange()) 1189 return 0.0f; 1190 1191 return getAttribute(aria_valuemaxAttr).toFloat(); 1192 } 1193 1194 float AccessibilityRenderObject::minValueForRange() const 1195 { 1196 if (!isARIARange()) 1197 return 0.0f; 1198 1199 return getAttribute(aria_valueminAttr).toFloat(); 1200 } 1201 652 1202 String AccessibilityRenderObject::stringValue() const 653 1203 { … … 708 1258 } 709 1259 1260 // This function implements the ARIA accessible name as described by the Mozilla 1261 // ARIA Implementer's Guide. 1262 static String accessibleNameForNode(Node* node) 1263 { 1264 if (node->isTextNode()) 1265 return toText(node)->data(); 1266 1267 if (node->hasTagName(inputTag)) 1268 return static_cast<HTMLInputElement*>(node)->value(); 1269 1270 if (node->isHTMLElement()) { 1271 const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr); 1272 if (!alt.isEmpty()) 1273 return alt; 1274 } 1275 1276 return String(); 1277 } 1278 1279 String AccessibilityRenderObject::accessibilityDescriptionForElements(Vector<Element*> &elements) const 1280 { 1281 StringBuilder builder; 1282 unsigned size = elements.size(); 1283 for (unsigned i = 0; i < size; ++i) { 1284 Element* idElement = elements[i]; 1285 1286 builder.append(accessibleNameForNode(idElement)); 1287 for (Node* n = idElement->firstChild(); n; n = n->traverseNextNode(idElement)) 1288 builder.append(accessibleNameForNode(n)); 1289 1290 if (i != size - 1) 1291 builder.append(' '); 1292 } 1293 return builder.toString(); 1294 } 1295 1296 void AccessibilityRenderObject::elementsFromAttribute(Vector<Element*>& elements, const QualifiedName& attribute) const 1297 { 1298 Node* node = m_renderer->node(); 1299 if (!node || !node->isElementNode()) 1300 return; 1301 1302 TreeScope* scope = node->treeScope(); 1303 if (!scope) 1304 return; 1305 1306 String idList = getAttribute(attribute).string(); 1307 if (idList.isEmpty()) 1308 return; 1309 1310 idList.replace('\n', ' '); 1311 Vector<String> idVector; 1312 idList.split(' ', idVector); 1313 1314 unsigned size = idVector.size(); 1315 for (unsigned i = 0; i < size; ++i) { 1316 AtomicString idName(idVector[i]); 1317 Element* idElement = scope->getElementById(idName); 1318 if (idElement) 1319 elements.append(idElement); 1320 } 1321 } 1322 1323 void AccessibilityRenderObject::ariaLabeledByElements(Vector<Element*>& elements) const 1324 { 1325 elementsFromAttribute(elements, aria_labeledbyAttr); 1326 if (!elements.size()) 1327 elementsFromAttribute(elements, aria_labelledbyAttr); 1328 } 1329 1330 String AccessibilityRenderObject::ariaLabeledByAttribute() const 1331 { 1332 Vector<Element*> elements; 1333 ariaLabeledByElements(elements); 1334 1335 return accessibilityDescriptionForElements(elements); 1336 } 1337 1338 static HTMLLabelElement* labelForElement(Element* element) 1339 { 1340 RefPtr<NodeList> list = element->document()->getElementsByTagName("label"); 1341 unsigned len = list->length(); 1342 for (unsigned i = 0; i < len; i++) { 1343 if (list->item(i)->hasTagName(labelTag)) { 1344 HTMLLabelElement* label = static_cast<HTMLLabelElement*>(list->item(i)); 1345 if (label->control() == element) 1346 return label; 1347 } 1348 } 1349 1350 return 0; 1351 } 1352 710 1353 HTMLLabelElement* AccessibilityRenderObject::labelElementContainer() const 711 1354 { … … 726 1369 } 727 1370 1371 String AccessibilityRenderObject::title() const 1372 { 1373 AccessibilityRole role = roleValue(); 1374 1375 if (!m_renderer) 1376 return String(); 1377 1378 Node* node = m_renderer->node(); 1379 if (!node) 1380 return String(); 1381 1382 bool isInputTag = node->hasTagName(inputTag); 1383 if (isInputTag) { 1384 HTMLInputElement* input = static_cast<HTMLInputElement*>(node); 1385 if (input->isTextButton()) 1386 return input->valueWithDefault(); 1387 } 1388 1389 if (isInputTag || AccessibilityObject::isARIAInput(ariaRoleAttribute()) || isControl()) { 1390 HTMLLabelElement* label = labelForElement(static_cast<Element*>(node)); 1391 if (label && !exposesTitleUIElement()) 1392 return label->innerText(); 1393 } 1394 1395 switch (role) { 1396 case ButtonRole: 1397 case ListBoxOptionRole: 1398 case MenuItemRole: 1399 case MenuButtonRole: 1400 case RadioButtonRole: 1401 case CheckBoxRole: 1402 case TabRole: 1403 case PopUpButtonRole: 1404 return textUnderElement(); 1405 default: 1406 break; 1407 } 1408 1409 if (isHeading() || isLink()) 1410 return textUnderElement(); 1411 1412 // If it's focusable but it's not content editable or a known control type, then it will appear to 1413 // the user as a single atomic object, so we should use its text as the default title. 1414 if (isGenericFocusableElement()) 1415 return textUnderElement(); 1416 1417 return String(); 1418 } 1419 728 1420 String AccessibilityRenderObject::ariaDescribedByAttribute() const 729 1421 { … … 734 1426 } 735 1427 1428 String AccessibilityRenderObject::ariaAccessibilityDescription() const 1429 { 1430 String ariaLabeledBy = ariaLabeledByAttribute(); 1431 if (!ariaLabeledBy.isEmpty()) 1432 return ariaLabeledBy; 1433 1434 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); 1435 if (!ariaLabel.isEmpty()) 1436 return ariaLabel; 1437 1438 return String(); 1439 } 1440 736 1441 String AccessibilityRenderObject::webAreaAccessibilityDescription() const 737 1442 { … … 786 1491 return String(); 787 1492 1493 // Static text should not have a description, it should only have a stringValue. 1494 if (roleValue() == StaticTextRole) 1495 return String(); 1496 1497 String ariaDescription = ariaAccessibilityDescription(); 1498 if (!ariaDescription.isEmpty()) 1499 return ariaDescription; 1500 1501 if (isImage() || isInputImage() || isNativeImage() || isCanvas()) { 1502 1503 // Images should use alt as long as the attribute is present, even if empty. 1504 // Otherwise, it should fallback to other methods, like the title attribute. 1505 const AtomicString& alt = getAttribute(altAttr); 1506 if (!alt.isNull()) 1507 return alt; 1508 } 1509 1510 #if ENABLE(MATHML) 1511 Node* node = m_renderer->node(); 1512 if (node && node->isElementNode() && static_cast<Element*>(node)->isMathMLElement()) 1513 return getAttribute(MathMLNames::alttextAttr); 1514 #endif 1515 788 1516 if (isWebArea()) 789 1517 return webAreaAccessibilityDescription(); 790 791 return AccessibilityNodeObject::accessibilityDescription(); 1518 1519 // An element's descriptive text is comprised of title() (what's visible on the screen) and accessibilityDescription() (other descriptive text). 1520 // Both are used to generate what a screen reader speaks. 1521 // If this point is reached (i.e. there's no accessibilityDescription) and there's no title(), we should fallback to using the title attribute. 1522 // The title attribute is normally used as help text (because it is a tooltip), but if there is nothing else available, this should be used (according to ARIA). 1523 if (title().isEmpty()) 1524 return getAttribute(titleAttr); 1525 1526 return String(); 792 1527 } 793 1528 … … 1076 1811 } 1077 1812 1813 bool AccessibilityRenderObject::isDescendantOfBarrenParent() const 1814 { 1815 for (AccessibilityObject* object = parentObject(); object; object = object->parentObject()) { 1816 if (!object->canHaveChildren()) 1817 return true; 1818 } 1819 1820 return false; 1821 } 1822 1078 1823 bool AccessibilityRenderObject::isAllowedChildOfTree() const 1079 1824 { … … 1315 2060 String AccessibilityRenderObject::text() const 1316 2061 { 2062 // If this is a user defined static text, use the accessible name computation. 2063 if (ariaRoleAttribute() == StaticTextRole) 2064 return ariaAccessibilityDescription(); 2065 2066 if (!isTextControl()) 2067 return String(); 2068 1317 2069 if (isPasswordField()) 1318 2070 return passwordFieldValue(); 1319 2071 1320 return AccessibilityNodeObject::text(); 2072 Node* node = m_renderer->node(); 2073 if (!node) 2074 return String(); 2075 2076 if (isNativeTextControl()) 2077 return toRenderTextControl(m_renderer)->textFormControlElement()->value(); 2078 2079 if (!node->isElementNode()) 2080 return String(); 2081 2082 return static_cast<Element*>(node)->innerText(); 1321 2083 } 1322 2084 … … 1476 2238 } 1477 2239 2240 bool AccessibilityRenderObject::isRequired() const 2241 { 2242 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true")) 2243 return true; 2244 2245 Node* n = node(); 2246 if (n && (n->isElementNode() && static_cast<Element*>(n)->isFormControlElement())) 2247 return static_cast<HTMLFormControlElement*>(n)->required(); 2248 2249 return false; 2250 } 2251 1478 2252 bool AccessibilityRenderObject::isSelected() const 1479 2253 { … … 1572 2346 } 1573 2347 2348 void AccessibilityRenderObject::changeValueByStep(bool increase) 2349 { 2350 float step = stepValueForRange(); 2351 float value = valueForRange(); 2352 2353 value += increase ? step : -step; 2354 2355 setValue(String::number(value)); 2356 2357 axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true); 2358 } 2359 2360 void AccessibilityRenderObject::changeValueByPercent(float percentChange) 2361 { 2362 float range = maxValueForRange() - minValueForRange(); 2363 float value = valueForRange(); 2364 2365 value += range * (percentChange / 100); 2366 setValue(String::number(value)); 2367 2368 axObjectCache()->postNotification(m_renderer, AXObjectCache::AXValueChanged, true); 2369 } 2370 1574 2371 void AccessibilityRenderObject::setSelectedRows(AccessibilityChildrenVector& selectedRows) 1575 2372 { … … 1631 2428 } 1632 2429 2430 bool AccessibilityRenderObject::isEnabled() const 2431 { 2432 ASSERT(m_renderer); 2433 2434 if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true")) 2435 return false; 2436 2437 Node* node = m_renderer->node(); 2438 if (!node || !node->isElementNode()) 2439 return true; 2440 2441 return static_cast<Element*>(node)->isEnabledFormControl(); 2442 } 2443 1633 2444 RenderView* AccessibilityRenderObject::topRenderer() const 1634 2445 { … … 2328 3139 } 2329 3140 3141 bool AccessibilityRenderObject::isGenericFocusableElement() const 3142 { 3143 if (!canSetFocusAttribute()) 3144 return false; 3145 3146 // If it's a control, it's not generic. 3147 if (isControl()) 3148 return false; 3149 3150 // If it has an aria role, it's not generic. 3151 if (m_ariaRole != UnknownRole) 3152 return false; 3153 3154 // If the content editable attribute is set on this element, that's the reason 3155 // it's focusable, and existing logic should handle this case already - so it's not a 3156 // generic focusable element. 3157 if (hasContentEditableAttributeSet()) 3158 return false; 3159 3160 // The web area and body element are both focusable, but existing logic handles these 3161 // cases already, so we don't need to include them here. 3162 if (roleValue() == WebAreaRole) 3163 return false; 3164 if (node() && node()->hasTagName(bodyTag)) 3165 return false; 3166 3167 return true; 3168 } 3169 2330 3170 AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole() 2331 3171 { … … 2598 3438 } 2599 3439 } 3440 3441 bool AccessibilityRenderObject::canHaveChildren() const 3442 { 3443 if (!m_renderer) 3444 return false; 3445 3446 // Elements that should not have children 3447 switch (roleValue()) { 3448 case ImageRole: 3449 case ButtonRole: 3450 case PopUpButtonRole: 3451 case CheckBoxRole: 3452 case RadioButtonRole: 3453 case TabRole: 3454 case StaticTextRole: 3455 case ListBoxOptionRole: 3456 case ScrollBarRole: 3457 return false; 3458 default: 3459 return true; 3460 } 3461 } 2600 3462 2601 3463 void AccessibilityRenderObject::clearChildren() … … 2735 3597 #endif 2736 3598 } 2737 2738 bool AccessibilityRenderObject::canHaveChildren() const 2739 { 2740 if (!m_renderer) 2741 return false; 2742 2743 return AccessibilityNodeObject::canHaveChildren(); 2744 } 2745 3599 2746 3600 const AtomicString& AccessibilityRenderObject::ariaLiveRegionStatus() const 2747 3601 { -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h
r128318 r128353 67 67 virtual void init(); 68 68 69 virtual bool isAnchor() const; 69 70 virtual bool isAttachment() const; 71 virtual bool isHeading() const; 72 virtual bool isLink() const; 73 virtual bool isImageButton() const; 74 virtual bool isImage() const; 75 virtual bool isNativeImage() const; 76 virtual bool isPasswordField() const; 77 virtual bool isNativeTextControl() const; 78 virtual bool isSearchField() const; 79 virtual bool isWebArea() const; 70 80 virtual bool isFileUploadButton() const; 71 81 virtual bool isInputImage() const; 82 virtual bool isProgressIndicator() const; 83 virtual bool isSlider() const; 84 virtual bool isMenuRelated() const; 85 virtual bool isMenu() const; 86 virtual bool isMenuBar() const; 87 virtual bool isMenuButton() const; 88 virtual bool isMenuItem() const; 89 virtual bool isControl() const; 90 virtual bool isFieldset() const; 91 virtual bool isGroup() const; 92 93 virtual bool isEnabled() const; 72 94 virtual bool isSelected() const; 73 95 virtual bool isFocused() const; 96 virtual bool isChecked() const; 97 virtual bool isHovered() const; 98 virtual bool isIndeterminate() const; 74 99 virtual bool isLoaded() const; 100 virtual bool isMultiSelectable() const; 75 101 virtual bool isOffScreen() const; 102 virtual bool isPressed() const; 76 103 virtual bool isReadOnly() const; 77 104 virtual bool isUnvisited() const; 78 105 virtual bool isVisited() const; 106 virtual bool isRequired() const; 79 107 virtual bool isLinked() const; 80 108 virtual bool hasBoldFont() const; … … 96 124 virtual bool accessibilityIsIgnored() const; 97 125 126 virtual int headingLevel() const; 127 virtual AccessibilityButtonState checkboxOrRadioValue() const; 128 virtual String valueDescription() const; 129 virtual float valueForRange() const; 130 virtual float maxValueForRange() const; 131 virtual float minValueForRange() const; 132 virtual float stepValueForRange() const; 133 virtual AccessibilityObject* selectedRadioButton(); 134 virtual AccessibilityObject* selectedTabItem(); 98 135 virtual int layoutCount() const; 99 136 virtual double estimatedLoadingProgress() const; … … 120 157 virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const; 121 158 159 virtual Element* actionElement() const; 160 Element* mouseButtonListener() const; 122 161 FrameView* frameViewIfRenderView() const; 123 162 virtual Element* anchorElement() const; 163 AccessibilityObject* menuForMenuButton() const; 164 AccessibilityObject* menuButtonForMenu() const; 124 165 125 166 virtual LayoutRect boundingBoxRect() const; … … 144 185 virtual VisibleSelection selection() const; 145 186 virtual String stringValue() const; 187 virtual String ariaLabeledByAttribute() const; 188 virtual String title() const; 146 189 virtual String ariaDescribedByAttribute() const; 147 190 virtual String accessibilityDescription() const; … … 157 200 virtual void getDocumentLinks(AccessibilityChildrenVector&); 158 201 virtual FrameView* documentFrameView() const; 202 virtual unsigned hierarchicalLevel() const; 159 203 160 204 virtual void clearChildren(); … … 165 209 virtual void setValue(const String&); 166 210 virtual void setSelectedRows(AccessibilityChildrenVector&); 211 virtual void changeValueByPercent(float percentChange); 167 212 virtual AccessibilityOrientation orientation() const; 213 virtual void increment(); 214 virtual void decrement(); 168 215 169 216 virtual void detach(); … … 217 264 218 265 void setRenderObject(RenderObject* renderer) { m_renderer = renderer; } 266 void ariaLabeledByElements(Vector<Element*>& elements) const; 219 267 bool needsToUpdateChildren() const { return m_childrenDirty; } 220 268 ScrollableArea* getScrollableAreaIfScrollable() const; … … 229 277 void ariaListboxVisibleChildren(AccessibilityChildrenVector&); 230 278 bool ariaIsHidden() const; 279 bool isDescendantOfBarrenParent() const; 231 280 bool isAllowedChildOfTree() const; 232 281 bool hasTextAlternative() const; … … 237 286 virtual void setNeedsToUpdateChildren() { m_childrenDirty = true; } 238 287 288 Element* menuElementForMenuButton() const; 289 Element* menuItemElementForMenu() const; 290 239 291 bool isTabItemSelected() const; 292 void alterSliderValue(bool increase); 293 void changeValueByStep(bool increase); 294 bool isNativeCheckboxOrRadio() const; 240 295 LayoutRect checkboxOrRadioRect() const; 241 296 void addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const; … … 247 302 bool isDescendantOfElementType(const QualifiedName& tagName) const; 248 303 // This returns true if it's focusable but it's not content editable and it's not a control or ARIA control. 304 bool isGenericFocusableElement() const; 305 bool isARIARange() const; 249 306 250 307 void addTextFieldChildren(); … … 261 318 void setElementAttributeValue(const QualifiedName&, bool); 262 319 320 String accessibilityDescriptionForElements(Vector<Element*> &elements) const; 321 void elementsFromAttribute(Vector<Element*>& elements, const QualifiedName&) const; 322 String ariaAccessibilityDescription() const; 263 323 String webAreaAccessibilityDescription() const; 264 324
Note: See TracChangeset
for help on using the changeset viewer.