accented 0.0.0-20250424114613 → 0.0.0-20250618181418

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 (201) hide show
  1. package/README.md +0 -209
  2. package/dist/accented.d.ts +2 -2
  3. package/dist/accented.d.ts.map +1 -1
  4. package/dist/accented.js +24 -20
  5. package/dist/accented.js.map +1 -1
  6. package/dist/common/tokens.d.ts +2 -0
  7. package/dist/common/tokens.d.ts.map +1 -0
  8. package/dist/common/tokens.js +2 -0
  9. package/dist/common/tokens.js.map +1 -0
  10. package/dist/dom-updater.d.ts +1 -1
  11. package/dist/dom-updater.d.ts.map +1 -1
  12. package/dist/dom-updater.js +14 -13
  13. package/dist/dom-updater.js.map +1 -1
  14. package/dist/elements/accented-dialog.d.ts +2 -3
  15. package/dist/elements/accented-dialog.d.ts.map +1 -1
  16. package/dist/elements/accented-dialog.js +14 -8
  17. package/dist/elements/accented-dialog.js.map +1 -1
  18. package/dist/elements/accented-trigger.d.ts +3 -4
  19. package/dist/elements/accented-trigger.d.ts.map +1 -1
  20. package/dist/elements/accented-trigger.js +8 -10
  21. package/dist/elements/accented-trigger.js.map +1 -1
  22. package/dist/fullscreen-listener.d.ts +1 -1
  23. package/dist/fullscreen-listener.d.ts.map +1 -1
  24. package/dist/fullscreen-listener.js +3 -4
  25. package/dist/fullscreen-listener.js.map +1 -1
  26. package/dist/intersection-observer.d.ts +1 -1
  27. package/dist/intersection-observer.d.ts.map +1 -1
  28. package/dist/intersection-observer.js +12 -6
  29. package/dist/intersection-observer.js.map +1 -1
  30. package/dist/log-and-rethrow.d.ts +1 -1
  31. package/dist/log-and-rethrow.d.ts.map +1 -1
  32. package/dist/log-and-rethrow.js +2 -3
  33. package/dist/log-and-rethrow.js.map +1 -1
  34. package/dist/logger.d.ts +1 -1
  35. package/dist/logger.d.ts.map +1 -1
  36. package/dist/logger.js +2 -2
  37. package/dist/logger.js.map +1 -1
  38. package/dist/register-elements.d.ts +1 -1
  39. package/dist/register-elements.d.ts.map +1 -1
  40. package/dist/register-elements.js +6 -7
  41. package/dist/register-elements.js.map +1 -1
  42. package/dist/resize-listener.d.ts +1 -1
  43. package/dist/resize-listener.d.ts.map +1 -1
  44. package/dist/resize-listener.js +3 -4
  45. package/dist/resize-listener.js.map +1 -1
  46. package/dist/scanner.d.ts +2 -2
  47. package/dist/scanner.d.ts.map +1 -1
  48. package/dist/scanner.js +25 -27
  49. package/dist/scanner.js.map +1 -1
  50. package/dist/scroll-listeners.d.ts +1 -1
  51. package/dist/scroll-listeners.d.ts.map +1 -1
  52. package/dist/scroll-listeners.js +3 -4
  53. package/dist/scroll-listeners.js.map +1 -1
  54. package/dist/state.d.ts +1 -1
  55. package/dist/state.d.ts.map +1 -1
  56. package/dist/state.js +4 -5
  57. package/dist/state.js.map +1 -1
  58. package/dist/task-queue.d.ts +2 -2
  59. package/dist/task-queue.d.ts.map +1 -1
  60. package/dist/task-queue.js +1 -1
  61. package/dist/task-queue.js.map +1 -1
  62. package/dist/types.d.ts +3 -3
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/utils/are-elements-with-issues-equal.d.ts +2 -2
  65. package/dist/utils/are-elements-with-issues-equal.d.ts.map +1 -1
  66. package/dist/utils/are-elements-with-issues-equal.js +3 -3
  67. package/dist/utils/are-elements-with-issues-equal.js.map +1 -1
  68. package/dist/utils/are-issue-sets-equal.d.ts +2 -2
  69. package/dist/utils/are-issue-sets-equal.d.ts.map +1 -1
  70. package/dist/utils/are-issue-sets-equal.js +3 -3
  71. package/dist/utils/are-issue-sets-equal.js.map +1 -1
  72. package/dist/utils/containing-blocks.d.ts.map +1 -1
  73. package/dist/utils/containing-blocks.js +1 -1
  74. package/dist/utils/containing-blocks.js.map +1 -1
  75. package/dist/utils/contains.d.ts +1 -1
  76. package/dist/utils/contains.d.ts.map +1 -1
  77. package/dist/utils/contains.js +1 -1
  78. package/dist/utils/contains.js.map +1 -1
  79. package/dist/utils/deduplicate-nodes.js +0 -1
  80. package/dist/utils/deduplicate-nodes.js.map +1 -1
  81. package/dist/utils/deep-merge.d.ts +1 -1
  82. package/dist/utils/deep-merge.d.ts.map +1 -1
  83. package/dist/utils/deep-merge.js +6 -5
  84. package/dist/utils/deep-merge.js.map +1 -1
  85. package/dist/utils/dom-helpers.d.ts.map +1 -1
  86. package/dist/utils/dom-helpers.js +4 -2
  87. package/dist/utils/dom-helpers.js.map +1 -1
  88. package/dist/utils/ensure-non-empty.d.ts +1 -1
  89. package/dist/utils/ensure-non-empty.d.ts.map +1 -1
  90. package/dist/utils/ensure-non-empty.js +2 -2
  91. package/dist/utils/ensure-non-empty.js.map +1 -1
  92. package/dist/utils/get-element-html.d.ts +1 -1
  93. package/dist/utils/get-element-html.d.ts.map +1 -1
  94. package/dist/utils/get-element-html.js +4 -2
  95. package/dist/utils/get-element-html.js.map +1 -1
  96. package/dist/utils/get-element-position.d.ts +2 -2
  97. package/dist/utils/get-element-position.d.ts.map +1 -1
  98. package/dist/utils/get-element-position.js +21 -25
  99. package/dist/utils/get-element-position.js.map +1 -1
  100. package/dist/utils/get-parent.d.ts +1 -1
  101. package/dist/utils/get-parent.d.ts.map +1 -1
  102. package/dist/utils/get-parent.js +1 -1
  103. package/dist/utils/get-parent.js.map +1 -1
  104. package/dist/utils/get-scan-context.d.ts +2 -2
  105. package/dist/utils/get-scan-context.d.ts.map +1 -1
  106. package/dist/utils/get-scan-context.js +9 -9
  107. package/dist/utils/get-scan-context.js.map +1 -1
  108. package/dist/utils/get-scrollable-ancestors.d.ts +1 -1
  109. package/dist/utils/get-scrollable-ancestors.d.ts.map +1 -1
  110. package/dist/utils/get-scrollable-ancestors.js +5 -5
  111. package/dist/utils/get-scrollable-ancestors.js.map +1 -1
  112. package/dist/utils/is-node-in-scan-context.d.ts +2 -2
  113. package/dist/utils/is-node-in-scan-context.d.ts.map +1 -1
  114. package/dist/utils/is-node-in-scan-context.js +5 -5
  115. package/dist/utils/is-node-in-scan-context.js.map +1 -1
  116. package/dist/utils/is-non-empty.d.ts +2 -0
  117. package/dist/utils/is-non-empty.d.ts.map +1 -0
  118. package/dist/utils/is-non-empty.js +4 -0
  119. package/dist/utils/is-non-empty.js.map +1 -0
  120. package/dist/utils/normalize-context.d.ts +2 -2
  121. package/dist/utils/normalize-context.d.ts.map +1 -1
  122. package/dist/utils/normalize-context.js +10 -8
  123. package/dist/utils/normalize-context.js.map +1 -1
  124. package/dist/utils/recalculate-positions.d.ts +1 -1
  125. package/dist/utils/recalculate-positions.d.ts.map +1 -1
  126. package/dist/utils/recalculate-positions.js +5 -5
  127. package/dist/utils/recalculate-positions.js.map +1 -1
  128. package/dist/utils/recalculate-scrollable-ancestors.d.ts +1 -1
  129. package/dist/utils/recalculate-scrollable-ancestors.d.ts.map +1 -1
  130. package/dist/utils/recalculate-scrollable-ancestors.js +4 -4
  131. package/dist/utils/recalculate-scrollable-ancestors.js.map +1 -1
  132. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts +1 -1
  133. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -1
  134. package/dist/utils/shadow-dom-aware-mutation-observer.js +19 -22
  135. package/dist/utils/shadow-dom-aware-mutation-observer.js.map +1 -1
  136. package/dist/utils/supports-anchor-positioning.d.ts +1 -1
  137. package/dist/utils/supports-anchor-positioning.d.ts.map +1 -1
  138. package/dist/utils/supports-anchor-positioning.js +1 -1
  139. package/dist/utils/supports-anchor-positioning.js.map +1 -1
  140. package/dist/utils/transform-violations.d.ts +2 -2
  141. package/dist/utils/transform-violations.d.ts.map +1 -1
  142. package/dist/utils/transform-violations.js +9 -9
  143. package/dist/utils/transform-violations.js.map +1 -1
  144. package/dist/utils/update-elements-with-issues.d.ts +3 -3
  145. package/dist/utils/update-elements-with-issues.d.ts.map +1 -1
  146. package/dist/utils/update-elements-with-issues.js +34 -29
  147. package/dist/utils/update-elements-with-issues.js.map +1 -1
  148. package/dist/validate-options.d.ts +2 -2
  149. package/dist/validate-options.d.ts.map +1 -1
  150. package/dist/validate-options.js +24 -23
  151. package/dist/validate-options.js.map +1 -1
  152. package/package.json +5 -3
  153. package/src/accented.test.ts +2 -2
  154. package/src/accented.ts +34 -26
  155. package/src/common/tokens.ts +1 -0
  156. package/src/dom-updater.ts +26 -19
  157. package/src/elements/accented-dialog.ts +69 -43
  158. package/src/elements/accented-trigger.ts +52 -43
  159. package/src/fullscreen-listener.ts +15 -11
  160. package/src/intersection-observer.ts +27 -16
  161. package/src/log-and-rethrow.ts +2 -3
  162. package/src/logger.ts +8 -6
  163. package/src/register-elements.ts +7 -7
  164. package/src/resize-listener.ts +15 -11
  165. package/src/scanner.ts +55 -41
  166. package/src/scroll-listeners.ts +27 -19
  167. package/src/state.ts +24 -21
  168. package/src/task-queue.test.ts +5 -4
  169. package/src/task-queue.ts +2 -2
  170. package/src/types.ts +52 -53
  171. package/src/utils/are-elements-with-issues-equal.ts +7 -5
  172. package/src/utils/are-issue-sets-equal.test.ts +10 -6
  173. package/src/utils/are-issue-sets-equal.ts +8 -6
  174. package/src/utils/containing-blocks.ts +6 -3
  175. package/src/utils/contains.test.ts +2 -2
  176. package/src/utils/contains.ts +1 -1
  177. package/src/utils/deduplicate-nodes.ts +1 -1
  178. package/src/utils/deep-merge.test.ts +8 -1
  179. package/src/utils/deep-merge.ts +11 -8
  180. package/src/utils/dom-helpers.ts +6 -2
  181. package/src/utils/ensure-non-empty.ts +2 -2
  182. package/src/utils/get-element-html.ts +4 -2
  183. package/src/utils/get-element-position.ts +37 -24
  184. package/src/utils/get-parent.ts +1 -1
  185. package/src/utils/get-scan-context.test.ts +14 -8
  186. package/src/utils/get-scan-context.ts +12 -15
  187. package/src/utils/get-scrollable-ancestors.ts +8 -5
  188. package/src/utils/is-node-in-scan-context.test.ts +3 -3
  189. package/src/utils/is-node-in-scan-context.ts +6 -6
  190. package/src/utils/is-non-empty.ts +3 -0
  191. package/src/utils/normalize-context.test.ts +9 -9
  192. package/src/utils/normalize-context.ts +17 -10
  193. package/src/utils/recalculate-positions.ts +5 -5
  194. package/src/utils/recalculate-scrollable-ancestors.ts +4 -4
  195. package/src/utils/shadow-dom-aware-mutation-observer.ts +21 -24
  196. package/src/utils/supports-anchor-positioning.ts +3 -3
  197. package/src/utils/transform-violations.test.ts +22 -20
  198. package/src/utils/transform-violations.ts +14 -10
  199. package/src/utils/update-elements-with-issues.test.ts +49 -49
  200. package/src/utils/update-elements-with-issues.ts +96 -71
  201. package/src/validate-options.ts +91 -38
