From 0e97936a2cfe60e9dc7277e4f104fd9975639148 Mon Sep 17 00:00:00 2001 From: Billy Levin Date: Fri, 8 May 2020 23:17:23 +0100 Subject: [PATCH] add accessible-emoji a11y check --- src/compiler/compile/nodes/Text.ts | 32 ++++++++++++++++++ .../a11y-accessible-emoji/input.svelte | 5 +++ .../a11y-accessible-emoji/warnings.json | 33 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 test/validator/samples/a11y-accessible-emoji/input.svelte create mode 100644 test/validator/samples/a11y-accessible-emoji/warnings.json diff --git a/src/compiler/compile/nodes/Text.ts b/src/compiler/compile/nodes/Text.ts index 6b7432c22f39..be351b6f299d 100644 --- a/src/compiler/compile/nodes/Text.ts +++ b/src/compiler/compile/nodes/Text.ts @@ -24,6 +24,7 @@ export default class Text extends Node { super(component, parent, scope, info); this.data = info.data; this.synthetic = info.synthetic || false; + this.validate(); } should_skip() { @@ -42,4 +43,35 @@ export default class Text extends Node { return parent_element.namespace || elements_without_text.has(parent_element.name); } + + validate() { + const { data, component, parent } = this; + + // https://github.com/mathiasbynens/emoji-regex/blob/master/src/index.js + const emoji_regex =/<% emojiSequence %>|\p{Emoji_Presentation}|\p{Emoji}\uFE0F|\p{Emoji_Modifier_Base}/gu; + + if (!emoji_regex.test(data)) return; + + let is_accessible = false; + + if (parent.type === 'Element' && parent.name === 'span') { + const { attributes } = parent; + const role = parent.get_static_attribute_value('role'); + const aria_label_index = attributes.findIndex(attr => + attr.type === 'Attribute' && + (attr.name === 'aria-label' || attr.name === 'aria-labelledby') + ); + + if (role === 'img' && aria_label_index > -1) { + is_accessible = true; + } + } + + if (!is_accessible) { + component.warn(this, { + code: 'a11y-accessible-emoji', + message: 'A11y: emojis should be wrapped in a , with role="img", and have a description using aria-label or aria-labelledby' + }); + } + } } diff --git a/test/validator/samples/a11y-accessible-emoji/input.svelte b/test/validator/samples/a11y-accessible-emoji/input.svelte new file mode 100644 index 000000000000..1a4ab1ae5e50 --- /dev/null +++ b/test/validator/samples/a11y-accessible-emoji/input.svelte @@ -0,0 +1,5 @@ +🐼 +🐼 + + +🐼 \ No newline at end of file diff --git a/test/validator/samples/a11y-accessible-emoji/warnings.json b/test/validator/samples/a11y-accessible-emoji/warnings.json new file mode 100644 index 000000000000..71077cca7d71 --- /dev/null +++ b/test/validator/samples/a11y-accessible-emoji/warnings.json @@ -0,0 +1,33 @@ +[ + { + "code": "a11y-accessible-emoji", + "message": "A11y: emojis should be wrapped in a , with role=\"img\", and have a description using aria-label or aria-labelledby", + "start": { + "line": 1, + "column": 6, + "character": 6 + }, + "end": { + "line": 1, + "column": 8, + "character": 8 + }, + "pos": 6 + }, + + { + "code": "a11y-accessible-emoji", + "message": "A11y: emojis should be wrapped in a , with role=\"img\", and have a description using aria-label or aria-labelledby", + "start": { + "line": 2, + "column": 33, + "character": 49 + }, + "end": { + "line": 2, + "column": 35, + "character": 51 + }, + "pos": 49 + } +] \ No newline at end of file