@ploaness/governance 1.12.0 → 1.13.0

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.
Files changed (109) hide show
  1. package/dist/a11y-focus-guard.d.ts +18 -0
  2. package/dist/a11y-focus-guard.d.ts.map +1 -0
  3. package/dist/a11y-focus-guard.js +17 -0
  4. package/dist/a11y-focus-guard.js.map +1 -0
  5. package/dist/a11y-hit-target.d.ts +7 -1
  6. package/dist/a11y-hit-target.d.ts.map +1 -1
  7. package/dist/a11y-hit-target.js +11 -0
  8. package/dist/a11y-hit-target.js.map +1 -1
  9. package/dist/asset-policy.d.ts +8 -4
  10. package/dist/asset-policy.d.ts.map +1 -1
  11. package/dist/asset-policy.js +28 -19
  12. package/dist/asset-policy.js.map +1 -1
  13. package/dist/browser-discovery.d.ts +116 -0
  14. package/dist/browser-discovery.d.ts.map +1 -0
  15. package/dist/browser-discovery.js +161 -0
  16. package/dist/browser-discovery.js.map +1 -0
  17. package/dist/browser-exemptions.d.ts +107 -0
  18. package/dist/browser-exemptions.d.ts.map +1 -0
  19. package/dist/browser-exemptions.js +163 -0
  20. package/dist/browser-exemptions.js.map +1 -0
  21. package/dist/browser-findings.d.ts +54 -0
  22. package/dist/browser-findings.d.ts.map +1 -0
  23. package/dist/browser-findings.js +52 -0
  24. package/dist/browser-findings.js.map +1 -0
  25. package/dist/browser-health.d.ts +45 -0
  26. package/dist/browser-health.d.ts.map +1 -0
  27. package/dist/browser-health.js +80 -0
  28. package/dist/browser-health.js.map +1 -0
  29. package/dist/browser-rules.d.ts +169 -0
  30. package/dist/browser-rules.d.ts.map +1 -0
  31. package/dist/browser-rules.js +345 -0
  32. package/dist/browser-rules.js.map +1 -0
  33. package/dist/browser-run.d.ts +110 -0
  34. package/dist/browser-run.d.ts.map +1 -0
  35. package/dist/browser-run.js +125 -0
  36. package/dist/browser-run.js.map +1 -0
  37. package/dist/browser-viewports.d.ts +77 -0
  38. package/dist/browser-viewports.d.ts.map +1 -0
  39. package/dist/browser-viewports.js +139 -0
  40. package/dist/browser-viewports.js.map +1 -0
  41. package/dist/change-scope.d.ts +158 -0
  42. package/dist/change-scope.d.ts.map +1 -0
  43. package/dist/change-scope.js +340 -0
  44. package/dist/change-scope.js.map +1 -0
  45. package/dist/cloudfront-functions.d.ts +34 -0
  46. package/dist/cloudfront-functions.d.ts.map +1 -0
  47. package/dist/cloudfront-functions.js +124 -0
  48. package/dist/cloudfront-functions.js.map +1 -0
  49. package/dist/generated-denial.d.ts +4 -1
  50. package/dist/generated-denial.d.ts.map +1 -1
  51. package/dist/generated-denial.js +10 -3
  52. package/dist/generated-denial.js.map +1 -1
  53. package/dist/index.d.ts +12 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +12 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/javascript-runtimes.d.ts +36 -0
  58. package/dist/javascript-runtimes.d.ts.map +1 -0
  59. package/dist/javascript-runtimes.js +40 -0
  60. package/dist/javascript-runtimes.js.map +1 -0
  61. package/dist/jsx-accessibility-scope.d.ts.map +1 -1
  62. package/dist/jsx-accessibility-scope.js +3 -0
  63. package/dist/jsx-accessibility-scope.js.map +1 -1
  64. package/dist/layout-boxes.d.ts.map +1 -1
  65. package/dist/layout-boxes.js +12 -14
  66. package/dist/layout-boxes.js.map +1 -1
  67. package/dist/layout-clip.d.ts +24 -0
  68. package/dist/layout-clip.d.ts.map +1 -0
  69. package/dist/layout-clip.js +82 -0
  70. package/dist/layout-clip.js.map +1 -0
  71. package/dist/layout-defects.d.ts +47 -4
  72. package/dist/layout-defects.d.ts.map +1 -1
  73. package/dist/layout-defects.js +94 -76
  74. package/dist/layout-defects.js.map +1 -1
  75. package/dist/layout-snapshot.d.ts +60 -2
  76. package/dist/layout-snapshot.d.ts.map +1 -1
  77. package/dist/layout-snapshot.js +65 -1
  78. package/dist/layout-snapshot.js.map +1 -1
  79. package/dist/layout-text.d.ts +4 -1
  80. package/dist/layout-text.d.ts.map +1 -1
  81. package/dist/layout-text.js +56 -7
  82. package/dist/layout-text.js.map +1 -1
  83. package/dist/route-map.d.ts +13 -0
  84. package/dist/route-map.d.ts.map +1 -1
  85. package/dist/route-map.js +13 -6
  86. package/dist/route-map.js.map +1 -1
  87. package/dist/run-plan.d.ts +27 -3
  88. package/dist/run-plan.d.ts.map +1 -1
  89. package/dist/run-plan.js +20 -3
  90. package/dist/run-plan.js.map +1 -1
  91. package/dist/settings-layering.d.ts.map +1 -1
  92. package/dist/settings-layering.js +6 -4
  93. package/dist/settings-layering.js.map +1 -1
  94. package/dist/settings.d.ts +32 -0
  95. package/dist/settings.d.ts.map +1 -1
  96. package/dist/settings.js +51 -12
  97. package/dist/settings.js.map +1 -1
  98. package/dist/terraform-blocks.d.ts +13 -0
  99. package/dist/terraform-blocks.d.ts.map +1 -0
  100. package/dist/terraform-blocks.js +27 -0
  101. package/dist/terraform-blocks.js.map +1 -0
  102. package/dist/terraform-policy.d.ts.map +1 -1
  103. package/dist/terraform-policy.js +3 -14
  104. package/dist/terraform-policy.js.map +1 -1
  105. package/dist/wiring-policy.d.ts +5 -2
  106. package/dist/wiring-policy.d.ts.map +1 -1
  107. package/dist/wiring-policy.js +16 -6
  108. package/dist/wiring-policy.js.map +1 -1
  109. package/package.json +1 -1
