Home | History | Annotate | Download | only in accessibility
      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/AccessibilityListBoxOption.h"
     31 
     32 #include "core/accessibility/AXObjectCache.h"
     33 #include "core/html/HTMLOptGroupElement.h"
     34 #include "core/html/HTMLOptionElement.h"
     35 #include "core/html/HTMLSelectElement.h"
     36 #include "core/rendering/RenderListBox.h"
     37 
     38 using namespace std;
     39 
     40 namespace WebCore {
     41 
     42 using namespace HTMLNames;
     43 
     44 AccessibilityListBoxOption::AccessibilityListBoxOption()
     45     : m_optionElement(0)
     46 {
     47 }
     48 
     49 AccessibilityListBoxOption::~AccessibilityListBoxOption()
     50 {
     51 }
     52 
     53 PassRefPtr<AccessibilityListBoxOption> AccessibilityListBoxOption::create()
     54 {
     55     return adoptRef(new AccessibilityListBoxOption());
     56 }
     57 
     58 bool AccessibilityListBoxOption::isEnabled() const
     59 {
     60     if (!m_optionElement)
     61         return false;
     62 
     63     if (isHTMLOptGroupElement(m_optionElement))
     64         return false;
     65 
     66     if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))
     67         return false;
     68 
     69     if (m_optionElement->hasAttribute(disabledAttr))
     70         return false;
     71 
     72     return true;
     73 }
     74 
     75 bool AccessibilityListBoxOption::isSelected() const
     76 {
     77     if (!m_optionElement)
     78         return false;
     79 
     80     if (!m_optionElement->hasTagName(optionTag))
     81         return false;
     82 
     83     return toHTMLOptionElement(m_optionElement)->selected();
     84 }
     85 
     86 bool AccessibilityListBoxOption::isSelectedOptionActive() const
     87 {
     88     HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
     89     if (!listBoxParentNode)
     90         return false;
     91 
     92     return listBoxParentNode->activeSelectionEndListIndex() == listBoxOptionIndex();
     93 }
     94 
     95 LayoutRect AccessibilityListBoxOption::elementRect() const
     96 {
     97     LayoutRect rect;
     98     if (!m_optionElement)
     99         return rect;
    100 
    101     HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
    102     if (!listBoxParentNode)
    103         return rect;
    104 
    105     RenderObject* listBoxRenderer = listBoxParentNode->renderer();
    106     if (!listBoxRenderer)
    107         return rect;
    108 
    109     LayoutRect parentRect = listBoxRenderer->document()->axObjectCache()->getOrCreate(listBoxRenderer)->elementRect();
    110     int index = listBoxOptionIndex();
    111     if (index != -1)
    112         rect = toRenderListBox(listBoxRenderer)->itemBoundingBoxRect(parentRect.location(), index);
    113 
    114     return rect;
    115 }
    116 
    117 bool AccessibilityListBoxOption::computeAccessibilityIsIgnored() const
    118 {
    119     if (!m_optionElement)
    120         return true;
    121 
    122     if (accessibilityIsIgnoredByDefault())
    123         return true;
    124 
    125     return parentObject()->accessibilityIsIgnored();
    126 }
    127 
    128 bool AccessibilityListBoxOption::canSetSelectedAttribute() const
    129 {
    130     if (!m_optionElement)
    131         return false;
    132 
    133     if (!m_optionElement->hasTagName(optionTag))
    134         return false;
    135 
    136     if (m_optionElement->isDisabledFormControl())
    137         return false;
    138 
    139     HTMLSelectElement* selectElement = listBoxOptionParentNode();
    140     if (selectElement && selectElement->isDisabledFormControl())
    141         return false;
    142 
    143     return true;
    144 }
    145 
    146 String AccessibilityListBoxOption::stringValue() const
    147 {
    148     if (!m_optionElement)
    149         return String();
    150 
    151     const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
    152     if (!ariaLabel.isNull())
    153         return ariaLabel;
    154 
    155     if (m_optionElement->hasTagName(optionTag))
    156         return toHTMLOptionElement(m_optionElement)->text();
    157 
    158     if (isHTMLOptGroupElement(m_optionElement))
    159         return toHTMLOptGroupElement(m_optionElement)->groupLabelText();
    160 
    161     return String();
    162 }
    163 
    164 Element* AccessibilityListBoxOption::actionElement() const
    165 {
    166     return m_optionElement;
    167 }
    168 
    169 AccessibilityObject* AccessibilityListBoxOption::parentObject() const
    170 {
    171     HTMLSelectElement* parentNode = listBoxOptionParentNode();
    172     if (!parentNode)
    173         return 0;
    174 
    175     return m_optionElement->document()->axObjectCache()->getOrCreate(parentNode);
    176 }
    177 
    178 void AccessibilityListBoxOption::setSelected(bool selected)
    179 {
    180     HTMLSelectElement* selectElement = listBoxOptionParentNode();
    181     if (!selectElement)
    182         return;
    183 
    184     if (!canSetSelectedAttribute())
    185         return;
    186 
    187     bool isOptionSelected = isSelected();
    188     if ((isOptionSelected && selected) || (!isOptionSelected && !selected))
    189         return;
    190 
    191     // Convert from the entire list index to the option index.
    192     int optionIndex = selectElement->listToOptionIndex(listBoxOptionIndex());
    193     selectElement->accessKeySetSelectedIndex(optionIndex);
    194 }
    195 
    196 HTMLSelectElement* AccessibilityListBoxOption::listBoxOptionParentNode() const
    197 {
    198     if (!m_optionElement)
    199         return 0;
    200 
    201     if (m_optionElement->hasTagName(optionTag))
    202         return toHTMLOptionElement(m_optionElement)->ownerSelectElement();
    203 
    204     if (isHTMLOptGroupElement(m_optionElement))
    205         return toHTMLOptGroupElement(m_optionElement)->ownerSelectElement();
    206 
    207     return 0;
    208 }
    209 
    210 int AccessibilityListBoxOption::listBoxOptionIndex() const
    211 {
    212     if (!m_optionElement)
    213         return -1;
    214 
    215     HTMLSelectElement* selectElement = listBoxOptionParentNode();
    216     if (!selectElement)
    217         return -1;
    218 
    219     const Vector<HTMLElement*>& listItems = selectElement->listItems();
    220     unsigned length = listItems.size();
    221     for (unsigned i = 0; i < length; i++)
    222         if (listItems[i] == m_optionElement)
    223             return i;
    224 
    225     return -1;
    226 }
    227 
    228 } // namespace WebCore
    229