accented 0.0.0-20250404114312 → 0.0.0-20250424114613

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +3 -1
  2. package/dist/accented.d.ts.map +1 -1
  3. package/dist/accented.js +5 -3
  4. package/dist/accented.js.map +1 -1
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/dom-updater.d.ts.map +1 -1
  7. package/dist/dom-updater.js +29 -3
  8. package/dist/dom-updater.js.map +1 -1
  9. package/dist/elements/accented-dialog.d.ts +11 -7
  10. package/dist/elements/accented-dialog.d.ts.map +1 -1
  11. package/dist/elements/accented-dialog.js +35 -64
  12. package/dist/elements/accented-dialog.js.map +1 -1
  13. package/dist/elements/accented-trigger.d.ts +9 -5
  14. package/dist/elements/accented-trigger.d.ts.map +1 -1
  15. package/dist/elements/accented-trigger.js +6 -5
  16. package/dist/elements/accented-trigger.js.map +1 -1
  17. package/dist/logger.d.ts.map +1 -1
  18. package/dist/logger.js +4 -1
  19. package/dist/logger.js.map +1 -1
  20. package/dist/scanner.d.ts +2 -2
  21. package/dist/scanner.d.ts.map +1 -1
  22. package/dist/scanner.js +19 -14
  23. package/dist/scanner.js.map +1 -1
  24. package/dist/task-queue.d.ts +2 -2
  25. package/dist/task-queue.d.ts.map +1 -1
  26. package/dist/task-queue.js +2 -1
  27. package/dist/task-queue.js.map +1 -1
  28. package/dist/types.d.ts +25 -3
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/types.js.map +1 -1
  31. package/dist/utils/containing-blocks.d.ts +3 -0
  32. package/dist/utils/containing-blocks.d.ts.map +1 -0
  33. package/dist/utils/containing-blocks.js +46 -0
  34. package/dist/utils/containing-blocks.js.map +1 -0
  35. package/dist/utils/contains.d.ts +2 -0
  36. package/dist/utils/contains.d.ts.map +1 -0
  37. package/dist/utils/contains.js +19 -0
  38. package/dist/utils/contains.js.map +1 -0
  39. package/dist/utils/deduplicate-nodes.d.ts +2 -0
  40. package/dist/utils/deduplicate-nodes.d.ts.map +1 -0
  41. package/dist/utils/deduplicate-nodes.js +5 -0
  42. package/dist/utils/deduplicate-nodes.js.map +1 -0
  43. package/dist/utils/dom-helpers.d.ts +3 -0
  44. package/dist/utils/dom-helpers.d.ts.map +1 -1
  45. package/dist/utils/dom-helpers.js +13 -0
  46. package/dist/utils/dom-helpers.js.map +1 -1
  47. package/dist/utils/ensure-non-empty.d.ts +2 -0
  48. package/dist/utils/ensure-non-empty.d.ts.map +1 -0
  49. package/dist/utils/ensure-non-empty.js +7 -0
  50. package/dist/utils/ensure-non-empty.js.map +1 -0
  51. package/dist/utils/get-element-position.d.ts +8 -0
  52. package/dist/utils/get-element-position.d.ts.map +1 -1
  53. package/dist/utils/get-element-position.js +22 -7
  54. package/dist/utils/get-element-position.js.map +1 -1
  55. package/dist/utils/get-scan-context.d.ts +3 -0
  56. package/dist/utils/get-scan-context.d.ts.map +1 -0
  57. package/dist/utils/get-scan-context.js +28 -0
  58. package/dist/utils/get-scan-context.js.map +1 -0
  59. package/dist/utils/is-node-in-scan-context.d.ts +3 -0
  60. package/dist/utils/is-node-in-scan-context.d.ts.map +1 -0
  61. package/dist/utils/is-node-in-scan-context.js +26 -0
  62. package/dist/utils/is-node-in-scan-context.js.map +1 -0
  63. package/dist/utils/normalize-context.d.ts +3 -0
  64. package/dist/utils/normalize-context.d.ts.map +1 -0
  65. package/dist/utils/normalize-context.js +57 -0
  66. package/dist/utils/normalize-context.js.map +1 -0
  67. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -1
  68. package/dist/utils/update-elements-with-issues.d.ts +10 -4
  69. package/dist/utils/update-elements-with-issues.d.ts.map +1 -1
  70. package/dist/utils/update-elements-with-issues.js +25 -2
  71. package/dist/utils/update-elements-with-issues.js.map +1 -1
  72. package/dist/validate-options.d.ts.map +1 -1
  73. package/dist/validate-options.js +86 -0
  74. package/dist/validate-options.js.map +1 -1
  75. package/package.json +7 -3
  76. package/src/accented.ts +5 -3
  77. package/src/dom-updater.ts +33 -3
  78. package/src/elements/accented-dialog.ts +38 -68
  79. package/src/elements/accented-trigger.ts +6 -5
  80. package/src/logger.ts +9 -1
  81. package/src/scanner.ts +21 -15
  82. package/src/task-queue.ts +6 -4
  83. package/src/types.ts +38 -5
  84. package/src/utils/containing-blocks.ts +57 -0
  85. package/src/utils/contains.test.ts +55 -0
  86. package/src/utils/contains.ts +19 -0
  87. package/src/utils/deduplicate-nodes.ts +3 -0
  88. package/src/utils/dom-helpers.ts +16 -0
  89. package/src/utils/ensure-non-empty.ts +6 -0
  90. package/src/utils/get-element-position.ts +23 -7
  91. package/src/utils/get-scan-context.test.ts +79 -0
  92. package/src/utils/get-scan-context.ts +39 -0
  93. package/src/utils/is-node-in-scan-context.test.ts +70 -0
  94. package/src/utils/is-node-in-scan-context.ts +29 -0
  95. package/src/utils/normalize-context.test.ts +105 -0
  96. package/src/utils/normalize-context.ts +58 -0
  97. package/src/utils/update-elements-with-issues.test.ts +61 -8
  98. package/src/utils/update-elements-with-issues.ts +42 -3
  99. package/src/validate-options.ts +88 -1