@@ -1,110 +1,128 @@
1
- // The layout sweep's verdict on one page, measured at every viewport the harness requires.
2
- //
3
- // Each defect is one line naming the route, the viewport, the rule, and the elements, so a failure says
4
- // where to look without a screenshot. Exemptions are judged across all the viewports of a page at once:
5
- // an edge attached at a phone width and apart at a desktop one is the ordinary shape of a responsive
6
- // layout, so an exemption is stale only when it excuses nothing at any of them.
1
+ import { applyExemptions, declaredExemptions, EXEMPTION_ATTRIBUTE, EXEMPTION_REASON_ATTRIBUTE, malformedExemptions, staleExemptions, } from './browser-exemptions.js';
2
+ import { findingAt, findingLine } from './browser-findings.js';
3
+ import { BASELINE_VIEWPORTS } from './browser-viewports.js';
7
4
  import { findTouchingBoxes } from './layout-boxes.js';
8
5
  import { ATTACHED_EXEMPTION, keyOf } from './layout-snapshot.js';
9
6
  import { findClippedText, findOverflowingElements, findOverlappingText, } from './layout-text.js';
10
- /** The viewports the harness requires: a phone and a desktop. A project may add more, never remove. */
11
- export const LAYOUT_VIEWPORTS = [
12
- { width: 390, height: 844 },
13
- { width: 1280, height: 800 },
14
- ];
7
+ /** The viewports the harness requires. A project may add more, never remove any. */
8
+ export const LAYOUT_VIEWPORTS = BASELINE_VIEWPORTS;
15
9
  /** The smallest gap, in CSS pixels, between a boxed element and its sibling. A project may raise it. */
16
10
  export const LAYOUT_MINIMUM_GAP = 4;
17
- /** The attribute a project writes on an element whose edge is shared on purpose. */
18
- export const LAYOUT_EXEMPTION_ATTRIBUTE = 'data-ploaness-layout';
11
+ /** The attribute a project writes on an element exempt from a rule. */
12
+ export const LAYOUT_EXEMPTION_ATTRIBUTE = EXEMPTION_ATTRIBUTE;
19
13
  /** The attribute carrying the reason for that exemption. */
20
- export const LAYOUT_REASON_ATTRIBUTE = 'data-ploaness-layout-reason';
14
+ export const LAYOUT_REASON_ATTRIBUTE = EXEMPTION_REASON_ATTRIBUTE;
15
+ /** The geometry rules the width sweep and the text-stress passes apply: L1 to L3. */
16
+ export const REFLOW_RULES = ['overflow', 'text-overlap', 'clipped-text'];
17
+ /** Every geometry rule of the layout scan: L1 to L4. */
18
+ export const LAYOUT_RULES = [...REFLOW_RULES, ATTACHED_EXEMPTION];
21
19
  const PAIR_SEPARATOR = ' <-> ';