@@ -1,9 +1,9 @@
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';
@@ -15,9 +15,9 @@ const win: Window & { CSS: typeof CSS } = {
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: {}
20
+ dataset: {},
21
21
  }),
22
22
  contains: () => true,
23
23
  },
@@ -25,33 +25,33 @@ const win: Window & { CSS: typeof CSS } = {
25
25
  getComputedStyle: () => ({
26
26
  zIndex: '',
27
27
  direction: 'ltr',
28
- getPropertyValue: () => 'none'
28
+ getPropertyValue: () => 'none',
29
29
  }),
30
30
  // @ts-expect-error we're missing a lot of properties
31
31
  CSS: {
32
- supports: () => true
33
- }
34
- }
32
+ supports: () => true,
33
+ },
34
+ };
35
35
 
36
36
  const getBoundingClientRect = () => ({});
37
37
 
38
- const getRootNode = (): Node => ({} as Node);
38
+ const getRootNode = (): Node => ({}) as Node;
39
39
 
40
40
  const baseElement = {
41
41
  getBoundingClientRect,
42
42
  getRootNode,
43
43
  style: {
44
- getPropertyValue: () => ''
44
+ getPropertyValue: () => '',
45
45
  },
46
46
  closest: () => null,
47
- }
47
+ };
48
48
 
