AccessibilityListBoxOption.cpp [plain text]
#include "config.h"
#include "AccessibilityListBoxOption.h"
#include "AXObjectCache.h"
#include "AccessibilityListBox.h"
#include "Element.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "HTMLOptGroupElement.h"
#include "HTMLOptionElement.h"
#include "HTMLSelectElement.h"
#include "IntRect.h"
#include "RenderListBox.h"
#include "RenderObject.h"
namespace WebCore {
using namespace HTMLNames;
AccessibilityListBoxOption::AccessibilityListBoxOption()
: m_optionElement(nullptr)
{
}
AccessibilityListBoxOption::~AccessibilityListBoxOption()
{
}
Ref<AccessibilityListBoxOption> AccessibilityListBoxOption::create()
{
return adoptRef(*new AccessibilityListBoxOption());
}
bool AccessibilityListBoxOption::isEnabled() const
{
if (is<HTMLOptGroupElement>(m_optionElement))
return false;
if (equalLettersIgnoringASCIICase(getAttribute(aria_disabledAttr), "true"))
return false;
if (m_optionElement->hasAttributeWithoutSynchronization(disabledAttr))
return false;
return true;
}
bool AccessibilityListBoxOption::isSelected() const
{
if (!is<HTMLOptionElement>(m_optionElement))
return false;
return downcast<HTMLOptionElement>(*m_optionElement).selected();
}
bool AccessibilityListBoxOption::isSelectedOptionActive() const
{
HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
if (!listBoxParentNode)
return false;
return listBoxParentNode->activeSelectionEndListIndex() == listBoxOptionIndex();
}
LayoutRect AccessibilityListBoxOption::elementRect() const
{
LayoutRect rect;
if (!m_optionElement)
return rect;
HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode();
if (!listBoxParentNode)
return rect;
RenderElement* listBoxRenderer = listBoxParentNode->renderer();
if (!listBoxRenderer)
return rect;
LayoutRect parentRect = listBoxRenderer->document().axObjectCache()->getOrCreate(listBoxRenderer)->boundingBoxRect();
int index = listBoxOptionIndex();
if (index != -1)
rect = downcast<RenderListBox>(*listBoxRenderer).itemBoundingBoxRect(parentRect.location(), index);
return rect;
}
bool AccessibilityListBoxOption::computeAccessibilityIsIgnored() const
{
if (!m_optionElement)
return true;
if (accessibilityIsIgnoredByDefault())
return true;
return parentObject()->accessibilityIsIgnored();
}
bool AccessibilityListBoxOption::canSetSelectedAttribute() const
{
if (!is<HTMLOptionElement>(m_optionElement))
return false;
if (m_optionElement->isDisabledFormControl())
return false;
HTMLSelectElement* selectElement = listBoxOptionParentNode();
if (selectElement && selectElement->isDisabledFormControl())
return false;
return true;
}
String AccessibilityListBoxOption::stringValue() const
{
if (!m_optionElement)
return String();
const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
if (!ariaLabel.isNull())
return ariaLabel;
if (is<HTMLOptionElement>(*m_optionElement))
return downcast<HTMLOptionElement>(*m_optionElement).label();
if (is<HTMLOptGroupElement>(*m_optionElement))
return downcast<HTMLOptGroupElement>(*m_optionElement).groupLabelText();
return String();
}
Element* AccessibilityListBoxOption::actionElement() const
{
return m_optionElement;
}
AccessibilityObject* AccessibilityListBoxOption::parentObject() const
{
HTMLSelectElement* parentNode = listBoxOptionParentNode();
if (!parentNode)
return nullptr;
return m_optionElement->document().axObjectCache()->getOrCreate(parentNode);
}
void AccessibilityListBoxOption::setSelected(bool selected)
{
HTMLSelectElement* selectElement = listBoxOptionParentNode();
if (!selectElement)
return;
if (!canSetSelectedAttribute())
return;
bool isOptionSelected = isSelected();
if ((isOptionSelected && selected) || (!isOptionSelected && !selected))
return;
int optionIndex = selectElement->listToOptionIndex(listBoxOptionIndex());
selectElement->accessKeySetSelectedIndex(optionIndex);
}
HTMLSelectElement* AccessibilityListBoxOption::listBoxOptionParentNode() const
{
if (!m_optionElement)
return nullptr;
if (is<HTMLOptionElement>(*m_optionElement))
return downcast<HTMLOptionElement>(*m_optionElement).ownerSelectElement();
if (is<HTMLOptGroupElement>(*m_optionElement))
return downcast<HTMLOptGroupElement>(*m_optionElement).ownerSelectElement();
return nullptr;
}
int AccessibilityListBoxOption::listBoxOptionIndex() const
{
if (!m_optionElement)
return -1;
HTMLSelectElement* selectElement = listBoxOptionParentNode();
if (!selectElement)
return -1;
const auto& listItems = selectElement->listItems();
unsigned length = listItems.size();
for (unsigned i = 0; i < length; i++)
if (listItems[i] == m_optionElement)
return i;
return -1;
}
}