UNPKG

3.56 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = function (d, b) {
4 extendStatics = Object.setPrototypeOf ||
5 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 return extendStatics(d, b);
8 }
9 return function (d, b) {
10 extendStatics(d, b);
11 function __() { this.constructor = d; }
12 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 };
14})();
15Object.defineProperty(exports, "__esModule", { value: true });
16var ts = require("typescript");
17var Lint = require("tslint");
18var tsutils = require("tsutils");
19var JsxAttribute_1 = require("./utils/JsxAttribute");
20var Rule = (function (_super) {
21 __extends(Rule, _super);
22 function Rule() {
23 return _super !== null && _super.apply(this, arguments) || this;
24 }
25 Rule.prototype.apply = function (sourceFile) {
26 return sourceFile.languageVariant === ts.LanguageVariant.JSX
27 ? this.applyWithFunction(sourceFile, walk, this.parseOptions(this.getOptions()))
28 : [];
29 };
30 Rule.prototype.parseOptions = function (options) {
31 var args = options.ruleArguments;
32 return {
33 additionalTagNames: Array.isArray(args) && args.length > 0 ? args[0] : []
34 };
35 };
36 Rule.metadata = {
37 ruleName: 'react-a11y-no-onchange',
38 type: 'functionality',
39 description: 'For accessibility of your website, enforce usage of onBlur over onChange on select menus.',
40 rationale: "References:\n <ul>\n <li><a href=\"http://cita.disability.uiuc.edu/html-best-practices/auto/onchange.php\">OnChange Event Accessibility Issues</a></li>\n <li><a href=\"https://www.w3.org/TR/WCAG10/wai-pageauth.html#gl-own-interface\">Guideline 8. Ensure direct accessibility of embedded user interfaces.</a></li>\n </ul>\n ",
41 options: 'string[]',
42 optionsDescription: 'Additional tag names to validate.',
43 optionExamples: ['true', '[true, ["Select"]]'],
44 typescriptOnly: false,
45 issueClass: 'Non-SDL',
46 issueType: 'Warning',
47 severity: 'Important',
48 level: 'Opportunity for Excellence',
49 group: 'Accessibility'
50 };
51 return Rule;
52}(Lint.Rules.AbstractRule));
53exports.Rule = Rule;
54function walk(ctx) {
55 function checkJsxOpeningElement(node) {
56 var tagName = node.tagName.getText();
57 var targetTagNames = ['select'].concat(ctx.options.additionalTagNames);
58 if (!tagName || targetTagNames.indexOf(tagName) === -1) {
59 return;
60 }
61 var attributes = JsxAttribute_1.getJsxAttributesFromJsxElement(node);
62 if (attributes.hasOwnProperty('onchange')) {
63 var errorMessage = "onChange event handler should not be used with the <" + tagName + ">. Please use onBlur instead.";
64 ctx.addFailureAt(node.getStart(), node.getWidth(), errorMessage);
65 }
66 }
67 function cb(node) {
68 if (tsutils.isJsxSelfClosingElement(node)) {
69 checkJsxOpeningElement(node);
70 }
71 else if (tsutils.isJsxElement(node)) {
72 checkJsxOpeningElement(node.openingElement);
73 }
74 return ts.forEachChild(node, cb);
75 }
76 return ts.forEachChild(ctx.sourceFile, cb);
77}
78//# sourceMappingURL=reactA11yNoOnchangeRule.js.map
\No newline at end of file