michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // NOTE: alphabetically ordered michael@0: michael@0: #include "FormControlAccessible.h" michael@0: #include "Role.h" michael@0: michael@0: #include "mozilla/FloatingPoint.h" michael@0: #include "nsIDOMHTMLFormElement.h" michael@0: #include "nsIDOMXULElement.h" michael@0: #include "nsIDOMXULControlElement.h" michael@0: michael@0: using namespace mozilla::a11y; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // ProgressMeterAccessible michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: template class mozilla::a11y::ProgressMeterAccessible<1>; michael@0: template class mozilla::a11y::ProgressMeterAccessible<100>; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsISupports michael@0: michael@0: template michael@0: NS_IMPL_ADDREF_INHERITED(ProgressMeterAccessible, LeafAccessible) michael@0: michael@0: template michael@0: NS_IMPL_RELEASE_INHERITED(ProgressMeterAccessible, LeafAccessible) michael@0: michael@0: template michael@0: NS_IMPL_QUERY_INTERFACE_INHERITED(ProgressMeterAccessible, michael@0: LeafAccessible, michael@0: nsIAccessibleValue) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // Accessible michael@0: michael@0: template michael@0: role michael@0: ProgressMeterAccessible::NativeRole() michael@0: { michael@0: return roles::PROGRESSBAR; michael@0: } michael@0: michael@0: template michael@0: uint64_t michael@0: ProgressMeterAccessible::NativeState() michael@0: { michael@0: uint64_t state = LeafAccessible::NativeState(); michael@0: michael@0: // An undetermined progressbar (i.e. without a value) has a mixed state. michael@0: nsAutoString attrValue; michael@0: mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue); michael@0: michael@0: if (attrValue.IsEmpty()) michael@0: state |= states::MIXED; michael@0: michael@0: return state; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // ProgressMeterAccessible: Widgets michael@0: michael@0: template michael@0: bool michael@0: ProgressMeterAccessible::IsWidget() const michael@0: { michael@0: return true; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsIAccessibleValue michael@0: michael@0: template michael@0: void michael@0: ProgressMeterAccessible::Value(nsString& aValue) michael@0: { michael@0: LeafAccessible::Value(aValue); michael@0: if (!aValue.IsEmpty()) michael@0: return; michael@0: michael@0: double maxValue = MaxValue(); michael@0: if (IsNaN(maxValue) || maxValue == 0) michael@0: return; michael@0: michael@0: double curValue = CurValue(); michael@0: if (IsNaN(curValue)) michael@0: return; michael@0: michael@0: // Treat the current value bigger than maximum as 100%. michael@0: double percentValue = (curValue < maxValue) ? michael@0: (curValue / maxValue) * 100 : 100; michael@0: michael@0: aValue.AppendFloat(percentValue); michael@0: aValue.AppendLiteral("%"); michael@0: } michael@0: michael@0: template michael@0: double michael@0: ProgressMeterAccessible::MaxValue() const michael@0: { michael@0: double value = LeafAccessible::MaxValue(); michael@0: if (!IsNaN(value)) michael@0: return value; michael@0: michael@0: nsAutoString strValue; michael@0: if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) { michael@0: nsresult result = NS_OK; michael@0: value = strValue.ToDouble(&result); michael@0: if (NS_SUCCEEDED(result)) michael@0: return value; michael@0: } michael@0: michael@0: return Max; michael@0: } michael@0: michael@0: template michael@0: double michael@0: ProgressMeterAccessible::MinValue() const michael@0: { michael@0: double value = LeafAccessible::MinValue(); michael@0: return IsNaN(value) ? 0 : value; michael@0: } michael@0: michael@0: template michael@0: double michael@0: ProgressMeterAccessible::Step() const michael@0: { michael@0: double value = LeafAccessible::Step(); michael@0: return IsNaN(value) ? 0 : value; michael@0: } michael@0: michael@0: template michael@0: double michael@0: ProgressMeterAccessible::CurValue() const michael@0: { michael@0: double value = LeafAccessible::CurValue(); michael@0: if (!IsNaN(value)) michael@0: return value; michael@0: michael@0: nsAutoString attrValue; michael@0: if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue)) michael@0: return UnspecifiedNaN(); michael@0: michael@0: nsresult error = NS_OK; michael@0: value = attrValue.ToDouble(&error); michael@0: return NS_FAILED(error) ? UnspecifiedNaN() : value; michael@0: } michael@0: michael@0: template michael@0: bool michael@0: ProgressMeterAccessible::SetCurValue(double aValue) michael@0: { michael@0: return false; // progress meters are readonly. michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // RadioButtonAccessible michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: RadioButtonAccessible:: michael@0: RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) : michael@0: LeafAccessible(aContent, aDoc) michael@0: { michael@0: } michael@0: michael@0: uint8_t michael@0: RadioButtonAccessible::ActionCount() michael@0: { michael@0: return 1; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RadioButtonAccessible::GetActionName(uint8_t aIndex, nsAString& aName) michael@0: { michael@0: if (aIndex == eAction_Click) { michael@0: aName.AssignLiteral("select"); michael@0: return NS_OK; michael@0: } michael@0: return NS_ERROR_INVALID_ARG; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: RadioButtonAccessible::DoAction(uint8_t aIndex) michael@0: { michael@0: if (aIndex != eAction_Click) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: DoCommand(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: role michael@0: RadioButtonAccessible::NativeRole() michael@0: { michael@0: return roles::RADIOBUTTON; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // RadioButtonAccessible: Widgets michael@0: michael@0: bool michael@0: RadioButtonAccessible::IsWidget() const michael@0: { michael@0: return true; michael@0: }