UNPKG

6.01 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return function (d, b) {
7 extendStatics(d, b);
8 function __() { this.constructor = d; }
9 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10 };
11})();
12Object.defineProperty(exports, "__esModule", { value: true });
13var ts = require("typescript");
14var Lint = require("tslint");
15var getImplicitRole_1 = require("./utils/getImplicitRole");
16var JsxAttribute_1 = require("./utils/JsxAttribute");
17var ROLE_SCHEMA = require('./utils/attributes/roleSchema.json');
18var ARIA_ATTRIBUTES = require('./utils/attributes/ariaSchema.json');
19var ROLES = ROLE_SCHEMA.roles;
20var ROLE_STRING = 'role';
21function getFailureStringForNotImplicitRole(roleNamesInElement, invalidPropNames) {
22 return "Attribute(s) " + invalidPropNames.join(', ') + " are not supported by role(s) " + roleNamesInElement.join(', ') + ". You are using incorrect role or incorrect aria-* attribute";
23}
24exports.getFailureStringForNotImplicitRole = getFailureStringForNotImplicitRole;
25function getFailureStringForImplicitRole(tagName, roleName, invalidPropNames) {
26 return "Attribute(s) " + invalidPropNames.join(', ') + " not supported by role " + roleName + " which is implicitly set by the HTML tag " + tagName + ".";
27}
28exports.getFailureStringForImplicitRole = getFailureStringForImplicitRole;
29function getFailureStringForNoRole(tagName, invalidPropNames) {
30 return "Attribute(s) " + invalidPropNames + " are not supported by no corresponding role. There is no corresponding role for the HTML tag " + tagName + ". A reference about no corresponding role: https://www.w3.org/TR/html-aria/#dfn-no-corresponding-role.";
31}
32exports.getFailureStringForNoRole = getFailureStringForNoRole;
33var Rule = (function (_super) {
34 __extends(Rule, _super);
35 function Rule() {
36 return _super !== null && _super.apply(this, arguments) || this;
37 }
38 Rule.prototype.apply = function (sourceFile) {
39 return sourceFile.languageVariant === ts.LanguageVariant.JSX
40 ? this.applyWithWalker(new A11yRoleSupportsAriaPropsWalker(sourceFile, this.getOptions()))
41 : [];
42 };
43 Rule.metadata = {
44 ruleName: 'react-a11y-role-supports-aria-props',
45 type: 'maintainability',
46 description: 'Enforce that elements with explicit or implicit roles defined contain ' +
47 'only `aria-*` properties supported by that `role`.',
48 options: null,
49 optionsDescription: '',
50 typescriptOnly: true,
51 issueClass: 'Non-SDL',
52 issueType: 'Warning',
53 severity: 'Important',
54 level: 'Opportunity for Excellence',
55 group: 'Accessibility'
56 };
57 return Rule;
58}(Lint.Rules.AbstractRule));
59exports.Rule = Rule;
60var A11yRoleSupportsAriaPropsWalker = (function (_super) {
61 __extends(A11yRoleSupportsAriaPropsWalker, _super);
62 function A11yRoleSupportsAriaPropsWalker() {
63 return _super !== null && _super.apply(this, arguments) || this;
64 }
65 A11yRoleSupportsAriaPropsWalker.prototype.visitJsxElement = function (node) {
66 this.checkJsxElement(node.openingElement);
67 _super.prototype.visitJsxElement.call(this, node);
68 };
69 A11yRoleSupportsAriaPropsWalker.prototype.visitJsxSelfClosingElement = function (node) {
70 this.checkJsxElement(node);
71 _super.prototype.visitJsxSelfClosingElement.call(this, node);
72 };
73 A11yRoleSupportsAriaPropsWalker.prototype.checkJsxElement = function (node) {
74 var attributesInElement = JsxAttribute_1.getJsxAttributesFromJsxElement(node);
75 var roleProp = attributesInElement[ROLE_STRING];
76 var roleValue;
77 if (node.tagName.getText().match(/^[A-Z].*/)) {
78 return;
79 }
80 if (roleProp != null) {
81 roleValue = JsxAttribute_1.getStringLiteral(roleProp);
82 if (!JsxAttribute_1.isEmpty(roleProp) && roleValue == null) {
83 return;
84 }
85 }
86 else {
87 roleValue = getImplicitRole_1.getImplicitRole(node);
88 }
89 var isImplicitRole = !roleProp && !!roleValue;
90 var normalizedRoles = (roleValue || '').toLowerCase().split(' ')
91 .filter(function (role) { return !!ROLES[role]; });
92 var supportedAttributeNames = ROLE_SCHEMA.globalSupportedProps;
93 normalizedRoles.forEach(function (role) {
94 supportedAttributeNames = supportedAttributeNames.concat(ROLES[role].additionalSupportedProps || []);
95 });
96 var attributeNamesInElement = Object.keys(attributesInElement)
97 .filter(function (attributeName) { return !!ARIA_ATTRIBUTES[attributeName.toLowerCase()]; });
98 var invalidAttributeNamesInElement = attributeNamesInElement
99 .filter(function (attributeName) { return supportedAttributeNames.indexOf(attributeName) === -1; });
100 var failureString;
101 if (normalizedRoles.length === 0) {
102 failureString = getFailureStringForNoRole(node.tagName.getText(), invalidAttributeNamesInElement);
103 }
104 else if (isImplicitRole) {
105 failureString = getFailureStringForImplicitRole(node.tagName.getText(), normalizedRoles[0], invalidAttributeNamesInElement);
106 }
107 else {
108 failureString = getFailureStringForNotImplicitRole(normalizedRoles, invalidAttributeNamesInElement);
109 }
110 if (invalidAttributeNamesInElement.length > 0) {
111 this.addFailureAt(node.getStart(), node.getWidth(), failureString);
112 }
113 };
114 return A11yRoleSupportsAriaPropsWalker;
115}(Lint.RuleWalker));
116//# sourceMappingURL=reactA11yRoleSupportsAriaPropsRule.js.map
\No newline at end of file