@@ -0,0 +1,57 @@
1
+ import { isNode, isNodeList } from './dom-helpers.js';
2
+ import { deduplicateNodes } from './deduplicate-nodes.js';
3
+ function recursiveSelectAll(selectors, root) {
4
+ const nodesOnCurrentLevel = root.querySelectorAll(selectors[0]);
5
+ if (selectors.length === 1) {
6
+ return Array.from(nodesOnCurrentLevel);
7
+ }
8
+ const restSelectors = selectors.slice(1);
9
+ const selected = [];
10
+ for (const node of nodesOnCurrentLevel) {
11
+ if (node.shadowRoot) {
12
+ selected.push(...recursiveSelectAll(restSelectors, node.shadowRoot));
13
+ }
14
+ }
15
+ return selected;
16
+ }
17
+ function selectorToNodes(selector) {
18
+ if (typeof selector === 'string') {
19
+ return recursiveSelectAll([selector], document);
20
+ }
21
+ else if (isNode(selector)) {
22
+ return [selector];
23
+ }
24
+ else {
25
+ return recursiveSelectAll(selector.fromShadowDom, document);
26
+ }
27
+ }
28
+ function contextPropToNodes(contextProp) {
29
+ let nodes = [];
30
+ if (typeof contextProp === 'object' && (Array.isArray(contextProp) || isNodeList(contextProp))) {
31
+ nodes = Array.from(contextProp).map(item => selectorToNodes(item)).flat();
32
+ }
33
+ else {
34
+ nodes = selectorToNodes(contextProp);
35
+ }
36
+ return deduplicateNodes(nodes);
37
+ }
38
+ export default function normalizeContext(context) {
39
+ let contextInclude = [];
40
+ let contextExclude = [];
41
+ if (typeof context === 'object' && ('include' in context || 'exclude' in context)) {
42
+ if (context.include !== undefined) {
43
+ contextInclude = contextPropToNodes(context.include);
44
+ }
45
+ if (context.exclude !== undefined) {
46
+ contextExclude = contextPropToNodes(context.exclude);
47
+ }
48
+ }
49
+ else {
50
+ contextInclude = contextPropToNodes(context);
51
+ }
52
+ return {
53
+ include: contextInclude,
54
+ exclude: contextExclude
55
+ };
56
+ }
57
+ //# sourceMappingURL=normalize-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-context.js","sourceRoot":"","sources":["../../src/utils/normalize-context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,SAAS,kBAAkB,CAAC,SAAwB,EAAE,IAA2B;IAC/E,MAAM,mBAAmB,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAC;IACjE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,aAAa,GAAkB,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,QAAkB;IACzC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,kBAAkB,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,OAAO,kBAAkB,CAAC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,WAAwB;IAClD,IAAI,KAAK,GAAgB,EAAE,CAAC;IAC5B,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QAC/F,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,OAAgB;IACvD,IAAI,cAAc,GAAgB,EAAE,CAAC;IACrC,IAAI,cAAc,GAAgB,EAAE,CAAC;IACrC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,CAAC,EAAE,CAAC;QAClF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO;QACL,OAAO,EAAE,cAAc;QACvB,OAAO,EAAE,cAAc;KACxB,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-dom-aware-mutation-observer.d.ts","sourceRoot":"","sources":["../../src/utils/shadow-dom-aware-mutation-observer.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,oCAAoC,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB;;qBAIxF,oBAAoB,GAAG,SAAS;oBA8BjB,IAAI,YAAY,oBAAoB,GAAG,IAAI;kBAQ7C,IAAI;2CAKM,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,gBAAgB,CAAC;0CAa7C,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,gBAAgB,CAAC;;EAc/E"}
1
+ {"version":3,"file":"shadow-dom-aware-mutation-observer.d.ts","sourceRoot":"","sources":["../../src/utils/shadow-dom-aware-mutation-observer.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,oCAAoC,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB;;qBAIxF,oBAAoB,GAAG,SAAS;oBA8BjB,IAAI,YAAY,oBAAoB,GAAG,IAAI;kBAQ7C,IAAI;iCAKJ,UAAU,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,gBAAgB,CAAC;gCAavD,UAAU,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,gBAAgB,CAAC;;EAc/E"}
@@ -1,7 +1,13 @@
1
1
  import type { AxeResults } from 'axe-core';
2
2
  import type { Signal } from '@preact/signals-core';
3
- import type { ExtendedElementWithIssues } from '../types';
4
- export default function updateElementsWithIssues(extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>>, violations: typeof AxeResults.violations, win: Window & {
5
- CSS: typeof CSS;
6
- }, name: string): void;
3
+ import type { ExtendedElementWithIssues, ScanContext } from '../types';
4
+ export default function updateElementsWithIssues({ extendedElementsWithIssues, scanContext, violations, win, name }: {
5
+ extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>>;
6
+ scanContext: ScanContext;
7
+ violations: typeof AxeResults.violations;
8
+ win: Window & {
9
+ CSS: typeof CSS;
10
+ };
11
+ name: string;
12
+ }): void;
7
13
  //# sourceMappingURL=update-elements-with-issues.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-elements-with-issues.d.ts","sourceRoot":"","sources":["../../src/utils/update-elements-with-issues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAY1D,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,0BAA0B,EAAE,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,OAAO,GAAG,CAAA;CAAE,EAAE,IAAI,EAAE,MAAM,QAgE/M"}
1
+ {"version":3,"file":"update-elements-with-issues.d.ts","sourceRoot":"","sources":["../../src/utils/update-elements-with-issues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAgCvE,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,EAC/C,0BAA0B,EAC1B,WAAW,EACX,UAAU,EACV,GAAG,EACH,IAAI,EACL,EAAE;IACD,0BAA0B,EAAE,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACrE,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,OAAO,UAAU,CAAC,UAAU,CAAC;IACzC,GAAG,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,OAAO,GAAG,CAAA;KAAE,CAAC;IAClC,IAAI,EAAE,MAAM,CAAA;CACb,QAuEA"}
@@ -2,11 +2,27 @@ import { batch, signal } from '@preact/signals-core';
2
2
  import transformViolations from './transform-violations.js';
3
3
  import areElementsWithIssuesEqual from './are-elements-with-issues-equal.js';
4
4
  import areIssueSetsEqual from './are-issue-sets-equal.js';
5
+ import isNodeInScanContext from './is-node-in-scan-context.js';
5
6
  import getElementPosition from './get-element-position.js';
6
7
  import getScrollableAncestors from './get-scrollable-ancestors.js';
7
8
  import supportsAnchorPositioning from './supports-anchor-positioning.js';
9
+ import { isSvgElement } from './dom-helpers.js';
10
+ import getParent from './get-parent.js';
11
+ function shouldSkipRender(element) {
12
+ // Skip rendering if the element is inside an SVG:
13
+ // https://github.com/pomerantsev/accented/issues/62
14
+ const parent = getParent(element);
15
+ const isInsideSvg = Boolean(parent && isSvgElement(parent));
16
+ // Some issues, such as meta-viewport, are on <head> descendants,
17
+ // but since <head> is never rendered, we don't want to output anything
18
+ // for those in the DOM.
19
+ // We're not anticipating the use of shadow DOM in <head>,
20
+ // so the use of .closest() should be fine.
21
+ const isInsideHead = element.closest('head') !== null;
22
+ return isInsideSvg || isInsideHead;
23
+ }
8
24
  let count = 0;
9
- export default function updateElementsWithIssues(extendedElementsWithIssues, violations, win, name) {
25
+ export default function updateElementsWithIssues({ extendedElementsWithIssues, scanContext, violations, win, name }) {
10
26
  const updatedElementsWithIssues = transformViolations(violations, name);
11
27
  batch(() => {
12
28
  for (const updatedElementWithIssues of updatedElementsWithIssues) {
@@ -18,8 +34,14 @@ export default function updateElementsWithIssues(extendedElementsWithIssues, vio
18
34
  const addedElementsWithIssues = updatedElementsWithIssues.filter(updatedElementWithIssues => {
19
35
  return !extendedElementsWithIssues.value.some(extendedElementWithIssues => areElementsWithIssuesEqual(extendedElementWithIssues, updatedElementWithIssues));
20
36
  });
37
+ // Only consider an element to be removed in two cases:
38
+ // 1. It has been removed from the DOM.
39
+ // 2. It is within the scan context, but not among updatedElementsWithIssues.
21
40
  const removedElementsWithIssues = extendedElementsWithIssues.value.filter(extendedElementWithIssues => {
22
- return !updatedElementsWithIssues.some(updatedElementWithIssues => areElementsWithIssuesEqual(updatedElementWithIssues, extendedElementWithIssues));
41
+ const isConnected = extendedElementWithIssues.element.isConnected;
42
+ const hasNoMoreIssues = isNodeInScanContext(extendedElementWithIssues.element, scanContext)
43
+ && !updatedElementsWithIssues.some(updatedElementWithIssues => areElementsWithIssuesEqual(updatedElementWithIssues, extendedElementWithIssues));
44
+ return !isConnected || hasNoMoreIssues;
23
45
  });
24
46
  if (addedElementsWithIssues.length > 0 || removedElementsWithIssues.length > 0) {
25
47
  extendedElementsWithIssues.value = [...extendedElementsWithIssues.value]
@@ -52,6 +74,7 @@ export default function updateElementsWithIssues(extendedElementsWithIssues, vio
52
74
  return {
53
75
  id,
54
76
  element: addedElementWithIssues.element,
77
+ skipRender: shouldSkipRender(addedElementWithIssues.element),
55
78
  rootNode: addedElementWithIssues.rootNode,
56
79
  visible: trigger.visible,
57
80
  position: trigger.position,
@@ -1 +1 @@
1
- {"version":3,"file":"update-elements-with-issues.js","sourceRoot":"","sources":["../../src/utils/update-elements-with-issues.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update-elements-with-issues.js","sourceRoot":"","sources":["../../src/utils/update-elements-with-issues.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate-options.d.ts","sourceRoot":"","sources":["../src/validate-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ/C,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,OAAO,EAAE,eAAe,QAmC/D"}
1
+ {"version":3,"file":"validate-options.d.ts","sourceRoot":"","sources":["../src/validate-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsD,eAAe,EAAW,MAAM,SAAS,CAAC;AA4F5G,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,OAAO,EAAE,eAAe,QAsC/D"}
@@ -1,4 +1,87 @@
1
1
  import { allowedAxeOptions } from './types.js';
2
+ import { isNode, isNodeList } from './utils/dom-helpers.js';
3
+ function isSelector(contextFragment) {
4
+ return typeof contextFragment === 'string'
5
+ || isNode(contextFragment)
6
+ || 'fromShadowDom' in contextFragment;
7
+ }
8
+ function validateSelector(selector) {
9
+ if (typeof selector === 'string') {
10
+ return;
11
+ }
12
+ else if (isNode(selector)) {
13
+ return;
14
+ }
15
+ else if ('fromShadowDom' in selector) {
16
+ if (!Array.isArray(selector.fromShadowDom)
17
+ || selector.fromShadowDom.length < 2 ||
18
+ !selector.fromShadowDom.every(item => typeof item === 'string')) {
19
+ throw new TypeError(`Accented: invalid argument. \`fromShadowDom\` must be an array of strings with at least 2 elements. It’s currently set to ${selector.fromShadowDom}.`);
20
+ }
21
+ return;
22
+ }
23
+ else {
24
+ const neverSelector = selector;
25
+ throw new TypeError(`Accented: invalid argument. The selector must be one of: string, Node, or an object with a \`fromShadowDom\` property. It’s currently set to ${neverSelector}.`);
26
+ }
27
+ }
28
+ function isSelectorList(contextFragment) {
29
+ return (typeof contextFragment === 'object' && isNodeList(contextFragment))
30
+ || (Array.isArray(contextFragment) && contextFragment.every(item => isSelector(item)));
31
+ }
32
+ function validateSelectorList(selectorList) {
33
+ if (isNodeList(selectorList)) {
34
+ return;
35
+ }
36
+ else if (Array.isArray(selectorList)) {
37
+ for (const selector of selectorList) {
38
+ validateSelector(selector);
39
+ }
40
+ }
41
+ else {
42
+ const neverSelectorList = selectorList;
43
+ throw new TypeError(`Accented: invalid argument. The selector list must either be a NodeList or an array. It’s currently set to ${neverSelectorList}.`);
44
+ }
45
+ }
46
+ function isContextProp(contextFragment) {
47
+ return isSelector(contextFragment) || isSelectorList(contextFragment);
48
+ }
49
+ function validateContextProp(context) {
50
+ if (isSelector(context)) {
51
+ validateSelector(context);
52
+ }
53
+ else if (isSelectorList(context)) {
54
+ validateSelectorList(context);
55
+ }
56
+ else {
57
+ const neverContext = context;
58
+ throw new TypeError(`Accented: invalid argument. The context property must either be a selector or a selector list. It’s currently set to ${neverContext}.`);
59
+ }
60
+ }
61
+ function isContextObject(contextFragment) {
62
+ return typeof contextFragment === 'object' && contextFragment !== null
63
+ && ('include' in contextFragment || 'exclude' in contextFragment);
64
+ }
65
+ function validateContextObject(contextObject) {
66
+ if ('include' in contextObject) {
67
+ validateContextProp(contextObject.include);
68
+ }
69
+ if ('exclude' in contextObject) {
70
+ validateContextProp(contextObject.exclude);
71
+ }
72
+ }
73
+ function validateContext(context) {
74
+ if (isContextProp(context)) {
75
+ validateContextProp(context);
76
+ }
77
+ else if (isContextObject(context)) {
78
+ validateContextObject(context);
79
+ }
80
+ else {
81
+ const neverContext = context;
82
+ throw new TypeError(`Accented: invalid context argument. It’s currently set to ${neverContext}.`);
83
+ }
84
+ }
2
85
  // The space of valid CSS and HTML names is wider than this,
3
86
  // but with Unicode it gets complicated quickly, so I'm sticking to only allowing
4
87
  // lowercase alphanumeric names that possibly contain dashes that start with a letter.
@@ -38,5 +121,8 @@ export default function validateOptions(options) {
38
121
  throw new TypeError(`Accented: invalid argument. \`axeOptions\` contains the following unsupported keys: ${unsupportedKeys.join(', ')}. Valid options are: ${allowedAxeOptions.join(', ')}.`);
39
122
  }
40
123
  }
124
+ if (options.context !== undefined) {
125
+ validateContext(options.context);
126
+ }
41
127
  }
42
128
  //# sourceMappingURL=validate-options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-options.js","sourceRoot":"","sources":["../src/validate-options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate-options.js","sourceRoot":"","sources":["../src/validate-options.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accented",
3
- "version": "0.0.0-20250404114312",
3
+ "version": "0.0.0-20250424114613",
4
4
  "description": "Continuous accessibility testing and issue highlighting for web development",
5
5
  "type": "module",
6
6
  "main": "dist/accented.js",
@@ -20,14 +20,18 @@
20
20
  "axe-core"
21
21
  ],
22
22
  "author": "Pavel Pomerantsev",
23
- "license": "MIT AND MPL-2.0",
23
+ "license": "MIT",
24
24
  "bugs": {
25
25
  "url": "https://github.com/pomerantsev/accented/issues"
26
26
  },
27
27
  "homepage": "https://github.com/pomerantsev/accented#readme",
28
28
  "dependencies": {
29
29
  "@preact/signals-core": "^1.8.0",
30
- "axe-core": "^4.10.2"
30
+ "axe-core": "^4.10.3"
31
+ },
32
+ "devDependencies": {
33
+ "@types/jsdom": "^21.1.7",
34
+ "jsdom": "^26.0.0"
31
35
  },
32
36
  "scripts": {
33
37
  "build": "tsc",
package/src/accented.ts CHANGED
@@ -13,6 +13,7 @@ import type { AccentedOptions, DisableAccented } from './types';
13
13
  import validateOptions from './validate-options.js';
14
14
  import supportsAnchorPositioning from './utils/supports-anchor-positioning.js';
15
15
  import logAndRethrow from './log-and-rethrow.js';
16
+ import { initializeContainingBlockSupportSet } from './utils/containing-blocks.js';
16
17
 
17
18
  export type { AccentedOptions, DisableAccented };
18
19
 
@@ -67,7 +68,7 @@ export default function accented(options: AccentedOptions = {}): DisableAccented
67
68
  // * update examples in the accented() function JSDoc;
68
69
  // * update examples in the Readme.
69
70
  const defaultOptions: Required<AccentedOptions> = {
70
- axeContext: document,
71
+ context: document,
71
72
  axeOptions: {},
72
73
  name: 'accented',
73
74
  output: defaultOutput,
@@ -75,7 +76,7 @@ export default function accented(options: AccentedOptions = {}): DisableAccented
75
76
  callback: () => {}
76
77
  };
77
78
 
78
- const {axeContext, axeOptions, name, output, throttle, callback} = deepMerge(defaultOptions, options);
79
+ const {context, axeOptions, name, output, throttle, callback} = deepMerge(defaultOptions, options);
79
80
 
80
81
  if (enabled.value) {
81
82
  // Add link to the recipes section of the docs (#56).
@@ -88,10 +89,11 @@ export default function accented(options: AccentedOptions = {}): DisableAccented
88
89
 
89
90
  enabled.value = true;
90
91
 
92
+ initializeContainingBlockSupportSet();
91
93
  registerElements(name);
92
94
 
93
95
  const {disconnect: cleanupIntersectionObserver, intersectionObserver } = supportsAnchorPositioning(window) ? {} : setupIntersectionObserver();
94
- const cleanupScanner = createScanner(name, axeContext, axeOptions, throttle, callback);
96
+ const cleanupScanner = createScanner(name, context, axeOptions, throttle, callback);
95
97
  const cleanupDomUpdater = createDomUpdater(name, intersectionObserver);
96
98
  const cleanupLogger = output.console ? createLogger() : () => {};
97
99
  const cleanupScrollListeners = supportsAnchorPositioning(window) ? () => {} : setupScrollListeners();
@@ -6,6 +6,30 @@ import supportsAnchorPositioning from './utils/supports-anchor-positioning.js';
6
6
  import { isDocument, isDocumentFragment, isShadowRoot } from './utils/dom-helpers.js';
7
7
  import getParent from './utils/get-parent.js';
8
8
 
9
+ const shouldInsertTriggerInsideElement = (element: Element): boolean => {
10
+ /**
11
+ * No parent means that the element is a root node,
12
+ * which cannot have siblings.
13
+ */
14
+ const noParent = !getParent(element);
15
+
16
+ /**
17
+ * Table cells get a special treatment because if a sibling to a TH or TD is inserted,
18
+ * it alters the table layout, no matter how that sibling is positioned.
19
+ * We don't want tables to look broken, so we're inserting the trigger inside the table cell.
20
+ */
21
+ const isTableCell = element.nodeName === 'TH' || element.nodeName === 'TD';
22
+
23
+ /**
24
+ * We want to put the trigger inside the <summary> element,
25
+ * because otherwise it will be hidden by the browser when the <details> element is collapsed
26
+ * (since none of the siblings of <summary> are visible then).
27
+ */
28
+ const isSummary = element.nodeName === 'SUMMARY';
29
+
30
+ return noParent || isTableCell || isSummary;
31
+ };
32
+
9
33
  export default function createDomUpdater(name: string, intersectionObserver?: IntersectionObserver) {
10
34
  const attrName = `data-${name}`;
11
35
 
@@ -38,15 +62,18 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
38
62
 
39
63
  function setIssues (extendedElementsWithIssues: Array<ExtendedElementWithIssues>) {
40
64
  for (const elementWithIssues of extendedElementsWithIssues) {
65
+ if (elementWithIssues.skipRender) {
66
+ continue;
67
+ }
41
68
  elementWithIssues.element.setAttribute(attrName, elementWithIssues.id.toString());
42
69
  if (supportsAnchorPositioning(window)) {
43
70
  setAnchorName(elementWithIssues);
44
71
  }
45
72
 
46
- if (getParent(elementWithIssues.element)) {
47
- elementWithIssues.element.insertAdjacentElement('afterend', elementWithIssues.trigger);
48
- } else {
73
+ if (shouldInsertTriggerInsideElement(elementWithIssues.element)) {
49
74
  elementWithIssues.element.insertAdjacentElement('beforeend', elementWithIssues.trigger);
75
+ } else {
76
+ elementWithIssues.element.insertAdjacentElement('afterend', elementWithIssues.trigger);
50
77
  }
51
78
  if (intersectionObserver) {
52
79
  intersectionObserver.observe(elementWithIssues.element);
@@ -56,6 +83,9 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
56
83
 
57
84
  function removeIssues (extendedElementsWithIssues: Array<ExtendedElementWithIssues>) {
58
85
  for (const elementWithIssues of extendedElementsWithIssues) {
86
+ if (elementWithIssues.skipRender) {
87
+ continue;
88
+ }
59
89
  elementWithIssues.element.removeAttribute(attrName);
60
90
  if (supportsAnchorPositioning(window)) {
61
91
  removeAnchorName(elementWithIssues);
@@ -1,6 +1,5 @@
1
1
  import type { Issue } from '../types';
2
2
  import type { Signal } from '@preact/signals-core';
3
- import { effect } from '@preact/signals-core';
4
3
  import getElementHtml from '../utils/get-element-html.js';
5
4
  import { accentedUrl } from '../constants.js';
6
5
  import logAndRethrow from '../log-and-rethrow.js';
@@ -9,6 +8,7 @@ export interface AccentedDialog extends HTMLElement {
9
8
  issues: Signal<Array<Issue>> | undefined;
10
9
  element: Element | undefined;
11
10
  showModal: () => void;
11
+ open: boolean;
12
12
  }
13
13
 
14
14
  // We want Accented to not throw an error in Node, and use static imports,
@@ -241,15 +241,13 @@ export default () => {
241
241
  `);
242
242
 
243
243
  return class extends HTMLElement implements AccentedDialog {
244
- #disposeOfEffect: (() => void) | undefined;
245
-
246
244
  #abortController: AbortController | undefined;
247
245
 
248
246
  issues: Signal<Array<Issue>> | undefined;
249
247
 
250
248
  element: Element | undefined;
251
249
 
252
- #elementMutationObserver: MutationObserver | undefined;
250
+ open: boolean = false;
253
251
 
254
252
  constructor() {
255
253
  try {
@@ -298,75 +296,52 @@ export default () => {
298
296
  }
299
297
  }, { signal: this.#abortController.signal });
300
298
 
301
- this.#disposeOfEffect = effect(() => {
302
- if (this.issues) {
303
- const issues = this.issues.value;
304
- const issuesList = shadowRoot.getElementById('issues');
305
- if (issuesList) {
306
- issuesList.innerHTML = '';
307
- for (const issue of issues) {
308
- const issueContent = issueTemplate.content.cloneNode(true) as Element;
309
- const title = issueContent.querySelector('a');
310
- const impact = issueContent.querySelector('.impact');
311
- const description = issueContent.querySelector('.description');
312
- if (title && impact && description) {
313
- title.textContent = issue.title + ' (' + issue.id + ')';
314
- title.href = issue.url;
315
-
316
- impact.textContent = 'User impact: ' + issue.impact;
317
- impact.setAttribute('data-impact', String(issue.impact));
318
-
319
- const descriptionItems = issue.description.split(/\n\s*/);
320
- const descriptionContent = descriptionTemplate.content.cloneNode(true) as Element;
321
- const descriptionTitle = descriptionContent.querySelector('span');
322
- const descriptionList = descriptionContent.querySelector('ul');
323
- if (descriptionTitle && descriptionList && descriptionItems.length > 1) {
324
- descriptionTitle.textContent = descriptionItems[0]!;
325
- for (const descriptionItem of descriptionItems.slice(1)) {
326
- const li = document.createElement('li');
327
- li.textContent = descriptionItem;
328
- descriptionList.appendChild(li);
329
- }
330
- description.appendChild(descriptionContent);
299
+ if (this.issues) {
300
+ const issues = this.issues.value;
301
+ const issuesList = shadowRoot.getElementById('issues');
302
+ if (issuesList) {
303
+ issuesList.innerHTML = '';
304
+ for (const issue of issues) {
305
+ const issueContent = issueTemplate.content.cloneNode(true) as Element;
306
+ const title = issueContent.querySelector('a');
307
+ const impact = issueContent.querySelector('.impact');
308
+ const description = issueContent.querySelector('.description');
309
+ if (title && impact && description) {
310
+ title.textContent = issue.title + ' (' + issue.id + ')';
311
+ title.href = issue.url;
312
+
313
+ impact.textContent = 'User impact: ' + issue.impact;
314
+ impact.setAttribute('data-impact', String(issue.impact));
315
+
316
+ const descriptionItems = issue.description.split(/\n\s*/);
317
+ const descriptionContent = descriptionTemplate.content.cloneNode(true) as Element;
318
+ const descriptionTitle = descriptionContent.querySelector('span');
319
+ const descriptionList = descriptionContent.querySelector('ul');
320
+ if (descriptionTitle && descriptionList && descriptionItems.length > 1) {
321
+ descriptionTitle.textContent = descriptionItems[0]!;
322
+ for (const descriptionItem of descriptionItems.slice(1)) {
323
+ const li = document.createElement('li');
324
+ li.textContent = descriptionItem;
325
+ descriptionList.appendChild(li);
331
326
  }
327
+ description.appendChild(descriptionContent);
332
328
  }
333
- issuesList.appendChild(issueContent);
334
329
  }
330
+ issuesList.appendChild(issueContent);
335
331
  }
336
332
  }
337
- });
338
-
339
- const updateElementHtml = () => {
340
- if (this.element) {
341
- const elementHtmlContainer = shadowRoot.getElementById('element-html');
342
- if (elementHtmlContainer) {
343
- elementHtmlContainer.textContent = getElementHtml(this.element);
344
- }
345
- }
346
- };
347
-
348
- updateElementHtml();
333
+ }
349
334
 
350
- this.#elementMutationObserver = new MutationObserver(() => {
351
- try {
352
- updateElementHtml();
353
- } catch (error) {
354
- logAndRethrow(error);
355
- }
356
- });
357
335
  if (this.element) {
358
- // We're only outputting the element itself, not its subtree.
359
- // However, we're still listening for childList changes, because
360
- // we display an ellipsis if the element has innerHTML,
361
- // and we leave it empty if the element is empty.
362
- this.#elementMutationObserver.observe(this.element, {
363
- attributes: true,
364
- childList: true
365
- });
336
+ const elementHtmlContainer = shadowRoot.getElementById('element-html');
337
+ if (elementHtmlContainer) {
338
+ elementHtmlContainer.textContent = getElementHtml(this.element);
339
+ }
366
340
  }
367
341
 
368
342
  dialog?.addEventListener('close', () => {
369
343
  try {
344
+ this.open = false;
370
345
  this.dispatchEvent(new Event('close'));
371
346
  } catch (error) {
372
347
  logAndRethrow(error);
@@ -380,15 +355,9 @@ export default () => {
380
355
 
381
356
  disconnectedCallback() {
382
357
  try {
383
- if (this.#disposeOfEffect) {
384
- this.#disposeOfEffect();
385
- }
386
358
  if (this.#abortController) {
387
359
  this.#abortController.abort();
388
360
  }
389
- if (this.#elementMutationObserver) {
390
- this.#elementMutationObserver.disconnect();
391
- }
392
361
  } catch (error) {
393
362
  logAndRethrow(error);
394
363
  }
@@ -399,6 +368,7 @@ export default () => {
399
368
  const dialog = this.shadowRoot.querySelector('dialog');
400
369
  if (dialog) {
401
370
  dialog.showModal();
371
+ this.open = true;
402
372
  }
403
373
  }
404
374
  }
@@ -44,11 +44,12 @@ export default (name: string) => {
44
44
  #trigger {
45
45
  pointer-events: auto;
46
46
 
47
- position: absolute;
48
- inset-block-start: 4px;
49
- inset-inline-end: 4px;
47
+ margin-inline-start: auto;
48
+ margin-inline-end: 4px;
49
+ margin-block-start: 4px;
50
50
 
51
51
  box-sizing: border-box;
52
+ font-family: system-ui;
52
53
  font-size: calc(var(--ratio) * var(--ratio) * var(--base-size));
53
54
  inline-size: calc(2 * var(--base-size));
54
55
  block-size: calc(2 * var(--base-size));
@@ -81,7 +82,7 @@ export default (name: string) => {
81
82
  }
82
83
  }
83
84
  </style>
84
- <button id="trigger" lang="en">!</button>
85
+ <button id="trigger" lang="en">á</button>
85
86
  `;
86
87
 
87
88
  return class extends HTMLElement implements AccentedTrigger {
@@ -200,7 +201,7 @@ export default (name: string) => {
200
201
  if (this.#abortController) {
201
202
  this.#abortController.abort();
202
203
  }
203
- if (this.#dialogCloseAbortController) {
204
+ if (this.#dialogCloseAbortController && !this.dialog?.open) {
204
205
  this.#dialogCloseAbortController.abort();
205
206
  this.dialog?.remove();
206
207
  }
package/src/logger.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import { effect } from '@preact/signals-core';
2
2
  import { elementsWithIssues, enabled } from './state.js';
3
3
  import { accentedUrl } from './constants.js';
4
+ import type { ElementWithIssues } from './types';
5
+
6
+ function filterPropsForOutput(elements: Array<ElementWithIssues>) {
7
+ return elements.map(({ element, issues }) => ({ element, issues }));
8
+ }
4
9
 
5
10
  export default function createLogger() {
6
11
 
@@ -14,7 +19,10 @@ export default function createLogger() {
14
19
  const elementCount = elementsWithIssues.value.length;
15
20
  if (elementCount > 0) {
16
21
  const issueCount = elementsWithIssues.value.reduce((acc, { issues }) => acc + issues.length, 0);
17
- console.log(`${issueCount} accessibility issue${issueCount === 1 ? '' : 's'} found in ${elementCount} element${issueCount === 1 ? '' : 's'} (Accented, ${accentedUrl}):\n`, elementsWithIssues.value);
22
+ console.log(
23
+ `${issueCount} accessibility issue${issueCount === 1 ? '' : 's'} found in ${elementCount} element${issueCount === 1 ? '' : 's'} (Accented, ${accentedUrl}):\n`,
24
+ filterPropsForOutput(elementsWithIssues.value)
25
+ );
18
26
  } else {
19
27
  if (firstRun) {
20
28
  firstRun = false;