Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/accessible/base/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 37 kB image not shown  

Quelle  ARIAMap.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=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 "ARIAMap.h"

#include "AccAttributes.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "mozilla/a11y/Role.h"
#include "States.h"

#include "nsAttrName.h"
#include "nsWhitespaceTokenizer.h"

#include "mozilla/BinarySearch.h"
#include "mozilla/dom/Element.h"

#include "nsUnicharUtils.h"

using namespace mozilla;
using namespace mozilla::a11y;
using namespace mozilla::a11y::aria;

static const uint32_t kGenericAccType = 0;

/**
 *  This list of WAI-defined roles are currently hardcoded.
 *  Eventually we will most likely be loading an RDF resource that contains this
 * information Using RDF will also allow for role extensibility. See bug 280138.
 *
 *  Definition of nsRoleMapEntry contains comments explaining this table.
 *
 *  When no Role enum mapping exists for an ARIA role, the role will be exposed
 *  via the object attribute "xml-roles".
 *
 * Note: the list must remain alphabetically ordered to support binary search.
 */


static const nsRoleMapEntry sWAIRoleMaps[] = {
    // clang-format off
  { // alert
    nsGkAtoms::alert,
    roles::ALERT,
    kUseMapRole,
    eNoValue,
    eNoAction,
#if defined(XP_MACOSX)
    eAssertiveLiveAttr,
#else
    eNoLiveAttr,
#endif
    eAlert,
    kNoReqStates
  },
  { // alertdialog
    nsGkAtoms::alertdialog,
    roles::DIALOG,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // application
    nsGkAtoms::application,
    roles::APPLICATION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // article
    nsGkAtoms::article,
    roles::ARTICLE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eReadonlyUntilEditable
  },
  { // banner
    nsGkAtoms::banner,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // blockquote
    nsGkAtoms::blockquote,
    roles::BLOCKQUOTE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // button
    nsGkAtoms::button,
    roles::PUSHBUTTON,
    kUseMapRole,
    eNoValue,
    ePressAction,
    eNoLiveAttr,
    eButton,
    kNoReqStates
    // eARIAPressed is auto applied on any button
  },
  { // caption
    nsGkAtoms::caption,
    roles::CAPTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // cell
    nsGkAtoms::cell,
    roles::CELL,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eTableCell,
    kNoReqStates
  },
  { // checkbox
    nsGkAtoms::checkbox,
    roles::CHECKBUTTON,
    kUseMapRole,
    eNoValue,
    eCheckUncheckAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIACheckableMixed,
    eARIAReadonly
  },
  { // code
    nsGkAtoms::code,
    roles::CODE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // columnheader
    nsGkAtoms::columnheader,
    roles::COLUMNHEADER,
    kUseMapRole,
    eNoValue,
    eSortAction,
    eNoLiveAttr,
    eTableCell,
    kNoReqStates,
    eARIASelectableIfDefined,
    eARIAReadonly
  },
  { // combobox, which consists of text input and popup
    nsGkAtoms::combobox,
    roles::EDITCOMBOBOX,
    kUseMapRole,
    eNoValue,
    eOpenCloseAction,
    eNoLiveAttr,
    eCombobox,
    states::COLLAPSED | states::HASPOPUP,
    eARIAAutoComplete,
    eARIAReadonly,
    eARIAOrientation
  },
  { // comment
    nsGkAtoms::comment,
    roles::COMMENT,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // complementary
    nsGkAtoms::complementary,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // contentinfo
    nsGkAtoms::contentinfo,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // definition
    nsGkAtoms::definition,
    roles::DEFINITION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // deletion
    nsGkAtoms::deletion,
    roles::CONTENT_DELETION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // dialog
    nsGkAtoms::dialog,
    roles::DIALOG,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // directory
    nsGkAtoms::directory,
    roles::LIST,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eList,
    states::READONLY
  },
  { // doc-abstract
    nsGkAtoms::docAbstract,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-acknowledgments
    nsGkAtoms::docAcknowledgments,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // doc-afterword
    nsGkAtoms::docAfterword,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // doc-appendix
    nsGkAtoms::docAppendix,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-backlink
    nsGkAtoms::docBacklink,
    roles::LINK,
    kUseMapRole,
    eNoValue,
    eJumpAction,
    eNoLiveAttr,
    eDPub,
    states::LINKED
  },
  { // doc-biblioentry
    nsGkAtoms::docBiblioentry,
    roles::LISTITEM,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    states::READONLY
  },
  { // doc-bibliography
    nsGkAtoms::docBibliography,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-biblioref
    nsGkAtoms::docBiblioref,
    roles::LINK,
    kUseMapRole,
    eNoValue,
    eJumpAction,
    eNoLiveAttr,
    eDPub,
    states::LINKED
  },
  { // doc-chapter
    nsGkAtoms::docChapter,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-colophon
    nsGkAtoms::docColophon,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-conclusion
    nsGkAtoms::docConclusion,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-cover
    nsGkAtoms::docCover,
    roles::GRAPHIC,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-credit
    nsGkAtoms::docCredit,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-credits
    nsGkAtoms::docCredits,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-dedication
    nsGkAtoms::docDedication,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-endnote
    nsGkAtoms::docEndnote,
    roles::LISTITEM,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    states::READONLY
  },
  { // doc-endnotes
    nsGkAtoms::docEndnotes,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-epigraph
    nsGkAtoms::docEpigraph,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-epilogue
    nsGkAtoms::docEpilogue,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-errata
    nsGkAtoms::docErrata,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-example
    nsGkAtoms::docExample,
    roles::FIGURE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-footnote
    nsGkAtoms::docFootnote,
    roles::FOOTNOTE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-foreword
    nsGkAtoms::docForeword,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-glossary
    nsGkAtoms::docGlossary,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-glossref
    nsGkAtoms::docGlossref,
    roles::LINK,
    kUseMapRole,
    eNoValue,
    eJumpAction,
    eNoLiveAttr,
    eDPub,
    states::LINKED
  },
  { // doc-index
    nsGkAtoms::docIndex,
    roles::NAVIGATION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-introduction
    nsGkAtoms::docIntroduction,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-noteref
    nsGkAtoms::docNoteref,
    roles::LINK,
    kUseMapRole,
    eNoValue,
    eJumpAction,
    eNoLiveAttr,
    eDPub,
    states::LINKED
  },
  { // doc-notice
    nsGkAtoms::docNotice,
    roles::NOTE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-pagebreak
    nsGkAtoms::docPagebreak,
    roles::SEPARATOR,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-pagefooter
    nsGkAtoms::docPagefooter,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-pageheader
    nsGkAtoms::docPageheader,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-pagelist
    nsGkAtoms::docPagelist,
    roles::NAVIGATION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-part
    nsGkAtoms::docPart,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-preface
    nsGkAtoms::docPreface,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-prologue
    nsGkAtoms::docPrologue,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // doc-pullquote
    nsGkAtoms::docPullquote,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-qna
    nsGkAtoms::docQna,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-subtitle
    nsGkAtoms::docSubtitle,
    roles::HEADING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-tip
    nsGkAtoms::docTip,
    roles::NOTE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub,
    kNoReqStates
  },
  { // doc-toc
    nsGkAtoms::docToc,
    roles::NAVIGATION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eDPub | eLandmark,
    kNoReqStates
  },
  { // document
    nsGkAtoms::document,
    roles::NON_NATIVE_DOCUMENT,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eReadonlyUntilEditable
  },
  { // emphasis
    nsGkAtoms::emphasis,
    roles::EMPHASIS,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // feed
    nsGkAtoms::feed,
    roles::GROUPING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // figure
    nsGkAtoms::figure,
    roles::FIGURE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // form
    nsGkAtoms::form,
    roles::FORM,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // generic
    nsGkAtoms::generic,
    roles::SECTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // graphics-document
    nsGkAtoms::graphicsDocument,
    roles::NON_NATIVE_DOCUMENT,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eReadonlyUntilEditable
  },
  { // graphics-object
    nsGkAtoms::graphicsObject,
    roles::GROUPING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // graphics-symbol
    nsGkAtoms::graphicsSymbol,
    roles::GRAPHIC,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // grid
    nsGkAtoms::grid,
    roles::GRID,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eSelect | eTable,
    kNoReqStates,
    eARIAMultiSelectable,
    eARIAReadonly,
    eFocusableUntilDisabled
  },
  { // gridcell
    nsGkAtoms::gridcell,
    roles::GRID_CELL,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eTableCell,
    kNoReqStates,
    eARIASelectable,
    eARIAReadonly
  },
  { // group
    nsGkAtoms::group,
    roles::GROUPING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // heading
    nsGkAtoms::heading,
    roles::HEADING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // image
    nsGkAtoms::image,
    roles::GRAPHIC,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // img
    nsGkAtoms::img,
    roles::GRAPHIC,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // insertion
    nsGkAtoms::insertion,
    roles::CONTENT_INSERTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // key
    nsGkAtoms::key,
    roles::KEY,
    kUseMapRole,
    eNoValue,
    ePressAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIAPressed
  },
  { // link
    nsGkAtoms::link,
    roles::LINK,
    kUseMapRole,
    eNoValue,
    eJumpAction,
    eNoLiveAttr,
    kGenericAccType,
    states::LINKED
  },
  { // list
    nsGkAtoms::list_,
    roles::LIST,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eList,
    states::READONLY
  },
  { // listbox
    nsGkAtoms::listbox,
    roles::LISTBOX,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eListControl | eSelect,
    states::VERTICAL,
    eARIAMultiSelectable,
    eARIAReadonly,
    eFocusableUntilDisabled,
    eARIAOrientation
  },
  { // listitem
    nsGkAtoms::listitem,
    roles::LISTITEM,
    kUseMapRole,
    eNoValue,
    eNoAction, // XXX: should depend on state, parent accessible
    eNoLiveAttr,
    kGenericAccType,
    states::READONLY
  },
  { // log
    nsGkAtoms::log_,
    roles::NOTHING,
    kUseNativeRole,
    eNoValue,
    eNoAction,
    ePoliteLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // main
    nsGkAtoms::main,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // mark
    nsGkAtoms::mark,
    roles::MARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // marquee
    nsGkAtoms::marquee,
    roles::ANIMATION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eOffLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // math
    nsGkAtoms::math,
    roles::FLAT_EQUATION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // menu
    nsGkAtoms::menu,
    roles::MENUPOPUP,
    kUseMapRole,
    eNoValue,
    eNoAction, // XXX: technically accessibles of menupopup role haven't
               // any action, but menu can be open or close.
    eNoLiveAttr,
    kGenericAccType,
    states::VERTICAL,
    eARIAOrientation
  },
  { // menubar
    nsGkAtoms::menubar,
    roles::MENUBAR,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::HORIZONTAL,
    eARIAOrientation
  },
  { // menuitem
    nsGkAtoms::menuitem,
    roles::MENUITEM,
    kUseMapRole,
    eNoValue,
    eClickAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // menuitemcheckbox
    nsGkAtoms::menuitemcheckbox,
    roles::CHECK_MENU_ITEM,
    kUseMapRole,
    eNoValue,
    eClickAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIACheckableMixed,
    eARIAReadonly
  },
  { // menuitemradio
    nsGkAtoms::menuitemradio,
    roles::RADIO_MENU_ITEM,
    kUseMapRole,
    eNoValue,
    eClickAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIACheckableBool,
    eARIAReadonly
  },
  { // meter
    nsGkAtoms::meter,
    roles::METER,
    kUseMapRole,
    eHasValueMinMax,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::READONLY
  },
  { // navigation
    nsGkAtoms::navigation,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // none
    nsGkAtoms::none,
    roles::NOTHING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // note
    nsGkAtoms::note_,
    roles::NOTE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // option
    nsGkAtoms::option,
    roles::OPTION,
    kUseMapRole,
    eNoValue,
    eSelectAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIASelectable,
    eARIACheckedMixed
  },
  { // paragraph
    nsGkAtoms::paragraph,
    roles::PARAGRAPH,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // presentation
    nsGkAtoms::presentation,
    roles::NOTHING,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // progressbar
    nsGkAtoms::progressbar,
    roles::PROGRESSBAR,
    kUseMapRole,
    eHasValueMinMax,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::READONLY,
    eIndeterminateIfNoValue
  },
  { // radio
    nsGkAtoms::radio,
    roles::RADIOBUTTON,
    kUseMapRole,
    eNoValue,
    eSelectAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIACheckableBool
  },
  { // radiogroup
    nsGkAtoms::radiogroup,
    roles::RADIO_GROUP,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIAOrientation,
    eARIAReadonly
  },
  { // region
    nsGkAtoms::region,
    roles::REGION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // row
    nsGkAtoms::row,
    roles::ROW,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eTableRow,
    kNoReqStates,
    eARIASelectable
  },
  { // rowgroup
    nsGkAtoms::rowgroup,
    roles::ROWGROUP,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // rowheader
    nsGkAtoms::rowheader,
    roles::ROWHEADER,
    kUseMapRole,
    eNoValue,
    eSortAction,
    eNoLiveAttr,
    eTableCell,
    kNoReqStates,
    eARIASelectableIfDefined,
    eARIAReadonly
  },
  { // scrollbar
    nsGkAtoms::scrollbar,
    roles::SCROLLBAR,
    kUseMapRole,
    eHasValueMinMax,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::VERTICAL,
    eARIAOrientation,
    eARIAReadonly
  },
  { // search
    nsGkAtoms::search,
    roles::LANDMARK,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eLandmark,
    kNoReqStates
  },
  { // searchbox
    nsGkAtoms::searchbox,
    roles::ENTRY,
    kUseMapRole,
    eNoValue,
    eActivateAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIAAutoComplete,
    eARIAMultiline,
    eARIAReadonlyOrEditable
  },
  { // separator
    nsGkAtoms::separator_,
    roles::SEPARATOR,
    kUseMapRole,
    eHasValueMinMaxIfFocusable,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::HORIZONTAL,
    eARIAOrientation
  },
  { // slider
    nsGkAtoms::slider,
    roles::SLIDER,
    kUseMapRole,
    eHasValueMinMax,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::HORIZONTAL,
    eARIAOrientation,
    eARIAReadonly
  },
  { // spinbutton
    nsGkAtoms::spinbutton,
    roles::SPINBUTTON,
    kUseMapRole,
    eHasValueMinMax,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIAReadonly
  },
  { // status
    nsGkAtoms::status,
    roles::STATUSBAR,
    kUseMapRole,
    eNoValue,
    eNoAction,
    ePoliteLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // strong
    nsGkAtoms::strong,
    roles::STRONG,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // subscript
    nsGkAtoms::subscript,
    roles::SUBSCRIPT,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType
  },
  { // suggestion
    nsGkAtoms::suggestion,
    roles::SUGGESTION,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
  },
  { // superscript
    nsGkAtoms::superscript,
    roles::SUPERSCRIPT,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType
  },
  { // switch
    nsGkAtoms::svgSwitch,
    roles::SWITCH,
    kUseMapRole,
    eNoValue,
    eCheckUncheckAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIACheckableBool,
    eARIAReadonly
  },
  { // tab
    nsGkAtoms::tab,
    roles::PAGETAB,
    kUseMapRole,
    eNoValue,
    eSwitchAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIASelectable
  },
  { // table
    nsGkAtoms::table,
    roles::TABLE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eTable,
    kNoReqStates,
    eARIASelectable
  },
  { // tablist
    nsGkAtoms::tablist,
    roles::PAGETABLIST,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eSelect,
    states::HORIZONTAL,
    eARIAOrientation,
    eARIAMultiSelectable
  },
  { // tabpanel
    nsGkAtoms::tabpanel,
    roles::PROPERTYPAGE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // term
    nsGkAtoms::term,
    roles::TERM,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::READONLY
  },
  { // textbox
    nsGkAtoms::textbox,
    roles::ENTRY,
    kUseMapRole,
    eNoValue,
    eActivateAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIAAutoComplete,
    eARIAMultiline,
    eARIAReadonlyOrEditable
  },
  { // time
    nsGkAtoms::time,
    roles::TIME,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kNoReqStates
  },
  { // timer
    nsGkAtoms::timer,
    roles::NOTHING,
    kUseNativeRole,
    eNoValue,
    eNoAction,
    eOffLiveAttr,
    kNoReqStates
  },
  { // toolbar
    nsGkAtoms::toolbar,
    roles::TOOLBAR,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    states::HORIZONTAL,
    eARIAOrientation
  },
  { // tooltip
    nsGkAtoms::tooltip,
    roles::TOOLTIP,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates
  },
  { // tree
    nsGkAtoms::tree,
    roles::OUTLINE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eSelect,
    states::VERTICAL,
    eARIAReadonly,
    eARIAMultiSelectable,
    eFocusableUntilDisabled,
    eARIAOrientation
  },
  { // treegrid
    nsGkAtoms::treegrid,
    roles::TREE_TABLE,
    kUseMapRole,
    eNoValue,
    eNoAction,
    eNoLiveAttr,
    eSelect | eTable,
    kNoReqStates,
    eARIAReadonly,
    eARIAMultiSelectable,
    eFocusableUntilDisabled,
    eARIAOrientation
  },
  { // treeitem
    nsGkAtoms::treeitem,
    roles::OUTLINEITEM,
    kUseMapRole,
    eNoValue,
    eActivateAction, // XXX: should expose second 'expand/collapse' action based
                     // on states
    eNoLiveAttr,
    kGenericAccType,
    kNoReqStates,
    eARIASelectable,
    eARIACheckedMixed
  }
    // clang-format on
};

