Add a11y-accessible-emoji

pull/4411/head
Lily Hoskin 6 years ago
parent 7fdae5f8a8
commit 01ff04024e
No known key found for this signature in database
GPG Key ID: BFC52E8176BA24B2

14
package-lock.json generated

@ -824,9 +824,9 @@
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"end-of-stream": {
@ -3371,6 +3371,14 @@
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
},
"dependencies": {
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
}
}
},
"string_decoder": {

@ -73,6 +73,7 @@
"code-red": "0.1.1",
"codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22",
"emoji-regex": "^8.0.0",
"eslint": "^6.3.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-svelte3": "^2.7.3",

@ -1,3 +1,4 @@
import emojiRegex from 'emoji-regex';
import { is_void } from '../../utils/names';
import Node from './shared/Node';
import Attribute from './Attribute';
@ -274,6 +275,7 @@ export default class Element extends Node {
this.validate_attributes();
this.validate_bindings();
this.validate_content();
this.validate_emoji();
this.validate_event_handlers();
}
@ -671,6 +673,36 @@ export default class Element extends Node {
}
}
validate_emoji() {
if (this.children.length === 1) {
const child = this.children[0];
if (child.type === 'Text' && emojiRegex().test(child.data)) {
const isHidden = this.attributes.find(
(attribute: Attribute) => attribute.name === 'aria-hidden'
);
if (isHidden && (isHidden.is_true || isHidden.get_static_value() === "true")) {
return; // emoji is decorative
}
const hasLabel = this.attributes.find(
(attribute: Attribute) => attribute.name === 'aria-label' || attribute.name === 'aria-labelledby'
);
const role = this.attributes.find(
(attribute: Attribute) => attribute.name === 'role'
);
const isSpan = this.name === 'span';
if (!hasLabel || role.get_static_value() !== 'img' || isSpan === false) {
this.component.warn(this, {
code: `a11y-accessible-emoji`,
message: `A11y: Emojis should be wrapped in <span>, have role="img", and have an accessible description with aria-label or aria-labelledby. `
});
}
}
}
}
validate_event_handlers() {
const { component } = this;

@ -0,0 +1,18 @@
<div />
<span />
<span>No emoji here!</span>
<span role="img" aria-label="Panda face">🐼</span>
<span role="img" aria-label="Snowman">&#9731;</span>
<span role="img" aria-labelledby="id1">🐼</span>
<span role="img" aria-labelledby="id1">&#9731;</span>
<span role="img" aria-labelledby="id1" aria-label="Snowman">&#9731;</span>
<span aria-hidden="true">🐼</span>
<span aria-hidden>🐼</span>
<div aria-hidden="true">🐼</div>
<span>🐼</span>
<span>foo🐼bar</span>
<span>foo 🐼 bar</span>
<i role="img" aria-label="Panda face">🐼</i>
<i role="img" aria-labelledby="id1">🐼</i>
<span aria-hidden="false">🐼</span>

@ -0,0 +1,92 @@
[
{
"code": "a11y-accessible-emoji",
"message": "A11y: Emojis should be wrapped in <span>, have role=\"img\", and have an accessible description with aria-label or aria-labelledby. ",
"start": {
"line": 13,
"column": 0,
"character": 424
},
"end": {
"line": 13,
"column": 15,
"character": 439
},
"pos": 424
},
{
"code": "a11y-accessible-emoji",
"message": "A11y: Emojis should be wrapped in <span>, have role=\"img\", and have an accessible description with aria-label or aria-labelledby. ",
"start": {
"line": 14,
"column": 0,
"character": 440
},
"end": {
"line": 14,
"column": 21,
"character": 461
},
"pos": 440
},
{
"code": "a11y-accessible-emoji",
"message": "A11y: Emojis should be wrapped in <span>, have role=\"img\", and have an accessible description with aria-label or aria-labelledby. ",
"start": {
"line": 15,
"column": 0,
"character": 462
},
"end": {
"line": 15,
"column": 23,
"character": 485
},
"pos": 462
},
{
"code": "a11y-accessible-emoji",
"message": "A11y: Emojis should be wrapped in <span>, have role=\"img\", and have an accessible description with aria-label or aria-labelledby. ",
"start": {
"line": 16,
"column": 0,
"character": 486
},
"end": {
"line": 16,
"column": 44,
"character": 530
},
"pos": 486
},
{
"code": "a11y-accessible-emoji",
"message": "A11y: Emojis should be wrapped in <span>, have role=\"img\", and have an accessible description with aria-label or aria-labelledby. ",
"start": {
"line": 17,
"column": 0,
"character": 531
},
"end": {
"line": 17,
"column": 42,
"character": 573
},
"pos": 531
},
{
"code": "a11y-accessible-emoji",
"message": "A11y: Emojis should be wrapped in <span>, have role=\"img\", and have an accessible description with aria-label or aria-labelledby. ",
"start": {
"line": 18,
"column": 0,
"character": 574
},
"end": {
"line": 18,
"column": 35,
"character": 609
},
"pos": 574
}
]
Loading…
Cancel
Save