49
49
  // @ts-expect-error element is not HTMLElement
50
- const element1: HTMLElement = {...baseElement, isConnected: true};
50
+ const element1: HTMLElement = { ...baseElement, isConnected: true };
51
51
  // @ts-expect-error element is not HTMLElement
52
- const element2: HTMLElement = {...baseElement, isConnected: true};
52
+ const element2: HTMLElement = { ...baseElement, isConnected: true };
53
53
  // @ts-expect-error element is not HTMLElement
54
- const element3: HTMLElement = {...baseElement, isConnected: false};
54
+ const element3: HTMLElement = { ...baseElement, isConnected: false };
55
55
 
56
56
  // @ts-expect-error rootNode is not Node
57
57
  const rootNode: Node = {};
@@ -62,7 +62,7 @@ const position = signal({
62
62
  left: 0,
63
63
  width: 100,
64
64
  top: 0,
65
- height: 100
65
+ height: 100,
66
66
  });
67
67
 
68
68
  const visible = signal(true);
@@ -74,7 +74,7 @@ const commonNodeProps = {
74
74
  any: [],
75
75
  all: [],
76
76
  none: [],
77
- target: ['div']
77
+ target: ['div'],
78
78
  };
79
79
 
80
80
  const node1: AxeNode = {
@@ -97,59 +97,59 @@ const commonViolationProps = {
97
97
  helpUrl: 'http://example.com',
98
98
  description: 'description',
99
99
  tags: [],
100
- impact: 'serious' as ImpactValue
100
+ impact: 'serious' as ImpactValue,
101
101
  };
102
102
 
103
103
  const violation1: Violation = {
104
104
  ...commonViolationProps,
105
105
  id: 'id1',
106
- nodes: [node1]
106
+ nodes: [node1],
107
107
  };
108
108
 
109
109
  const violation2: Violation = {
110
110
  ...commonViolationProps,
111
111
  id: 'id2',
112
- nodes: [node2]
112
+ nodes: [node2],
113
113
  };
114
114
 
115
115
  const violation3: Violation = {
116
116
  ...commonViolationProps,
117
117
  id: 'id3',
118
- nodes: [node2]
118
+ nodes: [node2],
119
119
  };
120
120
 
121
121
  const violation4: Violation = {
122
122
  ...commonViolationProps,
123
123
  id: 'id4',
124
- nodes: [node3]
124
+ nodes: [node3],
125
125
  };
126
126
 
127
127
  const commonIssueProps = {
128
128
  title: 'help',
129
129
  description: 'description',
130
130
  url: 'http://example.com',
131
- impact: 'serious'
131
+ impact: 'serious',
132
132
  } as const;
133
133
 
134
134
  const issue1: Issue = {
135
135
  id: 'id1',
136
- ...commonIssueProps
136
+ ...commonIssueProps,
137
137
  };
138
138
 
139
139
  const issue2: Issue = {
140
140
  id: 'id2',
141
- ...commonIssueProps
141
+ ...commonIssueProps,
142
142
  };
143
143
 
144
144
  const issue3: Issue = {
145
145
  id: 'id3',
146
- ...commonIssueProps
146
+ ...commonIssueProps,
147
147
  };
148
148
 
149
149
  const scanContext = {
150
150
  include: [win.document],
151
- exclude: []
152
- }
151
+ exclude: [],
152
+ };
153
153
 
