wcag-scanner 1.2.62 → 1.2.64
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/dist/react/WcagDevOverlay.js +22 -5
- package/dist/react/init.d.ts +1 -2
- package/dist/react/init.js +27 -61
- package/package.json +1 -1
|
@@ -238,8 +238,15 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
238
238
|
clearAllHighlights();
|
|
239
239
|
}, [open]);
|
|
240
240
|
// ── Scan ────────────────────────────────────────────────────────────────
|
|
241
|
+
const scanningRef = (0, react_1.useRef)(false);
|
|
241
242
|
const scan = (0, react_1.useCallback)(async () => {
|
|
243
|
+
var _a;
|
|
244
|
+
if (scanningRef.current)
|
|
245
|
+
return;
|
|
246
|
+
scanningRef.current = true;
|
|
242
247
|
setScanning(true);
|
|
248
|
+
// Pause observer while scanning to prevent scan-triggered mutations causing rescans
|
|
249
|
+
(_a = observerRef.current) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
243
250
|
try {
|
|
244
251
|
const opts = { level, rules };
|
|
245
252
|
const res = await (0, browserScanner_1.scanBrowserPage)(opts);
|
|
@@ -247,7 +254,17 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
247
254
|
setLastScan(new Date());
|
|
248
255
|
}
|
|
249
256
|
finally {
|
|
257
|
+
scanningRef.current = false;
|
|
250
258
|
setScanning(false);
|
|
259
|
+
// Reconnect observer after scan settles
|
|
260
|
+
if (observerRef.current) {
|
|
261
|
+
observerRef.current.observe(document.body, {
|
|
262
|
+
childList: true,
|
|
263
|
+
subtree: true,
|
|
264
|
+
attributes: true,
|
|
265
|
+
attributeFilter: ['class', 'hidden', 'aria-hidden', 'role', 'alt', 'src', 'href'],
|
|
266
|
+
});
|
|
267
|
+
}
|
|
251
268
|
}
|
|
252
269
|
}, [level, rules]);
|
|
253
270
|
(0, react_1.useEffect)(() => { scan(); }, [scan]);
|
|
@@ -265,7 +282,9 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
265
282
|
childList: true,
|
|
266
283
|
subtree: true,
|
|
267
284
|
attributes: true,
|
|
268
|
-
|
|
285
|
+
// 'style' intentionally excluded — our highlight helper modifies inline styles
|
|
286
|
+
// on page elements which would cause an infinite rescan loop
|
|
287
|
+
attributeFilter: ['class', 'hidden', 'aria-hidden', 'role', 'alt', 'src', 'href'],
|
|
269
288
|
});
|
|
270
289
|
return () => {
|
|
271
290
|
var _a;
|
|
@@ -413,13 +432,11 @@ const WcagDevOverlay = ({ level = 'AA', rules, position = 'bottom-right', deboun
|
|
|
413
432
|
fontSize: 13,
|
|
414
433
|
fontWeight: active ? 600 : 400,
|
|
415
434
|
color: active ? '#7c3aed' : '#64748b',
|
|
416
|
-
borderBottom: active ? '2px solid #7c3aed' : '2px solid transparent',
|
|
417
435
|
cursor: 'pointer',
|
|
418
436
|
background: 'none',
|
|
419
437
|
border: 'none',
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
borderBottomWidth: 2,
|
|
438
|
+
// Use inset box-shadow instead of borderBottom to avoid shorthand/longhand conflict
|
|
439
|
+
boxShadow: active ? 'inset 0 -2px 0 #7c3aed' : 'none',
|
|
423
440
|
whiteSpace: 'nowrap',
|
|
424
441
|
});
|
|
425
442
|
const filterSelectStyle = {
|
package/dist/react/init.d.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* initWcagOverlay — auto-injects the WCAG Dev Inspector overlay.
|
|
3
3
|
*
|
|
4
4
|
* Call this from any file (js / ts / jsx / tsx) in your app entry point.
|
|
5
|
-
* It is a no-op
|
|
5
|
+
* It is a no-op in production builds.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
|
-
* // main.ts / index.js / App.tsx — one line is all you need:
|
|
9
8
|
* import { initWcagOverlay } from 'wcag-scanner/react';
|
|
10
9
|
* initWcagOverlay();
|
|
11
10
|
*
|
package/dist/react/init.js
CHANGED
|
@@ -3,88 +3,54 @@
|
|
|
3
3
|
* initWcagOverlay — auto-injects the WCAG Dev Inspector overlay.
|
|
4
4
|
*
|
|
5
5
|
* Call this from any file (js / ts / jsx / tsx) in your app entry point.
|
|
6
|
-
* It is a no-op
|
|
6
|
+
* It is a no-op in production builds.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
|
-
* // main.ts / index.js / App.tsx — one line is all you need:
|
|
10
9
|
* import { initWcagOverlay } from 'wcag-scanner/react';
|
|
11
10
|
* initWcagOverlay();
|
|
12
11
|
*
|
|
13
12
|
* // With options:
|
|
14
13
|
* initWcagOverlay({ level: 'AAA', position: 'bottom-left', debounce: 500 });
|
|
15
14
|
*/
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
-
}
|
|
22
|
-
Object.defineProperty(o, k2, desc);
|
|
23
|
-
}) : (function(o, m, k, k2) {
|
|
24
|
-
if (k2 === undefined) k2 = k;
|
|
25
|
-
o[k2] = m[k];
|
|
26
|
-
}));
|
|
27
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
-
}) : function(o, v) {
|
|
30
|
-
o["default"] = v;
|
|
31
|
-
});
|
|
32
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
-
var ownKeys = function(o) {
|
|
34
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
-
var ar = [];
|
|
36
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
-
return ar;
|
|
38
|
-
};
|
|
39
|
-
return ownKeys(o);
|
|
40
|
-
};
|
|
41
|
-
return function (mod) {
|
|
42
|
-
if (mod && mod.__esModule) return mod;
|
|
43
|
-
var result = {};
|
|
44
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
-
__setModuleDefault(result, mod);
|
|
46
|
-
return result;
|
|
47
|
-
};
|
|
48
|
-
})();
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
49
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
19
|
exports.initWcagOverlay = initWcagOverlay;
|
|
20
|
+
const react_1 = __importDefault(require("react"));
|
|
21
|
+
const WcagDevOverlay_1 = require("./WcagDevOverlay");
|
|
51
22
|
function initWcagOverlay(options = {}) {
|
|
52
|
-
|
|
53
|
-
if (typeof window === 'undefined')
|
|
23
|
+
if (typeof window === 'undefined' || typeof document === 'undefined')
|
|
54
24
|
return;
|
|
55
25
|
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production')
|
|
56
26
|
return;
|
|
57
27
|
const mount = () => {
|
|
58
|
-
// Don't mount twice
|
|
59
28
|
if (document.querySelector('[data-wcag-overlay-root]'))
|
|
60
29
|
return;
|
|
61
30
|
const container = document.createElement('div');
|
|
62
31
|
container.setAttribute('data-wcag-overlay-root', 'true');
|
|
63
32
|
document.body.appendChild(container);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// React 17 fallback
|
|
83
|
-
rd.render(el, container);
|
|
84
|
-
}
|
|
85
|
-
}).catch((err) => {
|
|
33
|
+
const el = react_1.default.createElement(WcagDevOverlay_1.WcagDevOverlay, options);
|
|
34
|
+
// React 18+: use createRoot from react-dom/client
|
|
35
|
+
try {
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
37
|
+
const { createRoot } = require('react-dom/client');
|
|
38
|
+
createRoot(container).render(el);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
catch (_a) {
|
|
42
|
+
// react-dom/client not available — React 17
|
|
43
|
+
}
|
|
44
|
+
// React 17 fallback
|
|
45
|
+
try {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
47
|
+
const ReactDOM = require('react-dom');
|
|
48
|
+
ReactDOM.render(el, container);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
86
51
|
console.warn('[wcag-scanner] Failed to mount overlay:', err);
|
|
87
|
-
|
|
52
|
+
document.body.removeChild(container);
|
|
53
|
+
}
|
|
88
54
|
};
|
|
89
55
|
if (document.readyState === 'loading') {
|
|
90
56
|
document.addEventListener('DOMContentLoaded', mount, { once: true });
|