1 /* 2 * Copyright (C) 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "config.h" 30 #include "core/accessibility/AXListBoxOption.h" 31 32 #include "core/accessibility/AXObjectCache.h" 33 #include "core/html/HTMLOptionElement.h" 34 #include "core/html/HTMLSelectElement.h" 35 #include "core/rendering/RenderListBox.h" 36 37 38 namespace blink { 39 40 using namespace HTMLNames; 41 42 AXListBoxOption::AXListBoxOption(RenderObject* renderer) 43 : AXRenderObject(renderer) 44 { 45 } 46 47 AXListBoxOption::~AXListBoxOption() 48 { 49 } 50 51 PassRefPtr<AXListBoxOption> AXListBoxOption::create(RenderObject* renderer) 52 { 53 return adoptRef(new AXListBoxOption(renderer)); 54 } 55 56 bool AXListBoxOption::isEnabled() const 57 { 58 if (!node()) 59 return false; 60 61 if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true")) 62 return false; 63 64 if (toElement(node())->hasAttribute(disabledAttr)) 65 return false; 66 67 return true; 68 } 69 70 bool AXListBoxOption::isSelected() const 71 { 72 return isHTMLOptionElement(node()) && toHTMLOptionElement(node())->selected(); 73 } 74 75 bool AXListBoxOption::isSelectedOptionActive() const 76 { 77 HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode(); 78 if (!listBoxParentNode) 79 return false; 80 81 return listBoxParentNode->activeSelectionEndListIndex() == listBoxOptionIndex(); 82 } 83 84 bool AXListBoxOption::computeAccessibilityIsIgnored() const 85 { 86 if (!node()) 87 return true; 88 89 if (accessibilityIsIgnoredByDefault()) 90 return true; 91 92 return false; 93 } 94 95 bool AXListBoxOption::canSetSelectedAttribute() const 96 { 97 if (!isHTMLOptionElement(node())) 98 return false; 99 100 if (toHTMLOptionElement(node())->isDisabledFormControl()) 101 return false; 102 103 HTMLSelectElement* selectElement = listBoxOptionParentNode(); 104 if (selectElement && selectElement->isDisabledFormControl()) 105 return false; 106 107 return true; 108 } 109 110 String AXListBoxOption::stringValue() const 111 { 112 if (!node()) 113 return String(); 114 115 const AtomicString& ariaLabel = getAttribute(aria_labelAttr); 116 if (!ariaLabel.isNull()) 117 return ariaLabel; 118 119 if (isHTMLOptionElement(node())) 120 return toHTMLOptionElement(node())->text(); 121 122 return String(); 123 } 124 125 void AXListBoxOption::setSelected(bool selected) 126 { 127 HTMLSelectElement* selectElement = listBoxOptionParentNode(); 128 if (!selectElement) 129 return; 130 131 if (!canSetSelectedAttribute()) 132 return; 133 134 bool isOptionSelected = isSelected(); 135 if ((isOptionSelected && selected) || (!isOptionSelected && !selected)) 136 return; 137 138 // Convert from the entire list index to the option index. 139 int optionIndex = selectElement->listToOptionIndex(listBoxOptionIndex()); 140 selectElement->accessKeySetSelectedIndex(optionIndex); 141 } 142 143 HTMLSelectElement* AXListBoxOption::listBoxOptionParentNode() const 144 { 145 if (!node()) 146 return 0; 147 148 if (isHTMLOptionElement(node())) 149 return toHTMLOptionElement(node())->ownerSelectElement(); 150 151 return 0; 152 } 153 154 int AXListBoxOption::listBoxOptionIndex() const 155 { 156 HTMLSelectElement* selectElement = listBoxOptionParentNode(); 157 if (!selectElement) 158 return -1; 159 160 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement->listItems(); 161 unsigned length = listItems.size(); 162 for (unsigned i = 0; i < length; i++) { 163 if (listItems[i] == node()) 164 return i; 165 } 166 167 return -1; 168 } 169 170 } // namespace blink 171