pour-engine 1.31.1 → 1.31.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/config/project.config.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
// WCAG SC 1.3.5 Identify Input Purpose (Level AA)
|
|
2
2
|
// WCAG 1.3.5: autocomplete tokens from the HTML spec's input-purposes list.
|
|
3
|
+
// Membership set, so order is free: kept a-z rather than mirroring the spec
|
|
4
|
+
// table's own sequence.
|
|
3
5
|
const TOKENS = new Set([
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'tel
|
|
13
|
-
'tel-
|
|
14
|
-
'
|
|
6
|
+
'additional-name', 'address-level1', 'address-level2', 'address-level3', 'address-level4',
|
|
7
|
+
'address-line1', 'address-line2', 'address-line3', 'bday', 'bday-day', 'bday-month',
|
|
8
|
+
'bday-year', 'billing', 'cc-additional-name', 'cc-csc', 'cc-exp', 'cc-exp-month',
|
|
9
|
+
'cc-exp-year', 'cc-family-name', 'cc-given-name', 'cc-name', 'cc-number', 'cc-type',
|
|
10
|
+
'country', 'country-name', 'current-password', 'email', 'family-name', 'fax', 'given-name',
|
|
11
|
+
'home', 'honorific-prefix', 'honorific-suffix', 'impp', 'language', 'mobile', 'name',
|
|
12
|
+
'new-password', 'nickname', 'off', 'on', 'one-time-code', 'organization',
|
|
13
|
+
'organization-title', 'pager', 'photo', 'postal-code', 'sex', 'shipping', 'street-address',
|
|
14
|
+
'tel', 'tel-area-code', 'tel-country-code', 'tel-extension', 'tel-local', 'tel-local-prefix',
|
|
15
|
+
'tel-local-suffix', 'tel-national', 'transaction-amount', 'transaction-currency', 'url',
|
|
16
|
+
'username', 'webauthn', 'work',
|
|
15
17
|
]);
|
|
16
18
|
|
|
17
19
|
export default {
|
|
@@ -26,20 +26,31 @@ export default {
|
|
|
26
26
|
if (ownText(parent).replace(/\s+/g, '').length < 10) return { status: 'pass' };
|
|
27
27
|
|
|
28
28
|
const style = getComputedStyle(element);
|
|
29
|
-
if ((style.textDecorationLine ?? style.textDecoration ?? '').includes('underline')) return { status: 'pass' };
|
|
30
|
-
// Underline substitutes count as non-colour cues too: border-bottom
|
|
31
|
-
// "underlines", box-shadow underlines, and background chips/pills all
|
|
32
|
-
// mark the link by shape, not colour alone.
|
|
33
|
-
if (parseFloat(style.borderBottomWidth) > 0 && style.borderBottomStyle !== 'none') return { status: 'pass' };
|
|
34
|
-
if (style.boxShadow && style.boxShadow !== 'none') return { status: 'pass' };
|
|
35
|
-
const ownBackground = parseColor(style.backgroundColor);
|
|
36
|
-
if (ownBackground && ownBackground.a > 0) return { status: 'pass' };
|
|
37
|
-
if (style.backgroundImage !== 'none') return { status: 'pass' }; // gradient/image underline technique
|
|
38
|
-
|
|
39
|
-
// A clear weight difference is a non-colour distinction too.
|
|
40
29
|
const parentStyle = getComputedStyle(parent);
|
|
41
30
|
const weight = (s) => parseInt(s.fontWeight, 10) || 400;
|
|
42
|
-
|
|
31
|
+
// A cue counts wherever it is painted: sites routinely reset
|
|
32
|
+
// text-decoration on the anchor and underline (or embolden) an inner
|
|
33
|
+
// span that carries the text, so every visible text-bearing element in
|
|
34
|
+
// the link vouches, not just the anchor. The >1px rect floor keeps
|
|
35
|
+
// 1×1 sr-only clip spans from vouching for a cue nobody can see.
|
|
36
|
+
const cueBearers = [style];
|
|
37
|
+
for (const el of element.querySelectorAll('*')) {
|
|
38
|
+
if (!el.textContent.trim()) continue;
|
|
39
|
+
if ([...el.getClientRects()].some((r) => r.width > 1 && r.height > 1)) cueBearers.push(getComputedStyle(el));
|
|
40
|
+
}
|
|
41
|
+
for (const s of cueBearers) {
|
|
42
|
+
if ((s.textDecorationLine ?? s.textDecoration ?? '').includes('underline')) return { status: 'pass' };
|
|
43
|
+
// Underline substitutes count as non-colour cues too: border-bottom
|
|
44
|
+
// "underlines", box-shadow underlines, and background chips/pills all
|
|
45
|
+
// mark the link by shape, not colour alone.
|
|
46
|
+
if (parseFloat(s.borderBottomWidth) > 0 && s.borderBottomStyle !== 'none') return { status: 'pass' };
|
|
47
|
+
if (s.boxShadow && s.boxShadow !== 'none') return { status: 'pass' };
|
|
48
|
+
const ownBackground = parseColor(s.backgroundColor);
|
|
49
|
+
if (ownBackground && ownBackground.a > 0) return { status: 'pass' };
|
|
50
|
+
if (s.backgroundImage !== 'none') return { status: 'pass' }; // gradient/image underline technique
|
|
51
|
+
// A clear weight difference is a non-colour distinction too.
|
|
52
|
+
if (Math.abs(weight(s) - weight(parentStyle)) >= 300) return { status: 'pass' };
|
|
53
|
+
}
|
|
43
54
|
|
|
44
55
|
const linkColor = parseColor(style.color);
|
|
45
56
|
const textColor = parseColor(parentStyle.color);
|
package/package.json
CHANGED