Skip to content

Commit

Permalink
feat(preset-wcag): Add page-has-valid-lang rule
Browse files Browse the repository at this point in the history
  • Loading branch information
wadackel committed Nov 30, 2020
1 parent 631ea65 commit 8ee766c
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/acot-preset-wcag/docs/rules/img-has-name.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# img-has-name

img element or img role MUST has name.
The `img` element or img role MUST has name.

> All non-text content that is presented to the user has a text alternative that serves the equivalent purpose
Expand Down
31 changes: 31 additions & 0 deletions packages/acot-preset-wcag/docs/rules/page-has-valid-lang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# page-has-valid-lang

The `html` element MUST has a valid lang attribute.

> The objective of this technique is to identify the default language of a document by providing the lang and/or xml:lang attribute on the html element.
[H57: Using language attributes on the html element | Techniques for WCAG 2.0](https://www.w3.org/TR/WCAG20-TECHS/H57.html)

## :white_check_mark: Correct

```html acot-template:templates/empty.html
<html lang="en-GB"></html>
```

## :warning: Incorrect

```html acot-template:templates/empty.html
<html lang="en-FOO"></html>
```

```html acot-template:templates/empty.html
<!-- missing html element -->
```

```html acot-template:templates/empty.html
<html></html>
```

```html acot-template:templates/empty.html
<html lang=""></html>
```
2 changes: 2 additions & 0 deletions packages/acot-preset-wcag/docs/rules/templates/empty.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
{{{ html }}}
6 changes: 5 additions & 1 deletion packages/acot-preset-wcag/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
},
"dependencies": {
"@acot/cli": "0.0.2-canary.7",
"@acot/core": "0.0.2-canary.7"
"@acot/core": "0.0.2-canary.7",
"language-tags": "^1.0.5"
},
"devDependencies": {
"@types/language-tags": "^1.0.0"
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 2 additions & 0 deletions packages/acot-preset-wcag/src/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import interactiveHasName from './interactive-has-name';
import pageHasTitle from './page-has-title';
import imgHasName from './img-has-name';
import dialogFocus from './dialog-focus';
import pageHasValidLang from './page-has-valid-lang';

export const rules: RuleRecord = {
'interactive-has-enough-size': interactiveHasEnoughSize,
'interactive-supports-focus': interactiveSupportsFocus,
'interactive-has-name': interactiveHasName,
'page-has-title': pageHasTitle,
'page-has-valid-lang': pageHasValidLang,
'img-has-name': imgHasName,
'dialog-focus': dialogFocus,
};
47 changes: 47 additions & 0 deletions packages/acot-preset-wcag/src/rules/page-has-valid-lang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { ElementHandle } from 'puppeteer-core';
import { createRule } from '@acot/core';
import tags from 'language-tags';

type Options = {};

export default createRule<Options>({
type: 'global',
immutable: true,
meta: {
recommended: true,
},

test: async (context) => {
const html: ElementHandle<HTMLElement> | null = await context.page.$(
'html',
);

if (html == null) {
return await context.report({
message: 'html element MUST be exists.',
});
}

const lang = await html.evaluate(
(el) => el.getAttribute('lang') || el.getAttribute('xml:lang'),
);

if (!lang) {
return await context.report({
node: html,
message:
'html element MUST have the "lang" or "xml:lang" attribute specified.',
});
}

const valid = tags.check(lang);
context.debug('lang="%s"', lang, valid);

if (!valid) {
return await context.report({
node: html,
message: `"${lang}" lang attribute specified for the html element is invalid. The value of the lang attribute MUST be conforms to BCP 47: Tags for the Identification of Languages or its successor.`,
});
}
},
});
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3049,6 +3049,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=

"@types/language-tags@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/language-tags/-/language-tags-1.0.0.tgz#81829b5c50e324c0e6637264cd0d2754e7d7ba1a"
integrity sha512-pSCb1l71akSb46t3+kKyjEEe1Gb1NxxWfVeUacXwpYc4KGKF1+QnECQ26cGwVCTp9lqKAmNNN2d0FYMO2LV03Q==

"@types/listr@^0.14.2":
version "0.14.2"
resolved "https://registry.yarnpkg.com/@types/listr/-/listr-0.14.2.tgz#2e5f80fbc3ca8dceb9940ce9bf8e3113ab452545"
Expand Down Expand Up @@ -10258,6 +10263,18 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==

language-subtag-registry@~0.3.2:
version "0.3.21"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a"
integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==

language-tags@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a"
integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=
dependencies:
language-subtag-registry "~0.3.2"

lazy-cache@^0.2.3:
version "0.2.7"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65"
Expand Down

0 comments on commit 8ee766c

Please sign in to comment.