22
- const where = (snapshot) => `${snapshot.route} @${String(snapshot.viewportWidth)}px`;
23
- const boxLine = (snapshot, finding) => {
20
+ const boxMessage = (finding) => {
24
21
  const kind = finding.isOverlap
25
22
  ? 'overlapping boxes'
26
23
  : `touching boxes (gap ${String(Math.max(0, finding.gap))}px)`;
27
- return `${where(snapshot)}: ${kind}: ${finding.first.label}${PAIR_SEPARATOR}${finding.second.label}`;
24
+ return `${kind}: ${finding.first.label}${PAIR_SEPARATOR}${finding.second.label}`;
28
25
  };
29
- const textLine = (snapshot, finding) => `${where(snapshot)}: overlapping text: ${finding.first.label}${PAIR_SEPARATOR}${finding.second.label}`;
30
- const clipLine = (snapshot, finding) => {
26
+ const clipMessage = (finding) => {
31
27
  const node = finding.node;
32
28
  const kind = finding.isUnnamedTruncation
33
29
  ? 'truncated text without its full text in title or aria-label'
34
30
  : `clipped text (content ${String(node.scrollWidth)}x${String(node.scrollHeight)}px in a ` +
35
31
  `${String(node.clientWidth)}x${String(node.clientHeight)}px box)`;
36
- return `${where(snapshot)}: ${kind}: ${node.label}`;
32
+ return `${kind}: ${node.label}`;
37
33
  };
38
- const overflowLines = (snapshot) => {
34
+ const overflowCandidates = (snapshot) => {
39
35
  if (snapshot.scrollWidth <= snapshot.viewportWidth) {
40
36
  return [];
41
37
  }
42
- const prefix = `${where(snapshot)}: horizontal overflow (page ${String(snapshot.scrollWidth)}px wide ` +
38
+ const prefix = `horizontal overflow (page ${String(snapshot.scrollWidth)}px wide ` +
43
39
  `in a ${String(snapshot.viewportWidth)}px viewport)`;
44
40
  const culprits = findOverflowingElements(snapshot);
45
41
  return culprits.length === 0
46
- ? [`${prefix}: document`]
47
- : culprits.map((node) => `${prefix}: ${node.label}`);
42
+ ? [{ rule: 'overflow', subjects: [], message: `${prefix}: document` }]
43
+ : culprits.map((node) => ({
44
+ rule: 'overflow',
45
+ subjects: [node],
46
+ message: `${prefix}: ${node.label}`,
47
+ }));
48
48
  };
49
- const isExempted = (finding) => finding.exemptedBy.length > 0;
50
- const snapshotLines = (snapshot, minimumGap) => [
51
- ...findTouchingBoxes(snapshot, minimumGap)
52
- .filter((finding) => !isExempted(finding))
53
- .map((finding) => boxLine(snapshot, finding)),
54
- ...findOverlappingText(snapshot).map((finding) => textLine(snapshot, finding)),
55
- ...findClippedText(snapshot).map((finding) => clipLine(snapshot, finding)),
56
- ...overflowLines(snapshot),
49
+ /**
50
+ * The reflow rules' candidates on one measured page, before exemptions: L1 to L3.
51
+ * @param snapshot the measured page.
52
+ * @returns one candidate per defect.
53
+ */
54
+ export const reflowCandidates = (snapshot) => [
55
+ ...findOverlappingText(snapshot).map((finding) => ({
56
+ rule: 'text-overlap',
57
+ subjects: [finding.first, finding.second],
58
+ message: `overlapping text: ${finding.first.label}${PAIR_SEPARATOR}${finding.second.label}`,
59
+ })),
60
+ ...findClippedText(snapshot).map((finding) => ({
61
+ rule: 'clipped-text',
62
+ subjects: [finding.node],
63
+ message: clipMessage(finding),
64
+ })),
65
+ ...overflowCandidates(snapshot),
57
66
  ];
58
- const exemptionLines = (snapshot) => snapshot.nodes.flatMap((node) => {
59
- if (node.exemption === undefined) {
60
- return [];
61
- }
62
- if (node.exemption !== ATTACHED_EXEMPTION) {
63
- return [
64
- `${where(snapshot)}: unknown layout exemption ${LAYOUT_EXEMPTION_ATTRIBUTE}=` +
65
- `"${node.exemption}" on ${node.label}; the only value is "${ATTACHED_EXEMPTION}"`,
66
- ];
67
- }
68
- return node.exemptionReason.length === 0
69
- ? [
70
- `${where(snapshot)}: layout exemption without a reason on ${node.label}; ` +
71
- `state it in ${LAYOUT_REASON_ATTRIBUTE}`,
72
- ]
73
- : [];
74
- });
75
- const usedExemptionKeys = (snapshots, minimumGap) => new Set(snapshots.flatMap((snapshot) => findTouchingBoxes(snapshot, minimumGap).flatMap((finding) => finding.exemptedBy.map((node) => keyOf(snapshot, node)))));
76
- const attachedExemptions = (snapshots) => {
77
- const all = snapshots.flatMap((snapshot) => snapshot.nodes
78
- .filter((node) => node.exemption === ATTACHED_EXEMPTION)
79
- .map((node) => ({ key: keyOf(snapshot, node), label: node.label })));
80
- return all.filter((exemption, index) => all.findIndex((other) => other.key === exemption.key) === index);
81
- };
82
- const staleLines = (snapshots, minimumGap) => {
83
- const used = usedExemptionKeys(snapshots, minimumGap);
84
- const widths = snapshots
85
- .map((snapshot) => `${String(snapshot.viewportWidth)}px`)
86
- .join(', ');
87
- const route = snapshots[0]?.route ?? '';
88
- return attachedExemptions(snapshots)
89
- .filter((exemption) => !used.has(exemption.key))
90
- .map((exemption) => `${route}: stale layout exemption on ${exemption.label}: it excuses no touching or ` +
91
- `overlapping box at ${widths}; remove ${LAYOUT_EXEMPTION_ATTRIBUTE}`);
67
+ /**
68
+ * Judge one measured page by the geometry rules, with exemptions applied.
69
+ *
70
+ * Touching boxes are excused only by an exemption on one of the two boxes. Every other rule is excused
71
+ * by an exemption on the element it judges or on an ancestor of it.
72
+ * @param snapshot the measured page.
73
+ * @param place where it was measured.
74
+ * @param judgement the gap and rules to judge it by, and the candidates of further rules.
75
+ * @param judgement.minimumGap the smallest gap, in CSS pixels, between a boxed element and its sibling.
76
+ * @param judgement.extra candidates of further rules measured on the same page.
77
+ * @param judgement.rules the geometry rules to apply.
78
+ * @returns the findings, the exemptions used, and the exemptions declared.
79
+ */
80
+ export const judgeLayout = (snapshot, place, { minimumGap, extra = [], rules = LAYOUT_RULES }) => {
81
+ const boxes = rules.includes(ATTACHED_EXEMPTION) ? findTouchingBoxes(snapshot, minimumGap) : [];
82
+ const candidates = [
83
+ ...reflowCandidates(snapshot).filter((candidate) => rules.includes(candidate.rule)),
84
+ ...extra,
85
+ ];
86
+ const judged = applyExemptions(snapshot, place, candidates);
87
+ return {
88
+ findings: [
89
+ ...boxes
90
+ .filter((finding) => finding.exemptedBy.length === 0)
91
+ .map((finding) => findingAt(place, ATTACHED_EXEMPTION, boxMessage(finding), [finding.first.index, finding.second.index])),
92
+ ...judged.findings,
93
+ ...malformedExemptions(snapshot, place),
94
+ ],
95
+ used: [
96
+ ...boxes.flatMap((finding) => finding.exemptedBy.map((node) => ({
97
+ location: place.location,
98
+ key: keyOf(snapshot, node),
99
+ rule: ATTACHED_EXEMPTION,
100
+ }))),
101
+ ...judged.used,
102
+ ],
103
+ declared: declaredExemptions(snapshot, place.location),
104
+ };
92
105
  };
93
106
  /**
94
- * Every layout defect on one page, across the viewports it was measured at.
107
+ * Every layout defect on one page, across the viewports it was measured at, as report lines.
95
108
  * @param snapshots the same page measured at each required viewport.
96
109
  * @param minimumGap the smallest gap, in CSS pixels, between a boxed element and its sibling.
110
+ * @param engine the engine it was measured in.
111
+ * @param state the state it was measured in.
97
112
  * @returns one line per defect, without duplicates, in the order the viewports were measured.
98
113
  */
99
- export const findLayoutDefects = (snapshots, minimumGap) => [
100
- ...new Set([
101
- ...snapshots.flatMap((snapshot) => [
102
- ...snapshotLines(snapshot, minimumGap),
103
- ...exemptionLines(snapshot),
104
- ]),
105
- ...staleLines(snapshots, minimumGap),
106
- ]),
107
- ];
114
+ export const findLayoutDefects = (snapshots, minimumGap, engine = 'chromium', state = 'resting') => {
115
+ const judged = snapshots.map((snapshot) => judgeLayout(snapshot, {
116
+ location: snapshot.route,
117
+ state,
118
+ engine,
119
+ viewport: { width: snapshot.viewportWidth, height: snapshot.viewportHeight },
120
+ }, { minimumGap }));
121
+ const stale = staleExemptions(judged.flatMap((page) => page.declared), judged.flatMap((page) => page.used), LAYOUT_RULES, engine);
122
+ return [
123
+ ...new Set([...judged.flatMap((page) => page.findings), ...stale].map((finding) => findingLine(finding))),
124
+ ];
125
+ };
108
126
  /**
109
127
  * The viewports a scan must run at: the harness's own, then any a project adds.
110
128
  * @param declared the viewports a project declared.
@@ -1 +1 @@
1
- {"version":3,"file":"layout-defects.js","sourceRoot":"","sources":["../src/layout-defects.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout-defects.js","sourceRoot":"","sources":["../src/layout-defects.ts"],"names":[],"mappings":"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"}
@@ -41,6 +41,12 @@ export interface LayoutNode {
41
41
  readonly display: string;
42
42
  readonly visibility: string;
43
43
  readonly position: string;
44
+ /** The computed `z-index`: `auto` or an integer. */
45
+ readonly zIndex: string;
46
+ /** The computed `transform`: `none` or a `matrix()` or `matrix3d()`. */
47
+ readonly transform: string;
48
+ /** The computed `rotate` property, which `transform` does not include: `none` or an angle. */
49
+ readonly rotate: string;
44
50
  readonly backgroundColor: string;
45
51
  readonly backgroundImage: string;
46
52
  readonly boxShadow: string;
@@ -59,10 +65,40 @@ export interface LayoutNode {
59
65
  readonly clientHeight: number;
60
66
  readonly title: string;
61
67
  readonly ariaLabel: string;
62
- /** The value of `data-ploaness-layout`, or undefined when the attribute is absent. */
68
+ /** The value of `data-ploaness-layout`: the rule names it exempts, or undefined when it is absent. */
63
69
  readonly exemption: string | undefined;
64
70
  /** The value of `data-ploaness-layout-reason`, trimmed. */
65
71
  readonly exemptionReason: string;
72
+ /** The computed `font-size` in CSS pixels. */
73
+ readonly fontSize: number;
74
+ /** The computed `font-family` stack. */
75
+ readonly fontFamily: string;
76
+ /** What a replaced element reports about its content, or undefined for any other element. */
77
+ readonly media: MediaFacts | undefined;
78
+ }
79
+ /** What an image, video, frame or embed reports about the content it shows. */
80
+ export interface MediaFacts {
81
+ /** Whether an image has finished loading; always true for an element that is not an image. */
82
+ readonly isComplete: boolean;
83
+ /** Whether the source is a vector image, which has no fixed resolution to judge. */
84
+ readonly isVector: boolean;
85
+ /** The pixel size of the loaded source file, unscaled by a `srcset` density; 0 when it has none. */
86
+ readonly naturalWidth: number;
87
+ readonly naturalHeight: number;
88
+ /** The content box, inside padding and border. */
89
+ readonly contentWidth: number;
90
+ readonly contentHeight: number;
91
+ readonly objectFit: string;
92
+ /** The box the same element takes with no source loaded: the space it reserves before loading. */
93
+ readonly reservedWidth: number;
94
+ readonly reservedHeight: number;
95
+ }
96
+ /** One `@font-face` the document declares, and how far it got. */
97
+ export interface FontFaceFacts {
98
+ readonly family: string;
99
+ readonly status: string;
100
+ readonly weight: string;
101
+ readonly style: string;
66
102
  }
67
103
  /** One page measured at one viewport. */
68
104
  export interface LayoutSnapshot {
@@ -74,15 +110,29 @@ export interface LayoutSnapshot {
74
110
  /** The computed background of `<html>`, which is what `<body>` sits on. */
75
111
  readonly rootBackground: string;
76
112
  readonly nodes: readonly LayoutNode[];
113
+ /** Every `@font-face` the document declares. */
114
+ readonly fontFaces: readonly FontFaceFacts[];
77
115
  }
78
- /** The only exemption value: an edge shared on purpose, such as a tab joined to its panel. */
116
+ /** The touching-boxes rule's name, which exempts an edge shared on purpose, such as a tab joined to its panel. */
79
117
  export declare const ATTACHED_EXEMPTION: string;
118
+ /**
119
+ * Whether a computed colour hides what lies beneath it.
120
+ * @param color a computed colour string.
121
+ * @returns true for a colour with no alpha or a full one.
122
+ */
123
+ export declare const isOpaqueColor: (color: string) => boolean;
80
124
  /**
81
125
  * Whether a computed colour draws anything.
82
126
  * @param color a computed colour string.
83
127
  * @returns false for `transparent` and any colour whose alpha is zero.
84
128
  */
85
129
  export declare const isVisibleColor: (color: string) => boolean;
130
+ /**
131
+ * Whether an element's own background hides what lies beneath its box.
132
+ * @param node the element.
133
+ * @returns true for an opaque background colour, or a gradient of opaque stops only.
134
+ */
135
+ export declare const isOpaqueBackground: (node: LayoutNode) => boolean;
86
136
  /**
87
137
  * The background an element sits on: the nearest ancestor that paints one, or the page canvas.
88
138
  * @param snapshot the measured page.
@@ -125,6 +175,14 @@ export declare const isInAriaHidden: (snapshot: LayoutSnapshot, node: LayoutNode
125
175
  * @returns true inside a clipped subtree.
126
176
  */
127
177
  export declare const isInClip: (snapshot: LayoutSnapshot, node: LayoutNode) => boolean;
178
+ /**
179
+ * Whether an element or an ancestor is rotated or skewed. Its bounding rectangles are then the upright
180
+ * boxes around a turned shape, larger than what it paints, so no gap or overlap measured on them is real.
181
+ * @param snapshot the measured page.
182
+ * @param node the element.
183
+ * @returns true inside a turned subtree.
184
+ */
185
+ export declare const isInTurn: (snapshot: LayoutSnapshot, node: LayoutNode) => boolean;
128
186
  /**
129
187
  * Whether `ancestor` contains `node`.
130
188
  * @param snapshot the measured page.
@@ -1 +1 @@
1
- {"version":3,"file":"layout-snapshot.d.ts","sourceRoot":"","sources":["../src/layout-snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout-snapshot.d.ts","sourceRoot":"","sources":["../src/layout-snapshot.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  // The layout sweep measures inside the page and judges here. Everything a rule needs crosses the
4
4
  // boundary as data - whole CSS pixels and computed style strings - so the rules run without a browser
5
5
  // and a spec can state a defect as the numbers that make it one.
6
- /** The only exemption value: an edge shared on purpose, such as a tab joined to its panel. */
6
+ /** The touching-boxes rule's name, which exempts an edge shared on purpose, such as a tab joined to its panel. */
7
7
  export const ATTACHED_EXEMPTION = 'attached';
8
8
  // The canvas a page is drawn on when neither `<html>` nor any ancestor paints a background.
9
9
  const CANVAS_BACKGROUND = 'rgb(255, 255, 255)';
@@ -14,6 +14,16 @@ const COMMA_ALPHA = /^rgba\([^,]+,[^,]+,[^,]+,\s*([\d.]+)\)$/u;
14
14
  const SLASH_ALPHA = /\/\s*([\d.]+%?)\s*\)$/u;
15
15
  const PERCENT = '%';
16
16
  const alphaText = (color) => COMMA_ALPHA.exec(color)?.[1] ?? SLASH_ALPHA.exec(color)?.[1];
17
+ const FULL_ALPHAS = new Set(['1', `100${PERCENT}`]);
18
+ /**
19
+ * Whether a computed colour hides what lies beneath it.
20
+ * @param color a computed colour string.
21
+ * @returns true for a colour with no alpha or a full one.
22
+ */
23
+ export const isOpaqueColor = (color) => {
24
+ const alpha = alphaText(color.trim());
25
+ return isVisibleColor(color) && (alpha === undefined || FULL_ALPHAS.has(alpha));
26
+ };
17
27
  /**
18
28
  * Whether a computed colour draws anything.
19
29
  * @param color a computed colour string.
@@ -27,6 +37,24 @@ export const isVisibleColor = (color) => {
27
37
  const alpha = alphaText(trimmed);
28
38
  return alpha === undefined || Number(alpha.replace(PERCENT, '')) > 0;
29
39
  };
40
+ // A computed gradient spells each colour stop as a colour function. An image, a keyword left in the
41
+ // value, or a stop of partial alpha may let what lies beneath show through, so only a gradient whose
42
+ // every stop is an opaque colour function hides it.
43
+ const COLOR_FUNCTION = /(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\([^()]*\)/gu;
44
+ const UNKNOWN_PAINT = /url\(|transparent|currentcolor/u;
45
+ const isOpaqueGradient = (image) => {
46
+ const stops = image.match(COLOR_FUNCTION) ?? [];
47
+ return (image.includes('gradient(') &&
48
+ !UNKNOWN_PAINT.test(image) &&
49
+ stops.length > 0 &&
50
+ stops.every((stop) => isOpaqueColor(stop)));
51
+ };
52
+ /**
53
+ * Whether an element's own background hides what lies beneath its box.
54
+ * @param node the element.
55
+ * @returns true for an opaque background colour, or a gradient of opaque stops only.
56
+ */
57
+ export const isOpaqueBackground = (node) => isOpaqueColor(node.backgroundColor) || isOpaqueGradient(node.backgroundImage);
30
58
  /**
31
59
  * The background an element sits on: the nearest ancestor that paints one, or the page canvas.
32
60
  * @param snapshot the measured page.
@@ -88,6 +116,42 @@ export const isInClip = (snapshot, node) => {
88
116
  const parent = snapshot.nodes[node.parent];
89
117
  return node.isClipped || (parent !== undefined && isInClip(snapshot, parent));
90
118
  };
119
+ // A matrix turns a box when it moves either axis toward the other: `b` and `c` of `matrix(a, b, c, d, e,
120
+ // f)`, and the six off-diagonal terms of the column-major `matrix3d`. What is left is scaling and
121
+ // translation, under which a bounding rectangle is still the painted box.
122
+ const MATRIX = /^matrix(3d)?\((.*)\)$/u;
123
+ const TURN_EPSILON = 1e-6;
124
+ const turnTermsOf = (terms, isSpatial) => {
125
+ const [, m12, m13, , m21, , m23, , m31, m32] = terms;
126
+ return isSpatial ? [m12, m13, m21, m23, m31, m32] : [m12, m13];
127
+ };
128
+ const isTurnedTransform = (transform) => {
129
+ const match = MATRIX.exec(transform.trim());
130
+ if (match === null) {
131
+ return false;
132
+ }
133
+ const terms = (match[2] ?? '').split(',').map(Number);
134
+ return turnTermsOf(terms, match[1] !== undefined).some((term) => Math.abs(term ?? 0) > TURN_EPSILON);
135
+ };
136
+ // The angle is the last word of the computed value, after any axis: `3deg`, `x 10deg`, `0 0 1 3deg`.
137
+ const ANGLE_UNIT = /(?:deg|g?rad|turn)$/u;
138
+ const isTurnedRotate = (rotate) => {
139
+ const angle = Number((rotate.trim().split(/\s+/u).at(-1) ?? '').replace(ANGLE_UNIT, ''));
140
+ return Number.isFinite(angle) && angle !== 0;
141
+ };
142
+ /**
143
+ * Whether an element or an ancestor is rotated or skewed. Its bounding rectangles are then the upright
144
+ * boxes around a turned shape, larger than what it paints, so no gap or overlap measured on them is real.
145
+ * @param snapshot the measured page.
146
+ * @param node the element.
147
+ * @returns true inside a turned subtree.
148
+ */
149
+ export const isInTurn = (snapshot, node) => {
150
+ const parent = snapshot.nodes[node.parent];
151
+ return (isTurnedTransform(node.transform) ||
152
+ isTurnedRotate(node.rotate) ||
153
+ (parent !== undefined && isInTurn(snapshot, parent)));
154
+ };
91
155
  /**
92
156
  * Whether `ancestor` contains `node`.
93
157
  * @param snapshot the measured page.
@@ -1 +1 @@
1
- {"version":3,"file":"layout-snapshot.js","sourceRoot":"","sources":["../src/layout-snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout-snapshot.js","sourceRoot":"","sources":["../src/layout-snapshot.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,10 @@ export interface TextFinding {
10
10
  readonly second: LayoutNode;
11
11
  }
12
12
  /**
13
- * Every pair of unrelated elements whose own text overlaps.
13
+ * Every pair of unrelated elements whose visible text overlaps.
14
+ *
15
+ * Text inside a rotated or skewed subtree is not compared: its rects are the upright boxes around the
16
+ * turned lines, which meet where the glyphs do not.
14
17
  * @param snapshot the measured page.
15
18
  * @returns one finding per pair, in document order.
16
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"layout-text.d.ts","sourceRoot":"","sources":["../src/layout-text.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,UAAU,EAEf,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAA;AAE7B;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAU,CAAA;AAiD/C,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAC5B;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,cAAc,KAAG,SAAS,WAAW,EAclF,CAAA;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,oGAAoG;IACpG,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;CACtC;AAiBD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,cAAc,KAAG,SAAS,WAAW,EAazE,CAAA;AAgBN;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,cAAc,KAAG,SAAS,UAAU,EASlF,CAAA"}
1
+ {"version":3,"file":"layout-text.d.ts","sourceRoot":"","sources":["../src/layout-text.ts"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,UAAU,EAEf,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAA;AAE7B;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAU,CAAA;AAwH/C,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,cAAc,KAAG,SAAS,WAAW,EAclF,CAAA;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,oGAAoG;IACpG,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;CACtC;AAiBD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,cAAc,KAAG,SAAS,WAAW,EAazE,CAAA;AAgBN;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,cAAc,KAAG,SAAS,UAAU,EASlF,CAAA"}
@@ -1,5 +1,6 @@
1
1
  // Text that overlaps other text, text cut off by its own box, and a page wider than its viewport.
2
- import { hasArea, isAncestorOf, isInAriaHidden, isInClip, } from './layout-snapshot.js';
2
+ import { intersectionOf, outerBoxOf, visibleRectsOf } from './layout-clip.js';
3
+ import { hasArea, isAncestorOf, isInAriaHidden, isInClip, isInTurn, isOpaqueBackground, } from './layout-snapshot.js';
3
4
  /**
4
5
  * How far two text rects may intersect, in CSS pixels, before they overlap. Glyph boxes of adjacent
5
6
  * lines share a pixel row after rounding, which is a rounding artefact rather than a collision.
@@ -33,20 +34,68 @@ const lineBoxOf = (rect, lineHeight) => {
33
34
  return { ...rect, top: Math.round(rect.top + inset), bottom: Math.round(rect.bottom - inset) };
34
35
  };
35
36
  const lineBoxesOf = (node) => node.textRects.map((rect) => lineBoxOf(rect, node.lineHeight));
36
- const isIntersecting = (first, second) => Math.min(first.right, second.right) - Math.max(first.left, second.left) > TEXT_OVERLAP_TOLERANCE &&
37
- Math.min(first.bottom, second.bottom) - Math.max(first.top, second.top) > TEXT_OVERLAP_TOLERANCE;
38
- const hasCollidingText = (first, second) => lineBoxesOf(first).some((left) => lineBoxesOf(second).some((right) => isIntersecting(left, right)));
37
+ const isIntersecting = (first, second) => {
38
+ const shared = intersectionOf(first, second);
39
+ return shared.right - shared.left > TEXT_OVERLAP_TOLERANCE && shared.bottom - shared.top > TEXT_OVERLAP_TOLERANCE;
40
+ };
41
+ const STATIC = 'static';
42
+ // What of an element's text a reader can see: each line box, cut by every ancestor that clips it.
43
+ const visibleLineBoxesOf = (snapshot, node) => visibleRectsOf(snapshot, node, lineBoxesOf(node));
44
+ const ancestorsOf = (snapshot, node) => {
45
+ const parent = snapshot.nodes[node.parent];
46
+ return parent === undefined ? [] : [parent, ...ancestorsOf(snapshot, parent)];
47
+ };
48
+ const isSelfOrAncestorOf = (snapshot, candidate, node) => candidate === node || isAncestorOf(snapshot, candidate, node);
49
+ const stackLevelOf = (node) => (node.zIndex === 'auto' ? 0 : Number(node.zIndex) || 0);
50
+ const nearestPositioned = (snapshot, node, other) => [node, ...ancestorsOf(snapshot, node)].find((candidate) => candidate.position !== STATIC && !isSelfOrAncestorOf(snapshot, candidate, other));
51
+ const coversRegion = (outer, inner) => outer.left <= inner.left && outer.top <= inner.top && outer.right >= inner.right && outer.bottom >= inner.bottom;
52
+ // Whether `cover` paints an opaque background over all of `region` without containing `under`.
53
+ const isOpaqueOver = (snapshot, cover, under, region) => {
54
+ const box = outerBoxOf(cover);
55
+ return (box !== undefined &&
56
+ isOpaqueBackground(cover) &&
57
+ coversRegion(box, region) &&
58
+ !isSelfOrAncestorOf(snapshot, cover, under));
59
+ };
60
+ // Whether the positioned layer `cover` is painted in is painted after `under`'s text.
61
+ const isPaintedAfter = (snapshot, cover, under) => {
62
+ const layer = nearestPositioned(snapshot, cover, under);
63
+ if (layer === undefined) {
64
+ return false;
65
+ }
66
+ const beneath = nearestPositioned(snapshot, under, cover);
67
+ if (beneath === undefined) {
68
+ return stackLevelOf(layer) >= 0;
69
+ }
70
+ return (stackLevelOf(layer) > stackLevelOf(beneath) ||
71
+ (stackLevelOf(layer) === stackLevelOf(beneath) && layer.index > beneath.index));
72
+ };
73
+ // Whether `under`'s text at `region` is painted beneath an opaque background of `over` or of one of its
74
+ // ancestors, such as an open menu panel laid over the page. In one stacking context every in-flow
75
+ // background is painted before any text, so only a positioned layer covers text: it is painted after
76
+ // the in-flow content beside it, and after another positioned layer of no higher `z-index` before it in
77
+ // the document.
78
+ const isCoveredBy = (snapshot, under, over, region) => [over, ...ancestorsOf(snapshot, over)].some((cover) => isOpaqueOver(snapshot, cover, under, region) && isPaintedAfter(snapshot, cover, under));
79
+ const hasCollidingText = (snapshot, first, second) => visibleLineBoxesOf(snapshot, first).some((left) => visibleLineBoxesOf(snapshot, second).some((right) => {
80
+ const region = intersectionOf(left, right);
81
+ return (isIntersecting(left, right) &&
82
+ !isCoveredBy(snapshot, first, second, region) &&
83
+ !isCoveredBy(snapshot, second, first, region));
84
+ }));
39
85
  /**
40
- * Every pair of unrelated elements whose own text overlaps.
86
+ * Every pair of unrelated elements whose visible text overlaps.
87
+ *
88
+ * Text inside a rotated or skewed subtree is not compared: its rects are the upright boxes around the
89
+ * turned lines, which meet where the glyphs do not.
41
90
  * @param snapshot the measured page.
42
91
  * @returns one finding per pair, in document order.
43
92
  */
44
93
  export const findOverlappingText = (snapshot) => {
45
- const readable = snapshot.nodes.filter((node) => isReadableText(snapshot, node));
94
+ const readable = snapshot.nodes.filter((node) => isReadableText(snapshot, node) && !isInTurn(snapshot, node));
46
95
  return readable.flatMap((first, index) => readable
47
96
  .slice(index + 1)
48
97
  .filter((second) => !(isAncestorOf(snapshot, first, second) || isAncestorOf(snapshot, second, first)) &&
49
- hasCollidingText(first, second))
98
+ hasCollidingText(snapshot, first, second))
50
99
  .map((second) => ({ first, second })));
51
100
  };
52
101
  const hasHiddenOverflowX = (node) => CLIPPING_OVERFLOW.has(node.overflowX) && node.scrollWidth > node.clientWidth;