UNPKG

5.69 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 FAILURE_MISSING_LANG = 'An html element is missing the lang attribute';
20var FAILURE_WRONG_LANG_CODE = 'Lang attribute does not have a valid value. Found: ';
21var LANGUAGE_CODES = [
22 'ab',
23 'aa',
24 'af',
25 'sq',
26 'am',
27 'ar',
28 'an',
29 'hy',
30 'as',
31 'ay',
32 'az',
33 'ba',
34 'eu',
35 'bn',
36 'dz',
37 'bh',
38 'bi',
39 'br',
40 'bg',
41 'my',
42 'be',
43 'km',
44 'ca',
45 'zh',
46 'zh-Hans',
47 'zh-Hant',
48 'co',
49 'hr',
50 'cs',
51 'da',
52 'nl',
53 'en',
54 'eo',
55 'et',
56 'fo',
57 'fa',
58 'fj',
59 'fi',
60 'fr',
61 'fy',
62 'gl',
63 'gd',
64 'gv',
65 'ka',
66 'de',
67 'el',
68 'kl',
69 'gn',
70 'gu',
71 'ht',
72 'ha',
73 'he',
74 'iw',
75 'hi',
76 'hu',
77 'is',
78 'io',
79 'id',
80 'in',
81 'ia',
82 'ie',
83 'iu',
84 'ik',
85 'ga',
86 'it',
87 'ja',
88 'jv',
89 'kn',
90 'ks',
91 'kk',
92 'rw',
93 'ky',
94 'rn',
95 'ko',
96 'ku',
97 'lo',
98 'la',
99 'lv',
100 'li',
101 'ln',
102 'lt',
103 'mk',
104 'mg',
105 'ms',
106 'ml',
107 'mt',
108 'mi',
109 'mr',
110 'mo',
111 'mn',
112 'na',
113 'ne',
114 'no',
115 'oc',
116 'or',
117 'om',
118 'ps',
119 'pl',
120 'pt',
121 'pa',
122 'qu',
123 'rm',
124 'ro',
125 'ru',
126 'sm',
127 'sg',
128 'sa',
129 'sr',
130 'sh',
131 'st',
132 'tn',
133 'sn',
134 'ii',
135 'sd',
136 'si',
137 'ss',
138 'sk',
139 'sl',
140 'so',
141 'es',
142 'su',
143 'sw',
144 'sv',
145 'tl',
146 'tg',
147 'ta',
148 'tt',
149 'te',
150 'th',
151 'bo',
152 'ti',
153 'to',
154 'ts',
155 'tr',
156 'tk',
157 'tw',
158 'ug',
159 'uk',
160 'ur',
161 'uz',
162 'vi',
163 'vo',
164 'wa',
165 'cy',
166 'wo',
167 'xh',
168 'yi',
169 'ji',
170 'yo',
171 'zu'
172];
173var Rule = (function (_super) {
174 __extends(Rule, _super);
175 function Rule() {
176 return _super !== null && _super.apply(this, arguments) || this;
177 }
178 Rule.prototype.apply = function (sourceFile) {
179 if (sourceFile.languageVariant === ts.LanguageVariant.JSX) {
180 return this.applyWithFunction(sourceFile, walk);
181 }
182 else {
183 return [];
184 }
185 };
186 Rule.metadata = {
187 ruleName: 'react-a11y-lang',
188 type: 'functionality',
189 description: 'For accessibility of your website, html elements must have a valid lang attribute.',
190 rationale: "References:\n <ul>\n <li><a href=\"https://www.w3.org/TR/WCAG20-TECHS/H58.html\">\n H58: Using language attributes to identify changes in the human language\n </a></li>\n <li><a href=\"https://dequeuniversity.com/rules/axe/1.1/valid-lang\">\n lang attribute must have a valid value\n </a></li>\n <li><a href=\"https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes\">\n List of ISO 639-1 codes\n </a></li>\n </ul>",
191 options: null,
192 optionsDescription: '',
193 typescriptOnly: true,
194 issueClass: 'Non-SDL',
195 issueType: 'Warning',
196 severity: 'Low',
197 level: 'Opportunity for Excellence',
198 group: 'Accessibility'
199 };
200 return Rule;
201}(Lint.Rules.AbstractRule));
202exports.Rule = Rule;
203function walk(ctx) {
204 function validateOpeningElement(parent, openingElement) {
205 if (openingElement.tagName.getText() === 'html') {
206 var attributes = openingElement.attributes;
207 var langFound_1 = false;
208 attributes.properties.forEach(function (attribute) {
209 if (attribute.kind === ts.SyntaxKind.JsxAttribute) {
210 if (attribute.name.getText() === 'lang') {
211 langFound_1 = true;
212 if (attribute.initializer !== undefined && attribute.initializer.kind === ts.SyntaxKind.StringLiteral) {
213 var langText = attribute.initializer.text;
214 if (LANGUAGE_CODES.indexOf(langText) === -1) {
215 ctx.addFailureAt(parent.getStart(), parent.getWidth(), FAILURE_WRONG_LANG_CODE + langText);
216 }
217 }
218 }
219 }
220 });
221 if (!langFound_1) {
222 ctx.addFailureAt(parent.getStart(), parent.getWidth(), FAILURE_MISSING_LANG);
223 }
224 }
225 }
226 function cb(node) {
227 if (tsutils.isJsxSelfClosingElement(node)) {
228 validateOpeningElement(node, node);
229 }
230 else if (tsutils.isJsxElement(node)) {
231 validateOpeningElement(node, node.openingElement);
232 }
233 return ts.forEachChild(node, cb);
234 }
235 return ts.forEachChild(ctx.sourceFile, cb);
236}
237//# sourceMappingURL=reactA11yLangRule.js.map
\No newline at end of file