static const nsRoleMapEntry sLandmarkRoleMap = {
    nsGkAtoms::_empty, roles::NOTHING, kUseNativeRole,  eNoValue,
    eNoAction,         eNoLiveAttr,    kGenericAccType, kNoReqStates};

nsRoleMapEntry aria::gEmptyRoleMap = {
    nsGkAtoms::_empty, roles::TEXT_CONTAINER, kUseMapRole,     eNoValue,
    eNoAction,         eNoLiveAttr,           kGenericAccType, kNoReqStates};

/**
 * Universal (Global) states:
 * The following state rules are applied to any accessible element,
 * whether there is an ARIA role or not:
 */

static const EStateRule sWAIUnivStateMap[] = {
    eARIABusy,     eARIACurrent, eARIADisabled,
    eARIAExpanded,  // Currently under spec review but precedent exists
    eARIAHasPopup,  // Note this is a tokenised attribute starting in ARIA 1.1
    eARIAInvalid,  eARIAModal,
    eARIARequired,  // XXX not global, Bug 553117
    eARIANone};

/**
 * ARIA attribute map for attribute characteristics.
 * @note ARIA attributes that don't have any flags are not included here.
 */


struct AttrCharacteristics {
  const nsStaticAtom* const attributeName;
  const uint8_t characteristics;
};

