accented 1.0.0 → 1.1.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.
Files changed (70) hide show
  1. package/README.md +40 -26
  2. package/dist/accented.d.ts.map +1 -1
  3. package/dist/accented.js +4 -3
  4. package/dist/accented.js.map +1 -1
  5. package/dist/common/strings.d.ts +2 -0
  6. package/dist/common/strings.d.ts.map +1 -0
  7. package/dist/common/strings.js +2 -0
  8. package/dist/common/strings.js.map +1 -0
  9. package/dist/common/tokens.d.ts +9 -0
  10. package/dist/common/tokens.d.ts.map +1 -1
  11. package/dist/common/tokens.js +28 -0
  12. package/dist/common/tokens.js.map +1 -1
  13. package/dist/constants.d.ts +3 -1
  14. package/dist/constants.d.ts.map +1 -1
  15. package/dist/constants.js +2 -1
  16. package/dist/constants.js.map +1 -1
  17. package/dist/elements/accented-dialog.d.ts +25 -8
  18. package/dist/elements/accented-dialog.d.ts.map +1 -1
  19. package/dist/elements/accented-dialog.js +12 -24
  20. package/dist/elements/accented-dialog.js.map +1 -1
  21. package/dist/elements/accented-trigger.d.ts +24 -12
  22. package/dist/elements/accented-trigger.d.ts.map +1 -1
  23. package/dist/elements/accented-trigger.js +8 -4
  24. package/dist/elements/accented-trigger.js.map +1 -1
  25. package/dist/logger.d.ts +4 -1
  26. package/dist/logger.d.ts.map +1 -1
  27. package/dist/logger.js +196 -17
  28. package/dist/logger.js.map +1 -1
  29. package/dist/scanner.js +1 -1
  30. package/dist/scanner.js.map +1 -1
  31. package/dist/types.d.ts +31 -1
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/types.js.map +1 -1
  34. package/dist/utils/are-issue-sets-equal.d.ts.map +1 -1
  35. package/dist/utils/are-issue-sets-equal.js +2 -2
  36. package/dist/utils/are-issue-sets-equal.js.map +1 -1
  37. package/dist/utils/are-issues-equal.d.ts +3 -0
  38. package/dist/utils/are-issues-equal.d.ts.map +1 -0
  39. package/dist/utils/are-issues-equal.js +5 -0
  40. package/dist/utils/are-issues-equal.js.map +1 -0
  41. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts +4 -4
  42. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -1
  43. package/dist/utils/supports-anchor-positioning.d.ts.map +1 -1
  44. package/dist/utils/supports-anchor-positioning.js +14 -1
  45. package/dist/utils/supports-anchor-positioning.js.map +1 -1
  46. package/dist/utils/transform-violations.d.ts.map +1 -1
  47. package/dist/utils/transform-violations.js +8 -3
  48. package/dist/utils/transform-violations.js.map +1 -1
  49. package/dist/validate-options.d.ts.map +1 -1
  50. package/dist/validate-options.js +3 -0
  51. package/dist/validate-options.js.map +1 -1
  52. package/package.json +7 -7
  53. package/src/accented.test.ts +1 -1
  54. package/src/accented.ts +4 -3
  55. package/src/common/strings.ts +2 -0
  56. package/src/common/tokens.ts +36 -0
  57. package/src/constants.ts +5 -1
  58. package/src/elements/accented-dialog.ts +22 -24
  59. package/src/elements/accented-trigger.ts +11 -5
  60. package/src/logger.ts +276 -22
  61. package/src/scanner.ts +1 -1
  62. package/src/types.ts +32 -1
  63. package/src/utils/are-issue-sets-equal.test.ts +1 -6
  64. package/src/utils/are-issue-sets-equal.ts +2 -5
  65. package/src/utils/are-issues-equal.ts +7 -0
  66. package/src/utils/supports-anchor-positioning.ts +17 -1
  67. package/src/utils/transform-violations.test.ts +1 -1
  68. package/src/utils/transform-violations.ts +13 -5
  69. package/src/utils/update-elements-with-issues.test.ts +6 -2
  70. package/src/validate-options.ts +5 -0
@@ -0,0 +1,7 @@
1
+ import type { Issue } from '../types.ts';
2
+
3
+ const issueProps: Array<keyof Issue> = ['id', 'title', 'description', 'url', 'impact'];
4
+
5
+ export function areIssuesEqual(issue1: Issue, issue2: Issue) {
6
+ return issueProps.every((prop) => issue2[prop] === issue1[prop]);
7
+ }
@@ -2,6 +2,22 @@ type WindowWithCSS = Window & {
2
2
  CSS: typeof CSS;
3
3
  };
4
4
 
