OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012, Google Inc. All rights reserved. | 2 * Copyright (C) 2012, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 #include "core/accessibility/AXObjectCache.h" | 32 #include "core/accessibility/AXObjectCache.h" |
33 #include "core/dom/NodeTraversal.h" | 33 #include "core/dom/NodeTraversal.h" |
34 #include "core/dom/Text.h" | 34 #include "core/dom/Text.h" |
35 #include "core/html/HTMLFieldSetElement.h" | 35 #include "core/html/HTMLFieldSetElement.h" |
36 #include "core/html/HTMLFrameElementBase.h" | 36 #include "core/html/HTMLFrameElementBase.h" |
37 #include "core/html/HTMLInputElement.h" | 37 #include "core/html/HTMLInputElement.h" |
38 #include "core/html/HTMLLabelElement.h" | 38 #include "core/html/HTMLLabelElement.h" |
39 #include "core/html/HTMLLegendElement.h" | 39 #include "core/html/HTMLLegendElement.h" |
40 #include "core/html/HTMLSelectElement.h" | 40 #include "core/html/HTMLSelectElement.h" |
| 41 #include "core/html/HTMLTextAreaElement.h" |
41 #include "core/rendering/RenderObject.h" | 42 #include "core/rendering/RenderObject.h" |
42 #include "platform/UserGestureIndicator.h" | 43 #include "platform/UserGestureIndicator.h" |
43 #include "wtf/text/StringBuilder.h" | 44 #include "wtf/text/StringBuilder.h" |
44 | 45 |
45 using namespace std; | 46 using namespace std; |
46 | 47 |
47 namespace WebCore { | 48 namespace WebCore { |
48 | 49 |
49 using namespace HTMLNames; | 50 using namespace HTMLNames; |
50 | 51 |
(...skipping 18 matching lines...) Expand all Loading... |
69 ASSERT(isDetached()); | 70 ASSERT(isDetached()); |
70 } | 71 } |
71 | 72 |
72 // This function implements the ARIA accessible name as described by the Mozilla | 73 // This function implements the ARIA accessible name as described by the Mozilla |
73 // ARIA Implementer's Guide. | 74 // ARIA Implementer's Guide. |
74 static String accessibleNameForNode(Node* node) | 75 static String accessibleNameForNode(Node* node) |
75 { | 76 { |
76 if (node->isTextNode()) | 77 if (node->isTextNode()) |
77 return toText(node)->data(); | 78 return toText(node)->data(); |
78 | 79 |
79 if (node->hasTagName(inputTag)) | 80 if (isHTMLInputElement(*node)) |
80 return toHTMLInputElement(node)->value(); | 81 return toHTMLInputElement(*node).value(); |
81 | 82 |
82 if (node->isHTMLElement()) { | 83 if (node->isHTMLElement()) { |
83 const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr); | 84 const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr); |
84 if (!alt.isEmpty()) | 85 if (!alt.isEmpty()) |
85 return alt; | 86 return alt; |
86 } | 87 } |
87 | 88 |
88 return String(); | 89 return String(); |
89 } | 90 } |
90 | 91 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 AccessibilityRole ariaRole = ariaRoleAttribute(); | 180 AccessibilityRole ariaRole = ariaRoleAttribute(); |
180 if (ariaRole != UnknownRole) | 181 if (ariaRole != UnknownRole) |
181 return ariaRole; | 182 return ariaRole; |
182 | 183 |
183 if (node()->isLink()) | 184 if (node()->isLink()) |
184 return LinkRole; | 185 return LinkRole; |
185 if (node()->isTextNode()) | 186 if (node()->isTextNode()) |
186 return StaticTextRole; | 187 return StaticTextRole; |
187 if (node()->hasTagName(buttonTag)) | 188 if (node()->hasTagName(buttonTag)) |
188 return buttonRoleType(); | 189 return buttonRoleType(); |
189 if (node()->hasTagName(inputTag)) { | 190 if (isHTMLInputElement(*node())) { |
190 HTMLInputElement* input = toHTMLInputElement(node()); | 191 HTMLInputElement& input = toHTMLInputElement(*node()); |
191 if (input->isCheckbox()) | 192 if (input.isCheckbox()) |
192 return CheckBoxRole; | 193 return CheckBoxRole; |
193 if (input->isRadioButton()) | 194 if (input.isRadioButton()) |
194 return RadioButtonRole; | 195 return RadioButtonRole; |
195 if (input->isTextButton()) | 196 if (input.isTextButton()) |
196 return buttonRoleType(); | 197 return buttonRoleType(); |
197 if (input->isRangeControl()) | 198 if (input.isRangeControl()) |
198 return SliderRole; | 199 return SliderRole; |
199 | 200 |
200 const AtomicString& type = input->getAttribute(typeAttr); | 201 const AtomicString& type = input.getAttribute(typeAttr); |
201 if (equalIgnoringCase(type, "color")) | 202 if (equalIgnoringCase(type, "color")) |
202 return ColorWellRole; | 203 return ColorWellRole; |
203 | 204 |
204 return TextFieldRole; | 205 return TextFieldRole; |
205 } | 206 } |
206 if (node()->hasTagName(selectTag)) { | 207 if (isHTMLSelectElement(*node())) { |
207 HTMLSelectElement* selectElement = toHTMLSelectElement(node()); | 208 HTMLSelectElement& selectElement = toHTMLSelectElement(*node()); |
208 return selectElement->multiple() ? ListBoxRole : PopUpButtonRole; | 209 return selectElement.multiple() ? ListBoxRole : PopUpButtonRole; |
209 } | 210 } |
210 if (node()->hasTagName(textareaTag)) | 211 if (isHTMLTextAreaElement(*node())) |
211 return TextAreaRole; | 212 return TextAreaRole; |
212 if (headingLevel()) | 213 if (headingLevel()) |
213 return HeadingRole; | 214 return HeadingRole; |
214 if (node()->hasTagName(divTag)) | 215 if (node()->hasTagName(divTag)) |
215 return DivRole; | 216 return DivRole; |
216 if (node()->hasTagName(pTag)) | 217 if (node()->hasTagName(pTag)) |
217 return ParagraphRole; | 218 return ParagraphRole; |
218 if (node()->hasTagName(labelTag)) | 219 if (node()->hasTagName(labelTag)) |
219 return LabelRole; | 220 return LabelRole; |
220 if (node()->isElementNode() && toElement(node())->isFocusable()) | 221 if (node()->isElementNode() && toElement(node())->isFocusable()) |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 } | 500 } |
500 | 501 |
501 bool AXNodeObject::isImageButton() const | 502 bool AXNodeObject::isImageButton() const |
502 { | 503 { |
503 return isNativeImage() && isButton(); | 504 return isNativeImage() && isButton(); |
504 } | 505 } |
505 | 506 |
506 bool AXNodeObject::isInputImage() const | 507 bool AXNodeObject::isInputImage() const |
507 { | 508 { |
508 Node* node = this->node(); | 509 Node* node = this->node(); |
509 if (!node) | 510 if (roleValue() == ButtonRole && isHTMLInputElement(node)) |
510 return false; | 511 return toHTMLInputElement(*node).isImageButton(); |
511 | |
512 if (roleValue() == ButtonRole && node->hasTagName(inputTag)) | |
513 return toHTMLInputElement(node)->isImageButton(); | |
514 | 512 |
515 return false; | 513 return false; |
516 } | 514 } |
517 | 515 |
518 bool AXNodeObject::isLink() const | 516 bool AXNodeObject::isLink() const |
519 { | 517 { |
520 return roleValue() == LinkRole; | 518 return roleValue() == LinkRole; |
521 } | 519 } |
522 | 520 |
523 bool AXNodeObject::isMenu() const | 521 bool AXNodeObject::isMenu() const |
524 { | 522 { |
525 return roleValue() == MenuRole; | 523 return roleValue() == MenuRole; |
526 } | 524 } |
527 | 525 |
528 bool AXNodeObject::isMenuButton() const | 526 bool AXNodeObject::isMenuButton() const |
529 { | 527 { |
530 return roleValue() == MenuButtonRole; | 528 return roleValue() == MenuButtonRole; |
531 } | 529 } |
532 | 530 |
533 bool AXNodeObject::isMultiSelectable() const | 531 bool AXNodeObject::isMultiSelectable() const |
534 { | 532 { |
535 const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableA
ttr); | 533 const AtomicString& ariaMultiSelectable = getAttribute(aria_multiselectableA
ttr); |
536 if (equalIgnoringCase(ariaMultiSelectable, "true")) | 534 if (equalIgnoringCase(ariaMultiSelectable, "true")) |
537 return true; | 535 return true; |
538 if (equalIgnoringCase(ariaMultiSelectable, "false")) | 536 if (equalIgnoringCase(ariaMultiSelectable, "false")) |
539 return false; | 537 return false; |
540 | 538 |
541 return node() && node()->hasTagName(selectTag) && toHTMLSelectElement(node()
)->multiple(); | 539 return isHTMLSelectElement(node()) && toHTMLSelectElement(*node()).multiple(
); |
542 } | 540 } |
543 | 541 |
544 bool AXNodeObject::isNativeCheckboxOrRadio() const | 542 bool AXNodeObject::isNativeCheckboxOrRadio() const |
545 { | 543 { |
546 Node* node = this->node(); | 544 Node* node = this->node(); |
547 if (!node || !node->hasTagName(inputTag)) | 545 if (!isHTMLInputElement(node)) |
548 return false; | 546 return false; |
549 | 547 |
550 HTMLInputElement* input = toHTMLInputElement(node); | 548 HTMLInputElement* input = toHTMLInputElement(node); |
551 return input->isCheckbox() || input->isRadioButton(); | 549 return input->isCheckbox() || input->isRadioButton(); |
552 } | 550 } |
553 | 551 |
554 bool AXNodeObject::isNativeImage() const | 552 bool AXNodeObject::isNativeImage() const |
555 { | 553 { |
556 Node* node = this->node(); | 554 Node* node = this->node(); |
557 if (!node) | 555 if (!node) |
558 return false; | 556 return false; |
559 | 557 |
560 if (node->hasTagName(imgTag)) | 558 if (node->hasTagName(imgTag)) |
561 return true; | 559 return true; |
562 | 560 |
563 if (node->hasTagName(appletTag) || node->hasTagName(embedTag) || node->hasTa
gName(objectTag)) | 561 if (node->hasTagName(appletTag) || node->hasTagName(embedTag) || node->hasTa
gName(objectTag)) |
564 return true; | 562 return true; |
565 | 563 |
566 if (node->hasTagName(inputTag)) | 564 if (isHTMLInputElement(*node)) |
567 return toHTMLInputElement(node)->isImageButton(); | 565 return toHTMLInputElement(*node).isImageButton(); |
568 | 566 |
569 return false; | 567 return false; |
570 } | 568 } |
571 | 569 |
572 bool AXNodeObject::isNativeTextControl() const | 570 bool AXNodeObject::isNativeTextControl() const |
573 { | 571 { |
574 Node* node = this->node(); | 572 Node* node = this->node(); |
575 if (!node) | 573 if (!node) |
576 return false; | 574 return false; |
577 | 575 |
578 if (node->hasTagName(textareaTag)) | 576 if (isHTMLTextAreaElement(*node)) |
579 return true; | 577 return true; |
580 | 578 |
581 if (node->hasTagName(inputTag)) { | 579 if (isHTMLInputElement(*node)) { |
582 HTMLInputElement* input = toHTMLInputElement(node); | 580 HTMLInputElement* input = toHTMLInputElement(node); |
583 return input->isText() || input->isNumberField(); | 581 return input->isText() || input->isNumberField(); |
584 } | 582 } |
585 | 583 |
586 return false; | 584 return false; |
587 } | 585 } |
588 | 586 |
589 bool AXNodeObject::isNonNativeTextControl() const | 587 bool AXNodeObject::isNonNativeTextControl() const |
590 { | 588 { |
591 if (isNativeTextControl()) | 589 if (isNativeTextControl()) |
592 return false; | 590 return false; |
593 | 591 |
594 if (hasContentEditableAttributeSet()) | 592 if (hasContentEditableAttributeSet()) |
595 return true; | 593 return true; |
596 | 594 |
597 if (isARIATextControl()) | 595 if (isARIATextControl()) |
598 return true; | 596 return true; |
599 | 597 |
600 return false; | 598 return false; |
601 } | 599 } |
602 | 600 |
603 bool AXNodeObject::isPasswordField() const | 601 bool AXNodeObject::isPasswordField() const |
604 { | 602 { |
605 Node* node = this->node(); | 603 Node* node = this->node(); |
606 if (!node || !node->hasTagName(inputTag)) | 604 if (!isHTMLInputElement(node)) |
607 return false; | 605 return false; |
608 | 606 |
609 if (ariaRoleAttribute() != UnknownRole) | 607 if (ariaRoleAttribute() != UnknownRole) |
610 return false; | 608 return false; |
611 | 609 |
612 return toHTMLInputElement(node)->isPasswordField(); | 610 return toHTMLInputElement(node)->isPasswordField(); |
613 } | 611 } |
614 | 612 |
615 bool AXNodeObject::isProgressIndicator() const | 613 bool AXNodeObject::isProgressIndicator() const |
616 { | 614 { |
617 return roleValue() == ProgressIndicatorRole; | 615 return roleValue() == ProgressIndicatorRole; |
618 } | 616 } |
619 | 617 |
620 bool AXNodeObject::isSlider() const | 618 bool AXNodeObject::isSlider() const |
621 { | 619 { |
622 return roleValue() == SliderRole; | 620 return roleValue() == SliderRole; |
623 } | 621 } |
624 | 622 |
625 bool AXNodeObject::isChecked() const | 623 bool AXNodeObject::isChecked() const |
626 { | 624 { |
627 Node* node = this->node(); | 625 Node* node = this->node(); |
628 if (!node) | 626 if (!node) |
629 return false; | 627 return false; |
630 | 628 |
631 // First test for native checkedness semantics | 629 // First test for native checkedness semantics |
632 if (node->hasTagName(inputTag)) | 630 if (isHTMLInputElement(*node)) |
633 return toHTMLInputElement(node)->shouldAppearChecked(); | 631 return toHTMLInputElement(*node).shouldAppearChecked(); |
634 | 632 |
635 // Else, if this is an ARIA checkbox or radio, respect the aria-checked attr
ibute | 633 // Else, if this is an ARIA checkbox or radio, respect the aria-checked attr
ibute |
636 AccessibilityRole ariaRole = ariaRoleAttribute(); | 634 AccessibilityRole ariaRole = ariaRoleAttribute(); |
637 if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) { | 635 if (ariaRole == RadioButtonRole || ariaRole == CheckBoxRole) { |
638 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) | 636 if (equalIgnoringCase(getAttribute(aria_checkedAttr), "true")) |
639 return true; | 637 return true; |
640 return false; | 638 return false; |
641 } | 639 } |
642 | 640 |
643 // Otherwise it's not checked | 641 // Otherwise it's not checked |
(...skipping 22 matching lines...) Expand all Loading... |
666 Node* node = this->node(); | 664 Node* node = this->node(); |
667 if (!node || !node->isElementNode()) | 665 if (!node || !node->isElementNode()) |
668 return true; | 666 return true; |
669 | 667 |
670 return !toElement(node)->isDisabledFormControl(); | 668 return !toElement(node)->isDisabledFormControl(); |
671 } | 669 } |
672 | 670 |
673 bool AXNodeObject::isIndeterminate() const | 671 bool AXNodeObject::isIndeterminate() const |
674 { | 672 { |
675 Node* node = this->node(); | 673 Node* node = this->node(); |
676 if (!node || !node->hasTagName(inputTag)) | 674 if (!isHTMLInputElement(node)) |
677 return false; | 675 return false; |
678 | 676 |
679 return toHTMLInputElement(node)->shouldAppearIndeterminate(); | 677 return toHTMLInputElement(node)->shouldAppearIndeterminate(); |
680 } | 678 } |
681 | 679 |
682 bool AXNodeObject::isPressed() const | 680 bool AXNodeObject::isPressed() const |
683 { | 681 { |
684 if (!isButton()) | 682 if (!isButton()) |
685 return false; | 683 return false; |
686 | 684 |
(...skipping 10 matching lines...) Expand all Loading... |
697 | 695 |
698 return node->active(); | 696 return node->active(); |
699 } | 697 } |
700 | 698 |
701 bool AXNodeObject::isReadOnly() const | 699 bool AXNodeObject::isReadOnly() const |
702 { | 700 { |
703 Node* node = this->node(); | 701 Node* node = this->node(); |
704 if (!node) | 702 if (!node) |
705 return true; | 703 return true; |
706 | 704 |
707 if (node->hasTagName(textareaTag)) | 705 if (isHTMLTextAreaElement(*node)) |
708 return toHTMLFormControlElement(node)->isReadOnly(); | 706 return toHTMLTextAreaElement(*node).isReadOnly(); |
709 | 707 |
710 if (node->hasTagName(inputTag)) { | 708 if (isHTMLInputElement(*node)) { |
711 HTMLInputElement* input = toHTMLInputElement(node); | 709 HTMLInputElement& input = toHTMLInputElement(*node); |
712 if (input->isTextField()) | 710 if (input.isTextField()) |
713 return input->isReadOnly(); | 711 return input.isReadOnly(); |
714 } | 712 } |
715 | 713 |
716 return !node->rendererIsEditable(); | 714 return !node->rendererIsEditable(); |
717 } | 715 } |
718 | 716 |
719 bool AXNodeObject::isRequired() const | 717 bool AXNodeObject::isRequired() const |
720 { | 718 { |
721 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true")) | 719 if (equalIgnoringCase(getAttribute(aria_requiredAttr), "true")) |
722 return true; | 720 return true; |
723 | 721 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 if (ariaRoleAttribute() == StaticTextRole) | 872 if (ariaRoleAttribute() == StaticTextRole) |
875 return ariaAccessibilityDescription(); | 873 return ariaAccessibilityDescription(); |
876 | 874 |
877 if (!isTextControl()) | 875 if (!isTextControl()) |
878 return String(); | 876 return String(); |
879 | 877 |
880 Node* node = this->node(); | 878 Node* node = this->node(); |
881 if (!node) | 879 if (!node) |
882 return String(); | 880 return String(); |
883 | 881 |
884 if (isNativeTextControl() && (node->hasTagName(textareaTag) || node->hasTagN
ame(inputTag))) | 882 if (isNativeTextControl() && (isHTMLTextAreaElement(*node) || isHTMLInputEle
ment(*node))) |
885 return toHTMLTextFormControlElement(node)->value(); | 883 return toHTMLTextFormControlElement(*node).value(); |
886 | 884 |
887 if (!node->isElementNode()) | 885 if (!node->isElementNode()) |
888 return String(); | 886 return String(); |
889 | 887 |
890 return toElement(node)->innerText(); | 888 return toElement(node)->innerText(); |
891 } | 889 } |
892 | 890 |
893 AXObject* AXNodeObject::titleUIElement() const | 891 AXObject* AXNodeObject::titleUIElement() const |
894 { | 892 { |
895 if (!node() || !node()->isElementNode()) | 893 if (!node() || !node()->isElementNode()) |
(...skipping 19 matching lines...) Expand all Loading... |
915 | 913 |
916 void AXNodeObject::colorValue(int& r, int& g, int& b) const | 914 void AXNodeObject::colorValue(int& r, int& g, int& b) const |
917 { | 915 { |
918 r = 0; | 916 r = 0; |
919 g = 0; | 917 g = 0; |
920 b = 0; | 918 b = 0; |
921 | 919 |
922 if (!isColorWell()) | 920 if (!isColorWell()) |
923 return; | 921 return; |
924 | 922 |
925 if (!node() || !node()->hasTagName(inputTag)) | 923 if (!isHTMLInputElement(node())) |
926 return; | 924 return; |
927 | 925 |
928 HTMLInputElement* input = toHTMLInputElement(node()); | 926 HTMLInputElement* input = toHTMLInputElement(node()); |
929 const AtomicString& type = input->getAttribute(typeAttr); | 927 const AtomicString& type = input->getAttribute(typeAttr); |
930 if (!equalIgnoringCase(type, "color")) | 928 if (!equalIgnoringCase(type, "color")) |
931 return; | 929 return; |
932 | 930 |
933 // HTMLInputElement::value always returns a string parseable by Color. | 931 // HTMLInputElement::value always returns a string parseable by Color. |
934 Color color; | 932 Color color; |
935 bool success = color.setFromString(input->value()); | 933 bool success = color.setFromString(input->value()); |
936 ASSERT_UNUSED(success, success); | 934 ASSERT_UNUSED(success, success); |
937 r = color.red(); | 935 r = color.red(); |
938 g = color.green(); | 936 g = color.green(); |
939 b = color.blue(); | 937 b = color.blue(); |
940 } | 938 } |
941 | 939 |
942 String AXNodeObject::valueDescription() const | 940 String AXNodeObject::valueDescription() const |
943 { | 941 { |
944 if (!supportsRangeValue()) | 942 if (!supportsRangeValue()) |
945 return String(); | 943 return String(); |
946 | 944 |
947 return getAttribute(aria_valuetextAttr).string(); | 945 return getAttribute(aria_valuetextAttr).string(); |
948 } | 946 } |
949 | 947 |
950 float AXNodeObject::valueForRange() const | 948 float AXNodeObject::valueForRange() const |
951 { | 949 { |
952 if (hasAttribute(aria_valuenowAttr)) | 950 if (hasAttribute(aria_valuenowAttr)) |
953 return getAttribute(aria_valuenowAttr).toFloat(); | 951 return getAttribute(aria_valuenowAttr).toFloat(); |
954 | 952 |
955 if (node() && node()->hasTagName(inputTag)) { | 953 if (isHTMLInputElement(node())) { |
956 HTMLInputElement* input = toHTMLInputElement(node()); | 954 HTMLInputElement& input = toHTMLInputElement(*node()); |
957 if (input->isRangeControl()) | 955 if (input.isRangeControl()) |
958 return input->valueAsNumber(); | 956 return input.valueAsNumber(); |
959 } | 957 } |
960 | 958 |
961 return 0.0; | 959 return 0.0; |
962 } | 960 } |
963 | 961 |
964 float AXNodeObject::maxValueForRange() const | 962 float AXNodeObject::maxValueForRange() const |
965 { | 963 { |
966 if (hasAttribute(aria_valuemaxAttr)) | 964 if (hasAttribute(aria_valuemaxAttr)) |
967 return getAttribute(aria_valuemaxAttr).toFloat(); | 965 return getAttribute(aria_valuemaxAttr).toFloat(); |
968 | 966 |
969 if (node() && node()->hasTagName(inputTag)) { | 967 if (isHTMLInputElement(node())) { |
970 HTMLInputElement* input = toHTMLInputElement(node()); | 968 HTMLInputElement& input = toHTMLInputElement(*node()); |
971 if (input->isRangeControl()) | 969 if (input.isRangeControl()) |
972 return input->maximum(); | 970 return input.maximum(); |
973 } | 971 } |
974 | 972 |
975 return 0.0; | 973 return 0.0; |
976 } | 974 } |
977 | 975 |
978 float AXNodeObject::minValueForRange() const | 976 float AXNodeObject::minValueForRange() const |
979 { | 977 { |
980 if (hasAttribute(aria_valueminAttr)) | 978 if (hasAttribute(aria_valueminAttr)) |
981 return getAttribute(aria_valueminAttr).toFloat(); | 979 return getAttribute(aria_valueminAttr).toFloat(); |
982 | 980 |
983 if (node() && node()->hasTagName(inputTag)) { | 981 if (isHTMLInputElement(node())) { |
984 HTMLInputElement* input = toHTMLInputElement(node()); | 982 HTMLInputElement& input = toHTMLInputElement(*node()); |
985 if (input->isRangeControl()) | 983 if (input.isRangeControl()) |
986 return input->minimum(); | 984 return input.minimum(); |
987 } | 985 } |
988 | 986 |
989 return 0.0; | 987 return 0.0; |
990 } | 988 } |
991 | 989 |
992 float AXNodeObject::stepValueForRange() const | 990 float AXNodeObject::stepValueForRange() const |
993 { | 991 { |
994 return getAttribute(stepAttr).toFloat(); | 992 return getAttribute(stepAttr).toFloat(); |
995 } | 993 } |
996 | 994 |
997 String AXNodeObject::stringValue() const | 995 String AXNodeObject::stringValue() const |
998 { | 996 { |
999 Node* node = this->node(); | 997 Node* node = this->node(); |
1000 if (!node) | 998 if (!node) |
1001 return String(); | 999 return String(); |
1002 | 1000 |
1003 if (ariaRoleAttribute() == StaticTextRole) { | 1001 if (ariaRoleAttribute() == StaticTextRole) { |
1004 String staticText = text(); | 1002 String staticText = text(); |
1005 if (!staticText.length()) | 1003 if (!staticText.length()) |
1006 staticText = textUnderElement(); | 1004 staticText = textUnderElement(); |
1007 return staticText; | 1005 return staticText; |
1008 } | 1006 } |
1009 | 1007 |
1010 if (node->isTextNode()) | 1008 if (node->isTextNode()) |
1011 return textUnderElement(); | 1009 return textUnderElement(); |
1012 | 1010 |
1013 if (node->hasTagName(selectTag)) { | 1011 if (isHTMLSelectElement(*node)) { |
1014 HTMLSelectElement* selectElement = toHTMLSelectElement(node); | 1012 HTMLSelectElement& selectElement = toHTMLSelectElement(*node); |
1015 int selectedIndex = selectElement->selectedIndex(); | 1013 int selectedIndex = selectElement.selectedIndex(); |
1016 const Vector<HTMLElement*> listItems = selectElement->listItems(); | 1014 const Vector<HTMLElement*> listItems = selectElement.listItems(); |
1017 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems
.size()) { | 1015 if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems
.size()) { |
1018 const AtomicString& overriddenDescription = listItems[selectedIndex]
->fastGetAttribute(aria_labelAttr); | 1016 const AtomicString& overriddenDescription = listItems[selectedIndex]
->fastGetAttribute(aria_labelAttr); |
1019 if (!overriddenDescription.isNull()) | 1017 if (!overriddenDescription.isNull()) |
1020 return overriddenDescription; | 1018 return overriddenDescription; |
1021 } | 1019 } |
1022 if (!selectElement->multiple()) | 1020 if (!selectElement.multiple()) |
1023 return selectElement->value(); | 1021 return selectElement.value(); |
1024 return String(); | 1022 return String(); |
1025 } | 1023 } |
1026 | 1024 |
1027 if (isTextControl()) | 1025 if (isTextControl()) |
1028 return text(); | 1026 return text(); |
1029 | 1027 |
1030 // FIXME: We might need to implement a value here for more types | 1028 // FIXME: We might need to implement a value here for more types |
1031 // FIXME: It would be better not to advertise a value at all for the types f
or which we don't implement one; | 1029 // FIXME: It would be better not to advertise a value at all for the types f
or which we don't implement one; |
1032 // this would require subclassing or making accessibilityAttributeNames do s
omething other than return a | 1030 // this would require subclassing or making accessibilityAttributeNames do s
omething other than return a |
1033 // single static array. | 1031 // single static array. |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 | 1155 |
1158 return String(); | 1156 return String(); |
1159 } | 1157 } |
1160 | 1158 |
1161 String AXNodeObject::title() const | 1159 String AXNodeObject::title() const |
1162 { | 1160 { |
1163 Node* node = this->node(); | 1161 Node* node = this->node(); |
1164 if (!node) | 1162 if (!node) |
1165 return String(); | 1163 return String(); |
1166 | 1164 |
1167 bool isInputTag = node->hasTagName(inputTag); | 1165 bool isInputElement = isHTMLInputElement(*node); |
1168 if (isInputTag) { | 1166 if (isInputElement) { |
1169 HTMLInputElement* input = toHTMLInputElement(node); | 1167 HTMLInputElement& input = toHTMLInputElement(*node); |
1170 if (input->isTextButton()) | 1168 if (input.isTextButton()) |
1171 return input->valueWithDefault(); | 1169 return input.valueWithDefault(); |
1172 } | 1170 } |
1173 | 1171 |
1174 if (isInputTag || AXObject::isARIAInput(ariaRoleAttribute()) || isControl())
{ | 1172 if (isInputElement || AXObject::isARIAInput(ariaRoleAttribute()) || isContro
l()) { |
1175 HTMLLabelElement* label = labelForElement(toElement(node)); | 1173 HTMLLabelElement* label = labelForElement(toElement(node)); |
1176 if (label && !exposesTitleUIElement()) | 1174 if (label && !exposesTitleUIElement()) |
1177 return label->innerText(); | 1175 return label->innerText(); |
1178 } | 1176 } |
1179 | 1177 |
1180 // If this node isn't rendered, there's no inner text we can extract from a
select element. | 1178 // If this node isn't rendered, there's no inner text we can extract from a
select element. |
1181 if (!isAXRenderObject() && node->hasTagName(selectTag)) | 1179 if (!isAXRenderObject() && isHTMLSelectElement(*node)) |
1182 return String(); | 1180 return String(); |
1183 | 1181 |
1184 switch (roleValue()) { | 1182 switch (roleValue()) { |
1185 case PopUpButtonRole: | 1183 case PopUpButtonRole: |
1186 // Native popup buttons should not use their button children's text as a
title. That value is retrieved through stringValue(). | 1184 // Native popup buttons should not use their button children's text as a
title. That value is retrieved through stringValue(). |
1187 if (node->hasTagName(selectTag)) | 1185 if (isHTMLSelectElement(*node)) |
1188 return String(); | 1186 return String(); |
1189 case ButtonRole: | 1187 case ButtonRole: |
1190 case ToggleButtonRole: | 1188 case ToggleButtonRole: |
1191 case CheckBoxRole: | 1189 case CheckBoxRole: |
1192 case ListBoxOptionRole: | 1190 case ListBoxOptionRole: |
1193 case MenuButtonRole: | 1191 case MenuButtonRole: |
1194 case MenuItemRole: | 1192 case MenuItemRole: |
1195 case RadioButtonRole: | 1193 case RadioButtonRole: |
1196 case TabRole: | 1194 case TabRole: |
1197 return textUnderElement(); | 1195 return textUnderElement(); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 return true; | 1389 return true; |
1392 } | 1390 } |
1393 } | 1391 } |
1394 | 1392 |
1395 Element* AXNodeObject::actionElement() const | 1393 Element* AXNodeObject::actionElement() const |
1396 { | 1394 { |
1397 Node* node = this->node(); | 1395 Node* node = this->node(); |
1398 if (!node) | 1396 if (!node) |
1399 return 0; | 1397 return 0; |
1400 | 1398 |
1401 if (node->hasTagName(inputTag)) { | 1399 if (isHTMLInputElement(*node)) { |
1402 HTMLInputElement* input = toHTMLInputElement(node); | 1400 HTMLInputElement& input = toHTMLInputElement(*node); |
1403 if (!input->isDisabledFormControl() && (isCheckboxOrRadio() || input->is
TextButton())) | 1401 if (!input.isDisabledFormControl() && (isCheckboxOrRadio() || input.isTe
xtButton())) |
1404 return input; | 1402 return &input; |
1405 } else if (node->hasTagName(buttonTag)) { | 1403 } else if (node->hasTagName(buttonTag)) { |
1406 return toElement(node); | 1404 return toElement(node); |
1407 } | 1405 } |
1408 | 1406 |
1409 if (isFileUploadButton()) | 1407 if (isFileUploadButton()) |
1410 return toElement(node); | 1408 return toElement(node); |
1411 | 1409 |
1412 if (AXObject::isARIAInput(ariaRoleAttribute())) | 1410 if (AXObject::isARIAInput(ariaRoleAttribute())) |
1413 return toElement(node); | 1411 return toElement(node); |
1414 | 1412 |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 if (titleUIElement) | 1755 if (titleUIElement) |
1758 textOrder.append(AccessibilityText(String(), LabelByElementText, titleUI
Element)); | 1756 textOrder.append(AccessibilityText(String(), LabelByElementText, titleUI
Element)); |
1759 } | 1757 } |
1760 | 1758 |
1761 void AXNodeObject::visibleText(Vector<AccessibilityText>& textOrder) const | 1759 void AXNodeObject::visibleText(Vector<AccessibilityText>& textOrder) const |
1762 { | 1760 { |
1763 Node* node = this->node(); | 1761 Node* node = this->node(); |
1764 if (!node) | 1762 if (!node) |
1765 return; | 1763 return; |
1766 | 1764 |
1767 bool isInputTag = node->hasTagName(inputTag); | 1765 if (isHTMLInputElement(*node)) { |
1768 if (isInputTag) { | 1766 HTMLInputElement& input = toHTMLInputElement(*node); |
1769 HTMLInputElement* input = toHTMLInputElement(node); | 1767 if (input.isTextButton()) { |
1770 if (input->isTextButton()) { | 1768 textOrder.append(AccessibilityText(input.valueWithDefault(), Visible
Text)); |
1771 textOrder.append(AccessibilityText(input->valueWithDefault(), Visibl
eText)); | |
1772 return; | 1769 return; |
1773 } | 1770 } |
1774 } | 1771 } |
1775 | 1772 |
1776 // If this node isn't rendered, there's no inner text we can extract from a
select element. | 1773 // If this node isn't rendered, there's no inner text we can extract from a
select element. |
1777 if (!isAXRenderObject() && node->hasTagName(selectTag)) | 1774 if (!isAXRenderObject() && node->hasTagName(selectTag)) |
1778 return; | 1775 return; |
1779 | 1776 |
1780 bool useTextUnderElement = false; | 1777 bool useTextUnderElement = false; |
1781 | 1778 |
(...skipping 22 matching lines...) Expand all Loading... |
1804 useTextUnderElement = true; | 1801 useTextUnderElement = true; |
1805 | 1802 |
1806 if (useTextUnderElement) { | 1803 if (useTextUnderElement) { |
1807 String text = textUnderElement(); | 1804 String text = textUnderElement(); |
1808 if (!text.isEmpty()) | 1805 if (!text.isEmpty()) |
1809 textOrder.append(AccessibilityText(text, ChildrenText)); | 1806 textOrder.append(AccessibilityText(text, ChildrenText)); |
1810 } | 1807 } |
1811 } | 1808 } |
1812 | 1809 |
1813 } // namespace WebCore | 1810 } // namespace WebCore |
OLD | NEW |