@editora/core 1.0.1 → 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.
Files changed (121) hide show
  1. package/README.md +9 -0
  2. package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs +475 -0
  3. package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs.map +1 -0
  4. package/dist/AnchorPlugin.native-7es9PVZ9.mjs +340 -0
  5. package/dist/AnchorPlugin.native-7es9PVZ9.mjs.map +1 -0
  6. package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs +449 -0
  7. package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs.map +1 -0
  8. package/dist/BlockquotePlugin.native-JFmOLsxN.mjs +48 -0
  9. package/dist/BlockquotePlugin.native-JFmOLsxN.mjs.map +1 -0
  10. package/dist/BoldPlugin.native-BAzzoqU5.mjs +45 -0
  11. package/dist/BoldPlugin.native-BAzzoqU5.mjs.map +1 -0
  12. package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs +79 -0
  13. package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs.map +1 -0
  14. package/dist/ChecklistPlugin.native-Dccs3nLe.mjs +153 -0
  15. package/dist/ChecklistPlugin.native-Dccs3nLe.mjs.map +1 -0
  16. package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs +27 -0
  17. package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs.map +1 -0
  18. package/dist/CodePlugin.native-DD9xFIid.mjs +1679 -0
  19. package/dist/CodePlugin.native-DD9xFIid.mjs.map +1 -0
  20. package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs +326 -0
  21. package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs.map +1 -0
  22. package/dist/CommentsPlugin.native-2zQV8Ia4.mjs +473 -0
  23. package/dist/CommentsPlugin.native-2zQV8Ia4.mjs.map +1 -0
  24. package/dist/DirectionPlugin.native-Be7wCzkI.mjs +59 -0
  25. package/dist/DirectionPlugin.native-Be7wCzkI.mjs.map +1 -0
  26. package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs +116 -0
  27. package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs.map +1 -0
  28. package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs +461 -0
  29. package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs.map +1 -0
  30. package/dist/EmojisPlugin.native-D6mJSnSR.mjs +1033 -0
  31. package/dist/EmojisPlugin.native-D6mJSnSR.mjs.map +1 -0
  32. package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs +106 -0
  33. package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs.map +1 -0
  34. package/dist/FontSizePlugin.native-DkLMLPue.mjs +186 -0
  35. package/dist/FontSizePlugin.native-DkLMLPue.mjs.map +1 -0
  36. package/dist/FootnotePlugin.native-BciVc9W6.mjs +128 -0
  37. package/dist/FootnotePlugin.native-BciVc9W6.mjs.map +1 -0
  38. package/dist/FullscreenPlugin.native-ChXyxeNw.mjs +77 -0
  39. package/dist/FullscreenPlugin.native-ChXyxeNw.mjs.map +1 -0
  40. package/dist/HeadingPlugin.native-DrLYwQnQ.mjs +64 -0
  41. package/dist/HeadingPlugin.native-DrLYwQnQ.mjs.map +1 -0
  42. package/dist/HistoryPlugin.native-DoDRifCf.mjs +89 -0
  43. package/dist/HistoryPlugin.native-DoDRifCf.mjs.map +1 -0
  44. package/dist/IndentPlugin.native-CbFugPoi.mjs +133 -0
  45. package/dist/IndentPlugin.native-CbFugPoi.mjs.map +1 -0
  46. package/dist/ItalicPlugin.native-CQjjDyUL.mjs +43 -0
  47. package/dist/ItalicPlugin.native-CQjjDyUL.mjs.map +1 -0
  48. package/dist/LineHeightPlugin.native-CWQT2FIa.mjs +73 -0
  49. package/dist/LineHeightPlugin.native-CWQT2FIa.mjs.map +1 -0
  50. package/dist/LinkPlugin.native-BdAOV-iu.mjs +206 -0
  51. package/dist/LinkPlugin.native-BdAOV-iu.mjs.map +1 -0
  52. package/dist/ListPlugin.native-CLFU5AUQ.mjs +59 -0
  53. package/dist/ListPlugin.native-CLFU5AUQ.mjs.map +1 -0
  54. package/dist/MathPlugin.native-DE_ii-LA.mjs +182 -0
  55. package/dist/MathPlugin.native-DE_ii-LA.mjs.map +1 -0
  56. package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs +533 -0
  57. package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs.map +1 -0
  58. package/dist/MergeTagPlugin.native-CrxyThyn.mjs +178 -0
  59. package/dist/MergeTagPlugin.native-CrxyThyn.mjs.map +1 -0
  60. package/dist/PageBreakPlugin.native-DDjcDyRW.mjs +172 -0
  61. package/dist/PageBreakPlugin.native-DDjcDyRW.mjs.map +1 -0
  62. package/dist/PreviewPlugin.native-DBvfpmIv.mjs +322 -0
  63. package/dist/PreviewPlugin.native-DBvfpmIv.mjs.map +1 -0
  64. package/dist/PrintPlugin.native-BUpm52VJ.mjs +311 -0
  65. package/dist/PrintPlugin.native-BUpm52VJ.mjs.map +1 -0
  66. package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs +731 -0
  67. package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs.map +1 -0
  68. package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs +465 -0
  69. package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs.map +1 -0
  70. package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs +43 -0
  71. package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs.map +1 -0
  72. package/dist/TablePlugin.native-EEWXn1-s.mjs +491 -0
  73. package/dist/TablePlugin.native-EEWXn1-s.mjs.map +1 -0
  74. package/dist/TemplatePlugin.native-BlSn1c9h.mjs +564 -0
  75. package/dist/TemplatePlugin.native-BlSn1c9h.mjs.map +1 -0
  76. package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs +97 -0
  77. package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs.map +1 -0
  78. package/dist/TextColorPlugin.native-D6SmTglm.mjs +432 -0
  79. package/dist/TextColorPlugin.native-D6SmTglm.mjs.map +1 -0
  80. package/dist/UnderlinePlugin.native-QpIcK4L2.mjs +35 -0
  81. package/dist/UnderlinePlugin.native-QpIcK4L2.mjs.map +1 -0
  82. package/dist/documentManager-irzj9n3V.mjs +37627 -0
  83. package/dist/documentManager-irzj9n3V.mjs.map +1 -0
  84. package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
  85. package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
  86. package/dist/editora.min.js +14 -12
  87. package/dist/editora.min.js.map +1 -1
  88. package/dist/editora.umd.js +14 -12
  89. package/dist/editora.umd.js.map +1 -1
  90. package/dist/index-BF5RBhL9.js +4 -0
  91. package/dist/index-BF5RBhL9.js.map +1 -0
  92. package/dist/{index-BS4zT-KN.mjs → index-BPsf460l.mjs} +286 -162
  93. package/dist/index-BPsf460l.mjs.map +1 -0
  94. package/dist/index.cjs.js +3 -3
  95. package/dist/index.cjs.js.map +1 -1
  96. package/dist/index.es-CuicffkQ.mjs +6665 -0
  97. package/dist/index.es-CuicffkQ.mjs.map +1 -0
  98. package/dist/index.esm.js +117 -112
  99. package/dist/index.esm.js.map +1 -1
  100. package/dist/plugin-loader.js +55 -0
  101. package/dist/plugin-loader.js.map +1 -0
  102. package/dist/purify.es-CKpwg8Tk.mjs +471 -0
  103. package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
  104. package/dist/webcomponent-core.js +1243 -0
  105. package/dist/webcomponent-core.js.map +1 -0
  106. package/dist/webcomponent-core.min.css +1 -0
  107. package/dist/webcomponent-core.min.js +597 -0
  108. package/dist/webcomponent-core.min.js.map +1 -0
  109. package/dist/webcomponent.cjs.js +1 -1
  110. package/dist/webcomponent.esm.js +3 -3
  111. package/dist/webcomponent.js +1286 -0
  112. package/dist/webcomponent.js.map +1 -0
  113. package/dist/webcomponent.min.css +1 -0
  114. package/dist/webcomponent.min.js +337 -334
  115. package/dist/webcomponent.min.js.map +1 -1
  116. package/package.json +16 -4
  117. package/dist/index-BK2lHfHK.js +0 -2
  118. package/dist/index-BK2lHfHK.js.map +0 -1
  119. package/dist/index-BS4zT-KN.mjs.map +0 -1
  120. package/dist/webcomponent.umd.js +0 -4073
  121. package/dist/webcomponent.umd.js.map +0 -1
