@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
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { f as A, g as S } from "./editorContainerHelpers-C7kdWnS0.mjs";
|
|
2
|
+
const b = /* @__PURE__ */ new Set();
|
|
3
|
+
function D() {
|
|
4
|
+
if (typeof window == "undefined" || window.__anchorObserverInitialized) return;
|
|
5
|
+
window.__anchorObserverInitialized = !0, new MutationObserver((l) => {
|
|
6
|
+
l.forEach((s) => {
|
|
7
|
+
s.removedNodes.forEach((i) => {
|
|
8
|
+
var a, d;
|
|
9
|
+
if (i.nodeType === Node.ELEMENT_NODE) {
|
|
10
|
+
const o = i;
|
|
11
|
+
if ((a = o.classList) != null && a.contains("rte-anchor")) {
|
|
12
|
+
const u = o.id;
|
|
13
|
+
u && b.delete(u);
|
|
14
|
+
}
|
|
15
|
+
const p = (d = o.querySelectorAll) == null ? void 0 : d.call(o, ".rte-anchor");
|
|
16
|
+
p == null || p.forEach((u) => {
|
|
17
|
+
const c = u.id;
|
|
18
|
+
c && b.delete(c);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}).observe(document.body, {
|
|
24
|
+
childList: !0,
|
|
25
|
+
subtree: !0
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function E(t) {
|
|
29
|
+
return !t || t.trim().length === 0 ? { valid: !1, error: "Anchor ID cannot be empty" } : t.length > 256 ? { valid: !1, error: "Anchor ID must be less than 256 characters" } : /^[a-z_]/.test(t) ? /^[a-z0-9\-_]+$/.test(t) ? { valid: !0, error: "" } : { valid: !1, error: "Anchor ID can only contain letters, numbers, hyphens, and underscores" } : { valid: !1, error: "Anchor ID must start with a letter or underscore" };
|
|
30
|
+
}
|
|
31
|
+
function I() {
|
|
32
|
+
const t = A();
|
|
33
|
+
if (!t) return;
|
|
34
|
+
const l = S(t);
|
|
35
|
+
if (!l) return;
|
|
36
|
+
const s = l.querySelectorAll(".rte-anchor"), i = /* @__PURE__ */ new Set();
|
|
37
|
+
s.forEach((a) => {
|
|
38
|
+
const d = a.id;
|
|
39
|
+
d && i.add(d);
|
|
40
|
+
}), b.clear(), i.forEach((a) => b.add(a));
|
|
41
|
+
}
|
|
42
|
+
function R(t, l, s, i) {
|
|
43
|
+
I();
|
|
44
|
+
const a = document.createElement("div");
|
|
45
|
+
a.className = "rte-anchor-dialog-overlay", a.style.cssText = `
|
|
46
|
+
position: fixed;
|
|
47
|
+
top: 0;
|
|
48
|
+
left: 0;
|
|
49
|
+
right: 0;
|
|
50
|
+
bottom: 0;
|
|
51
|
+
background: rgba(0, 0, 0, 0.5);
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
justify-content: center;
|
|
55
|
+
z-index: 10000;
|
|
56
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
57
|
+
`;
|
|
58
|
+
const d = document.createElement("div");
|
|
59
|
+
if (d.className = "rte-anchor-dialog", d.style.cssText = `
|
|
60
|
+
background: white;
|
|
61
|
+
border-radius: 8px;
|
|
62
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
|
63
|
+
width: 90%;
|
|
64
|
+
max-width: 450px;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
animation: rte-anchor-dialog-appear 0.2s ease;
|
|
67
|
+
`, !document.getElementById("rte-anchor-dialog-styles")) {
|
|
68
|
+
const r = document.createElement("style");
|
|
69
|
+
r.id = "rte-anchor-dialog-styles", r.textContent = `
|
|
70
|
+
@keyframes rte-anchor-dialog-appear {
|
|
71
|
+
from { opacity: 0; transform: scale(0.95); }
|
|
72
|
+
to { opacity: 1; transform: scale(1); }
|
|
73
|
+
}
|
|
74
|
+
.rte-anchor-dialog input:focus {
|
|
75
|
+
outline: none !important;
|
|
76
|
+
}
|
|
77
|
+
`, document.head.appendChild(r);
|
|
78
|
+
}
|
|
79
|
+
let o = "";
|
|
80
|
+
const p = document.createElement("div");
|
|
81
|
+
p.style.cssText = `
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
justify-content: space-between;
|
|
85
|
+
padding: 16px 20px;
|
|
86
|
+
border-bottom: 1px solid #e0e0e0;
|
|
87
|
+
background: #f9f9f9;
|
|
88
|
+
`;
|
|
89
|
+
const u = document.createElement("h3");
|
|
90
|
+
u.style.cssText = "margin: 0; font-size: 18px; font-weight: 600; color: #333;", u.textContent = "Add Anchor";
|
|
91
|
+
const c = document.createElement("button");
|
|
92
|
+
c.textContent = "✕", c.style.cssText = `
|
|
93
|
+
background: none;
|
|
94
|
+
border: none;
|
|
95
|
+
font-size: 24px;
|
|
96
|
+
color: #999;
|
|
97
|
+
cursor: pointer;
|
|
98
|
+
padding: 0;
|
|
99
|
+
width: 32px;
|
|
100
|
+
height: 32px;
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
justify-content: center;
|
|
104
|
+
border-radius: 4px;
|
|
105
|
+
transition: all 0.2s ease;
|
|
106
|
+
`, c.onmouseover = () => {
|
|
107
|
+
c.style.background = "#e0e0e0", c.style.color = "#333";
|
|
108
|
+
}, c.onmouseout = () => {
|
|
109
|
+
c.style.background = "none", c.style.color = "#999";
|
|
110
|
+
}, p.appendChild(u), p.appendChild(c);
|
|
111
|
+
const w = document.createElement("div");
|
|
112
|
+
w.style.cssText = "padding: 20px;";
|
|
113
|
+
const y = document.createElement("div");
|
|
114
|
+
y.style.cssText = "margin-bottom: 0;";
|
|
115
|
+
const m = document.createElement("label");
|
|
116
|
+
m.textContent = "Anchor ID", m.style.cssText = "display: block; font-size: 14px; font-weight: 500; color: #333; margin-bottom: 8px;", m.setAttribute("for", "anchor-id-input");
|
|
117
|
+
const e = document.createElement("input");
|
|
118
|
+
e.id = "anchor-id-input", e.type = "text", e.placeholder = "e.g., section-introduction", e.value = "", e.style.cssText = `
|
|
119
|
+
width: 100%;
|
|
120
|
+
padding: 10px 12px;
|
|
121
|
+
font-size: 14px;
|
|
122
|
+
border: 1px solid #d0d0d0;
|
|
123
|
+
border-radius: 4px;
|
|
124
|
+
font-family: 'Courier New', monospace;
|
|
125
|
+
transition: all 0.2s ease;
|
|
126
|
+
box-sizing: border-box;
|
|
127
|
+
`;
|
|
128
|
+
const f = document.createElement("div");
|
|
129
|
+
f.style.cssText = `
|
|
130
|
+
color: #d32f2f;
|
|
131
|
+
font-size: 12px;
|
|
132
|
+
margin-top: 6px;
|
|
133
|
+
display: none;
|
|
134
|
+
`;
|
|
135
|
+
const v = document.createElement("div");
|
|
136
|
+
v.textContent = "URL-safe ID (letters, numbers, hyphens, underscores). Must start with letter or underscore.", v.style.cssText = "color: #999; font-size: 12px; margin-top: 8px; line-height: 1.4;", y.appendChild(m), y.appendChild(e), y.appendChild(f), y.appendChild(v), w.appendChild(y);
|
|
137
|
+
const x = document.createElement("div");
|
|
138
|
+
x.style.cssText = `
|
|
139
|
+
display: flex;
|
|
140
|
+
gap: 12px;
|
|
141
|
+
padding: 16px 20px;
|
|
142
|
+
border-top: 1px solid #e0e0e0;
|
|
143
|
+
background: #f9f9f9;
|
|
144
|
+
justify-content: flex-end;
|
|
145
|
+
`;
|
|
146
|
+
const h = document.createElement("button");
|
|
147
|
+
h.textContent = "Cancel", h.style.cssText = `
|
|
148
|
+
padding: 8px 16px;
|
|
149
|
+
font-size: 14px;
|
|
150
|
+
font-weight: 500;
|
|
151
|
+
border: none;
|
|
152
|
+
border-radius: 4px;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
transition: all 0.2s ease;
|
|
155
|
+
background: #f0f0f0;
|
|
156
|
+
color: #333;
|
|
157
|
+
`, h.onmouseover = () => h.style.background = "#e0e0e0", h.onmouseout = () => h.style.background = "#f0f0f0";
|
|
158
|
+
const n = document.createElement("button");
|
|
159
|
+
n.textContent = "Add Anchor", n.style.cssText = `
|
|
160
|
+
padding: 8px 16px;
|
|
161
|
+
font-size: 14px;
|
|
162
|
+
font-weight: 500;
|
|
163
|
+
border: none;
|
|
164
|
+
border-radius: 4px;
|
|
165
|
+
cursor: pointer;
|
|
166
|
+
transition: all 0.2s ease;
|
|
167
|
+
background: #0066cc;
|
|
168
|
+
color: white;
|
|
169
|
+
`, n.disabled = !e.value.trim();
|
|
170
|
+
const T = () => {
|
|
171
|
+
e.value.trim() ? (n.disabled = !1, n.style.background = "#0066cc", n.style.color = "white", n.style.cursor = "pointer") : (n.disabled = !0, n.style.background = "#d0d0d0", n.style.color = "#999", n.style.cursor = "not-allowed");
|
|
172
|
+
};
|
|
173
|
+
n.onmouseover = () => {
|
|
174
|
+
n.disabled || (n.style.background = "#0052a3", n.style.boxShadow = "0 2px 8px rgba(0, 102, 204, 0.3)");
|
|
175
|
+
}, n.onmouseout = () => {
|
|
176
|
+
n.disabled || (n.style.background = "#0066cc", n.style.boxShadow = "none");
|
|
177
|
+
}, x.appendChild(h), x.appendChild(n), e.oninput = () => {
|
|
178
|
+
const r = e.value;
|
|
179
|
+
if (T(), r.trim()) {
|
|
180
|
+
const C = E(r);
|
|
181
|
+
C.valid ? b.has(r) ? (o = `Anchor ID already exists: ${r}`, f.textContent = "⚠ " + o, f.style.display = "block", e.style.borderColor = "#d32f2f", e.style.background = "#ffebee") : (o = "", f.style.display = "none", e.style.borderColor = "#d0d0d0", e.style.background = "white") : (o = C.error, f.textContent = "⚠ " + o, f.style.display = "block", e.style.borderColor = "#d32f2f", e.style.background = "#ffebee");
|
|
182
|
+
} else
|
|
183
|
+
f.style.display = "none", e.style.borderColor = "#d0d0d0", e.style.background = "white";
|
|
184
|
+
}, e.onfocus = () => {
|
|
185
|
+
e.style.borderColor = o ? "#d32f2f" : "#0066cc", e.style.boxShadow = o ? "0 0 0 3px rgba(211, 47, 47, 0.1)" : "0 0 0 3px rgba(0, 102, 204, 0.1)", e.style.background = o ? "#ffebee" : "#f9f9ff";
|
|
186
|
+
}, e.onblur = () => {
|
|
187
|
+
e.style.boxShadow = "none", o || (e.style.background = "white");
|
|
188
|
+
};
|
|
189
|
+
const k = () => {
|
|
190
|
+
const r = e.value.trim();
|
|
191
|
+
!r || !E(r).valid || b.has(r) || (s && s(r), a.remove());
|
|
192
|
+
}, g = () => {
|
|
193
|
+
a.remove();
|
|
194
|
+
};
|
|
195
|
+
n.onclick = k, h.onclick = g, c.onclick = g, e.onkeydown = (r) => {
|
|
196
|
+
r.key === "Enter" ? (r.preventDefault(), k()) : r.key === "Escape" && (r.preventDefault(), g());
|
|
197
|
+
}, a.onclick = (r) => {
|
|
198
|
+
r.target === a && g();
|
|
199
|
+
}, d.appendChild(p), d.appendChild(w), d.appendChild(x), a.appendChild(d), document.body.appendChild(a), setTimeout(() => e.focus(), 100);
|
|
200
|
+
}
|
|
201
|
+
function N(t, l) {
|
|
202
|
+
let s;
|
|
203
|
+
if (l)
|
|
204
|
+
s = l;
|
|
205
|
+
else {
|
|
206
|
+
const o = window.getSelection();
|
|
207
|
+
if (!o || o.rangeCount === 0) return;
|
|
208
|
+
s = o.getRangeAt(0);
|
|
209
|
+
}
|
|
210
|
+
const i = document.createElement("span");
|
|
211
|
+
i.id = t, i.className = "rte-anchor", i.setAttribute("data-type", "anchor"), i.setAttribute("data-anchor-id", t), i.setAttribute("title", `Anchor: ${t}`), i.style.cssText = `
|
|
212
|
+
display: inline;
|
|
213
|
+
position: relative;
|
|
214
|
+
cursor: pointer;
|
|
215
|
+
`, s.insertNode(i), b.add(t), s.setStart(i.nextSibling || i.parentNode, 0), s.collapse(!0);
|
|
216
|
+
const a = window.getSelection();
|
|
217
|
+
a && (a.removeAllRanges(), a.addRange(s));
|
|
218
|
+
const d = A();
|
|
219
|
+
if (d) {
|
|
220
|
+
const o = S(d);
|
|
221
|
+
o && o.dispatchEvent(new Event("input", { bubbles: !0 }));
|
|
222
|
+
}
|
|
223
|
+
z();
|
|
224
|
+
}
|
|
225
|
+
function z() {
|
|
226
|
+
if (document.getElementById("rte-anchor-styles")) return;
|
|
227
|
+
const t = document.createElement("style");
|
|
228
|
+
t.id = "rte-anchor-styles", t.textContent = `
|
|
229
|
+
.rte-anchor {
|
|
230
|
+
display: inline;
|
|
231
|
+
position: relative;
|
|
232
|
+
cursor: pointer;
|
|
233
|
+
transition: all 0.2s ease;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.rte-anchor:hover::before {
|
|
237
|
+
content: '⚓';
|
|
238
|
+
position: absolute;
|
|
239
|
+
top: -1.2em;
|
|
240
|
+
left: 0;
|
|
241
|
+
background: #333;
|
|
242
|
+
color: #fff;
|
|
243
|
+
padding: 2px 6px;
|
|
244
|
+
border-radius: 3px;
|
|
245
|
+
font-size: 0.8em;
|
|
246
|
+
white-space: nowrap;
|
|
247
|
+
z-index: 100;
|
|
248
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.rte-anchor:hover::after {
|
|
252
|
+
content: attr(data-anchor-id);
|
|
253
|
+
position: absolute;
|
|
254
|
+
top: -1.2em;
|
|
255
|
+
left: 1.4em;
|
|
256
|
+
background: #333;
|
|
257
|
+
color: #fff;
|
|
258
|
+
padding: 2px 6px;
|
|
259
|
+
border-radius: 3px;
|
|
260
|
+
font-size: 0.75em;
|
|
261
|
+
font-family: 'Courier New', monospace;
|
|
262
|
+
white-space: nowrap;
|
|
263
|
+
z-index: 100;
|
|
264
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
[contenteditable='true'] .rte-anchor::before {
|
|
268
|
+
content: '';
|
|
269
|
+
position: absolute;
|
|
270
|
+
width: 8px;
|
|
271
|
+
height: 8px;
|
|
272
|
+
background: #0066cc;
|
|
273
|
+
border-radius: 50%;
|
|
274
|
+
top: -3px;
|
|
275
|
+
left: 0;
|
|
276
|
+
opacity: 0.5;
|
|
277
|
+
transition: opacity 0.2s ease;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
[contenteditable='true'] .rte-anchor:hover::before {
|
|
281
|
+
opacity: 1;
|
|
282
|
+
width: auto;
|
|
283
|
+
height: auto;
|
|
284
|
+
background: #333;
|
|
285
|
+
border-radius: 3px;
|
|
286
|
+
top: -1.2em;
|
|
287
|
+
padding: 2px 6px;
|
|
288
|
+
font-size: 0.8em;
|
|
289
|
+
content: '⚓';
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
@media print {
|
|
293
|
+
.rte-anchor::before,
|
|
294
|
+
.rte-anchor::after {
|
|
295
|
+
display: none;
|
|
296
|
+
}
|
|
297
|
+
.rte-anchor {
|
|
298
|
+
cursor: auto;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.rte-anchor:focus {
|
|
303
|
+
outline: 2px solid #0066cc;
|
|
304
|
+
outline-offset: 2px;
|
|
305
|
+
}
|
|
306
|
+
`, document.head.appendChild(t);
|
|
307
|
+
}
|
|
308
|
+
const _ = () => (typeof window != "undefined" && (D(), z()), {
|
|
309
|
+
name: "anchor",
|
|
310
|
+
toolbar: [
|
|
311
|
+
{
|
|
312
|
+
label: "Anchor",
|
|
313
|
+
command: "insertAnchor",
|
|
314
|
+
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 d="M12 8.4C13.4912 8.4 14.7 7.19117 14.7 5.7C14.7 4.20883 13.4912 3 12 3C10.5088 3 9.3 4.20883 9.3 5.7C9.3 7.19117 10.5088 8.4 12 8.4ZM12 8.4V20.9999M12 20.9999C9.61305 20.9999 7.32387 20.0518 5.63604 18.364C3.94821 16.6761 3 14.3869 3 12H5M12 20.9999C14.3869 20.9999 16.6761 20.0518 18.364 18.364C20.0518 16.6761 21 14.3869 21 12H19" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg>',
|
|
315
|
+
shortcut: "Mod-Shift-k"
|
|
316
|
+
}
|
|
317
|
+
],
|
|
318
|
+
commands: {
|
|
319
|
+
insertAnchor: () => {
|
|
320
|
+
try {
|
|
321
|
+
const t = window.getSelection();
|
|
322
|
+
if (!t || t.rangeCount === 0)
|
|
323
|
+
return alert("Please place your cursor where you want to insert the anchor."), !1;
|
|
324
|
+
const l = t.getRangeAt(0).cloneRange();
|
|
325
|
+
return R("add", "", (s) => {
|
|
326
|
+
N(s, l);
|
|
327
|
+
}, l), !0;
|
|
328
|
+
} catch (t) {
|
|
329
|
+
return console.error("Failed to insert anchor:", t), !1;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
keymap: {
|
|
334
|
+
"Mod-Shift-k": "insertAnchor"
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
export {
|
|
338
|
+
_ as AnchorPlugin
|
|
339
|
+
};
|
|
340
|
+
//# sourceMappingURL=AnchorPlugin.native-7es9PVZ9.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnchorPlugin.native-7es9PVZ9.mjs","sources":["../../plugins/anchor/src/AnchorPlugin.native.ts"],"sourcesContent":["import type { Plugin } from '@editora/core';\nimport { findEditorContainerFromSelection, getContentElement } from '../../shared/editorContainerHelpers';\n\n/**\n * AnchorPlugin - Native implementation with complete UI/UX dialog\n * \n * Creates named navigation targets with:\n * - ID uniqueness enforcement\n * - Automatic ID validation and sanitization\n * - URL-safe ID generation\n * - Duplicate collision detection\n * - Reference update on rename\n * - Safe deletion handling\n * - Full UI dialog for adding/editing anchors\n * - Visual hover indicators\n * - Registry sync with DOM\n * \n * Features:\n * - Add/Edit/Delete anchors with dialog\n * - ID validation (URL-safe, unique)\n * - Visual indicators on hover\n * - Keyboard shortcuts (ESC, Enter)\n * - Auto-sanitization\n * - Mutation observer for cleanup\n */\n\n// --- Anchor Registry ---\nconst anchorRegistry = new Set<string>();\n\n/**\n * Initialize mutation observer to track anchor deletions\n */\nfunction initializeAnchorObserver() {\n if (typeof window === 'undefined') return;\n if ((window as any).__anchorObserverInitialized) return;\n \n (window as any).__anchorObserverInitialized = true;\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.removedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n \n if (element.classList?.contains('rte-anchor')) {\n const anchorId = element.id;\n if (anchorId) anchorRegistry.delete(anchorId);\n }\n \n const anchors = element.querySelectorAll?.('.rte-anchor');\n anchors?.forEach((anchor: Element) => {\n const anchorId = (anchor as HTMLElement).id;\n if (anchorId) anchorRegistry.delete(anchorId);\n });\n }\n });\n });\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true\n });\n}\n\n/**\n * Generate unique anchor ID\n */\nfunction generateUniqueId(): string {\n let id: string;\n let counter = 0;\n\n do {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substr(2, 9);\n id = `anchor-${timestamp}-${random}`;\n counter++;\n if (counter > 100) return '';\n } while (anchorRegistry.has(id));\n\n return id;\n}\n\n/**\n * Sanitize and validate anchor ID\n */\nfunction sanitizeId(id: string): string {\n return id\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\-_]/g, '-')\n .replace(/^[^a-z_]/, `a-${Math.random().toString(36).substr(2, 5)}`)\n .substring(0, 256);\n}\n\n/**\n * Validate anchor ID\n */\nfunction validateId(id: string): { valid: boolean; error: string } {\n if (!id || id.trim().length === 0) {\n return { valid: false, error: 'Anchor ID cannot be empty' };\n }\n\n if (id.length > 256) {\n return { valid: false, error: 'Anchor ID must be less than 256 characters' };\n }\n\n if (!/^[a-z_]/.test(id)) {\n return { valid: false, error: 'Anchor ID must start with a letter or underscore' };\n }\n\n if (!/^[a-z0-9\\-_]+$/.test(id)) {\n return { valid: false, error: 'Anchor ID can only contain letters, numbers, hyphens, and underscores' };\n }\n\n return { valid: true, error: '' };\n}\n\n/**\n * Sync anchor registry with DOM (multi-instance safe)\n */\nfunction syncAnchorRegistry() {\n const editorContainer = findEditorContainerFromSelection();\n if (!editorContainer) return;\n \n const editor = getContentElement(editorContainer);\n if (!editor) return;\n \n const anchors = editor.querySelectorAll('.rte-anchor');\n const domAnchors = new Set<string>();\n\n anchors.forEach((anchor) => {\n const id = (anchor as HTMLElement).id;\n if (id) domAnchors.add(id);\n });\n\n anchorRegistry.clear();\n domAnchors.forEach((id) => anchorRegistry.add(id));\n}\n\n/**\n * Create Anchor Dialog\n */\nfunction createAnchorDialog(mode: 'add' | 'edit', currentId?: string, onSave?: (id: string) => void, savedRange?: Range) {\n // Sync registry before showing dialog\n syncAnchorRegistry();\n \n // Create overlay\n const overlay = document.createElement('div');\n overlay.className = 'rte-anchor-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 display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n `;\n \n // Create dialog\n const dialog = document.createElement('div');\n dialog.className = 'rte-anchor-dialog';\n dialog.style.cssText = `\n background: white;\n border-radius: 8px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);\n width: 90%;\n max-width: 450px;\n overflow: hidden;\n animation: rte-anchor-dialog-appear 0.2s ease;\n `;\n \n // Add animation keyframes\n if (!document.getElementById('rte-anchor-dialog-styles')) {\n const style = document.createElement('style');\n style.id = 'rte-anchor-dialog-styles';\n style.textContent = `\n @keyframes rte-anchor-dialog-appear {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n }\n .rte-anchor-dialog input:focus {\n outline: none !important;\n }\n `;\n document.head.appendChild(style);\n }\n \n let errorMessage = '';\n let touched = false;\n \n // Header\n const header = document.createElement('div');\n header.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid #e0e0e0;\n background: #f9f9f9;\n `;\n \n const title = document.createElement('h3');\n title.style.cssText = 'margin: 0; font-size: 18px; font-weight: 600; color: #333;';\n title.textContent = mode === 'add' ? 'Add Anchor' : 'Edit Anchor';\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 color: #999;\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 transition: all 0.2s ease;\n `;\n closeBtn.onmouseover = () => { closeBtn.style.background = '#e0e0e0'; closeBtn.style.color = '#333'; };\n closeBtn.onmouseout = () => { closeBtn.style.background = 'none'; closeBtn.style.color = '#999'; };\n \n header.appendChild(title);\n header.appendChild(closeBtn);\n \n // Body\n const body = document.createElement('div');\n body.style.cssText = 'padding: 20px;';\n \n const field = document.createElement('div');\n field.style.cssText = 'margin-bottom: 0;';\n \n const label = document.createElement('label');\n label.textContent = 'Anchor ID';\n label.style.cssText = 'display: block; font-size: 14px; font-weight: 500; color: #333; margin-bottom: 8px;';\n label.setAttribute('for', 'anchor-id-input');\n \n const input = document.createElement('input');\n input.id = 'anchor-id-input';\n input.type = 'text';\n input.placeholder = 'e.g., section-introduction';\n input.value = currentId || '';\n input.style.cssText = `\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n border: 1px solid #d0d0d0;\n border-radius: 4px;\n font-family: 'Courier New', monospace;\n transition: all 0.2s ease;\n box-sizing: border-box;\n `;\n \n const errorDiv = document.createElement('div');\n errorDiv.style.cssText = `\n color: #d32f2f;\n font-size: 12px;\n margin-top: 6px;\n display: none;\n `;\n \n const helpText = document.createElement('div');\n helpText.textContent = 'URL-safe ID (letters, numbers, hyphens, underscores). Must start with letter or underscore.';\n helpText.style.cssText = 'color: #999; font-size: 12px; margin-top: 8px; line-height: 1.4;';\n \n field.appendChild(label);\n field.appendChild(input);\n field.appendChild(errorDiv);\n field.appendChild(helpText);\n body.appendChild(field);\n \n // Footer\n const footer = document.createElement('div');\n footer.style.cssText = `\n display: flex;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid #e0e0e0;\n background: #f9f9f9;\n justify-content: flex-end;\n `;\n \n const cancelBtn = document.createElement('button');\n cancelBtn.textContent = 'Cancel';\n cancelBtn.style.cssText = `\n padding: 8px 16px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n background: #f0f0f0;\n color: #333;\n `;\n cancelBtn.onmouseover = () => cancelBtn.style.background = '#e0e0e0';\n cancelBtn.onmouseout = () => cancelBtn.style.background = '#f0f0f0';\n \n const saveBtn = document.createElement('button');\n saveBtn.textContent = mode === 'add' ? 'Add Anchor' : 'Save Changes';\n saveBtn.style.cssText = `\n padding: 8px 16px;\n font-size: 14px;\n font-weight: 500;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n transition: all 0.2s ease;\n background: #0066cc;\n color: white;\n `;\n saveBtn.disabled = !input.value.trim();\n \n const updateSaveButton = () => {\n if (!input.value.trim()) {\n saveBtn.disabled = true;\n saveBtn.style.background = '#d0d0d0';\n saveBtn.style.color = '#999';\n saveBtn.style.cursor = 'not-allowed';\n } else {\n saveBtn.disabled = false;\n saveBtn.style.background = '#0066cc';\n saveBtn.style.color = 'white';\n saveBtn.style.cursor = 'pointer';\n }\n };\n \n saveBtn.onmouseover = () => {\n if (!saveBtn.disabled) {\n saveBtn.style.background = '#0052a3';\n saveBtn.style.boxShadow = '0 2px 8px rgba(0, 102, 204, 0.3)';\n }\n };\n saveBtn.onmouseout = () => {\n if (!saveBtn.disabled) {\n saveBtn.style.background = '#0066cc';\n saveBtn.style.boxShadow = 'none';\n }\n };\n \n footer.appendChild(cancelBtn);\n footer.appendChild(saveBtn);\n \n // Validation on input\n input.oninput = () => {\n touched = true;\n const value = input.value;\n updateSaveButton();\n \n if (value.trim()) {\n const validation = validateId(value);\n if (!validation.valid) {\n errorMessage = validation.error;\n errorDiv.textContent = '⚠ ' + errorMessage;\n errorDiv.style.display = 'block';\n input.style.borderColor = '#d32f2f';\n input.style.background = '#ffebee';\n } else if (mode === 'add' && anchorRegistry.has(value)) {\n errorMessage = `Anchor ID already exists: ${value}`;\n errorDiv.textContent = '⚠ ' + errorMessage;\n errorDiv.style.display = 'block';\n input.style.borderColor = '#d32f2f';\n input.style.background = '#ffebee';\n } else if (mode === 'edit' && value !== currentId && anchorRegistry.has(value)) {\n errorMessage = `Anchor ID already exists: ${value}`;\n errorDiv.textContent = '⚠ ' + errorMessage;\n errorDiv.style.display = 'block';\n input.style.borderColor = '#d32f2f';\n input.style.background = '#ffebee';\n } else {\n errorMessage = '';\n errorDiv.style.display = 'none';\n input.style.borderColor = '#d0d0d0';\n input.style.background = 'white';\n }\n } else {\n errorDiv.style.display = 'none';\n input.style.borderColor = '#d0d0d0';\n input.style.background = 'white';\n }\n };\n \n input.onfocus = () => {\n input.style.borderColor = errorMessage ? '#d32f2f' : '#0066cc';\n input.style.boxShadow = errorMessage \n ? '0 0 0 3px rgba(211, 47, 47, 0.1)' \n : '0 0 0 3px rgba(0, 102, 204, 0.1)';\n input.style.background = errorMessage ? '#ffebee' : '#f9f9ff';\n };\n \n input.onblur = () => {\n input.style.boxShadow = 'none';\n if (!errorMessage) {\n input.style.background = 'white';\n }\n };\n \n // Handle save\n const handleSave = () => {\n const value = input.value.trim();\n if (!value) return;\n \n const validation = validateId(value);\n if (!validation.valid) return;\n \n if (mode === 'add' && anchorRegistry.has(value)) return;\n if (mode === 'edit' && value !== currentId && anchorRegistry.has(value)) return;\n \n if (onSave) onSave(value);\n overlay.remove();\n };\n \n const handleCancel = () => {\n overlay.remove();\n };\n \n saveBtn.onclick = handleSave;\n cancelBtn.onclick = handleCancel;\n closeBtn.onclick = handleCancel;\n \n input.onkeydown = (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleSave();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n handleCancel();\n }\n };\n \n overlay.onclick = (e) => {\n if (e.target === overlay) handleCancel();\n };\n \n // Assemble\n dialog.appendChild(header);\n dialog.appendChild(body);\n dialog.appendChild(footer);\n overlay.appendChild(dialog);\n document.body.appendChild(overlay);\n \n // Auto-focus input\n setTimeout(() => input.focus(), 100);\n}\n\n/**\n * Insert anchor at cursor\n */\nfunction insertAnchor(anchorId: string, savedRange?: Range) {\n let range: Range;\n \n if (savedRange) {\n range = savedRange;\n } else {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n range = selection.getRangeAt(0);\n }\n\n // Create anchor element\n const anchor = document.createElement('span');\n anchor.id = anchorId;\n anchor.className = 'rte-anchor';\n anchor.setAttribute('data-type', 'anchor');\n anchor.setAttribute('data-anchor-id', anchorId);\n anchor.setAttribute('title', `Anchor: ${anchorId}`);\n \n // Add inline styles for visibility\n anchor.style.cssText = `\n display: inline;\n position: relative;\n cursor: pointer;\n `;\n\n range.insertNode(anchor);\n anchorRegistry.add(anchorId);\n\n // Move cursor after anchor\n range.setStart(anchor.nextSibling || anchor.parentNode!, 0);\n range.collapse(true);\n const sel = window.getSelection();\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(range);\n }\n \n // Trigger input event to update editor state\n const editorContainer = findEditorContainerFromSelection();\n if (editorContainer) {\n const contentElement = getContentElement(editorContainer);\n if (contentElement) {\n contentElement.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n \n // Add hover CSS if not already present\n addAnchorStyles();\n}\n\n/**\n * Add anchor hover styles\n */\nfunction addAnchorStyles() {\n if (document.getElementById('rte-anchor-styles')) return;\n \n const style = document.createElement('style');\n style.id = 'rte-anchor-styles';\n style.textContent = `\n .rte-anchor {\n display: inline;\n position: relative;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n \n .rte-anchor:hover::before {\n content: '⚓';\n position: absolute;\n top: -1.2em;\n left: 0;\n background: #333;\n color: #fff;\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 0.8em;\n white-space: nowrap;\n z-index: 100;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n }\n \n .rte-anchor:hover::after {\n content: attr(data-anchor-id);\n position: absolute;\n top: -1.2em;\n left: 1.4em;\n background: #333;\n color: #fff;\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 0.75em;\n font-family: 'Courier New', monospace;\n white-space: nowrap;\n z-index: 100;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n }\n \n [contenteditable='true'] .rte-anchor::before {\n content: '';\n position: absolute;\n width: 8px;\n height: 8px;\n background: #0066cc;\n border-radius: 50%;\n top: -3px;\n left: 0;\n opacity: 0.5;\n transition: opacity 0.2s ease;\n }\n \n [contenteditable='true'] .rte-anchor:hover::before {\n opacity: 1;\n width: auto;\n height: auto;\n background: #333;\n border-radius: 3px;\n top: -1.2em;\n padding: 2px 6px;\n font-size: 0.8em;\n content: '⚓';\n }\n \n @media print {\n .rte-anchor::before,\n .rte-anchor::after {\n display: none;\n }\n .rte-anchor {\n cursor: auto;\n }\n }\n \n .rte-anchor:focus {\n outline: 2px solid #0066cc;\n outline-offset: 2px;\n }\n `;\n document.head.appendChild(style);\n}\n\nexport const AnchorPlugin = (): Plugin => {\n // Initialize observer\n if (typeof window !== 'undefined') {\n initializeAnchorObserver();\n addAnchorStyles();\n }\n\n return {\n name: \"anchor\",\n\n toolbar: [\n {\n label: \"Anchor\",\n command: \"insertAnchor\",\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 d=\"M12 8.4C13.4912 8.4 14.7 7.19117 14.7 5.7C14.7 4.20883 13.4912 3 12 3C10.5088 3 9.3 4.20883 9.3 5.7C9.3 7.19117 10.5088 8.4 12 8.4ZM12 8.4V20.9999M12 20.9999C9.61305 20.9999 7.32387 20.0518 5.63604 18.364C3.94821 16.6761 3 14.3869 3 12H5M12 20.9999C14.3869 20.9999 16.6761 20.0518 18.364 18.364C20.0518 16.6761 21 14.3869 21 12H19\" stroke=\"#000000\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path> </g></svg>',\n shortcut: 'Mod-Shift-k'\n },\n ],\n\n commands: {\n insertAnchor: () => {\n try {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) {\n alert('Please place your cursor where you want to insert the anchor.');\n return false;\n }\n \n const savedRange = selection.getRangeAt(0).cloneRange();\n \n createAnchorDialog('add', '', (anchorId) => {\n insertAnchor(anchorId, savedRange);\n }, savedRange);\n return true;\n } catch (error) {\n console.error('Failed to insert anchor:', error);\n return false;\n }\n },\n },\n\n keymap: {\n 'Mod-Shift-k': 'insertAnchor',\n },\n };\n};\n"],"names":["anchorRegistry","initializeAnchorObserver","mutations","mutation","node","element","_a","anchorId","anchors","_b","anchor","validateId","id","syncAnchorRegistry","editorContainer","findEditorContainerFromSelection","editor","getContentElement","domAnchors","createAnchorDialog","mode","currentId","onSave","savedRange","overlay","dialog","style","errorMessage","header","title","closeBtn","body","field","label","input","errorDiv","helpText","footer","cancelBtn","saveBtn","updateSaveButton","value","validation","handleSave","handleCancel","e","insertAnchor","range","selection","sel","contentElement","addAnchorStyles","AnchorPlugin","error"],"mappings":"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"}
|