mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
270 lines
6.1 KiB
C++
270 lines
6.1 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
// NOTE: alphabetically ordered
|
|
|
|
#include "FormControlAccessible.h"
|
|
|
|
#include "mozilla/dom/HTMLInputElement.h"
|
|
#include "mozilla/FloatingPoint.h"
|
|
#include "Role.h"
|
|
|
|
using namespace mozilla::a11y;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ProgressMeterAccessible
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
template class mozilla::a11y::ProgressMeterAccessible<1>;
|
|
template class mozilla::a11y::ProgressMeterAccessible<100>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Accessible
|
|
|
|
template<int Max>
|
|
role
|
|
ProgressMeterAccessible<Max>::NativeRole() const
|
|
{
|
|
return roles::PROGRESSBAR;
|
|
}
|
|
|
|
template<int Max>
|
|
uint64_t
|
|
ProgressMeterAccessible<Max>::NativeState() const
|
|
{
|
|
uint64_t state = LeafAccessible::NativeState();
|
|
|
|
// An undetermined progressbar (i.e. without a value) has a mixed state.
|
|
nsAutoString attrValue;
|
|
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
|
|
|
|
if (attrValue.IsEmpty())
|
|
state |= states::MIXED;
|
|
|
|
return state;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ProgressMeterAccessible<Max>: Widgets
|
|
|
|
template<int Max>
|
|
bool
|
|
ProgressMeterAccessible<Max>::IsWidget() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ProgressMeterAccessible<Max>: Value
|
|
|
|
template<int Max>
|
|
void
|
|
ProgressMeterAccessible<Max>::Value(nsString& aValue) const
|
|
{
|
|
LeafAccessible::Value(aValue);
|
|
if (!aValue.IsEmpty())
|
|
return;
|
|
|
|
double maxValue = MaxValue();
|
|
if (IsNaN(maxValue) || maxValue == 0)
|
|
return;
|
|
|
|
double curValue = CurValue();
|
|
if (IsNaN(curValue))
|
|
return;
|
|
|
|
// Treat the current value bigger than maximum as 100%.
|
|
double percentValue = (curValue < maxValue) ?
|
|
(curValue / maxValue) * 100 : 100;
|
|
|
|
aValue.AppendFloat(percentValue);
|
|
aValue.Append('%');
|
|
}
|
|
|
|
template<int Max>
|
|
double
|
|
ProgressMeterAccessible<Max>::MaxValue() const
|
|
{
|
|
double value = LeafAccessible::MaxValue();
|
|
if (!IsNaN(value))
|
|
return value;
|
|
|
|
nsAutoString strValue;
|
|
if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) {
|
|
nsresult result = NS_OK;
|
|
value = strValue.ToDouble(&result);
|
|
if (NS_SUCCEEDED(result))
|
|
return value;
|
|
}
|
|
|
|
return Max;
|
|
}
|
|
|
|
template<int Max>
|
|
double
|
|
ProgressMeterAccessible<Max>::MinValue() const
|
|
{
|
|
double value = LeafAccessible::MinValue();
|
|
return IsNaN(value) ? 0 : value;
|
|
}
|
|
|
|
template<int Max>
|
|
double
|
|
ProgressMeterAccessible<Max>::Step() const
|
|
{
|
|
double value = LeafAccessible::Step();
|
|
return IsNaN(value) ? 0 : value;
|
|
}
|
|
|
|
template<int Max>
|
|
double
|
|
ProgressMeterAccessible<Max>::CurValue() const
|
|
{
|
|
double value = LeafAccessible::CurValue();
|
|
if (!IsNaN(value))
|
|
return value;
|
|
|
|
nsAutoString attrValue;
|
|
if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue))
|
|
return UnspecifiedNaN<double>();
|
|
|
|
nsresult error = NS_OK;
|
|
value = attrValue.ToDouble(&error);
|
|
return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
|
|
}
|
|
|
|
template<int Max>
|
|
bool
|
|
ProgressMeterAccessible<Max>::SetCurValue(double aValue)
|
|
{
|
|
return false; // progress meters are readonly.
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// CheckboxAccessible
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
role
|
|
CheckboxAccessible::NativeRole() const
|
|
{
|
|
return roles::CHECKBUTTON;
|
|
}
|
|
|
|
uint8_t
|
|
CheckboxAccessible::ActionCount() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
CheckboxAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
|
|
{
|
|
if (aIndex == eAction_Click) {
|
|
uint64_t state = NativeState();
|
|
if (state & states::CHECKED) {
|
|
aName.AssignLiteral("uncheck");
|
|
} else if (state & states::MIXED) {
|
|
aName.AssignLiteral("cycle");
|
|
} else {
|
|
aName.AssignLiteral("check");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool
|
|
CheckboxAccessible::DoAction(uint8_t aIndex) const
|
|
{
|
|
if (aIndex != eAction_Click) {
|
|
return false;
|
|
}
|
|
DoCommand();
|
|
return true;
|
|
}
|
|
|
|
uint64_t
|
|
CheckboxAccessible::NativeState() const
|
|
{
|
|
uint64_t state = LeafAccessible::NativeState();
|
|
|
|
state |= states::CHECKABLE;
|
|
dom::HTMLInputElement* input = dom::HTMLInputElement::FromNode(mContent);
|
|
if (input) { // HTML:input@type="checkbox"
|
|
if (input->Indeterminate()) {
|
|
return state | states::MIXED;
|
|
}
|
|
|
|
if (input->Checked()) {
|
|
return state | states::CHECKED;
|
|
}
|
|
|
|
} else if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
|
|
nsGkAtoms::checked,
|
|
nsGkAtoms::_true,
|
|
eCaseMatters)) { // XUL checkbox
|
|
return state | states::CHECKED;
|
|
}
|
|
|
|
return state;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// CheckboxAccessible: Widgets
|
|
|
|
bool
|
|
CheckboxAccessible::IsWidget() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// RadioButtonAccessible
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
RadioButtonAccessible::
|
|
RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
|
LeafAccessible(aContent, aDoc)
|
|
{
|
|
}
|
|
|
|
uint8_t
|
|
RadioButtonAccessible::ActionCount() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
RadioButtonAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
|
|
{
|
|
if (aIndex == eAction_Click)
|
|
aName.AssignLiteral("select");
|
|
}
|
|
|
|
bool
|
|
RadioButtonAccessible::DoAction(uint8_t aIndex) const
|
|
{
|
|
if (aIndex != eAction_Click)
|
|
return false;
|
|
|
|
DoCommand();
|
|
return true;
|
|
}
|
|
|
|
role
|
|
RadioButtonAccessible::NativeRole() const
|
|
{
|
|
return roles::RADIOBUTTON;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// RadioButtonAccessible: Widgets
|
|
|
|
bool
|
|
RadioButtonAccessible::IsWidget() const
|
|
{
|
|
return true;
|
|
}
|