@@ -0,0 +1,473 @@
1
+ const u = /* @__PURE__ */ new Map();
2
+ let x = !1, d = null, C = /* @__PURE__ */ new Set(), v = {}, h = null, p = "";
3
+ const w = "User";
4
+ let y = null;
5
+ function R() {
6
+ return Array.from(u.values());
7
+ }
8
+ function S(e, o, t = !1) {
9
+ if (t) {
10
+ const b = `comment-${Date.now()}`, B = {
11
+ id: b,
12
+ anchorId: "",
13
+ selectedText: "",
14
+ author: e,
15
+ text: o,
16
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
17
+ resolved: !1,
18
+ replies: []
19
+ };
20
+ return u.set(b, B), s(), b;
21
+ }
22
+ const n = window.getSelection();
23
+ if (!n || n.rangeCount === 0) return "";
24
+ const c = h || n.getRangeAt(0), g = c.toString();
25
+ if (!g) return "";
26
+ const a = `comment-${Date.now()}`, f = `comment-anchor-${Date.now()}`, l = document.createElement("span");
27
+ l.id = f, l.className = "rte-comment-anchor", l.setAttribute("data-comment-id", a), l.style.cssText = `
28
+ background-color: #ffeb3b;
29
+ border-bottom: 2px solid #fbc02d;
30
+ cursor: pointer;
31
+ position: relative;
32
+ `, l.title = "Click to view comment";
33
+ const r = c.cloneRange(), i = r.extractContents();
34
+ l.appendChild(i), r.insertNode(l);
35
+ const m = {
36
+ id: a,
37
+ anchorId: f,
38
+ selectedText: g,
39
+ author: e,
40
+ text: o,
41
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
42
+ resolved: !1,
43
+ replies: []
44
+ };
45
+ return u.set(a, m), l.onclick = () => {
46
+ x = !0, k();
47
+ }, s(), h = null, n.removeAllRanges(), a;
48
+ }
49
+ function z(e, o) {
50
+ const t = u.get(e);
51
+ if (t) {
52
+ if (t.resolved = !0, t.resolvedAt = (/* @__PURE__ */ new Date()).toISOString(), t.resolvedBy = o, t.anchorId) {
53
+ const n = document.getElementById(t.anchorId);
54
+ n && (n.style.backgroundColor = "#e0e0e0", n.style.borderBottom = "2px solid #bdbdbd", n.style.opacity = "0.6");
55
+ }
56
+ s();
57
+ }
58
+ }
59
+ function L(e) {
60
+ const o = u.get(e);
61
+ if (o) {
62
+ if (o.resolved = !1, o.resolvedAt = void 0, o.resolvedBy = void 0, o.anchorId) {
63
+ const t = document.getElementById(o.anchorId);
64
+ t && (t.style.backgroundColor = "#ffeb3b", t.style.borderBottom = "2px solid #fbc02d", t.style.opacity = "1");
65
+ }
66
+ s();
67
+ }
68
+ }
69
+ function N(e) {
70
+ const o = u.get(e);
71
+ if (o) {
72
+ if (o.anchorId) {
73
+ const t = document.getElementById(o.anchorId);
74
+ if (t) {
75
+ const n = t.parentNode;
76
+ for (; t.firstChild; )
77
+ n == null || n.insertBefore(t.firstChild, t);
78
+ t.remove();
79
+ }
80
+ }
81
+ u.delete(e), s();
82
+ }
83
+ }
84
+ function T(e, o, t) {
85
+ const n = u.get(e);
86
+ if (!n) return;
87
+ const c = {
88
+ id: `reply-${Date.now()}`,
89
+ author: o,
90
+ text: t,
91
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
92
+ };
93
+ n.replies.push(c), s();
94
+ }
95
+ function E(e, o) {
96
+ const t = u.get(e);
97
+ if (!t || !t.anchorId) return;
98
+ const n = document.getElementById(t.anchorId);
99
+ n && (o ? (n.classList.add("highlighted"), n.style.outline = "2px solid #0066cc", n.style.outlineOffset = "2px") : (n.classList.remove("highlighted"), n.style.outline = "none"));
100
+ }
101
+ function k() {
102
+ if (d) {
103
+ d.style.display = x ? "block" : "none", x ? (s(), I()) : A();
104
+ return;
105
+ }
106
+ const e = document.createElement("div");
107
+ e.className = "rte-comments-panel", d = e, document.body.appendChild(e), s(), I(), V();
108
+ }
109
+ function I() {
110
+ y || (y = () => {
111
+ const e = window.getSelection();
112
+ e && e.rangeCount > 0 && !e.isCollapsed && (h = e.getRangeAt(0).cloneRange());
113
+ }, document.addEventListener("selectionchange", y));
114
+ }
115
+ function A() {
116
+ y && (document.removeEventListener("selectionchange", y), y = null), h = null;
117
+ }
118
+ function s() {
119
+ if (!d) return;
120
+ const e = R();
121
+ d.innerHTML = `
122
+ <div class="comments-header" style="display: flex; justify-content: space-between; align-items: center;">
123
+ <h3 style="margin: 0;">Comments (${e.length})</h3>
124
+ <button class="rte-comments-close" aria-label="Close comments panel">✕</button>
125
+ </div>
126
+
127
+ <div class="comment-add-box">
128
+ <textarea class="new-comment-textarea" placeholder="Add a new comment..." rows="2"></textarea>
129
+ <button class="rte-button-small add-comment-btn">Add Comment</button>
130
+ </div>
131
+
132
+ ${e.length === 0 ? '<div class="comments-empty">No comments yet</div>' : '<div class="comments-list"></div>'}
133
+ `;
134
+ const o = d.querySelector(".rte-comments-close");
135
+ o && o.addEventListener("click", () => {
136
+ x = !1, d && (d.style.display = "none"), A();
137
+ });
138
+ const t = d.querySelector(".new-comment-textarea"), n = d.querySelector(".add-comment-btn");
139
+ if (t && n && (t.value = p, t.oninput = () => {
140
+ p = t.value, n.disabled = !p.trim(), n.style.opacity = p.trim() ? "1" : "0.5";
141
+ }, n.disabled = !p.trim(), n.style.opacity = p.trim() ? "1" : "0.5", n.onclick = () => {
142
+ if (!p.trim()) {
143
+ alert("Comment cannot be empty"), t.focus();
144
+ return;
145
+ }
146
+ h ? S(w, p.trim()) : S(w, p.trim(), !0), p = "", t.value = "", s();
147
+ }), e.length > 0) {
148
+ const c = d.querySelector(".comments-list");
149
+ c && e.forEach((g) => {
150
+ const a = D(g);
151
+ c.appendChild(a);
152
+ });
153
+ }
154
+ }
155
+ function D(e) {
156
+ const o = C.has(e.id), t = document.createElement("div");
157
+ t.className = `comment-item${e.resolved ? " resolved" : ""}`;
158
+ const n = document.createElement("div");
159
+ n.className = "comment-header", n.innerHTML = `
160
+ <div class="comment-meta">
161
+ <strong>${e.author}</strong>
162
+ <span class="comment-date">${new Date(e.createdAt).toLocaleDateString()}</span>
163
+ </div>
164
+ <button class="comment-expand" aria-label="Toggle comment">${o ? "▼" : "▶"}</button>
165
+ `;
166
+ const c = n.querySelector(".comment-expand");
167
+ c && c.addEventListener("click", () => {
168
+ C.has(e.id) ? C.delete(e.id) : C.add(e.id), s();
169
+ }), t.appendChild(n);
170
+ const g = document.createElement("div");
171
+ if (g.className = "comment-text", g.textContent = e.text, t.appendChild(g), e.selectedText) {
172
+ const a = document.createElement("div");
173
+ a.className = "comment-selection", a.textContent = `"${e.selectedText}"`, t.appendChild(a);
174
+ }
175
+ if (o) {
176
+ const a = document.createElement("div");
177
+ if (a.className = "comment-expanded", e.replies.length > 0) {
178
+ const r = document.createElement("div");
179
+ r.className = "comment-replies", e.replies.forEach((i) => {
180
+ const m = document.createElement("div");
181
+ m.className = "comment-reply", m.innerHTML = `
182
+ <div class="reply-header">
183
+ <strong>${i.author}</strong>
184
+ <span class="reply-date">${new Date(i.createdAt).toLocaleDateString()}</span>
185
+ </div>
186
+ <div class="reply-text">${i.text}</div>
187
+ `, r.appendChild(m);
188
+ }), a.appendChild(r);
189
+ }
190
+ if (!e.resolved) {
191
+ const r = document.createElement("div");
192
+ r.className = "comment-reply-input";
193
+ const i = document.createElement("textarea");
194
+ i.placeholder = "Add a reply...", i.rows = 2, i.value = v[e.id] || "", i.oninput = () => {
195
+ v[e.id] = i.value;
196
+ };
197
+ const m = document.createElement("button");
198
+ m.className = "rte-button-small", m.textContent = "Reply", m.onclick = () => {
199
+ var b;
200
+ (b = v[e.id]) != null && b.trim() && (T(e.id, w, v[e.id]), v[e.id] = "", s());
201
+ }, r.appendChild(i), r.appendChild(m), a.appendChild(r);
202
+ }
203
+ const f = document.createElement("div");
204
+ if (f.className = "comment-actions", e.resolved) {
205
+ const r = document.createElement("button");
206
+ r.className = "action-button reopen", r.textContent = "↻ Reopen", r.onclick = () => L(e.id), f.appendChild(r);
207
+ } else {
208
+ const r = document.createElement("button");
209
+ r.className = "action-button resolve", r.textContent = "✓ Resolve", r.onclick = () => z(e.id, w), f.appendChild(r);
210
+ }
211
+ const l = document.createElement("button");
212
+ l.className = "action-button delete", l.textContent = "🗑 Delete", l.onclick = () => {
213
+ confirm("Delete this comment?") && N(e.id);
214
+ }, f.appendChild(l), a.appendChild(f), t.appendChild(a);
215
+ }
216
+ return t.onmouseenter = () => E(e.id, !0), t.onmouseleave = () => E(e.id, !1), t;
217
+ }
218
+ function V() {
219
+ if (document.getElementById("rte-comments-panel-styles")) return;
220
+ const e = document.createElement("style");
221
+ e.id = "rte-comments-panel-styles", e.textContent = `
222
+ .rte-comments-close:hover {
223
+ color: #d32f2f;
224
+ }
225
+ .rte-comments-panel {
226
+ position: fixed;
227
+ right: 0;
228
+ top: 0;
229
+ width: 350px;
230
+ height: 100%;
231
+ background: white;
232
+ border-left: 1px solid #ddd;
233
+ box-shadow: -2px 0 4px rgba(0,0,0,0.1);
234
+ overflow-y: auto;
235
+ z-index: 1000;
236
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
237
+ display: flex;
238
+ flex-direction: column;
239
+ }
240
+ .comments-header {
241
+ padding: 16px;
242
+ border-bottom: 1px solid #eee;
243
+ background-color: #fafafa;
244
+ }
245
+ .comments-header h3 {
246
+ margin: 0;
247
+ font-size: 14px;
248
+ font-weight: 600;
249
+ }
250
+ .rte-comments-close {
251
+ background: none;
252
+ border: none;
253
+ font-size: 22px;
254
+ cursor: pointer;
255
+ color: #888;
256
+ margin-left: 8px;
257
+ padding: 0;
258
+ }
259
+ .comment-add-box {
260
+ padding: 12px;
261
+ border-bottom: 1px solid #eee;
262
+ background: #fafafa;
263
+ display: flex;
264
+ flex-direction: column;
265
+ gap: 8px;
266
+ }
267
+ .new-comment-textarea {
268
+ font-size: 13px;
269
+ padding: 8px;
270
+ border-radius: 3px;
271
+ border: 1px solid #ddd;
272
+ resize: vertical;
273
+ font-family: inherit;
274
+ }
275
+ .comments-empty {
276
+ padding: 16px;
277
+ text-align: center;
278
+ color: #999;
279
+ font-size: 13px;
280
+ }
281
+ .comments-list {
282
+ padding: 12px;
283
+ }
284
+ .comment-item {
285
+ padding: 12px;
286
+ margin-bottom: 12px;
287
+ border: 1px solid #eee;
288
+ border-radius: 4px;
289
+ background-color: white;
290
+ transition: all 0.2s;
291
+ }
292
+ .comment-item:hover {
293
+ border-color: #ddd;
294
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
295
+ }
296
+ .comment-item.resolved {
297
+ opacity: 0.6;
298
+ background-color: #f5f5f5;
299
+ }
300
+ .comment-header {
301
+ display: flex;
302
+ justify-content: space-between;
303
+ align-items: center;
304
+ margin-bottom: 8px;
305
+ }
306
+ .comment-meta {
307
+ display: flex;
308
+ flex-direction: column;
309
+ gap: 2px;
310
+ }
311
+ .comment-meta strong {
312
+ font-size: 13px;
313
+ color: #333;
314
+ }
315
+ .comment-date {
316
+ font-size: 11px;
317
+ color: #999;
318
+ }
319
+ .comment-expand {
320
+ background: none;
321
+ border: none;
322
+ cursor: pointer;
323
+ color: #666;
324
+ font-size: 12px;
325
+ padding: 0;
326
+ }
327
+ .comment-text {
328
+ font-size: 13px;
329
+ line-height: 1.4;
330
+ color: #333;
331
+ margin-bottom: 8px;
332
+ }
333
+ .comment-selection {
334
+ font-size: 12px;
335
+ color: #666;
336
+ font-style: italic;
337
+ background-color: #f9f9f9;
338
+ padding: 6px;
339
+ border-radius: 3px;
340
+ margin-bottom: 8px;
341
+ }
342
+ .comment-expanded {
343
+ margin-top: 12px;
344
+ padding-top: 12px;
345
+ border-top: 1px solid #eee;
346
+ }
347
+ .comment-replies {
348
+ margin-bottom: 12px;
349
+ }
350
+ .comment-reply {
351
+ padding: 8px;
352
+ background-color: #fafafa;
353
+ border-radius: 3px;
354
+ margin-bottom: 8px;
355
+ font-size: 12px;
356
+ }
357
+ .reply-header {
358
+ display: flex;
359
+ gap: 8px;
360
+ margin-bottom: 4px;
361
+ }
362
+ .reply-header strong {
363
+ font-size: 12px;
364
+ color: #333;
365
+ }
366
+ .reply-date {
367
+ font-size: 11px;
368
+ color: #999;
369
+ }
370
+ .reply-text {
371
+ font-size: 12px;
372
+ color: #666;
373
+ line-height: 1.3;
374
+ }
375
+ .comment-reply-input {
376
+ display: flex;
377
+ flex-direction: column;
378
+ gap: 6px;
379
+ margin-bottom: 12px;
380
+ }
381
+ .comment-reply-input textarea {
382
+ font-size: 12px;
383
+ padding: 6px;
384
+ border: 1px solid #ddd;
385
+ border-radius: 3px;
386
+ font-family: inherit;
387
+ resize: vertical;
388
+ }
389
+ .rte-button-small {
390
+ font-size: 12px;
391
+ padding: 4px 8px;
392
+ background-color: #1976d2;
393
+ color: white;
394
+ border: none;
395
+ border-radius: 3px;
396
+ cursor: pointer;
397
+ align-self: flex-end;
398
+ }
399
+ .rte-button-small:hover {
400
+ background-color: #1565c0;
401
+ }
402
+ .rte-button-small:disabled {
403
+ opacity: 0.5;
404
+ pointer-events: none;
405
+ }
406
+ .comment-actions {
407
+ display: flex;
408
+ gap: 6px;
409
+ justify-content: flex-end;
410
+ }
411
+ .action-button {
412
+ font-size: 12px;
413
+ padding: 4px 8px;
414
+ background-color: #f5f5f5;
415
+ border: 1px solid #ddd;
416
+ border-radius: 3px;
417
+ cursor: pointer;
418
+ transition: all 0.2s;
419
+ }
420
+ .action-button:hover {
421
+ background-color: #eeeeee;
422
+ }
423
+ .action-button.resolve {
424
+ color: #2e7d32;
425
+ }
426
+ .action-button.delete {
427
+ color: #c62828;
428
+ }
429
+ .rte-comment-anchor {
430
+ position: relative;
431
+ }
432
+ .rte-comment-anchor.highlighted {
433
+ background-color: #ffeb3b !important;
434
+ border-radius: 3px;
435
+ }
436
+ `, document.head.appendChild(e);
437
+ }
438
+ const H = () => ({
439
+ name: "comments",
440
+ toolbar: [
441
+ {
442
+ label: "Add Comment",
443
+ command: "addComment",
444
+ type: "button",
445
+ icon: '<svg fill="#000000" width="24px" height="24px" viewBox="0 0 32 32" id="icon" 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"><defs><style>.cls-1{fill:none;}</style></defs><title>add-comment</title><path d="M17.74,30,16,29l4-7h6a2,2,0,0,0,2-2V8a2,2,0,0,0-2-2H6A2,2,0,0,0,4,8V20a2,2,0,0,0,2,2h9v2H6a4,4,0,0,1-4-4V8A4,4,0,0,1,6,4H26a4,4,0,0,1,4,4V20a4,4,0,0,1-4,4H21.16Z" transform="translate(0 0)"></path><polygon points="17 9 15 9 15 13 11 13 11 15 15 15 15 19 17 19 17 15 21 15 21 13 17 13 17 9"></polygon><rect id="_Transparent_Rectangle_" data-name="&lt;Transparent Rectangle&gt;" class="cls-1" width="32" height="32"></rect></g></svg>'
446
+ },
447
+ {
448
+ label: "Show / Hide Comments",
449
+ command: "toggleComments",
450
+ type: "button",
451
+ icon: '<svg width="24px" height="24px" viewBox="0 0 16 16" 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="M16 1H4V11H8L10 13L12 11H16V1Z" fill="#000000"></path> <path d="M2 5V13H7.17157L8.70711 14.5355L7.29289 15.9497L6.34315 15H0V5H2Z" fill="#000000"></path> </g></svg>'
452
+ }
453
+ ],
454
+ commands: {
455
+ addComment: () => {
456
+ const e = window.getSelection();
457
+ return e && e.rangeCount > 0 && !e.isCollapsed ? h = e.getRangeAt(0).cloneRange() : h = null, x = !0, k(), !0;
458
+ },
459
+ toggleComments: () => (x = !x, k(), !0)
460
+ },
461
+ keymap: {}
462
+ });
463
+ export {
464
+ H as CommentsPlugin,
465
+ S as addCommentCommand,
466
+ N as deleteComment,
467
+ R as getAllComments,
468
+ E as highlightComment,
469
+ L as reopenComment,
470
+ T as replyToComment,
471
+ z as resolveComment
472
+ };
473
+ //# sourceMappingURL=CommentsPlugin.native-2zQV8Ia4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommentsPlugin.native-2zQV8Ia4.mjs","sources":["../../plugins/comments/src/CommentsPlugin.native.ts"],"sourcesContent":["import { Plugin } from '@editora/core';\n\n/**\n * Comments Plugin - Native Implementation with Complete UI Parity\n * \n * Matches React CommentsPluginProvider exactly:\n * - Expandable/collapsible comments\n * - Always-on \"Add Comment\" textarea at top\n * - Selection preservation with selectionRef\n * - Comment count in header\n * - Inline reply textareas in expanded view\n * - Complete CSS styling\n * - Selection change tracking\n * - General comments support\n */\n\ninterface CommentReply {\n id: string;\n author: string;\n text: string;\n createdAt: string;\n}\n\ninterface Comment {\n id: string;\n anchorId: string;\n selectedText: string;\n author: string;\n text: string;\n createdAt: string;\n resolved: boolean;\n resolvedAt?: string;\n resolvedBy?: string;\n replies: CommentReply[];\n}\n\n// State\nconst commentRegistry = new Map<string, Comment>();\nlet commentsPanelVisible = false;\nlet commentsPanelElement: HTMLElement | null = null;\nlet expandedComments = new Set<string>();\nlet replyTexts: { [key: string]: string } = {};\nlet savedSelection: Range | null = null;\nlet newCommentText = '';\nconst commentAuthor = 'User';\n\n// Track selection changes while panel is open\nlet selectionChangeListener: (() => void) | null = null;\n\n/**\n * Get all comments\n */\nexport function getAllComments(): Comment[] {\n return Array.from(commentRegistry.values());\n}\n\n/**\n * Add comment (with or without selection)\n */\nexport function addCommentCommand(author: string, text: string, general = false): string {\n if (general) {\n const commentId = `comment-${Date.now()}`;\n const comment: Comment = {\n id: commentId,\n anchorId: '',\n selectedText: '',\n author,\n text,\n createdAt: new Date().toISOString(),\n resolved: false,\n replies: []\n };\n commentRegistry.set(commentId, comment);\n refreshCommentsPanel();\n return commentId;\n }\n\n // Use saved selection if available\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return '';\n \n const range = savedSelection || selection.getRangeAt(0);\n const selectedText = range.toString();\n \n if (!selectedText) return '';\n\n const commentId = `comment-${Date.now()}`;\n const anchorId = `comment-anchor-${Date.now()}`;\n\n // Create anchor span\n const anchor = document.createElement('span');\n anchor.id = anchorId;\n anchor.className = 'rte-comment-anchor';\n anchor.setAttribute('data-comment-id', commentId);\n anchor.style.cssText = `\n background-color: #ffeb3b;\n border-bottom: 2px solid #fbc02d;\n cursor: pointer;\n position: relative;\n `;\n anchor.title = 'Click to view comment';\n\n // Wrap selection\n const clonedRange = range.cloneRange();\n const contents = clonedRange.extractContents();\n anchor.appendChild(contents);\n clonedRange.insertNode(anchor);\n\n // Create comment\n const comment: Comment = {\n id: commentId,\n anchorId,\n selectedText,\n author,\n text,\n createdAt: new Date().toISOString(),\n resolved: false,\n replies: []\n };\n\n commentRegistry.set(commentId, comment);\n\n // Add click handler\n anchor.onclick = () => {\n commentsPanelVisible = true;\n createCommentsPanel();\n };\n\n refreshCommentsPanel();\n \n // Clear selection\n savedSelection = null;\n selection.removeAllRanges();\n \n return commentId;\n}\n\n/**\n * Resolve comment\n */\nexport function resolveComment(commentId: string, author: string) {\n const comment = commentRegistry.get(commentId);\n if (!comment) return;\n\n comment.resolved = true;\n comment.resolvedAt = new Date().toISOString();\n comment.resolvedBy = author;\n\n if (comment.anchorId) {\n const anchor = document.getElementById(comment.anchorId);\n if (anchor) {\n anchor.style.backgroundColor = '#e0e0e0';\n anchor.style.borderBottom = '2px solid #bdbdbd';\n anchor.style.opacity = '0.6';\n }\n }\n\n refreshCommentsPanel();\n}\n\n/**\n * Reopen comment\n */\nexport function reopenComment(commentId: string) {\n const comment = commentRegistry.get(commentId);\n if (!comment) return;\n\n comment.resolved = false;\n comment.resolvedAt = undefined;\n comment.resolvedBy = undefined;\n\n if (comment.anchorId) {\n const anchor = document.getElementById(comment.anchorId);\n if (anchor) {\n anchor.style.backgroundColor = '#ffeb3b';\n anchor.style.borderBottom = '2px solid #fbc02d';\n anchor.style.opacity = '1';\n }\n }\n\n refreshCommentsPanel();\n}\n\n/**\n * Delete comment\n */\nexport function deleteComment(commentId: string) {\n const comment = commentRegistry.get(commentId);\n if (!comment) return;\n\n if (comment.anchorId) {\n const anchor = document.getElementById(comment.anchorId);\n if (anchor) {\n const parent = anchor.parentNode;\n while (anchor.firstChild) {\n parent?.insertBefore(anchor.firstChild, anchor);\n }\n anchor.remove();\n }\n }\n\n commentRegistry.delete(commentId);\n refreshCommentsPanel();\n}\n\n/**\n * Reply to comment\n */\nexport function replyToComment(commentId: string, author: string, text: string) {\n const comment = commentRegistry.get(commentId);\n if (!comment) return;\n\n const reply: CommentReply = {\n id: `reply-${Date.now()}`,\n author,\n text,\n createdAt: new Date().toISOString()\n };\n\n comment.replies.push(reply);\n refreshCommentsPanel();\n}\n\n/**\n * Highlight comment\n */\nexport function highlightComment(commentId: string, highlight: boolean) {\n const comment = commentRegistry.get(commentId);\n if (!comment || !comment.anchorId) return;\n\n const anchor = document.getElementById(comment.anchorId);\n if (anchor) {\n if (highlight) {\n anchor.classList.add('highlighted');\n anchor.style.outline = '2px solid #0066cc';\n anchor.style.outlineOffset = '2px';\n } else {\n anchor.classList.remove('highlighted');\n anchor.style.outline = 'none';\n }\n }\n}\n\n/**\n * Create Comments Panel with exact React UI\n */\nfunction createCommentsPanel() {\n if (commentsPanelElement) {\n commentsPanelElement.style.display = commentsPanelVisible ? 'block' : 'none';\n if (commentsPanelVisible) {\n refreshCommentsPanel();\n startSelectionTracking();\n } else {\n stopSelectionTracking();\n }\n return;\n }\n\n const panel = document.createElement('div');\n panel.className = 'rte-comments-panel';\n \n commentsPanelElement = panel;\n document.body.appendChild(panel);\n \n refreshCommentsPanel();\n startSelectionTracking();\n addCommentsPanelStyles();\n}\n\n/**\n * Start tracking selection changes\n */\nfunction startSelectionTracking() {\n if (selectionChangeListener) return;\n \n selectionChangeListener = () => {\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0 && !sel.isCollapsed) {\n savedSelection = sel.getRangeAt(0).cloneRange();\n }\n };\n \n document.addEventListener('selectionchange', selectionChangeListener);\n}\n\n/**\n * Stop tracking selection changes\n */\nfunction stopSelectionTracking() {\n if (selectionChangeListener) {\n document.removeEventListener('selectionchange', selectionChangeListener);\n selectionChangeListener = null;\n }\n savedSelection = null;\n}\n\n/**\n * Refresh Comments Panel Content\n */\nfunction refreshCommentsPanel() {\n if (!commentsPanelElement) return;\n\n const comments = getAllComments();\n \n commentsPanelElement.innerHTML = `\n <div class=\"comments-header\" style=\"display: flex; justify-content: space-between; align-items: center;\">\n <h3 style=\"margin: 0;\">Comments (${comments.length})</h3>\n <button class=\"rte-comments-close\" aria-label=\"Close comments panel\">✕</button>\n </div>\n\n <div class=\"comment-add-box\">\n <textarea class=\"new-comment-textarea\" placeholder=\"Add a new comment...\" rows=\"2\"></textarea>\n <button class=\"rte-button-small add-comment-btn\">Add Comment</button>\n </div>\n\n ${comments.length === 0 ? \n '<div class=\"comments-empty\">No comments yet</div>' :\n '<div class=\"comments-list\"></div>'\n }\n `;\n\n // Close button handler\n const closeBtn = commentsPanelElement.querySelector('.rte-comments-close');\n if (closeBtn) {\n closeBtn.addEventListener('click', () => {\n commentsPanelVisible = false;\n if (commentsPanelElement) commentsPanelElement.style.display = 'none';\n stopSelectionTracking();\n });\n }\n\n // New comment handler\n const textarea = commentsPanelElement.querySelector('.new-comment-textarea') as HTMLTextAreaElement;\n const addBtn = commentsPanelElement.querySelector('.add-comment-btn') as HTMLButtonElement;\n \n if (textarea && addBtn) {\n textarea.value = newCommentText;\n textarea.oninput = () => {\n newCommentText = textarea.value;\n addBtn.disabled = !newCommentText.trim();\n addBtn.style.opacity = newCommentText.trim() ? '1' : '0.5';\n };\n \n addBtn.disabled = !newCommentText.trim();\n addBtn.style.opacity = newCommentText.trim() ? '1' : '0.5';\n \n addBtn.onclick = () => {\n if (!newCommentText.trim()) {\n alert('Comment cannot be empty');\n textarea.focus();\n return;\n }\n \n if (savedSelection) {\n addCommentCommand(commentAuthor, newCommentText.trim());\n } else {\n addCommentCommand(commentAuthor, newCommentText.trim(), true);\n }\n \n newCommentText = '';\n textarea.value = '';\n refreshCommentsPanel();\n };\n }\n\n // Render comment cards\n if (comments.length > 0) {\n const commentsList = commentsPanelElement.querySelector('.comments-list');\n if (commentsList) {\n comments.forEach(comment => {\n const card = createCommentCard(comment);\n commentsList.appendChild(card);\n });\n }\n }\n}\n\n/**\n * Create Comment Card\n */\nfunction createCommentCard(comment: Comment): HTMLElement {\n const isExpanded = expandedComments.has(comment.id);\n \n const card = document.createElement('div');\n card.className = `comment-item${comment.resolved ? ' resolved' : ''}`;\n \n // Header\n const header = document.createElement('div');\n header.className = 'comment-header';\n header.innerHTML = `\n <div class=\"comment-meta\">\n <strong>${comment.author}</strong>\n <span class=\"comment-date\">${new Date(comment.createdAt).toLocaleDateString()}</span>\n </div>\n <button class=\"comment-expand\" aria-label=\"Toggle comment\">${isExpanded ? '▼' : '▶'}</button>\n `;\n \n const expandBtn = header.querySelector('.comment-expand');\n if (expandBtn) {\n expandBtn.addEventListener('click', () => {\n if (expandedComments.has(comment.id)) {\n expandedComments.delete(comment.id);\n } else {\n expandedComments.add(comment.id);\n }\n refreshCommentsPanel();\n });\n }\n \n card.appendChild(header);\n \n // Comment text\n const text = document.createElement('div');\n text.className = 'comment-text';\n text.textContent = comment.text;\n card.appendChild(text);\n \n // Selected text\n if (comment.selectedText) {\n const selection = document.createElement('div');\n selection.className = 'comment-selection';\n selection.textContent = `\"${comment.selectedText}\"`;\n card.appendChild(selection);\n }\n \n // Expanded content\n if (isExpanded) {\n const expanded = document.createElement('div');\n expanded.className = 'comment-expanded';\n \n // Replies\n if (comment.replies.length > 0) {\n const repliesDiv = document.createElement('div');\n repliesDiv.className = 'comment-replies';\n \n comment.replies.forEach(reply => {\n const replyDiv = document.createElement('div');\n replyDiv.className = 'comment-reply';\n replyDiv.innerHTML = `\n <div class=\"reply-header\">\n <strong>${reply.author}</strong>\n <span class=\"reply-date\">${new Date(reply.createdAt).toLocaleDateString()}</span>\n </div>\n <div class=\"reply-text\">${reply.text}</div>\n `;\n repliesDiv.appendChild(replyDiv);\n });\n \n expanded.appendChild(repliesDiv);\n }\n \n // Reply input\n if (!comment.resolved) {\n const replyInput = document.createElement('div');\n replyInput.className = 'comment-reply-input';\n \n const replyTextarea = document.createElement('textarea');\n replyTextarea.placeholder = 'Add a reply...';\n replyTextarea.rows = 2;\n replyTextarea.value = replyTexts[comment.id] || '';\n replyTextarea.oninput = () => {\n replyTexts[comment.id] = replyTextarea.value;\n };\n \n const replyBtn = document.createElement('button');\n replyBtn.className = 'rte-button-small';\n replyBtn.textContent = 'Reply';\n replyBtn.onclick = () => {\n if (replyTexts[comment.id]?.trim()) {\n replyToComment(comment.id, commentAuthor, replyTexts[comment.id]);\n replyTexts[comment.id] = '';\n refreshCommentsPanel();\n }\n };\n \n replyInput.appendChild(replyTextarea);\n replyInput.appendChild(replyBtn);\n expanded.appendChild(replyInput);\n }\n \n // Actions\n const actions = document.createElement('div');\n actions.className = 'comment-actions';\n \n if (!comment.resolved) {\n const resolveBtn = document.createElement('button');\n resolveBtn.className = 'action-button resolve';\n resolveBtn.textContent = '✓ Resolve';\n resolveBtn.onclick = () => resolveComment(comment.id, commentAuthor);\n actions.appendChild(resolveBtn);\n } else {\n const reopenBtn = document.createElement('button');\n reopenBtn.className = 'action-button reopen';\n reopenBtn.textContent = '↻ Reopen';\n reopenBtn.onclick = () => reopenComment(comment.id);\n actions.appendChild(reopenBtn);\n }\n \n const deleteBtn = document.createElement('button');\n deleteBtn.className = 'action-button delete';\n deleteBtn.textContent = '🗑 Delete';\n deleteBtn.onclick = () => {\n if (confirm('Delete this comment?')) {\n deleteComment(comment.id);\n }\n };\n actions.appendChild(deleteBtn);\n \n expanded.appendChild(actions);\n card.appendChild(expanded);\n }\n \n // Hover highlighting\n card.onmouseenter = () => highlightComment(comment.id, true);\n card.onmouseleave = () => highlightComment(comment.id, false);\n \n return card;\n}\n\n/**\n * Add Comments Panel Styles (matching React CSS exactly)\n */\nfunction addCommentsPanelStyles() {\n if (document.getElementById('rte-comments-panel-styles')) return;\n \n const style = document.createElement('style');\n style.id = 'rte-comments-panel-styles';\n style.textContent = `\n .rte-comments-close:hover {\n color: #d32f2f;\n }\n .rte-comments-panel {\n position: fixed;\n right: 0;\n top: 0;\n width: 350px;\n height: 100%;\n background: white;\n border-left: 1px solid #ddd;\n box-shadow: -2px 0 4px rgba(0,0,0,0.1);\n overflow-y: auto;\n z-index: 1000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n display: flex;\n flex-direction: column;\n }\n .comments-header {\n padding: 16px;\n border-bottom: 1px solid #eee;\n background-color: #fafafa;\n }\n .comments-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n }\n .rte-comments-close {\n background: none;\n border: none;\n font-size: 22px;\n cursor: pointer;\n color: #888;\n margin-left: 8px;\n padding: 0;\n }\n .comment-add-box {\n padding: 12px;\n border-bottom: 1px solid #eee;\n background: #fafafa;\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .new-comment-textarea {\n font-size: 13px;\n padding: 8px;\n border-radius: 3px;\n border: 1px solid #ddd;\n resize: vertical;\n font-family: inherit;\n }\n .comments-empty {\n padding: 16px;\n text-align: center;\n color: #999;\n font-size: 13px;\n }\n .comments-list {\n padding: 12px;\n }\n .comment-item {\n padding: 12px;\n margin-bottom: 12px;\n border: 1px solid #eee;\n border-radius: 4px;\n background-color: white;\n transition: all 0.2s;\n }\n .comment-item:hover {\n border-color: #ddd;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n }\n .comment-item.resolved {\n opacity: 0.6;\n background-color: #f5f5f5;\n }\n .comment-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n }\n .comment-meta {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .comment-meta strong {\n font-size: 13px;\n color: #333;\n }\n .comment-date {\n font-size: 11px;\n color: #999;\n }\n .comment-expand {\n background: none;\n border: none;\n cursor: pointer;\n color: #666;\n font-size: 12px;\n padding: 0;\n }\n .comment-text {\n font-size: 13px;\n line-height: 1.4;\n color: #333;\n margin-bottom: 8px;\n }\n .comment-selection {\n font-size: 12px;\n color: #666;\n font-style: italic;\n background-color: #f9f9f9;\n padding: 6px;\n border-radius: 3px;\n margin-bottom: 8px;\n }\n .comment-expanded {\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #eee;\n }\n .comment-replies {\n margin-bottom: 12px;\n }\n .comment-reply {\n padding: 8px;\n background-color: #fafafa;\n border-radius: 3px;\n margin-bottom: 8px;\n font-size: 12px;\n }\n .reply-header {\n display: flex;\n gap: 8px;\n margin-bottom: 4px;\n }\n .reply-header strong {\n font-size: 12px;\n color: #333;\n }\n .reply-date {\n font-size: 11px;\n color: #999;\n }\n .reply-text {\n font-size: 12px;\n color: #666;\n line-height: 1.3;\n }\n .comment-reply-input {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-bottom: 12px;\n }\n .comment-reply-input textarea {\n font-size: 12px;\n padding: 6px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-family: inherit;\n resize: vertical;\n }\n .rte-button-small {\n font-size: 12px;\n padding: 4px 8px;\n background-color: #1976d2;\n color: white;\n border: none;\n border-radius: 3px;\n cursor: pointer;\n align-self: flex-end;\n }\n .rte-button-small:hover {\n background-color: #1565c0;\n }\n .rte-button-small:disabled {\n opacity: 0.5;\n pointer-events: none;\n }\n .comment-actions {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n }\n .action-button {\n font-size: 12px;\n padding: 4px 8px;\n background-color: #f5f5f5;\n border: 1px solid #ddd;\n border-radius: 3px;\n cursor: pointer;\n transition: all 0.2s;\n }\n .action-button:hover {\n background-color: #eeeeee;\n }\n .action-button.resolve {\n color: #2e7d32;\n }\n .action-button.delete {\n color: #c62828;\n }\n .rte-comment-anchor {\n position: relative;\n }\n .rte-comment-anchor.highlighted {\n background-color: #ffeb3b !important;\n border-radius: 3px;\n }\n `;\n document.head.appendChild(style);\n}\n\nexport const CommentsPlugin = (): Plugin => ({\n name: 'comments',\n \n toolbar: [\n {\n label: 'Add Comment',\n command: 'addComment',\n type: 'button',\n icon: '<svg fill=\"#000000\" width=\"24px\" height=\"24px\" viewBox=\"0 0 32 32\" id=\"icon\" 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\"><defs><style>.cls-1{fill:none;}</style></defs><title>add-comment</title><path d=\"M17.74,30,16,29l4-7h6a2,2,0,0,0,2-2V8a2,2,0,0,0-2-2H6A2,2,0,0,0,4,8V20a2,2,0,0,0,2,2h9v2H6a4,4,0,0,1-4-4V8A4,4,0,0,1,6,4H26a4,4,0,0,1,4,4V20a4,4,0,0,1-4,4H21.16Z\" transform=\"translate(0 0)\"></path><polygon points=\"17 9 15 9 15 13 11 13 11 15 15 15 15 19 17 19 17 15 21 15 21 13 17 13 17 9\"></polygon><rect id=\"_Transparent_Rectangle_\" data-name=\"&lt;Transparent Rectangle&gt;\" class=\"cls-1\" width=\"32\" height=\"32\"></rect></g></svg>',\n },\n {\n label: 'Show / Hide Comments',\n command: 'toggleComments',\n type: 'button',\n icon: '<svg width=\"24px\" height=\"24px\" viewBox=\"0 0 16 16\" 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=\"M16 1H4V11H8L10 13L12 11H16V1Z\" fill=\"#000000\"></path> <path d=\"M2 5V13H7.17157L8.70711 14.5355L7.29289 15.9497L6.34315 15H0V5H2Z\" fill=\"#000000\"></path> </g></svg>',\n },\n ],\n \n commands: {\n addComment: () => {\n // Save current selection\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0 && !sel.isCollapsed) {\n savedSelection = sel.getRangeAt(0).cloneRange();\n } else {\n savedSelection = null;\n }\n \n commentsPanelVisible = true;\n createCommentsPanel();\n return true;\n },\n \n toggleComments: () => {\n commentsPanelVisible = !commentsPanelVisible;\n createCommentsPanel();\n return true;\n }\n },\n \n keymap: {}\n});\n"],"names":["commentRegistry","commentsPanelVisible","commentsPanelElement","expandedComments","replyTexts","savedSelection","newCommentText","commentAuthor","selectionChangeListener","getAllComments","addCommentCommand","author","text","general","commentId","comment","refreshCommentsPanel","selection","range","selectedText","anchorId","anchor","clonedRange","contents","createCommentsPanel","resolveComment","reopenComment","deleteComment","parent","replyToComment","reply","highlightComment","highlight","startSelectionTracking","stopSelectionTracking","panel","addCommentsPanelStyles","sel","comments","closeBtn","textarea","addBtn","commentsList","card","createCommentCard","isExpanded","header","expandBtn","expanded","repliesDiv","replyDiv","replyInput","replyTextarea","replyBtn","_a","actions","reopenBtn","resolveBtn","deleteBtn","style","CommentsPlugin"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ const o = ["P", "DIV", "H1", "H2", "H3", "H4", "H5", "H6", "LI", "BLOCKQUOTE"], i = () => ({
2
+ name: "direction",
3
+ toolbar: [
4
+ {
5
+ label: "Left to Right",
6
+ command: "setDirectionLTR",
7
+ icon: '<svg width="24" height="24" 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="M21 18H3M21 18L18 21M21 18L18 15M13 3V12M13 3H7M13 3C13.4596 3 13.9148 3.0776 14.3394 3.22836C14.764 3.37913 15.1499 3.6001 15.4749 3.87868C15.7999 4.15726 16.0577 4.48797 16.2336 4.85195C16.4095 5.21593 16.5 5.60603 16.5 6C16.5 6.39397 16.4095 6.78407 16.2336 7.14805C16.0577 7.51203 15.7999 7.84274 15.4749 8.12132C15.1499 8.3999 14.764 8.62087 14.3394 8.77164C13.9148 8.9224 13.4596 9 13 9V3ZM9 3V12" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg>',
8
+ shortcut: "Mod-Shift-l"
9
+ },
10
+ {
11
+ label: "Right to Left",
12
+ command: "setDirectionRTL",
13
+ icon: '<svg width="24" height="24" 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="M3 18H21M3 18L6 21M3 18L6 15M11 12V3H17M15 3V12M10.5 3C10.0404 3 9.58525 3.0776 9.16061 3.22836C8.73597 3.37913 8.35013 3.6001 8.02513 3.87868C7.70012 4.15726 7.44231 4.48797 7.26642 4.85195C7.09053 5.21593 7 5.60603 7 6C7 6.39397 7.09053 6.78407 7.26642 7.14805C7.44231 7.51203 7.70012 7.84274 8.02513 8.12132C8.35013 8.3999 8.73597 8.62087 9.16061 8.77164C9.58525 8.9224 10.0404 9 10.5 9L10.5 3Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> </g></svg>',
14
+ shortcut: "Mod-Shift-r"
15
+ }
16
+ ],
17
+ commands: {
18
+ setDirectionLTR: () => {
19
+ try {
20
+ const t = window.getSelection();
21
+ if (!t || t.rangeCount === 0) return !1;
22
+ let e = t.getRangeAt(0).commonAncestorContainer;
23
+ for (e && e.nodeType === Node.TEXT_NODE && (e = e.parentElement); e && e !== document.body; ) {
24
+ const r = e;
25
+ if (r.tagName && o.includes(r.tagName))
26
+ return r.removeAttribute("dir"), !0;
27
+ e = r.parentElement;
28
+ }
29
+ return !1;
30
+ } catch (t) {
31
+ return console.error("Failed to set LTR direction:", t), !1;
32
+ }
33
+ },
34
+ setDirectionRTL: () => {
35
+ try {
36
+ const t = window.getSelection();
37
+ if (!t || t.rangeCount === 0) return !1;
38
+ let e = t.getRangeAt(0).commonAncestorContainer;
39
+ for (e && e.nodeType === Node.TEXT_NODE && (e = e.parentElement); e && e !== document.body; ) {
40
+ const r = e;
41
+ if (r.tagName && o.includes(r.tagName))
42
+ return r.setAttribute("dir", "rtl"), !0;
43
+ e = r.parentElement;
44
+ }
45
+ return !1;
46
+ } catch (t) {
47
+ return console.error("Failed to set RTL direction:", t), !1;
48
+ }
49
+ }
50
+ },
51
+ keymap: {
52
+ "Mod-Shift-l": "setDirectionLTR",
53
+ "Mod-Shift-r": "setDirectionRTL"
54
+ }
55
+ });
56
+ export {
57
+ i as DirectionPlugin
58
+ };
59
+ //# sourceMappingURL=DirectionPlugin.native-Be7wCzkI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirectionPlugin.native-Be7wCzkI.mjs","sources":["../../plugins/direction/src/DirectionPlugin.native.ts"],"sourcesContent":["import type { Plugin } from '@editora/core';\n\n/**\n * DirectionPlugin - Native implementation for text direction (LTR/RTL)\n * \n * Features:\n * - Set text direction to Left-to-Right (LTR) - removes dir attribute (default)\n * - Set text direction to Right-to-Left (RTL) - sets dir=\"rtl\"\n * - Essential for multilingual content (Arabic, Hebrew, Persian, Urdu, etc.)\n * \n * Commands:\n * - setDirectionLTR: Remove dir attribute (default LTR behavior)\n * - setDirectionRTL: Set dir=\"rtl\" on nearest block element\n * \n * UI/UX Features:\n * - Detailed SVG icons matching React implementation\n * - Works on block-level elements (P, DIV, H1-H6, LI, BLOCKQUOTE)\n * - Keyboard shortcuts: Cmd/Ctrl+Shift+L (LTR), Cmd/Ctrl+Shift+R (RTL)\n * - Clean attribute-only approach (no inline styles)\n */\n\n// List of block-level elements that can have direction attributes\nconst BLOCK_LEVEL_TAGS = ['P', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI', 'BLOCKQUOTE'];\n\nexport const DirectionPlugin = (): Plugin => {\n return {\n name: 'direction',\n \n toolbar: [\n {\n label: 'Left to Right',\n command: 'setDirectionLTR',\n icon: `<svg width=\"24\" height=\"24\" 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=\"M21 18H3M21 18L18 21M21 18L18 15M13 3V12M13 3H7M13 3C13.4596 3 13.9148 3.0776 14.3394 3.22836C14.764 3.37913 15.1499 3.6001 15.4749 3.87868C15.7999 4.15726 16.0577 4.48797 16.2336 4.85195C16.4095 5.21593 16.5 5.60603 16.5 6C16.5 6.39397 16.4095 6.78407 16.2336 7.14805C16.0577 7.51203 15.7999 7.84274 15.4749 8.12132C15.1499 8.3999 14.764 8.62087 14.3394 8.77164C13.9148 8.9224 13.4596 9 13 9V3ZM9 3V12\" stroke=\"#000000\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path> </g></svg>`,\n shortcut: 'Mod-Shift-l'\n },\n {\n label: 'Right to Left',\n command: 'setDirectionRTL',\n icon: `<svg width=\"24\" height=\"24\" 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=\"M3 18H21M3 18L6 21M3 18L6 15M11 12V3H17M15 3V12M10.5 3C10.0404 3 9.58525 3.0776 9.16061 3.22836C8.73597 3.37913 8.35013 3.6001 8.02513 3.87868C7.70012 4.15726 7.44231 4.48797 7.26642 4.85195C7.09053 5.21593 7 5.60603 7 6C7 6.39397 7.09053 6.78407 7.26642 7.14805C7.44231 7.51203 7.70012 7.84274 8.02513 8.12132C8.35013 8.3999 8.73597 8.62087 9.16061 8.77164C9.58525 8.9224 10.0404 9 10.5 9L10.5 3Z\" stroke=\"#000000\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path> </g></svg>`,\n shortcut: 'Mod-Shift-r'\n }\n ],\n\n commands: {\n setDirectionLTR: () => {\n try {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return false;\n\n const range = selection.getRangeAt(0);\n let element: Node | null = range.commonAncestorContainer;\n\n // If it's a text node, get the parent element\n if (element && element.nodeType === Node.TEXT_NODE) {\n element = element.parentElement;\n }\n\n // Find the nearest block-level element\n while (element && element !== document.body) {\n const htmlElement = element as HTMLElement;\n if (htmlElement.tagName && BLOCK_LEVEL_TAGS.includes(htmlElement.tagName)) {\n // Remove the dir attribute - browser defaults to LTR\n htmlElement.removeAttribute('dir');\n return true;\n }\n element = htmlElement.parentElement;\n }\n \n return false;\n } catch (error) {\n console.error('Failed to set LTR direction:', error);\n return false;\n }\n },\n\n setDirectionRTL: () => {\n try {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return false;\n\n const range = selection.getRangeAt(0);\n let element: Node | null = range.commonAncestorContainer;\n\n // If it's a text node, get the parent element\n if (element && element.nodeType === Node.TEXT_NODE) {\n element = element.parentElement;\n }\n\n // Find the nearest block-level element\n while (element && element !== document.body) {\n const htmlElement = element as HTMLElement;\n if (htmlElement.tagName && BLOCK_LEVEL_TAGS.includes(htmlElement.tagName)) {\n // Set the dir attribute to \"rtl\"\n htmlElement.setAttribute('dir', 'rtl');\n return true;\n }\n element = htmlElement.parentElement;\n }\n \n return false;\n } catch (error) {\n console.error('Failed to set RTL direction:', error);\n return false;\n }\n }\n },\n\n keymap: {\n 'Mod-Shift-l': 'setDirectionLTR',\n 'Mod-Shift-r': 'setDirectionRTL'\n }\n };\n};\n"],"names":["BLOCK_LEVEL_TAGS","DirectionPlugin","selection","element","htmlElement","error"],"mappings":"AAsBA,MAAMA,IAAmB,CAAC,KAAK,OAAO,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,YAAY,GAE/EC,IAAkB,OACtB;AAAA,EACL,MAAM;AAAA,EAEN,SAAS;AAAA,IACP;AAAA,MACE,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,IAEZ;AAAA,MACE,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,EACZ;AAAA,EAGF,UAAU;AAAA,IACR,iBAAiB,MAAM;AACrB,UAAI;AACF,cAAMC,IAAY,OAAO,aAAA;AACzB,YAAI,CAACA,KAAaA,EAAU,eAAe,EAAG,QAAO;AAGrD,YAAIC,IADUD,EAAU,WAAW,CAAC,EACH;AAQjC,aALIC,KAAWA,EAAQ,aAAa,KAAK,cACvCA,IAAUA,EAAQ,gBAIbA,KAAWA,MAAY,SAAS,QAAM;AAC3C,gBAAMC,IAAcD;AACpB,cAAIC,EAAY,WAAWJ,EAAiB,SAASI,EAAY,OAAO;AAEtE,mBAAAA,EAAY,gBAAgB,KAAK,GAC1B;AAET,UAAAD,IAAUC,EAAY;AAAA,QACxB;AAEA,eAAO;AAAA,MACT,SAASC,GAAO;AACd,uBAAQ,MAAM,gCAAgCA,CAAK,GAC5C;AAAA,MACT;AAAA,IACF;AAAA,IAEA,iBAAiB,MAAM;AACrB,UAAI;AACF,cAAMH,IAAY,OAAO,aAAA;AACzB,YAAI,CAACA,KAAaA,EAAU,eAAe,EAAG,QAAO;AAGrD,YAAIC,IADUD,EAAU,WAAW,CAAC,EACH;AAQjC,aALIC,KAAWA,EAAQ,aAAa,KAAK,cACvCA,IAAUA,EAAQ,gBAIbA,KAAWA,MAAY,SAAS,QAAM;AAC3C,gBAAMC,IAAcD;AACpB,cAAIC,EAAY,WAAWJ,EAAiB,SAASI,EAAY,OAAO;AAEtE,mBAAAA,EAAY,aAAa,OAAO,KAAK,GAC9B;AAET,UAAAD,IAAUC,EAAY;AAAA,QACxB;AAEA,eAAO;AAAA,MACT,SAASC,GAAO;AACd,uBAAQ,MAAM,gCAAgCA,CAAK,GAC5C;AAAA,MACT;AAAA,IACF;AAAA,EAAA;AAAA,EAGF,QAAQ;AAAA,IACN,eAAe;AAAA,IACf,eAAe;AAAA,EAAA;AACjB;"}