accented 0.0.1-dev.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +14 -0
- package/README.md +71 -0
- package/dist/accented.d.ts +28 -7
- package/dist/accented.d.ts.map +1 -1
- package/dist/accented.js +107 -42
- package/dist/accented.js.map +1 -1
- package/dist/common/tokens.d.ts +7 -0
- package/dist/common/tokens.d.ts.map +1 -0
- package/dist/common/tokens.js +8 -0
- package/dist/common/tokens.js.map +1 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -0
- package/dist/dom-updater.d.ts +1 -6
- package/dist/dom-updater.d.ts.map +1 -1
- package/dist/dom-updater.js +136 -20
- package/dist/dom-updater.js.map +1 -1
- package/dist/elements/accented-dialog.d.ts +359 -0
- package/dist/elements/accented-dialog.d.ts.map +1 -0
- package/dist/elements/accented-dialog.js +377 -0
- package/dist/elements/accented-dialog.js.map +1 -0
- package/dist/elements/accented-trigger.d.ts +364 -0
- package/dist/elements/accented-trigger.d.ts.map +1 -0
- package/dist/elements/accented-trigger.js +214 -0
- package/dist/elements/accented-trigger.js.map +1 -0
- package/dist/fullscreen-listener.d.ts +2 -0
- package/dist/fullscreen-listener.d.ts.map +1 -0
- package/dist/fullscreen-listener.js +17 -0
- package/dist/fullscreen-listener.js.map +1 -0
- package/dist/intersection-observer.d.ts +5 -0
- package/dist/intersection-observer.d.ts.map +1 -0
- package/dist/intersection-observer.js +34 -0
- package/dist/intersection-observer.js.map +1 -0
- package/dist/log-and-rethrow.d.ts +2 -0
- package/dist/log-and-rethrow.d.ts.map +1 -0
- package/dist/log-and-rethrow.js +6 -0
- package/dist/log-and-rethrow.js.map +1 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +28 -0
- package/dist/logger.js.map +1 -0
- package/dist/register-elements.d.ts +2 -0
- package/dist/register-elements.d.ts.map +1 -0
- package/dist/register-elements.js +20 -0
- package/dist/register-elements.js.map +1 -0
- package/dist/resize-listener.d.ts +2 -0
- package/dist/resize-listener.d.ts.map +1 -0
- package/dist/resize-listener.js +17 -0
- package/dist/resize-listener.js.map +1 -0
- package/dist/scanner.d.ts +3 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +153 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scroll-listeners.d.ts +2 -0
- package/dist/scroll-listeners.d.ts.map +1 -0
- package/dist/scroll-listeners.js +37 -0
- package/dist/scroll-listeners.js.map +1 -0
- package/dist/state.d.ts +7 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +16 -0
- package/dist/state.js.map +1 -0
- package/dist/task-queue.d.ts +5 -6
- package/dist/task-queue.d.ts.map +1 -1
- package/dist/task-queue.js +30 -25
- package/dist/task-queue.js.map +1 -1
- package/dist/types.d.ts +227 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/are-elements-with-issues-equal.d.ts +3 -0
- package/dist/utils/are-elements-with-issues-equal.d.ts.map +1 -0
- package/dist/utils/are-elements-with-issues-equal.js +5 -0
- package/dist/utils/are-elements-with-issues-equal.js.map +1 -0
- package/dist/utils/are-issue-sets-equal.d.ts +3 -0
- package/dist/utils/are-issue-sets-equal.d.ts.map +1 -0
- package/dist/utils/are-issue-sets-equal.js +6 -0
- package/dist/utils/are-issue-sets-equal.js.map +1 -0
- package/dist/utils/containing-blocks.d.ts +3 -0
- package/dist/utils/containing-blocks.d.ts.map +1 -0
- package/dist/utils/containing-blocks.js +46 -0
- package/dist/utils/containing-blocks.js.map +1 -0
- package/dist/utils/contains.d.ts +2 -0
- package/dist/utils/contains.d.ts.map +1 -0
- package/dist/utils/contains.js +19 -0
- package/dist/utils/contains.js.map +1 -0
- package/dist/utils/deduplicate-nodes.d.ts +2 -0
- package/dist/utils/deduplicate-nodes.d.ts.map +1 -0
- package/dist/utils/deduplicate-nodes.js +4 -0
- package/dist/utils/deduplicate-nodes.js.map +1 -0
- package/dist/utils/deep-merge.d.ts +4 -0
- package/dist/utils/deep-merge.d.ts.map +1 -0
- package/dist/utils/deep-merge.js +21 -0
- package/dist/utils/deep-merge.js.map +1 -0
- package/dist/utils/dom-helpers.d.ts +9 -0
- package/dist/utils/dom-helpers.d.ts.map +1 -0
- package/dist/utils/dom-helpers.js +34 -0
- package/dist/utils/dom-helpers.js.map +1 -0
- package/dist/utils/ensure-non-empty.d.ts +2 -0
- package/dist/utils/ensure-non-empty.d.ts.map +1 -0
- package/dist/utils/ensure-non-empty.js +7 -0
- package/dist/utils/ensure-non-empty.js.map +1 -0
- package/dist/utils/get-element-html.d.ts +2 -0
- package/dist/utils/get-element-html.d.ts.map +1 -0
- package/dist/utils/get-element-html.js +16 -0
- package/dist/utils/get-element-html.js.map +1 -0
- package/dist/utils/get-element-position.d.ts +11 -0
- package/dist/utils/get-element-position.d.ts.map +1 -0
- package/dist/utils/get-element-position.js +70 -0
- package/dist/utils/get-element-position.js.map +1 -0
- package/dist/utils/get-parent.d.ts +2 -0
- package/dist/utils/get-parent.d.ts.map +1 -0
- package/dist/utils/get-parent.js +12 -0
- package/dist/utils/get-parent.js.map +1 -0
- package/dist/utils/get-scan-context.d.ts +3 -0
- package/dist/utils/get-scan-context.d.ts.map +1 -0
- package/dist/utils/get-scan-context.js +28 -0
- package/dist/utils/get-scan-context.js.map +1 -0
- package/dist/utils/get-scrollable-ancestors.d.ts +2 -0
- package/dist/utils/get-scrollable-ancestors.d.ts.map +1 -0
- package/dist/utils/get-scrollable-ancestors.js +19 -0
- package/dist/utils/get-scrollable-ancestors.js.map +1 -0
- package/dist/utils/is-node-in-scan-context.d.ts +3 -0
- package/dist/utils/is-node-in-scan-context.d.ts.map +1 -0
- package/dist/utils/is-node-in-scan-context.js +26 -0
- package/dist/utils/is-node-in-scan-context.js.map +1 -0
- 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 +3 -0
- package/dist/utils/normalize-context.d.ts.map +1 -0
- package/dist/utils/normalize-context.js +59 -0
- package/dist/utils/normalize-context.js.map +1 -0
- package/dist/utils/recalculate-positions.d.ts +2 -0
- package/dist/utils/recalculate-positions.d.ts.map +1 -0
- package/dist/utils/recalculate-positions.js +27 -0
- package/dist/utils/recalculate-positions.js.map +1 -0
- package/dist/utils/recalculate-scrollable-ancestors.d.ts +2 -0
- package/dist/utils/recalculate-scrollable-ancestors.d.ts.map +1 -0
- package/dist/utils/recalculate-scrollable-ancestors.js +13 -0
- package/dist/utils/recalculate-scrollable-ancestors.js.map +1 -0
- package/dist/utils/shadow-dom-aware-mutation-observer.d.ts +10 -0
- package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -0
- package/dist/utils/shadow-dom-aware-mutation-observer.js +61 -0
- package/dist/utils/shadow-dom-aware-mutation-observer.js.map +1 -0
- package/dist/utils/supports-anchor-positioning.d.ts +6 -0
- package/dist/utils/supports-anchor-positioning.d.ts.map +1 -0
- package/dist/utils/supports-anchor-positioning.js +4 -0
- package/dist/utils/supports-anchor-positioning.js.map +1 -0
- package/dist/utils/transform-violations.d.ts +4 -0
- package/dist/utils/transform-violations.d.ts.map +1 -0
- package/dist/utils/transform-violations.js +61 -0
- package/dist/utils/transform-violations.js.map +1 -0
- package/dist/utils/update-elements-with-issues.d.ts +13 -0
- package/dist/utils/update-elements-with-issues.d.ts.map +1 -0
- package/dist/utils/update-elements-with-issues.js +96 -0
- package/dist/utils/update-elements-with-issues.js.map +1 -0
- package/dist/validate-options.d.ts +3 -0
- package/dist/validate-options.d.ts.map +1 -0
- package/dist/validate-options.js +129 -0
- package/dist/validate-options.js.map +1 -0
- package/package.json +21 -8
- package/src/accented.test.ts +24 -0
- package/src/accented.ts +130 -0
- package/src/common/tokens.ts +10 -0
- package/src/constants.ts +3 -0
- package/src/dom-updater.ts +165 -0
- package/src/elements/accented-dialog.ts +419 -0
- package/src/elements/accented-trigger.ts +251 -0
- package/src/fullscreen-listener.ts +21 -0
- package/src/intersection-observer.ts +39 -0
- package/src/log-and-rethrow.ts +8 -0
- package/src/logger.ts +36 -0
- package/src/register-elements.ts +21 -0
- package/src/resize-listener.ts +21 -0
- package/src/scanner.ts +195 -0
- package/src/scroll-listeners.ts +45 -0
- package/src/state.ts +35 -0
- package/src/task-queue.test.ts +136 -0
- package/src/task-queue.ts +61 -0
- package/src/types.ts +258 -0
- package/src/utils/are-elements-with-issues-equal.ts +11 -0
- package/src/utils/are-issue-sets-equal.test.ts +53 -0
- package/src/utils/are-issue-sets-equal.ts +12 -0
- package/src/utils/containing-blocks.ts +60 -0
- package/src/utils/contains.test.ts +54 -0
- package/src/utils/contains.ts +19 -0
- package/src/utils/deduplicate-nodes.ts +3 -0
- package/src/utils/deep-merge.test.ts +41 -0
- package/src/utils/deep-merge.ts +24 -0
- package/src/utils/dom-helpers.ts +42 -0
- package/src/utils/ensure-non-empty.ts +6 -0
- package/src/utils/get-element-html.ts +15 -0
- package/src/utils/get-element-position.ts +89 -0
- package/src/utils/get-parent.ts +14 -0
- package/src/utils/get-scan-context.test.ts +85 -0
- package/src/utils/get-scan-context.ts +36 -0
- package/src/utils/get-scrollable-ancestors.ts +22 -0
- package/src/utils/is-node-in-scan-context.test.ts +70 -0
- package/src/utils/is-node-in-scan-context.ts +29 -0
- package/src/utils/is-non-empty.ts +3 -0
- package/src/utils/normalize-context.test.ts +105 -0
- package/src/utils/normalize-context.ts +65 -0
- package/src/utils/recalculate-positions.ts +27 -0
- package/src/utils/recalculate-scrollable-ancestors.ts +13 -0
- package/src/utils/shadow-dom-aware-mutation-observer.ts +75 -0
- package/src/utils/supports-anchor-positioning.ts +7 -0
- package/src/utils/transform-violations.test.ts +128 -0
- package/src/utils/transform-violations.ts +74 -0
- package/src/utils/update-elements-with-issues.test.ts +371 -0
- package/src/utils/update-elements-with-issues.ts +144 -0
- package/src/validate-options.ts +184 -0
- package/dist/utils/issuesToElements.d.ts +0 -3
- package/dist/utils/issuesToElements.d.ts.map +0 -1
- package/dist/utils/issuesToElements.js +0 -16
- package/dist/utils/issuesToElements.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { logAndRethrow } from './log-and-rethrow.js';
|
|
2
|
+
import { extendedElementsWithIssues } from './state.js';
|
|
3
|
+
import { getElementPosition } from './utils/get-element-position.js';
|
|
4
|
+
import { supportsAnchorPositioning } from './utils/supports-anchor-positioning.js';
|
|
5
|
+
export function setupIntersectionObserver() {
|
|
6
|
+
const intersectionObserver = new IntersectionObserver((entries) => {
|
|
7
|
+
try {
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
const extendedElementWithIssues = extendedElementsWithIssues.value.find((el) => el.element === entry.target);
|
|
10
|
+
if (extendedElementWithIssues) {
|
|
11
|
+
// We initially treated setting visibility in the intersection observer
|
|
12
|
+
// as a fallback option for browsers that don't support `position-visibility`,
|
|
13
|
+
// but then we realized that this `position-visibility` actually works
|
|
14
|
+
// in an unexpected way when the container has `overflow: visible`.
|
|
15
|
+
// So now we always set visibility in the intersection observer.
|
|
16
|
+
extendedElementWithIssues.visible.value = entry.isIntersecting;
|
|
17
|
+
if (entry.isIntersecting && !supportsAnchorPositioning(window)) {
|
|
18
|
+
extendedElementWithIssues.position.value = getElementPosition(entry.target, window);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
logAndRethrow(error);
|
|
25
|
+
}
|
|
26
|
+
}, { threshold: 0 });
|
|
27
|
+
return {
|
|
28
|
+
intersectionObserver,
|
|
29
|
+
disconnect: () => {
|
|
30
|
+
intersectionObserver.disconnect();
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=intersection-observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intersection-observer.js","sourceRoot":"","sources":["../src/intersection-observer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAEnF,MAAM,UAAU,yBAAyB;IACvC,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,CACnD,CAAC,OAAO,EAAE,EAAE;QACV,IAAI,CAAC;YACH,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,yBAAyB,GAAG,0BAA0B,CAAC,KAAK,CAAC,IAAI,CACrE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,CACpC,CAAC;gBACF,IAAI,yBAAyB,EAAE,CAAC;oBAC9B,uEAAuE;oBACvE,8EAA8E;oBAC9E,sEAAsE;oBACtE,mEAAmE;oBACnE,gEAAgE;oBAChE,yBAAyB,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC;oBAC/D,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC/D,yBAAyB,CAAC,QAAQ,CAAC,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBACtF,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EACD,EAAE,SAAS,EAAE,CAAC,EAAE,CACjB,CAAC;IAEF,OAAO;QACL,oBAAoB;QACpB,UAAU,EAAE,GAAG,EAAE;YACf,oBAAoB,CAAC,UAAU,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-and-rethrow.d.ts","sourceRoot":"","sources":["../src/log-and-rethrow.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,QAK3C"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { issuesUrl } from './constants.js';
|
|
2
|
+
export function logAndRethrow(error) {
|
|
3
|
+
console.error(`Accented threw an error (see below). Try updating your browser to the latest version. If you’re still seeing the error, file an issue at ${issuesUrl}.`);
|
|
4
|
+
throw error;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=log-and-rethrow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-and-rethrow.js","sourceRoot":"","sources":["../src/log-and-rethrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,CAAC,KAAK,CACX,4IAA4I,SAAS,GAAG,CACzJ,CAAC;IACF,MAAM,KAAK,CAAC;AACd,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AASA,wBAAgB,YAAY,eA0B3B"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { effect } from '@preact/signals-core';
|
|
2
|
+
import { accentedUrl } from './constants.js';
|
|
3
|
+
import { elementsWithIssues, enabled } from './state.js';
|
|
4
|
+
function filterPropsForOutput(elements) {
|
|
5
|
+
return elements.map(({ element, issues }) => ({ element, issues }));
|
|
6
|
+
}
|
|
7
|
+
export function createLogger() {
|
|
8
|
+
let firstRun = true;
|
|
9
|
+
return effect(() => {
|
|
10
|
+
if (!enabled.value) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const elementCount = elementsWithIssues.value.length;
|
|
14
|
+
if (elementCount > 0) {
|
|
15
|
+
const issueCount = elementsWithIssues.value.reduce((acc, { issues }) => acc + issues.length, 0);
|
|
16
|
+
console.log(`${issueCount} accessibility issue${issueCount === 1 ? '' : 's'} found in ${elementCount} element${issueCount === 1 ? '' : 's'} (Accented, ${accentedUrl}):\n`, filterPropsForOutput(elementsWithIssues.value));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
if (firstRun) {
|
|
20
|
+
firstRun = false;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
console.log(`No accessibility issues found (Accented, ${accentedUrl}).`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGzD,SAAS,oBAAoB,CAAC,QAAkC;IAC9D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,QAAQ,GAAG,IAAI,CAAC;IAEpB,OAAO,MAAM,CAAC,GAAG,EAAE;QACjB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC;QACrD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAChD,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,EACxC,CAAC,CACF,CAAC;YACF,OAAO,CAAC,GAAG,CACT,GAAG,UAAU,uBAAuB,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,aAAa,YAAY,WAAW,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,eAAe,WAAW,MAAM,EAC9J,oBAAoB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAC/C,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,GAAG,KAAK,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,4CAA4C,WAAW,IAAI,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-elements.d.ts","sourceRoot":"","sources":["../src/register-elements.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiBnD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getAccentedDialog } from './elements/accented-dialog.js';
|
|
2
|
+
import { getAccentedTrigger } from './elements/accented-trigger.js';
|
|
3
|
+
export function registerElements(name) {
|
|
4
|
+
const elements = [
|
|
5
|
+
{
|
|
6
|
+
elementName: `${name}-trigger`,
|
|
7
|
+
Component: getAccentedTrigger(name),
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
elementName: `${name}-dialog`,
|
|
11
|
+
Component: getAccentedDialog(),
|
|
12
|
+
},
|
|
13
|
+
];
|
|
14
|
+
for (const { elementName, Component } of elements) {
|
|
15
|
+
if (!customElements.get(elementName)) {
|
|
16
|
+
customElements.define(elementName, Component);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=register-elements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-elements.js","sourceRoot":"","sources":["../src/register-elements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,QAAQ,GAAG;QACf;YACE,WAAW,EAAE,GAAG,IAAI,UAAU;YAC9B,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC;SACpC;QACD;YACE,WAAW,EAAE,GAAG,IAAI,SAAS;YAC7B,SAAS,EAAE,iBAAiB,EAAE;SAC/B;KACF,CAAC;IAEF,KAAK,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;QAClD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-listener.d.ts","sourceRoot":"","sources":["../src/resize-listener.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,eAiBlC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { logAndRethrow } from './log-and-rethrow.js';
|
|
2
|
+
import { recalculatePositions } from './utils/recalculate-positions.js';
|
|
3
|
+
export function setupResizeListener() {
|
|
4
|
+
const abortController = new AbortController();
|
|
5
|
+
window.addEventListener('resize', () => {
|
|
6
|
+
try {
|
|
7
|
+
recalculatePositions();
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
logAndRethrow(error);
|
|
11
|
+
}
|
|
12
|
+
}, { signal: abortController.signal });
|
|
13
|
+
return () => {
|
|
14
|
+
abortController.abort();
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=resize-listener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize-listener.js","sourceRoot":"","sources":["../src/resize-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,UAAU,mBAAmB;IACjC,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EACR,GAAG,EAAE;QACH,IAAI,CAAC;YACH,oBAAoB,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EACD,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,CACnC,CAAC;IAEF,OAAO,GAAG,EAAE;QACV,eAAe,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ1E,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC5B,QAAQ,EAAE,QAAQ,cAgLnB"}
|
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import axe from 'axe-core';
|
|
2
|
+
import { getAccentedElementNames, issuesUrl } from './constants.js';
|
|
3
|
+
import { logAndRethrow } from './log-and-rethrow.js';
|
|
4
|
+
import { elementsWithIssues, enabled, extendedElementsWithIssues } from './state.js';
|
|
5
|
+
import { TaskQueue } from './task-queue.js';
|
|
6
|
+
import { getScanContext } from './utils/get-scan-context.js';
|
|
7
|
+
import { recalculatePositions } from './utils/recalculate-positions.js';
|
|
8
|
+
import { recalculateScrollableAncestors } from './utils/recalculate-scrollable-ancestors.js';
|
|
9
|
+
import { createShadowDOMAwareMutationObserver } from './utils/shadow-dom-aware-mutation-observer.js';
|
|
10
|
+
import { supportsAnchorPositioning } from './utils/supports-anchor-positioning.js';
|
|
11
|
+
import { updateElementsWithIssues } from './utils/update-elements-with-issues.js';
|
|
12
|
+
export function createScanner(name, context, axeOptions, throttle, callback) {
|
|
13
|
+
const axeRunningWindowProp = `__${name}_axe_running__`;
|
|
14
|
+
const win = window;
|
|
15
|
+
const taskQueue = new TaskQueue(async (nodes) => {
|
|
16
|
+
// We may see errors coming from axe-core when Accented is toggled off and on in qiuck succession,
|
|
17
|
+
// which I've seen happen with hot reloading of a React application.
|
|
18
|
+
// This window property serves as a circuit breaker for that particular case.
|
|
19
|
+
if (win[axeRunningWindowProp]) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
performance.mark('scan-start');
|
|
24
|
+
win[axeRunningWindowProp] = true;
|
|
25
|
+
const scanContext = getScanContext(nodes, context);
|
|
26
|
+
let result;
|
|
27
|
+
try {
|
|
28
|
+
result = await axe.run(scanContext, {
|
|
29
|
+
/**
|
|
30
|
+
* By default, axe-core doesn't include element refs
|
|
31
|
+
* in the violations array,
|
|
32
|
+
* and we need those element refs.
|
|
33
|
+
*/
|
|
34
|
+
elementRef: true,
|
|
35
|
+
/**
|
|
36
|
+
* Although axe-core can perform iframe scanning, I haven't succeeded in it,
|
|
37
|
+
* and the docs suggest that the axe-core script should be explicitly included
|
|
38
|
+
* in each of the iframed documents anyway.
|
|
39
|
+
* It seems preferable to disallow iframe scanning and not report issues in elements within iframes
|
|
40
|
+
* in the case that such issues are for some reason reported by axe-core.
|
|
41
|
+
* A consumer of Accented can instead scan the iframed document by calling Accented initialization from that document.
|
|
42
|
+
*/
|
|
43
|
+
iframes: false,
|
|
44
|
+
/**
|
|
45
|
+
* The `preload` docs are not clear to me,
|
|
46
|
+
* but when it's set to `true` by default,
|
|
47
|
+
* axe-core tries to fetch cross-origin CSS,
|
|
48
|
+
* which fails in the absence of CORS headers.
|
|
49
|
+
* I'm not sure why axe-core needs to preload
|
|
50
|
+
* those resources in the first place,
|
|
51
|
+
* so disabling it seems to be the safe option.
|
|
52
|
+
*/
|
|
53
|
+
preload: false,
|
|
54
|
+
/**
|
|
55
|
+
* We're only interested in violations,
|
|
56
|
+
* not in passes or incomplete results.
|
|
57
|
+
*/
|
|
58
|
+
resultTypes: ['violations'],
|
|
59
|
+
...axeOptions,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(`Accented: axe-core (the accessibility testing engine) threw an error. Check the \`axeOptions\` property (https://www.accented.dev/api#axeoptions) that you’re passing to Accented. If you still think it’s a bug in Accented, file an issue at ${issuesUrl}.\n`, error);
|
|
64
|
+
}
|
|
65
|
+
win[axeRunningWindowProp] = false;
|
|
66
|
+
const scanMeasure = performance.measure('scan', 'scan-start');
|
|
67
|
+
const scanDuration = Math.round(scanMeasure.duration);
|
|
68
|
+
if (!enabled.value || !result) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
performance.mark('dom-update-start');
|
|
72
|
+
updateElementsWithIssues({
|
|
73
|
+
extendedElementsWithIssues,
|
|
74
|
+
scanContext,
|
|
75
|
+
violations: result.violations,
|
|
76
|
+
win: window,
|
|
77
|
+
name,
|
|
78
|
+
});
|
|
79
|
+
const domUpdateMeasure = performance.measure('dom-update', 'dom-update-start');
|
|
80
|
+
const domUpdateDuration = Math.round(domUpdateMeasure.duration);
|
|
81
|
+
callback({
|
|
82
|
+
// Assuming that the {include, exclude} shape of the context object will be used less often
|
|
83
|
+
// than other variants, we'll output just the `include` array in case nothing is excluded
|
|
84
|
+
// in the scan.
|
|
85
|
+
scanContext: scanContext.exclude.length > 0 ? scanContext : scanContext.include,
|
|
86
|
+
elementsWithIssues: elementsWithIssues.value,
|
|
87
|
+
performance: {
|
|
88
|
+
totalBlockingTime: scanDuration + domUpdateDuration,
|
|
89
|
+
scan: scanDuration,
|
|
90
|
+
domUpdate: domUpdateDuration,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
win[axeRunningWindowProp] = false;
|
|
96
|
+
logAndRethrow(error);
|
|
97
|
+
}
|
|
98
|
+
}, throttle);
|
|
99
|
+
taskQueue.add(document);
|
|
100
|
+
const accentedElementNames = getAccentedElementNames(name);
|
|
101
|
+
const mutationObserver = createShadowDOMAwareMutationObserver(name, (mutationList) => {
|
|
102
|
+
try {
|
|
103
|
+
// We're not interested in mutations that are caused exclusively by the custom elements
|
|
104
|
+
// introduced by Accented.
|
|
105
|
+
const listWithoutAccentedElements = mutationList.filter((mutationRecord) => {
|
|
106
|
+
const onlyAccentedElementsAddedOrRemoved = mutationRecord.type === 'childList' &&
|
|
107
|
+
[...mutationRecord.addedNodes].every((node) => accentedElementNames.includes(node.nodeName.toLowerCase())) &&
|
|
108
|
+
[...mutationRecord.removedNodes].every((node) => accentedElementNames.includes(node.nodeName.toLowerCase()));
|
|
109
|
+
const accentedElementChanged = mutationRecord.type === 'attributes' &&
|
|
110
|
+
accentedElementNames.includes(mutationRecord.target.nodeName.toLowerCase());
|
|
111
|
+
return !(onlyAccentedElementsAddedOrRemoved || accentedElementChanged);
|
|
112
|
+
});
|
|
113
|
+
if (listWithoutAccentedElements.length !== 0 && !supportsAnchorPositioning(window)) {
|
|
114
|
+
// Something has changed in the DOM, so we need to realign all triggers with respective elements.
|
|
115
|
+
recalculatePositions();
|
|
116
|
+
// Elements' scrollable ancestors only change when styles change
|
|
117
|
+
// (specifically when the `display` prop on one of the ancestors changes),
|
|
118
|
+
// so a good place to recalculate the scrollable ancestors for elements is here.
|
|
119
|
+
// In future, we could further optimize this by only recalculating scrollable ancestors for elements that have changed.
|
|
120
|
+
recalculateScrollableAncestors();
|
|
121
|
+
}
|
|
122
|
+
// Exclude all mutations on elements that got the accented attribute added or removed.
|
|
123
|
+
// If we simply exclude all mutations where attributeName = `data-${name}`,
|
|
124
|
+
// we may miss other mutations on those same elements caused by Accented,
|
|
125
|
+
// leading to extra runs of the mutation observer.
|
|
126
|
+
const elementsWithAccentedAttributeChanges = listWithoutAccentedElements.reduce((nodes, mutationRecord) => {
|
|
127
|
+
if (mutationRecord.type === 'attributes' &&
|
|
128
|
+
mutationRecord.attributeName === `data-${name}`) {
|
|
129
|
+
nodes.add(mutationRecord.target);
|
|
130
|
+
}
|
|
131
|
+
return nodes;
|
|
132
|
+
}, new Set());
|
|
133
|
+
const filteredMutationList = listWithoutAccentedElements.filter((mutationRecord) => {
|
|
134
|
+
return !elementsWithAccentedAttributeChanges.has(mutationRecord.target);
|
|
135
|
+
});
|
|
136
|
+
const nodes = filteredMutationList.map((mutationRecord) => mutationRecord.target);
|
|
137
|
+
taskQueue.addMultiple(nodes);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
logAndRethrow(error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
mutationObserver.observe(document, {
|
|
144
|
+
subtree: true,
|
|
145
|
+
childList: true,
|
|
146
|
+
attributes: true,
|
|
147
|
+
characterData: true,
|
|
148
|
+
});
|
|
149
|
+
return () => {
|
|
150
|
+
mutationObserver.disconnect();
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll-listeners.d.ts","sourceRoot":"","sources":["../src/scroll-listeners.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,eAuCnC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { effect } from '@preact/signals-core';
|
|
2
|
+
import { logAndRethrow } from './log-and-rethrow.js';
|
|
3
|
+
import { scrollableAncestors } from './state.js';
|
|
4
|
+
import { recalculatePositions } from './utils/recalculate-positions.js';
|
|
5
|
+
export function setupScrollListeners() {
|
|
6
|
+
const documentAbortController = new AbortController();
|
|
7
|
+
document.addEventListener('scroll', () => {
|
|
8
|
+
try {
|
|
9
|
+
recalculatePositions();
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
logAndRethrow(error);
|
|
13
|
+
}
|
|
14
|
+
}, { signal: documentAbortController.signal });
|
|
15
|
+
const disposeOfEffect = effect(() => {
|
|
16
|
+
// TODO: optimize performance, issue #81
|
|
17
|
+
const elementAbortController = new AbortController();
|
|
18
|
+
for (const scrollableAncestor of scrollableAncestors.value) {
|
|
19
|
+
scrollableAncestor.addEventListener('scroll', () => {
|
|
20
|
+
try {
|
|
21
|
+
recalculatePositions();
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
logAndRethrow(error);
|
|
25
|
+
}
|
|
26
|
+
}, { signal: elementAbortController.signal });
|
|
27
|
+
}
|
|
28
|
+
return () => {
|
|
29
|
+
elementAbortController.abort();
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
return () => {
|
|
33
|
+
documentAbortController.abort();
|
|
34
|
+
disposeOfEffect();
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=scroll-listeners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll-listeners.js","sourceRoot":"","sources":["../src/scroll-listeners.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,UAAU,oBAAoB;IAClC,MAAM,uBAAuB,GAAG,IAAI,eAAe,EAAE,CAAC;IACtD,QAAQ,CAAC,gBAAgB,CACvB,QAAQ,EACR,GAAG,EAAE;QACH,IAAI,CAAC;YACH,oBAAoB,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EACD,EAAE,MAAM,EAAE,uBAAuB,CAAC,MAAM,EAAE,CAC3C,CAAC;IAEF,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,EAAE;QAClC,wCAAwC;QACxC,MAAM,sBAAsB,GAAG,IAAI,eAAe,EAAE,CAAC;QACrD,KAAK,MAAM,kBAAkB,IAAI,mBAAmB,CAAC,KAAK,EAAE,CAAC;YAC3D,kBAAkB,CAAC,gBAAgB,CACjC,QAAQ,EACR,GAAG,EAAE;gBACH,IAAI,CAAC;oBACH,oBAAoB,EAAE,CAAC;gBACzB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,aAAa,CAAC,KAAK,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC,EACD,EAAE,MAAM,EAAE,sBAAsB,CAAC,MAAM,EAAE,CAC1C,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,EAAE;YACV,sBAAsB,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACV,uBAAuB,CAAC,KAAK,EAAE,CAAC;QAChC,eAAe,EAAE,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ElementWithIssues, ExtendedElementWithIssues } from './types.ts';
|
|
2
|
+
export declare const enabled: import("@preact/signals-core").Signal<boolean>;
|
|
3
|
+
export declare const extendedElementsWithIssues: import("@preact/signals-core").Signal<ExtendedElementWithIssues[]>;
|
|
4
|
+
export declare const elementsWithIssues: import("@preact/signals-core").ReadonlySignal<ElementWithIssues[]>;
|
|
5
|
+
export declare const rootNodes: import("@preact/signals-core").ReadonlySignal<Set<Node>>;
|
|
6
|
+
export declare const scrollableAncestors: import("@preact/signals-core").ReadonlySignal<Set<Element>>;
|
|
7
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE/E,eAAO,MAAM,OAAO,gDAAgB,CAAC;AAErC,eAAO,MAAM,0BAA0B,oEAA+C,CAAC;AAEvF,eAAO,MAAM,kBAAkB,oEAM9B,CAAC;AAEF,eAAO,MAAM,SAAS,0DASrB,CAAC;AAEF,eAAO,MAAM,mBAAmB,6DAO/B,CAAC"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { computed, signal } from '@preact/signals-core';
|
|
2
|
+
export const enabled = signal(false);
|
|
3
|
+
export const extendedElementsWithIssues = signal([]);
|
|
4
|
+
export const elementsWithIssues = computed(() => extendedElementsWithIssues.value.map((extendedElementWithIssues) => ({
|
|
5
|
+
element: extendedElementWithIssues.element,
|
|
6
|
+
rootNode: extendedElementWithIssues.rootNode,
|
|
7
|
+
issues: extendedElementWithIssues.issues.value,
|
|
8
|
+
})));
|
|
9
|
+
export const rootNodes = computed(() => new Set((enabled.value ? [document] : []).concat(...extendedElementsWithIssues.value.map((extendedElementWithIssues) => extendedElementWithIssues.rootNode))));
|
|
10
|
+
export const scrollableAncestors = computed(() => extendedElementsWithIssues.value.reduce((scrollableAncestors, extendedElementWithIssues) => {
|
|
11
|
+
for (const scrollableAncestor of extendedElementWithIssues.scrollableAncestors.value) {
|
|
12
|
+
scrollableAncestors.add(scrollableAncestor);
|
|
13
|
+
}
|
|
14
|
+
return scrollableAncestors;
|
|
15
|
+
}, new Set()));
|
|
16
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAIxD,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAmC,EAAE,CAAC,CAAC;AAEvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAA2B,GAAG,EAAE,CACxE,0BAA0B,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IACnE,OAAO,EAAE,yBAAyB,CAAC,OAAO;IAC1C,QAAQ,EAAE,yBAAyB,CAAC,QAAQ;IAC5C,MAAM,EAAE,yBAAyB,CAAC,MAAM,CAAC,KAAK;CAC/C,CAAC,CAAC,CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ,CAC/B,GAAG,EAAE,CACH,IAAI,GAAG,CACL,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAC9C,GAAG,0BAA0B,CAAC,KAAK,CAAC,GAAG,CACrC,CAAC,yBAAyB,EAAE,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAClE,CACF,CACF,CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,QAAQ,CAAe,GAAG,EAAE,CAC7D,0BAA0B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,mBAAmB,EAAE,yBAAyB,EAAE,EAAE;IACzF,KAAK,MAAM,kBAAkB,IAAI,yBAAyB,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;QACrF,mBAAmB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,CAAC,EAAE,IAAI,GAAG,EAAW,CAAC,CACvB,CAAC"}
|
package/dist/task-queue.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
1
|
+
import type { Throttle } from './types.ts';
|
|
2
|
+
type TaskCallback<T> = (items: Array<T>) => void;
|
|
3
|
+
export declare class TaskQueue<T> {
|
|
3
4
|
#private;
|
|
4
|
-
constructor(asyncCallback: TaskCallback
|
|
5
|
-
|
|
6
|
-
throttleDelay?: number;
|
|
7
|
-
});
|
|
5
|
+
constructor(asyncCallback: TaskCallback<T>, throttle: Required<Throttle>);
|
|
6
|
+
addMultiple(items: Array<T>): void;
|
|
8
7
|
add(item: T): void;
|
|
9
8
|
}
|
|
10
9
|
export {};
|
package/dist/task-queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-queue.d.ts","sourceRoot":"","sources":["../src/task-queue.ts"],"names":[],"mappings":"AAAA,KAAK,
|
|
1
|
+
{"version":3,"file":"task-queue.d.ts","sourceRoot":"","sources":["../src/task-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEjD,qBAAa,SAAS,CAAC,CAAC;;gBAOV,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAqCxE,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAS3B,GAAG,CAAC,IAAI,EAAE,CAAC;CAGZ"}
|
package/dist/task-queue.js
CHANGED
|
@@ -1,40 +1,45 @@
|
|
|
1
|
-
export
|
|
2
|
-
#
|
|
3
|
-
#runningOrScheduled = false;
|
|
4
|
-
#initialDelay;
|
|
5
|
-
#throttleDelay;
|
|
6
|
-
// I'm not sure why the editor needs NodeJS.Timeout here.
|
|
7
|
-
// tsconfig.json doesn't mention that the code needs to run in Node.
|
|
8
|
-
// Maybe it's somehow related to the fact that we're using the Node test runner.
|
|
9
|
-
#timeoutId = null;
|
|
1
|
+
export class TaskQueue {
|
|
2
|
+
#throttle;
|
|
10
3
|
#asyncCallback = null;
|
|
11
|
-
|
|
4
|
+
#items = new Set();
|
|
5
|
+
#inRunLoop = false;
|
|
6
|
+
constructor(asyncCallback, throttle) {
|
|
12
7
|
this.#asyncCallback = asyncCallback;
|
|
13
|
-
this.#
|
|
14
|
-
this.#throttleDelay = throttleDelay ?? 1000;
|
|
8
|
+
this.#throttle = throttle;
|
|
15
9
|
}
|
|
16
|
-
#
|
|
17
|
-
if (this.#
|
|
18
|
-
this.#runningOrScheduled = false;
|
|
19
|
-
}
|
|
20
|
-
if (this.#timeoutId !== null || this.#items.size === 0) {
|
|
10
|
+
async #preRun() {
|
|
11
|
+
if (this.#inRunLoop) {
|
|
21
12
|
return;
|
|
22
13
|
}
|
|
23
|
-
|
|
24
|
-
this.#
|
|
25
|
-
|
|
14
|
+
this.#inRunLoop = true;
|
|
15
|
+
if (!this.#throttle.leading) {
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, this.#throttle.wait));
|
|
17
|
+
}
|
|
18
|
+
await this.#run();
|
|
26
19
|
}
|
|
27
20
|
async #run() {
|
|
21
|
+
if (this.#items.size === 0) {
|
|
22
|
+
this.#inRunLoop = false;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const items = Array.from(this.#items);
|
|
28
26
|
this.#items.clear();
|
|
29
27
|
if (this.#asyncCallback) {
|
|
30
|
-
await this.#asyncCallback();
|
|
28
|
+
await this.#asyncCallback(items);
|
|
29
|
+
}
|
|
30
|
+
await new Promise((resolve) => setTimeout(resolve, this.#throttle.wait));
|
|
31
|
+
await this.#run();
|
|
32
|
+
}
|
|
33
|
+
addMultiple(items) {
|
|
34
|
+
for (const item of items) {
|
|
35
|
+
this.#items.add(item);
|
|
36
|
+
}
|
|
37
|
+
if (this.#items.size > 0) {
|
|
38
|
+
this.#preRun();
|
|
31
39
|
}
|
|
32
|
-
this.#timeoutId = null;
|
|
33
|
-
this.#scheduleRun();
|
|
34
40
|
}
|
|
35
41
|
add(item) {
|
|
36
|
-
this
|
|
37
|
-
this.#scheduleRun();
|
|
42
|
+
this.addMultiple([item]);
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
//# sourceMappingURL=task-queue.js.map
|
package/dist/task-queue.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-queue.js","sourceRoot":"","sources":["../src/task-queue.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task-queue.js","sourceRoot":"","sources":["../src/task-queue.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,SAAS;IACpB,SAAS,CAAW;IACpB,cAAc,GAA2B,IAAI,CAAC;IAE9C,MAAM,GAAG,IAAI,GAAG,EAAK,CAAC;IACtB,UAAU,GAAG,KAAK,CAAC;IAEnB,YAAY,aAA8B,EAAE,QAA4B;QACtE,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEtC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAEzE,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,WAAW,CAAC,KAAe;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAO;QACT,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3B,CAAC;CACF"}
|