@editora/plugins 1.0.2 → 1.0.5

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 (105) hide show
  1. package/README.md +30 -5
  2. package/dist/a11y-checker.cjs.js +109 -0
  3. package/dist/a11y-checker.esm.js +509 -0
  4. package/dist/anchor.cjs.js +176 -0
  5. package/dist/anchor.esm.js +400 -0
  6. package/dist/background-color.cjs.js +218 -0
  7. package/dist/background-color.esm.js +482 -0
  8. package/dist/blockquote.cjs.js +1 -0
  9. package/dist/blockquote.esm.js +47 -0
  10. package/dist/bold.cjs.js +1 -0
  11. package/dist/bold.esm.js +44 -0
  12. package/dist/capitalization.cjs.js +1 -0
  13. package/dist/capitalization.esm.js +78 -0
  14. package/dist/checklist.cjs.js +1 -0
  15. package/dist/checklist.esm.js +305 -0
  16. package/dist/clear-formatting.cjs.js +1 -0
  17. package/dist/clear-formatting.esm.js +138 -0
  18. package/dist/code-sample.cjs.js +161 -0
  19. package/dist/code-sample.esm.js +381 -0
  20. package/dist/code.cjs.js +606 -0
  21. package/dist/code.esm.js +2164 -0
  22. package/dist/colorSelectionApply-C0iOfMWb.js +1 -0
  23. package/dist/colorSelectionApply-D8r_gV32.mjs +63 -0
  24. package/dist/comments.cjs.js +354 -0
  25. package/dist/comments.esm.js +692 -0
  26. package/dist/direction.cjs.js +1 -0
  27. package/dist/direction.esm.js +129 -0
  28. package/dist/document-manager.cjs.js +1 -0
  29. package/dist/document-manager.esm.js +6 -0
  30. package/dist/{documentManager-CYC9totK.mjs → documentManager-DRUc1-Cs.mjs} +3 -3
  31. package/dist/{documentManager-BGlu3WRB.js → documentManager-_tQQfQi9.js} +3 -3
  32. package/dist/editorContainerHelpers-C7kdWnS0.mjs +26 -0
  33. package/dist/editorContainerHelpers-CFbfiOJI.js +1 -0
  34. package/dist/embed-iframe.cjs.js +361 -0
  35. package/dist/embed-iframe.esm.js +556 -0
  36. package/dist/emojis.cjs.js +284 -0
  37. package/dist/emojis.esm.js +1080 -0
  38. package/dist/font-family.cjs.js +1 -0
  39. package/dist/font-family.esm.js +152 -0
  40. package/dist/font-size.cjs.js +1 -0
  41. package/dist/font-size.esm.js +278 -0
  42. package/dist/footnote.cjs.js +85 -0
  43. package/dist/footnote.esm.js +397 -0
  44. package/dist/fullscreen.cjs.js +1 -0
  45. package/dist/fullscreen.esm.js +73 -0
  46. package/dist/heading.cjs.js +1 -0
  47. package/dist/heading.esm.js +63 -0
  48. package/dist/history.cjs.js +1 -0
  49. package/dist/history.esm.js +246 -0
  50. package/dist/indent.cjs.js +1 -0
  51. package/dist/indent.esm.js +146 -0
  52. package/dist/index-Bskk414V.mjs +145 -0
  53. package/dist/index-D3pJyAsj.js +1 -0
  54. package/dist/index.cjs.js +1 -1
  55. package/dist/{index.es-B-to-4j4.js → index.es-Cz1qItab.js} +1 -1
  56. package/dist/{index.es-BbXJ7tyO.mjs → index.es-DEcRmSTY.mjs} +1 -1
  57. package/dist/index.esm.js +89 -49
  58. package/dist/italic.cjs.js +1 -0
  59. package/dist/italic.esm.js +40 -0
  60. package/dist/line-height.cjs.js +1 -0
  61. package/dist/line-height.esm.js +145 -0
  62. package/dist/link.cjs.js +138 -0
  63. package/dist/link.esm.js +276 -0
  64. package/dist/list.cjs.js +1 -0
  65. package/dist/list.esm.js +102 -0
  66. package/dist/lite.cjs.js +1 -0
  67. package/dist/lite.esm.js +61 -0
  68. package/dist/math.cjs.js +45 -0
  69. package/dist/math.esm.js +249 -0
  70. package/dist/media-manager.cjs.js +619 -0
  71. package/dist/media-manager.esm.js +994 -0
  72. package/dist/merge-tag.cjs.js +93 -0
  73. package/dist/merge-tag.esm.js +412 -0
  74. package/dist/page-break.cjs.js +72 -0
  75. package/dist/page-break.esm.js +295 -0
  76. package/dist/plugins.css +1 -1
  77. package/dist/preview.cjs.js +230 -0
  78. package/dist/preview.esm.js +321 -0
  79. package/dist/print.cjs.js +254 -0
  80. package/dist/print.esm.js +309 -0
  81. package/dist/purify.es-DHhaBdbu.mjs +470 -0
  82. package/dist/purify.es-T2a3nLiC.js +3 -0
  83. package/dist/shared-config.cjs.js +1 -0
  84. package/dist/shared-config.esm.js +30 -0
  85. package/dist/special-characters.cjs.js +257 -0
  86. package/dist/special-characters.esm.js +772 -0
  87. package/dist/spell-check.cjs.js +512 -0
  88. package/dist/spell-check.esm.js +1013 -0
  89. package/dist/strikethrough.cjs.js +1 -0
  90. package/dist/strikethrough.esm.js +71 -0
  91. package/dist/table.cjs.js +35 -0
  92. package/dist/table.esm.js +477 -0
  93. package/dist/template.cjs.js +356 -0
  94. package/dist/template.esm.js +560 -0
  95. package/dist/text-alignment.cjs.js +1 -0
  96. package/dist/text-alignment.esm.js +105 -0
  97. package/dist/text-color.cjs.js +300 -0
  98. package/dist/text-color.esm.js +507 -0
  99. package/dist/underline.cjs.js +1 -0
  100. package/dist/underline.esm.js +34 -0
  101. package/index.d.ts +62 -0
  102. package/package.json +220 -7
  103. package/LICENSE +0 -21
  104. package/dist/index-BbORIHoM.mjs +0 -11763
  105. package/dist/index-C-OCBS_6.js +0 -3753
