From e20c98a25a49bcef7e785afa7ff71f9c3e08bbe7 Mon Sep 17 00:00:00 2001 From: Liubin Guo Date: Thu, 8 Sep 2016 13:57:29 +0800 Subject: [PATCH] [Issue #234] ARIA Rules - Fixed getImplicitRole for openingElements * added opening element support in getImplicitRole * changed case of all HTML elements names from upper to lower * exposed JsxAttribute functions for testability --- src/utils/JsxAttribute.ts | 44 ++++++- src/utils/getImplicitRole.ts | 11 +- src/utils/implicitRoles/a.ts | 2 +- src/utils/implicitRoles/area.ts | 2 +- src/utils/implicitRoles/article.ts | 2 +- src/utils/implicitRoles/aside.ts | 2 +- src/utils/implicitRoles/body.ts | 2 +- src/utils/implicitRoles/button.ts | 2 +- src/utils/implicitRoles/datalist.ts | 2 +- src/utils/implicitRoles/dd.ts | 8 ++ src/utils/implicitRoles/details.ts | 2 +- src/utils/implicitRoles/dialog.ts | 2 +- src/utils/implicitRoles/dl.ts | 2 +- src/utils/implicitRoles/dt.ts | 8 ++ src/utils/implicitRoles/footer.ts | 11 ++ src/utils/implicitRoles/form.ts | 2 +- src/utils/implicitRoles/h1.ts | 2 +- src/utils/implicitRoles/h2.ts | 2 +- src/utils/implicitRoles/h3.ts | 2 +- src/utils/implicitRoles/h4.ts | 2 +- src/utils/implicitRoles/h5.ts | 2 +- src/utils/implicitRoles/h6.ts | 2 +- src/utils/implicitRoles/header.ts | 11 ++ src/utils/implicitRoles/hr.ts | 2 +- src/utils/implicitRoles/img.ts | 2 +- src/utils/implicitRoles/index.ts | 175 ++++++++++++++++------------ src/utils/implicitRoles/input.ts | 37 ++++-- src/utils/implicitRoles/li.ts | 15 ++- src/utils/implicitRoles/link.ts | 2 +- src/utils/implicitRoles/main.ts | 8 ++ src/utils/implicitRoles/math.ts | 8 ++ src/utils/implicitRoles/menu.ts | 8 +- src/utils/implicitRoles/menuitem.ts | 8 +- src/utils/implicitRoles/meter.ts | 2 +- src/utils/implicitRoles/nav.ts | 2 +- src/utils/implicitRoles/ol.ts | 2 +- src/utils/implicitRoles/optgroup.ts | 8 ++ src/utils/implicitRoles/option.ts | 2 +- src/utils/implicitRoles/output.ts | 2 +- src/utils/implicitRoles/progress.ts | 2 +- src/utils/implicitRoles/section.ts | 2 +- src/utils/implicitRoles/select.ts | 2 +- src/utils/implicitRoles/summary.ts | 8 ++ src/utils/implicitRoles/table.ts | 8 ++ src/utils/implicitRoles/tbody.ts | 2 +- src/utils/implicitRoles/td.ts | 8 ++ src/utils/implicitRoles/textarea.ts | 2 +- src/utils/implicitRoles/tfoot.ts | 2 +- src/utils/implicitRoles/th.ts | 9 ++ src/utils/implicitRoles/thead.ts | 2 +- src/utils/implicitRoles/tr.ts | 8 ++ src/utils/implicitRoles/ul.ts | 2 +- 52 files changed, 331 insertions(+), 136 deletions(-) create mode 100644 src/utils/implicitRoles/dd.ts create mode 100644 src/utils/implicitRoles/dt.ts create mode 100644 src/utils/implicitRoles/footer.ts create mode 100644 src/utils/implicitRoles/header.ts create mode 100644 src/utils/implicitRoles/main.ts create mode 100644 src/utils/implicitRoles/math.ts create mode 100644 src/utils/implicitRoles/optgroup.ts create mode 100644 src/utils/implicitRoles/summary.ts create mode 100644 src/utils/implicitRoles/table.ts create mode 100644 src/utils/implicitRoles/td.ts create mode 100644 src/utils/implicitRoles/th.ts create mode 100644 src/utils/implicitRoles/tr.ts diff --git a/src/utils/JsxAttribute.ts b/src/utils/JsxAttribute.ts index 14ac47b7b..34fbb7af7 100644 --- a/src/utils/JsxAttribute.ts +++ b/src/utils/JsxAttribute.ts @@ -1,6 +1,4 @@ /** - * @copyright Microsoft Corporation. All rights reserved. - * * @JsxAttribute utilities for react rules. */ @@ -127,3 +125,45 @@ export function getJsxAttributesFromJsxElement(node: ts.Node): { [propName: stri return attributesDictionary; } + +/** + * Get first JsxElement whose tagName equals tagName from code. + * @param code - a string of jsx code. + * @param exceptTagName - the element's tagName you want to get. + * @return { ts.JsxElement | ts.JsxSelfClosingElement } - a element. + */ +export function getJsxElementFromCode(code: string, exceptTagName: string): ts.JsxElement | ts.JsxSelfClosingElement { + const sourceFile: ts.SourceFile = ts.createSourceFile('test.tsx', code, ts.ScriptTarget.ES6, true); + + return delintNode(sourceFile, exceptTagName); +} + +function delintNode(node: ts.Node, tagName: string): ts.JsxElement | ts.JsxSelfClosingElement { + if (isJsxElement(node) && node.openingElement.tagName.getText() === tagName) { + return node; + } else if (isJsxSelfClosingElement(node) && node.tagName.getText() === tagName) { + return node; + } else if (!node || node.getChildCount() === 0) { + return undefined; + } + + return ts.forEachChild(node, (childNode: ts.Node) => delintNode(childNode, tagName)); +} + +/** + * Get ancestor node whose tagName is ancestorTagName for a node. + * @return { ts.JsxElement } the ancestor node or undefined if the ancestor node is not exist. + */ +export function getAncestorNode(node: ts.Node, ancestorTagName: string): ts.JsxElement { + if (!node) { + return undefined; + } + + const ancestorNode: ts.Node = node.parent; + + if (isJsxElement(ancestorNode) && ancestorNode.openingElement.tagName.getText() === ancestorTagName) { + return ancestorNode; + } else { + return getAncestorNode(ancestorNode, ancestorTagName); + } +} diff --git a/src/utils/getImplicitRole.ts b/src/utils/getImplicitRole.ts index fa78e667d..af896d81d 100644 --- a/src/utils/getImplicitRole.ts +++ b/src/utils/getImplicitRole.ts @@ -1,11 +1,14 @@ import * as ts from 'typescript'; import * as implicitRoles from './implicitRoles'; -import { isJsxElement, isJsxSelfClosingElement } from './TypeGuard'; +import { isJsxElement, isJsxSelfClosingElement, isJsxOpeningElement } from './TypeGuard'; /** - * @returns the implicit role for a JsxElement, JsxSelfClosingElement or JsxOpeningElement. + * @returns { string } the implicit role or undefined if no corresponding role for a + * JsxElement, JsxSelfClosingElement or JsxOpeningElement. * The implementation is inspired and re-implemented from * https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/src/util/getImplicitRole.js + * A reference about implicit role: https://www.w3.org/TR/html-aria/#sec-strong-native-semantics. + * A reference about no corresponding role: https://www.w3.org/TR/html-aria/#dfn-no-corresponding-role. */ export function getImplicitRole(node: ts.Node): string { let tagName: string; @@ -14,9 +17,11 @@ export function getImplicitRole(node: ts.Node): string { tagName = node.openingElement.tagName.getText(); } else if (isJsxSelfClosingElement(node)) { tagName = node.tagName.getText(); + } else if (isJsxOpeningElement(node)) { + tagName = node.tagName.getText(); } else { tagName = undefined; } - return tagName && implicitRoles[tagName.toUpperCase()] && implicitRoles[tagName.toUpperCase()](node); + return tagName && implicitRoles[tagName] && implicitRoles[tagName](node); } diff --git a/src/utils/implicitRoles/a.ts b/src/utils/implicitRoles/a.ts index 259c02e99..64d6e6473 100644 --- a/src/utils/implicitRoles/a.ts +++ b/src/utils/implicitRoles/a.ts @@ -10,4 +10,4 @@ function getImplicitRoleForAnchor(node: ts.Node): string { return getJsxAttributesFromJsxElement(node)[hrefString] ? 'link' : undefined; } -export { getImplicitRoleForAnchor as A }; +export { getImplicitRoleForAnchor as a }; diff --git a/src/utils/implicitRoles/area.ts b/src/utils/implicitRoles/area.ts index 743c87d27..6d38afde8 100644 --- a/src/utils/implicitRoles/area.ts +++ b/src/utils/implicitRoles/area.ts @@ -10,4 +10,4 @@ function getImplicitRoleForArea(node: ts.Node): string { return getJsxAttributesFromJsxElement(node)[hrefString] ? 'link' : undefined; } -export { getImplicitRoleForArea as AREA }; +export { getImplicitRoleForArea as area }; diff --git a/src/utils/implicitRoles/article.ts b/src/utils/implicitRoles/article.ts index 3a9d41e97..1f3e4930d 100644 --- a/src/utils/implicitRoles/article.ts +++ b/src/utils/implicitRoles/article.ts @@ -5,4 +5,4 @@ function getImplicitRoleForArticle(): string { return 'article'; } -export { getImplicitRoleForArticle as ARTICLE }; +export { getImplicitRoleForArticle as article }; diff --git a/src/utils/implicitRoles/aside.ts b/src/utils/implicitRoles/aside.ts index f984b83dc..3d98f5ce3 100644 --- a/src/utils/implicitRoles/aside.ts +++ b/src/utils/implicitRoles/aside.ts @@ -5,4 +5,4 @@ function getImplicitRoleForAside(): string { return 'complementary'; } -export { getImplicitRoleForAside as ASIDE }; +export { getImplicitRoleForAside as aside }; diff --git a/src/utils/implicitRoles/body.ts b/src/utils/implicitRoles/body.ts index a013d2346..49e364a43 100644 --- a/src/utils/implicitRoles/body.ts +++ b/src/utils/implicitRoles/body.ts @@ -5,4 +5,4 @@ function getImplicitRoleForBody(): string { return 'document'; } -export { getImplicitRoleForBody as BODY }; +export { getImplicitRoleForBody as body }; diff --git a/src/utils/implicitRoles/button.ts b/src/utils/implicitRoles/button.ts index fc1ec338b..04d5ac096 100644 --- a/src/utils/implicitRoles/button.ts +++ b/src/utils/implicitRoles/button.ts @@ -5,4 +5,4 @@ function getImplicitRoleForButton(): string { return 'button'; } -export { getImplicitRoleForButton as BUTTON }; +export { getImplicitRoleForButton as button }; diff --git a/src/utils/implicitRoles/datalist.ts b/src/utils/implicitRoles/datalist.ts index b0c164e3d..4fcd7c8f2 100644 --- a/src/utils/implicitRoles/datalist.ts +++ b/src/utils/implicitRoles/datalist.ts @@ -5,4 +5,4 @@ function getImplicitRoleForDatalist(): string { return 'listbox'; } -export { getImplicitRoleForDatalist as DATALIST }; +export { getImplicitRoleForDatalist as datalist }; diff --git a/src/utils/implicitRoles/dd.ts b/src/utils/implicitRoles/dd.ts new file mode 100644 index 000000000..1262d8690 --- /dev/null +++ b/src/utils/implicitRoles/dd.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a dd tag. + */ +function getImplicitRoleForDd(): string { + return 'definition'; +} + +export { getImplicitRoleForDd as dd }; diff --git a/src/utils/implicitRoles/details.ts b/src/utils/implicitRoles/details.ts index dd17d689f..6997a4e2f 100644 --- a/src/utils/implicitRoles/details.ts +++ b/src/utils/implicitRoles/details.ts @@ -5,4 +5,4 @@ function getImplicitRoleForDetails(): string { return 'group'; } -export { getImplicitRoleForDetails as DETAILS }; +export { getImplicitRoleForDetails as details }; diff --git a/src/utils/implicitRoles/dialog.ts b/src/utils/implicitRoles/dialog.ts index 432002757..caf38ed26 100644 --- a/src/utils/implicitRoles/dialog.ts +++ b/src/utils/implicitRoles/dialog.ts @@ -5,4 +5,4 @@ function getImplicitRoleForDialog(): string { return 'dialog'; } -export { getImplicitRoleForDialog as DIALOG }; +export { getImplicitRoleForDialog as dialog }; diff --git a/src/utils/implicitRoles/dl.ts b/src/utils/implicitRoles/dl.ts index 2726ee14d..d210280eb 100644 --- a/src/utils/implicitRoles/dl.ts +++ b/src/utils/implicitRoles/dl.ts @@ -5,4 +5,4 @@ function getImplicitRoleForDl(): string { return 'list'; } -export { getImplicitRoleForDl as DL }; +export { getImplicitRoleForDl as dl }; diff --git a/src/utils/implicitRoles/dt.ts b/src/utils/implicitRoles/dt.ts new file mode 100644 index 000000000..84e138b35 --- /dev/null +++ b/src/utils/implicitRoles/dt.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a dt tag. + */ +function getImplicitRoleForDt(): string { + return 'listitem'; +} + +export { getImplicitRoleForDt as dt }; diff --git a/src/utils/implicitRoles/footer.ts b/src/utils/implicitRoles/footer.ts new file mode 100644 index 000000000..389fecb91 --- /dev/null +++ b/src/utils/implicitRoles/footer.ts @@ -0,0 +1,11 @@ +import * as ts from 'typescript'; +import { getAncestorNode } from '../JsxAttribute'; + +/** + * @Returns the implicit role for a footer tag. + */ +function getImplicitRoleForFooter(node: ts.Node): string { + return getAncestorNode(node, 'article') || getAncestorNode(node, 'section') ? undefined : 'contentinfo'; +} + +export { getImplicitRoleForFooter as footer }; diff --git a/src/utils/implicitRoles/form.ts b/src/utils/implicitRoles/form.ts index 1902cb363..31fee9e8c 100644 --- a/src/utils/implicitRoles/form.ts +++ b/src/utils/implicitRoles/form.ts @@ -5,4 +5,4 @@ function getImplicitRoleForForm(): string { return 'form'; } -export { getImplicitRoleForForm as FORM }; +export { getImplicitRoleForForm as form }; diff --git a/src/utils/implicitRoles/h1.ts b/src/utils/implicitRoles/h1.ts index 2bc25a301..15d8e5ce1 100644 --- a/src/utils/implicitRoles/h1.ts +++ b/src/utils/implicitRoles/h1.ts @@ -5,4 +5,4 @@ function getImplicitRoleForH1(): string { return 'heading'; } -export { getImplicitRoleForH1 as H1 }; +export { getImplicitRoleForH1 as h1 }; diff --git a/src/utils/implicitRoles/h2.ts b/src/utils/implicitRoles/h2.ts index c1c757d96..4acc2fe16 100644 --- a/src/utils/implicitRoles/h2.ts +++ b/src/utils/implicitRoles/h2.ts @@ -5,4 +5,4 @@ function getImplicitRoleForH2(): string { return 'heading'; } -export { getImplicitRoleForH2 as H2 }; +export { getImplicitRoleForH2 as h2 }; diff --git a/src/utils/implicitRoles/h3.ts b/src/utils/implicitRoles/h3.ts index f6acf354f..912003c92 100644 --- a/src/utils/implicitRoles/h3.ts +++ b/src/utils/implicitRoles/h3.ts @@ -5,4 +5,4 @@ function getImplicitRoleForH3(): string { return 'heading'; } -export { getImplicitRoleForH3 as H3 }; +export { getImplicitRoleForH3 as h3 }; diff --git a/src/utils/implicitRoles/h4.ts b/src/utils/implicitRoles/h4.ts index 660bc4630..9833cad26 100644 --- a/src/utils/implicitRoles/h4.ts +++ b/src/utils/implicitRoles/h4.ts @@ -5,4 +5,4 @@ function getImplicitRoleForH4(): string { return 'heading'; } -export { getImplicitRoleForH4 as H4 }; +export { getImplicitRoleForH4 as h4 }; diff --git a/src/utils/implicitRoles/h5.ts b/src/utils/implicitRoles/h5.ts index e04535f06..6026af7b5 100644 --- a/src/utils/implicitRoles/h5.ts +++ b/src/utils/implicitRoles/h5.ts @@ -5,4 +5,4 @@ function getImplicitRoleForH5(): string { return 'heading'; } -export { getImplicitRoleForH5 as H5 }; +export { getImplicitRoleForH5 as h5 }; diff --git a/src/utils/implicitRoles/h6.ts b/src/utils/implicitRoles/h6.ts index ea3ab1202..9ab6ad855 100644 --- a/src/utils/implicitRoles/h6.ts +++ b/src/utils/implicitRoles/h6.ts @@ -5,4 +5,4 @@ function getImplicitRoleForH6(): string { return 'heading'; } -export { getImplicitRoleForH6 as H6 }; +export { getImplicitRoleForH6 as h6 }; diff --git a/src/utils/implicitRoles/header.ts b/src/utils/implicitRoles/header.ts new file mode 100644 index 000000000..11a134cb4 --- /dev/null +++ b/src/utils/implicitRoles/header.ts @@ -0,0 +1,11 @@ +import * as ts from 'typescript'; +import { getAncestorNode } from '../JsxAttribute'; + +/** + * @Returns the implicit role for a header tag. + */ +function getImplicitRoleForHeader(node: ts.Node): string { + return getAncestorNode(node, 'article') || getAncestorNode(node, 'section') ? undefined : 'banner'; +} + +export { getImplicitRoleForHeader as header }; diff --git a/src/utils/implicitRoles/hr.ts b/src/utils/implicitRoles/hr.ts index a2a4b1832..ec4553fa9 100644 --- a/src/utils/implicitRoles/hr.ts +++ b/src/utils/implicitRoles/hr.ts @@ -5,4 +5,4 @@ function getImplicitRoleForHr(): string { return 'separator'; } -export { getImplicitRoleForHr as HR }; +export { getImplicitRoleForHr as hr }; diff --git a/src/utils/implicitRoles/img.ts b/src/utils/implicitRoles/img.ts index 9193b00f4..a079e6a34 100644 --- a/src/utils/implicitRoles/img.ts +++ b/src/utils/implicitRoles/img.ts @@ -16,4 +16,4 @@ function getImplicitRoleForImg(node: ts.Node): string { return 'presentation'; } -export { getImplicitRoleForImg as IMG }; +export { getImplicitRoleForImg as img }; diff --git a/src/utils/implicitRoles/index.ts b/src/utils/implicitRoles/index.ts index c307fe85f..c88637db1 100644 --- a/src/utils/implicitRoles/index.ts +++ b/src/utils/implicitRoles/index.ts @@ -1,80 +1,101 @@ -import { A } from './a'; -import { AREA } from './area'; -import { ARTICLE } from './article'; -import { ASIDE } from './aside'; -import { BODY } from './body'; -import { BUTTON } from './button'; -import { DATALIST } from './datalist'; -import { DETAILS } from './details'; -import { DIALOG } from './dialog'; -import { DL } from './dl'; -import { FORM } from './form'; -import { H1 } from './h1'; -import { H2 } from './h2'; -import { H3 } from './h3'; -import { H4 } from './h4'; -import { H5 } from './h5'; -import { H6 } from './h6'; -import { HR } from './hr'; -import { IMG } from './img'; -import { INPUT } from './input'; -import { LI } from './li'; -import { LINK } from './link'; -import { MENU } from './menu'; -import { MENUITEM } from './menuitem'; -import { METER } from './meter'; -import { NAV } from './nav'; -import { OL } from './ol'; -import { OPTION } from './option'; -import { OUTPUT } from './output'; -import { PROGRESS } from './progress'; -import { SECTION } from './section'; -import { SELECT } from './select'; -import { TBODY } from './tbody'; -import { TEXTAREA } from './textarea'; -import { TFOOT } from './tfoot'; -import { THEAD } from './thead'; -import { UL } from './ul'; +import { a } from './a'; +import { area } from './area'; +import { article } from './article'; +import { aside } from './aside'; +import { body } from './body'; +import { button } from './button'; +import { datalist } from './datalist'; +import { dd } from './dd'; +import { details } from './details'; +import { dialog } from './dialog'; +import { dl } from './dl'; +import { dt } from './dt'; +import { footer } from './footer'; +import { form } from './form'; +import { h1 } from './h1'; +import { h2 } from './h2'; +import { h3 } from './h3'; +import { h4 } from './h4'; +import { h5 } from './h5'; +import { h6 } from './h6'; +import { header } from './header'; +import { hr } from './hr'; +import { img } from './img'; +import { input } from './input'; +import { li } from './li'; +import { link } from './link'; +import { main } from './main'; +import { math } from './math'; +import { menu } from './menu'; +import { menuitem } from './menuitem'; +import { meter } from './meter'; +import { nav } from './nav'; +import { ol } from './ol'; +import { optgroup } from './optgroup'; +import { option } from './option'; +import { output } from './output'; +import { progress } from './progress'; +import { section } from './section'; +import { select } from './select'; +import { summary } from './summary'; +import { table } from './table'; +import { tbody } from './tbody'; +import { td } from './td'; +import { textarea } from './textarea'; +import { tfoot } from './tfoot'; +import { th } from './th'; +import { thead } from './thead'; +import { tr } from './tr'; +import { ul } from './ul'; -/** - * Export function for getting implicit role based on tag name. - */ export { -A, -AREA, -ARTICLE, -ASIDE, -BODY, -BUTTON, -DATALIST, -DETAILS, -DIALOG, -DL, -FORM, -H1, -H2, -H3, -H4, -H5, -H6, -HR, -IMG, -INPUT, -LI, -LINK, -MENU, -MENUITEM, -METER, -NAV, -OL, -OPTION, -OUTPUT, -PROGRESS, -SECTION, -SELECT, -TBODY, -TEXTAREA, -TFOOT, -THEAD, -UL +a, +area, +article, +aside, +body, +button, +datalist, +dd, +details, +dialog, +dl, +dt, +footer, +form, +h1, +h2, +h3, +h4, +h5, +h6, +header, +hr, +img, +input, +li, +link, +main, +math, +menu, +menuitem, +meter, +nav, +ol, +optgroup, +option, +output, +progress, +section, +select, +summary, +table, +tbody, +td, +textarea, +tfoot, +th, +thead, +tr, +ul }; diff --git a/src/utils/implicitRoles/input.ts b/src/utils/implicitRoles/input.ts index 3b0ab27a3..7c377f405 100644 --- a/src/utils/implicitRoles/input.ts +++ b/src/utils/implicitRoles/input.ts @@ -2,17 +2,19 @@ import * as ts from 'typescript'; import { getJsxAttributesFromJsxElement, getStringLiteral } from '../JsxAttribute'; const typeString: string = 'type'; +const listString: string = 'list'; /** * @Returns the implicit role for an input tag. */ function getImplicitRoleForInput(node: ts.Node): string { - const typeProp: ts.JsxAttribute = getJsxAttributesFromJsxElement(node)[typeString]; + const attributes: { [propName: string]: ts.JsxAttribute } = getJsxAttributesFromJsxElement(node); + const typeAttribute: ts.JsxAttribute = attributes[typeString]; - if (typeProp) { - const value: string = getStringLiteral(typeProp) || ''; + if (typeAttribute) { + const value: string = getStringLiteral(typeAttribute) || ''; - /* tslint:disable:no-switch-case-fall-through */ + // tslint:disable:no-switch-case-fall-through switch (value.toUpperCase()) { case 'BUTTON': case 'IMAGE': @@ -21,22 +23,37 @@ function getImplicitRoleForInput(node: ts.Node): string { return 'button'; case 'CHECKBOX': return 'checkbox'; + case 'NUMBER': + return 'spinbutton'; + case 'PASSWORD': + return 'textbox'; case 'RADIO': return 'radio'; case 'RANGE': return 'slider'; + case 'SEARCH': + return attributes[listString] ? 'combobox' : 'searchbox'; case 'EMAIL': - case 'PASSWORD': - case 'SEARCH': // with [list] selector it's combobox - case 'TEL': // with [list] selector it's combobox - case 'URL': // with [list] selector it's combobox + case 'TEL': + case 'URL': + case 'TEXT': + return attributes[listString] ? 'combobox' : 'textbox'; + case 'COLOR': + case 'DATE': + case 'DATETIME': + case 'FILE': + case 'HIDDEN': + case 'MONTH': + case 'TIME': + case 'WEEK': + return undefined; default: return 'textbox'; } } - /* tslint:enable:no-switch-case-fall-through */ + // tslint:enable:no-switch-case-fall-through return 'textbox'; } -export { getImplicitRoleForInput as INPUT }; +export { getImplicitRoleForInput as input }; diff --git a/src/utils/implicitRoles/li.ts b/src/utils/implicitRoles/li.ts index 50b41b7e2..2294b9ed9 100644 --- a/src/utils/implicitRoles/li.ts +++ b/src/utils/implicitRoles/li.ts @@ -1,8 +1,17 @@ +import * as ts from 'typescript'; +import { isJsxElement } from '../TypeGuard'; + /** * @Returns the implicit role for an li tag. */ -function getImplicitRoleForLi(): string { - return 'listitem'; +function getImplicitRoleForLi(node: ts.Node): string { + const parentNode: ts.Node = node.parent; + let parentTagName: string; + + if (isJsxElement(parentNode)) { + parentTagName = parentNode.openingElement.tagName.getText(); + } + return (parentTagName === 'ol' || parentTagName === 'ul') ? 'listitem' : undefined; } -export { getImplicitRoleForLi as LI }; +export { getImplicitRoleForLi as li }; diff --git a/src/utils/implicitRoles/link.ts b/src/utils/implicitRoles/link.ts index fd3a675f9..286424ab2 100644 --- a/src/utils/implicitRoles/link.ts +++ b/src/utils/implicitRoles/link.ts @@ -10,4 +10,4 @@ function getImplicitRoleForLink(node: ts.Node): string { return getJsxAttributesFromJsxElement(node)[hrefString] ? 'link' : undefined; } -export { getImplicitRoleForLink as LINK }; +export { getImplicitRoleForLink as link }; diff --git a/src/utils/implicitRoles/main.ts b/src/utils/implicitRoles/main.ts new file mode 100644 index 000000000..89d015ceb --- /dev/null +++ b/src/utils/implicitRoles/main.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a main tag. + */ +function getImplicitRoleForMain(): string { + return 'main'; +} + +export { getImplicitRoleForMain as main }; diff --git a/src/utils/implicitRoles/math.ts b/src/utils/implicitRoles/math.ts new file mode 100644 index 000000000..5035ff05b --- /dev/null +++ b/src/utils/implicitRoles/math.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a math tag. + */ +function getImplicitRoleForMath(): string { + return 'math'; +} + +export { getImplicitRoleForMath as math }; diff --git a/src/utils/implicitRoles/menu.ts b/src/utils/implicitRoles/menu.ts index d38d38354..a36d55baf 100644 --- a/src/utils/implicitRoles/menu.ts +++ b/src/utils/implicitRoles/menu.ts @@ -7,10 +7,10 @@ const typeString: string = 'type'; * @Returns the implicit role for a menu tag. */ function getImplicitRoleForMenu(node: ts.Node): string { - const typeProp: ts.JsxAttribute = getJsxAttributesFromJsxElement(node)[typeString]; + const typeAttribute: ts.JsxAttribute = getJsxAttributesFromJsxElement(node)[typeString]; - if (typeProp) { - const value: string = getStringLiteral(typeProp) || undefined; + if (typeAttribute) { + const value: string = getStringLiteral(typeAttribute) || undefined; return (value && value.toUpperCase() === 'TOOLBAR') ? 'toolbar' : undefined; } @@ -18,4 +18,4 @@ function getImplicitRoleForMenu(node: ts.Node): string { return undefined; } -export { getImplicitRoleForMenu as MENU }; +export { getImplicitRoleForMenu as menu }; diff --git a/src/utils/implicitRoles/menuitem.ts b/src/utils/implicitRoles/menuitem.ts index dab772bd4..ea5369680 100644 --- a/src/utils/implicitRoles/menuitem.ts +++ b/src/utils/implicitRoles/menuitem.ts @@ -7,10 +7,10 @@ const typeString: string = 'type'; * @Returns the implicit role for a menuitem tag. */ function getImplicitRoleForMenuitem(node: ts.Node): string { - const typeProp: ts.JsxAttribute = getJsxAttributesFromJsxElement(node)[typeString]; + const type: ts.JsxAttribute = getJsxAttributesFromJsxElement(node)[typeString]; - if (typeProp) { - const value: string = getStringLiteral(typeProp) || ''; + if (type) { + const value: string = getStringLiteral(type) || ''; switch (value.toUpperCase()) { case 'COMMAND': @@ -27,4 +27,4 @@ function getImplicitRoleForMenuitem(node: ts.Node): string { return undefined; } -export { getImplicitRoleForMenuitem as MENUITEM }; +export { getImplicitRoleForMenuitem as menuitem }; diff --git a/src/utils/implicitRoles/meter.ts b/src/utils/implicitRoles/meter.ts index 298ab2d88..a79abd958 100644 --- a/src/utils/implicitRoles/meter.ts +++ b/src/utils/implicitRoles/meter.ts @@ -5,4 +5,4 @@ function getImplicitRoleForMeter(): string { return 'progressbar'; } -export { getImplicitRoleForMeter as METER }; +export { getImplicitRoleForMeter as meter }; diff --git a/src/utils/implicitRoles/nav.ts b/src/utils/implicitRoles/nav.ts index 3b9aeaca9..04ecac470 100644 --- a/src/utils/implicitRoles/nav.ts +++ b/src/utils/implicitRoles/nav.ts @@ -5,4 +5,4 @@ function getImplicitRoleForNav(): string { return 'navigation'; } -export { getImplicitRoleForNav as NAV }; +export { getImplicitRoleForNav as nav }; diff --git a/src/utils/implicitRoles/ol.ts b/src/utils/implicitRoles/ol.ts index 9730a3d45..ade126008 100644 --- a/src/utils/implicitRoles/ol.ts +++ b/src/utils/implicitRoles/ol.ts @@ -5,4 +5,4 @@ function getImplicitRoleForOl(): string { return 'list'; } -export { getImplicitRoleForOl as OL }; +export { getImplicitRoleForOl as ol }; diff --git a/src/utils/implicitRoles/optgroup.ts b/src/utils/implicitRoles/optgroup.ts new file mode 100644 index 000000000..2daf61aba --- /dev/null +++ b/src/utils/implicitRoles/optgroup.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a optgroup tag. + */ +function getImplicitRoleForOptgroup(): string { + return 'group'; +} + +export { getImplicitRoleForOptgroup as optgroup }; diff --git a/src/utils/implicitRoles/option.ts b/src/utils/implicitRoles/option.ts index db841ac5b..c11a89ccf 100644 --- a/src/utils/implicitRoles/option.ts +++ b/src/utils/implicitRoles/option.ts @@ -5,4 +5,4 @@ function getImplicitRoleForOption(): string { return 'option'; } -export { getImplicitRoleForOption as OPTION }; +export { getImplicitRoleForOption as option }; diff --git a/src/utils/implicitRoles/output.ts b/src/utils/implicitRoles/output.ts index 8de675119..a48e85ad5 100644 --- a/src/utils/implicitRoles/output.ts +++ b/src/utils/implicitRoles/output.ts @@ -5,4 +5,4 @@ function getImplicitRoleForOutput(): string { return 'status'; } -export { getImplicitRoleForOutput as OUTPUT }; +export { getImplicitRoleForOutput as output }; diff --git a/src/utils/implicitRoles/progress.ts b/src/utils/implicitRoles/progress.ts index 9b905a258..2e29308ba 100644 --- a/src/utils/implicitRoles/progress.ts +++ b/src/utils/implicitRoles/progress.ts @@ -5,4 +5,4 @@ function getImplicitRoleForProgress(): string { return 'progressbar'; } -export { getImplicitRoleForProgress as PROGRESS }; +export { getImplicitRoleForProgress as progress }; diff --git a/src/utils/implicitRoles/section.ts b/src/utils/implicitRoles/section.ts index 31096462e..cee94bec3 100644 --- a/src/utils/implicitRoles/section.ts +++ b/src/utils/implicitRoles/section.ts @@ -5,4 +5,4 @@ function getImplicitRoleForSection(): string { return 'region'; } -export { getImplicitRoleForSection as SECTION }; +export { getImplicitRoleForSection as section }; diff --git a/src/utils/implicitRoles/select.ts b/src/utils/implicitRoles/select.ts index 707b1faae..eb12cff2f 100644 --- a/src/utils/implicitRoles/select.ts +++ b/src/utils/implicitRoles/select.ts @@ -5,4 +5,4 @@ function getImplicitRoleForSelect(): string { return 'listbox'; } -export { getImplicitRoleForSelect as SELECT }; +export { getImplicitRoleForSelect as select }; diff --git a/src/utils/implicitRoles/summary.ts b/src/utils/implicitRoles/summary.ts new file mode 100644 index 000000000..e9e41c2ec --- /dev/null +++ b/src/utils/implicitRoles/summary.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a summary tag. + */ +function getImplicitRoleForSummary(): string { + return 'button'; +} + +export { getImplicitRoleForSummary as summary }; diff --git a/src/utils/implicitRoles/table.ts b/src/utils/implicitRoles/table.ts new file mode 100644 index 000000000..4034c9781 --- /dev/null +++ b/src/utils/implicitRoles/table.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a table tag. + */ +function getImplicitRoleForTable(): string { + return 'table'; +} + +export { getImplicitRoleForTable as table }; diff --git a/src/utils/implicitRoles/tbody.ts b/src/utils/implicitRoles/tbody.ts index 8955fadd2..46d8de862 100644 --- a/src/utils/implicitRoles/tbody.ts +++ b/src/utils/implicitRoles/tbody.ts @@ -5,4 +5,4 @@ function getImplicitRoleForTbody(): string { return 'rowgroup'; } -export { getImplicitRoleForTbody as TBODY }; +export { getImplicitRoleForTbody as tbody }; diff --git a/src/utils/implicitRoles/td.ts b/src/utils/implicitRoles/td.ts new file mode 100644 index 000000000..e2552ba90 --- /dev/null +++ b/src/utils/implicitRoles/td.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a td tag. + */ +function getImplicitRoleForTd(): string { + return 'cell'; +} + +export { getImplicitRoleForTd as td }; diff --git a/src/utils/implicitRoles/textarea.ts b/src/utils/implicitRoles/textarea.ts index 8a0e217d8..b8481ca26 100644 --- a/src/utils/implicitRoles/textarea.ts +++ b/src/utils/implicitRoles/textarea.ts @@ -5,4 +5,4 @@ function getImplicitRoleForTextarea(): string { return 'textbox'; } -export { getImplicitRoleForTextarea as TEXTAREA }; +export { getImplicitRoleForTextarea as textarea }; diff --git a/src/utils/implicitRoles/tfoot.ts b/src/utils/implicitRoles/tfoot.ts index 61ba2626d..fbc6b4f9e 100644 --- a/src/utils/implicitRoles/tfoot.ts +++ b/src/utils/implicitRoles/tfoot.ts @@ -5,4 +5,4 @@ function getImplicitRoleForTfoot(): string { return 'rowgroup'; } -export { getImplicitRoleForTfoot as TFOOT }; +export { getImplicitRoleForTfoot as tfoot }; diff --git a/src/utils/implicitRoles/th.ts b/src/utils/implicitRoles/th.ts new file mode 100644 index 000000000..7978a09c6 --- /dev/null +++ b/src/utils/implicitRoles/th.ts @@ -0,0 +1,9 @@ +/** + * @Returns the implicit role for a th tag. + * The implicit role is columnheader or rowheader, the func only return columnheader. + */ +function getImplicitRoleForTh(): string { + return 'columnheader'; +} + +export { getImplicitRoleForTh as th }; diff --git a/src/utils/implicitRoles/thead.ts b/src/utils/implicitRoles/thead.ts index 8c30f445f..52fdd9d97 100644 --- a/src/utils/implicitRoles/thead.ts +++ b/src/utils/implicitRoles/thead.ts @@ -5,4 +5,4 @@ function getImplicitRoleForThead(): string { return 'rowgroup'; } -export { getImplicitRoleForThead as THEAD }; +export { getImplicitRoleForThead as thead }; diff --git a/src/utils/implicitRoles/tr.ts b/src/utils/implicitRoles/tr.ts new file mode 100644 index 000000000..48265b130 --- /dev/null +++ b/src/utils/implicitRoles/tr.ts @@ -0,0 +1,8 @@ +/** + * @Returns the implicit role for a tr tag. + */ +function getImplicitRoleForTr(): string { + return 'row'; +} + +export { getImplicitRoleForTr as tr }; diff --git a/src/utils/implicitRoles/ul.ts b/src/utils/implicitRoles/ul.ts index 07e876a67..913bf6142 100644 --- a/src/utils/implicitRoles/ul.ts +++ b/src/utils/implicitRoles/ul.ts @@ -5,4 +5,4 @@ function getImplicitRoleForUl(): string { return 'list'; } -export { getImplicitRoleForUl as UL }; +export { getImplicitRoleForUl as ul };