5
+ /**
6
+ * We have to do browser sniffing now and explicitly turn off Anchor positioning in Safari
7
+ * since anchor positioning is not working correctly in Safari 26 Technology Preview.
8
+ */
9
+ function isWebKit(win: Window) {
10
+ const ua = win.navigator.userAgent;
11
+ return (/AppleWebKit/.test(ua) && !/Chrome/.test(ua)) || /\b(iPad|iPhone|iPod)\b/.test(ua);
12
+ }
13
+
14
+ // ATTENTION: sync with the implementation in end-to-end tests.
15
+ // I didn't find a way to sync this with automatically with the implementation of supportsAnchorPositioning
16
+ // in end-to-end tests, so it has to be synced manually.
5
17
  export function supportsAnchorPositioning(win: WindowWithCSS) {
6
- return win.CSS.supports('anchor-name: --foo') && win.CSS.supports('position-anchor: --foo');
18
+ return (
19
+ win.CSS.supports('anchor-name: --foo') &&
20
+ win.CSS.supports('position-anchor: --foo') &&
21
+ !isWebKit(win)
22
+ );
7
23
  }
@@ -1,8 +1,8 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { suite, test } from 'node:test';
3
+ import type { AxeResults } from 'axe-core';
3
4
  import { transformViolations } from './transform-violations';
4
5
 
5
- import type { AxeResults } from 'axe-core';
6
6
  type Violation = AxeResults['violations'][number];
7
7
  type Node = Violation['nodes'][number];
8
8
 
@@ -1,4 +1,5 @@
1
- import type { AxeResults, ImpactValue } from 'axe-core';
1
+ import type { AxeResults } from 'axe-core';
2
+ import { issuesUrl, orderedImpacts } from '../constants.js';
2
3
  import type { ElementWithIssues, Issue } from '../types.ts';
3
4
 
4
5
  // This is a list of axe-core violations (their ids) that may be flagged by axe-core
@@ -20,9 +21,8 @@ function maybeCausedByAccented(violationId: string, element: HTMLElement, name:
20
21
  );
21
22
  }
22
23
 
23
- function impactCompare(a: ImpactValue, b: ImpactValue) {
24
- const impactOrder = [null, 'minor', 'moderate', 'serious', 'critical'];
25
- return impactOrder.indexOf(a) - impactOrder.indexOf(b);
24
+ function impactCompare(a: Issue['impact'], b: Issue['impact']) {
25
+ return orderedImpacts.indexOf(a) - orderedImpacts.indexOf(b);
26
26
  }
27
27
 
28
28
  export function transformViolations(violations: typeof AxeResults.violations, name: string) {
@@ -41,12 +41,20 @@ export function transformViolations(violations: typeof AxeResults.violations, na
41
41
  const isInIframe = target.length > 1;
42
42
 
43
43
  if (element && !isInIframe && !maybeCausedByAccented(violation.id, element, name)) {
44
+ if (!violation.impact) {
45
+ console.warn(
46
+ `Accented: axe-core (the accessibility testing engine) returned a violation with an empty impact. This may be a bug in axe-core or in Accented. Please report it at ${issuesUrl}.`,
47
+ violation,
48
+ );
49
+ continue;
50
+ }
44
51
  const issue: Issue = {
45
52
  id: violation.id,
46
53
  title: violation.help,
54
+ // See https://github.com/pomerantsev/accented/issues/203
47
55
  description: node.failureSummary ?? violation.description,
48
56
  url: violation.helpUrl,
49
- impact: violation.impact ?? null,
57
+ impact: violation.impact,
50
58
  };
51
59
  const existingElement = elementsWithIssues.find(
52
60
  (elementWithIssues) => elementWithIssues.element === element,
@@ -2,11 +2,11 @@ import assert from 'node:assert/strict';
2
2
  import { suite, test } from 'node:test';
3
3
  import type { Signal } from '@preact/signals-core';
4
4
  import { signal } from '@preact/signals-core';
5
+ import type { AxeResults, ImpactValue } from 'axe-core';
6
+ import type { AccentedTrigger } from '../elements/accented-trigger';
5
7
  import type { ExtendedElementWithIssues, Issue } from '../types';
6
8
  import { updateElementsWithIssues } from './update-elements-with-issues';
7
9
 
8
- import type { AxeResults, ImpactValue } from 'axe-core';
9
- import type { AccentedTrigger } from '../elements/accented-trigger';
10
10
  type Violation = AxeResults['violations'][number];
11
11
  type AxeNode = Violation['nodes'][number];
12
12
 
@@ -31,6 +31,10 @@ const win: Window & { CSS: typeof CSS } = {
31
31
  CSS: {
32
32
  supports: () => true,
33
33
  },
34
+ // @ts-expect-error we're missing a lot of properties
35
+ navigator: {
36
+ userAgent: '',
37
+ },
34
38
  };
35
39
 
36
40
  const getBoundingClientRect = () => ({});
@@ -149,6 +149,11 @@ export function validateOptions(options: AccentedOptions) {
149
149
  `Accented: invalid argument. \`output.console\` option is expected to be a boolean. It’s currently set to ${options.output.console}.`,
150
150
  );
151
151
  }
152
+ if (options.output.page !== undefined && typeof options.output.page !== 'boolean') {
153
+ console.warn(
154
+ `Accented: invalid argument. \`output.page\` option is expected to be a boolean. It’s currently set to ${options.output.page}.`,
155
+ );
156
+ }
152
157
  }
153
158
  if (options.callback !== undefined && typeof options.callback !== 'function') {
154
159
  throw new TypeError(