@@ -0,0 +1,509 @@
1
+ const B = /* @__PURE__ */ new Set(), v = [], f = (t) => {
2
+ v.push(t);
3
+ }, x = '[data-theme="dark"], .dark, .editora-theme-dark';
4
+ f({
5
+ id: "image-alt-text",
6
+ wcag: "1.1.1",
7
+ description: "Images must have alt text",
8
+ severity: "error",
9
+ selector: "img",
10
+ evaluate(t, n) {
11
+ const e = t;
12
+ return e.hasAttribute("role") && e.getAttribute("role") === "presentation" || e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "image-alt-text" ? null : !e.hasAttribute("alt") || e.getAttribute("alt")?.trim() === "" ? {
13
+ id: `img-alt-${n.cache.get("imgIdx")}`,
14
+ rule: "image-alt-text",
15
+ wcag: "1.1.1",
16
+ severity: "error",
17
+ message: "Image missing alt text",
18
+ nodePath: n.cache.get("imgPath"),
19
+ element: e,
20
+ suggestion: "Add descriptive alt text to all images",
21
+ fixable: !0,
22
+ fixLabel: "Add empty alt"
23
+ } : null;
24
+ },
25
+ fix(t) {
26
+ t.element && t.element.setAttribute("alt", "");
27
+ }
28
+ });
29
+ f({
30
+ id: "empty-interactive",
31
+ wcag: "4.1.2",
32
+ description: "Interactive elements must have accessible names",
33
+ severity: "error",
34
+ selector: 'button, a, [role="button"]',
35
+ evaluate(t, n) {
36
+ const e = t;
37
+ if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "empty-interactive") return null;
38
+ const r = e.textContent?.trim(), a = e.hasAttribute("aria-label"), o = e.hasAttribute("aria-labelledby"), s = e.hasAttribute("title");
39
+ return !r && !a && !o && !s ? {
40
+ id: `interactive-empty-${n.cache.get("buttonIdx")}`,
41
+ rule: "empty-interactive",
42
+ wcag: "4.1.2",
43
+ severity: "error",
44
+ message: "Interactive element has no accessible name",
45
+ nodePath: n.cache.get("buttonPath"),
46
+ element: e,
47
+ suggestion: "Add text, aria-label, aria-labelledby, or title",
48
+ fixable: !0,
49
+ fixLabel: "Add aria-label"
50
+ } : null;
51
+ },
52
+ fix(t) {
53
+ t.element && t.element.setAttribute("aria-label", "Button");
54
+ }
55
+ });
56
+ f({
57
+ id: "form-label",
58
+ wcag: "1.3.1",
59
+ description: "Form controls must have labels",
60
+ severity: "error",
61
+ selector: "input, textarea, select",
62
+ evaluate(t, n) {
63
+ const e = t;
64
+ if (e.hasAttribute("type") && e.getAttribute("type") === "hidden" || e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "form-label") return null;
65
+ const r = n.doc.querySelector(`label[for="${e.getAttribute("id")}"]`), a = e.hasAttribute("aria-label"), o = e.hasAttribute("aria-labelledby");
66
+ return !r && !a && !o ? {
67
+ id: `form-label-${n.cache.get("inputIdx")}`,
68
+ rule: "form-label",
69
+ wcag: "1.3.1",
70
+ severity: "error",
71
+ message: "Form control missing label",
72
+ nodePath: n.cache.get("inputPath"),
73
+ element: e,
74
+ suggestion: "Add <label>, aria-label, or aria-labelledby",
75
+ fixable: !0,
76
+ fixLabel: "Add aria-label"
77
+ } : null;
78
+ },
79
+ fix(t) {
80
+ t.element && t.element.setAttribute("aria-label", "Input");
81
+ }
82
+ });
83
+ f({
84
+ id: "table-headers",
85
+ wcag: "1.3.1",
86
+ description: "Tables must have header rows",
87
+ severity: "error",
88
+ selector: "table",
89
+ evaluate(t, n) {
90
+ const e = t;
91
+ if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "table-headers") return null;
92
+ const r = e.querySelectorAll("th"), a = e.querySelectorAll("tr");
93
+ return r.length === 0 && a.length > 0 ? {
94
+ id: `table-no-headers-${n.cache.get("tableIdx")}`,
95
+ rule: "table-headers",
96
+ wcag: "1.3.1",
97
+ severity: "error",
98
+ message: "Table missing header row (<th> elements)",
99
+ nodePath: n.cache.get("tablePath"),
100
+ element: e,
101
+ suggestion: "Add <th> elements to first row",
102
+ fixable: !0,
103
+ fixLabel: "Convert first row to headers"
104
+ } : null;
105
+ },
106
+ fix(t) {
107
+ if (t.element) {
108
+ const e = t.element.querySelector("tr");
109
+ e && Array.from(e.children).forEach((r) => {
110
+ if (r.tagName === "TD") {
111
+ const a = document.createElement("th");
112
+ a.innerHTML = r.innerHTML, e.replaceChild(a, r);
113
+ }
114
+ });
115
+ }
116
+ }
117
+ });
118
+ f({
119
+ id: "heading-empty",
120
+ wcag: "1.3.1",
121
+ description: "Headings must not be empty",
122
+ severity: "error",
123
+ selector: "h1, h2, h3, h4, h5, h6",
124
+ evaluate(t, n) {
125
+ const e = t;
126
+ if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "heading-empty") return null;
127
+ const r = e.textContent?.replace(/\s+/g, "") || "", a = e.childNodes.length === 1 && e.childNodes[0].nodeName === "BR";
128
+ return !r && !a ? {
129
+ id: `heading-empty-${n.cache.get("headingIdx")}`,
130
+ rule: "heading-empty",
131
+ wcag: "1.3.1",
132
+ severity: "error",
133
+ message: `Empty ${e.tagName.toLowerCase()} heading`,
134
+ nodePath: n.cache.get("headingPath"),
135
+ element: e,
136
+ suggestion: "All headings must contain text",
137
+ fixable: !1
138
+ } : null;
139
+ }
140
+ });
141
+ f({
142
+ id: "heading-order",
143
+ wcag: "1.3.1",
144
+ description: "Headings should not skip levels",
145
+ severity: "warning",
146
+ selector: "h1, h2, h3, h4, h5, h6",
147
+ evaluate(t, n) {
148
+ const e = t, r = parseInt(e.tagName[1]), a = n.cache.get("previousHeadingLevel") || r;
149
+ return n.cache.set("previousHeadingLevel", r), r - a > 1 ? {
150
+ id: `heading-order-${n.cache.get("headingIdx")}`,
151
+ rule: "heading-order",
152
+ wcag: "1.3.1",
153
+ severity: "warning",
154
+ message: `Heading skips level (${a} → ${r})`,
155
+ nodePath: n.cache.get("headingPath"),
156
+ element: e,
157
+ suggestion: `Use heading level ${a + 1} instead`,
158
+ fixable: !1
159
+ } : null;
160
+ }
161
+ });
162
+ f({
163
+ id: "link-text",
164
+ wcag: "2.4.4",
165
+ description: "Links must have descriptive text",
166
+ severity: "error",
167
+ selector: "a",
168
+ evaluate(t, n) {
169
+ const e = t;
170
+ if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "link-text") return null;
171
+ const r = e.textContent?.replace(/\s+/g, "").toLowerCase() || "", a = e.childNodes.length === 1 && e.childNodes[0].nodeName === "BR", o = ["clickhere", "readmore", "link", "here", "this", "page"];
172
+ return !r && !a ? {
173
+ id: `link-empty-${n.cache.get("aIdx")}`,
174
+ rule: "link-text",
175
+ wcag: "2.4.4",
176
+ severity: "error",
177
+ message: "Link has no text content",
178
+ nodePath: n.cache.get("aPath"),
179
+ element: e,
180
+ suggestion: "All links must have descriptive text",
181
+ fixable: !0,
182
+ fixLabel: "Insert placeholder"
183
+ } : o.some((s) => r.includes(s)) ? {
184
+ id: `link-vague-${n.cache.get("aIdx")}`,
185
+ rule: "link-text",
186
+ wcag: "2.4.4",
187
+ severity: "warning",
188
+ message: `Vague link text: "${e.textContent?.trim()}"`,
189
+ nodePath: n.cache.get("aPath"),
190
+ element: e,
191
+ suggestion: "Use descriptive link text",
192
+ fixable: !1
193
+ } : null;
194
+ },
195
+ fix(t) {
196
+ t.element && (t.element.textContent = "Link");
197
+ }
198
+ });
199
+ f({
200
+ id: "list-structure",
201
+ wcag: "1.3.1",
202
+ description: "Lists must only contain <li> children",
203
+ severity: "error",
204
+ selector: "ul, ol",
205
+ evaluate(t, n) {
206
+ const e = t;
207
+ if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "list-structure") return null;
208
+ const r = e.querySelectorAll(":scope > li");
209
+ return Array.from(e.children).filter((o) => o.tagName !== "LI").length > 0 ? {
210
+ id: `list-structure-${n.cache.get("ulIdx")}`,
211
+ rule: "list-structure",
212
+ wcag: "1.3.1",
213
+ severity: "error",
214
+ message: "List contains non-li elements",
215
+ nodePath: n.cache.get("ulPath"),
216
+ element: e,
217
+ suggestion: "All direct children of ul/ol must be li elements",
218
+ fixable: !1
219
+ } : r.length === 0 ? {
220
+ id: `list-empty-${n.cache.get("ulIdx")}`,
221
+ rule: "list-structure",
222
+ wcag: "1.3.1",
223
+ severity: "warning",
224
+ message: "Empty list element",
225
+ nodePath: n.cache.get("ulPath"),
226
+ element: e,
227
+ suggestion: "Remove empty lists or add list items",
228
+ fixable: !1
229
+ } : null;
230
+ }
231
+ });
232
+ const A = () => {
233
+ const t = window.getSelection();
234
+ if (t && t.rangeCount > 0) {
235
+ let e = t.getRangeAt(0).startContainer;
236
+ for (; e && e !== document.body; ) {
237
+ if (e.nodeType === Node.ELEMENT_NODE) {
238
+ const r = e;
239
+ if (r.getAttribute("contenteditable") === "true")
240
+ return r;
241
+ }
242
+ e = e.parentNode;
243
+ }
244
+ }
245
+ const n = document.activeElement;
246
+ if (n) {
247
+ if (n.getAttribute("contenteditable") === "true")
248
+ return n;
249
+ const e = n.closest('[contenteditable="true"]');
250
+ if (e) return e;
251
+ }
252
+ return document.querySelector('[contenteditable="true"]');
253
+ }, T = () => {
254
+ if (A()?.closest(x)) return !0;
255
+ const n = window.getSelection();
256
+ if (n && n.rangeCount > 0) {
257
+ const r = n.getRangeAt(0).startContainer;
258
+ if ((r.nodeType === Node.ELEMENT_NODE ? r : r.parentElement)?.closest(x)) return !0;
259
+ }
260
+ return document.activeElement?.closest(x) ? !0 : document.body.matches(x) || document.documentElement.matches(x);
261
+ }, w = () => {
262
+ const t = A();
263
+ if (!t) return [];
264
+ const n = [], e = { doc: t.ownerDocument || document, cache: /* @__PURE__ */ new Map() }, r = e.doc.createTreeWalker(t, NodeFilter.SHOW_ELEMENT, null);
265
+ let a = r.currentNode, o = {}, s = {}, p = 0;
266
+ for (; a && p < 5e3; ) {
267
+ const h = a, i = h.tagName?.toLowerCase?.() || "";
268
+ if (h.hidden || h.style.display === "none" || h.style.visibility === "hidden") {
269
+ a = r.nextNode(), p++;
270
+ continue;
271
+ }
272
+ o[i] = (o[i] || 0) + 1, s[i] = `${i}[${o[i] - 1}]`;
273
+ for (const u of v) {
274
+ if (B.has(u.id) || u.selector && !a.matches?.(u.selector)) continue;
275
+ e.cache.set(`${i}Idx`, o[i] - 1), e.cache.set(`${i}Path`, s[i]), /^h[1-6]$/.test(i) && (e.cache.set("headingIdx", o[i] - 1), e.cache.set("headingPath", s[i])), i === "a" && (e.cache.set("aIdx", o[i] - 1), e.cache.set("aPath", s[i])), i === "table" && (e.cache.set("tableIdx", o[i] - 1), e.cache.set("tablePath", s[i])), i === "button" && (e.cache.set("buttonIdx", o[i] - 1), e.cache.set("buttonPath", s[i])), i === "input" && (e.cache.set("inputIdx", o[i] - 1), e.cache.set("inputPath", s[i])), (i === "ul" || i === "ol") && (e.cache.set("ulIdx", o[i] - 1), e.cache.set("ulPath", s[i]));
276
+ const m = u.evaluate(a, e);
277
+ m && n.push(m);
278
+ }
279
+ a = r.nextNode(), p++;
280
+ }
281
+ return n;
282
+ }, b = (t, n = !0) => {
283
+ t.element && (n ? (t.element.classList.add("a11y-highlighted"), t.element.style.outline = "2px solid #ff9800", t.element.style.backgroundColor = "#fff3cd") : (t.element.classList.remove("a11y-highlighted"), t.element.style.outline = "", t.element.style.backgroundColor = ""));
284
+ }, I = (t) => {
285
+ t || (t = w());
286
+ const n = t.filter((a) => a.severity === "error").length, e = t.filter((a) => a.severity === "warning").length;
287
+ let r = 100 - n * 20 - e * 5;
288
+ return Math.max(0, r);
289
+ }, H = (t) => {
290
+ const n = v.find((e) => e.id === t.rule);
291
+ n && n.fix && n.fix(t);
292
+ }, k = () => {
293
+ const t = w(), n = I(t), r = T() ? {
294
+ overlay: "rgba(0, 0, 0, 0.62)",
295
+ dialogBg: "#1f2937",
296
+ panelBg: "#222d3a",
297
+ border: "#3b4657",
298
+ text: "#e2e8f0",
299
+ muted: "#9fb0c6",
300
+ closeHover: "#334155",
301
+ summaryBg: "#111827",
302
+ issueBg: "#1f2937",
303
+ issueHoverBg: "#273244",
304
+ issueBorder: "#4b5563",
305
+ issueHoverBorder: "#58a6ff",
306
+ fixBtn: "#3b82f6",
307
+ fixBtnHover: "#2563eb"
308
+ } : {
309
+ overlay: "rgba(0, 0, 0, 0.5)",
310
+ dialogBg: "#ffffff",
311
+ panelBg: "#ffffff",
312
+ border: "#e0e0e0",
313
+ text: "#1f2937",
314
+ muted: "#666666",
315
+ closeHover: "#f0f0f0",
316
+ summaryBg: "#f5f5f5",
317
+ issueBg: "#ffffff",
318
+ issueHoverBg: "#f5f9ff",
319
+ issueBorder: "#e0e0e0",
320
+ issueHoverBorder: "#2196f3",
321
+ fixBtn: "#2196f3",
322
+ fixBtnHover: "#1976d2"
323
+ }, a = document.createElement("div");
324
+ a.className = "a11y-dialog-overlay", a.style.cssText = `
325
+ position: fixed;
326
+ top: 0;
327
+ left: 0;
328
+ right: 0;
329
+ bottom: 0;
330
+ background: ${r.overlay};
331
+ z-index: 10000;
332
+ display: flex;
333
+ align-items: center;
334
+ justify-content: center;
335
+ `;
336
+ const o = document.createElement("div");
337
+ o.className = "a11y-dialog", o.style.cssText = `
338
+ background: ${r.dialogBg};
339
+ border: 1px solid ${r.border};
340
+ color: ${r.text};
341
+ border-radius: 8px;
342
+ max-width: 800px;
343
+ width: 90%;
344
+ max-height: 80vh;
345
+ display: flex;
346
+ flex-direction: column;
347
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
348
+ `;
349
+ const s = document.createElement("div");
350
+ s.style.cssText = `
351
+ padding: 20px;
352
+ border-bottom: 1px solid ${r.border};
353
+ background: ${r.panelBg};
354
+ display: flex;
355
+ align-items: center;
356
+ justify-content: space-between;
357
+ `;
358
+ const p = document.createElement("h2");
359
+ p.style.cssText = `margin: 0; font-size: 20px; font-weight: 600; color: ${r.text};`, p.textContent = "Accessibility Checker";
360
+ const h = document.createElement("div");
361
+ h.style.cssText = `
362
+ font-size: 24px;
363
+ font-weight: bold;
364
+ padding: 8px 16px;
365
+ border-radius: 4px;
366
+ background: ${n >= 80 ? "#4caf50" : n >= 60 ? "#ff9800" : "#f44336"};
367
+ color: white;
368
+ `, h.textContent = `${n}/100`;
369
+ const i = document.createElement("button");
370
+ i.textContent = "✕", i.style.cssText = `
371
+ background: none;
372
+ border: none;
373
+ font-size: 24px;
374
+ cursor: pointer;
375
+ padding: 0;
376
+ width: 32px;
377
+ height: 32px;
378
+ display: flex;
379
+ align-items: center;
380
+ justify-content: center;
381
+ border-radius: 4px;
382
+ color: ${r.muted};
383
+ `, i.onmouseover = () => {
384
+ i.style.background = r.closeHover, i.style.color = "#f8fafc";
385
+ }, i.onmouseout = () => {
386
+ i.style.background = "none", i.style.color = r.muted;
387
+ }, i.onclick = () => {
388
+ t.forEach((g) => b(g, !1)), a.remove();
389
+ };
390
+ const u = document.createElement("div");
391
+ u.style.cssText = "display: flex; align-items: center; gap: 16px;", u.appendChild(p), u.appendChild(h), s.appendChild(u), s.appendChild(i);
392
+ const m = document.createElement("div");
393
+ if (m.style.cssText = `
394
+ flex: 1;
395
+ overflow-y: auto;
396
+ padding: 20px;
397
+ background: ${r.dialogBg};
398
+ `, t.length === 0)
399
+ m.innerHTML = `
400
+ <div style="text-align: center; padding: 40px 20px;">
401
+ <div style="font-size: 48px; margin-bottom: 16px;">✅</div>
402
+ <h3 style="margin: 0 0 8px 0; color: #4caf50;">No issues found!</h3>
403
+ <p style="margin: 0; color: ${r.muted};">Your content meets WCAG 2.1 AA standards.</p>
404
+ </div>
405
+ `;
406
+ else {
407
+ const g = document.createElement("div");
408
+ g.style.cssText = `
409
+ background: ${r.summaryBg};
410
+ border: 1px solid ${r.border};
411
+ padding: 12px 16px;
412
+ border-radius: 6px;
413
+ margin-bottom: 20px;
414
+ display: flex;
415
+ gap: 20px;
416
+ `;
417
+ const y = t.filter((l) => l.severity === "error").length, $ = t.filter((l) => l.severity === "warning").length, E = t.filter((l) => l.severity === "info").length;
418
+ g.innerHTML = `
419
+ <div><strong style="color: #f44336;">${y}</strong> <span style="color: ${r.muted};">Errors</span></div>
420
+ <div><strong style="color: #ff9800;">${$}</strong> <span style="color: ${r.muted};">Warnings</span></div>
421
+ <div><strong style="color: #2196f3;">${E}</strong> <span style="color: ${r.muted};">Info</span></div>
422
+ `, m.appendChild(g), t.forEach((l) => {
423
+ const c = document.createElement("div");
424
+ c.style.cssText = `
425
+ border: 1px solid ${r.issueBorder};
426
+ border-radius: 6px;
427
+ padding: 16px;
428
+ margin-bottom: 12px;
429
+ transition: all 0.2s;
430
+ background: ${r.issueBg};
431
+ color: ${r.text};
432
+ `, c.onmouseover = () => {
433
+ c.style.borderColor = r.issueHoverBorder, c.style.background = r.issueHoverBg, b(l, !0);
434
+ }, c.onmouseout = () => {
435
+ c.style.borderColor = r.issueBorder, c.style.background = r.issueBg, b(l, !1);
436
+ };
437
+ const L = l.severity === "error" ? "#f44336" : l.severity === "warning" ? "#ff9800" : "#2196f3";
438
+ if (c.innerHTML = `
439
+ <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 8px;">
440
+ <span style="
441
+ background: ${L};
442
+ color: white;
443
+ padding: 2px 8px;
444
+ border-radius: 4px;
445
+ font-size: 12px;
446
+ font-weight: 600;
447
+ text-transform: uppercase;
448
+ ">${l.severity}</span>
449
+ <div style="flex: 1;">
450
+ <div style="font-weight: 600; margin-bottom: 4px;">${l.message}</div>
451
+ <div style="font-size: 12px; color: ${r.muted};">WCAG ${l.wcag} · ${l.rule}</div>
452
+ </div>
453
+ </div>
454
+ <div style="font-size: 14px; color: ${r.text}; margin-bottom: 8px; padding-left: 68px;">
455
+ ${l.suggestion || ""}
456
+ </div>
457
+ `, l.fixable) {
458
+ const d = document.createElement("button");
459
+ d.textContent = `🔧 ${l.fixLabel || "Auto-fix"}`, d.style.cssText = `
460
+ background: ${r.fixBtn};
461
+ color: white;
462
+ border: none;
463
+ padding: 6px 12px;
464
+ border-radius: 4px;
465
+ cursor: pointer;
466
+ font-size: 13px;
467
+ margin-left: 68px;
468
+ `, d.onmouseover = () => d.style.background = r.fixBtnHover, d.onmouseout = () => d.style.background = r.fixBtn, d.onclick = () => {
469
+ H(l), d.textContent = "✓ Fixed", d.style.background = "#4caf50", d.disabled = !0, d.style.cursor = "not-allowed", b(l, !1), setTimeout(() => {
470
+ a.remove(), k();
471
+ }, 1e3);
472
+ }, c.appendChild(d);
473
+ }
474
+ m.appendChild(c);
475
+ });
476
+ }
477
+ o.appendChild(s), o.appendChild(m), a.appendChild(o), document.body.appendChild(a), a.onclick = (g) => {
478
+ g.target === a && (t.forEach((y) => b(y, !1)), a.remove());
479
+ };
480
+ const C = (g) => {
481
+ g.key === "Escape" && (t.forEach((y) => b(y, !1)), a.remove(), document.removeEventListener("keydown", C));
482
+ };
483
+ document.addEventListener("keydown", C);
484
+ }, P = () => ({
485
+ name: "a11yChecker",
486
+ toolbar: [
487
+ {
488
+ label: "Accessibility",
489
+ command: "toggleA11yChecker",
490
+ icon: '<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M9 6.82954C10.1652 6.4177 11 5.30646 11 4.00024C11 2.34339 9.65686 1.00024 8 1.00024C6.34315 1.00024 5 2.34339 5 4.00024C5 5.30646 5.83481 6.4177 7 6.82954V12.0002C7 13.6571 8.34315 15.0002 10 15.0002H14.9296C15.264 15.0002 15.5762 15.1673 15.7617 15.4455L18.4913 19.54C19.1914 20.5901 20.6772 20.7373 21.5696 19.8448L22.7071 18.7074C23.0976 18.3168 23.0976 17.6837 22.7071 17.2931C22.3166 16.9026 21.6834 16.9026 21.2929 17.2931L20.1554 18.4306L17.4258 14.3361C16.8694 13.5015 15.9327 13.0002 14.9296 13.0002H10C9.44772 13.0002 9 12.5525 9 12.0002V11.0002H15C15.5523 11.0002 16 10.5525 16 10.0002C16 9.44796 15.5523 9.00025 15 9.00025H9V6.82954ZM8 5.10758C7.38844 5.10758 6.89267 4.61181 6.89267 4.00024C6.89267 3.38868 7.38844 2.89291 8 2.89291C8.61157 2.89291 9.10734 3.38868 9.10734 4.00024C9.10734 4.61181 8.61157 5.10758 8 5.10758Z" fill="#0F0F0F"></path> <path d="M4.6328 9.07414C5.10517 8.78987 5.69738 9.0279 5.91645 9.53381C6.13552 10.0397 5.89604 10.6205 5.43795 10.9272C4.92993 11.2673 4.48018 11.6911 4.10882 12.1826C3.53598 12.9408 3.16922 13.8345 3.04425 14.7765C2.91928 15.7185 3.04036 16.6768 3.3957 17.5582C3.75103 18.4395 4.32852 19.2138 5.07194 19.8058C5.81535 20.3977 6.69937 20.787 7.63791 20.9359C8.57646 21.0847 9.53756 20.988 10.4276 20.6552C11.3177 20.3223 12.1065 19.7647 12.7171 19.0366C13.1129 18.5645 13.4251 18.0313 13.6428 17.46C13.8391 16.9448 14.3514 16.5813 14.8936 16.6815C15.4357 16.7816 15.8004 17.3054 15.6291 17.8295C15.3326 18.7372 14.8644 19.583 14.2468 20.3194C13.4147 21.3117 12.3399 22.0716 11.1269 22.5252C9.91394 22.9787 8.6042 23.1105 7.32518 22.9077C6.04617 22.7048 4.84148 22.1742 3.82838 21.3676C2.81528 20.561 2.02831 19.5058 1.54407 18.3047C1.05983 17.1037 0.894836 15.7977 1.06514 14.5139C1.23545 13.2302 1.73525 12.0124 2.51589 10.9791C3.09523 10.2123 3.81459 9.56654 4.6328 9.07414Z" fill="#0F0F0F"></path> </g></svg>',
491
+ shortcut: "Mod-Shift-Alt-a"
492
+ }
493
+ ],
494
+ commands: {
495
+ toggleA11yChecker: () => {
496
+ try {
497
+ return k(), !0;
498
+ } catch (t) {
499
+ return console.error("Failed to open accessibility checker:", t), !1;
500
+ }
501
+ }
502
+ },
503
+ keymap: {
504
+ "Mod-Shift-Alt-a": "toggleA11yChecker"
505
+ }
506
+ });
507
+ export {
508
+ P as A11yCheckerPlugin
509
+ };