accented 0.0.2 → 1.0.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 (212) hide show
  1. package/NOTICE +14 -0
  2. package/README.md +44 -187
  3. package/dist/accented.d.ts +8 -8
  4. package/dist/accented.d.ts.map +1 -1
  5. package/dist/accented.js +37 -30
  6. package/dist/accented.js.map +1 -1
  7. package/dist/common/tokens.d.ts +7 -0
  8. package/dist/common/tokens.d.ts.map +1 -0
  9. package/dist/common/tokens.js +8 -0
  10. package/dist/common/tokens.js.map +1 -0
  11. package/dist/constants.d.ts +2 -1
  12. package/dist/constants.d.ts.map +1 -1
  13. package/dist/constants.js +2 -1
  14. package/dist/constants.js.map +1 -1
  15. package/dist/dom-updater.d.ts +1 -1
  16. package/dist/dom-updater.d.ts.map +1 -1
  17. package/dist/dom-updater.js +73 -31
  18. package/dist/dom-updater.js.map +1 -1
  19. package/dist/elements/accented-dialog.d.ts +13 -10
  20. package/dist/elements/accented-dialog.d.ts.map +1 -1
  21. package/dist/elements/accented-dialog.js +110 -94
  22. package/dist/elements/accented-dialog.js.map +1 -1
  23. package/dist/elements/accented-trigger.d.ts +14 -9
  24. package/dist/elements/accented-trigger.d.ts.map +1 -1
  25. package/dist/elements/accented-trigger.js +77 -22
  26. package/dist/elements/accented-trigger.js.map +1 -1
  27. package/dist/fullscreen-listener.d.ts +2 -0
  28. package/dist/fullscreen-listener.d.ts.map +1 -0
  29. package/dist/fullscreen-listener.js +17 -0
  30. package/dist/fullscreen-listener.js.map +1 -0
  31. package/dist/intersection-observer.d.ts +1 -1
  32. package/dist/intersection-observer.d.ts.map +1 -1
  33. package/dist/intersection-observer.js +12 -6
  34. package/dist/intersection-observer.js.map +1 -1
  35. package/dist/log-and-rethrow.d.ts +1 -1
  36. package/dist/log-and-rethrow.d.ts.map +1 -1
  37. package/dist/log-and-rethrow.js +2 -3
  38. package/dist/log-and-rethrow.js.map +1 -1
  39. package/dist/logger.d.ts +1 -1
  40. package/dist/logger.d.ts.map +1 -1
  41. package/dist/logger.js +6 -3
  42. package/dist/logger.js.map +1 -1
  43. package/dist/register-elements.d.ts +1 -1
  44. package/dist/register-elements.d.ts.map +1 -1
  45. package/dist/register-elements.js +6 -7
  46. package/dist/register-elements.js.map +1 -1
  47. package/dist/resize-listener.d.ts +1 -1
  48. package/dist/resize-listener.d.ts.map +1 -1
  49. package/dist/resize-listener.js +3 -4
  50. package/dist/resize-listener.js.map +1 -1
  51. package/dist/scanner.d.ts +2 -2
  52. package/dist/scanner.d.ts.map +1 -1
  53. package/dist/scanner.js +76 -43
  54. package/dist/scanner.js.map +1 -1
  55. package/dist/scroll-listeners.d.ts +1 -1
  56. package/dist/scroll-listeners.d.ts.map +1 -1
  57. package/dist/scroll-listeners.js +3 -4
  58. package/dist/scroll-listeners.js.map +1 -1
  59. package/dist/state.d.ts +3 -2
  60. package/dist/state.d.ts.map +1 -1
  61. package/dist/state.js +5 -3
  62. package/dist/state.js.map +1 -1
  63. package/dist/task-queue.d.ts +4 -4
  64. package/dist/task-queue.d.ts.map +1 -1
  65. package/dist/task-queue.js +3 -2
  66. package/dist/task-queue.js.map +1 -1
  67. package/dist/types.d.ts +140 -49
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/types.js.map +1 -1
  70. package/dist/utils/are-elements-with-issues-equal.d.ts +3 -0
  71. package/dist/utils/are-elements-with-issues-equal.d.ts.map +1 -0
  72. package/dist/utils/are-elements-with-issues-equal.js +5 -0
  73. package/dist/utils/are-elements-with-issues-equal.js.map +1 -0
  74. package/dist/utils/are-issue-sets-equal.d.ts +2 -2
  75. package/dist/utils/are-issue-sets-equal.d.ts.map +1 -1
  76. package/dist/utils/are-issue-sets-equal.js +3 -3
  77. package/dist/utils/are-issue-sets-equal.js.map +1 -1
  78. package/dist/utils/containing-blocks.d.ts +3 -0
  79. package/dist/utils/containing-blocks.d.ts.map +1 -0
  80. package/dist/utils/containing-blocks.js +46 -0
  81. package/dist/utils/containing-blocks.js.map +1 -0
  82. package/dist/utils/contains.d.ts +2 -0
  83. package/dist/utils/contains.d.ts.map +1 -0
  84. package/dist/utils/contains.js +19 -0
  85. package/dist/utils/contains.js.map +1 -0
  86. package/dist/utils/deduplicate-nodes.d.ts +2 -0
  87. package/dist/utils/deduplicate-nodes.d.ts.map +1 -0
  88. package/dist/utils/deduplicate-nodes.js +4 -0
  89. package/dist/utils/deduplicate-nodes.js.map +1 -0
  90. package/dist/utils/deep-merge.d.ts +1 -1
  91. package/dist/utils/deep-merge.d.ts.map +1 -1
  92. package/dist/utils/deep-merge.js +8 -5
  93. package/dist/utils/deep-merge.js.map +1 -1
  94. package/dist/utils/dom-helpers.d.ts +9 -0
  95. package/dist/utils/dom-helpers.d.ts.map +1 -0
  96. package/dist/utils/dom-helpers.js +34 -0
  97. package/dist/utils/dom-helpers.js.map +1 -0
  98. package/dist/utils/ensure-non-empty.d.ts +2 -0
  99. package/dist/utils/ensure-non-empty.d.ts.map +1 -0
  100. package/dist/utils/ensure-non-empty.js +7 -0
  101. package/dist/utils/ensure-non-empty.js.map +1 -0
  102. package/dist/utils/get-element-html.d.ts +1 -1
  103. package/dist/utils/get-element-html.d.ts.map +1 -1
  104. package/dist/utils/get-element-html.js +4 -2
  105. package/dist/utils/get-element-html.js.map +1 -1
  106. package/dist/utils/get-element-position.d.ts +10 -2
  107. package/dist/utils/get-element-position.d.ts.map +1 -1
  108. package/dist/utils/get-element-position.js +64 -16
  109. package/dist/utils/get-element-position.js.map +1 -1
  110. package/dist/utils/get-parent.d.ts +2 -0
  111. package/dist/utils/get-parent.d.ts.map +1 -0
  112. package/dist/utils/get-parent.js +12 -0
  113. package/dist/utils/get-parent.js.map +1 -0
  114. package/dist/utils/get-scan-context.d.ts +3 -0
  115. package/dist/utils/get-scan-context.d.ts.map +1 -0
  116. package/dist/utils/get-scan-context.js +28 -0
  117. package/dist/utils/get-scan-context.js.map +1 -0
  118. package/dist/utils/get-scrollable-ancestors.d.ts +1 -1
  119. package/dist/utils/get-scrollable-ancestors.d.ts.map +1 -1
  120. package/dist/utils/get-scrollable-ancestors.js +10 -6
  121. package/dist/utils/get-scrollable-ancestors.js.map +1 -1
  122. package/dist/utils/is-node-in-scan-context.d.ts +3 -0
  123. package/dist/utils/is-node-in-scan-context.d.ts.map +1 -0
  124. package/dist/utils/is-node-in-scan-context.js +26 -0
  125. package/dist/utils/is-node-in-scan-context.js.map +1 -0
  126. package/dist/utils/is-non-empty.d.ts +2 -0
  127. package/dist/utils/is-non-empty.d.ts.map +1 -0
  128. package/dist/utils/is-non-empty.js +4 -0
  129. package/dist/utils/is-non-empty.js.map +1 -0
  130. package/dist/utils/normalize-context.d.ts +3 -0
  131. package/dist/utils/normalize-context.d.ts.map +1 -0
  132. package/dist/utils/normalize-context.js +59 -0
  133. package/dist/utils/normalize-context.js.map +1 -0
  134. package/dist/utils/recalculate-positions.d.ts +1 -1
  135. package/dist/utils/recalculate-positions.d.ts.map +1 -1
  136. package/dist/utils/recalculate-positions.js +5 -5
  137. package/dist/utils/recalculate-positions.js.map +1 -1
  138. package/dist/utils/recalculate-scrollable-ancestors.d.ts +1 -1
  139. package/dist/utils/recalculate-scrollable-ancestors.d.ts.map +1 -1
  140. package/dist/utils/recalculate-scrollable-ancestors.js +4 -4
  141. package/dist/utils/recalculate-scrollable-ancestors.js.map +1 -1
  142. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts +10 -0
  143. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -0
  144. package/dist/utils/shadow-dom-aware-mutation-observer.js +61 -0
  145. package/dist/utils/shadow-dom-aware-mutation-observer.js.map +1 -0
  146. package/dist/utils/supports-anchor-positioning.d.ts +1 -1
  147. package/dist/utils/supports-anchor-positioning.d.ts.map +1 -1
  148. package/dist/utils/supports-anchor-positioning.js +1 -1
  149. package/dist/utils/supports-anchor-positioning.js.map +1 -1
  150. package/dist/utils/transform-violations.d.ts +2 -2
  151. package/dist/utils/transform-violations.d.ts.map +1 -1
  152. package/dist/utils/transform-violations.js +23 -10
  153. package/dist/utils/transform-violations.js.map +1 -1
  154. package/dist/utils/update-elements-with-issues.d.ts +11 -5
  155. package/dist/utils/update-elements-with-issues.d.ts.map +1 -1
  156. package/dist/utils/update-elements-with-issues.js +56 -24
  157. package/dist/utils/update-elements-with-issues.js.map +1 -1
  158. package/dist/validate-options.d.ts +2 -2
  159. package/dist/validate-options.d.ts.map +1 -1
  160. package/dist/validate-options.js +91 -4
  161. package/dist/validate-options.js.map +1 -1
  162. package/package.json +15 -7
  163. package/src/accented.test.ts +2 -2
  164. package/src/accented.ts +45 -34
  165. package/src/common/tokens.ts +10 -0
  166. package/src/constants.ts +2 -1
  167. package/src/dom-updater.ts +87 -34
  168. package/src/elements/accented-dialog.ts +157 -122
  169. package/src/elements/accented-trigger.ts +119 -47
  170. package/src/fullscreen-listener.ts +21 -0
  171. package/src/intersection-observer.ts +27 -16
  172. package/src/log-and-rethrow.ts +2 -3
  173. package/src/logger.ts +14 -4
  174. package/src/register-elements.ts +7 -7
  175. package/src/resize-listener.ts +15 -11
  176. package/src/scanner.ts +113 -57
  177. package/src/scroll-listeners.ts +27 -19
  178. package/src/state.ts +27 -16
  179. package/src/task-queue.test.ts +5 -4
  180. package/src/task-queue.ts +8 -6
  181. package/src/types.ts +179 -76
  182. package/src/utils/are-elements-with-issues-equal.ts +11 -0
  183. package/src/utils/are-issue-sets-equal.test.ts +10 -6
  184. package/src/utils/are-issue-sets-equal.ts +8 -6
  185. package/src/utils/containing-blocks.ts +60 -0
  186. package/src/utils/contains.test.ts +54 -0
  187. package/src/utils/contains.ts +19 -0
  188. package/src/utils/deduplicate-nodes.ts +3 -0
  189. package/src/utils/deep-merge.test.ts +8 -1
  190. package/src/utils/deep-merge.ts +14 -8
  191. package/src/utils/dom-helpers.ts +42 -0
  192. package/src/utils/ensure-non-empty.ts +6 -0
  193. package/src/utils/get-element-html.ts +4 -2
  194. package/src/utils/get-element-position.ts +84 -16
  195. package/src/utils/get-parent.ts +14 -0
  196. package/src/utils/get-scan-context.test.ts +85 -0
  197. package/src/utils/get-scan-context.ts +36 -0
  198. package/src/utils/get-scrollable-ancestors.ts +15 -7
  199. package/src/utils/is-node-in-scan-context.test.ts +70 -0
  200. package/src/utils/is-node-in-scan-context.ts +29 -0
  201. package/src/utils/is-non-empty.ts +3 -0
  202. package/src/utils/normalize-context.test.ts +105 -0
  203. package/src/utils/normalize-context.ts +65 -0
  204. package/src/utils/recalculate-positions.ts +5 -5
  205. package/src/utils/recalculate-scrollable-ancestors.ts +4 -4
  206. package/src/utils/shadow-dom-aware-mutation-observer.ts +75 -0
  207. package/src/utils/supports-anchor-positioning.ts +3 -3
  208. package/src/utils/transform-violations.test.ts +28 -24
  209. package/src/utils/transform-violations.ts +30 -12
  210. package/src/utils/update-elements-with-issues.test.ts +139 -51
  211. package/src/utils/update-elements-with-issues.ts +123 -54
  212. package/src/validate-options.ts +154 -14
