import { Rule } from "@siteimprove/alfa-act" ; import { Element , Namespace , Text } from "@siteimprove/alfa-dom" ; import { Criterion } from "@siteimprove/alfa-wcag" ; import { Page } from "@siteimprove/alfa-web" ; import { Predicate } from "@siteimprove/alfa-predicate" ; import { Refinement } from "@siteimprove/alfa-refinement" ; import { TextSpacing } from "../common/outcome/text-spacing" ; import { expectation } from "../common/expectation" ; import { hasInlineStyleProperty , isVisible , isWhitespace , isImportant , hasCascadedValueDeclaredInInlineStyleOf , isWideEnough , } from "../common/predicate" ; import { Scope } from "../tags" ; const { isElement , hasNamespace } = Element ; const { not , or , test } = Predicate ; const { and } = Refinement ; const { isText } = Text ; const property = "letter-spacing" ; export default Rule . Atomic . of < Page , Element > ( { uri : "https://alfa.siteimprove.com/rules/sia-r91" , requirements : [ Criterion . of ( "1.4.12" ) ] , tags : [ Scope . Component ] , evaluate ( { device , document } ) { return { applicability ( ) { return document . descendants ( { nested : true , flattened : true } ) . filter ( and ( isElement , and ( hasNamespace ( Namespace . HTML ) , isVisible ( device ) , hasInlineStyleProperty ( property ) ) ) ) ; } , expectations ( target ) { return { 1 : expectation ( ! isImportant ( device , property ) ( target ) , ( ) => Outcomes . NotImportant , ( ) => expectation ( target . inclusiveDescendants ( { flattened : true } ) . filter ( and ( isText , ( text ) => test ( not ( isWhitespace ) , text . data ) ) ) . every ( ( text ) => text . parent ( { flattened : true } ) . filter ( isElement ) . some ( or ( isWideEnough ( device , property , ( letterSpacing ) => ( fontSize ) => letterSpacing . value >= 0.12 * fontSize . value ) , not ( hasCascadedValueDeclaredInInlineStyleOf ( target , device , property ) ) ) ) ) , ( ) => Outcomes . WideEnough , ( ) => Outcomes . Important ) ) , } ; } , } ; } , } ) ; export const Outcomes = TextSpacing ( property ) ;