accessible/src/base/ARIAMap.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:expandtab:shiftwidth=2:tabstop=2:
     3  */
     4 /* This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     8 #include "ARIAMap.h"
    10 #include "nsAccUtils.h"
    11 #include "nsCoreUtils.h"
    12 #include "Role.h"
    13 #include "States.h"
    15 #include "nsAttrName.h"
    16 #include "nsWhitespaceTokenizer.h"
    18 using namespace mozilla;
    19 using namespace mozilla::a11y;
    20 using namespace mozilla::a11y::aria;
    22 static const uint32_t kGenericAccType = 0;
    24 /**
    25  *  This list of WAI-defined roles are currently hardcoded.
    26  *  Eventually we will most likely be loading an RDF resource that contains this information
    27  *  Using RDF will also allow for role extensibility. See bug 280138.
    28  *
    29  *  Definition of nsRoleMapEntry contains comments explaining this table.
    30  *
    31  *  When no nsIAccessibleRole enum mapping exists for an ARIA role, the
    32  *  role will be exposed via the object attribute "xml-roles".
    33  *  In addition, in MSAA, the unmapped role will also be exposed as a BSTR string role.
    34  *
    35  *  There are no nsIAccessibleRole enums for the following landmark roles:
    36  *    banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
    37  */
    39 static nsRoleMapEntry sWAIRoleMaps[] =
    40 {
    41   { // alert
    42     &nsGkAtoms::alert,
    43     roles::ALERT,
    44     kUseMapRole,
    45     eNoValue,
    46     eNoAction,
    47     eNoLiveAttr,
    48     kGenericAccType,
    49     kNoReqStates
    50   },
    51   { // alertdialog
    52     &nsGkAtoms::alertdialog,
    53     roles::DIALOG,
    54     kUseMapRole,
    55     eNoValue,
    56     eNoAction,
    57     eNoLiveAttr,
    58     kGenericAccType,
    59     kNoReqStates
    60   },
    61   { // application
    62     &nsGkAtoms::application,
    63     roles::APPLICATION,
    64     kUseMapRole,
    65     eNoValue,
    66     eNoAction,
    67     eNoLiveAttr,
    68     kGenericAccType,
    69     kNoReqStates
    70   },
    71   { // article
    72     &nsGkAtoms::article,
    73     roles::DOCUMENT,
    74     kUseMapRole,
    75     eNoValue,
    76     eNoAction,
    77     eNoLiveAttr,
    78     kGenericAccType,
    79     kNoReqStates,
    80     eReadonlyUntilEditable
    81   },
    82   { // button
    83     &nsGkAtoms::button,
    84     roles::PUSHBUTTON,
    85     kUseMapRole,
    86     eNoValue,
    87     ePressAction,
    88     eNoLiveAttr,
    89     eButton,
    90     kNoReqStates
    91     // eARIAPressed is auto applied on any button
    92   },
    93   { // checkbox
    94     &nsGkAtoms::checkbox,
    95     roles::CHECKBUTTON,
    96     kUseMapRole,
    97     eNoValue,
    98     eCheckUncheckAction,
    99     eNoLiveAttr,
   100     kGenericAccType,
   101     kNoReqStates,
   102     eARIACheckableMixed,
   103     eARIAReadonly
   104   },
   105   { // columnheader
   106     &nsGkAtoms::columnheader,
   107     roles::COLUMNHEADER,
   108     kUseMapRole,
   109     eNoValue,
   110     eSortAction,
   111     eNoLiveAttr,
   112     eTableCell,
   113     kNoReqStates,
   114     eARIASelectableIfDefined,
   115     eARIAReadonlyOrEditableIfDefined
   116   },
   117   { // combobox
   118     &nsGkAtoms::combobox,
   119     roles::COMBOBOX,
   120     kUseMapRole,
   121     eNoValue,
   122     eOpenCloseAction,
   123     eNoLiveAttr,
   124     kGenericAccType,
   125     states::COLLAPSED | states::HASPOPUP,
   126     eARIAAutoComplete,
   127     eARIAReadonly
   128   },
   129   { // dialog
   130     &nsGkAtoms::dialog,
   131     roles::DIALOG,
   132     kUseMapRole,
   133     eNoValue,
   134     eNoAction,
   135     eNoLiveAttr,
   136     kGenericAccType,
   137     kNoReqStates
   138   },
   139   { // directory
   140     &nsGkAtoms::directory,
   141     roles::LIST,
   142     kUseMapRole,
   143     eNoValue,
   144     eNoAction,
   145     eNoLiveAttr,
   146     eList,
   147     kNoReqStates
   148   },
   149   { // document
   150     &nsGkAtoms::document,
   151     roles::DOCUMENT,
   152     kUseMapRole,
   153     eNoValue,
   154     eNoAction,
   155     eNoLiveAttr,
   156     kGenericAccType,
   157     kNoReqStates,
   158     eReadonlyUntilEditable
   159   },
   160   { // form
   161     &nsGkAtoms::form,
   162     roles::FORM,
   163     kUseMapRole,
   164     eNoValue,
   165     eNoAction,
   166     eNoLiveAttr,
   167     kGenericAccType,
   168     kNoReqStates
   169   },
   170   { // grid
   171     &nsGkAtoms::grid,
   172     roles::TABLE,
   173     kUseMapRole,
   174     eNoValue,
   175     eNoAction,
   176     eNoLiveAttr,
   177     eSelect | eTable,
   178     kNoReqStates,
   179     eARIAMultiSelectable,
   180     eARIAReadonlyOrEditable,
   181     eFocusableUntilDisabled
   182   },
   183   { // gridcell
   184     &nsGkAtoms::gridcell,
   185     roles::GRID_CELL,
   186     kUseMapRole,
   187     eNoValue,
   188     eNoAction,
   189     eNoLiveAttr,
   190     eTableCell,
   191     kNoReqStates,
   192     eARIASelectable,
   193     eARIAReadonlyOrEditableIfDefined
   194   },
   195   { // group
   196     &nsGkAtoms::group,
   197     roles::GROUPING,
   198     kUseMapRole,
   199     eNoValue,
   200     eNoAction,
   201     eNoLiveAttr,
   202     kGenericAccType,
   203     kNoReqStates
   204   },
   205   { // heading
   206     &nsGkAtoms::heading,
   207     roles::HEADING,
   208     kUseMapRole,
   209     eNoValue,
   210     eNoAction,
   211     eNoLiveAttr,
   212     kGenericAccType,
   213     kNoReqStates
   214   },
   215   { // img
   216     &nsGkAtoms::img,
   217     roles::GRAPHIC,
   218     kUseMapRole,
   219     eNoValue,
   220     eNoAction,
   221     eNoLiveAttr,
   222     kGenericAccType,
   223     kNoReqStates
   224   },
   225   { // key
   226     &nsGkAtoms::key,
   227     roles::KEY,
   228     kUseMapRole,
   229     eNoValue,
   230     ePressAction,
   231     eNoLiveAttr,
   232     kGenericAccType,
   233     kNoReqStates,
   234     eARIAPressed
   235   },
   236   { // link
   237     &nsGkAtoms::link,
   238     roles::LINK,
   239     kUseMapRole,
   240     eNoValue,
   241     eJumpAction,
   242     eNoLiveAttr,
   243     kGenericAccType,
   244     states::LINKED
   245   },
   246   { // list
   247     &nsGkAtoms::list,
   248     roles::LIST,
   249     kUseMapRole,
   250     eNoValue,
   251     eNoAction,
   252     eNoLiveAttr,
   253     eList,
   254     states::READONLY
   255   },
   256   { // listbox
   257     &nsGkAtoms::listbox,
   258     roles::LISTBOX,
   259     kUseMapRole,
   260     eNoValue,
   261     eNoAction,
   262     eNoLiveAttr,
   263     eListControl | eSelect,
   264     kNoReqStates,
   265     eARIAMultiSelectable,
   266     eARIAReadonly,
   267     eFocusableUntilDisabled
   268   },
   269   { // listitem
   270     &nsGkAtoms::listitem,
   271     roles::LISTITEM,
   272     kUseMapRole,
   273     eNoValue,
   274     eNoAction, // XXX: should depend on state, parent accessible
   275     eNoLiveAttr,
   276     kGenericAccType,
   277     states::READONLY
   278   },
   279   { // log
   280     &nsGkAtoms::log_,
   281     roles::NOTHING,
   282     kUseNativeRole,
   283     eNoValue,
   284     eNoAction,
   285     ePoliteLiveAttr,
   286     kGenericAccType,
   287     kNoReqStates
   288   },
   289   { // marquee
   290     &nsGkAtoms::marquee,
   291     roles::ANIMATION,
   292     kUseMapRole,
   293     eNoValue,
   294     eNoAction,
   295     eOffLiveAttr,
   296     kGenericAccType,
   297     kNoReqStates
   298   },
   299   { // math
   300     &nsGkAtoms::math,
   301     roles::FLAT_EQUATION,
   302     kUseMapRole,
   303     eNoValue,
   304     eNoAction,
   305     eNoLiveAttr,
   306     kGenericAccType,
   307     kNoReqStates
   308   },
   309   { // menu
   310     &nsGkAtoms::menu,
   311     roles::MENUPOPUP,
   312     kUseMapRole,
   313     eNoValue,
   314     eNoAction, // XXX: technically accessibles of menupopup role haven't
   315                // any action, but menu can be open or close.
   316     eNoLiveAttr,
   317     kGenericAccType,
   318     kNoReqStates
   319   },
   320   { // menubar
   321     &nsGkAtoms::menubar,
   322     roles::MENUBAR,
   323     kUseMapRole,
   324     eNoValue,
   325     eNoAction,
   326     eNoLiveAttr,
   327     kGenericAccType,
   328     kNoReqStates
   329   },
   330   { // menuitem
   331     &nsGkAtoms::menuitem,
   332     roles::MENUITEM,
   333     kUseMapRole,
   334     eNoValue,
   335     eClickAction,
   336     eNoLiveAttr,
   337     kGenericAccType,
   338     kNoReqStates,
   339     eARIACheckedMixed
   340   },
   341   { // menuitemcheckbox
   342     &nsGkAtoms::menuitemcheckbox,
   343     roles::CHECK_MENU_ITEM,
   344     kUseMapRole,
   345     eNoValue,
   346     eClickAction,
   347     eNoLiveAttr,
   348     kGenericAccType,
   349     kNoReqStates,
   350     eARIACheckableMixed
   351   },
   352   { // menuitemradio
   353     &nsGkAtoms::menuitemradio,
   354     roles::RADIO_MENU_ITEM,
   355     kUseMapRole,
   356     eNoValue,
   357     eClickAction,
   358     eNoLiveAttr,
   359     kGenericAccType,
   360     kNoReqStates,
   361     eARIACheckableBool
   362   },
   363   { // note
   364     &nsGkAtoms::note_,
   365     roles::NOTE,
   366     kUseMapRole,
   367     eNoValue,
   368     eNoAction,
   369     eNoLiveAttr,
   370     kGenericAccType,
   371     kNoReqStates
   372   },
   373   { // option
   374     &nsGkAtoms::option,
   375     roles::OPTION,
   376     kUseMapRole,
   377     eNoValue,
   378     eSelectAction,
   379     eNoLiveAttr,
   380     kGenericAccType,
   381     kNoReqStates,
   382     eARIASelectable,
   383     eARIACheckedMixed
   384   },
   385   { // presentation
   386     &nsGkAtoms::presentation,
   387     roles::NOTHING,
   388     kUseMapRole,
   389     eNoValue,
   390     eNoAction,
   391     eNoLiveAttr,
   392     kGenericAccType,
   393     kNoReqStates
   394   },
   395   { // progressbar
   396     &nsGkAtoms::progressbar,
   397     roles::PROGRESSBAR,
   398     kUseMapRole,
   399     eHasValueMinMax,
   400     eNoAction,
   401     eNoLiveAttr,
   402     kGenericAccType,
   403     states::READONLY,
   404     eIndeterminateIfNoValue
   405   },
   406   { // radio
   407     &nsGkAtoms::radio,
   408     roles::RADIOBUTTON,
   409     kUseMapRole,
   410     eNoValue,
   411     eSelectAction,
   412     eNoLiveAttr,
   413     kGenericAccType,
   414     kNoReqStates,
   415     eARIACheckableBool
   416   },
   417   { // radiogroup
   418     &nsGkAtoms::radiogroup,
   419     roles::GROUPING,
   420     kUseMapRole,
   421     eNoValue,
   422     eNoAction,
   423     eNoLiveAttr,
   424     kGenericAccType,
   425     kNoReqStates
   426   },
   427   { // region
   428     &nsGkAtoms::region,
   429     roles::PANE,
   430     kUseMapRole,
   431     eNoValue,
   432     eNoAction,
   433     eNoLiveAttr,
   434     kGenericAccType,
   435     kNoReqStates
   436   },
   437   { // row
   438     &nsGkAtoms::row,
   439     roles::ROW,
   440     kUseMapRole,
   441     eNoValue,
   442     eNoAction,
   443     eNoLiveAttr,
   444     eTableRow,
   445     kNoReqStates,
   446     eARIASelectable
   447   },
   448   { // rowgroup
   449     &nsGkAtoms::rowgroup,
   450     roles::GROUPING,
   451     kUseMapRole,
   452     eNoValue,
   453     eNoAction,
   454     eNoLiveAttr,
   455     kGenericAccType,
   456     kNoReqStates
   457   },
   458   { // rowheader
   459     &nsGkAtoms::rowheader,
   460     roles::ROWHEADER,
   461     kUseMapRole,
   462     eNoValue,
   463     eSortAction,
   464     eNoLiveAttr,
   465     eTableCell,
   466     kNoReqStates,
   467     eARIASelectableIfDefined,
   468     eARIAReadonlyOrEditableIfDefined
   469   },
   470   { // scrollbar
   471     &nsGkAtoms::scrollbar,
   472     roles::SCROLLBAR,
   473     kUseMapRole,
   474     eHasValueMinMax,
   475     eNoAction,
   476     eNoLiveAttr,
   477     kGenericAccType,
   478     kNoReqStates,
   479     eARIAOrientation,
   480     eARIAReadonly
   481   },
   482   { // separator
   483     &nsGkAtoms::separator_,
   484     roles::SEPARATOR,
   485     kUseMapRole,
   486     eNoValue,
   487     eNoAction,
   488     eNoLiveAttr,
   489     kGenericAccType,
   490     kNoReqStates,
   491     eARIAOrientation
   492   },
   493   { // slider
   494     &nsGkAtoms::slider,
   495     roles::SLIDER,
   496     kUseMapRole,
   497     eHasValueMinMax,
   498     eNoAction,
   499     eNoLiveAttr,
   500     kGenericAccType,
   501     kNoReqStates,
   502     eARIAOrientation,
   503     eARIAReadonly
   504   },
   505   { // spinbutton
   506     &nsGkAtoms::spinbutton,
   507     roles::SPINBUTTON,
   508     kUseMapRole,
   509     eHasValueMinMax,
   510     eNoAction,
   511     eNoLiveAttr,
   512     kGenericAccType,
   513     kNoReqStates,
   514     eARIAReadonly
   515   },
   516   { // status
   517     &nsGkAtoms::status,
   518     roles::STATUSBAR,
   519     kUseMapRole,
   520     eNoValue,
   521     eNoAction,
   522     ePoliteLiveAttr,
   523     kGenericAccType,
   524     kNoReqStates
   525   },
   526   { // tab
   527     &nsGkAtoms::tab,
   528     roles::PAGETAB,
   529     kUseMapRole,
   530     eNoValue,
   531     eSwitchAction,
   532     eNoLiveAttr,
   533     kGenericAccType,
   534     kNoReqStates,
   535     eARIASelectable
   536   },
   537   { // tablist
   538     &nsGkAtoms::tablist,
   539     roles::PAGETABLIST,
   540     kUseMapRole,
   541     eNoValue,
   542     eNoAction,
   543     eNoLiveAttr,
   544     eSelect,
   545     kNoReqStates
   546   },
   547   { // tabpanel
   548     &nsGkAtoms::tabpanel,
   549     roles::PROPERTYPAGE,
   550     kUseMapRole,
   551     eNoValue,
   552     eNoAction,
   553     eNoLiveAttr,
   554     kGenericAccType,
   555     kNoReqStates
   556   },
   557   { // textbox
   558     &nsGkAtoms::textbox,
   559     roles::ENTRY,
   560     kUseMapRole,
   561     eNoValue,
   562     eActivateAction,
   563     eNoLiveAttr,
   564     kGenericAccType,
   565     kNoReqStates,
   566     eARIAAutoComplete,
   567     eARIAMultiline,
   568     eARIAReadonlyOrEditable
   569   },
   570   { // timer
   571     &nsGkAtoms::timer,
   572     roles::NOTHING,
   573     kUseNativeRole,
   574     eNoValue,
   575     eNoAction,
   576     eOffLiveAttr,
   577     kNoReqStates
   578   },
   579   { // toolbar
   580     &nsGkAtoms::toolbar,
   581     roles::TOOLBAR,
   582     kUseMapRole,
   583     eNoValue,
   584     eNoAction,
   585     eNoLiveAttr,
   586     kGenericAccType,
   587     kNoReqStates
   588   },
   589   { // tooltip
   590     &nsGkAtoms::tooltip,
   591     roles::TOOLTIP,
   592     kUseMapRole,
   593     eNoValue,
   594     eNoAction,
   595     eNoLiveAttr,
   596     kGenericAccType,
   597     kNoReqStates
   598   },
   599   { // tree
   600     &nsGkAtoms::tree,
   601     roles::OUTLINE,
   602     kUseMapRole,
   603     eNoValue,
   604     eNoAction,
   605     eNoLiveAttr,
   606     eSelect,
   607     kNoReqStates,
   608     eARIAReadonly,
   609     eARIAMultiSelectable,
   610     eFocusableUntilDisabled
   611   },
   612   { // treegrid
   613     &nsGkAtoms::treegrid,
   614     roles::TREE_TABLE,
   615     kUseMapRole,
   616     eNoValue,
   617     eNoAction,
   618     eNoLiveAttr,
   619     eSelect | eTable,
   620     kNoReqStates,
   621     eARIAReadonlyOrEditable,
   622     eARIAMultiSelectable,
   623     eFocusableUntilDisabled
   624   },
   625   { // treeitem
   626     &nsGkAtoms::treeitem,
   627     roles::OUTLINEITEM,
   628     kUseMapRole,
   629     eNoValue,
   630     eActivateAction, // XXX: should expose second 'expand/collapse' action based
   631                      // on states
   632     eNoLiveAttr,
   633     kGenericAccType,
   634     kNoReqStates,
   635     eARIASelectable,
   636     eARIACheckedMixed
   637   }
   638 };
   640 static nsRoleMapEntry sLandmarkRoleMap = {
   641   &nsGkAtoms::_empty,
   642   roles::NOTHING,
   643   kUseNativeRole,
   644   eNoValue,
   645   eNoAction,
   646   eNoLiveAttr,
   647   kGenericAccType,
   648   kNoReqStates
   649 };
   651 nsRoleMapEntry aria::gEmptyRoleMap = {
   652   &nsGkAtoms::_empty,
   653   roles::NOTHING,
   654   kUseMapRole,
   655   eNoValue,
   656   eNoAction,
   657   eNoLiveAttr,
   658   kGenericAccType,
   659   kNoReqStates
   660 };
   662 /**
   663  * Universal (Global) states:
   664  * The following state rules are applied to any accessible element,
   665  * whether there is an ARIA role or not:
   666  */
   667 static const EStateRule sWAIUnivStateMap[] = {
   668   eARIABusy,
   669   eARIADisabled,
   670   eARIAExpanded,  // Currently under spec review but precedent exists
   671   eARIAHasPopup,  // Note this is technically a "property"
   672   eARIAInvalid,
   673   eARIARequired,  // XXX not global, Bug 553117
   674   eARIANone
   675 };
   678 /**
   679  * ARIA attribute map for attribute characteristics.
   680  * @note ARIA attributes that don't have any flags are not included here.
   681  */
   683 struct AttrCharacteristics
   684 {
   685   nsIAtom** attributeName;
   686   const uint8_t characteristics;
   687 };
   689 static const AttrCharacteristics gWAIUnivAttrMap[] = {
   690   {&nsGkAtoms::aria_activedescendant,  ATTR_BYPASSOBJ                               },
   691   {&nsGkAtoms::aria_atomic,   ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
   692   {&nsGkAtoms::aria_busy,                               ATTR_VALTOKEN | ATTR_GLOBAL },
   693   {&nsGkAtoms::aria_checked,           ATTR_BYPASSOBJ | ATTR_VALTOKEN               }, /* exposes checkable obj attr */
   694   {&nsGkAtoms::aria_controls,          ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   695   {&nsGkAtoms::aria_describedby,       ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   696   {&nsGkAtoms::aria_disabled,          ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
   697   {&nsGkAtoms::aria_dropeffect,                         ATTR_VALTOKEN | ATTR_GLOBAL },
   698   {&nsGkAtoms::aria_expanded,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   699   {&nsGkAtoms::aria_flowto,            ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   700   {&nsGkAtoms::aria_grabbed,                            ATTR_VALTOKEN | ATTR_GLOBAL },
   701   {&nsGkAtoms::aria_haspopup,          ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
   702   {&nsGkAtoms::aria_hidden,   ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
   703   {&nsGkAtoms::aria_invalid,           ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
   704   {&nsGkAtoms::aria_label,             ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   705   {&nsGkAtoms::aria_labelledby,        ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   706   {&nsGkAtoms::aria_level,             ATTR_BYPASSOBJ                               }, /* handled via groupPosition */
   707   {&nsGkAtoms::aria_live,                               ATTR_VALTOKEN | ATTR_GLOBAL },
   708   {&nsGkAtoms::aria_multiline,         ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   709   {&nsGkAtoms::aria_multiselectable,   ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   710   {&nsGkAtoms::aria_owns,              ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   711   {&nsGkAtoms::aria_orientation,                        ATTR_VALTOKEN               },
   712   {&nsGkAtoms::aria_posinset,          ATTR_BYPASSOBJ                               }, /* handled via groupPosition */
   713   {&nsGkAtoms::aria_pressed,           ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   714   {&nsGkAtoms::aria_readonly,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   715   {&nsGkAtoms::aria_relevant,          ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   716   {&nsGkAtoms::aria_required,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   717   {&nsGkAtoms::aria_selected,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   718   {&nsGkAtoms::aria_setsize,           ATTR_BYPASSOBJ                               }, /* handled via groupPosition */
   719   {&nsGkAtoms::aria_sort,                               ATTR_VALTOKEN               },
   720   {&nsGkAtoms::aria_valuenow,          ATTR_BYPASSOBJ                               },
   721   {&nsGkAtoms::aria_valuemin,          ATTR_BYPASSOBJ                               },
   722   {&nsGkAtoms::aria_valuemax,          ATTR_BYPASSOBJ                               },
   723   {&nsGkAtoms::aria_valuetext,         ATTR_BYPASSOBJ                               }
   724 };
   726 nsRoleMapEntry*
   727 aria::GetRoleMap(nsINode* aNode)
   728 {
   729   nsIContent* content = nsCoreUtils::GetRoleContent(aNode);
   730   nsAutoString roles;
   731   if (!content ||
   732       !content->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roles) ||
   733       roles.IsEmpty()) {
   734     // We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
   735     return nullptr;
   736   }
   738   nsWhitespaceTokenizer tokenizer(roles);
   739   while (tokenizer.hasMoreTokens()) {
   740     // Do a binary search through table for the next role in role list
   741     const nsDependentSubstring role = tokenizer.nextToken();
   742     uint32_t low = 0;
   743     uint32_t high = ArrayLength(sWAIRoleMaps);
   744     while (low < high) {
   745       uint32_t idx = (low + high) / 2;
   746       int32_t compare = Compare(role, sWAIRoleMaps[idx].ARIARoleString());
   747       if (compare == 0)
   748         return sWAIRoleMaps + idx;
   750       if (compare < 0)
   751         high = idx;
   752       else
   753         low = idx + 1;
   754     }
   755   }
   757   // Always use some entry if there is a non-empty role string
   758   // To ensure an accessible object is created
   759   return &sLandmarkRoleMap;
   760 }
   762 uint64_t
   763 aria::UniversalStatesFor(mozilla::dom::Element* aElement)
   764 {
   765   uint64_t state = 0;
   766   uint32_t index = 0;
   767   while (MapToState(sWAIUnivStateMap[index], aElement, &state))
   768     index++;
   770   return state;
   771 }
   773 uint8_t
   774 aria::AttrCharacteristicsFor(nsIAtom* aAtom)
   775 {
   776   for (uint32_t i = 0; i < ArrayLength(gWAIUnivAttrMap); i++)
   777     if (*gWAIUnivAttrMap[i].attributeName == aAtom)
   778       return gWAIUnivAttrMap[i].characteristics;
   780   return 0;
   781 }
   783 ////////////////////////////////////////////////////////////////////////////////
   784 // AttrIterator class
   786 bool
   787 AttrIterator::Next(nsAString& aAttrName, nsAString& aAttrValue)
   788 {
   789   while (mAttrIdx < mAttrCount) {
   790     const nsAttrName* attr = mContent->GetAttrNameAt(mAttrIdx);
   791     mAttrIdx++;
   792     if (attr->NamespaceEquals(kNameSpaceID_None)) {
   793       nsIAtom* attrAtom = attr->Atom();
   794       nsDependentAtomString attrStr(attrAtom);
   795       if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
   796         continue; // Not ARIA
   798       uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
   799       if (attrFlags & ATTR_BYPASSOBJ)
   800         continue; // No need to handle exposing as obj attribute here
   802       if ((attrFlags & ATTR_VALTOKEN) &&
   803            !nsAccUtils::HasDefinedARIAToken(mContent, attrAtom))
   804         continue; // only expose token based attributes if they are defined
   806       if ((attrFlags & ATTR_BYPASSOBJ_IF_FALSE) &&
   807           mContent->AttrValueIs(kNameSpaceID_None, attrAtom,
   808                                 nsGkAtoms::_false, eCaseMatters)) {
   809         continue; // only expose token based attribute if value is not 'false'.
   810       }
   812       nsAutoString value;
   813       if (mContent->GetAttr(kNameSpaceID_None, attrAtom, value)) {
   814         aAttrName.Assign(Substring(attrStr, 5));
   815         aAttrValue.Assign(value);
   816         return true;
   817       }
   818     }
   819   }
   821   return false;
   822 }

mercurial