154
154
  suite('updateElementsWithIssues', () => {
155
155
  test('no changes', () => {
@@ -164,7 +164,7 @@ suite('updateElementsWithIssues', () => {
164
164
  trigger,
165
165
  anchorNameValue: 'none',
166
166
  scrollableAncestors,
167
- issues: signal([issue1])
167
+ issues: signal([issue1]),
168
168
  },
169
169
  {
170
170
  id: 2,
@@ -176,15 +176,15 @@ suite('updateElementsWithIssues', () => {
176
176
  trigger,
177
177
  anchorNameValue: 'none',
178
178
  scrollableAncestors,
179
- issues: signal([issue2])
180
- }
179
+ issues: signal([issue2]),
180
+ },
181
181
  ]);
182
182
  updateElementsWithIssues({
183
183
  extendedElementsWithIssues,
184
184
  scanContext,
185
185
  violations: [violation1, violation2],
186
186
  win,
187
- name: 'accented'
187
+ name: 'accented',
188
188
  });
189
189
  assert.equal(extendedElementsWithIssues.value.length, 2);
190
190
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
@@ -205,7 +205,7 @@ suite('updateElementsWithIssues', () => {
205
205
  trigger,
206
206
  anchorNameValue: 'none',
207
207
  scrollableAncestors,
208
- issues: signal([issue1])
208
+ issues: signal([issue1]),
209
209
  },
210
210
  {
211
211
  id: 2,
@@ -217,15 +217,15 @@ suite('updateElementsWithIssues', () => {
217
217
  trigger,
218
218
  anchorNameValue: 'none',
219
219
  scrollableAncestors,
220
- issues: signal([issue2])
221
- }
220
+ issues: signal([issue2]),
221
+ },
222
222
  ]);
223
223
  updateElementsWithIssues({
224
224
  extendedElementsWithIssues,
225
225
  scanContext,
226
226
  violations: [violation1, violation2, violation3],
227
227
  win,
228
- name: 'accented'
228
+ name: 'accented',
229
229
  });
230
230
  assert.equal(extendedElementsWithIssues.value.length, 2);
231
231
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
@@ -246,7 +246,7 @@ suite('updateElementsWithIssues', () => {
246
246
  trigger,
247
247
  anchorNameValue: 'none',
248
248
  scrollableAncestors,
249
- issues: signal([issue1])
249
+ issues: signal([issue1]),
250
250
  },
251
251
  {
252
252
  id: 2,
@@ -258,15 +258,15 @@ suite('updateElementsWithIssues', () => {
258
258
  trigger,
259
259
  anchorNameValue: 'none',
260
260
  scrollableAncestors,
261
- issues: signal([issue2, issue3])
262
- }
261
+ issues: signal([issue2, issue3]),
262
+ },
263
263
  ]);
264
264
  updateElementsWithIssues({
265
265
  extendedElementsWithIssues,
266
266
  scanContext,
267
267
  violations: [violation1, violation2],
268
268
  win,
269
- name: 'accented'
269
+ name: 'accented',
270
270
  });
271
271
  assert.equal(extendedElementsWithIssues.value.length, 2);
272
272
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
@@ -287,15 +287,15 @@ suite('updateElementsWithIssues', () => {
287
287
  trigger,
288
288
  anchorNameValue: 'none',
289
289
  scrollableAncestors,
290
- issues: signal([issue1])
291
- }
290
+ issues: signal([issue1]),
291
+ },
292
292
  ]);
293
293
  updateElementsWithIssues({
294
294
  extendedElementsWithIssues,
295
295
  scanContext,
296
296
  violations: [violation1, violation2],
297
297
  win,
298
- name: 'accented'
298
+ name: 'accented',
299
299
  });
300
300
  assert.equal(extendedElementsWithIssues.value.length, 2);
301
301
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
@@ -316,15 +316,15 @@ suite('updateElementsWithIssues', () => {
316
316
  trigger,
317
317
  anchorNameValue: 'none',
318
318
  scrollableAncestors,
319
- issues: signal([issue1])
320
- }
319
+ issues: signal([issue1]),
320
+ },
321
321
  ]);