static const AttrCharacteristics gWAIUnivAttrMap[] = {
    // clang-format off
  {nsGkAtoms::aria_activedescendant,  ATTR_BYPASSOBJ                               },
  {nsGkAtoms::aria_atomic,   ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_busy,                               ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_checked,           ATTR_BYPASSOBJ | ATTR_VALTOKEN               }, /* exposes checkable obj attr */
  {nsGkAtoms::aria_colcount,          ATTR_VALINT                                  },
  {nsGkAtoms::aria_colindex,          ATTR_VALINT                                  },
  {nsGkAtoms::aria_controls,          ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  {nsGkAtoms::aria_current,  ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_describedby,       ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  // XXX Ideally, aria-description shouldn't expose a description object
  // attribute (i.e. it should have ATTR_BYPASSOBJ). However, until the
  // description-from attribute is implemented (bug 1726087), clients such as
  // NVDA depend on the description object attribute to work out whether the
  // accDescription originated from aria-description.
  {nsGkAtoms::aria_description,                                        ATTR_GLOBAL },
  {nsGkAtoms::aria_details,           ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  {nsGkAtoms::aria_disabled,          ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_dropeffect,                         ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_errormessage,      ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  {nsGkAtoms::aria_expanded,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_flowto,            ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  {nsGkAtoms::aria_grabbed,                            ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_haspopup,          ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_hidden,            ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */
  {nsGkAtoms::aria_invalid,           ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_label,             ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
  {nsGkAtoms::aria_labelledby,        ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  {nsGkAtoms::aria_level,             ATTR_BYPASSOBJ                               }, /* handled via groupPosition */
  {nsGkAtoms::aria_live,                               ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_modal,             ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
  {nsGkAtoms::aria_multiline,         ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_multiselectable,   ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_owns,              ATTR_BYPASSOBJ                 | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
  {nsGkAtoms::aria_orientation,                        ATTR_VALTOKEN               },
  {nsGkAtoms::aria_posinset,          ATTR_BYPASSOBJ                               }, /* handled via groupPosition */
  {nsGkAtoms::aria_pressed,           ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_readonly,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_relevant,          ATTR_GLOBAL                                  },
  {nsGkAtoms::aria_required,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_rowcount,          ATTR_VALINT                                  },
  {nsGkAtoms::aria_rowindex,          ATTR_VALINT                                  },
  {nsGkAtoms::aria_selected,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
  {nsGkAtoms::aria_setsize,           ATTR_BYPASSOBJ                               }, /* handled via groupPosition */
  {nsGkAtoms::aria_sort,                               ATTR_VALTOKEN               },
  {nsGkAtoms::aria_valuenow,          ATTR_BYPASSOBJ                               },
  {nsGkAtoms::aria_valuemin,          ATTR_BYPASSOBJ                               },
  {nsGkAtoms::aria_valuemax,          ATTR_BYPASSOBJ                               },
  {nsGkAtoms::aria_valuetext,         ATTR_BYPASSOBJ                               }
    // clang-format on
};

const nsRoleMapEntry* aria::GetRoleMap(dom::Element* aEl) {
  return GetRoleMapFromIndex(GetRoleMapIndex(aEl));
}

uint8_t aria::GetFirstValidRoleMapIndexExcluding(
    dom::Element* aEl, std::initializer_list<nsStaticAtom*> aRolesToSkip) {
  nsAutoString roles;
  if (!aEl || !nsAccUtils::GetARIAAttr(aEl, nsGkAtoms::role, roles) ||
      roles.IsEmpty()) {
    // We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
    return NO_ROLE_MAP_ENTRY_INDEX;
  }

  nsWhitespaceTokenizer tokenizer(roles);
  while (tokenizer.hasMoreTokens()) {
    // Do a binary search through table for the next role in role list
    const nsDependentSubstring role = tokenizer.nextToken();

    // Skip any roles that we aren't interested in.
    bool shouldSkip = false;
    for (nsStaticAtom* atomRole : aRolesToSkip) {
      if (role.Equals(atomRole->GetUTF16String())) {
        shouldSkip = true;
        break;
      }
    }
    if (shouldSkip) {
      continue;
    }

    size_t idx;
    auto comparator = [&role](const nsRoleMapEntry& aEntry) {
      return Compare(role, aEntry.ARIARoleString(),
                     nsCaseInsensitiveStringComparator);
    };
    if (BinarySearchIf(sWAIRoleMaps, 0, std::size(sWAIRoleMaps), comparator,
                       &idx)) {
      return idx;
    }
  }

  // Always use some entry index if there is a non-empty role string
  // To ensure an accessible object is created
  return LANDMARK_ROLE_MAP_ENTRY_INDEX;
}

uint8_t aria::GetRoleMapIndex(dom::Element* aEl) {
  // Get the rolemap index of the first valid role, excluding nothing.
  return GetFirstValidRoleMapIndexExcluding(aEl, {});
}

const nsRoleMapEntry* aria::GetRoleMapFromIndex(uint8_t aRoleMapIndex) {
  switch (aRoleMapIndex) {
    case NO_ROLE_MAP_ENTRY_INDEX:
      return nullptr;
    case EMPTY_ROLE_MAP_ENTRY_INDEX:
      return &gEmptyRoleMap;
    case LANDMARK_ROLE_MAP_ENTRY_INDEX:
      return &sLandmarkRoleMap;
    default:
      return sWAIRoleMaps + aRoleMapIndex;
  }
}

uint8_t aria::GetIndexFromRoleMap(const nsRoleMapEntry* aRoleMapEntry) {
  if (aRoleMapEntry == nullptr) {
    return NO_ROLE_MAP_ENTRY_INDEX;
  } else if (aRoleMapEntry == &gEmptyRoleMap) {
    return EMPTY_ROLE_MAP_ENTRY_INDEX;
  } else if (aRoleMapEntry == &sLandmarkRoleMap) {
    return LANDMARK_ROLE_MAP_ENTRY_INDEX;
  } else {
    uint8_t index = aRoleMapEntry - sWAIRoleMaps;
    MOZ_ASSERT(aria::IsRoleMapIndexValid(index));
    return index;
  }
}

bool aria::IsRoleMapIndexValid(uint8_t aRoleMapIndex) {
  switch (aRoleMapIndex) {
    case NO_ROLE_MAP_ENTRY_INDEX:
    case EMPTY_ROLE_MAP_ENTRY_INDEX:
    case LANDMARK_ROLE_MAP_ENTRY_INDEX:
      return true;
  }
  return aRoleMapIndex < std::size(sWAIRoleMaps);
}

uint64_t aria::UniversalStatesFor(mozilla::dom::Element* aElement) {
  uint64_t state = 0;
  uint32_t index = 0;
  while (MapToState(sWAIUnivStateMap[index], aElement, &state)) index++;

  return state;
}

uint8_t aria::AttrCharacteristicsFor(nsAtom* aAtom) {
  for (uint32_t i = 0; i < std::size(gWAIUnivAttrMap); i++) {
    if (gWAIUnivAttrMap[i].attributeName == aAtom) {
      return gWAIUnivAttrMap[i].characteristics;
    }
  }

  return 0;
}

bool aria::HasDefinedARIAHidden(nsIContent* aContent) {
  return aContent && aContent->IsElement() &&
         nsAccUtils::ARIAAttrValueIs(aContent->AsElement(),
                                     nsGkAtoms::aria_hidden, nsGkAtoms::_true,
                                     eCaseMatters);
}

const nsRoleMapEntry* aria::GetRoleMap(const nsStaticAtom* aAriaRole) {
  const nsDependentAtomString role(aAriaRole);
  auto comparator = [&role](const nsRoleMapEntry& aEntry) {
    return Compare(role, aEntry.ARIARoleString());
  };
  size_t idx;
  if (BinarySearchIf(sWAIRoleMaps, 0, std::size(sWAIRoleMaps), comparator,
                     &idx)) {
    return GetRoleMapFromIndex(idx);
  }
  return nullptr;
}

////////////////////////////////////////////////////////////////////////////////
// AttrIterator class

AttrIterator::AttrIterator(nsIContent* aContent)
    : mElement(dom::Element::FromNode(aContent)),
      mIteratingDefaults(false),
      mAttrIdx(0),
      mAttrCharacteristics(0) {
  mAttrs = mElement ? &mElement->GetAttrs() : nullptr;
  mAttrCount = mAttrs ? mAttrs->AttrCount() : 0;
}

bool AttrIterator::Next() {
  while (mAttrIdx < mAttrCount) {
    const nsAttrName* attr = mAttrs->GetSafeAttrNameAt(mAttrIdx);
    mAttrIdx++;
    if (attr->NamespaceEquals(kNameSpaceID_None)) {
      mAttrAtom = attr->Atom();
      nsDependentAtomString attrStr(mAttrAtom);
      if (!StringBeginsWith(attrStr, u"aria-"_ns)) continue;  // Not ARIA

      if (mIteratingDefaults) {
        if (mOverriddenAttrs.Contains(mAttrAtom)) {
          continue;
        }
      } else {
        mOverriddenAttrs.Insert(mAttrAtom);
      }

      // AttrCharacteristicsFor has to search for the entry, so cache it here
      // rather than having to search again later.
      mAttrCharacteristics = aria::AttrCharacteristicsFor(mAttrAtom);
      if (mAttrCharacteristics & ATTR_BYPASSOBJ) {
        continue;  // No need to handle exposing as obj attribute here
      }

      if ((mAttrCharacteristics & ATTR_VALTOKEN) &&
          !nsAccUtils::HasDefinedARIAToken(mAttrs, mAttrAtom)) {
        continue;  // only expose token based attributes if they are defined
      }

      if ((mAttrCharacteristics & ATTR_BYPASSOBJ_IF_FALSE) &&
          mAttrs->AttrValueIs(kNameSpaceID_None, mAttrAtom, nsGkAtoms::_false,
                              eCaseMatters)) {
        continue;  // only expose token based attribute if value is not 'false'.
      }

      return true;
    }
  }

  mAttrCharacteristics = 0;
  mAttrAtom = nullptr;

  if (const auto* defaults = nsAccUtils::GetARIADefaults(mElement);
      !mIteratingDefaults && defaults) {
    mIteratingDefaults = true;
    mAttrs = defaults;
    mAttrCount = mAttrs->AttrCount();
    mAttrIdx = 0;
    return Next();
  }

  return false;
}

nsAtom* AttrIterator::AttrName() const { return mAttrAtom; }

void AttrIterator::AttrValue(nsAString& aAttrValue) const {
  nsAutoString value;
  if (mAttrs->GetAttr(mAttrAtom, value)) {
    if (mAttrCharacteristics & ATTR_VALTOKEN) {
      nsAtom* normalizedValue =
          nsAccUtils::NormalizeARIAToken(mAttrs, mAttrAtom);
      if (normalizedValue) {
        nsDependentAtomString normalizedValueStr(normalizedValue);
        aAttrValue.Assign(normalizedValueStr);
        return;
      }
    }
    aAttrValue.Assign(value);
  }
}

bool AttrIterator::ExposeAttr(AccAttributes* aTargetAttrs) const {
  if (mAttrCharacteristics & ATTR_VALTOKEN) {
    nsAtom* normalizedValue = nsAccUtils::NormalizeARIAToken(mAttrs, mAttrAtom);
    if (normalizedValue) {
      aTargetAttrs->SetAttribute(mAttrAtom, normalizedValue);
      return true;
    }
  } else if (mAttrCharacteristics & ATTR_VALINT) {
    int32_t intVal;
    if (nsCoreUtils::GetUIntAttrValue(mAttrs->GetAttr(mAttrAtom), &intVal)) {
      aTargetAttrs->SetAttribute(mAttrAtom, intVal);
      return true;
    }
    if (mAttrAtom == nsGkAtoms::aria_colcount ||
        mAttrAtom == nsGkAtoms::aria_rowcount) {
      // These attributes allow a value of -1.
      if (mAttrs->AttrValueIs(kNameSpaceID_None, mAttrAtom, u"-1"_ns,
                              eCaseMatters)) {
        aTargetAttrs->SetAttribute(mAttrAtom, -1);
        return true;
      }
    }
    return false;  // Invalid value.
  }
  nsAutoString value;
  if (mAttrs->GetAttr(mAttrAtom, value)) {
    aTargetAttrs->SetAttribute(mAttrAtom, std::move(value));
    return true;
  }
  return false;
}

////////////////////////////////////////////////////////////////////////////////
// AttrWithCharacteristicsIterator class
bool AttrWithCharacteristicsIterator::Next() {
  for (mIdx++; mIdx < static_cast<int32_t>(std::size(gWAIUnivAttrMap));
       mIdx++) {
    if (gWAIUnivAttrMap[mIdx].characteristics & mCharacteristics) {
      return true;
    }
  }

  return false;
}

nsStaticAtom* AttrWithCharacteristicsIterator::AttrName() const {
  return mIdx >= 0
             ? const_cast<nsStaticAtom*>(gWAIUnivAttrMap[mIdx].attributeName)
             : nullptr;
}

93%


¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.