Changeset 128368 in webkit
- Timestamp:
- Sep 12, 2012 3:19:50 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r128366 r128368 1 2012-09-12 Sheriff Bot <webkit.review.bot@gmail.com> 2 3 Unreviewed, rolling out r128353. 4 http://trac.webkit.org/changeset/128353 5 https://bugs.webkit.org/show_bug.cgi?id=96565 6 7 Re-land change that broke tests on Chromium. Tests are now 8 disabled, will rebaseline after this rolls. (Requested by 9 dmazzoni on #webkit). 10 11 * accessibility/canvas-fallback-content-2-expected.txt: Added. 12 * accessibility/canvas-fallback-content-2.html: Added. 13 1 14 2012-09-12 Ojan Vafai <ojan@chromium.org> 2 15 -
trunk/Source/WebCore/ChangeLog
r128363 r128368 1 2012-09-12 Sheriff Bot <webkit.review.bot@gmail.com> 2 3 Unreviewed, rolling out r128353. 4 http://trac.webkit.org/changeset/128353 5 https://bugs.webkit.org/show_bug.cgi?id=96565 6 7 Re-land change that broke tests on Chromium. Tests are now 8 disabled, will rebaseline after this rolls. (Requested by 9 dmazzoni on #webkit). 10 11 * accessibility/AccessibilityNodeObject.cpp: 12 (WebCore::AccessibilityNodeObject::determineAccessibilityRole): 13 (WebCore::AccessibilityNodeObject::canHaveChildren): 14 (WebCore): 15 (WebCore::AccessibilityNodeObject::accessibilityIsIgnored): 16 (WebCore::AccessibilityNodeObject::isWebArea): 17 (WebCore::AccessibilityNodeObject::isImageButton): 18 (WebCore::AccessibilityNodeObject::isAnchor): 19 (WebCore::AccessibilityNodeObject::isNativeTextControl): 20 (WebCore::AccessibilityNodeObject::isSearchField): 21 (WebCore::AccessibilityNodeObject::isNativeImage): 22 (WebCore::AccessibilityNodeObject::isImage): 23 (WebCore::AccessibilityNodeObject::isPasswordField): 24 (WebCore::AccessibilityNodeObject::isInputImage): 25 (WebCore::AccessibilityNodeObject::isProgressIndicator): 26 (WebCore::AccessibilityNodeObject::isSlider): 27 (WebCore::AccessibilityNodeObject::isMenuRelated): 28 (WebCore::AccessibilityNodeObject::isMenu): 29 (WebCore::AccessibilityNodeObject::isMenuBar): 30 (WebCore::AccessibilityNodeObject::isMenuButton): 31 (WebCore::AccessibilityNodeObject::isMenuItem): 32 (WebCore::AccessibilityNodeObject::isNativeCheckboxOrRadio): 33 (WebCore::AccessibilityNodeObject::isEnabled): 34 (WebCore::AccessibilityNodeObject::isIndeterminate): 35 (WebCore::AccessibilityNodeObject::isPressed): 36 (WebCore::AccessibilityNodeObject::isChecked): 37 (WebCore::AccessibilityNodeObject::isHovered): 38 (WebCore::AccessibilityNodeObject::isMultiSelectable): 39 (WebCore::AccessibilityNodeObject::isReadOnly): 40 (WebCore::AccessibilityNodeObject::isRequired): 41 (WebCore::AccessibilityNodeObject::headingLevel): 42 (WebCore::AccessibilityNodeObject::valueDescription): 43 (WebCore::AccessibilityNodeObject::isARIARange): 44 (WebCore::AccessibilityNodeObject::valueForRange): 45 (WebCore::AccessibilityNodeObject::maxValueForRange): 46 (WebCore::AccessibilityNodeObject::minValueForRange): 47 (WebCore::AccessibilityNodeObject::stepValueForRange): 48 (WebCore::AccessibilityNodeObject::isHeading): 49 (WebCore::AccessibilityNodeObject::isLink): 50 (WebCore::AccessibilityNodeObject::isControl): 51 (WebCore::AccessibilityNodeObject::isFieldset): 52 (WebCore::AccessibilityNodeObject::isGroup): 53 (WebCore::AccessibilityNodeObject::selectedRadioButton): 54 (WebCore::AccessibilityNodeObject::selectedTabItem): 55 (WebCore::AccessibilityNodeObject::checkboxOrRadioValue): 56 (WebCore::AccessibilityNodeObject::anchorElement): 57 (WebCore::AccessibilityNodeObject::actionElement): 58 (WebCore::AccessibilityNodeObject::mouseButtonListener): 59 (WebCore::AccessibilityNodeObject::isDescendantOfBarrenParent): 60 (WebCore::AccessibilityNodeObject::alterSliderValue): 61 (WebCore::AccessibilityNodeObject::increment): 62 (WebCore::AccessibilityNodeObject::decrement): 63 (WebCore::AccessibilityNodeObject::changeValueByStep): 64 (WebCore::AccessibilityNodeObject::changeValueByPercent): 65 (WebCore::AccessibilityNodeObject::isGenericFocusableElement): 66 (WebCore::AccessibilityNodeObject::labelForElement): 67 (WebCore::AccessibilityNodeObject::ariaAccessibilityDescription): 68 (WebCore::siblingWithAriaRole): 69 (WebCore::AccessibilityNodeObject::menuElementForMenuButton): 70 (WebCore::AccessibilityNodeObject::menuForMenuButton): 71 (WebCore::AccessibilityNodeObject::menuItemElementForMenu): 72 (WebCore::AccessibilityNodeObject::menuButtonForMenu): 73 (WebCore::AccessibilityNodeObject::accessibilityDescription): 74 (WebCore::AccessibilityNodeObject::helpText): 75 (WebCore::AccessibilityNodeObject::hierarchicalLevel): 76 (WebCore::AccessibilityNodeObject::textUnderElement): 77 (WebCore::AccessibilityNodeObject::title): 78 (WebCore::AccessibilityNodeObject::text): 79 (WebCore::AccessibilityNodeObject::stringValue): 80 (WebCore::accessibleNameForNode): 81 (WebCore::AccessibilityNodeObject::accessibilityDescriptionForElements): 82 (WebCore::AccessibilityNodeObject::elementsFromAttribute): 83 (WebCore::AccessibilityNodeObject::ariaLabeledByElements): 84 (WebCore::AccessibilityNodeObject::ariaLabeledByAttribute): 85 (WebCore::AccessibilityNodeObject::canSetFocusAttribute): 86 * accessibility/AccessibilityNodeObject.h: 87 (AccessibilityNodeObject): 88 (WebCore::AccessibilityNodeObject::node): 89 * accessibility/AccessibilityRenderObject.cpp: 90 (WebCore::AccessibilityRenderObject::parentObject): 91 (WebCore::AccessibilityRenderObject::isReadOnly): 92 (WebCore::AccessibilityRenderObject::helpText): 93 (WebCore::AccessibilityRenderObject::accessibilityDescription): 94 (WebCore::AccessibilityRenderObject::text): 95 (WebCore::AccessibilityRenderObject::contentChanged): 96 (WebCore): 97 (WebCore::AccessibilityRenderObject::canHaveChildren): 98 * accessibility/AccessibilityRenderObject.h: 99 (AccessibilityRenderObject): 100 1 101 2012-09-12 Michael Saboff <msaboff@apple.com> 2 102 -
trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp
r128353 r128368 260 260 if (input->isTextButton()) 261 261 return buttonRoleType(); 262 if (input->isRangeControl()) 263 return SliderRole; 262 264 return TextFieldRole; 263 265 } 264 266 if (node()->hasTagName(selectTag)) { 265 267 HTMLSelectElement* selectElement = toHTMLSelectElement(node()); 266 return selectElement->multiple() ? ListRole : PopUpButtonRole; 267 } 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; 268 280 if (node()->isFocusable()) 269 281 return GroupRole; … … 302 314 } 303 315 316 bool AccessibilityNodeObject::canHaveChildren() const 317 { 318 // If this is an AccessibilityRenderObject, then it's okay if this object 319 // doesn't have a node - there are some renderers that don't have associated 320 // nodes, like scroll areas and css-generated text. 321 if (!node() && !isAccessibilityRenderObject()) 322 return false; 323 324 // Elements that should not have children 325 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 304 342 bool AccessibilityNodeObject::accessibilityIsIgnored() const 305 343 { 344 // If this element is within a parent that cannot have children, it should not be exposed. 345 if (isDescendantOfBarrenParent()) 346 return true; 347 306 348 return m_role == UnknownRole; 307 349 } … … 324 366 } 325 367 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 384 { 385 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() const 401 { 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 will 414 // 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() const 431 { 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() const 451 { 452 return roleValue() == ImageRole; 453 } 454 455 bool AccessibilityNodeObject::isPasswordField() const 456 { 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() const 472 { 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() const 486 { 487 return roleValue() == ProgressIndicatorRole; 488 } 489 490 bool AccessibilityNodeObject::isSlider() const 491 { 492 return roleValue() == SliderRole; 493 } 494 495 bool AccessibilityNodeObject::isMenuRelated() const 496 { 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() const 509 { 510 return roleValue() == MenuRole; 511 } 512 513 bool AccessibilityNodeObject::isMenuBar() const 514 { 515 return roleValue() == MenuBarRole; 516 } 517 518 bool AccessibilityNodeObject::isMenuButton() const 519 { 520 return roleValue() == MenuButtonRole; 521 } 522 523 bool AccessibilityNodeObject::isMenuItem() const 524 { 525 return roleValue() == MenuItemRole; 526 } 527 528 bool AccessibilityNodeObject::isNativeCheckboxOrRadio() const 529 { 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() const 542 { 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() const 554 { 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() const 567 { 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() const 586 { 587 Node* node = this->node(); 588 if (!node) 589 return false; 590 591 // First test for native checkedness semantics 592 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 attribute 597 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 checked 605 return false; 606 } 607 608 bool AccessibilityNodeObject::isHovered() const 609 { 610 Node* node = this->node(); 611 if (!node) 612 return false; 613 614 return node->hovered(); 615 } 616 617 bool AccessibilityNodeObject::isMultiSelectable() const 618 { 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() const 629 { 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() const 644 { 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() const 656 { 657 // headings can be in block flow and non-block flow 658 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() const 687 { 688 if (!isARIARange()) 689 return String(); 690 691 return getAttribute(aria_valuetextAttr).string(); 692 } 693 694 bool AccessibilityNodeObject::isARIARange() const 695 { 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() const 708 { 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() const 722 { 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() const 736 { 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() const 750 { 751 return getAttribute(stepAttr).toFloat(); 752 } 753 754 bool AccessibilityNodeObject::isHeading() const 755 { 756 return roleValue() == HeadingRole; 757 } 758 759 bool AccessibilityNodeObject::isLink() const 760 { 761 return roleValue() == WebCoreLinkRole; 762 } 763 764 bool AccessibilityNodeObject::isControl() const 765 { 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() const 775 { 776 Node* node = this->node(); 777 if (!node) 778 return false; 779 780 return node->hasTagName(fieldsetTag); 781 } 782 783 bool AccessibilityNodeObject::isGroup() const 784 { 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() const 825 { 826 if (isNativeCheckboxOrRadio()) 827 return isChecked() ? ButtonStateOn : ButtonStateOff; 828 829 return AccessibilityObject::checkboxOrRadioValue(); 830 } 831 832 Element* AccessibilityNodeObject::anchorElement() const 833 { 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 element 841 // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement 842 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() const 851 { 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() const 893 { 894 Node* node = this->node(); 895 if (!node) 896 return 0; 897 898 // check if our parent is a mouse button listener 899 while (node && !node->isElementNode()) 900 node = node->parentNode(); 901 902 if (!node) 903 return 0; 904 905 // FIXME: Do the continuation search like anchorElement does 906 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() const 915 { 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 else 932 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() const 969 { 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 reason 982 // it's focusable, and existing logic should handle this case already - so it's not a 983 // 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 these 989 // 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) const 999 { 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() const 1014 { 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() const 1040 { 1041 if (ariaRoleAttribute() != MenuButtonRole) 1042 return 0; 1043 1044 return siblingWithAriaRole("menu", node()); 1045 } 1046 1047 AccessibilityObject* AccessibilityNodeObject::menuForMenuButton() const 1048 { 1049 return axObjectCache()->getOrCreate(menuElementForMenuButton()); 1050 } 1051 1052 Element* AccessibilityNodeObject::menuItemElementForMenu() const 1053 { 1054 if (ariaRoleAttribute() != MenuRole) 1055 return 0; 1056 1057 return siblingWithAriaRole("menuitem", node()); 1058 } 1059 1060 AccessibilityObject* AccessibilityNodeObject::menuButtonForMenu() const 1061 { 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 MenuBarItem 1066 AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem); 1067 if (menuItemAX->isMenuButton()) 1068 return menuItemAX; 1069 } 1070 return 0; 1071 } 1072 1073 String AccessibilityNodeObject::accessibilityDescription() const 1074 { 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 #endif 1096 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() const 1108 { 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 was 1135 // 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() const 1148 { 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() const 1176 { 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() const 1190 { 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 to 1230 // 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() const 1238 { 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() const 1264 { 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 types 1297 // 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 a 1299 // single static array. 1300 return String(); 1301 } 1302 1303 // This function implements the ARIA accessible name as described by the Mozilla 1304 // 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) const 1323 { 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) const 1340 { 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) const 1368 { 1369 elementsFromAttribute(elements, aria_labeledbyAttr); 1370 if (!elements.size()) 1371 elementsFromAttribute(elements, aria_labelledbyAttr); 1372 } 1373 1374 1375 String AccessibilityNodeObject::ariaLabeledByAttribute() const 1376 { 1377 Vector<Element*> elements; 1378 ariaLabeledByElements(elements); 1379 1380 return accessibilityDescriptionForElements(elements); 1381 } 1382 326 1383 bool AccessibilityNodeObject::canSetFocusAttribute() const 327 1384 { 328 1385 Node* node = this->node(); 1386 if (!node) 1387 return false; 329 1388 330 1389 if (isWebArea()) … … 337 1396 return false; 338 1397 339 if (node->isElementNode() && ! static_cast<Element*>(node)->isEnabledFormControl())1398 if (node->isElementNode() && !toElement(node)->isEnabledFormControl()) 340 1399 return false; 341 1400 -
trunk/Source/WebCore/accessibility/AccessibilityNodeObject.h
r128353 r128368 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 71 107 virtual bool canSetFocusAttribute() const; 72 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 73 136 virtual AccessibilityObject* firstChild() const; 74 137 virtual AccessibilityObject* lastChild() const; … … 78 141 virtual AccessibilityObject* parentObjectIfExists() const; 79 142 80 void setNode(Node*);81 virtual Node* node() const { return m_node; }82 virtual Document* document() const;83 84 143 virtual void detach(); 85 144 virtual void childrenChanged(); 86 145 virtual void updateAccessibilityRole(); 146 147 virtual void increment(); 148 virtual void decrement(); 87 149 88 150 virtual LayoutRect elementRect() const; … … 97 159 virtual AccessibilityRole determineAccessibilityRole(); 98 160 virtual void addChildren(); 161 virtual bool canHaveChildren() const; 99 162 virtual bool accessibilityIsIgnored() const; 100 163 AccessibilityRole ariaRoleAttribute() const; … … 102 165 AccessibilityRole remapAriaRoleDueToParent(AccessibilityRole) const; 103 166 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; 104 181 105 182 private: -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
r128353 r128368 478 478 return 0; 479 479 } 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 480 540 481 bool AccessibilityRenderObject::isAttachment() const 541 482 { … … 549 490 } 550 491 551 bool AccessibilityRenderObject::isPasswordField() const552 {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 566 492 bool AccessibilityRenderObject::isFileUploadButton() const 567 493 { … … 574 500 } 575 501 576 bool AccessibilityRenderObject::isInputImage() const577 {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() const588 {589 return roleValue() == ProgressIndicatorRole;590 }591 592 bool AccessibilityRenderObject::isSlider() const593 {594 return roleValue() == SliderRole;595 }596 597 bool AccessibilityRenderObject::isMenuRelated() const598 {599 AccessibilityRole role = roleValue();600 return role == MenuRole601 || role == MenuBarRole602 || role == MenuButtonRole603 || role == MenuItemRole;604 }605 606 bool AccessibilityRenderObject::isMenu() const607 {608 return roleValue() == MenuRole;609 }610 611 bool AccessibilityRenderObject::isMenuBar() const612 {613 return roleValue() == MenuBarRole;614 }615 616 bool AccessibilityRenderObject::isMenuButton() const617 {618 return roleValue() == MenuButtonRole;619 }620 621 bool AccessibilityRenderObject::isMenuItem() const622 {623 return roleValue() == MenuItemRole;624 }625 626 bool AccessibilityRenderObject::isPressed() const627 {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() const647 {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() const660 {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() const672 {673 ASSERT(m_renderer);674 675 Node* node = this->node();676 if (!node)677 return false;678 679 // First test for native checkedness semantics680 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 attribute685 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 checked693 return false;694 }695 696 bool AccessibilityRenderObject::isHovered() const697 {698 ASSERT(m_renderer);699 return m_renderer->node() && m_renderer->node()->hovered();700 }701 702 bool AccessibilityRenderObject::isMultiSelectable() const703 {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 717 502 bool AccessibilityRenderObject::isReadOnly() const 718 503 { … … 731 516 } 732 517 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(); 518 return AccessibilityNodeObject::isReadOnly(); 742 519 } 743 520 … … 750 527 viewRect.intersect(contentRect); 751 528 return viewRect.isEmpty(); 752 }753 754 int AccessibilityRenderObject::headingLevel() const755 {756 // headings can be in block flow and non-block flow757 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() const786 {787 return roleValue() == HeadingRole;788 }789 790 bool AccessibilityRenderObject::isLink() const791 {792 return roleValue() == WebCoreLinkRole;793 }794 795 bool AccessibilityRenderObject::isControl() const796 {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() const806 {807 RenderBoxModelObject* renderer = renderBoxModelObject();808 if (!renderer)809 return false;810 return renderer->isFieldset();811 }812 813 bool AccessibilityRenderObject::isGroup() const814 {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;853 529 } 854 530 … … 882 558 } 883 559 884 return 0;885 }886 887 Element* AccessibilityRenderObject::actionElement() const888 {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() const932 {933 Node* node = m_renderer->node();934 if (!node)935 return 0;936 937 // check if our parent is a mouse button listener938 while (node && !node->isElementNode())939 node = node->parentNode();940 941 if (!node)942 return 0;943 944 // FIXME: Do the continuation search like anchorElement does945 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 else961 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() const990 {991 if (ariaRoleAttribute() != MenuButtonRole)992 return 0;993 994 return siblingWithAriaRole("menu", renderer()->node());995 }996 997 AccessibilityObject* AccessibilityRenderObject::menuForMenuButton() const998 {999 Element* menu = menuElementForMenuButton();1000 if (menu && menu->renderer())1001 return axObjectCache()->getOrCreate(menu);1002 return 0;1003 }1004 1005 Element* AccessibilityRenderObject::menuItemElementForMenu() const1006 {1007 if (ariaRoleAttribute() != MenuRole)1008 return 0;1009 1010 return siblingWithAriaRole("menuitem", renderer()->node());1011 }1012 1013 AccessibilityObject* AccessibilityRenderObject::menuButtonForMenu() const1014 {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 MenuBarItem1019 AccessibilityObject* menuItemAX = axObjectCache()->getOrCreate(menuItem);1020 if (menuItemAX->isMenuButton())1021 return menuItemAX;1022 }1023 560 return 0; 1024 561 } … … 1062 599 return String(); 1063 600 } 1064 1065 unsigned AccessibilityRenderObject::hierarchicalLevel() const1066 {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 }1098 601 1099 602 static TextIteratorBehavior textIteratorBehaviorForTextRange() … … 1147 650 } 1148 651 1149 AccessibilityButtonState AccessibilityRenderObject::checkboxOrRadioValue() const1150 {1151 if (isNativeCheckboxOrRadio())1152 return isChecked() ? ButtonStateOn : ButtonStateOff;1153 1154 return AccessibilityObject::checkboxOrRadioValue();1155 }1156 1157 String AccessibilityRenderObject::valueDescription() const1158 {1159 if (!isARIARange())1160 return String();1161 1162 return getAttribute(aria_valuetextAttr).string();1163 }1164 1165 float AccessibilityRenderObject::stepValueForRange() const1166 {1167 return getAttribute(stepAttr).toFloat();1168 }1169 1170 bool AccessibilityRenderObject::isARIARange() const1171 {1172 return m_ariaRole == ProgressIndicatorRole1173 || m_ariaRole == SliderRole1174 || m_ariaRole == ScrollBarRole1175 || m_ariaRole == SpinButtonRole;1176 }1177 1178 float AccessibilityRenderObject::valueForRange() const1179 {1180 if (!isARIARange())1181 return 0.0f;1182 1183 return getAttribute(aria_valuenowAttr).toFloat();1184 }1185 1186 float AccessibilityRenderObject::maxValueForRange() const1187 {1188 if (!isARIARange())1189 return 0.0f;1190 1191 return getAttribute(aria_valuemaxAttr).toFloat();1192 }1193 1194 float AccessibilityRenderObject::minValueForRange() const1195 {1196 if (!isARIARange())1197 return 0.0f;1198 1199 return getAttribute(aria_valueminAttr).toFloat();1200 }1201 1202 652 String AccessibilityRenderObject::stringValue() const 1203 653 { … … 1258 708 } 1259 709 1260 // This function implements the ARIA accessible name as described by the Mozilla1261 // 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) const1280 {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) const1297 {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) const1324 {1325 elementsFromAttribute(elements, aria_labeledbyAttr);1326 if (!elements.size())1327 elementsFromAttribute(elements, aria_labelledbyAttr);1328 }1329 1330 String AccessibilityRenderObject::ariaLabeledByAttribute() const1331 {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 1353 710 HTMLLabelElement* AccessibilityRenderObject::labelElementContainer() const 1354 711 { … … 1369 726 } 1370 727 1371 String AccessibilityRenderObject::title() const1372 {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 to1413 // 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 1420 728 String AccessibilityRenderObject::ariaDescribedByAttribute() const 1421 729 { … … 1426 734 } 1427 735 1428 String AccessibilityRenderObject::ariaAccessibilityDescription() const1429 {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 1441 736 String AccessibilityRenderObject::webAreaAccessibilityDescription() const 1442 737 { … … 1491 786 return String(); 1492 787 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 #endif1515 1516 788 if (isWebArea()) 1517 789 return webAreaAccessibilityDescription(); 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(); 790 791 return AccessibilityNodeObject::accessibilityDescription(); 1527 792 } 1528 793 … … 1811 1076 } 1812 1077 1813 bool AccessibilityRenderObject::isDescendantOfBarrenParent() const1814 {1815 for (AccessibilityObject* object = parentObject(); object; object = object->parentObject()) {1816 if (!object->canHaveChildren())1817 return true;1818 }1819 1820 return false;1821 }1822 1823 1078 bool AccessibilityRenderObject::isAllowedChildOfTree() const 1824 1079 { … … 2060 1315 String AccessibilityRenderObject::text() const 2061 1316 { 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 2069 1317 if (isPasswordField()) 2070 1318 return passwordFieldValue(); 2071 1319 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(); 1320 return AccessibilityNodeObject::text(); 2083 1321 } 2084 1322 … … 2238 1476 } 2239 1477 2240 bool AccessibilityRenderObject::isRequired() const2241 {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 2252 1478 bool AccessibilityRenderObject::isSelected() const 2253 1479 { … … 2346 1572 } 2347 1573 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 2371 1574 void AccessibilityRenderObject::setSelectedRows(AccessibilityChildrenVector& selectedRows) 2372 1575 { … … 2428 1631 } 2429 1632 2430 bool AccessibilityRenderObject::isEnabled() const2431 {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 2444 1633 RenderView* AccessibilityRenderObject::topRenderer() const 2445 1634 { … … 3139 2328 } 3140 2329 3141 bool AccessibilityRenderObject::isGenericFocusableElement() const3142 {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 reason3155 // it's focusable, and existing logic should handle this case already - so it's not a3156 // generic focusable element.3157 if (hasContentEditableAttributeSet())3158 return false;3159 3160 // The web area and body element are both focusable, but existing logic handles these3161 // 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 3170 2330 AccessibilityRole AccessibilityRenderObject::determineAccessibilityRole() 3171 2331 { … … 3438 2598 } 3439 2599 } 3440 3441 bool AccessibilityRenderObject::canHaveChildren() const3442 {3443 if (!m_renderer)3444 return false;3445 3446 // Elements that should not have children3447 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 }3462 2600 3463 2601 void AccessibilityRenderObject::clearChildren() … … 3597 2735 #endif 3598 2736 } 3599 2737 2738 bool AccessibilityRenderObject::canHaveChildren() const 2739 { 2740 if (!m_renderer) 2741 return false; 2742 2743 return AccessibilityNodeObject::canHaveChildren(); 2744 } 2745 3600 2746 const AtomicString& AccessibilityRenderObject::ariaLiveRegionStatus() const 3601 2747 { -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h
r128353 r128368 67 67 virtual void init(); 68 68 69 virtual bool isAnchor() const;70 69 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;80 70 virtual bool isFileUploadButton() const; 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; 71 94 72 virtual bool isSelected() const; 95 73 virtual bool isFocused() const; 96 virtual bool isChecked() const;97 virtual bool isHovered() const;98 virtual bool isIndeterminate() const;99 74 virtual bool isLoaded() const; 100 virtual bool isMultiSelectable() const;101 75 virtual bool isOffScreen() const; 102 virtual bool isPressed() const;103 76 virtual bool isReadOnly() const; 104 77 virtual bool isUnvisited() const; 105 78 virtual bool isVisited() const; 106 virtual bool isRequired() const;107 79 virtual bool isLinked() const; 108 80 virtual bool hasBoldFont() const; … … 124 96 virtual bool accessibilityIsIgnored() const; 125 97 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();135 98 virtual int layoutCount() const; 136 99 virtual double estimatedLoadingProgress() const; … … 157 120 virtual AccessibilityObject* accessibilityHitTest(const IntPoint&) const; 158 121 159 virtual Element* actionElement() const;160 Element* mouseButtonListener() const;161 122 FrameView* frameViewIfRenderView() const; 162 123 virtual Element* anchorElement() const; 163 AccessibilityObject* menuForMenuButton() const;164 AccessibilityObject* menuButtonForMenu() const;165 124 166 125 virtual LayoutRect boundingBoxRect() const; … … 185 144 virtual VisibleSelection selection() const; 186 145 virtual String stringValue() const; 187 virtual String ariaLabeledByAttribute() const;188 virtual String title() const;189 146 virtual String ariaDescribedByAttribute() const; 190 147 virtual String accessibilityDescription() const; … … 200 157 virtual void getDocumentLinks(AccessibilityChildrenVector&); 201 158 virtual FrameView* documentFrameView() const; 202 virtual unsigned hierarchicalLevel() const;203 159 204 160 virtual void clearChildren(); … … 209 165 virtual void setValue(const String&); 210 166 virtual void setSelectedRows(AccessibilityChildrenVector&); 211 virtual void changeValueByPercent(float percentChange);212 167 virtual AccessibilityOrientation orientation() const; 213 virtual void increment();214 virtual void decrement();215 168 216 169 virtual void detach(); … … 264 217 265 218 void setRenderObject(RenderObject* renderer) { m_renderer = renderer; } 266 void ariaLabeledByElements(Vector<Element*>& elements) const;267 219 bool needsToUpdateChildren() const { return m_childrenDirty; } 268 220 ScrollableArea* getScrollableAreaIfScrollable() const; … … 277 229 void ariaListboxVisibleChildren(AccessibilityChildrenVector&); 278 230 bool ariaIsHidden() const; 279 bool isDescendantOfBarrenParent() const;280 231 bool isAllowedChildOfTree() const; 281 232 bool hasTextAlternative() const; … … 286 237 virtual void setNeedsToUpdateChildren() { m_childrenDirty = true; } 287 238 288 Element* menuElementForMenuButton() const;289 Element* menuItemElementForMenu() const;290 291 239 bool isTabItemSelected() const; 292 void alterSliderValue(bool increase);293 void changeValueByStep(bool increase);294 bool isNativeCheckboxOrRadio() const;295 240 LayoutRect checkboxOrRadioRect() const; 296 241 void addRadioButtonGroupMembers(AccessibilityChildrenVector& linkedUIElements) const; … … 302 247 bool isDescendantOfElementType(const QualifiedName& tagName) const; 303 248 // 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;306 249 307 250 void addTextFieldChildren(); … … 318 261 void setElementAttributeValue(const QualifiedName&, bool); 319 262 320 String accessibilityDescriptionForElements(Vector<Element*> &elements) const;321 void elementsFromAttribute(Vector<Element*>& elements, const QualifiedName&) const;322 String ariaAccessibilityDescription() const;323 263 String webAreaAccessibilityDescription() const; 324 264
Note: See TracChangeset
for help on using the changeset viewer.