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