@editora/core 1.0.0 → 1.0.2
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/README.md +9 -0
- package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs +475 -0
- package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs.map +1 -0
- package/dist/AnchorPlugin.native-7es9PVZ9.mjs +340 -0
- package/dist/AnchorPlugin.native-7es9PVZ9.mjs.map +1 -0
- package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs +449 -0
- package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs.map +1 -0
- package/dist/BlockquotePlugin.native-JFmOLsxN.mjs +48 -0
- package/dist/BlockquotePlugin.native-JFmOLsxN.mjs.map +1 -0
- package/dist/BoldPlugin.native-BAzzoqU5.mjs +45 -0
- package/dist/BoldPlugin.native-BAzzoqU5.mjs.map +1 -0
- package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs +79 -0
- package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs.map +1 -0
- package/dist/ChecklistPlugin.native-Dccs3nLe.mjs +153 -0
- package/dist/ChecklistPlugin.native-Dccs3nLe.mjs.map +1 -0
- package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs +27 -0
- package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs.map +1 -0
- package/dist/CodePlugin.native-DD9xFIid.mjs +1679 -0
- package/dist/CodePlugin.native-DD9xFIid.mjs.map +1 -0
- package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs +326 -0
- package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs.map +1 -0
- package/dist/CommentsPlugin.native-2zQV8Ia4.mjs +473 -0
- package/dist/CommentsPlugin.native-2zQV8Ia4.mjs.map +1 -0
- package/dist/DirectionPlugin.native-Be7wCzkI.mjs +59 -0
- package/dist/DirectionPlugin.native-Be7wCzkI.mjs.map +1 -0
- package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs +116 -0
- package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs.map +1 -0
- package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs +461 -0
- package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs.map +1 -0
- package/dist/EmojisPlugin.native-D6mJSnSR.mjs +1033 -0
- package/dist/EmojisPlugin.native-D6mJSnSR.mjs.map +1 -0
- package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs +106 -0
- package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs.map +1 -0
- package/dist/FontSizePlugin.native-DkLMLPue.mjs +186 -0
- package/dist/FontSizePlugin.native-DkLMLPue.mjs.map +1 -0
- package/dist/FootnotePlugin.native-BciVc9W6.mjs +128 -0
- package/dist/FootnotePlugin.native-BciVc9W6.mjs.map +1 -0
- package/dist/FullscreenPlugin.native-ChXyxeNw.mjs +77 -0
- package/dist/FullscreenPlugin.native-ChXyxeNw.mjs.map +1 -0
- package/dist/HeadingPlugin.native-DrLYwQnQ.mjs +64 -0
- package/dist/HeadingPlugin.native-DrLYwQnQ.mjs.map +1 -0
- package/dist/HistoryPlugin.native-DoDRifCf.mjs +89 -0
- package/dist/HistoryPlugin.native-DoDRifCf.mjs.map +1 -0
- package/dist/IndentPlugin.native-CbFugPoi.mjs +133 -0
- package/dist/IndentPlugin.native-CbFugPoi.mjs.map +1 -0
- package/dist/ItalicPlugin.native-CQjjDyUL.mjs +43 -0
- package/dist/ItalicPlugin.native-CQjjDyUL.mjs.map +1 -0
- package/dist/LineHeightPlugin.native-CWQT2FIa.mjs +73 -0
- package/dist/LineHeightPlugin.native-CWQT2FIa.mjs.map +1 -0
- package/dist/LinkPlugin.native-BdAOV-iu.mjs +206 -0
- package/dist/LinkPlugin.native-BdAOV-iu.mjs.map +1 -0
- package/dist/ListPlugin.native-CLFU5AUQ.mjs +59 -0
- package/dist/ListPlugin.native-CLFU5AUQ.mjs.map +1 -0
- package/dist/MathPlugin.native-DE_ii-LA.mjs +182 -0
- package/dist/MathPlugin.native-DE_ii-LA.mjs.map +1 -0
- package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs +533 -0
- package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs.map +1 -0
- package/dist/MergeTagPlugin.native-CrxyThyn.mjs +178 -0
- package/dist/MergeTagPlugin.native-CrxyThyn.mjs.map +1 -0
- package/dist/PageBreakPlugin.native-DDjcDyRW.mjs +172 -0
- package/dist/PageBreakPlugin.native-DDjcDyRW.mjs.map +1 -0
- package/dist/PreviewPlugin.native-DBvfpmIv.mjs +322 -0
- package/dist/PreviewPlugin.native-DBvfpmIv.mjs.map +1 -0
- package/dist/PrintPlugin.native-BUpm52VJ.mjs +311 -0
- package/dist/PrintPlugin.native-BUpm52VJ.mjs.map +1 -0
- package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs +731 -0
- package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs.map +1 -0
- package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs +465 -0
- package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs.map +1 -0
- package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs +43 -0
- package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs.map +1 -0
- package/dist/TablePlugin.native-EEWXn1-s.mjs +491 -0
- package/dist/TablePlugin.native-EEWXn1-s.mjs.map +1 -0
- package/dist/TemplatePlugin.native-BlSn1c9h.mjs +564 -0
- package/dist/TemplatePlugin.native-BlSn1c9h.mjs.map +1 -0
- package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs +97 -0
- package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs.map +1 -0
- package/dist/TextColorPlugin.native-D6SmTglm.mjs +432 -0
- package/dist/TextColorPlugin.native-D6SmTglm.mjs.map +1 -0
- package/dist/UnderlinePlugin.native-QpIcK4L2.mjs +35 -0
- package/dist/UnderlinePlugin.native-QpIcK4L2.mjs.map +1 -0
- package/dist/core.css +1 -0
- package/dist/documentManager-irzj9n3V.mjs +37627 -0
- package/dist/documentManager-irzj9n3V.mjs.map +1 -0
- package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
- package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
- package/dist/editora.min.js +519 -4
- package/dist/editora.min.js.map +1 -0
- package/dist/editora.umd.js +519 -4
- package/dist/editora.umd.js.map +1 -0
- package/dist/index-BF5RBhL9.js +4 -0
- package/dist/index-BF5RBhL9.js.map +1 -0
- package/dist/index-BPsf460l.mjs +1243 -0
- package/dist/index-BPsf460l.mjs.map +1 -0
- package/dist/index.cjs.js +517 -4
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.es-CuicffkQ.mjs +6665 -0
- package/dist/index.es-CuicffkQ.mjs.map +1 -0
- package/dist/index.esm.js +1403 -122
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin-loader.js +55 -0
- package/dist/plugin-loader.js.map +1 -0
- package/dist/purify.es-CKpwg8Tk.mjs +471 -0
- package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
- package/dist/webcomponent-core.js +1243 -0
- package/dist/webcomponent-core.js.map +1 -0
- package/dist/webcomponent-core.min.css +1 -0
- package/dist/webcomponent-core.min.js +597 -0
- package/dist/webcomponent-core.min.js.map +1 -0
- package/dist/webcomponent.cjs.js +2 -0
- package/dist/webcomponent.cjs.js.map +1 -0
- package/dist/webcomponent.esm.js +6 -0
- package/dist/webcomponent.esm.js.map +1 -0
- package/dist/webcomponent.js +1286 -0
- package/dist/webcomponent.js.map +1 -0
- package/dist/webcomponent.min.css +1 -0
- package/dist/webcomponent.min.js +4076 -0
- package/dist/webcomponent.min.js.map +1 -0
- package/package.json +64 -6
package/README.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @editora/core
|
|
2
2
|
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img src="../../images/editora_logo_blocks.svg" alt="Editora Logo" width="200" height="auto">
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
<img src="../../images/features-overview-1.png" alt="Editora Core - Framework Agnostic Rich Text Editor" width="600" style="border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
|
|
9
|
+
<p><em>Framework-agnostic core editor engine that works with any JavaScript framework</em></p>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
3
12
|
Framework-agnostic core editor engine for Editora Rich Text Editor.
|
|
4
13
|
|
|
5
14
|
## 📦 Installation
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
const v = /* @__PURE__ */ new Set(), C = [], f = (t) => {
|
|
2
|
+
C.push(t);
|
|
3
|
+
};
|
|
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, r) {
|
|
11
|
+
var n;
|
|
12
|
+
const e = t;
|
|
13
|
+
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") || ((n = e.getAttribute("alt")) == null ? void 0 : n.trim()) === "" ? {
|
|
14
|
+
id: `img-alt-${r.cache.get("imgIdx")}`,
|
|
15
|
+
rule: "image-alt-text",
|
|
16
|
+
wcag: "1.1.1",
|
|
17
|
+
severity: "error",
|
|
18
|
+
message: "Image missing alt text",
|
|
19
|
+
nodePath: r.cache.get("imgPath"),
|
|
20
|
+
element: e,
|
|
21
|
+
suggestion: "Add descriptive alt text to all images",
|
|
22
|
+
fixable: !0,
|
|
23
|
+
fixLabel: "Add empty alt"
|
|
24
|
+
} : null;
|
|
25
|
+
},
|
|
26
|
+
fix(t) {
|
|
27
|
+
t.element && t.element.setAttribute("alt", "");
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
f({
|
|
31
|
+
id: "empty-interactive",
|
|
32
|
+
wcag: "4.1.2",
|
|
33
|
+
description: "Interactive elements must have accessible names",
|
|
34
|
+
severity: "error",
|
|
35
|
+
selector: 'button, a, [role="button"]',
|
|
36
|
+
evaluate(t, r) {
|
|
37
|
+
var s;
|
|
38
|
+
const e = t;
|
|
39
|
+
if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "empty-interactive") return null;
|
|
40
|
+
const n = (s = e.textContent) == null ? void 0 : s.trim(), a = e.hasAttribute("aria-label"), l = e.hasAttribute("aria-labelledby"), c = e.hasAttribute("title");
|
|
41
|
+
return !n && !a && !l && !c ? {
|
|
42
|
+
id: `interactive-empty-${r.cache.get("buttonIdx")}`,
|
|
43
|
+
rule: "empty-interactive",
|
|
44
|
+
wcag: "4.1.2",
|
|
45
|
+
severity: "error",
|
|
46
|
+
message: "Interactive element has no accessible name",
|
|
47
|
+
nodePath: r.cache.get("buttonPath"),
|
|
48
|
+
element: e,
|
|
49
|
+
suggestion: "Add text, aria-label, aria-labelledby, or title",
|
|
50
|
+
fixable: !0,
|
|
51
|
+
fixLabel: "Add aria-label"
|
|
52
|
+
} : null;
|
|
53
|
+
},
|
|
54
|
+
fix(t) {
|
|
55
|
+
t.element && t.element.setAttribute("aria-label", "Button");
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
f({
|
|
59
|
+
id: "form-label",
|
|
60
|
+
wcag: "1.3.1",
|
|
61
|
+
description: "Form controls must have labels",
|
|
62
|
+
severity: "error",
|
|
63
|
+
selector: "input, textarea, select",
|
|
64
|
+
evaluate(t, r) {
|
|
65
|
+
const e = t;
|
|
66
|
+
if (e.hasAttribute("type") && e.getAttribute("type") === "hidden" || e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "form-label") return null;
|
|
67
|
+
const n = r.doc.querySelector(`label[for="${e.getAttribute("id")}"]`), a = e.hasAttribute("aria-label"), l = e.hasAttribute("aria-labelledby");
|
|
68
|
+
return !n && !a && !l ? {
|
|
69
|
+
id: `form-label-${r.cache.get("inputIdx")}`,
|
|
70
|
+
rule: "form-label",
|
|
71
|
+
wcag: "1.3.1",
|
|
72
|
+
severity: "error",
|
|
73
|
+
message: "Form control missing label",
|
|
74
|
+
nodePath: r.cache.get("inputPath"),
|
|
75
|
+
element: e,
|
|
76
|
+
suggestion: "Add <label>, aria-label, or aria-labelledby",
|
|
77
|
+
fixable: !0,
|
|
78
|
+
fixLabel: "Add aria-label"
|
|
79
|
+
} : null;
|
|
80
|
+
},
|
|
81
|
+
fix(t) {
|
|
82
|
+
t.element && t.element.setAttribute("aria-label", "Input");
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
f({
|
|
86
|
+
id: "table-headers",
|
|
87
|
+
wcag: "1.3.1",
|
|
88
|
+
description: "Tables must have header rows",
|
|
89
|
+
severity: "error",
|
|
90
|
+
selector: "table",
|
|
91
|
+
evaluate(t, r) {
|
|
92
|
+
const e = t;
|
|
93
|
+
if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "table-headers") return null;
|
|
94
|
+
const n = e.querySelectorAll("th"), a = e.querySelectorAll("tr");
|
|
95
|
+
return n.length === 0 && a.length > 0 ? {
|
|
96
|
+
id: `table-no-headers-${r.cache.get("tableIdx")}`,
|
|
97
|
+
rule: "table-headers",
|
|
98
|
+
wcag: "1.3.1",
|
|
99
|
+
severity: "error",
|
|
100
|
+
message: "Table missing header row (<th> elements)",
|
|
101
|
+
nodePath: r.cache.get("tablePath"),
|
|
102
|
+
element: e,
|
|
103
|
+
suggestion: "Add <th> elements to first row",
|
|
104
|
+
fixable: !0,
|
|
105
|
+
fixLabel: "Convert first row to headers"
|
|
106
|
+
} : null;
|
|
107
|
+
},
|
|
108
|
+
fix(t) {
|
|
109
|
+
if (t.element) {
|
|
110
|
+
const e = t.element.querySelector("tr");
|
|
111
|
+
e && Array.from(e.children).forEach((n) => {
|
|
112
|
+
if (n.tagName === "TD") {
|
|
113
|
+
const a = document.createElement("th");
|
|
114
|
+
a.innerHTML = n.innerHTML, e.replaceChild(a, n);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
f({
|
|
121
|
+
id: "heading-empty",
|
|
122
|
+
wcag: "1.3.1",
|
|
123
|
+
description: "Headings must not be empty",
|
|
124
|
+
severity: "error",
|
|
125
|
+
selector: "h1, h2, h3, h4, h5, h6",
|
|
126
|
+
evaluate(t, r) {
|
|
127
|
+
var l;
|
|
128
|
+
const e = t;
|
|
129
|
+
if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "heading-empty") return null;
|
|
130
|
+
const n = ((l = e.textContent) == null ? void 0 : l.replace(/\s+/g, "")) || "", a = e.childNodes.length === 1 && e.childNodes[0].nodeName === "BR";
|
|
131
|
+
return !n && !a ? {
|
|
132
|
+
id: `heading-empty-${r.cache.get("headingIdx")}`,
|
|
133
|
+
rule: "heading-empty",
|
|
134
|
+
wcag: "1.3.1",
|
|
135
|
+
severity: "error",
|
|
136
|
+
message: `Empty ${e.tagName.toLowerCase()} heading`,
|
|
137
|
+
nodePath: r.cache.get("headingPath"),
|
|
138
|
+
element: e,
|
|
139
|
+
suggestion: "All headings must contain text",
|
|
140
|
+
fixable: !1
|
|
141
|
+
} : null;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
f({
|
|
145
|
+
id: "heading-order",
|
|
146
|
+
wcag: "1.3.1",
|
|
147
|
+
description: "Headings should not skip levels",
|
|
148
|
+
severity: "warning",
|
|
149
|
+
selector: "h1, h2, h3, h4, h5, h6",
|
|
150
|
+
evaluate(t, r) {
|
|
151
|
+
const e = t, n = parseInt(e.tagName[1]), a = r.cache.get("previousHeadingLevel") || n;
|
|
152
|
+
return r.cache.set("previousHeadingLevel", n), n - a > 1 ? {
|
|
153
|
+
id: `heading-order-${r.cache.get("headingIdx")}`,
|
|
154
|
+
rule: "heading-order",
|
|
155
|
+
wcag: "1.3.1",
|
|
156
|
+
severity: "warning",
|
|
157
|
+
message: `Heading skips level (${a} → ${n})`,
|
|
158
|
+
nodePath: r.cache.get("headingPath"),
|
|
159
|
+
element: e,
|
|
160
|
+
suggestion: `Use heading level ${a + 1} instead`,
|
|
161
|
+
fixable: !1
|
|
162
|
+
} : null;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
f({
|
|
166
|
+
id: "link-text",
|
|
167
|
+
wcag: "2.4.4",
|
|
168
|
+
description: "Links must have descriptive text",
|
|
169
|
+
severity: "error",
|
|
170
|
+
selector: "a",
|
|
171
|
+
evaluate(t, r) {
|
|
172
|
+
var c, s;
|
|
173
|
+
const e = t;
|
|
174
|
+
if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "link-text") return null;
|
|
175
|
+
const n = ((c = e.textContent) == null ? void 0 : c.replace(/\s+/g, "").toLowerCase()) || "", a = e.childNodes.length === 1 && e.childNodes[0].nodeName === "BR", l = ["clickhere", "readmore", "link", "here", "this", "page"];
|
|
176
|
+
return !n && !a ? {
|
|
177
|
+
id: `link-empty-${r.cache.get("aIdx")}`,
|
|
178
|
+
rule: "link-text",
|
|
179
|
+
wcag: "2.4.4",
|
|
180
|
+
severity: "error",
|
|
181
|
+
message: "Link has no text content",
|
|
182
|
+
nodePath: r.cache.get("aPath"),
|
|
183
|
+
element: e,
|
|
184
|
+
suggestion: "All links must have descriptive text",
|
|
185
|
+
fixable: !0,
|
|
186
|
+
fixLabel: "Insert placeholder"
|
|
187
|
+
} : l.some((u) => n.includes(u)) ? {
|
|
188
|
+
id: `link-vague-${r.cache.get("aIdx")}`,
|
|
189
|
+
rule: "link-text",
|
|
190
|
+
wcag: "2.4.4",
|
|
191
|
+
severity: "warning",
|
|
192
|
+
message: `Vague link text: "${(s = e.textContent) == null ? void 0 : s.trim()}"`,
|
|
193
|
+
nodePath: r.cache.get("aPath"),
|
|
194
|
+
element: e,
|
|
195
|
+
suggestion: "Use descriptive link text",
|
|
196
|
+
fixable: !1
|
|
197
|
+
} : null;
|
|
198
|
+
},
|
|
199
|
+
fix(t) {
|
|
200
|
+
t.element && (t.element.textContent = "Link");
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
f({
|
|
204
|
+
id: "list-structure",
|
|
205
|
+
wcag: "1.3.1",
|
|
206
|
+
description: "Lists must only contain <li> children",
|
|
207
|
+
severity: "error",
|
|
208
|
+
selector: "ul, ol",
|
|
209
|
+
evaluate(t, r) {
|
|
210
|
+
const e = t;
|
|
211
|
+
if (e.hasAttribute("data-a11y-ignore") && e.getAttribute("data-a11y-ignore") === "list-structure") return null;
|
|
212
|
+
const n = e.querySelectorAll(":scope > li");
|
|
213
|
+
return Array.from(e.children).filter((l) => l.tagName !== "LI").length > 0 ? {
|
|
214
|
+
id: `list-structure-${r.cache.get("ulIdx")}`,
|
|
215
|
+
rule: "list-structure",
|
|
216
|
+
wcag: "1.3.1",
|
|
217
|
+
severity: "error",
|
|
218
|
+
message: "List contains non-li elements",
|
|
219
|
+
nodePath: r.cache.get("ulPath"),
|
|
220
|
+
element: e,
|
|
221
|
+
suggestion: "All direct children of ul/ol must be li elements",
|
|
222
|
+
fixable: !1
|
|
223
|
+
} : n.length === 0 ? {
|
|
224
|
+
id: `list-empty-${r.cache.get("ulIdx")}`,
|
|
225
|
+
rule: "list-structure",
|
|
226
|
+
wcag: "1.3.1",
|
|
227
|
+
severity: "warning",
|
|
228
|
+
message: "Empty list element",
|
|
229
|
+
nodePath: r.cache.get("ulPath"),
|
|
230
|
+
element: e,
|
|
231
|
+
suggestion: "Remove empty lists or add list items",
|
|
232
|
+
fixable: !1
|
|
233
|
+
} : null;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
const L = () => {
|
|
237
|
+
const t = window.getSelection();
|
|
238
|
+
if (t && t.rangeCount > 0) {
|
|
239
|
+
let e = t.getRangeAt(0).startContainer;
|
|
240
|
+
for (; e && e !== document.body; ) {
|
|
241
|
+
if (e.nodeType === Node.ELEMENT_NODE) {
|
|
242
|
+
const n = e;
|
|
243
|
+
if (n.getAttribute("contenteditable") === "true")
|
|
244
|
+
return n;
|
|
245
|
+
}
|
|
246
|
+
e = e.parentNode;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const r = document.activeElement;
|
|
250
|
+
if (r) {
|
|
251
|
+
if (r.getAttribute("contenteditable") === "true")
|
|
252
|
+
return r;
|
|
253
|
+
const e = r.closest('[contenteditable="true"]');
|
|
254
|
+
if (e) return e;
|
|
255
|
+
}
|
|
256
|
+
return document.querySelector('[contenteditable="true"]');
|
|
257
|
+
}, A = () => {
|
|
258
|
+
var u, m, y;
|
|
259
|
+
const t = L();
|
|
260
|
+
if (!t) return [];
|
|
261
|
+
const r = [], e = { doc: t.ownerDocument || document, cache: /* @__PURE__ */ new Map() }, n = e.doc.createTreeWalker(t, NodeFilter.SHOW_ELEMENT, null);
|
|
262
|
+
let a = n.currentNode, l = {}, c = {}, s = 0;
|
|
263
|
+
for (; a && s < 5e3; ) {
|
|
264
|
+
const d = a, i = ((m = (u = d.tagName) == null ? void 0 : u.toLowerCase) == null ? void 0 : m.call(u)) || "";
|
|
265
|
+
if (d.hidden || d.style.display === "none" || d.style.visibility === "hidden") {
|
|
266
|
+
a = n.nextNode(), s++;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
l[i] = (l[i] || 0) + 1, c[i] = `${i}[${l[i] - 1}]`;
|
|
270
|
+
for (const p of C) {
|
|
271
|
+
if (v.has(p.id) || p.selector && !((y = a.matches) != null && y.call(a, p.selector))) continue;
|
|
272
|
+
e.cache.set(`${i}Idx`, l[i] - 1), e.cache.set(`${i}Path`, c[i]), /^h[1-6]$/.test(i) && (e.cache.set("headingIdx", l[i] - 1), e.cache.set("headingPath", c[i])), i === "a" && (e.cache.set("aIdx", l[i] - 1), e.cache.set("aPath", c[i])), i === "table" && (e.cache.set("tableIdx", l[i] - 1), e.cache.set("tablePath", c[i])), i === "button" && (e.cache.set("buttonIdx", l[i] - 1), e.cache.set("buttonPath", c[i])), i === "input" && (e.cache.set("inputIdx", l[i] - 1), e.cache.set("inputPath", c[i])), (i === "ul" || i === "ol") && (e.cache.set("ulIdx", l[i] - 1), e.cache.set("ulPath", c[i]));
|
|
273
|
+
const x = p.evaluate(a, e);
|
|
274
|
+
x && r.push(x);
|
|
275
|
+
}
|
|
276
|
+
a = n.nextNode(), s++;
|
|
277
|
+
}
|
|
278
|
+
return r;
|
|
279
|
+
}, b = (t, r = !0) => {
|
|
280
|
+
t.element && (r ? (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 = ""));
|
|
281
|
+
}, E = (t) => {
|
|
282
|
+
t || (t = A());
|
|
283
|
+
const r = t.filter((a) => a.severity === "error").length, e = t.filter((a) => a.severity === "warning").length;
|
|
284
|
+
let n = 100 - r * 20 - e * 5;
|
|
285
|
+
return Math.max(0, n);
|
|
286
|
+
}, $ = (t) => {
|
|
287
|
+
const r = C.find((e) => e.id === t.rule);
|
|
288
|
+
r && r.fix && r.fix(t);
|
|
289
|
+
}, I = (t) => {
|
|
290
|
+
v.add(t);
|
|
291
|
+
}, P = (t) => {
|
|
292
|
+
v.delete(t);
|
|
293
|
+
}, w = () => {
|
|
294
|
+
const t = A(), r = E(t), e = document.createElement("div");
|
|
295
|
+
e.className = "a11y-dialog-overlay", e.style.cssText = `
|
|
296
|
+
position: fixed;
|
|
297
|
+
top: 0;
|
|
298
|
+
left: 0;
|
|
299
|
+
right: 0;
|
|
300
|
+
bottom: 0;
|
|
301
|
+
background: rgba(0, 0, 0, 0.5);
|
|
302
|
+
z-index: 10000;
|
|
303
|
+
display: flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
justify-content: center;
|
|
306
|
+
`;
|
|
307
|
+
const n = document.createElement("div");
|
|
308
|
+
n.className = "a11y-dialog", n.style.cssText = `
|
|
309
|
+
background: white;
|
|
310
|
+
border-radius: 8px;
|
|
311
|
+
max-width: 800px;
|
|
312
|
+
width: 90%;
|
|
313
|
+
max-height: 80vh;
|
|
314
|
+
display: flex;
|
|
315
|
+
flex-direction: column;
|
|
316
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
|
|
317
|
+
`;
|
|
318
|
+
const a = document.createElement("div");
|
|
319
|
+
a.style.cssText = `
|
|
320
|
+
padding: 20px;
|
|
321
|
+
border-bottom: 1px solid #e0e0e0;
|
|
322
|
+
display: flex;
|
|
323
|
+
align-items: center;
|
|
324
|
+
justify-content: space-between;
|
|
325
|
+
`;
|
|
326
|
+
const l = document.createElement("h2");
|
|
327
|
+
l.style.cssText = "margin: 0; font-size: 20px; font-weight: 600;", l.textContent = "Accessibility Checker";
|
|
328
|
+
const c = document.createElement("div");
|
|
329
|
+
c.style.cssText = `
|
|
330
|
+
font-size: 24px;
|
|
331
|
+
font-weight: bold;
|
|
332
|
+
padding: 8px 16px;
|
|
333
|
+
border-radius: 4px;
|
|
334
|
+
background: ${r >= 80 ? "#4caf50" : r >= 60 ? "#ff9800" : "#f44336"};
|
|
335
|
+
color: white;
|
|
336
|
+
`, c.textContent = `${r}/100`;
|
|
337
|
+
const s = document.createElement("button");
|
|
338
|
+
s.textContent = "✕", s.style.cssText = `
|
|
339
|
+
background: none;
|
|
340
|
+
border: none;
|
|
341
|
+
font-size: 24px;
|
|
342
|
+
cursor: pointer;
|
|
343
|
+
padding: 0;
|
|
344
|
+
width: 32px;
|
|
345
|
+
height: 32px;
|
|
346
|
+
display: flex;
|
|
347
|
+
align-items: center;
|
|
348
|
+
justify-content: center;
|
|
349
|
+
border-radius: 4px;
|
|
350
|
+
`, s.onmouseover = () => s.style.background = "#f0f0f0", s.onmouseout = () => s.style.background = "none", s.onclick = () => {
|
|
351
|
+
t.forEach((d) => b(d, !1)), e.remove();
|
|
352
|
+
};
|
|
353
|
+
const u = document.createElement("div");
|
|
354
|
+
u.style.cssText = "display: flex; align-items: center; gap: 16px;", u.appendChild(l), u.appendChild(c), a.appendChild(u), a.appendChild(s);
|
|
355
|
+
const m = document.createElement("div");
|
|
356
|
+
if (m.style.cssText = `
|
|
357
|
+
flex: 1;
|
|
358
|
+
overflow-y: auto;
|
|
359
|
+
padding: 20px;
|
|
360
|
+
`, t.length === 0)
|
|
361
|
+
m.innerHTML = `
|
|
362
|
+
<div style="text-align: center; padding: 40px 20px;">
|
|
363
|
+
<div style="font-size: 48px; margin-bottom: 16px;">✅</div>
|
|
364
|
+
<h3 style="margin: 0 0 8px 0; color: #4caf50;">No issues found!</h3>
|
|
365
|
+
<p style="margin: 0; color: #666;">Your content meets WCAG 2.1 AA standards.</p>
|
|
366
|
+
</div>
|
|
367
|
+
`;
|
|
368
|
+
else {
|
|
369
|
+
const d = document.createElement("div");
|
|
370
|
+
d.style.cssText = `
|
|
371
|
+
background: #f5f5f5;
|
|
372
|
+
padding: 12px 16px;
|
|
373
|
+
border-radius: 6px;
|
|
374
|
+
margin-bottom: 20px;
|
|
375
|
+
display: flex;
|
|
376
|
+
gap: 20px;
|
|
377
|
+
`;
|
|
378
|
+
const i = t.filter((o) => o.severity === "error").length, p = t.filter((o) => o.severity === "warning").length, x = t.filter((o) => o.severity === "info").length;
|
|
379
|
+
d.innerHTML = `
|
|
380
|
+
<div><strong style="color: #f44336;">${i}</strong> <span style="color: #666;">Errors</span></div>
|
|
381
|
+
<div><strong style="color: #ff9800;">${p}</strong> <span style="color: #666;">Warnings</span></div>
|
|
382
|
+
<div><strong style="color: #2196f3;">${x}</strong> <span style="color: #666;">Info</span></div>
|
|
383
|
+
`, m.appendChild(d), t.forEach((o) => {
|
|
384
|
+
const h = document.createElement("div");
|
|
385
|
+
h.style.cssText = `
|
|
386
|
+
border: 1px solid #e0e0e0;
|
|
387
|
+
border-radius: 6px;
|
|
388
|
+
padding: 16px;
|
|
389
|
+
margin-bottom: 12px;
|
|
390
|
+
transition: all 0.2s;
|
|
391
|
+
`, h.onmouseover = () => {
|
|
392
|
+
h.style.borderColor = "#2196f3", h.style.background = "#f5f9ff", b(o, !0);
|
|
393
|
+
}, h.onmouseout = () => {
|
|
394
|
+
h.style.borderColor = "#e0e0e0", h.style.background = "white", b(o, !1);
|
|
395
|
+
};
|
|
396
|
+
const k = o.severity === "error" ? "#f44336" : o.severity === "warning" ? "#ff9800" : "#2196f3";
|
|
397
|
+
if (h.innerHTML = `
|
|
398
|
+
<div style="display: flex; align-items: start; gap: 12px; margin-bottom: 8px;">
|
|
399
|
+
<span style="
|
|
400
|
+
background: ${k};
|
|
401
|
+
color: white;
|
|
402
|
+
padding: 2px 8px;
|
|
403
|
+
border-radius: 4px;
|
|
404
|
+
font-size: 12px;
|
|
405
|
+
font-weight: 600;
|
|
406
|
+
text-transform: uppercase;
|
|
407
|
+
">${o.severity}</span>
|
|
408
|
+
<div style="flex: 1;">
|
|
409
|
+
<div style="font-weight: 600; margin-bottom: 4px;">${o.message}</div>
|
|
410
|
+
<div style="font-size: 12px; color: #666;">WCAG ${o.wcag} · ${o.rule}</div>
|
|
411
|
+
</div>
|
|
412
|
+
</div>
|
|
413
|
+
<div style="font-size: 14px; color: #444; margin-bottom: 8px; padding-left: 68px;">
|
|
414
|
+
${o.suggestion || ""}
|
|
415
|
+
</div>
|
|
416
|
+
`, o.fixable) {
|
|
417
|
+
const g = document.createElement("button");
|
|
418
|
+
g.textContent = `🔧 ${o.fixLabel || "Auto-fix"}`, g.style.cssText = `
|
|
419
|
+
background: #2196f3;
|
|
420
|
+
color: white;
|
|
421
|
+
border: none;
|
|
422
|
+
padding: 6px 12px;
|
|
423
|
+
border-radius: 4px;
|
|
424
|
+
cursor: pointer;
|
|
425
|
+
font-size: 13px;
|
|
426
|
+
margin-left: 68px;
|
|
427
|
+
`, g.onmouseover = () => g.style.background = "#1976d2", g.onmouseout = () => g.style.background = "#2196f3", g.onclick = () => {
|
|
428
|
+
$(o), g.textContent = "✓ Fixed", g.style.background = "#4caf50", g.disabled = !0, g.style.cursor = "not-allowed", b(o, !1), setTimeout(() => {
|
|
429
|
+
e.remove(), w();
|
|
430
|
+
}, 1e3);
|
|
431
|
+
}, h.appendChild(g);
|
|
432
|
+
}
|
|
433
|
+
m.appendChild(h);
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
n.appendChild(a), n.appendChild(m), e.appendChild(n), document.body.appendChild(e), e.onclick = (d) => {
|
|
437
|
+
d.target === e && (t.forEach((i) => b(i, !1)), e.remove());
|
|
438
|
+
};
|
|
439
|
+
const y = (d) => {
|
|
440
|
+
d.key === "Escape" && (t.forEach((i) => b(i, !1)), e.remove(), document.removeEventListener("keydown", y));
|
|
441
|
+
};
|
|
442
|
+
document.addEventListener("keydown", y);
|
|
443
|
+
}, T = () => ({
|
|
444
|
+
name: "a11yChecker",
|
|
445
|
+
toolbar: [
|
|
446
|
+
{
|
|
447
|
+
label: "Accessibility",
|
|
448
|
+
command: "toggleA11yChecker",
|
|
449
|
+
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>',
|
|
450
|
+
shortcut: "Mod-Shift-Alt-a"
|
|
451
|
+
}
|
|
452
|
+
],
|
|
453
|
+
commands: {
|
|
454
|
+
toggleA11yChecker: () => {
|
|
455
|
+
try {
|
|
456
|
+
return w(), !0;
|
|
457
|
+
} catch (t) {
|
|
458
|
+
return console.error("Failed to open accessibility checker:", t), !1;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
keymap: {
|
|
463
|
+
"Mod-Shift-Alt-a": "toggleA11yChecker"
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
export {
|
|
467
|
+
T as A11yCheckerPlugin,
|
|
468
|
+
$ as autoFixA11yIssue,
|
|
469
|
+
E as getA11yScore,
|
|
470
|
+
b as highlightIssue,
|
|
471
|
+
A as runA11yAudit,
|
|
472
|
+
I as suppressRule,
|
|
473
|
+
P as unsuppressRule
|
|
474
|
+
};
|
|
475
|
+
//# sourceMappingURL=A11yCheckerPlugin.native-CZKpi3uF.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"A11yCheckerPlugin.native-CZKpi3uF.mjs","sources":["../../plugins/a11y-checker/src/A11yCheckerPlugin.native.ts"],"sourcesContent":["import type { Plugin } from '@editora/core';\n\n/**\n * A11yCheckerPlugin - Native implementation with complete WCAG 2.1 AA checking and UI dialog\n * \n * Features:\n * - Comprehensive WCAG 2.1 AA rule checking\n * - Visual issue highlighting\n * - Auto-fix capabilities\n * - Issue suppression\n * - Accessibility score\n * - Full UI dialog with issue list, details, and actions\n */\n\n// --- Rule Engine Types ---\nexport interface A11yContext {\n doc: Document;\n cache: Map<string, any>;\n}\n\nexport interface A11yRule {\n id: string;\n wcag: string;\n description: string;\n severity: 'error' | 'warning' | 'info';\n selector?: string;\n evaluate(node: Node, ctx: A11yContext): A11yIssue | null;\n fix?(issue: A11yIssue): void;\n}\n\nexport interface A11yIssue {\n id: string;\n rule: string;\n wcag: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n nodePath: string;\n element?: HTMLElement;\n suggestion?: string;\n fixable?: boolean;\n fixLabel?: string;\n}\n\nconst suppressedRules = new Set<string>();\nconst ruleRegistry: A11yRule[] = [];\nconst registerA11yRule = (rule: A11yRule) => { ruleRegistry.push(rule); };\n\n// --- WCAG 2.1 AA Rule Implementations ---\n\n// 1. Image Alt Text (Error - WCAG 1.1.1)\nregisterA11yRule({\n id: 'image-alt-text',\n wcag: '1.1.1',\n description: 'Images must have alt text',\n severity: 'error',\n selector: 'img',\n evaluate(node, ctx) {\n const img = node as HTMLImageElement;\n if (img.hasAttribute('role') && img.getAttribute('role') === 'presentation') return null;\n if (img.hasAttribute('data-a11y-ignore') && img.getAttribute('data-a11y-ignore') === 'image-alt-text') return null;\n if (!img.hasAttribute('alt') || img.getAttribute('alt')?.trim() === '') {\n return {\n id: `img-alt-${ctx.cache.get('imgIdx')}`,\n rule: 'image-alt-text',\n wcag: '1.1.1',\n severity: 'error',\n message: 'Image missing alt text',\n nodePath: ctx.cache.get('imgPath'),\n element: img,\n suggestion: 'Add descriptive alt text to all images',\n fixable: true,\n fixLabel: 'Add empty alt',\n };\n }\n return null;\n },\n fix(issue) {\n if (issue.element) (issue.element as HTMLImageElement).setAttribute('alt', '');\n }\n});\n\n// 2. Empty Interactive Elements (Error - WCAG 4.1.2)\nregisterA11yRule({\n id: 'empty-interactive',\n wcag: '4.1.2',\n description: 'Interactive elements must have accessible names',\n severity: 'error',\n selector: 'button, a, [role=\"button\"]',\n evaluate(node, ctx) {\n const el = node as HTMLElement;\n if (el.hasAttribute('data-a11y-ignore') && el.getAttribute('data-a11y-ignore') === 'empty-interactive') return null;\n const hasText = el.textContent?.trim();\n const hasAriaLabel = el.hasAttribute('aria-label');\n const hasAriaLabelledBy = el.hasAttribute('aria-labelledby');\n const hasTitle = el.hasAttribute('title');\n if (!hasText && !hasAriaLabel && !hasAriaLabelledBy && !hasTitle) {\n return {\n id: `interactive-empty-${ctx.cache.get('buttonIdx')}`,\n rule: 'empty-interactive',\n wcag: '4.1.2',\n severity: 'error',\n message: 'Interactive element has no accessible name',\n nodePath: ctx.cache.get('buttonPath'),\n element: el,\n suggestion: 'Add text, aria-label, aria-labelledby, or title',\n fixable: true,\n fixLabel: 'Add aria-label',\n };\n }\n return null;\n },\n fix(issue) {\n if (issue.element) issue.element.setAttribute('aria-label', 'Button');\n }\n});\n\n// 3. Form Control Labels (Error - WCAG 1.3.1)\nregisterA11yRule({\n id: 'form-label',\n wcag: '1.3.1',\n description: 'Form controls must have labels',\n severity: 'error',\n selector: 'input, textarea, select',\n evaluate(node, ctx) {\n const el = node as HTMLElement;\n if (el.hasAttribute('type') && el.getAttribute('type') === 'hidden') return null;\n if (el.hasAttribute('data-a11y-ignore') && el.getAttribute('data-a11y-ignore') === 'form-label') return null;\n const hasLabel = ctx.doc.querySelector(`label[for=\"${el.getAttribute('id')}\"]`);\n const hasAriaLabel = el.hasAttribute('aria-label');\n const hasAriaLabelledBy = el.hasAttribute('aria-labelledby');\n if (!hasLabel && !hasAriaLabel && !hasAriaLabelledBy) {\n return {\n id: `form-label-${ctx.cache.get('inputIdx')}`,\n rule: 'form-label',\n wcag: '1.3.1',\n severity: 'error',\n message: 'Form control missing label',\n nodePath: ctx.cache.get('inputPath'),\n element: el,\n suggestion: 'Add <label>, aria-label, or aria-labelledby',\n fixable: true,\n fixLabel: 'Add aria-label',\n };\n }\n return null;\n },\n fix(issue) {\n if (issue.element) issue.element.setAttribute('aria-label', 'Input');\n }\n});\n\n// 4. Table Headers (Error - WCAG 1.3.1)\nregisterA11yRule({\n id: 'table-headers',\n wcag: '1.3.1',\n description: 'Tables must have header rows',\n severity: 'error',\n selector: 'table',\n evaluate(node, ctx) {\n const table = node as HTMLTableElement;\n if (table.hasAttribute('data-a11y-ignore') && table.getAttribute('data-a11y-ignore') === 'table-headers') return null;\n const headers = table.querySelectorAll('th');\n const rows = table.querySelectorAll('tr');\n if (headers.length === 0 && rows.length > 0) {\n return {\n id: `table-no-headers-${ctx.cache.get('tableIdx')}`,\n rule: 'table-headers',\n wcag: '1.3.1',\n severity: 'error',\n message: 'Table missing header row (<th> elements)',\n nodePath: ctx.cache.get('tablePath'),\n element: table,\n suggestion: 'Add <th> elements to first row',\n fixable: true,\n fixLabel: 'Convert first row to headers',\n };\n }\n return null;\n },\n fix(issue) {\n if (issue.element) {\n const table = issue.element as HTMLTableElement;\n const firstRow = table.querySelector('tr');\n if (firstRow) {\n Array.from(firstRow.children).forEach(cell => {\n if (cell.tagName === 'TD') {\n const th = document.createElement('th');\n th.innerHTML = cell.innerHTML;\n firstRow.replaceChild(th, cell);\n }\n });\n }\n }\n }\n});\n\n// 5. Empty Headings (Error - WCAG 1.3.1)\nregisterA11yRule({\n id: 'heading-empty',\n wcag: '1.3.1',\n description: 'Headings must not be empty',\n severity: 'error',\n selector: 'h1, h2, h3, h4, h5, h6',\n evaluate(node, ctx) {\n const heading = node as HTMLElement;\n if (heading.hasAttribute('data-a11y-ignore') && heading.getAttribute('data-a11y-ignore') === 'heading-empty') return null;\n const text = heading.textContent?.replace(/\\s+/g, '') || '';\n const onlyBr = heading.childNodes.length === 1 && heading.childNodes[0].nodeName === 'BR';\n if (!text && !onlyBr) {\n return {\n id: `heading-empty-${ctx.cache.get('headingIdx')}`,\n rule: 'heading-empty',\n wcag: '1.3.1',\n severity: 'error',\n message: `Empty ${heading.tagName.toLowerCase()} heading`,\n nodePath: ctx.cache.get('headingPath'),\n element: heading,\n suggestion: 'All headings must contain text',\n fixable: false,\n };\n }\n return null;\n }\n});\n\n// 6. Heading Order (Warning - WCAG 1.3.1)\nregisterA11yRule({\n id: 'heading-order',\n wcag: '1.3.1',\n description: 'Headings should not skip levels',\n severity: 'warning',\n selector: 'h1, h2, h3, h4, h5, h6',\n evaluate(node, ctx) {\n const heading = node as HTMLElement;\n const currentLevel = parseInt(heading.tagName[1]);\n const previousLevel = ctx.cache.get('previousHeadingLevel') || currentLevel;\n ctx.cache.set('previousHeadingLevel', currentLevel);\n if (currentLevel - previousLevel > 1) {\n return {\n id: `heading-order-${ctx.cache.get('headingIdx')}`,\n rule: 'heading-order',\n wcag: '1.3.1',\n severity: 'warning',\n message: `Heading skips level (${previousLevel} → ${currentLevel})`,\n nodePath: ctx.cache.get('headingPath'),\n element: heading,\n suggestion: `Use heading level ${previousLevel + 1} instead`,\n fixable: false,\n };\n }\n return null;\n }\n});\n\n// 7. Link Text Quality (Error/Warning - WCAG 2.4.4)\nregisterA11yRule({\n id: 'link-text',\n wcag: '2.4.4',\n description: 'Links must have descriptive text',\n severity: 'error',\n selector: 'a',\n evaluate(node, ctx) {\n const link = node as HTMLElement;\n if (link.hasAttribute('data-a11y-ignore') && link.getAttribute('data-a11y-ignore') === 'link-text') return null;\n const text = link.textContent?.replace(/\\s+/g, '').toLowerCase() || '';\n const onlyBr = link.childNodes.length === 1 && link.childNodes[0].nodeName === 'BR';\n const vagueText = ['clickhere', 'readmore', 'link', 'here', 'this', 'page'];\n \n if (!text && !onlyBr) {\n return {\n id: `link-empty-${ctx.cache.get('aIdx')}`,\n rule: 'link-text',\n wcag: '2.4.4',\n severity: 'error',\n message: 'Link has no text content',\n nodePath: ctx.cache.get('aPath'),\n element: link,\n suggestion: 'All links must have descriptive text',\n fixable: true,\n fixLabel: 'Insert placeholder',\n };\n } else if (vagueText.some(vt => text.includes(vt))) {\n return {\n id: `link-vague-${ctx.cache.get('aIdx')}`,\n rule: 'link-text',\n wcag: '2.4.4',\n severity: 'warning',\n message: `Vague link text: \"${link.textContent?.trim()}\"`,\n nodePath: ctx.cache.get('aPath'),\n element: link,\n suggestion: 'Use descriptive link text',\n fixable: false,\n };\n }\n return null;\n },\n fix(issue) {\n if (issue.element) issue.element.textContent = 'Link';\n }\n});\n\n// 8. List Structure (Error - WCAG 1.3.1)\nregisterA11yRule({\n id: 'list-structure',\n wcag: '1.3.1',\n description: 'Lists must only contain <li> children',\n severity: 'error',\n selector: 'ul, ol',\n evaluate(node, ctx) {\n const list = node as HTMLElement;\n if (list.hasAttribute('data-a11y-ignore') && list.getAttribute('data-a11y-ignore') === 'list-structure') return null;\n const items = list.querySelectorAll(':scope > li');\n const nonLiChildren = Array.from(list.children).filter(child => child.tagName !== 'LI');\n if (nonLiChildren.length > 0) {\n return {\n id: `list-structure-${ctx.cache.get('ulIdx')}`,\n rule: 'list-structure',\n wcag: '1.3.1',\n severity: 'error',\n message: 'List contains non-li elements',\n nodePath: ctx.cache.get('ulPath'),\n element: list,\n suggestion: 'All direct children of ul/ol must be li elements',\n fixable: false,\n };\n }\n if (items.length === 0) {\n return {\n id: `list-empty-${ctx.cache.get('ulIdx')}`,\n rule: 'list-structure',\n wcag: '1.3.1',\n severity: 'warning',\n message: 'Empty list element',\n nodePath: ctx.cache.get('ulPath'),\n element: list,\n suggestion: 'Remove empty lists or add list items',\n fixable: false,\n };\n }\n return null;\n }\n});\n\n/**\n * Find the active editor element\n */\nconst findActiveEditor = (): HTMLElement | null => {\n // Try to find editor from current selection\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n let node: Node | null = selection.getRangeAt(0).startContainer;\n while (node && node !== document.body) {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n if (element.getAttribute('contenteditable') === 'true') {\n return element;\n }\n }\n node = node.parentNode;\n }\n }\n \n // Try active element\n const activeElement = document.activeElement;\n if (activeElement) {\n if (activeElement.getAttribute('contenteditable') === 'true') {\n return activeElement as HTMLElement;\n }\n const editor = activeElement.closest('[contenteditable=\"true\"]');\n if (editor) return editor as HTMLElement;\n }\n \n // Fallback to first editor\n return document.querySelector('[contenteditable=\"true\"]');\n};\n\n// --- Audit Engine ---\nexport const runA11yAudit = (): A11yIssue[] => {\n const editor = findActiveEditor();\n if (!editor) return [];\n \n const issues: A11yIssue[] = [];\n const ctx: A11yContext = { doc: editor.ownerDocument || document, cache: new Map() };\n const walker = ctx.doc.createTreeWalker(editor, NodeFilter.SHOW_ELEMENT, null);\n \n let node: Node | null = walker.currentNode;\n let idxMap: Record<string, number> = {};\n let pathMap: Record<string, string> = {};\n let nodeIdx = 0;\n \n while (node && nodeIdx < 5000) {\n const el = node as HTMLElement;\n const tag = el.tagName?.toLowerCase?.() || '';\n \n // Skip hidden elements\n if (el.hidden || el.style.display === 'none' || el.style.visibility === 'hidden') {\n node = walker.nextNode();\n nodeIdx++;\n continue;\n }\n \n idxMap[tag] = (idxMap[tag] || 0) + 1;\n pathMap[tag] = `${tag}[${idxMap[tag] - 1}]`;\n \n for (const rule of ruleRegistry) {\n if (suppressedRules.has(rule.id)) continue;\n if (rule.selector && !(node as Element).matches?.(rule.selector)) continue;\n \n ctx.cache.set(`${tag}Idx`, idxMap[tag] - 1);\n ctx.cache.set(`${tag}Path`, pathMap[tag]);\n \n if (/^h[1-6]$/.test(tag)) {\n ctx.cache.set('headingIdx', idxMap[tag] - 1);\n ctx.cache.set('headingPath', pathMap[tag]);\n }\n if (tag === 'a') {\n ctx.cache.set('aIdx', idxMap[tag] - 1);\n ctx.cache.set('aPath', pathMap[tag]);\n }\n if (tag === 'table') {\n ctx.cache.set('tableIdx', idxMap[tag] - 1);\n ctx.cache.set('tablePath', pathMap[tag]);\n }\n if (tag === 'button') {\n ctx.cache.set('buttonIdx', idxMap[tag] - 1);\n ctx.cache.set('buttonPath', pathMap[tag]);\n }\n if (tag === 'input') {\n ctx.cache.set('inputIdx', idxMap[tag] - 1);\n ctx.cache.set('inputPath', pathMap[tag]);\n }\n if (tag === 'ul' || tag === 'ol') {\n ctx.cache.set('ulIdx', idxMap[tag] - 1);\n ctx.cache.set('ulPath', pathMap[tag]);\n }\n \n const issue = rule.evaluate(node, ctx);\n if (issue) issues.push(issue);\n }\n \n node = walker.nextNode();\n nodeIdx++;\n }\n \n return issues;\n};\n\nexport const highlightIssue = (issue: A11yIssue, highlight: boolean = true) => {\n if (!issue.element) return;\n if (highlight) {\n issue.element.classList.add('a11y-highlighted');\n issue.element.style.outline = '2px solid #ff9800';\n issue.element.style.backgroundColor = '#fff3cd';\n } else {\n issue.element.classList.remove('a11y-highlighted');\n issue.element.style.outline = '';\n issue.element.style.backgroundColor = '';\n }\n};\n\nexport const getA11yScore = (issues?: A11yIssue[]): number => {\n // Use provided issues or run fresh audit if not provided\n if (!issues) {\n issues = runA11yAudit();\n }\n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n let score = 100 - (errors * 20) - (warnings * 5);\n return Math.max(0, score);\n};\n\nexport const autoFixA11yIssue = (issue: A11yIssue) => {\n const rule = ruleRegistry.find(r => r.id === issue.rule);\n if (rule && rule.fix) rule.fix(issue);\n};\n\nexport const suppressRule = (ruleId: string) => { suppressedRules.add(ruleId); };\nexport const unsuppressRule = (ruleId: string) => { suppressedRules.delete(ruleId); };\n\n// --- UI Dialog Implementation ---\nconst createA11yDialog = () => {\n const issues = runA11yAudit();\n const score = getA11yScore(issues); // Pass issues to avoid duplicate audit\n \n // Create dialog overlay\n const overlay = document.createElement('div');\n overlay.className = 'a11y-dialog-overlay';\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n \n // Create dialog\n const dialog = document.createElement('div');\n dialog.className = 'a11y-dialog';\n dialog.style.cssText = `\n background: white;\n border-radius: 8px;\n max-width: 800px;\n width: 90%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);\n `;\n \n // Header\n const header = document.createElement('div');\n header.style.cssText = `\n padding: 20px;\n border-bottom: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n `;\n \n const title = document.createElement('h2');\n title.style.cssText = 'margin: 0; font-size: 20px; font-weight: 600;';\n title.textContent = 'Accessibility Checker';\n \n const scoreDisplay = document.createElement('div');\n scoreDisplay.style.cssText = `\n font-size: 24px;\n font-weight: bold;\n padding: 8px 16px;\n border-radius: 4px;\n background: ${score >= 80 ? '#4caf50' : score >= 60 ? '#ff9800' : '#f44336'};\n color: white;\n `;\n scoreDisplay.textContent = `${score}/100`;\n \n const closeBtn = document.createElement('button');\n closeBtn.textContent = '✕';\n closeBtn.style.cssText = `\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n `;\n closeBtn.onmouseover = () => closeBtn.style.background = '#f0f0f0';\n closeBtn.onmouseout = () => closeBtn.style.background = 'none';\n closeBtn.onclick = () => {\n // Clear all highlights\n issues.forEach(issue => highlightIssue(issue, false));\n overlay.remove();\n };\n \n const headerLeft = document.createElement('div');\n headerLeft.style.cssText = 'display: flex; align-items: center; gap: 16px;';\n headerLeft.appendChild(title);\n headerLeft.appendChild(scoreDisplay);\n \n header.appendChild(headerLeft);\n header.appendChild(closeBtn);\n \n // Content\n const content = document.createElement('div');\n content.style.cssText = `\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n `;\n \n if (issues.length === 0) {\n content.innerHTML = `\n <div style=\"text-align: center; padding: 40px 20px;\">\n <div style=\"font-size: 48px; margin-bottom: 16px;\">✅</div>\n <h3 style=\"margin: 0 0 8px 0; color: #4caf50;\">No issues found!</h3>\n <p style=\"margin: 0; color: #666;\">Your content meets WCAG 2.1 AA standards.</p>\n </div>\n `;\n } else {\n const summary = document.createElement('div');\n summary.style.cssText = `\n background: #f5f5f5;\n padding: 12px 16px;\n border-radius: 6px;\n margin-bottom: 20px;\n display: flex;\n gap: 20px;\n `;\n \n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n \n summary.innerHTML = `\n <div><strong style=\"color: #f44336;\">${errors}</strong> <span style=\"color: #666;\">Errors</span></div>\n <div><strong style=\"color: #ff9800;\">${warnings}</strong> <span style=\"color: #666;\">Warnings</span></div>\n <div><strong style=\"color: #2196f3;\">${infos}</strong> <span style=\"color: #666;\">Info</span></div>\n `;\n \n content.appendChild(summary);\n \n // Issue list\n issues.forEach(issue => {\n const issueItem = document.createElement('div');\n issueItem.style.cssText = `\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n padding: 16px;\n margin-bottom: 12px;\n transition: all 0.2s;\n `;\n issueItem.onmouseover = () => {\n issueItem.style.borderColor = '#2196f3';\n issueItem.style.background = '#f5f9ff';\n highlightIssue(issue, true);\n };\n issueItem.onmouseout = () => {\n issueItem.style.borderColor = '#e0e0e0';\n issueItem.style.background = 'white';\n highlightIssue(issue, false);\n };\n \n const severityColor = issue.severity === 'error' ? '#f44336' : \n issue.severity === 'warning' ? '#ff9800' : '#2196f3';\n \n issueItem.innerHTML = `\n <div style=\"display: flex; align-items: start; gap: 12px; margin-bottom: 8px;\">\n <span style=\"\n background: ${severityColor};\n color: white;\n padding: 2px 8px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n \">${issue.severity}</span>\n <div style=\"flex: 1;\">\n <div style=\"font-weight: 600; margin-bottom: 4px;\">${issue.message}</div>\n <div style=\"font-size: 12px; color: #666;\">WCAG ${issue.wcag} · ${issue.rule}</div>\n </div>\n </div>\n <div style=\"font-size: 14px; color: #444; margin-bottom: 8px; padding-left: 68px;\">\n ${issue.suggestion || ''}\n </div>\n `;\n \n if (issue.fixable) {\n const fixBtn = document.createElement('button');\n fixBtn.textContent = `🔧 ${issue.fixLabel || 'Auto-fix'}`;\n fixBtn.style.cssText = `\n background: #2196f3;\n color: white;\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n margin-left: 68px;\n `;\n fixBtn.onmouseover = () => fixBtn.style.background = '#1976d2';\n fixBtn.onmouseout = () => fixBtn.style.background = '#2196f3';\n fixBtn.onclick = () => {\n autoFixA11yIssue(issue);\n fixBtn.textContent = '✓ Fixed';\n fixBtn.style.background = '#4caf50';\n fixBtn.disabled = true;\n fixBtn.style.cursor = 'not-allowed';\n highlightIssue(issue, false);\n setTimeout(() => {\n overlay.remove();\n // Re-open dialog with updated issues\n createA11yDialog();\n }, 1000);\n };\n issueItem.appendChild(fixBtn);\n }\n \n content.appendChild(issueItem);\n });\n }\n \n dialog.appendChild(header);\n dialog.appendChild(content);\n overlay.appendChild(dialog);\n document.body.appendChild(overlay);\n \n // Close on overlay click\n overlay.onclick = (e) => {\n if (e.target === overlay) {\n issues.forEach(issue => highlightIssue(issue, false));\n overlay.remove();\n }\n };\n \n // Close on ESC key\n const escHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n issues.forEach(issue => highlightIssue(issue, false));\n overlay.remove();\n document.removeEventListener('keydown', escHandler);\n }\n };\n document.addEventListener('keydown', escHandler);\n};\n\nexport const A11yCheckerPlugin = (): Plugin => ({\n name: 'a11yChecker',\n \n toolbar: [\n {\n label: 'Accessibility',\n command: 'toggleA11yChecker',\n 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>',\n shortcut: 'Mod-Shift-Alt-a'\n }\n ],\n \n commands: {\n toggleA11yChecker: () => {\n try {\n createA11yDialog();\n return true;\n } catch (error) {\n console.error('Failed to open accessibility checker:', error);\n return false;\n }\n }\n },\n \n keymap: {\n 'Mod-Shift-Alt-a': 'toggleA11yChecker'\n }\n});\n"],"names":["suppressedRules","ruleRegistry","registerA11yRule","rule","node","ctx","_a","img","issue","el","hasText","hasAriaLabel","hasAriaLabelledBy","hasTitle","hasLabel","table","headers","rows","firstRow","cell","th","heading","text","onlyBr","currentLevel","previousLevel","_b","link","vagueText","vt","list","items","child","findActiveEditor","selection","element","activeElement","editor","runA11yAudit","_c","issues","walker","idxMap","pathMap","nodeIdx","tag","highlightIssue","highlight","getA11yScore","errors","i","warnings","score","autoFixA11yIssue","r","suppressRule","ruleId","unsuppressRule","createA11yDialog","overlay","dialog","header","title","scoreDisplay","closeBtn","headerLeft","content","summary","infos","issueItem","severityColor","fixBtn","e","escHandler","A11yCheckerPlugin","error"],"mappings":"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"}
|