322
322
  updateElementsWithIssues({
323
323
  extendedElementsWithIssues,
324
324
  scanContext,
325
325
  violations: [violation1, violation4],
326
326
  win,
327
- name: 'accented'
327
+ name: 'accented',
328
328
  });
329
329
  assert.equal(extendedElementsWithIssues.value.length, 1);
330
330
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
@@ -342,7 +342,7 @@ suite('updateElementsWithIssues', () => {
342
342
  trigger,
343
343
  anchorNameValue: 'none',
344
344
  scrollableAncestors,
345
- issues: signal([issue1])
345
+ issues: signal([issue1]),
346
346
  },
347
347
  {
348
348
  id: 2,
@@ -354,15 +354,15 @@ suite('updateElementsWithIssues', () => {
354
354
  trigger,
355
355
  anchorNameValue: 'none',
356
356
  scrollableAncestors,
357
- issues: signal([issue2])
358
- }
357
+ issues: signal([issue2]),
358
+ },
359
359
  ]);
360
360
  updateElementsWithIssues({
361
361
  extendedElementsWithIssues,
362
362
  scanContext,
363
363
  violations: [violation1],
364
364
  win,
365
- name: 'accented'
365
+ name: 'accented',
366
366
  });
367
367
  assert.equal(extendedElementsWithIssues.value.length, 1);
