accessible/generic/FormControlAccessible.cpp
author Xidorn Quan <me@upsuper.org>
Fri, 04 May 2018 13:44:51 +1000
changeset 417091 61084cd281886ca3bbf4c19842e5f8f92d801337
parent 412499 b148ee743b26bd3f19286ad69c6eedabc4867ee6
child 418198 6d057f79731365555281285f6a5441febc168e62
permissions -rw-r--r--
Bug 1454591 part 1 - Generate more structured data in ServoCSSPropList.py. r=heycam This patch changes ServoCSSPropList.py to use classes for properties. This allows extending the data in the file without needing to update all users of this file. Sorting in GenerateCSSPropsGenerated.py is removed because the data file has the right order already. MozReview-Commit-ID: D74bItCfpPH

/* -*- 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 "Role.h"

#include "mozilla/FloatingPoint.h"
#include "nsIDOMXULControlElement.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()
{
  return roles::PROGRESSBAR;
}

template<int Max>
uint64_t
ProgressMeterAccessible<Max>::NativeState()
{
  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)
{
  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.
}

////////////////////////////////////////////////////////////////////////////////
// RadioButtonAccessible
////////////////////////////////////////////////////////////////////////////////

RadioButtonAccessible::
  RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
  LeafAccessible(aContent, aDoc)
{
}

uint8_t
RadioButtonAccessible::ActionCount()
{
  return 1;
}

void
RadioButtonAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
{
  if (aIndex == eAction_Click)
    aName.AssignLiteral("select");
}

bool
RadioButtonAccessible::DoAction(uint8_t aIndex)
{
  if (aIndex != eAction_Click)
    return false;

  DoCommand();
  return true;
}

role
RadioButtonAccessible::NativeRole()
{
  return roles::RADIOBUTTON;
}

////////////////////////////////////////////////////////////////////////////////
// RadioButtonAccessible: Widgets

bool
RadioButtonAccessible::IsWidget() const
{
  return true;
}