From ce88b9aa9d61c7ad5de61a4c2c5202df4f21b901 Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Sun, 17 Jul 2022 23:12:30 +0800 Subject: [PATCH] slight refactor to use existing utils --- src/compiler/compile/nodes/Element.ts | 18 ++----- src/compiler/compile/utils/a11y.ts | 4 ++ .../compile/utils/is_interactive_element.ts | 48 ------------------- .../compile/utils/is_interactive_role.ts | 18 ------- 4 files changed, 9 insertions(+), 79 deletions(-) delete mode 100644 src/compiler/compile/utils/is_interactive_element.ts delete mode 100644 src/compiler/compile/utils/is_interactive_role.ts diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 7986a37e94..b41c5654ea 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -24,8 +24,7 @@ import { Literal } from 'estree'; import compiler_warnings from '../compiler_warnings'; import compiler_errors from '../compiler_errors'; import { ARIARoleDefintionKey, roles, aria, ARIAPropertyDefinition, ARIAProperty } from 'aria-query'; -import { is_interactive_element, is_non_interactive_roles, is_presentation_role } from '../utils/a11y'; -import { is_interactive_roles } from '../utils/is_interactive_role'; +import { is_interactive_element, is_non_interactive_roles, is_presentation_role, is_interactive_roles } from '../utils/a11y'; const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; @@ -554,21 +553,14 @@ export default class Element extends Node { }); // no-nointeractive-tabindex - if (!is_interactive_element(this)) { - const roleValue = this.attributes.find(attr => attr.name === 'role')?.get_static_value()?.toString(); - if (!roleValue || !is_interactive_roles(roleValue)) { - const _tabIndexValue = this.attributes.find(attr => attr.name === 'tabindex'); - if (_tabIndexValue) { - const tabIndexValue = Number(_tabIndexValue.get_static_value()); - if (!isNaN(tabIndexValue) && tabIndexValue >= 0) { - component.warn(this, compiler_warnings.a11y_no_nointeractive_tabindex); - } - } + if (!is_interactive_element(this.name, attribute_map) && !is_interactive_roles(attribute_map.get('role')?.get_static_value() as ARIARoleDefintionKey)) { + const tab_index = attribute_map.get('tabindex'); + if (tab_index && (!tab_index.is_static || Number(tab_index.get_static_value()) >= 0)) { + component.warn(this, compiler_warnings.a11y_no_nointeractive_tabindex); } } } - validate_special_cases() { const { component, attributes, handlers } = this; diff --git a/src/compiler/compile/utils/a11y.ts b/src/compiler/compile/utils/a11y.ts index 1e06608b54..5b300eac13 100644 --- a/src/compiler/compile/utils/a11y.ts +++ b/src/compiler/compile/utils/a11y.ts @@ -51,6 +51,10 @@ export function is_non_interactive_roles(role: ARIARoleDefintionKey) { return non_interactive_roles.has(role); } +export function is_interactive_roles(role: ARIARoleDefintionKey) { + return interactive_roles.has(role); +} + const presentation_roles = new Set(['presentation', 'none']); export function is_presentation_role(role: ARIARoleDefintionKey) { diff --git a/src/compiler/compile/utils/is_interactive_element.ts b/src/compiler/compile/utils/is_interactive_element.ts deleted file mode 100644 index acbc04108a..0000000000 --- a/src/compiler/compile/utils/is_interactive_element.ts +++ /dev/null @@ -1,48 +0,0 @@ -import Element from '../nodes/Element'; - -const interactiveInputTypes = new Set([ - 'submit', - 'reset', - 'image', - 'button', - 'radio', - 'checkbox' -]); - -export const is_interactive_element: (element: Element) => boolean = function ( - element -) { - if (element.name === 'details') { - return true; - } - - if (element.name === 'summary') { - return true; - } - - if (element.name === 'a') { - return element.attributes.some((attr) => attr.name === 'href'); - } - - if (element.name === 'button') { - return true; - } - - if (element.name === 'input') { - const typeValue = element.attributes.find((attr) => attr.name === 'type'); - if (typeValue) { - return interactiveInputTypes.has((typeValue.get_static_value() || '').toString()); - } - return false; - } - - if (element.name === 'option') { - return element.attributes.some((attr) => attr.name === 'value'); - } - - if (element.name === 'dialog') { - return true; - } - - return false; -}; diff --git a/src/compiler/compile/utils/is_interactive_role.ts b/src/compiler/compile/utils/is_interactive_role.ts deleted file mode 100644 index 52bb48a93c..0000000000 --- a/src/compiler/compile/utils/is_interactive_role.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ARIARoleDefintionKey, roles as rolesMap } from 'aria-query'; - -const roles = [...rolesMap.keys()]; -const _interactiveRoles = roles.filter( - (name) => - !rolesMap.get(name).abstract && - rolesMap.get(name).superClass.some((c) => c.includes('widget')) -); - -// 'toolbar' does not descend from widget, but it does support -// aria-activedescendant, thus in practice we treat it as a widget. -_interactiveRoles.push('toolbar'); - -const interactiveRoles = new Set(_interactiveRoles); - -export const is_interactive_roles: (role: string) => boolean = (role) => { - return interactiveRoles.has(role as ARIARoleDefintionKey); -};