368
368
  assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
@@ -1,21 +1,20 @@
1
- import type { AxeResults } from 'axe-core';
2
1
  import type { Signal } from '@preact/signals-core';
3
2
  import { batch, signal } from '@preact/signals-core';
4
- import type { ExtendedElementWithIssues, ScanContext } from '../types';
5
- import transformViolations from './transform-violations.js';
6
- import areElementsWithIssuesEqual from './are-elements-with-issues-equal.js';
7
- import areIssueSetsEqual from './are-issue-sets-equal.js';
8
- import isNodeInScanContext from './is-node-in-scan-context.js';
9
- import type { AccentedTrigger } from '../elements/accented-trigger';
10
- import type { AccentedDialog } from '../elements/accented-dialog';
11
- import getElementPosition from './get-element-position.js';
12
- import getScrollableAncestors from './get-scrollable-ancestors.js';
13
- import supportsAnchorPositioning from './supports-anchor-positioning.js';
3
+ import type { AxeResults } from 'axe-core';
4
+ import type { AccentedDialog } from '../elements/accented-dialog.ts';
5
+ import type { AccentedTrigger } from '../elements/accented-trigger.ts';
6
+ import type { ExtendedElementWithIssues, ScanContext } from '../types.ts';
7
+ import { areElementsWithIssuesEqual } from './are-elements-with-issues-equal.js';
8
+ import { areIssueSetsEqual } from './are-issue-sets-equal.js';
14
9
  import { isSvgElement } from './dom-helpers.js';
15
- import getParent from './get-parent.js';
10
+ import { getElementPosition } from './get-element-position.js';
11
+ import { getParent } from './get-parent.js';
12
+ import { getScrollableAncestors } from './get-scrollable-ancestors.js';
13
+ import { isNodeInScanContext } from './is-node-in-scan-context.js';
14
+ import { supportsAnchorPositioning } from './supports-anchor-positioning.js';
15
+ import { transformViolations } from './transform-violations.js';
16
16
 
