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: #include "XULSliderAccessible.h" michael@0: michael@0: #include "nsAccessibilityService.h" michael@0: #include "Role.h" michael@0: #include "States.h" michael@0: michael@0: #include "nsIFrame.h" michael@0: #include "mozilla/dom/Element.h" michael@0: #include "mozilla/FloatingPoint.h" michael@0: michael@0: using namespace mozilla::a11y; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // XULSliderAccessible michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: XULSliderAccessible:: michael@0: XULSliderAccessible(nsIContent* aContent, DocAccessible* aDoc) : michael@0: AccessibleWrap(aContent, aDoc) michael@0: { michael@0: mStateFlags |= eHasNumericValue; michael@0: } michael@0: michael@0: // Accessible michael@0: michael@0: role michael@0: XULSliderAccessible::NativeRole() michael@0: { michael@0: return roles::SLIDER; michael@0: } michael@0: michael@0: uint64_t michael@0: XULSliderAccessible::NativeInteractiveState() const michael@0: { michael@0: if (NativelyUnavailable()) michael@0: return states::UNAVAILABLE; michael@0: michael@0: nsIContent* sliderElm = GetSliderElement(); michael@0: if (sliderElm) { michael@0: nsIFrame* frame = sliderElm->GetPrimaryFrame(); michael@0: if (frame && frame->IsFocusable()) michael@0: return states::FOCUSABLE; michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: bool michael@0: XULSliderAccessible::NativelyUnavailable() const michael@0: { michael@0: return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled, michael@0: nsGkAtoms::_true, eCaseMatters); michael@0: } michael@0: michael@0: // nsIAccessible michael@0: michael@0: void michael@0: XULSliderAccessible::Value(nsString& aValue) michael@0: { michael@0: GetSliderAttr(nsGkAtoms::curpos, aValue); michael@0: } michael@0: michael@0: uint8_t michael@0: XULSliderAccessible::ActionCount() michael@0: { michael@0: return 1; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: XULSliderAccessible::GetActionName(uint8_t aIndex, nsAString& aName) michael@0: { michael@0: aName.Truncate(); michael@0: michael@0: NS_ENSURE_ARG(aIndex == 0); michael@0: michael@0: aName.AssignLiteral("activate"); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: XULSliderAccessible::DoAction(uint8_t aIndex) michael@0: { michael@0: NS_ENSURE_ARG(aIndex == 0); michael@0: michael@0: nsIContent* sliderElm = GetSliderElement(); michael@0: if (sliderElm) michael@0: DoCommand(sliderElm); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: double michael@0: XULSliderAccessible::MaxValue() const michael@0: { michael@0: double value = AccessibleWrap::MaxValue(); michael@0: return IsNaN(value) ? GetSliderAttr(nsGkAtoms::maxpos) : value; michael@0: } michael@0: michael@0: double michael@0: XULSliderAccessible::MinValue() const michael@0: { michael@0: double value = AccessibleWrap::MinValue(); michael@0: return IsNaN(value) ? GetSliderAttr(nsGkAtoms::minpos) : value; michael@0: } michael@0: michael@0: double michael@0: XULSliderAccessible::Step() const michael@0: { michael@0: double value = AccessibleWrap::Step(); michael@0: return IsNaN(value) ? GetSliderAttr(nsGkAtoms::increment) : value; michael@0: } michael@0: michael@0: double michael@0: XULSliderAccessible::CurValue() const michael@0: { michael@0: double value = AccessibleWrap::CurValue(); michael@0: return IsNaN(value) ? GetSliderAttr(nsGkAtoms::curpos) : value; michael@0: } michael@0: michael@0: bool michael@0: XULSliderAccessible::SetCurValue(double aValue) michael@0: { michael@0: if (AccessibleWrap::SetCurValue(aValue)) michael@0: return true; michael@0: michael@0: return SetSliderAttr(nsGkAtoms::curpos, aValue); michael@0: } michael@0: michael@0: bool michael@0: XULSliderAccessible::CanHaveAnonChildren() michael@0: { michael@0: // Do not allow anonymous xul:slider be accessible. michael@0: return false; michael@0: } michael@0: michael@0: // Utils michael@0: michael@0: nsIContent* michael@0: XULSliderAccessible::GetSliderElement() const michael@0: { michael@0: if (!mSliderNode) { michael@0: // XXX: we depend on anonymous content. michael@0: mSliderNode = mContent->OwnerDoc()-> michael@0: GetAnonymousElementByAttribute(mContent, nsGkAtoms::anonid, michael@0: NS_LITERAL_STRING("slider")); michael@0: } michael@0: michael@0: return mSliderNode; michael@0: } michael@0: michael@0: nsresult michael@0: XULSliderAccessible::GetSliderAttr(nsIAtom* aName, nsAString& aValue) const michael@0: { michael@0: aValue.Truncate(); michael@0: michael@0: if (IsDefunct()) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsIContent* sliderElm = GetSliderElement(); michael@0: if (sliderElm) michael@0: sliderElm->GetAttr(kNameSpaceID_None, aName, aValue); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: XULSliderAccessible::SetSliderAttr(nsIAtom* aName, const nsAString& aValue) michael@0: { michael@0: if (IsDefunct()) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsIContent* sliderElm = GetSliderElement(); michael@0: if (sliderElm) michael@0: sliderElm->SetAttr(kNameSpaceID_None, aName, aValue, true); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: double michael@0: XULSliderAccessible::GetSliderAttr(nsIAtom* aName) const michael@0: { michael@0: nsAutoString attrValue; michael@0: nsresult rv = GetSliderAttr(aName, attrValue); michael@0: if (NS_FAILED(rv)) michael@0: return UnspecifiedNaN(); michael@0: michael@0: nsresult error = NS_OK; michael@0: double value = attrValue.ToDouble(&error); michael@0: return NS_FAILED(error) ? UnspecifiedNaN() : value; michael@0: } michael@0: michael@0: bool michael@0: XULSliderAccessible::SetSliderAttr(nsIAtom* aName, double aValue) michael@0: { michael@0: nsAutoString value; michael@0: value.AppendFloat(aValue); michael@0: michael@0: return NS_SUCCEEDED(SetSliderAttr(aName, value)); michael@0: } michael@0: michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // XULThumbAccessible michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: XULThumbAccessible:: michael@0: XULThumbAccessible(nsIContent* aContent, DocAccessible* aDoc) : michael@0: AccessibleWrap(aContent, aDoc) michael@0: { michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // XULThumbAccessible: Accessible michael@0: michael@0: role michael@0: XULThumbAccessible::NativeRole() michael@0: { michael@0: return roles::INDICATOR; michael@0: } michael@0: