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