17
17
  function shouldSkipRender(element: Element): boolean {
18
-
19
18
  // Skip rendering if the element is inside an SVG:
20
19
  // https://github.com/pomerantsev/accented/issues/62
21
20
  const parent = getParent(element);
@@ -33,86 +32,112 @@ function shouldSkipRender(element: Element): boolean {
33
32
 
34
33
  let count = 0;
35
34
 
36
- export default function updateElementsWithIssues({
35
+ export function updateElementsWithIssues({
37
36
  extendedElementsWithIssues,
38
37
  scanContext,
39
38
  violations,
40
39
  win,
41
- name
40
+ name,
42
41
  }: {
43
- extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>>,
44
- scanContext: ScanContext,
45
- violations: typeof AxeResults.violations,
46
- win: Window & { CSS: typeof CSS },
47
- name: string
42
+ extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>>;
43
+ scanContext: ScanContext;
44
+ violations: typeof AxeResults.violations;
45
+ win: Window & { CSS: typeof CSS };
46
+ name: string;
48
47
  }) {
49
48
  const updatedElementsWithIssues = transformViolations(violations, name);
50
49
 
51
50
  batch(() => {
52
51
  for (const updatedElementWithIssues of updatedElementsWithIssues) {
53
- const existingElementIndex = extendedElementsWithIssues.value.findIndex(extendedElementWithIssues => areElementsWithIssuesEqual(extendedElementWithIssues, updatedElementWithIssues));
54
- if (existingElementIndex > -1 && extendedElementsWithIssues.value[existingElementIndex] && !areIssueSetsEqual(extendedElementsWithIssues.value[existingElementIndex].issues.value, updatedElementWithIssues.issues)) {
55
- extendedElementsWithIssues.value[existingElementIndex].issues.value = updatedElementWithIssues.issues;
52
+ const existingElementIndex = extendedElementsWithIssues.value.findIndex(
53
+ (extendedElementWithIssues) =>
54
+ areElementsWithIssuesEqual(extendedElementWithIssues, updatedElementWithIssues),
55
+ );
56
+ if (
57
+ existingElementIndex > -1 &&
58
+ extendedElementsWithIssues.value[existingElementIndex] &&
59
+ !areIssueSetsEqual(
60
+ extendedElementsWithIssues.value[existingElementIndex].issues.value,
61
+ updatedElementWithIssues.issues,
62
+ )
63
+ ) {
64
+ extendedElementsWithIssues.value[existingElementIndex].issues.value =
65
+ updatedElementWithIssues.issues;
56
66
  }
57
67
  }
58
68
 
59
- const addedElementsWithIssues = updatedElementsWithIssues.filter(updatedElementWithIssues => {
60
- return !extendedElementsWithIssues.value.some(extendedElementWithIssues => areElementsWithIssuesEqual(extendedElementWithIssues, updatedElementWithIssues));
69
+ const addedElementsWithIssues = updatedElementsWithIssues.filter((updatedElementWithIssues) => {
70
+ return !extendedElementsWithIssues.value.some((extendedElementWithIssues) =>
71
+ areElementsWithIssuesEqual(extendedElementWithIssues, updatedElementWithIssues),
72
+ );
61
73
  });
62
74
 
63
75
  // Only consider an element to be removed in two cases:
64
76
  // 1. It has been removed from the DOM.
65
77
  // 2. It is within the scan context, but not among updatedElementsWithIssues.
66
- const removedElementsWithIssues = extendedElementsWithIssues.value.filter(extendedElementWithIssues => {
67
- const isConnected = extendedElementWithIssues.element.isConnected;
68
- const hasNoMoreIssues = isNodeInScanContext(extendedElementWithIssues.element, scanContext)
69
- && !updatedElementsWithIssues.some(updatedElementWithIssues => areElementsWithIssuesEqual(updatedElementWithIssues, extendedElementWithIssues));
70
- return !isConnected || hasNoMoreIssues;
71
- });
78
+ const removedElementsWithIssues = extendedElementsWithIssues.value.filter(
79
+ (extendedElementWithIssues) => {
80
+ const isConnected = extendedElementWithIssues.element.isConnected;
81
+ const hasNoMoreIssues =
82
+ isNodeInScanContext(extendedElementWithIssues.element, scanContext) &&
83
+ !updatedElementsWithIssues.some((updatedElementWithIssues) =>
84
+ areElementsWithIssuesEqual(updatedElementWithIssues, extendedElementWithIssues),
85
+ );
86
+ return !isConnected || hasNoMoreIssues;
87
+ },
88
+ );
72
89
 
73
90
  if (addedElementsWithIssues.length > 0 || removedElementsWithIssues.length > 0) {
74
91
  extendedElementsWithIssues.value = [...extendedElementsWithIssues.value]
75
- .filter(extendedElementWithIssues => {
76
- return !removedElementsWithIssues.some(removedElementWithIssues => areElementsWithIssuesEqual(removedElementWithIssues, extendedElementWithIssues));
92
+ .filter((extendedElementWithIssues) => {
93
+ return !removedElementsWithIssues.some((removedElementWithIssues) =>
94
+ areElementsWithIssuesEqual(removedElementWithIssues, extendedElementWithIssues),
95
+ );
77
96
  })
78
- .concat(addedElementsWithIssues
79
- .filter(addedElementWithIssues => addedElementWithIssues.element.isConnected)
80
- .map(addedElementWithIssues => {
81
- const id = count++;
82
- const trigger = win.document.createElement(`${name}-trigger`) as AccentedTrigger;
83
- const elementZIndex = parseInt(win.getComputedStyle(addedElementWithIssues.element).zIndex, 10);
84
- if (!isNaN(elementZIndex)) {
85
- trigger.style.setProperty('z-index', (elementZIndex + 1).toString(), 'important');
86
- }
87
- trigger.style.setProperty('position-anchor', `--${name}-anchor-${id}`, 'important');
88
- trigger.dataset.id = id.toString();
89
- const accentedDialog = win.document.createElement(`${name}-dialog`) as AccentedDialog;
90
- trigger.dialog = accentedDialog;
91
- const position = getElementPosition(addedElementWithIssues.element, win);
92
- trigger.position = signal(position);
93
- trigger.visible = signal(true);
94
- trigger.element = addedElementWithIssues.element;
95
- const scrollableAncestors = supportsAnchorPositioning(win) ?
96
- new Set<HTMLElement>() :
97
- getScrollableAncestors(addedElementWithIssues.element, win);
98
- const issues = signal(addedElementWithIssues.issues);
99
- accentedDialog.issues = issues;
100
- accentedDialog.element = addedElementWithIssues.element;
101
- return {
102
- id,
103
- element: addedElementWithIssues.element,
104
- skipRender: shouldSkipRender(addedElementWithIssues.element),
105
- rootNode: addedElementWithIssues.rootNode,
106
- visible: trigger.visible,
107
- position: trigger.position,
108
- scrollableAncestors: signal(scrollableAncestors),
109
- anchorNameValue:
110
- addedElementWithIssues.element.style.getPropertyValue('anchor-name')
111
- || win.getComputedStyle(addedElementWithIssues.element).getPropertyValue('anchor-name'),
112
- trigger,
113
- issues
114
- };
115
- })
97
+ .concat(
98
+ addedElementsWithIssues
99
+ .filter((addedElementWithIssues) => addedElementWithIssues.element.isConnected)
100
+ .map((addedElementWithIssues) => {
101
+ const id = count++;
102
+ const trigger = win.document.createElement(`${name}-trigger`) as AccentedTrigger;
103
+ const elementZIndex = Number.parseInt(
104
+ win.getComputedStyle(addedElementWithIssues.element).zIndex,
105
+ 10,
106
+ );
107
+ if (!Number.isNaN(elementZIndex)) {
108
+ trigger.style.setProperty('z-index', (elementZIndex + 1).toString(), 'important');
109
+ }
110
+ trigger.style.setProperty('position-anchor', `--${name}-anchor-${id}`, 'important');
111
+ trigger.dataset.id = id.toString();
112
+ const accentedDialog = win.document.createElement(`${name}-dialog`) as AccentedDialog;
113
+ trigger.dialog = accentedDialog;
114
+ const position = getElementPosition(addedElementWithIssues.element, win);
115
+ trigger.position = signal(position);
116
+ trigger.visible = signal(true);
117
+ trigger.element = addedElementWithIssues.element;
118
+ const scrollableAncestors = supportsAnchorPositioning(win)
119
+ ? new Set<HTMLElement>()
120
+ : getScrollableAncestors(addedElementWithIssues.element, win);
121
+ const issues = signal(addedElementWithIssues.issues);
122
+ accentedDialog.issues = issues;
123
+ accentedDialog.element = addedElementWithIssues.element;
124
+ return {
125
+ id,
126
+ element: addedElementWithIssues.element,
127
+ skipRender: shouldSkipRender(addedElementWithIssues.element),
128
+ rootNode: addedElementWithIssues.rootNode,
129
+ visible: trigger.visible,
130
+ position: trigger.position,
131
+ scrollableAncestors: signal(scrollableAncestors),
132
+ anchorNameValue:
133
+ addedElementWithIssues.element.style.getPropertyValue('anchor-name') ||
134
+ win
135
+ .getComputedStyle(addedElementWithIssues.element)
136
+ .getPropertyValue('anchor-name'),
137
+ trigger,
138
+ issues,
139
+ };
140
+ }),
116
141
  );
117
142
  }
118
143
  });