123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932 |
- // Source: https://www.w3.org/TR/html-aria/#allowed-aria-roles-states-and-properties
- // Source: https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
- // Source https://html.spec.whatwg.org/multipage/dom.html#content-models
- // Source https://dom.spec.whatwg.org/#dom-element-attachshadow
- const htmlElms = {
- a: {
- // Note: variants work by matching the node against the
- // `matches` attribute. if the variant matches AND has the
- // desired property (contentTypes, etc.) then we use it,
- // otherwise we move on to the next matching variant
- variant: {
- href: {
- matches: '[href]',
- contentTypes: ['interactive', 'phrasing', 'flow'],
- allowedRoles: [
- 'button',
- 'checkbox',
- 'menuitem',
- 'menuitemcheckbox',
- 'menuitemradio',
- 'option',
- 'radio',
- 'switch',
- 'tab',
- 'treeitem',
- 'doc-backlink',
- 'doc-biblioref',
- 'doc-glossref',
- 'doc-noteref'
- ],
- namingMethods: ['subtreeText']
- },
- // Note: the default variant is a special variant and is
- // used as the last match if none of the other variants
- // match or have the desired attribute
- default: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- }
- }
- },
- abbr: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- addres: {
- contentTypes: ['flow'],
- allowedRoles: true
- },
- area: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- namingMethods: ['altText']
- },
- article: {
- contentTypes: ['sectioning', 'flow'],
- allowedRoles: [
- 'feed',
- 'presentation',
- 'none',
- 'document',
- 'application',
- 'main',
- 'region'
- ],
- shadowRoot: true
- },
- aside: {
- contentTypes: ['sectioning', 'flow'],
- allowedRoles: [
- 'feed',
- 'note',
- 'presentation',
- 'none',
- 'region',
- 'search',
- 'doc-dedication',
- 'doc-example',
- 'doc-footnote',
- 'doc-pullquote',
- 'doc-tip'
- ]
- },
- audio: {
- variant: {
- controls: {
- matches: '[controls]',
- contentTypes: ['interactive', 'embedded', 'phrasing', 'flow']
- },
- default: {
- contentTypes: ['embedded', 'phrasing', 'flow']
- }
- },
- // Note: if the property applies regardless of variants it is
- // placed at the top level instead of the default variant
- allowedRoles: ['application'],
- chromiumRole: 'Audio'
- },
- b: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false
- },
- base: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- bdi: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- bdo: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- blockquote: {
- contentTypes: ['flow'],
- allowedRoles: true,
- shadowRoot: true
- },
- body: {
- allowedRoles: false,
- shadowRoot: true
- },
- br: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: ['presentation', 'none'],
- namingMethods: ['titleText', 'singleSpace']
- },
- button: {
- contentTypes: ['interactive', 'phrasing', 'flow'],
- allowedRoles: [
- 'checkbox',
- 'link',
- 'menuitem',
- 'menuitemcheckbox',
- 'menuitemradio',
- 'option',
- 'radio',
- 'switch',
- 'tab'
- ],
- // 5.4 button Element
- namingMethods: ['subtreeText']
- },
- canvas: {
- allowedRoles: true,
- contentTypes: ['embedded', 'phrasing', 'flow'],
- chromiumRole: 'Canvas'
- },
- caption: {
- allowedRoles: false
- },
- cite: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- code: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- col: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- colgroup: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- data: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- datalist: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- implicitAttrs: {
- // Note: even though the value of aria-multiselectable is based
- // on the attributes, we don't currently need to know the
- // precise value. however, this allows us to make the attribute
- // future proof in case we ever do need to know it
- 'aria-multiselectable': 'false'
- }
- },
- dd: {
- allowedRoles: false
- },
- del: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- dfn: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- details: {
- contentTypes: ['interactive', 'flow'],
- allowedRoles: false
- },
- dialog: {
- contentTypes: ['flow'],
- allowedRoles: ['alertdialog']
- },
- div: {
- contentTypes: ['flow'],
- allowedRoles: true,
- shadowRoot: true
- },
- dl: {
- contentTypes: ['flow'],
- allowedRoles: ['group', 'list', 'presentation', 'none'],
- chromiumRole: 'DescriptionList'
- },
- dt: {
- allowedRoles: ['listitem']
- },
- em: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- embed: {
- contentTypes: ['interactive', 'embedded', 'phrasing', 'flow'],
- allowedRoles: ['application', 'document', 'img', 'presentation', 'none'],
- chromiumRole: 'EmbeddedObject'
- },
- fieldset: {
- contentTypes: ['flow'],
- allowedRoles: ['none', 'presentation', 'radiogroup'],
- // 5.5 fieldset and legend Elements
- namingMethods: ['fieldsetLegendText']
- },
- figcaption: {
- allowedRoles: ['group', 'none', 'presentation']
- },
- figure: {
- contentTypes: ['flow'],
- // Note: technically you're allowed no role when a figcaption
- // descendant, but we can't match that so we'll go with any role
- allowedRoles: true,
- // 5.9 figure and figcaption Elements
- namingMethods: ['figureText', 'titleText']
- },
- footer: {
- contentTypes: ['flow'],
- allowedRoles: ['group', 'none', 'presentation', 'doc-footnote'],
- shadowRoot: true
- },
- form: {
- contentTypes: ['flow'],
- allowedRoles: ['search', 'none', 'presentation']
- },
- h1: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: ['none', 'presentation', 'tab', 'doc-subtitle'],
- shadowRoot: true,
- implicitAttrs: {
- 'aria-level': '1'
- }
- },
- h2: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: ['none', 'presentation', 'tab', 'doc-subtitle'],
- shadowRoot: true,
- implicitAttrs: {
- 'aria-level': '2'
- }
- },
- h3: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: ['none', 'presentation', 'tab', 'doc-subtitle'],
- shadowRoot: true,
- implicitAttrs: {
- 'aria-level': '3'
- }
- },
- h4: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: ['none', 'presentation', 'tab', 'doc-subtitle'],
- shadowRoot: true,
- implicitAttrs: {
- 'aria-level': '4'
- }
- },
- h5: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: ['none', 'presentation', 'tab', 'doc-subtitle'],
- shadowRoot: true,
- implicitAttrs: {
- 'aria-level': '5'
- }
- },
- h6: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: ['none', 'presentation', 'tab', 'doc-subtitle'],
- shadowRoot: true,
- implicitAttrs: {
- 'aria-level': '6'
- }
- },
- head: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- header: {
- contentTypes: ['flow'],
- allowedRoles: ['group', 'none', 'presentation', 'doc-footnote'],
- shadowRoot: true
- },
- hgroup: {
- contentTypes: ['heading', 'flow'],
- allowedRoles: true
- },
- hr: {
- contentTypes: ['flow'],
- allowedRoles: ['none', 'presentation', 'doc-pagebreak'],
- namingMethods: ['titleText', 'singleSpace']
- },
- html: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- i: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- iframe: {
- contentTypes: ['interactive', 'embedded', 'phrasing', 'flow'],
- allowedRoles: ['application', 'document', 'img', 'none', 'presentation'],
- chromiumRole: 'Iframe'
- },
- img: {
- variant: {
- nonEmptyAlt: {
- matches: {
- attributes: {
- alt: '/.+/'
- }
- },
- allowedRoles: [
- 'button',
- 'checkbox',
- 'link',
- 'menuitem',
- 'menuitemcheckbox',
- 'menuitemradio',
- 'option',
- 'progressbar',
- 'scrollbar',
- 'separator',
- 'slider',
- 'switch',
- 'tab',
- 'treeitem',
- 'doc-cover'
- ]
- },
- usemap: {
- matches: '[usemap]',
- contentTypes: ['interactive', 'embedded', 'phrasing', 'flow']
- },
- default: {
- // Note: allow role presentation and none on image with no
- // alt as a way to prevent axe from flagging the image as
- // needing an alt
- allowedRoles: ['presentation', 'none'],
- contentTypes: ['embedded', 'phrasing', 'flow']
- }
- },
- // 5.10 img Element
- namingMethods: ['altText']
- },
- input: {
- variant: {
- button: {
- matches: {
- properties: {
- type: 'button'
- }
- },
- allowedRoles: [
- 'link',
- 'menuitem',
- 'menuitemcheckbox',
- 'menuitemradio',
- 'option',
- 'radio',
- 'switch',
- 'tab'
- ]
- },
- // 5.2 input type="button", input type="submit" and input type="reset"
- buttonType: {
- matches: {
- properties: {
- type: ['button', 'submit', 'reset']
- }
- },
- namingMethods: ['valueText', 'titleText', 'buttonDefaultText']
- },
- checkboxPressed: {
- matches: {
- properties: {
- type: 'checkbox'
- },
- attributes: {
- 'aria-pressed': '/.*/'
- }
- },
- allowedRoles: ['button', 'menuitemcheckbox', 'option', 'switch'],
- implicitAttrs: {
- 'aria-checked': 'false'
- }
- },
- checkbox: {
- matches: {
- properties: {
- type: 'checkbox'
- },
- attributes: {
- 'aria-pressed': null
- }
- },
- allowedRoles: ['menuitemcheckbox', 'option', 'switch'],
- implicitAttrs: {
- 'aria-checked': 'false'
- }
- },
- noRoles: {
- matches: {
- properties: {
- // Note: types of url, search, tel, and email are listed
- // as not allowed roles however since they are text
- // types they should be allowed to have role=combobox
- type: [
- 'color',
- 'date',
- 'datetime-local',
- 'file',
- 'month',
- 'number',
- 'password',
- 'range',
- 'reset',
- 'submit',
- 'time',
- 'week'
- ]
- }
- },
- allowedRoles: false
- },
- hidden: {
- matches: {
- properties: {
- type: 'hidden'
- }
- },
- // Note: spec change (do not count as phrasing)
- contentTypes: ['flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- image: {
- matches: {
- properties: {
- type: 'image'
- }
- },
- allowedRoles: [
- 'link',
- 'menuitem',
- 'menuitemcheckbox',
- 'menuitemradio',
- 'radio',
- 'switch'
- ],
- // 5.3 input type="image"
- namingMethods: [
- 'altText',
- 'valueText',
- 'labelText',
- 'titleText',
- 'buttonDefaultText'
- ]
- },
- radio: {
- matches: {
- properties: {
- type: 'radio'
- }
- },
- allowedRoles: ['menuitemradio'],
- implicitAttrs: {
- 'aria-checked': 'false'
- }
- },
- textWithList: {
- matches: {
- properties: {
- type: 'text'
- },
- attributes: {
- list: '/.*/'
- }
- },
- allowedRoles: false
- },
- default: {
- // Note: spec change (do not count as phrasing)
- contentTypes: ['interactive', 'flow'],
- allowedRoles: ['combobox', 'searchbox', 'spinbutton'],
- implicitAttrs: {
- 'aria-valuenow': ''
- },
- // 5.1 input type="text", input type="password", input type="search", input type="tel", input type="url"
- // 5.7 Other Form Elements
- namingMethods: ['labelText', 'placeholderText']
- }
- }
- },
- ins: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- kbd: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- label: {
- contentTypes: ['interactive', 'phrasing', 'flow'],
- allowedRoles: false,
- chromiumRole: 'Label'
- },
- legend: {
- allowedRoles: false
- },
- li: {
- allowedRoles: [
- 'menuitem',
- 'menuitemcheckbox',
- 'menuitemradio',
- 'option',
- 'none',
- 'presentation',
- 'radio',
- 'separator',
- 'tab',
- 'treeitem',
- 'doc-biblioentry',
- 'doc-endnote'
- ],
- implicitAttrs: {
- 'aria-setsize': '1',
- 'aria-posinset': '1'
- }
- },
- link: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- main: {
- contentTypes: ['flow'],
- allowedRoles: false,
- shadowRoot: true
- },
- map: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- math: {
- contentTypes: ['embedded', 'phrasing', 'flow'],
- allowedRoles: false
- },
- mark: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- menu: {
- contentTypes: ['flow'],
- allowedRoles: [
- 'directory',
- 'group',
- 'listbox',
- 'menu',
- 'menubar',
- 'none',
- 'presentation',
- 'radiogroup',
- 'tablist',
- 'toolbar',
- 'tree'
- ]
- },
- meta: {
- variant: {
- itemprop: {
- matches: '[itemprop]',
- contentTypes: ['phrasing', 'flow']
- }
- },
- allowedRoles: false,
- noAriaAttrs: true
- },
- meter: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- chromiumRole: 'progressbar'
- },
- nav: {
- contentTypes: ['sectioning', 'flow'],
- allowedRoles: ['doc-index', 'doc-pagelist', 'doc-toc'],
- shadowRoot: true
- },
- noscript: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- object: {
- variant: {
- usemap: {
- matches: '[usemap]',
- contentTypes: ['interactive', 'embedded', 'phrasing', 'flow']
- },
- default: {
- contentTypes: ['embedded', 'phrasing', 'flow']
- }
- },
- allowedRoles: ['application', 'document', 'img'],
- chromiumRole: 'PluginObject'
- },
- ol: {
- contentTypes: ['flow'],
- allowedRoles: [
- 'directory',
- 'group',
- 'listbox',
- 'menu',
- 'menubar',
- 'none',
- 'presentation',
- 'radiogroup',
- 'tablist',
- 'toolbar',
- 'tree'
- ]
- },
- optgroup: {
- allowedRoles: false
- },
- option: {
- allowedRoles: false,
- implicitAttrs: {
- 'aria-selected': 'false'
- }
- },
- output: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true,
- // 5.6 output Element
- namingMethods: ['subtreeText']
- },
- p: {
- contentTypes: ['flow'],
- allowedRoles: true,
- shadowRoot: true
- },
- param: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- picture: {
- contentTypes: ['embedded', 'phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- pre: {
- contentTypes: ['flow'],
- allowedRoles: true
- },
- progress: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true,
- implicitAttrs: {
- 'aria-valuemax': '100',
- 'aria-valuemin': '0',
- 'aria-valuenow': '0'
- }
- },
- q: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- rp: {
- allowedRoles: true
- },
- rt: {
- allowedRoles: true
- },
- ruby: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- s: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- samp: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- script: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- section: {
- contentTypes: ['sectioning', 'flow'],
- allowedRoles: [
- 'alert',
- 'alertdialog',
- 'application',
- 'banner',
- 'complementary',
- 'contentinfo',
- 'dialog',
- 'document',
- 'feed',
- 'log',
- 'main',
- 'marquee',
- 'navigation',
- 'none',
- 'note',
- 'presentation',
- 'search',
- 'status',
- 'tabpanel',
- 'doc-abstract',
- 'doc-acknowledgments',
- 'doc-afterword',
- 'doc-appendix',
- 'doc-bibliography',
- 'doc-chapter',
- 'doc-colophon',
- 'doc-conclusion',
- 'doc-credit',
- 'doc-credits',
- 'doc-dedication',
- 'doc-endnotes',
- 'doc-epigraph',
- 'doc-epilogue',
- 'doc-errata',
- 'doc-example',
- 'doc-foreword',
- 'doc-glossary',
- 'doc-index',
- 'doc-introduction',
- 'doc-notice',
- 'doc-pagelist',
- 'doc-part',
- 'doc-preface',
- 'doc-prologue',
- 'doc-pullquote',
- 'doc-qna',
- 'doc-toc'
- ],
- shadowRoot: true
- },
- select: {
- variant: {
- combobox: {
- matches: {
- attributes: {
- multiple: null,
- size: [null, '1']
- }
- },
- allowedRoles: ['menu']
- },
- default: {
- allowedRoles: false
- }
- },
- contentTypes: ['interactive', 'phrasing', 'flow'],
- implicitAttrs: {
- 'aria-valuenow': ''
- },
- // 5.7 Other form elements
- namingMethods: ['labelText']
- },
- slot: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- small: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- source: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- span: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true,
- shadowRoot: true
- },
- strong: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- style: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- svg: {
- contentTypes: ['embedded', 'phrasing', 'flow'],
- allowedRoles: ['application', 'document', 'img'],
- chromiumRole: 'SVGRoot',
- namingMethods: ['svgTitleText']
- },
- sub: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- summary: {
- allowedRoles: false,
- // 5.8 summary Element
- namingMethods: ['subtreeText']
- },
- sup: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- table: {
- contentTypes: ['flow'],
- allowedRoles: true,
- // 5.11 table Element
- namingMethods: ['tableCaptionText', 'tableSummaryText']
- },
- tbody: {
- allowedRoles: true
- },
- template: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: false,
- noAriaAttrs: true
- },
- textarea: {
- contentTypes: ['interactive', 'phrasing', 'flow'],
- allowedRoles: false,
- implicitAttrs: {
- 'aria-valuenow': '',
- 'aria-multiline': 'true'
- },
- // 5.1 textarea
- namingMethods: ['labelText', 'placeholderText']
- },
- tfoot: {
- allowedRoles: true
- },
- thead: {
- allowedRoles: true
- },
- time: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- title: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- td: {
- allowedRoles: true
- },
- th: {
- allowedRoles: true
- },
- tr: {
- allowedRoles: true
- },
- track: {
- allowedRoles: false,
- noAriaAttrs: true
- },
- u: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- ul: {
- contentTypes: ['flow'],
- allowedRoles: [
- 'directory',
- 'group',
- 'listbox',
- 'menu',
- 'menubar',
- 'none',
- 'presentation',
- 'radiogroup',
- 'tablist',
- 'toolbar',
- 'tree'
- ]
- },
- var: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- },
- video: {
- variant: {
- controls: {
- matches: '[controls]',
- contentTypes: ['interactive', 'embedded', 'phrasing', 'flow']
- },
- default: {
- contentTypes: ['embedded', 'phrasing', 'flow']
- }
- },
- allowedRoles: ['application'],
- chromiumRole: 'video'
- },
- wbr: {
- contentTypes: ['phrasing', 'flow'],
- allowedRoles: true
- }
- };
- export default htmlElms;
|