wcag-scanner 1.2.63 → 1.2.65
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.
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export interface WcagDevOverlayProps {
|
|
3
|
-
/** WCAG conformance level (default: 'AA') */
|
|
4
3
|
level?: 'A' | 'AA' | 'AAA';
|
|
5
|
-
/** Subset of rules to run. Omit to run all. */
|
|
6
4
|
rules?: string[];
|
|
7
|
-
/** Corner to anchor the overlay (default: 'bottom-right') */
|
|
8
5
|
position?: 'bottom-right' | 'bottom-left';
|
|
9
|
-
/** Delay in ms between DOM mutation and re-scan (default: 750) */
|
|
10
6
|
debounce?: number;
|
|
11
7
|
}
|
|
12
8
|
export declare const WcagDevOverlay: React.FC<WcagDevOverlayProps>;
|
|
@@ -4,211 +4,106 @@ exports.WcagDevOverlay = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const browserScanner_1 = require("./browserScanner");
|
|
7
|
-
// ───
|
|
8
|
-
const
|
|
9
|
-
critical: '#
|
|
10
|
-
serious: '#
|
|
11
|
-
moderate: '#
|
|
12
|
-
minor: '#
|
|
7
|
+
// ─── Impact theme ──────────────────────────────────────────────────────────────
|
|
8
|
+
const IMPACT = {
|
|
9
|
+
critical: { color: '#dc2626', bg: '#fef2f2', border: '#fca5a5' },
|
|
10
|
+
serious: { color: '#ea580c', bg: '#fff7ed', border: '#fdba74' },
|
|
11
|
+
moderate: { color: '#ca8a04', bg: '#fefce8', border: '#fde047' },
|
|
12
|
+
minor: { color: '#2563eb', bg: '#eff6ff', border: '#93c5fd' },
|
|
13
13
|
};
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
serious: '#fdba74',
|
|
23
|
-
moderate: '#fde047',
|
|
24
|
-
minor: '#93c5fd',
|
|
25
|
-
};
|
|
26
|
-
// ─── Highlight helpers ────────────────────────────────────────────────────────
|
|
27
|
-
let _prevHighlighted = null;
|
|
28
|
-
let _prevOutline = '';
|
|
29
|
-
let _prevBoxShadow = '';
|
|
30
|
-
let _pinnedEl = null;
|
|
31
|
-
let _pinnedOutline = '';
|
|
32
|
-
let _pinnedBoxShadow = '';
|
|
14
|
+
const impactTheme = (impact) => { var _a; return (_a = IMPACT[impact]) !== null && _a !== void 0 ? _a : { color: '#6b7280', bg: '#f9fafb', border: '#e5e7eb' }; };
|
|
15
|
+
// ─── Highlight helpers ─────────────────────────────────────────────────────────
|
|
16
|
+
let _hovered = null;
|
|
17
|
+
let _pinned = null;
|
|
18
|
+
function restoreEl(saved) {
|
|
19
|
+
saved.el.style.outline = saved.outline;
|
|
20
|
+
saved.el.style.boxShadow = saved.shadow;
|
|
21
|
+
}
|
|
33
22
|
function applyHighlight(el, color) {
|
|
34
|
-
el.style.outline = `
|
|
35
|
-
el.style.boxShadow = `0 0 0
|
|
23
|
+
el.style.outline = `2px solid ${color}`;
|
|
24
|
+
el.style.boxShadow = `0 0 0 4px ${color}28`;
|
|
36
25
|
}
|
|
37
|
-
function
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (pinned) {
|
|
42
|
-
// Clear previous pin
|
|
43
|
-
if (_pinnedEl && _pinnedEl !== el) {
|
|
44
|
-
_pinnedEl.style.outline = _pinnedOutline;
|
|
45
|
-
_pinnedEl.style.boxShadow = _pinnedBoxShadow;
|
|
46
|
-
}
|
|
47
|
-
_pinnedOutline = htmlEl.style.outline;
|
|
48
|
-
_pinnedBoxShadow = htmlEl.style.boxShadow;
|
|
49
|
-
_pinnedEl = el;
|
|
50
|
-
applyHighlight(htmlEl, '#7c3aed');
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
if (_prevHighlighted) {
|
|
54
|
-
_prevHighlighted.style.outline = _prevOutline;
|
|
55
|
-
_prevHighlighted.style.boxShadow = _prevBoxShadow;
|
|
56
|
-
_prevHighlighted = null;
|
|
57
|
-
}
|
|
58
|
-
// Don't hover-highlight if this element is pinned
|
|
59
|
-
if (_pinnedEl === el)
|
|
60
|
-
return;
|
|
61
|
-
_prevOutline = htmlEl.style.outline;
|
|
62
|
-
_prevBoxShadow = htmlEl.style.boxShadow;
|
|
63
|
-
_prevHighlighted = el;
|
|
64
|
-
applyHighlight(htmlEl, '#0ea5e9');
|
|
26
|
+
function hoverEl(el) {
|
|
27
|
+
if (_hovered) {
|
|
28
|
+
restoreEl(_hovered);
|
|
29
|
+
_hovered = null;
|
|
65
30
|
}
|
|
66
|
-
el
|
|
31
|
+
if (!el || (_pinned === null || _pinned === void 0 ? void 0 : _pinned.el) === el)
|
|
32
|
+
return;
|
|
33
|
+
const h = el;
|
|
34
|
+
_hovered = { el: h, outline: h.style.outline, shadow: h.style.boxShadow };
|
|
35
|
+
applyHighlight(h, '#0ea5e9');
|
|
36
|
+
h.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
67
37
|
}
|
|
68
38
|
function clearHover() {
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
_prevHighlighted = null;
|
|
39
|
+
if (_hovered) {
|
|
40
|
+
restoreEl(_hovered);
|
|
41
|
+
_hovered = null;
|
|
73
42
|
}
|
|
74
43
|
}
|
|
75
|
-
function
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
44
|
+
function pinEl(el) {
|
|
45
|
+
if ((_pinned === null || _pinned === void 0 ? void 0 : _pinned.el) === el) {
|
|
46
|
+
restoreEl(_pinned);
|
|
47
|
+
_pinned = null;
|
|
48
|
+
return false;
|
|
80
49
|
}
|
|
50
|
+
if (_pinned)
|
|
51
|
+
restoreEl(_pinned);
|
|
52
|
+
if ((_hovered === null || _hovered === void 0 ? void 0 : _hovered.el) === el) {
|
|
53
|
+
restoreEl(_hovered);
|
|
54
|
+
_hovered = null;
|
|
55
|
+
}
|
|
56
|
+
const h = el;
|
|
57
|
+
_pinned = { el: h, outline: h.style.outline, shadow: h.style.boxShadow };
|
|
58
|
+
applyHighlight(h, '#7c3aed');
|
|
59
|
+
h.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
60
|
+
return true;
|
|
81
61
|
}
|
|
82
62
|
function clearAllHighlights() {
|
|
83
|
-
|
|
84
|
-
|
|
63
|
+
if (_hovered) {
|
|
64
|
+
restoreEl(_hovered);
|
|
65
|
+
_hovered = null;
|
|
66
|
+
}
|
|
67
|
+
if (_pinned) {
|
|
68
|
+
restoreEl(_pinned);
|
|
69
|
+
_pinned = null;
|
|
70
|
+
}
|
|
85
71
|
}
|
|
86
|
-
const ViolationCard = ({ item,
|
|
87
|
-
var _a, _b, _c;
|
|
72
|
+
const ViolationCard = ({ item, pinned, onPin }) => {
|
|
88
73
|
const [expanded, setExpanded] = (0, react_1.useState)(false);
|
|
89
|
-
const color
|
|
90
|
-
const
|
|
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
|
-
fontWeight: 700,
|
|
116
|
-
letterSpacing: '0.06em',
|
|
117
|
-
textTransform: 'uppercase',
|
|
118
|
-
borderRadius: 4,
|
|
119
|
-
padding: '2px 6px',
|
|
120
|
-
flexShrink: 0,
|
|
121
|
-
marginTop: 2,
|
|
122
|
-
};
|
|
123
|
-
const descStyle = {
|
|
124
|
-
fontSize: 13,
|
|
125
|
-
fontWeight: 500,
|
|
126
|
-
color: '#1e293b',
|
|
127
|
-
lineHeight: 1.45,
|
|
128
|
-
flex: 1,
|
|
129
|
-
};
|
|
130
|
-
const expandBtnStyle = {
|
|
131
|
-
background: 'none',
|
|
132
|
-
border: 'none',
|
|
133
|
-
cursor: 'pointer',
|
|
134
|
-
fontSize: 11,
|
|
135
|
-
color: '#94a3b8',
|
|
136
|
-
padding: '2px 4px',
|
|
137
|
-
flexShrink: 0,
|
|
138
|
-
marginTop: 1,
|
|
139
|
-
lineHeight: 1,
|
|
140
|
-
};
|
|
141
|
-
const detailsStyle = {
|
|
142
|
-
padding: '0 12px 10px',
|
|
143
|
-
borderTop: `1px solid ${border}`,
|
|
144
|
-
};
|
|
145
|
-
const codeStyle = {
|
|
146
|
-
fontFamily: '"JetBrains Mono", "Fira Code", "Cascadia Code", monospace',
|
|
147
|
-
fontSize: 11,
|
|
148
|
-
background: '#0f172a',
|
|
149
|
-
color: '#e2e8f0',
|
|
150
|
-
borderRadius: 6,
|
|
151
|
-
padding: '6px 10px',
|
|
152
|
-
marginTop: 8,
|
|
153
|
-
display: 'block',
|
|
154
|
-
whiteSpace: 'pre-wrap',
|
|
155
|
-
wordBreak: 'break-all',
|
|
156
|
-
overflowWrap: 'break-word',
|
|
157
|
-
maxHeight: 80,
|
|
158
|
-
overflow: 'auto',
|
|
159
|
-
};
|
|
160
|
-
const pathStyle = {
|
|
161
|
-
fontFamily: 'monospace',
|
|
162
|
-
fontSize: 10,
|
|
163
|
-
color: '#64748b',
|
|
164
|
-
background: '#f1f5f9',
|
|
165
|
-
border: '1px solid #e2e8f0',
|
|
166
|
-
borderRadius: 4,
|
|
167
|
-
padding: '3px 7px',
|
|
168
|
-
marginTop: 6,
|
|
169
|
-
display: 'inline-block',
|
|
170
|
-
maxWidth: '100%',
|
|
171
|
-
overflow: 'hidden',
|
|
172
|
-
textOverflow: 'ellipsis',
|
|
173
|
-
whiteSpace: 'nowrap',
|
|
174
|
-
};
|
|
175
|
-
const metaRowStyle = {
|
|
176
|
-
display: 'flex',
|
|
177
|
-
flexWrap: 'wrap',
|
|
178
|
-
gap: 6,
|
|
179
|
-
marginTop: 8,
|
|
180
|
-
alignItems: 'center',
|
|
181
|
-
};
|
|
182
|
-
const wcagTagStyle = {
|
|
183
|
-
fontSize: 10,
|
|
184
|
-
fontWeight: 600,
|
|
185
|
-
color: '#7c3aed',
|
|
186
|
-
background: '#f5f3ff',
|
|
187
|
-
border: '1px solid #ddd6fe',
|
|
188
|
-
borderRadius: 4,
|
|
189
|
-
padding: '2px 6px',
|
|
190
|
-
};
|
|
191
|
-
const helpStyle = {
|
|
192
|
-
fontSize: 11,
|
|
193
|
-
color: '#475569',
|
|
194
|
-
fontStyle: 'italic',
|
|
195
|
-
marginTop: 6,
|
|
196
|
-
lineHeight: 1.5,
|
|
197
|
-
};
|
|
198
|
-
const pinIndicatorStyle = {
|
|
199
|
-
fontSize: 10,
|
|
200
|
-
color: '#7c3aed',
|
|
201
|
-
fontWeight: 700,
|
|
202
|
-
marginLeft: 4,
|
|
203
|
-
};
|
|
204
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: cardStyle, children: [(0, jsx_runtime_1.jsxs)("div", { style: headerRowStyle, onMouseEnter: () => highlightElement(item.domElement), onMouseLeave: () => clearHover(), onClick: () => item.domElement && onPin(item.domElement), title: item.domElement ? (pinned ? 'Click to unpin' : 'Click to pin element') : undefined, children: [(0, jsx_runtime_1.jsx)("span", { style: badgeStyle, children: item.impact }), (0, jsx_runtime_1.jsxs)("span", { style: descStyle, children: [item.description, pinned && (0, jsx_runtime_1.jsx)("span", { style: pinIndicatorStyle, children: "\uD83D\uDCCD" })] }), (0, jsx_runtime_1.jsx)("button", { style: expandBtnStyle, onClick: e => { e.stopPropagation(); setExpanded(x => !x); }, title: expanded ? 'Collapse' : 'Expand details', children: expanded ? '▲' : '▼' })] }), expanded && ((0, jsx_runtime_1.jsxs)("div", { style: detailsStyle, children: [item.elementPath && ((0, jsx_runtime_1.jsx)("span", { style: pathStyle, title: "Element path in DOM", children: item.elementPath })), item.snippet && ((0, jsx_runtime_1.jsx)("code", { style: codeStyle, children: item.snippet })), item.help && ((0, jsx_runtime_1.jsx)("div", { style: helpStyle, children: item.help })), item.wcag && item.wcag.length > 0 && ((0, jsx_runtime_1.jsx)("div", { style: metaRowStyle, children: item.wcag.map(w => ((0, jsx_runtime_1.jsxs)("span", { style: wcagTagStyle, children: ["WCAG ", w] }, w))) }))] }))] }));
|
|
74
|
+
const { color, bg, border } = impactTheme(item.impact);
|
|
75
|
+
const clickable = !!item.domElement;
|
|
76
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
77
|
+
background: bg,
|
|
78
|
+
borderRadius: 8,
|
|
79
|
+
marginBottom: 6,
|
|
80
|
+
overflow: 'hidden',
|
|
81
|
+
outline: pinned ? `2px solid ${color}` : `1px solid ${border}`,
|
|
82
|
+
outlineOffset: pinned ? 1 : 0,
|
|
83
|
+
borderLeft: `3px solid ${color}`,
|
|
84
|
+
}, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'flex-start', gap: 8, padding: '9px 10px', cursor: clickable ? 'pointer' : 'default' }, onMouseEnter: () => hoverEl(item.domElement), onMouseLeave: () => clearHover(), onClick: () => item.domElement && onPin(item.domElement), children: [(0, jsx_runtime_1.jsx)("span", { style: {
|
|
85
|
+
fontSize: 9, fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase',
|
|
86
|
+
background: color, color: '#fff', borderRadius: 4, padding: '2px 5px', flexShrink: 0, marginTop: 2,
|
|
87
|
+
}, children: item.impact }), (0, jsx_runtime_1.jsxs)("span", { style: { fontSize: 12, fontWeight: 500, color: '#1e293b', lineHeight: 1.5, flex: 1 }, children: [item.description, pinned && (0, jsx_runtime_1.jsx)("span", { style: { marginLeft: 5, fontSize: 10 }, children: "\uD83D\uDCCD" })] }), (0, jsx_runtime_1.jsx)("button", { style: { background: 'none', border: 'none', cursor: 'pointer', color: '#94a3b8', fontSize: 11, padding: '1px 4px', flexShrink: 0 }, onClick: e => { e.stopPropagation(); setExpanded(x => !x); }, title: expanded ? 'Collapse' : 'Show details', children: expanded ? '▲' : '▼' })] }), expanded && ((0, jsx_runtime_1.jsxs)("div", { style: { padding: '0 10px 10px', borderTop: `1px solid ${border}` }, children: [item.elementPath && ((0, jsx_runtime_1.jsx)("code", { style: {
|
|
88
|
+
display: 'block', marginTop: 8, fontSize: 10, color: '#475569',
|
|
89
|
+
background: '#f1f5f9', border: '1px solid #e2e8f0', borderRadius: 4,
|
|
90
|
+
padding: '3px 7px', fontFamily: 'monospace', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
|
|
91
|
+
}, children: item.elementPath })), item.snippet && ((0, jsx_runtime_1.jsx)("code", { style: {
|
|
92
|
+
display: 'block', marginTop: 6, fontSize: 10,
|
|
93
|
+
background: '#0f172a', color: '#e2e8f0', borderRadius: 5,
|
|
94
|
+
padding: '5px 8px', fontFamily: 'monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-all',
|
|
95
|
+
maxHeight: 72, overflow: 'auto',
|
|
96
|
+
}, children: item.snippet })), item.help && ((0, jsx_runtime_1.jsx)("p", { style: { margin: '7px 0 0', fontSize: 11, color: '#475569', fontStyle: 'italic', lineHeight: 1.5 }, children: item.help })), item.wcag && item.wcag.length > 0 && ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 7 }, children: item.wcag.map(w => ((0, jsx_runtime_1.jsxs)("span", { style: {
|
|
97
|
+
fontSize: 10, fontWeight: 600, color: '#7c3aed',
|
|
98
|
+
background: '#f5f3ff', border: '1px solid #ddd6fe', borderRadius: 4, padding: '1px 6px',
|
|
99
|
+
}, children: ["WCAG ", w] }, w))) }))] }))] }));
|
|
205
100
|
};
|
|
206
|
-
// ─── Main Overlay
|
|
101
|
+
// ─── Main Overlay ──────────────────────────────────────────────────────────────
|
|
207
102
|
const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', debounce = 750, }) => {
|
|
208
|
-
var _a, _b, _c
|
|
103
|
+
var _a, _b, _c;
|
|
209
104
|
const [open, setOpen] = (0, react_1.useState)(() => {
|
|
210
105
|
try {
|
|
211
|
-
return sessionStorage.getItem('wcag-
|
|
106
|
+
return sessionStorage.getItem('wcag-open') === '1';
|
|
212
107
|
}
|
|
213
108
|
catch (_a) {
|
|
214
109
|
return false;
|
|
@@ -220,40 +115,49 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
220
115
|
const [results, setResults] = (0, react_1.useState)(null);
|
|
221
116
|
const [lastScan, setLastScan] = (0, react_1.useState)(null);
|
|
222
117
|
const [pinnedEl, setPinnedEl] = (0, react_1.useState)(null);
|
|
223
|
-
// Drag
|
|
118
|
+
// Drag
|
|
224
119
|
const [pos, setPos] = (0, react_1.useState)(null);
|
|
225
120
|
const dragging = (0, react_1.useRef)(false);
|
|
226
121
|
const dragOffset = (0, react_1.useRef)({ x: 0, y: 0 });
|
|
227
122
|
const observerRef = (0, react_1.useRef)(null);
|
|
228
123
|
const timerRef = (0, react_1.useRef)(null);
|
|
229
124
|
const overlayRef = (0, react_1.useRef)(null);
|
|
230
|
-
const
|
|
231
|
-
|
|
125
|
+
const scanningRef = (0, react_1.useRef)(false);
|
|
126
|
+
const cooldownRef = (0, react_1.useRef)(false);
|
|
127
|
+
// ── Persist open state ────────────────────────────────────────────────────
|
|
232
128
|
(0, react_1.useEffect)(() => {
|
|
233
129
|
try {
|
|
234
|
-
sessionStorage.setItem('wcag-
|
|
130
|
+
sessionStorage.setItem('wcag-open', open ? '1' : '0');
|
|
235
131
|
}
|
|
236
|
-
catch ( /*
|
|
132
|
+
catch ( /* */_a) { /* */ }
|
|
237
133
|
if (!open)
|
|
238
134
|
clearAllHighlights();
|
|
239
135
|
}, [open]);
|
|
240
|
-
// ── Scan
|
|
136
|
+
// ── Scan ──────────────────────────────────────────────────────────────────
|
|
241
137
|
const scan = (0, react_1.useCallback)(async () => {
|
|
138
|
+
if (scanningRef.current)
|
|
139
|
+
return;
|
|
140
|
+
scanningRef.current = true;
|
|
242
141
|
setScanning(true);
|
|
243
142
|
try {
|
|
244
|
-
const
|
|
245
|
-
const res = await (0, browserScanner_1.scanBrowserPage)(opts);
|
|
143
|
+
const res = await (0, browserScanner_1.scanBrowserPage)({ level, rules });
|
|
246
144
|
setResults(res);
|
|
247
145
|
setLastScan(new Date());
|
|
248
146
|
}
|
|
249
147
|
finally {
|
|
148
|
+
scanningRef.current = false;
|
|
250
149
|
setScanning(false);
|
|
150
|
+
// Cooldown prevents the observer from immediately re-triggering after scan
|
|
151
|
+
cooldownRef.current = true;
|
|
152
|
+
setTimeout(() => { cooldownRef.current = false; }, 1200);
|
|
251
153
|
}
|
|
252
154
|
}, [level, rules]);
|
|
253
155
|
(0, react_1.useEffect)(() => { scan(); }, [scan]);
|
|
254
|
-
// ── MutationObserver
|
|
156
|
+
// ── MutationObserver ──────────────────────────────────────────────────────
|
|
255
157
|
(0, react_1.useEffect)(() => {
|
|
256
158
|
observerRef.current = new MutationObserver((mutations) => {
|
|
159
|
+
if (scanningRef.current || cooldownRef.current)
|
|
160
|
+
return;
|
|
257
161
|
if (overlayRef.current &&
|
|
258
162
|
mutations.every(m => overlayRef.current.contains(m.target)))
|
|
259
163
|
return;
|
|
@@ -265,7 +169,9 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
265
169
|
childList: true,
|
|
266
170
|
subtree: true,
|
|
267
171
|
attributes: true,
|
|
268
|
-
|
|
172
|
+
// 'style' excluded — our highlight helper modifies inline styles on
|
|
173
|
+
// page elements which would otherwise cause an infinite rescan loop
|
|
174
|
+
attributeFilter: ['class', 'hidden', 'aria-hidden', 'role', 'alt', 'src', 'href'],
|
|
269
175
|
});
|
|
270
176
|
return () => {
|
|
271
177
|
var _a;
|
|
@@ -275,38 +181,26 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
275
181
|
clearAllHighlights();
|
|
276
182
|
};
|
|
277
183
|
}, [scan, debounce]);
|
|
278
|
-
// ── Keyboard shortcut Alt+Shift+W
|
|
184
|
+
// ── Keyboard shortcut Alt+Shift+W ─────────────────────────────────────────
|
|
279
185
|
(0, react_1.useEffect)(() => {
|
|
280
186
|
const handler = (e) => {
|
|
281
|
-
if (e.altKey && e.shiftKey && e.key === 'W')
|
|
187
|
+
if (e.altKey && e.shiftKey && e.key === 'W')
|
|
282
188
|
setOpen(o => !o);
|
|
283
|
-
}
|
|
284
189
|
};
|
|
285
190
|
window.addEventListener('keydown', handler);
|
|
286
191
|
return () => window.removeEventListener('keydown', handler);
|
|
287
192
|
}, []);
|
|
288
|
-
// ── Pin handler
|
|
193
|
+
// ── Pin handler ───────────────────────────────────────────────────────────
|
|
289
194
|
const handlePin = (0, react_1.useCallback)((el) => {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (_pinnedEl === el) {
|
|
293
|
-
clearPin();
|
|
294
|
-
setPinnedEl(null);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
highlightElement(el, true);
|
|
298
|
-
setPinnedEl(el);
|
|
299
|
-
}
|
|
195
|
+
const nowPinned = pinEl(el);
|
|
196
|
+
setPinnedEl(nowPinned ? el : null);
|
|
300
197
|
}, []);
|
|
301
|
-
// ── Drag
|
|
198
|
+
// ── Drag ──────────────────────────────────────────────────────────────────
|
|
302
199
|
const onDragStart = (e) => {
|
|
303
200
|
var _a, _b, _c;
|
|
304
201
|
dragging.current = true;
|
|
305
202
|
const rect = (_a = overlayRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
306
|
-
dragOffset.current = {
|
|
307
|
-
x: e.clientX - ((_b = rect === null || rect === void 0 ? void 0 : rect.left) !== null && _b !== void 0 ? _b : 0),
|
|
308
|
-
y: e.clientY - ((_c = rect === null || rect === void 0 ? void 0 : rect.top) !== null && _c !== void 0 ? _c : 0),
|
|
309
|
-
};
|
|
203
|
+
dragOffset.current = { x: e.clientX - ((_b = rect === null || rect === void 0 ? void 0 : rect.left) !== null && _b !== void 0 ? _b : 0), y: e.clientY - ((_c = rect === null || rect === void 0 ? void 0 : rect.top) !== null && _c !== void 0 ? _c : 0) };
|
|
310
204
|
e.preventDefault();
|
|
311
205
|
};
|
|
312
206
|
(0, react_1.useEffect)(() => {
|
|
@@ -318,181 +212,107 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
318
212
|
const onUp = () => { dragging.current = false; };
|
|
319
213
|
window.addEventListener('mousemove', onMove);
|
|
320
214
|
window.addEventListener('mouseup', onUp);
|
|
321
|
-
return () => {
|
|
322
|
-
window.removeEventListener('mousemove', onMove);
|
|
323
|
-
window.removeEventListener('mouseup', onUp);
|
|
324
|
-
};
|
|
215
|
+
return () => { window.removeEventListener('mousemove', onMove); window.removeEventListener('mouseup', onUp); };
|
|
325
216
|
}, []);
|
|
326
|
-
// ── Derived
|
|
327
|
-
const
|
|
328
|
-
const
|
|
217
|
+
// ── Derived ───────────────────────────────────────────────────────────────
|
|
218
|
+
const vCount = (_a = results === null || results === void 0 ? void 0 : results.violations.length) !== null && _a !== void 0 ? _a : 0;
|
|
219
|
+
const wCount = (_b = results === null || results === void 0 ? void 0 : results.warnings.length) !== null && _b !== void 0 ? _b : 0;
|
|
220
|
+
const pCount = (_c = results === null || results === void 0 ? void 0 : results.passes.length) !== null && _c !== void 0 ? _c : 0;
|
|
329
221
|
const isLeft = position === 'bottom-left';
|
|
330
222
|
const rawItems = tab === 'violations' ? results === null || results === void 0 ? void 0 : results.violations : results === null || results === void 0 ? void 0 : results.warnings;
|
|
331
|
-
const items = filter === 'all'
|
|
332
|
-
? rawItems
|
|
333
|
-
: rawItems === null || rawItems === void 0 ? void 0 : rawItems.filter(i => i.impact === filter);
|
|
223
|
+
const items = filter === 'all' ? rawItems : rawItems === null || rawItems === void 0 ? void 0 : rawItems.filter(i => i.impact === filter);
|
|
334
224
|
const isEmpty = !items || items.length === 0;
|
|
335
|
-
const elapsed = lastScan
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
: '—';
|
|
341
|
-
// ── Styles ───────────────────────────────────────────────────────────────
|
|
225
|
+
const elapsed = lastScan ? (() => {
|
|
226
|
+
const s = Math.round((Date.now() - lastScan.getTime()) / 1000);
|
|
227
|
+
return s < 5 ? 'just now' : s < 60 ? `${s}s ago` : `${Math.round(s / 60)}m ago`;
|
|
228
|
+
})() : '—';
|
|
229
|
+
// ── Styles ────────────────────────────────────────────────────────────────
|
|
342
230
|
const anchorStyle = pos
|
|
343
231
|
? { position: 'fixed', top: pos.y, left: pos.x, zIndex: 2147483647, fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' }
|
|
344
|
-
: {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
232
|
+
: { position: 'fixed', bottom: 20, [isLeft ? 'left' : 'right']: 20, zIndex: 2147483647, fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' };
|
|
233
|
+
const btnColor = scanning ? '#64748b' : vCount > 0 ? '#7c3aed' : '#16a34a';
|
|
234
|
+
const s = {
|
|
235
|
+
toggle: {
|
|
236
|
+
display: 'flex', alignItems: 'center', gap: 6,
|
|
237
|
+
background: btnColor, color: '#fff', border: 'none', borderRadius: 22,
|
|
238
|
+
padding: '8px 14px', fontSize: 12, fontWeight: 600, cursor: 'pointer',
|
|
239
|
+
boxShadow: '0 2px 12px rgba(0,0,0,0.2)', userSelect: 'none',
|
|
240
|
+
},
|
|
241
|
+
badge: {
|
|
242
|
+
background: 'rgba(255,255,255,0.22)', borderRadius: 9,
|
|
243
|
+
padding: '1px 6px', fontSize: 11, fontWeight: 700,
|
|
244
|
+
},
|
|
245
|
+
panel: {
|
|
246
|
+
position: 'absolute',
|
|
247
|
+
bottom: pos ? undefined : 48,
|
|
248
|
+
top: pos ? 48 : undefined,
|
|
249
|
+
[isLeft ? 'left' : 'right']: 0,
|
|
250
|
+
width: 400,
|
|
251
|
+
maxHeight: '74vh',
|
|
252
|
+
background: '#ffffff',
|
|
253
|
+
borderRadius: 10,
|
|
254
|
+
boxShadow: '0 8px 40px rgba(0,0,0,0.16), 0 0 0 1px rgba(0,0,0,0.07)',
|
|
255
|
+
display: 'flex',
|
|
256
|
+
flexDirection: 'column',
|
|
257
|
+
overflow: 'hidden',
|
|
258
|
+
},
|
|
259
|
+
header: {
|
|
260
|
+
display: 'flex', alignItems: 'center', gap: 8,
|
|
261
|
+
padding: '10px 12px', background: '#0f172a',
|
|
262
|
+
cursor: 'grab', userSelect: 'none', flexShrink: 0,
|
|
263
|
+
},
|
|
264
|
+
headerBtn: {
|
|
265
|
+
background: 'none', border: 'none', cursor: 'pointer',
|
|
266
|
+
color: '#64748b', fontSize: 14, padding: '2px 5px', lineHeight: 1, borderRadius: 4,
|
|
267
|
+
},
|
|
268
|
+
summary: {
|
|
269
|
+
display: 'flex', gap: 6, padding: '8px 12px',
|
|
270
|
+
borderBottom: '1px solid #f1f5f9', background: '#f8fafc', flexShrink: 0,
|
|
271
|
+
},
|
|
272
|
+
toolbar: {
|
|
273
|
+
display: 'flex', alignItems: 'center',
|
|
274
|
+
borderBottom: '1px solid #f1f5f9', padding: '0 12px',
|
|
275
|
+
gap: 2, flexShrink: 0,
|
|
276
|
+
},
|
|
277
|
+
list: {
|
|
278
|
+
flex: 1, overflowY: 'auto', padding: '10px 10px',
|
|
279
|
+
},
|
|
280
|
+
footer: {
|
|
281
|
+
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
|
|
282
|
+
padding: '7px 12px', borderTop: '1px solid #f1f5f9',
|
|
283
|
+
background: '#f8fafc', fontSize: 10, color: '#94a3b8', flexShrink: 0,
|
|
284
|
+
},
|
|
366
285
|
};
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
};
|
|
374
|
-
const panelStyle = {
|
|
375
|
-
position: 'absolute',
|
|
376
|
-
bottom: pos ? undefined : 54,
|
|
377
|
-
top: pos ? 54 : undefined,
|
|
378
|
-
[isLeft ? 'left' : 'right']: 0,
|
|
379
|
-
width: 420,
|
|
380
|
-
maxHeight: '75vh',
|
|
381
|
-
background: '#fff',
|
|
382
|
-
borderRadius: 12,
|
|
383
|
-
boxShadow: '0 24px 64px rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.08)',
|
|
384
|
-
display: 'flex',
|
|
385
|
-
flexDirection: 'column',
|
|
386
|
-
overflow: 'hidden',
|
|
387
|
-
};
|
|
388
|
-
const headerStyle = {
|
|
389
|
-
display: 'flex',
|
|
390
|
-
alignItems: 'center',
|
|
391
|
-
padding: '11px 14px',
|
|
392
|
-
background: '#0f172a',
|
|
393
|
-
gap: 8,
|
|
394
|
-
cursor: 'grab',
|
|
395
|
-
userSelect: 'none',
|
|
396
|
-
};
|
|
397
|
-
const summaryStyle = {
|
|
398
|
-
display: 'flex',
|
|
399
|
-
gap: 8,
|
|
400
|
-
padding: '10px 14px',
|
|
401
|
-
borderBottom: '1px solid #e2e8f0',
|
|
402
|
-
background: '#f8fafc',
|
|
403
|
-
};
|
|
404
|
-
const toolbarStyle = {
|
|
405
|
-
display: 'flex',
|
|
406
|
-
alignItems: 'center',
|
|
407
|
-
borderBottom: '1px solid #e2e8f0',
|
|
408
|
-
padding: '0 14px',
|
|
409
|
-
gap: 4,
|
|
410
|
-
};
|
|
411
|
-
const tabBtnStyle = (active) => ({
|
|
412
|
-
padding: '8px 12px',
|
|
413
|
-
fontSize: 13,
|
|
414
|
-
fontWeight: active ? 600 : 400,
|
|
415
|
-
color: active ? '#7c3aed' : '#64748b',
|
|
416
|
-
borderBottom: active ? '2px solid #7c3aed' : '2px solid transparent',
|
|
417
|
-
cursor: 'pointer',
|
|
418
|
-
background: 'none',
|
|
419
|
-
border: 'none',
|
|
420
|
-
borderBottomColor: active ? '#7c3aed' : 'transparent',
|
|
421
|
-
borderBottomStyle: 'solid',
|
|
422
|
-
borderBottomWidth: 2,
|
|
423
|
-
whiteSpace: 'nowrap',
|
|
286
|
+
const chip = (color, count) => ({
|
|
287
|
+
display: 'flex', alignItems: 'center', gap: 3, fontSize: 11, fontWeight: 600,
|
|
288
|
+
color: count > 0 ? color : '#94a3b8',
|
|
289
|
+
background: count > 0 ? `${color}14` : '#f1f5f9',
|
|
290
|
+
border: `1px solid ${count > 0 ? color + '35' : '#e2e8f0'}`,
|
|
291
|
+
borderRadius: 5, padding: '3px 8px', flexShrink: 0,
|
|
424
292
|
});
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
color: '#475569',
|
|
432
|
-
background: '#fff',
|
|
433
|
-
cursor: 'pointer',
|
|
434
|
-
outline: 'none',
|
|
435
|
-
};
|
|
436
|
-
const listStyle = {
|
|
437
|
-
flex: 1,
|
|
438
|
-
overflowY: 'auto',
|
|
439
|
-
padding: '12px 12px',
|
|
440
|
-
};
|
|
441
|
-
const footerStyle = {
|
|
442
|
-
display: 'flex',
|
|
443
|
-
alignItems: 'center',
|
|
444
|
-
justifyContent: 'space-between',
|
|
445
|
-
padding: '8px 14px',
|
|
446
|
-
borderTop: '1px solid #e2e8f0',
|
|
447
|
-
background: '#f8fafc',
|
|
448
|
-
fontSize: 11,
|
|
449
|
-
color: '#94a3b8',
|
|
450
|
-
};
|
|
451
|
-
const rescanBtnStyle = {
|
|
452
|
-
background: '#7c3aed',
|
|
453
|
-
color: '#fff',
|
|
454
|
-
border: 'none',
|
|
455
|
-
borderRadius: 6,
|
|
456
|
-
padding: '4px 12px',
|
|
457
|
-
fontSize: 11,
|
|
458
|
-
fontWeight: 600,
|
|
459
|
-
cursor: scanning ? 'wait' : 'pointer',
|
|
460
|
-
opacity: scanning ? 0.6 : 1,
|
|
461
|
-
};
|
|
462
|
-
const chipStyle = (color, active = true) => ({
|
|
463
|
-
display: 'flex',
|
|
464
|
-
alignItems: 'center',
|
|
465
|
-
gap: 4,
|
|
466
|
-
fontSize: 11,
|
|
467
|
-
fontWeight: 600,
|
|
468
|
-
color: active ? color : '#94a3b8',
|
|
469
|
-
background: active ? `${color}18` : '#f1f5f9',
|
|
470
|
-
border: `1px solid ${active ? color + '40' : '#e2e8f0'}`,
|
|
471
|
-
borderRadius: 6,
|
|
472
|
-
padding: '4px 10px',
|
|
473
|
-
flexShrink: 0,
|
|
293
|
+
const tabBtn = (active) => ({
|
|
294
|
+
padding: '7px 10px', fontSize: 12, fontWeight: active ? 600 : 400,
|
|
295
|
+
color: active ? '#7c3aed' : '#64748b', cursor: 'pointer',
|
|
296
|
+
background: 'none', border: 'none',
|
|
297
|
+
boxShadow: active ? 'inset 0 -2px 0 #7c3aed' : 'none',
|
|
298
|
+
whiteSpace: 'nowrap',
|
|
474
299
|
});
|
|
475
|
-
const
|
|
476
|
-
background: 'none',
|
|
477
|
-
|
|
478
|
-
cursor: 'pointer',
|
|
479
|
-
color: '#94a3b8',
|
|
480
|
-
padding: '3px 6px',
|
|
481
|
-
fontSize: 14,
|
|
482
|
-
lineHeight: 1,
|
|
483
|
-
borderRadius: 4,
|
|
484
|
-
transition: 'color 0.15s',
|
|
300
|
+
const rescanBtn = {
|
|
301
|
+
background: '#7c3aed', color: '#fff', border: 'none', borderRadius: 5,
|
|
302
|
+
padding: '4px 10px', fontSize: 10, fontWeight: 600,
|
|
303
|
+
cursor: scanning ? 'wait' : 'pointer', opacity: scanning ? 0.55 : 1,
|
|
485
304
|
};
|
|
486
|
-
return ((0, jsx_runtime_1.jsxs)("div", { ref: overlayRef, style: anchorStyle, "data-wcag-overlay": "true", children: [open && ((0, jsx_runtime_1.jsxs)("div", {
|
|
487
|
-
fontSize:
|
|
488
|
-
background: '#4c1d95', borderRadius: 4, padding: '2px
|
|
489
|
-
}, children: level }), (0, jsx_runtime_1.jsx)("button", { onClick: scan, disabled: scanning, title: "Rescan
|
|
490
|
-
|
|
491
|
-
:
|
|
492
|
-
|
|
493
|
-
:
|
|
494
|
-
|
|
495
|
-
: (0, jsx_runtime_1.jsx)("span", { style:
|
|
305
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: overlayRef, style: anchorStyle, "data-wcag-overlay": "true", children: [open && ((0, jsx_runtime_1.jsxs)("div", { style: s.panel, role: "dialog", "aria-label": "WCAG Dev Inspector", children: [(0, jsx_runtime_1.jsxs)("div", { style: s.header, onMouseDown: onDragStart, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: 14 }, children: "\u267F" }), (0, jsx_runtime_1.jsx)("span", { style: { fontWeight: 700, fontSize: 13, flex: 1, color: '#f1f5f9' }, children: "WCAG Inspector" }), (0, jsx_runtime_1.jsx)("span", { style: {
|
|
306
|
+
fontSize: 9, fontWeight: 700, color: '#a78bfa',
|
|
307
|
+
background: '#4c1d95', borderRadius: 4, padding: '2px 6px', letterSpacing: '0.05em',
|
|
308
|
+
}, children: level }), (0, jsx_runtime_1.jsx)("button", { onClick: scan, disabled: scanning, title: "Rescan", style: s.headerBtn, children: scanning ? '⏳' : '↻' }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setOpen(false), title: "Close (Alt+Shift+W)", style: s.headerBtn, children: "\u2715" })] }), (0, jsx_runtime_1.jsxs)("div", { style: s.summary, children: [(0, jsx_runtime_1.jsxs)("span", { style: chip('#dc2626', vCount), children: ["\u2717 ", vCount, " violation", vCount !== 1 ? 's' : ''] }), (0, jsx_runtime_1.jsxs)("span", { style: chip('#ea580c', wCount), children: ["\u26A0 ", wCount, " warning", wCount !== 1 ? 's' : ''] }), (0, jsx_runtime_1.jsxs)("span", { style: chip('#16a34a', pCount), children: ["\u2713 ", pCount, " pass", pCount !== 1 ? 'es' : ''] })] }), (0, jsx_runtime_1.jsxs)("div", { style: s.toolbar, children: [(0, jsx_runtime_1.jsxs)("button", { style: tabBtn(tab === 'violations'), onClick: () => setTab('violations'), children: ["Violations (", vCount, ")"] }), (0, jsx_runtime_1.jsxs)("button", { style: tabBtn(tab === 'warnings'), onClick: () => setTab('warnings'), children: ["Warnings (", wCount, ")"] }), (0, jsx_runtime_1.jsxs)("select", { style: {
|
|
309
|
+
marginLeft: 'auto', fontSize: 10, border: '1px solid #e2e8f0',
|
|
310
|
+
borderRadius: 5, padding: '3px 6px', color: '#475569', background: '#fff', cursor: 'pointer', outline: 'none',
|
|
311
|
+
}, value: filter, onChange: e => setFilter(e.target.value), children: [(0, jsx_runtime_1.jsx)("option", { value: "all", children: "All" }), (0, jsx_runtime_1.jsx)("option", { value: "critical", children: "Critical" }), (0, jsx_runtime_1.jsx)("option", { value: "serious", children: "Serious" }), (0, jsx_runtime_1.jsx)("option", { value: "moderate", children: "Moderate" }), (0, jsx_runtime_1.jsx)("option", { value: "minor", children: "Minor" })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: s.list, children: [scanning && !results && ((0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'center', color: '#94a3b8', padding: '28px 0', fontSize: 12 }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontSize: 22, marginBottom: 8 }, children: "\u23F3" }), "Scanning\u2026"] })), !scanning && isEmpty && ((0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'center', padding: '28px 0' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontSize: 28, marginBottom: 8 }, children: tab === 'violations' ? '✅' : '🔕' }), (0, jsx_runtime_1.jsxs)("div", { style: { color: '#64748b', fontSize: 12, fontWeight: 500 }, children: ["No ", tab, " found"] }), filter !== 'all' && ((0, jsx_runtime_1.jsx)("button", { style: { marginTop: 6, fontSize: 11, color: '#7c3aed', background: 'none', border: 'none', cursor: 'pointer' }, onClick: () => setFilter('all'), children: "Clear filter" }))] })), items === null || items === void 0 ? void 0 : items.map((item, i) => ((0, jsx_runtime_1.jsx)(ViolationCard, { item: item, pinned: pinnedEl === item.domElement && item.domElement != null, onPin: handlePin }, `${item.rule}-${i}`)))] }), (0, jsx_runtime_1.jsxs)("div", { style: s.footer, children: [(0, jsx_runtime_1.jsxs)("span", { children: [pinnedEl ? '📍 pinned · ' : '', "Scanned ", elapsed, results ? ` · ${results.duration}ms` : ''] }), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: 6, alignItems: 'center' }, children: [pinnedEl && ((0, jsx_runtime_1.jsx)("button", { style: { ...rescanBtn, background: '#64748b' }, onClick: () => { clearAllHighlights(); setPinnedEl(null); }, children: "Unpin" })), (0, jsx_runtime_1.jsx)("button", { style: rescanBtn, onClick: scan, disabled: scanning, children: scanning ? 'Scanning…' : 'Rescan' })] })] })] })), (0, jsx_runtime_1.jsxs)("button", { style: s.toggle, onClick: () => setOpen(o => !o), title: "Toggle WCAG Inspector (Alt+Shift+W)", "aria-expanded": open, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: 14 }, children: "\u267F" }), scanning
|
|
312
|
+
? (0, jsx_runtime_1.jsx)("span", { style: { opacity: 0.8, fontSize: 11 }, children: "scanning\u2026" })
|
|
313
|
+
: vCount > 0
|
|
314
|
+
? (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { style: s.badge, children: vCount }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: 11 }, children: "issues" })] })
|
|
315
|
+
: (0, jsx_runtime_1.jsx)("span", { style: s.badge, children: "\u2713" })] })] }));
|
|
496
316
|
};
|
|
497
317
|
exports.WcagDevOverlay = WcagDevOverlay;
|
|
498
318
|
exports.default = exports.WcagDevOverlay;
|
|
@@ -39,13 +39,16 @@ async function scanBrowserPage(options = {}) {
|
|
|
39
39
|
// rule failed in browser context — skip silently
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
+
// Exclude any elements that live inside the WCAG overlay itself
|
|
43
|
+
const overlayRoot = document.querySelector('[data-wcag-overlay-root]');
|
|
44
|
+
const isInOverlay = (el) => el != null && overlayRoot != null && overlayRoot.contains(el);
|
|
42
45
|
const annotate = (item) => {
|
|
43
46
|
const el = findElement(item, document);
|
|
44
47
|
return { ...item, domElement: el !== null && el !== void 0 ? el : undefined, elementPath: el ? getElementPath(el) : undefined };
|
|
45
48
|
};
|
|
46
49
|
return {
|
|
47
|
-
violations: violations.map(annotate),
|
|
48
|
-
warnings: warnings.map(annotate),
|
|
50
|
+
violations: violations.map(annotate).filter(v => { var _a; return !isInOverlay((_a = v.domElement) !== null && _a !== void 0 ? _a : null); }),
|
|
51
|
+
warnings: warnings.map(annotate).filter(w => { var _a; return !isInOverlay((_a = w.domElement) !== null && _a !== void 0 ? _a : null); }),
|
|
49
52
|
passes,
|
|
50
53
|
duration: Math.round(performance.now() - start),
|
|
51
54
|
};
|