accented 0.0.0-20250424114613 → 0.0.0-20250701143712
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -193
- package/dist/accented.d.ts +7 -7
- package/dist/accented.d.ts.map +1 -1
- package/dist/accented.js +30 -27
- package/dist/accented.js.map +1 -1
- package/dist/common/tokens.d.ts +2 -0
- package/dist/common/tokens.d.ts.map +1 -0
- package/dist/common/tokens.js +2 -0
- package/dist/common/tokens.js.map +1 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/dom-updater.d.ts +1 -1
- package/dist/dom-updater.d.ts.map +1 -1
- package/dist/dom-updater.js +14 -13
- package/dist/dom-updater.js.map +1 -1
- package/dist/elements/accented-dialog.d.ts +2 -3
- package/dist/elements/accented-dialog.d.ts.map +1 -1
- package/dist/elements/accented-dialog.js +14 -8
- package/dist/elements/accented-dialog.js.map +1 -1
- package/dist/elements/accented-trigger.d.ts +3 -4
- package/dist/elements/accented-trigger.d.ts.map +1 -1
- package/dist/elements/accented-trigger.js +10 -10
- package/dist/elements/accented-trigger.js.map +1 -1
- package/dist/fullscreen-listener.d.ts +1 -1
- package/dist/fullscreen-listener.d.ts.map +1 -1
- package/dist/fullscreen-listener.js +3 -4
- package/dist/fullscreen-listener.js.map +1 -1
- package/dist/intersection-observer.d.ts +1 -1
- package/dist/intersection-observer.d.ts.map +1 -1
- package/dist/intersection-observer.js +12 -6
- package/dist/intersection-observer.js.map +1 -1
- package/dist/log-and-rethrow.d.ts +1 -1
- package/dist/log-and-rethrow.d.ts.map +1 -1
- package/dist/log-and-rethrow.js +2 -3
- package/dist/log-and-rethrow.js.map +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +2 -2
- package/dist/logger.js.map +1 -1
- package/dist/register-elements.d.ts +1 -1
- package/dist/register-elements.d.ts.map +1 -1
- package/dist/register-elements.js +6 -7
- package/dist/register-elements.js.map +1 -1
- package/dist/resize-listener.d.ts +1 -1
- package/dist/resize-listener.d.ts.map +1 -1
- package/dist/resize-listener.js +3 -4
- package/dist/resize-listener.js.map +1 -1
- package/dist/scanner.d.ts +2 -2
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +36 -36
- package/dist/scanner.js.map +1 -1
- package/dist/scroll-listeners.d.ts +1 -1
- package/dist/scroll-listeners.d.ts.map +1 -1
- package/dist/scroll-listeners.js +3 -4
- package/dist/scroll-listeners.js.map +1 -1
- package/dist/state.d.ts +1 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +4 -5
- package/dist/state.js.map +1 -1
- package/dist/task-queue.d.ts +2 -2
- package/dist/task-queue.d.ts.map +1 -1
- package/dist/task-queue.js +1 -1
- package/dist/task-queue.js.map +1 -1
- package/dist/types.d.ts +102 -46
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/are-elements-with-issues-equal.d.ts +2 -2
- package/dist/utils/are-elements-with-issues-equal.d.ts.map +1 -1
- package/dist/utils/are-elements-with-issues-equal.js +3 -3
- package/dist/utils/are-elements-with-issues-equal.js.map +1 -1
- package/dist/utils/are-issue-sets-equal.d.ts +2 -2
- package/dist/utils/are-issue-sets-equal.d.ts.map +1 -1
- package/dist/utils/are-issue-sets-equal.js +3 -3
- package/dist/utils/are-issue-sets-equal.js.map +1 -1
- package/dist/utils/containing-blocks.d.ts.map +1 -1
- package/dist/utils/containing-blocks.js +1 -1
- package/dist/utils/containing-blocks.js.map +1 -1
- package/dist/utils/contains.d.ts +1 -1
- package/dist/utils/contains.d.ts.map +1 -1
- package/dist/utils/contains.js +1 -1
- package/dist/utils/contains.js.map +1 -1
- package/dist/utils/deduplicate-nodes.js +0 -1
- package/dist/utils/deduplicate-nodes.js.map +1 -1
- package/dist/utils/deep-merge.d.ts +1 -1
- package/dist/utils/deep-merge.d.ts.map +1 -1
- package/dist/utils/deep-merge.js +8 -5
- package/dist/utils/deep-merge.js.map +1 -1
- package/dist/utils/dom-helpers.d.ts.map +1 -1
- package/dist/utils/dom-helpers.js +4 -2
- package/dist/utils/dom-helpers.js.map +1 -1
- package/dist/utils/ensure-non-empty.d.ts +1 -1
- package/dist/utils/ensure-non-empty.d.ts.map +1 -1
- package/dist/utils/ensure-non-empty.js +2 -2
- package/dist/utils/ensure-non-empty.js.map +1 -1
- package/dist/utils/get-element-html.d.ts +1 -1
- package/dist/utils/get-element-html.d.ts.map +1 -1
- package/dist/utils/get-element-html.js +4 -2
- package/dist/utils/get-element-html.js.map +1 -1
- package/dist/utils/get-element-position.d.ts +2 -2
- package/dist/utils/get-element-position.d.ts.map +1 -1
- package/dist/utils/get-element-position.js +21 -25
- package/dist/utils/get-element-position.js.map +1 -1
- package/dist/utils/get-parent.d.ts +1 -1
- package/dist/utils/get-parent.d.ts.map +1 -1
- package/dist/utils/get-parent.js +1 -1
- package/dist/utils/get-parent.js.map +1 -1
- package/dist/utils/get-scan-context.d.ts +2 -2
- package/dist/utils/get-scan-context.d.ts.map +1 -1
- package/dist/utils/get-scan-context.js +9 -9
- package/dist/utils/get-scan-context.js.map +1 -1
- package/dist/utils/get-scrollable-ancestors.d.ts +1 -1
- package/dist/utils/get-scrollable-ancestors.d.ts.map +1 -1
- package/dist/utils/get-scrollable-ancestors.js +5 -5
- package/dist/utils/get-scrollable-ancestors.js.map +1 -1
- package/dist/utils/is-node-in-scan-context.d.ts +2 -2
- package/dist/utils/is-node-in-scan-context.d.ts.map +1 -1
- package/dist/utils/is-node-in-scan-context.js +5 -5
- package/dist/utils/is-node-in-scan-context.js.map +1 -1
- package/dist/utils/is-non-empty.d.ts +2 -0
- package/dist/utils/is-non-empty.d.ts.map +1 -0
- package/dist/utils/is-non-empty.js +4 -0
- package/dist/utils/is-non-empty.js.map +1 -0
- package/dist/utils/normalize-context.d.ts +2 -2
- package/dist/utils/normalize-context.d.ts.map +1 -1
- package/dist/utils/normalize-context.js +10 -8
- package/dist/utils/normalize-context.js.map +1 -1
- package/dist/utils/recalculate-positions.d.ts +1 -1
- package/dist/utils/recalculate-positions.d.ts.map +1 -1
- package/dist/utils/recalculate-positions.js +5 -5
- package/dist/utils/recalculate-positions.js.map +1 -1
- package/dist/utils/recalculate-scrollable-ancestors.d.ts +1 -1
- package/dist/utils/recalculate-scrollable-ancestors.d.ts.map +1 -1
- package/dist/utils/recalculate-scrollable-ancestors.js +4 -4
- package/dist/utils/recalculate-scrollable-ancestors.js.map +1 -1
- package/dist/utils/shadow-dom-aware-mutation-observer.d.ts +1 -1
- package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -1
- package/dist/utils/shadow-dom-aware-mutation-observer.js +19 -22
- package/dist/utils/shadow-dom-aware-mutation-observer.js.map +1 -1
- package/dist/utils/supports-anchor-positioning.d.ts +1 -1
- package/dist/utils/supports-anchor-positioning.d.ts.map +1 -1
- package/dist/utils/supports-anchor-positioning.js +1 -1
- package/dist/utils/supports-anchor-positioning.js.map +1 -1
- package/dist/utils/transform-violations.d.ts +2 -2
- package/dist/utils/transform-violations.d.ts.map +1 -1
- package/dist/utils/transform-violations.js +9 -9
- package/dist/utils/transform-violations.js.map +1 -1
- package/dist/utils/update-elements-with-issues.d.ts +3 -3
- package/dist/utils/update-elements-with-issues.d.ts.map +1 -1
- package/dist/utils/update-elements-with-issues.js +34 -29
- package/dist/utils/update-elements-with-issues.js.map +1 -1
- package/dist/validate-options.d.ts +2 -2
- package/dist/validate-options.d.ts.map +1 -1
- package/dist/validate-options.js +24 -23
- package/dist/validate-options.js.map +1 -1
- package/package.json +7 -4
- package/src/accented.test.ts +2 -2
- package/src/accented.ts +39 -32
- package/src/common/tokens.ts +1 -0
- package/src/constants.ts +1 -1
- package/src/dom-updater.ts +26 -19
- package/src/elements/accented-dialog.ts +69 -43
- package/src/elements/accented-trigger.ts +54 -43
- package/src/fullscreen-listener.ts +15 -11
- package/src/intersection-observer.ts +27 -16
- package/src/log-and-rethrow.ts +2 -3
- package/src/logger.ts +8 -6
- package/src/register-elements.ts +7 -7
- package/src/resize-listener.ts +15 -11
- package/src/scanner.ts +66 -50
- package/src/scroll-listeners.ts +27 -19
- package/src/state.ts +24 -21
- package/src/task-queue.test.ts +5 -4
- package/src/task-queue.ts +2 -2
- package/src/types.ts +151 -95
- package/src/utils/are-elements-with-issues-equal.ts +7 -5
- package/src/utils/are-issue-sets-equal.test.ts +10 -6
- package/src/utils/are-issue-sets-equal.ts +8 -6
- package/src/utils/containing-blocks.ts +6 -3
- package/src/utils/contains.test.ts +2 -2
- package/src/utils/contains.ts +1 -1
- package/src/utils/deduplicate-nodes.ts +1 -1
- package/src/utils/deep-merge.test.ts +8 -1
- package/src/utils/deep-merge.ts +14 -8
- package/src/utils/dom-helpers.ts +6 -2
- package/src/utils/ensure-non-empty.ts +2 -2
- package/src/utils/get-element-html.ts +4 -2
- package/src/utils/get-element-position.ts +37 -24
- package/src/utils/get-parent.ts +1 -1
- package/src/utils/get-scan-context.test.ts +14 -8
- package/src/utils/get-scan-context.ts +12 -15
- package/src/utils/get-scrollable-ancestors.ts +8 -5
- package/src/utils/is-node-in-scan-context.test.ts +3 -3
- package/src/utils/is-node-in-scan-context.ts +6 -6
- package/src/utils/is-non-empty.ts +3 -0
- package/src/utils/normalize-context.test.ts +9 -9
- package/src/utils/normalize-context.ts +17 -10
- package/src/utils/recalculate-positions.ts +5 -5
- package/src/utils/recalculate-scrollable-ancestors.ts +4 -4
- package/src/utils/shadow-dom-aware-mutation-observer.ts +21 -24
- package/src/utils/supports-anchor-positioning.ts +3 -3
- package/src/utils/transform-violations.test.ts +22 -20
- package/src/utils/transform-violations.ts +14 -10
- package/src/utils/update-elements-with-issues.test.ts +49 -49
- package/src/utils/update-elements-with-issues.ts +96 -71
- 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 {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
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
|
|
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
|
|
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(
|
|
54
|
-
|
|
55
|
-
|
|
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 =>
|
|
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(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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 =>
|
|
92
|
+
.filter((extendedElementWithIssues) => {
|
|
93
|
+
return !removedElementsWithIssues.some((removedElementWithIssues) =>
|
|
94
|
+
areElementsWithIssuesEqual(removedElementWithIssues, extendedElementWithIssues),
|
|
95
|
+
);
|
|
77
96
|
})
|
|
78
|
-
.concat(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
});
|