@@ -1,7 +1,7 @@
1
1
  type WindowWithCSS = Window & {
2
- CSS: typeof CSS
3
- }
2
+ CSS: typeof CSS;
3
+ };
4
4
 
5
- export default function supportsAnchorPositioning(win: WindowWithCSS) {
5
+ export function supportsAnchorPositioning(win: WindowWithCSS) {
6
6
  return win.CSS.supports('anchor-name: --foo') && win.CSS.supports('position-anchor: --foo');
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import assert from 'node:assert/strict';
2
- import {suite, test} from 'node:test';
3
- import transformViolations from './transform-violations';
2
+ import { suite, test } from 'node:test';
3
+ import { transformViolations } from './transform-violations';
4
4
 
5
5
  import type { AxeResults } from 'axe-core';
6
6
  type Violation = AxeResults['violations'][number];
@@ -12,7 +12,7 @@ const commonViolationProps1: Omit<Violation, 'nodes'> = {
12
12
  helpUrl: 'http://example.com',
13
13
  description: 'description1',
14
14
  tags: [],
15
- impact: 'serious'
15
+ impact: 'serious',
16
16
  };
17
17
 
18
18
  const commonViolationProps2: Omit<Violation, 'nodes'> = {
@@ -21,51 +21,53 @@ const commonViolationProps2: Omit<Violation, 'nodes'> = {
21
21
  helpUrl: 'http://example.com',
22
22
  description: 'description2',
23
23
  tags: [],
24
- impact: 'serious'
24
+ impact: 'serious',
25
25
  };
26
26
 
27
+ const getRootNode = (): Node => ({}) as Node;
28
+
27
29
  // @ts-expect-error element is not HTMLElement
28
- const element1: HTMLElement = {};
30
+ const element1: HTMLElement = { getRootNode };
29
31
  // @ts-expect-error element is not HTMLElement
30
- const element2: HTMLElement = {};
32
+ const element2: HTMLElement = { getRootNode };
31
33
  // @ts-expect-error element is not HTMLElement
32
- const element3: HTMLElement = {};
34
+ const element3: HTMLElement = { getRootNode };
33
35
 
34
36
  const commonNodeProps = {
35
37
  html: '<div></div>',
36
38
  any: [],
37
39
  all: [],
38
- none: []
40
+ none: [],
39
41
  };
40
42
 
41
43
  const node1: Node = {
42
44
  ...commonNodeProps,
43
45
  element: element1,
44
46
  target: ['div'],
45
- failureSummary: 'summary1'
47
+ failureSummary: 'summary1',
46
48
  };
47
49
 
48
50
  const node2: Node = {
49
51
  ...commonNodeProps,
50
52
  element: element2,
51
53
  target: ['div'],
52
- failureSummary: 'summary2'
54
+ failureSummary: 'summary2',
53
55
  };
54
56
 
55
57
  const node3: Node = {
56
58
  ...commonNodeProps,
57
59
  element: element3,
58
60
  target: ['div'],
59
- failureSummary: 'summary3'
61
+ failureSummary: 'summary3',
60
62
  };
61
63
 
62
64
  suite('transformViolations', () => {
63
65
  test('one violation, one element', () => {
64
66
  const violation: Violation = {
65
67
  ...commonViolationProps1,
66
- nodes: [node1]
68
+ nodes: [node1],
67
69
  };
68
- const elementsWithIssues = transformViolations([violation]);
70
+ const elementsWithIssues = transformViolations([violation], 'accented');
69
71
  assert.equal(elementsWithIssues.length, 1);
70
72
  assert.equal(elementsWithIssues[0]?.element, element1);
71
73
  assert.equal(elementsWithIssues[0].issues.length, 1);
@@ -76,15 +78,17 @@ suite('transformViolations', () => {
76
78
  test('two violations, two elements each', () => {
77
79
  const violation1: Violation = {
78
80
  ...commonViolationProps1,
79
- nodes: [node1, node2]
81
+ nodes: [node1, node2],
80
82
  };
81
83
  const violation2: Violation = {
82
84
  ...commonViolationProps2,
83
- nodes: [node1, node3]
85
+ nodes: [node1, node3],
84
86
  };
85
- const elementsWithIssues = transformViolations([violation1, violation2]);
87
+ const elementsWithIssues = transformViolations([violation1, violation2], 'accented');
86
88
  assert.equal(elementsWithIssues.length, 3);
87
- const elementWithTwoIssues = elementsWithIssues.find(elementWithIssues => elementWithIssues.element === element1);
89
+ const elementWithTwoIssues = elementsWithIssues.find(
90
+ (elementWithIssues) => elementWithIssues.element === element1,
91
+ );
88
92
  assert.equal(elementWithTwoIssues?.issues.length, 2);
89
93
  });
90
94
 
@@ -94,14 +98,14 @@ suite('transformViolations', () => {
94
98
  element: element1,
95
99
  // A target array whose length is > 1 signifies an element in an iframe
96
100
  target: ['iframe', 'div'],
97
- failureSummary: 'summary1'
101
+ failureSummary: 'summary1',
98
102
  };
99
103
  const violation: Violation = {
100
104
  ...commonViolationProps1,
101
- nodes: [node]
105
+ nodes: [node],
102
106
  };
103
107
 
104
- const elementsWithIssues = transformViolations([violation]);
108
+ const elementsWithIssues = transformViolations([violation], 'accented');
105
109
  assert.equal(elementsWithIssues.length, 0);
106
110
  });
107
111
 
@@ -111,14 +115,14 @@ suite('transformViolations', () => {
111
115
  element: element1,
112
116
  // A target that contains an array within the outer array signifies an element in shadow DOM
113
117
  target: [['div', 'div']],
114
- failureSummary: 'summary1'
118
+ failureSummary: 'summary1',
115
119
  };
116
120
  const violation: Violation = {
117
121
  ...commonViolationProps1,
118
- nodes: [node]
122
+ nodes: [node],
119
123
  };
120
124
 
121
- const elementsWithIssues = transformViolations([violation]);
122
- assert.equal(elementsWithIssues.length, 0);
125
+ const elementsWithIssues = transformViolations([violation], 'accented');
126
+ assert.equal(elementsWithIssues.length, 1);
123
127
  });
124
128
  });
@@ -1,12 +1,31 @@
1
1
  import type { AxeResults, ImpactValue } from 'axe-core';
2
- import type { Issue, ElementWithIssues } from '../types';
2
+ import type { ElementWithIssues, Issue } from '../types.ts';
3
+
4
+ // This is a list of axe-core violations (their ids) that may be flagged by axe-core
5
+ // as false positives if an Accented trigger is a descendant of the element with the issue.
6
+ const violationsAffectedByAccentedTriggers = [
7
+ 'aria-hidden-focus',
8
+ 'aria-text',
9
+ 'definition-list',
10
+ 'label-content-name-mismatch',
11
+ 'list',
12
+ 'nested-interactive',
13
+ 'scrollable-region-focusable', // The Accented trigger might make the content grow such that scrolling is required.
14
+ ];
15
+
16
+ function maybeCausedByAccented(violationId: string, element: HTMLElement, name: string) {
17
+ return (
18
+ violationsAffectedByAccentedTriggers.includes(violationId) &&
19
+ Boolean(element.querySelector(`${name}-trigger`))
20
+ );
21
+ }
3
22
 
4
23
  function impactCompare(a: ImpactValue, b: ImpactValue) {
5
24
  const impactOrder = [null, 'minor', 'moderate', 'serious', 'critical'];
6
25
  return impactOrder.indexOf(a) - impactOrder.indexOf(b);
7
26
  }
8
27
 
9
- export default function transformViolations(violations: typeof AxeResults.violations) {
28
+ export function transformViolations(violations: typeof AxeResults.violations, name: string) {
10
29
  const elementsWithIssues: Array<ElementWithIssues> = [];
11
30
 
12
31
  for (const violation of violations) {
@@ -21,26 +40,25 @@ export default function transformViolations(violations: typeof AxeResults.violat
21
40
  // A consumer of Accented can instead scan the iframed document by calling Accented initialization from that document.
22
41
  const isInIframe = target.length > 1;
23
42
 
24
- // Highlighting elements in shadow DOM is not yet supported, see https://github.com/pomerantsev/accented/issues/25
25
- // Until then, we don’t want such elements to be added to the set.
26
- const isInShadowDOM = Array.isArray(target[0]);
27
-
28
- if (element && !isInIframe && !isInShadowDOM) {
43
+ if (element && !isInIframe && !maybeCausedByAccented(violation.id, element, name)) {
29
44
  const issue: Issue = {
30
45
  id: violation.id,
31
46
  title: violation.help,
32
47
  description: node.failureSummary ?? violation.description,
33
48
  url: violation.helpUrl,
34
- impact: violation.impact ?? null
49
+ impact: violation.impact ?? null,
35
50
  };
36
- const existingElementIndex = elementsWithIssues.findIndex(elementWithIssues => elementWithIssues.element === element);
37
- if (existingElementIndex === -1) {
51
+ const existingElement = elementsWithIssues.find(
52
+ (elementWithIssues) => elementWithIssues.element === element,
53
+ );
54
+ if (existingElement === undefined) {
38
55
  elementsWithIssues.push({
39
56
  element,
40
- issues: [issue]
57
+ rootNode: element.getRootNode(),
58
+ issues: [issue],
41
59
  });
42
60
  } else {
43
- elementsWithIssues[existingElementIndex]!.issues.push(issue);
61
+ existingElement.issues.push(issue);
44
62
  }
45
63
  }
46
64
  }
@@ -1,51 +1,68 @@
1
- import {suite, test} from 'node:test';
2
1
  import assert from 'node:assert/strict';
2
+ import { suite, test } from 'node:test';
3
3
  import type { Signal } from '@preact/signals-core';
4
4
  import { signal } from '@preact/signals-core';
5
5
  import type { ExtendedElementWithIssues, Issue } from '../types';
6
- import updateElementsWithIssues from './update-elements-with-issues';
6
+ import { updateElementsWithIssues } from './update-elements-with-issues';
7
7
 
8
8
  import type { AxeResults, ImpactValue } from 'axe-core';
9
9
  import type { AccentedTrigger } from '../elements/accented-trigger';
10
10
  type Violation = AxeResults['violations'][number];
11
- type Node = Violation['nodes'][number];
11
+ type AxeNode = Violation['nodes'][number];
12
12
 
13
13
  const win: Window & { CSS: typeof CSS } = {
14
14
  document: {
15
15
  // @ts-expect-error the return value is of incorrect type.
16
16
  createElement: () => ({
17
17
  style: {
18
- setProperty: () => {}
18
+ setProperty: () => {},
19
19
  },
20
- dataset: {}
21
- })
20
+ dataset: {},
21
+ }),
22
+ contains: () => true,
22
23
  },
23
24
  // @ts-expect-error we're missing a lot of properties
24
25
  getComputedStyle: () => ({
25
26
  zIndex: '',
26
- direction: 'ltr'
27
+ direction: 'ltr',
28
+ getPropertyValue: () => 'none',
27
29
  }),
28
30
  // @ts-expect-error we're missing a lot of properties
29
31
  CSS: {
30
- supports: () => true
31
- }
32
- }
32
+ supports: () => true,
33
+ },
34
+ };
33
35
 
34
36
  const getBoundingClientRect = () => ({});
35
37
 
38
+ const getRootNode = (): Node => ({}) as Node;
39
+
40
+ const baseElement = {
41
+ getBoundingClientRect,
42
+ getRootNode,
43
+ style: {
44
+ getPropertyValue: () => '',
45
+ },
46
+ closest: () => null,
47
+ };
48
+
36
49
  // @ts-expect-error element is not HTMLElement
37
- const element1: HTMLElement = {getBoundingClientRect, isConnected: true};
50
+ const element1: HTMLElement = { ...baseElement, isConnected: true };
38
51
  // @ts-expect-error element is not HTMLElement
39
- const element2: HTMLElement = {getBoundingClientRect, isConnected: true};
52
+ const element2: HTMLElement = { ...baseElement, isConnected: true };
40
53
  // @ts-expect-error element is not HTMLElement
41
- const element3: HTMLElement = {getBoundingClientRect, isConnected: false};
54
+ const element3: HTMLElement = { ...baseElement, isConnected: false };
55
+
56
+ // @ts-expect-error rootNode is not Node
57
+ const rootNode: Node = {};
42
58
 
43
59
  const trigger = win.document.createElement('accented-trigger') as AccentedTrigger;
44
60
 
45
61
  const position = signal({
46
- inlineEndLeft: 0,
47
- blockStartTop: 0,
48
- direction: 'ltr' as const
62
+ left: 0,
63
+ width: 100,
64
+ top: 0,
65
+ height: 100,
49
66
  });
50
67
 
51
68
  const visible = signal(true);
@@ -57,20 +74,20 @@ const commonNodeProps = {
57
74
  any: [],
58
75
  all: [],
59
76
  none: [],
60
- target: ['div']
77
+ target: ['div'],
61
78
  };
62
79
 
63
- const node1: Node = {
80
+ const node1: AxeNode = {
64
81
  ...commonNodeProps,
65
82
  element: element1,
66
83
  };
67
84
 
68
- const node2: Node = {
85
+ const node2: AxeNode = {
69
86
  ...commonNodeProps,
70
87
  element: element2,
71
88
  };
72
89
 
73
- const node3: Node = {
90
+ const node3: AxeNode = {
74
91
  ...commonNodeProps,
75
92
  element: element3,
76
93
  };
@@ -80,53 +97,58 @@ const commonViolationProps = {
80
97
  helpUrl: 'http://example.com',
81
98
  description: 'description',
82
99
  tags: [],
83
- impact: 'serious' as ImpactValue
100
+ impact: 'serious' as ImpactValue,
84
101
  };
85
102
 
86
103
  const violation1: Violation = {
87
104
  ...commonViolationProps,
88
105
  id: 'id1',
89
- nodes: [node1]
106
+ nodes: [node1],
90
107
  };
91
108
 
92
109
  const violation2: Violation = {
93
110
  ...commonViolationProps,
94
111
  id: 'id2',
95
- nodes: [node2]
112
+ nodes: [node2],
96
113
  };
97
114
 
98
115
  const violation3: Violation = {
99
116
  ...commonViolationProps,
100
117
  id: 'id3',
101
- nodes: [node2]
118
+ nodes: [node2],
102
119
  };
103
120
 
104
121
  const violation4: Violation = {
105
122
  ...commonViolationProps,
106
123
  id: 'id4',
107
- nodes: [node3]
124
+ nodes: [node3],
108
125
  };
109
126
 
110
127
  const commonIssueProps = {
111
128
  title: 'help',
112
129
  description: 'description',
113
130
  url: 'http://example.com',
114
- impact: 'serious'
131
+ impact: 'serious',
115
132
  } as const;
116
133
 
117
134
  const issue1: Issue = {
118
135
  id: 'id1',
119
- ...commonIssueProps
136
+ ...commonIssueProps,
120
137
  };
121
138
 
122
139
  const issue2: Issue = {
123
140
  id: 'id2',
124
- ...commonIssueProps
141
+ ...commonIssueProps,
125
142
  };
126
143
 
127
144
  const issue3: Issue = {
128
145
  id: 'id3',
129
- ...commonIssueProps
146
+ ...commonIssueProps,
147
+ };
148
+
149
+ const scanContext = {
150
+ include: [win.document],
151
+ exclude: [],
130
152
  };
131
153
 
132
154
  suite('updateElementsWithIssues', () => {
@@ -135,23 +157,35 @@ suite('updateElementsWithIssues', () => {
135
157
  {
136
158
  id: 1,
137
159
  element: element1,
160
+ rootNode,
161
+ skipRender: false,
138
162
  position,
139
163
  visible,
140
164
  trigger,
165
+ anchorNameValue: 'none',
141
166
  scrollableAncestors,
142
- issues: signal([issue1])
167
+ issues: signal([issue1]),
143
168
  },
144
169
  {
145
170
  id: 2,
146
171
  element: element2,
172
+ rootNode,
173
+ skipRender: false,
147
174
  position,
148
175
  visible,
149
176
  trigger,
177
+ anchorNameValue: 'none',
150
178
  scrollableAncestors,
151
- issues: signal([issue2])
152
- }
179
+ issues: signal([issue2]),
180
+ },
153
181
  ]);
154
- updateElementsWithIssues(extendedElementsWithIssues, [violation1, violation2], win, 'accented');
182
+ updateElementsWithIssues({
183
+ extendedElementsWithIssues,
184
+ scanContext,
185
+ violations: [violation1, violation2],
186
+ win,
187
+ name: 'accented',
188
+ });
155
189
  assert.equal(extendedElementsWithIssues.value.length, 2);
156
190
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
157
191
  assert.equal(extendedElementsWithIssues.value[0]?.issues.value.length, 1);
@@ -164,23 +198,35 @@ suite('updateElementsWithIssues', () => {
164
198
  {
165
199
  id: 1,
166
200
  element: element1,
201
+ rootNode,
202
+ skipRender: false,
167
203
  position,
168
204
  visible,
169
205
  trigger,
206
+ anchorNameValue: 'none',
170
207
  scrollableAncestors,
171
- issues: signal([issue1])
208
+ issues: signal([issue1]),
172
209
  },
173
210
  {
174
211
  id: 2,
175
212
  element: element2,
213
+ rootNode,
214
+ skipRender: false,
176
215
  position,
177
216
  visible,
178
217
  trigger,
218
+ anchorNameValue: 'none',
179
219
  scrollableAncestors,
180
- issues: signal([issue2])
181
- }
220
+ issues: signal([issue2]),
221
+ },
182
222
  ]);
183
- updateElementsWithIssues(extendedElementsWithIssues, [violation1, violation2, violation3], win, 'accented');
223
+ updateElementsWithIssues({
224
+ extendedElementsWithIssues,
225
+ scanContext,
226
+ violations: [violation1, violation2, violation3],
227
+ win,
228
+ name: 'accented',
229
+ });
184
230
  assert.equal(extendedElementsWithIssues.value.length, 2);
185
231
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
186
232
  assert.equal(extendedElementsWithIssues.value[0]?.issues.value.length, 1);
@@ -193,23 +239,35 @@ suite('updateElementsWithIssues', () => {
193
239
  {
194
240
  id: 1,
195
241
  element: element1,
242
+ rootNode,
243
+ skipRender: false,
196
244
  position,
197
245
  visible,
198
246
  trigger,
247
+ anchorNameValue: 'none',
199
248
  scrollableAncestors,
200
- issues: signal([issue1])
249
+ issues: signal([issue1]),
201
250
  },
202
251
  {
203
252
  id: 2,
204
253
  element: element2,
254
+ rootNode,
255
+ skipRender: false,
205
256
  position,
206
257
  visible,
207
258
  trigger,
259
+ anchorNameValue: 'none',
208
260
  scrollableAncestors,
209
- issues: signal([issue2, issue3])
210
- }
261
+ issues: signal([issue2, issue3]),
262
+ },
211
263
  ]);
212
- updateElementsWithIssues(extendedElementsWithIssues, [violation1, violation2], win, 'accented');
264
+ updateElementsWithIssues({
265
+ extendedElementsWithIssues,
266
+ scanContext,
267
+ violations: [violation1, violation2],
268
+ win,
269
+ name: 'accented',
270
+ });
213
271
  assert.equal(extendedElementsWithIssues.value.length, 2);
214
272
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
215
273
  assert.equal(extendedElementsWithIssues.value[0]?.issues.value.length, 1);
@@ -222,14 +280,23 @@ suite('updateElementsWithIssues', () => {
222
280
  {
223
281
  id: 1,
224
282
  element: element1,
283
+ rootNode,
284
+ skipRender: false,
225
285
  position,
226
286
  visible,
227
287
  trigger,
288
+ anchorNameValue: 'none',
228
289
  scrollableAncestors,
229
- issues: signal([issue1])
230
- }
290
+ issues: signal([issue1]),
291
+ },
231
292
  ]);
232
- updateElementsWithIssues(extendedElementsWithIssues, [violation1, violation2], win, 'accented');
293
+ updateElementsWithIssues({
294
+ extendedElementsWithIssues,
295
+ scanContext,
296
+ violations: [violation1, violation2],
297
+ win,
298
+ name: 'accented',
299
+ });
233
300
  assert.equal(extendedElementsWithIssues.value.length, 2);
234
301
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
235
302
  assert.equal(extendedElementsWithIssues.value[0]?.issues.value.length, 1);
@@ -242,14 +309,23 @@ suite('updateElementsWithIssues', () => {
242
309
  {
243
310
  id: 1,
244
311
  element: element1,
312
+ rootNode,
313
+ skipRender: false,
245
314
  position,
246
315
  visible,
247
316
  trigger,
317
+ anchorNameValue: 'none',
248
318
  scrollableAncestors,
249
- issues: signal([issue1])
250
- }
319
+ issues: signal([issue1]),
320
+ },
251
321
  ]);
252
- updateElementsWithIssues(extendedElementsWithIssues, [violation1, violation4], win, 'accented');
322
+ updateElementsWithIssues({
323
+ extendedElementsWithIssues,
324
+ scanContext,
325
+ violations: [violation1, violation4],
326
+ win,
327
+ name: 'accented',
328
+ });
253
329
  assert.equal(extendedElementsWithIssues.value.length, 1);
254
330
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
255
331
  });
@@ -259,23 +335,35 @@ suite('updateElementsWithIssues', () => {
259
335
  {
260
336
  id: 1,
261
337
  element: element1,
338
+ rootNode,
339
+ skipRender: false,
262
340
  position,
263
341
  visible,
264
342
  trigger,
343
+ anchorNameValue: 'none',
265
344
  scrollableAncestors,
266
- issues: signal([issue1])
345
+ issues: signal([issue1]),
267
346
  },
268
347
  {
269
348
  id: 2,
270
349
  element: element2,
350
+ rootNode,
351
+ skipRender: false,
271
352
  position,
272
353
  visible,
273
354
  trigger,
355
+ anchorNameValue: 'none',
274
356
  scrollableAncestors,
275
- issues: signal([issue2])
276
- }
357
+ issues: signal([issue2]),
358
+ },
277
359
  ]);
278
- updateElementsWithIssues(extendedElementsWithIssues, [violation1], win, 'accented');
360
+ updateElementsWithIssues({
361
+ extendedElementsWithIssues,
362
+ scanContext,
363
+ violations: [violation1],
364
+ win,
365
+ name: 'accented',
366
+ });
279
367
  assert.equal(extendedElementsWithIssues.value.length, 1);
280
368
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
281
369
  assert.equal(extendedElementsWithIssues.value[0]?.issues.value.length, 1);