@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.
Files changed (119) 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/core.css +1 -0
  83. package/dist/documentManager-irzj9n3V.mjs +37627 -0
  84. package/dist/documentManager-irzj9n3V.mjs.map +1 -0
  85. package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
  86. package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
  87. package/dist/editora.min.js +519 -4
  88. package/dist/editora.min.js.map +1 -0
  89. package/dist/editora.umd.js +519 -4
  90. package/dist/editora.umd.js.map +1 -0
  91. package/dist/index-BF5RBhL9.js +4 -0
  92. package/dist/index-BF5RBhL9.js.map +1 -0
  93. package/dist/index-BPsf460l.mjs +1243 -0
  94. package/dist/index-BPsf460l.mjs.map +1 -0
  95. package/dist/index.cjs.js +517 -4
  96. package/dist/index.cjs.js.map +1 -0
  97. package/dist/index.es-CuicffkQ.mjs +6665 -0
  98. package/dist/index.es-CuicffkQ.mjs.map +1 -0
  99. package/dist/index.esm.js +1403 -122
  100. package/dist/index.esm.js.map +1 -0
  101. package/dist/plugin-loader.js +55 -0
  102. package/dist/plugin-loader.js.map +1 -0
  103. package/dist/purify.es-CKpwg8Tk.mjs +471 -0
  104. package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
  105. package/dist/webcomponent-core.js +1243 -0
  106. package/dist/webcomponent-core.js.map +1 -0
  107. package/dist/webcomponent-core.min.css +1 -0
  108. package/dist/webcomponent-core.min.js +597 -0
  109. package/dist/webcomponent-core.min.js.map +1 -0
  110. package/dist/webcomponent.cjs.js +2 -0
  111. package/dist/webcomponent.cjs.js.map +1 -0
  112. package/dist/webcomponent.esm.js +6 -0
  113. package/dist/webcomponent.esm.js.map +1 -0
  114. package/dist/webcomponent.js +1286 -0
  115. package/dist/webcomponent.js.map +1 -0
  116. package/dist/webcomponent.min.css +1 -0
  117. package/dist/webcomponent.min.js +4076 -0
  118. package/dist/webcomponent.min.js.map +1 -0
  119. package/package.json +64 -6
@@ -0,0 +1,449 @@
1
+ let a = null, v = null, y = null, d = "#ffff00";
2
+ const B = [
3
+ "#000000",
4
+ "#ffffff",
5
+ "#808080",
6
+ "#ff0000",
7
+ "#00ff00",
8
+ "#0000ff",
9
+ "#ffff00",
10
+ "#ff00ff",
11
+ "#00ffff",
12
+ "#ffa500",
13
+ "#800080",
14
+ "#ffc0cb"
15
+ ];
16
+ function R() {
17
+ if (document.getElementById("rte-bg-color-picker-styles"))
18
+ return;
19
+ const e = document.createElement("style");
20
+ e.id = "rte-bg-color-picker-styles", e.textContent = `
21
+ /* Background Color Picker Container */
22
+ .rte-bg-color-picker {
23
+ position: absolute;
24
+ background: white;
25
+ border: 1px solid #ccc;
26
+ border-radius: 8px;
27
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
28
+ padding: 16px;
29
+ z-index: 10000;
30
+ width: 220px;
31
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
32
+ font-size: 14px;
33
+ display: flex;
34
+ flex-direction: column;
35
+ gap: 16px;
36
+ }
37
+
38
+ /* Preview Section */
39
+ .rte-bg-color-preview {
40
+ display: flex;
41
+ flex-direction: column;
42
+ gap: 8px;
43
+ }
44
+
45
+ .rte-bg-color-preview-label {
46
+ font-weight: 600;
47
+ color: #333;
48
+ font-size: 13px;
49
+ }
50
+
51
+ .rte-bg-color-preview-box {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 12px;
55
+ padding: 3px;
56
+ background: #f5f5f5;
57
+ border-radius: 4px;
58
+ border: 1px solid #e0e0e0;
59
+ }
60
+
61
+ .rte-bg-color-preview-swatch {
62
+ width: 24px;
63
+ height: 24px;
64
+ border: 2px solid #ddd;
65
+ border-radius: 4px;
66
+ flex-shrink: 0;
67
+ }
68
+
69
+ .rte-bg-color-preview-hex {
70
+ font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
71
+ font-size: 14px;
72
+ font-weight: 600;
73
+ color: #555;
74
+ user-select: all;
75
+ }
76
+
77
+ /* Preset Colors Section */
78
+ .rte-bg-color-section {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: 8px;
82
+ }
83
+
84
+ .rte-bg-color-section-label {
85
+ font-weight: 600;
86
+ color: #333;
87
+ font-size: 13px;
88
+ }
89
+
90
+ .rte-bg-color-grid {
91
+ display: grid;
92
+ grid-template-columns: repeat(7, 1fr);
93
+ gap: 6px;
94
+ max-width: 180px;
95
+ }
96
+
97
+ .rte-bg-color-swatch {
98
+ width: 100%;
99
+ aspect-ratio: 1;
100
+ border: 1px solid #e0e0e0;
101
+ border-radius: 3px;
102
+ cursor: pointer;
103
+ transition: all 0.15s ease;
104
+ padding: 0;
105
+ background: none;
106
+ position: relative;
107
+ min-height: 20px;
108
+ }
109
+
110
+ .rte-bg-color-swatch:hover {
111
+ border-color: #ccc;
112
+ transform: scale(1.05);
113
+ }
114
+
115
+ .rte-bg-color-swatch.selected {
116
+ border-color: #1976d2;
117
+ border-width: 2px;
118
+ transform: scale(1.02);
119
+ }
120
+
121
+ .rte-bg-color-swatch.selected::after {
122
+ content: '✓';
123
+ position: absolute;
124
+ top: 50%;
125
+ left: 50%;
126
+ transform: translate(-50%, -50%);
127
+ color: white;
128
+ font-weight: bold;
129
+ font-size: 12px;
130
+ text-shadow: 0 0 2px rgba(0,0,0,0.5);
131
+ }
132
+
133
+ /* Custom Color Section */
134
+ .rte-bg-color-custom {
135
+ display: flex;
136
+ gap: 8px;
137
+ align-items: center;
138
+ }
139
+
140
+ .rte-bg-color-input {
141
+ width: 50px;
142
+ height: 26px;
143
+ border: 2px solid #ddd;
144
+ border-radius: 4px;
145
+ cursor: pointer;
146
+ padding: 2px;
147
+ background: white;
148
+ }
149
+
150
+ .rte-bg-color-input:hover {
151
+ border-color: #999;
152
+ }
153
+
154
+ .rte-bg-color-text-input {
155
+ flex: 1;
156
+ height: 24px;
157
+ border: 2px solid #ddd;
158
+ border-radius: 4px;
159
+ padding: 0 12px;
160
+ width: 60px;
161
+ font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
162
+ font-size: 14px;
163
+ transition: border-color 0.2s ease;
164
+ }
165
+
166
+ .rte-bg-color-text-input:focus {
167
+ outline: none;
168
+ border-color: #0066cc;
169
+ }
170
+
171
+ .rte-bg-color-text-input::placeholder {
172
+ color: #aaa;
173
+ }
174
+
175
+ /* Action Buttons */
176
+ .rte-bg-color-actions {
177
+ display: flex;
178
+ gap: 8px;
179
+ justify-content: flex-end;
180
+ padding-top: 8px;
181
+ border-top: 1px solid #e0e0e0;
182
+ }
183
+
184
+ .rte-bg-color-btn {
185
+ padding: 8px 16px;
186
+ border: none;
187
+ border-radius: 4px;
188
+ font-size: 13px;
189
+ font-weight: 500;
190
+ cursor: pointer;
191
+ transition: all 0.2s ease;
192
+ }
193
+
194
+ .rte-bg-color-btn-cancel {
195
+ background: #f5f5f5;
196
+ color: #666;
197
+ }
198
+
199
+ .rte-bg-color-btn-cancel:hover {
200
+ background: #e0e0e0;
201
+ }
202
+
203
+ .rte-bg-color-btn-apply {
204
+ background: #0066cc;
205
+ color: white;
206
+ }
207
+
208
+ .rte-bg-color-btn-apply:hover {
209
+ background: #0052a3;
210
+ }
211
+
212
+ .rte-bg-color-btn:active {
213
+ transform: scale(0.98);
214
+ }
215
+ `, document.head.appendChild(e);
216
+ }
217
+ function A() {
218
+ const e = document.createElement("div");
219
+ e.className = "rte-bg-color-picker";
220
+ const r = document.createElement("div");
221
+ r.className = "rte-bg-color-preview";
222
+ const o = document.createElement("div");
223
+ o.className = "rte-bg-color-preview-label", o.textContent = "Current Color";
224
+ const l = document.createElement("div");
225
+ l.className = "rte-bg-color-preview-box";
226
+ const c = document.createElement("div");
227
+ c.className = "rte-bg-color-preview-swatch", c.id = "rte-bg-color-preview-swatch";
228
+ const t = document.createElement("span");
229
+ t.className = "rte-bg-color-preview-hex", t.id = "rte-bg-color-preview-hex", l.appendChild(c), l.appendChild(t), r.appendChild(o), r.appendChild(l);
230
+ const n = document.createElement("div");
231
+ n.className = "rte-bg-color-section";
232
+ const i = document.createElement("div");
233
+ i.className = "rte-bg-color-section-label", i.textContent = "Preset Colors";
234
+ const g = document.createElement("div");
235
+ g.className = "rte-bg-color-grid", g.id = "rte-bg-color-grid", B.forEach((E) => {
236
+ const f = document.createElement("button");
237
+ f.type = "button", f.className = "rte-bg-color-swatch", f.style.backgroundColor = E, f.dataset.color = E, f.title = E, g.appendChild(f);
238
+ }), n.appendChild(i), n.appendChild(g);
239
+ const p = document.createElement("div");
240
+ p.className = "rte-bg-color-section";
241
+ const s = document.createElement("div");
242
+ s.className = "rte-bg-color-section-label", s.textContent = "Custom Color";
243
+ const C = document.createElement("div");
244
+ C.className = "rte-bg-color-custom";
245
+ const b = document.createElement("input");
246
+ b.type = "color", b.className = "rte-bg-color-input", b.id = "rte-bg-color-input", b.value = d;
247
+ const u = document.createElement("input");
248
+ u.type = "text", u.className = "rte-bg-color-text-input", u.id = "rte-bg-color-text-input", u.placeholder = "#FFFF00", u.value = d.toUpperCase(), u.maxLength = 7, C.appendChild(b), C.appendChild(u), p.appendChild(s), p.appendChild(C);
249
+ const k = document.createElement("div");
250
+ k.className = "rte-bg-color-actions";
251
+ const m = document.createElement("button");
252
+ m.type = "button", m.className = "rte-bg-color-btn rte-bg-color-btn-cancel", m.textContent = "Cancel", m.id = "rte-bg-color-cancel";
253
+ const h = document.createElement("button");
254
+ return h.type = "button", h.className = "rte-bg-color-btn rte-bg-color-btn-apply", h.textContent = "Apply", h.id = "rte-bg-color-apply", k.appendChild(m), k.appendChild(h), e.appendChild(r), e.appendChild(n), e.appendChild(p), e;
255
+ }
256
+ function L() {
257
+ if (!a) return;
258
+ const e = a.querySelector("#rte-bg-color-grid");
259
+ e && e.addEventListener("click", (c) => {
260
+ const t = c.target;
261
+ if (t.classList.contains("rte-bg-color-swatch")) {
262
+ const n = t.dataset.color;
263
+ n && (d = n, w(n), x());
264
+ }
265
+ });
266
+ const r = a.querySelector("#rte-bg-color-input");
267
+ r && (r.addEventListener("change", (c) => {
268
+ const t = c.target.value.toUpperCase();
269
+ d = t, w(t), x();
270
+ }), r.addEventListener("input", (c) => {
271
+ d = c.target.value.toUpperCase(), S(), N();
272
+ }));
273
+ const o = a.querySelector("#rte-bg-color-text-input");
274
+ o && (o.addEventListener("change", (c) => {
275
+ let t = c.target.value.trim();
276
+ t && !t.startsWith("#") && (t = "#" + t), /^#[0-9A-F]{6}$/i.test(t) && (d = t.toUpperCase(), w(d), x());
277
+ }), o.addEventListener("input", (c) => {
278
+ let t = c.target.value.trim();
279
+ t && !t.startsWith("#") && (t = "#" + t, o.value = t), /^#[0-9A-F]{6}$/i.test(t) && (d = t.toUpperCase(), S(), N());
280
+ }));
281
+ const l = (c) => {
282
+ if (a && v) {
283
+ const t = c.target;
284
+ !a.contains(t) && !v.contains(t) && x();
285
+ }
286
+ };
287
+ setTimeout(() => {
288
+ document.addEventListener("click", l);
289
+ }, 100), a._clickOutsideHandler = l;
290
+ }
291
+ function S() {
292
+ if (!a) return;
293
+ const e = a.querySelector("#rte-bg-color-preview-swatch"), r = a.querySelector("#rte-bg-color-preview-hex"), o = a.querySelector("#rte-bg-color-input"), l = a.querySelector("#rte-bg-color-text-input");
294
+ e && (e.style.backgroundColor = d), r && (r.textContent = d.toUpperCase()), o && (o.value = d), l && (l.value = d.toUpperCase());
295
+ }
296
+ function N() {
297
+ if (!a) return;
298
+ a.querySelectorAll(".rte-bg-color-swatch").forEach((r) => {
299
+ const o = r.dataset.color;
300
+ (o == null ? void 0 : o.toUpperCase()) === d.toUpperCase() ? r.classList.add("selected") : r.classList.remove("selected");
301
+ });
302
+ }
303
+ function P() {
304
+ try {
305
+ const e = window.getSelection();
306
+ if (!e || e.rangeCount === 0)
307
+ return "#ffff00";
308
+ const o = e.getRangeAt(0).commonAncestorContainer, l = o.nodeType === 1 ? o : o.parentElement;
309
+ if (l) {
310
+ const c = l.closest('[style*="background-color"]');
311
+ if (c) {
312
+ const t = c.style.backgroundColor;
313
+ if (t)
314
+ return T(t);
315
+ }
316
+ }
317
+ return "#ffff00";
318
+ } catch (e) {
319
+ return "#ffff00";
320
+ }
321
+ }
322
+ function T(e) {
323
+ if (e.startsWith("#"))
324
+ return e.toUpperCase();
325
+ const r = e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
326
+ if (r) {
327
+ const o = parseInt(r[1]), l = parseInt(r[2]), c = parseInt(r[3]);
328
+ return "#" + [o, l, c].map((t) => {
329
+ const n = t.toString(16);
330
+ return n.length === 1 ? "0" + n : n;
331
+ }).join("").toUpperCase();
332
+ }
333
+ return "#ffff00";
334
+ }
335
+ function w(e) {
336
+ try {
337
+ if (y) {
338
+ const s = window.getSelection();
339
+ s && (s.removeAllRanges(), s.addRange(y.cloneRange()));
340
+ }
341
+ const r = window.getSelection();
342
+ if (!r || r.rangeCount === 0 || r.isCollapsed)
343
+ return console.warn("[BackgroundColor] No valid selection"), !1;
344
+ const o = r.getRangeAt(0);
345
+ if (o.collapsed)
346
+ return console.warn("[BackgroundColor] Range is collapsed"), !1;
347
+ const l = o.startContainer.nodeType === Node.TEXT_NODE ? o.startContainer.parentElement : o.startContainer, c = o.endContainer.nodeType === Node.TEXT_NODE ? o.endContainer.parentElement : o.endContainer;
348
+ let t = null, n = l;
349
+ for (; n && n !== document.body; ) {
350
+ if (n.classList.contains("rte-bg-color")) {
351
+ const s = document.createRange();
352
+ if (s.selectNodeContents(n), s.compareBoundaryPoints(Range.START_TO_START, o) <= 0 && s.compareBoundaryPoints(Range.END_TO_END, o) >= 0) {
353
+ t = n;
354
+ break;
355
+ }
356
+ }
357
+ n = n.parentElement;
358
+ }
359
+ if (t) {
360
+ t.style.backgroundColor = e;
361
+ const s = t.closest('[contenteditable="true"]') || document.querySelector('[contenteditable="true"]');
362
+ return s && s.dispatchEvent(new Event("input", { bubbles: !0 })), console.log("[BackgroundColor] Updated existing span with color:", e), !0;
363
+ }
364
+ const i = document.createElement("span");
365
+ i.style.backgroundColor = e, i.className = "rte-bg-color";
366
+ const g = o.extractContents();
367
+ i.appendChild(g), o.insertNode(i), o.setStartAfter(i), o.setEndAfter(i), r.removeAllRanges(), r.addRange(o);
368
+ const p = i.closest('[contenteditable="true"]') || document.querySelector('[contenteditable="true"]');
369
+ return p && p.dispatchEvent(new Event("input", { bubbles: !0 })), console.log("[BackgroundColor] Applied color:", e), !0;
370
+ } catch (r) {
371
+ return console.error("[BackgroundColor] Failed to apply background color:", r), !1;
372
+ }
373
+ }
374
+ function x() {
375
+ if (a) {
376
+ const e = a._clickOutsideHandler;
377
+ e && document.removeEventListener("click", e), a.remove(), a = null;
378
+ }
379
+ v = null, y = null;
380
+ }
381
+ function U(e, r) {
382
+ const o = e.getBoundingClientRect(), l = 450, c = 280;
383
+ let t = o.bottom + 5, n = o.left;
384
+ if (n + c > window.innerWidth && (n = window.innerWidth - c - 10), t + l > window.innerHeight) {
385
+ const i = o.top - l - 5;
386
+ i < 0 ? t = window.scrollY + 10 : t = i + window.scrollY;
387
+ } else
388
+ t = t + window.scrollY;
389
+ n < 0 && (n = 10), r.style.top = `${t}px`, r.style.left = `${n}px`;
390
+ }
391
+ function M() {
392
+ if (R(), a)
393
+ return x(), !0;
394
+ const e = document.querySelector('[data-command="openBackgroundColorPicker"]');
395
+ if (!e)
396
+ return !1;
397
+ const r = window.getSelection();
398
+ return !r || r.isCollapsed ? (alert("Please select text to apply background color"), !1) : (r.rangeCount > 0 && (y = r.getRangeAt(0).cloneRange()), d = P(), a = A(), document.body.appendChild(a), v = e, U(e, a), S(), N(), L(), !0);
399
+ }
400
+ const q = () => ({
401
+ name: "backgroundColor",
402
+ marks: {
403
+ backgroundColor: {
404
+ attrs: {
405
+ color: { default: "#ffffff" }
406
+ },
407
+ parseDOM: [
408
+ {
409
+ tag: 'span[style*="background-color"]',
410
+ getAttrs: (e) => {
411
+ const l = (e.getAttribute("style") || "").match(/background-color:\s*([^;]+)/);
412
+ return l ? { color: l[1] } : null;
413
+ }
414
+ },
415
+ {
416
+ tag: "mark",
417
+ getAttrs: (e) => ({ color: e.style.backgroundColor || "#ffff00" })
418
+ }
419
+ ],
420
+ toDOM: (e) => [
421
+ "span",
422
+ {
423
+ style: `background-color: ${e.attrs.color || "#ffffff"}`,
424
+ class: "rte-bg-color"
425
+ },
426
+ 0
427
+ ]
428
+ }
429
+ },
430
+ toolbar: [
431
+ {
432
+ label: "Background Color",
433
+ command: "openBackgroundColorPicker",
434
+ icon: '<svg width="24" height="24" focusable="false"><g fill-rule="evenodd"><path class="tox-icon-highlight-bg-color__color" d="M3 18h18v3H3z" fill="#000000"></path><path fill-rule="nonzero" d="M7.7 16.7H3l3.3-3.3-.7-.8L10.2 8l4 4.1-4 4.2c-.2.2-.6.2-.8 0l-.6-.7-1.1 1.1zm5-7.5L11 7.4l3-2.9a2 2 0 0 1 2.6 0L18 6c.7.7.7 2 0 2.7l-2.9 2.9-1.8-1.8-.5-.6"></path></g></svg>',
435
+ shortcut: "Mod-Shift-h"
436
+ }
437
+ ],
438
+ commands: {
439
+ openBackgroundColorPicker: () => M(),
440
+ setBackgroundColor: (e) => e ? w(e) : !1
441
+ },
442
+ keymap: {
443
+ "Mod-Shift-h": "openBackgroundColorPicker"
444
+ }
445
+ });
446
+ export {
447
+ q as BackgroundColorPlugin
448
+ };
449
+ //# sourceMappingURL=BackgroundColorPlugin.native-Dip5uqTg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackgroundColorPlugin.native-Dip5uqTg.mjs","sources":["../../plugins/background-color/src/BackgroundColorPlugin.native.ts"],"sourcesContent":["import type { Plugin } from '@editora/core';\n\n/**\n * BackgroundColorPlugin - Native implementation with inline color picker\n * \n * Features:\n * - Inline color picker positioned below toolbar button (not modal dialog)\n * - 18 preset colors in 6-column grid\n * - Custom color picker (hex input + native color input)\n * - Real-time color preview with hex display\n * - Apply/Cancel buttons\n * - Click outside to close\n * - Smart positioning to avoid viewport edges\n * - Applies background color (highlight) to selected text\n * \n * Commands:\n * - openBackgroundColorPicker: Opens inline color picker\n * - setBackgroundColor: Sets the background color to specified value\n */\n\n/**\n * Module-level state for the color picker\n */\nlet colorPickerElement: HTMLDivElement | null = null;\nlet currentButton: HTMLElement | null = null;\nlet savedRange: Range | null = null;\nlet selectedColor: string = '#ffff00'; // Default yellow highlight\n\n/**\n * Preset colors for background color - reduced set for smaller picker\n */\nconst PRESET_COLORS = [\n '#000000', '#ffffff', '#808080', '#ff0000', '#00ff00', '#0000ff',\n '#ffff00', '#ff00ff', '#00ffff', '#ffa500', '#800080', '#ffc0cb'\n];\n\n/**\n * Inject CSS styles for the background color picker\n */\nfunction injectStyles() {\n if (document.getElementById('rte-bg-color-picker-styles')) {\n return; // Already injected\n }\n\n const styleElement = document.createElement('style');\n styleElement.id = 'rte-bg-color-picker-styles';\n styleElement.textContent = `\n /* Background Color Picker Container */\n .rte-bg-color-picker {\n position: absolute;\n background: white;\n border: 1px solid #ccc;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 16px;\n z-index: 10000;\n width: 220px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n\n /* Preview Section */\n .rte-bg-color-preview {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .rte-bg-color-preview-label {\n font-weight: 600;\n color: #333;\n font-size: 13px;\n }\n\n .rte-bg-color-preview-box {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 3px;\n background: #f5f5f5;\n border-radius: 4px;\n border: 1px solid #e0e0e0;\n }\n\n .rte-bg-color-preview-swatch {\n width: 24px;\n height: 24px;\n border: 2px solid #ddd;\n border-radius: 4px;\n flex-shrink: 0;\n }\n\n .rte-bg-color-preview-hex {\n font-family: 'Monaco', 'Menlo', 'Courier New', monospace;\n font-size: 14px;\n font-weight: 600;\n color: #555;\n user-select: all;\n }\n\n /* Preset Colors Section */\n .rte-bg-color-section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .rte-bg-color-section-label {\n font-weight: 600;\n color: #333;\n font-size: 13px;\n }\n\n .rte-bg-color-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 6px;\n max-width: 180px;\n }\n\n .rte-bg-color-swatch {\n width: 100%;\n aspect-ratio: 1;\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n cursor: pointer;\n transition: all 0.15s ease;\n padding: 0;\n background: none;\n position: relative;\n min-height: 20px;\n }\n\n .rte-bg-color-swatch:hover {\n border-color: #ccc;\n transform: scale(1.05);\n }\n\n .rte-bg-color-swatch.selected {\n border-color: #1976d2;\n border-width: 2px;\n transform: scale(1.02);\n }\n\n .rte-bg-color-swatch.selected::after {\n content: '✓';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: white;\n font-weight: bold;\n font-size: 12px;\n text-shadow: 0 0 2px rgba(0,0,0,0.5);\n }\n\n /* Custom Color Section */\n .rte-bg-color-custom {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n\n .rte-bg-color-input {\n width: 50px;\n height: 26px;\n border: 2px solid #ddd;\n border-radius: 4px;\n cursor: pointer;\n padding: 2px;\n background: white;\n }\n\n .rte-bg-color-input:hover {\n border-color: #999;\n }\n\n .rte-bg-color-text-input {\n flex: 1;\n height: 24px;\n border: 2px solid #ddd;\n border-radius: 4px;\n padding: 0 12px;\n width: 60px;\n font-family: 'Monaco', 'Menlo', 'Courier New', monospace;\n font-size: 14px;\n transition: border-color 0.2s ease;\n }\n\n .rte-bg-color-text-input:focus {\n outline: none;\n border-color: #0066cc;\n }\n\n .rte-bg-color-text-input::placeholder {\n color: #aaa;\n }\n\n /* Action Buttons */\n .rte-bg-color-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n padding-top: 8px;\n border-top: 1px solid #e0e0e0;\n }\n\n .rte-bg-color-btn {\n padding: 8px 16px;\n border: none;\n border-radius: 4px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .rte-bg-color-btn-cancel {\n background: #f5f5f5;\n color: #666;\n }\n\n .rte-bg-color-btn-cancel:hover {\n background: #e0e0e0;\n }\n\n .rte-bg-color-btn-apply {\n background: #0066cc;\n color: white;\n }\n\n .rte-bg-color-btn-apply:hover {\n background: #0052a3;\n }\n\n .rte-bg-color-btn:active {\n transform: scale(0.98);\n }\n `;\n\n document.head.appendChild(styleElement);\n}\n\n/**\n * Create the inline color picker element\n */\nfunction createColorPicker(): HTMLDivElement {\n const picker = document.createElement('div');\n picker.className = 'rte-bg-color-picker';\n\n // Preview Section\n const previewSection = document.createElement('div');\n previewSection.className = 'rte-bg-color-preview';\n\n const previewLabel = document.createElement('div');\n previewLabel.className = 'rte-bg-color-preview-label';\n previewLabel.textContent = 'Current Color';\n\n const previewBox = document.createElement('div');\n previewBox.className = 'rte-bg-color-preview-box';\n\n const previewSwatch = document.createElement('div');\n previewSwatch.className = 'rte-bg-color-preview-swatch';\n previewSwatch.id = 'rte-bg-color-preview-swatch';\n\n const previewHex = document.createElement('span');\n previewHex.className = 'rte-bg-color-preview-hex';\n previewHex.id = 'rte-bg-color-preview-hex';\n\n previewBox.appendChild(previewSwatch);\n previewBox.appendChild(previewHex);\n previewSection.appendChild(previewLabel);\n previewSection.appendChild(previewBox);\n\n // Preset Colors Section\n const presetSection = document.createElement('div');\n presetSection.className = 'rte-bg-color-section';\n\n const presetLabel = document.createElement('div');\n presetLabel.className = 'rte-bg-color-section-label';\n presetLabel.textContent = 'Preset Colors';\n\n const colorGrid = document.createElement('div');\n colorGrid.className = 'rte-bg-color-grid';\n colorGrid.id = 'rte-bg-color-grid';\n\n PRESET_COLORS.forEach((color) => {\n const swatch = document.createElement('button');\n swatch.type = 'button';\n swatch.className = 'rte-bg-color-swatch';\n swatch.style.backgroundColor = color;\n swatch.dataset.color = color;\n swatch.title = color;\n colorGrid.appendChild(swatch);\n });\n\n presetSection.appendChild(presetLabel);\n presetSection.appendChild(colorGrid);\n\n // Custom Color Section\n const customSection = document.createElement('div');\n customSection.className = 'rte-bg-color-section';\n\n const customLabel = document.createElement('div');\n customLabel.className = 'rte-bg-color-section-label';\n customLabel.textContent = 'Custom Color';\n\n const customDiv = document.createElement('div');\n customDiv.className = 'rte-bg-color-custom';\n\n const colorInput = document.createElement('input');\n colorInput.type = 'color';\n colorInput.className = 'rte-bg-color-input';\n colorInput.id = 'rte-bg-color-input';\n colorInput.value = selectedColor;\n\n const textInput = document.createElement('input');\n textInput.type = 'text';\n textInput.className = 'rte-bg-color-text-input';\n textInput.id = 'rte-bg-color-text-input';\n textInput.placeholder = '#FFFF00';\n textInput.value = selectedColor.toUpperCase();\n textInput.maxLength = 7;\n\n customDiv.appendChild(colorInput);\n customDiv.appendChild(textInput);\n customSection.appendChild(customLabel);\n customSection.appendChild(customDiv);\n\n // Action Buttons\n const actions = document.createElement('div');\n actions.className = 'rte-bg-color-actions';\n\n const cancelBtn = document.createElement('button');\n cancelBtn.type = 'button';\n cancelBtn.className = 'rte-bg-color-btn rte-bg-color-btn-cancel';\n cancelBtn.textContent = 'Cancel';\n cancelBtn.id = 'rte-bg-color-cancel';\n\n const applyBtn = document.createElement('button');\n applyBtn.type = 'button';\n applyBtn.className = 'rte-bg-color-btn rte-bg-color-btn-apply';\n applyBtn.textContent = 'Apply';\n applyBtn.id = 'rte-bg-color-apply';\n\n actions.appendChild(cancelBtn);\n actions.appendChild(applyBtn);\n\n // Assemble picker\n picker.appendChild(previewSection);\n picker.appendChild(presetSection);\n picker.appendChild(customSection);\n\n return picker;\n}\n\n/**\n * Attach event listeners to the color picker\n */\nfunction attachColorPickerListeners() {\n if (!colorPickerElement) return;\n\n // Preset color swatches - apply immediately on click\n const grid = colorPickerElement.querySelector('#rte-bg-color-grid');\n if (grid) {\n grid.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.classList.contains('rte-bg-color-swatch')) {\n const color = target.dataset.color;\n if (color) {\n selectedColor = color;\n applyBackgroundColor(color);\n closeColorPicker();\n }\n }\n });\n }\n\n // Native color input - apply on change\n const colorInput = colorPickerElement.querySelector('#rte-bg-color-input') as HTMLInputElement;\n if (colorInput) {\n colorInput.addEventListener('change', (e) => {\n const color = (e.target as HTMLInputElement).value.toUpperCase();\n selectedColor = color;\n applyBackgroundColor(color);\n closeColorPicker();\n });\n\n // Update preview on input (but don't apply yet)\n colorInput.addEventListener('input', (e) => {\n const color = (e.target as HTMLInputElement).value.toUpperCase();\n selectedColor = color;\n updateColorPreview();\n updateSelectedSwatch();\n });\n }\n\n // Hex text input - apply on valid change\n const textInput = colorPickerElement.querySelector('#rte-bg-color-text-input') as HTMLInputElement;\n if (textInput) {\n textInput.addEventListener('change', (e) => {\n let value = (e.target as HTMLInputElement).value.trim();\n \n // Auto-prepend # if missing\n if (value && !value.startsWith('#')) {\n value = '#' + value;\n }\n \n // Validate and apply hex color format\n if (/^#[0-9A-F]{6}$/i.test(value)) {\n selectedColor = value.toUpperCase();\n applyBackgroundColor(selectedColor);\n closeColorPicker();\n }\n });\n\n // Update preview on input (but don't apply yet)\n textInput.addEventListener('input', (e) => {\n let value = (e.target as HTMLInputElement).value.trim();\n \n // Auto-prepend # if missing\n if (value && !value.startsWith('#')) {\n value = '#' + value;\n textInput.value = value;\n }\n \n // Validate hex color format for preview\n if (/^#[0-9A-F]{6}$/i.test(value)) {\n selectedColor = value.toUpperCase();\n updateColorPreview();\n updateSelectedSwatch();\n }\n });\n }\n\n // Click outside to close\n const handleClickOutside = (e: MouseEvent) => {\n if (colorPickerElement && currentButton) {\n const target = e.target as Node;\n if (!colorPickerElement.contains(target) && !currentButton.contains(target)) {\n closeColorPicker();\n }\n }\n };\n\n // Add slight delay to prevent immediate closure\n setTimeout(() => {\n document.addEventListener('click', handleClickOutside);\n }, 100);\n\n // Store handler for cleanup\n (colorPickerElement as any)._clickOutsideHandler = handleClickOutside;\n}\n\n/**\n * Update the color preview display\n */\nfunction updateColorPreview() {\n if (!colorPickerElement) return;\n\n const previewSwatch = colorPickerElement.querySelector('#rte-bg-color-preview-swatch') as HTMLElement;\n const previewHex = colorPickerElement.querySelector('#rte-bg-color-preview-hex') as HTMLElement;\n const colorInput = colorPickerElement.querySelector('#rte-bg-color-input') as HTMLInputElement;\n const textInput = colorPickerElement.querySelector('#rte-bg-color-text-input') as HTMLInputElement;\n\n if (previewSwatch) {\n previewSwatch.style.backgroundColor = selectedColor;\n }\n if (previewHex) {\n previewHex.textContent = selectedColor.toUpperCase();\n }\n if (colorInput) {\n colorInput.value = selectedColor;\n }\n if (textInput) {\n textInput.value = selectedColor.toUpperCase();\n }\n}\n\n/**\n * Update selected swatch highlight\n */\nfunction updateSelectedSwatch() {\n if (!colorPickerElement) return;\n\n const swatches = colorPickerElement.querySelectorAll('.rte-bg-color-swatch');\n swatches.forEach((swatch) => {\n const swatchColor = (swatch as HTMLElement).dataset.color;\n if (swatchColor?.toUpperCase() === selectedColor.toUpperCase()) {\n swatch.classList.add('selected');\n } else {\n swatch.classList.remove('selected');\n }\n });\n}\n\n/**\n * Get current background color at cursor or selection\n */\nfunction getCurrentBackgroundColor(): string {\n try {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) {\n return '#ffff00'; // Default yellow highlight\n }\n\n const range = selection.getRangeAt(0);\n const container = range.commonAncestorContainer;\n const element = container.nodeType === 1 \n ? (container as HTMLElement)\n : container.parentElement;\n\n if (element) {\n // Check for background-color in style attribute\n const bgElement = element.closest('[style*=\"background-color\"]') as HTMLElement;\n if (bgElement) {\n const bgColor = bgElement.style.backgroundColor;\n if (bgColor) {\n return rgbToHex(bgColor);\n }\n }\n }\n\n return '#ffff00'; // Default yellow highlight\n } catch (error) {\n return '#ffff00';\n }\n}\n\n/**\n * Convert RGB color to hex format\n */\nfunction rgbToHex(rgb: string): string {\n // If already hex, return as-is\n if (rgb.startsWith('#')) {\n return rgb.toUpperCase();\n }\n\n // Parse rgb(r, g, b) or rgba(r, g, b, a)\n const match = rgb.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (match) {\n const r = parseInt(match[1]);\n const g = parseInt(match[2]);\n const b = parseInt(match[3]);\n return '#' + [r, g, b].map(x => {\n const hex = x.toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n }).join('').toUpperCase();\n }\n\n return '#ffff00'; // Default yellow highlight\n}\n\n/**\n * Apply background color to the saved selection\n */\nfunction applyBackgroundColor(color: string): boolean {\n try {\n // Restore saved range\n if (savedRange) {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(savedRange.cloneRange()); // Clone to avoid mutating saved range\n }\n }\n\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {\n console.warn('[BackgroundColor] No valid selection');\n return false;\n }\n\n const range = selection.getRangeAt(0);\n\n // Check if range is valid and has content\n if (range.collapsed) {\n console.warn('[BackgroundColor] Range is collapsed');\n return false;\n }\n\n // Check if the selection is entirely within existing background color spans\n const startElement = range.startContainer.nodeType === Node.TEXT_NODE ? range.startContainer.parentElement : range.startContainer as Element;\n const endElement = range.endContainer.nodeType === Node.TEXT_NODE ? range.endContainer.parentElement : range.endContainer as Element;\n\n // Find the outermost background color span that contains the entire selection\n let targetSpan: Element | null = null;\n let currentElement: Element | null = startElement;\n\n while (currentElement && currentElement !== document.body) {\n if (currentElement.classList.contains('rte-bg-color')) {\n // Check if this span contains the entire selection\n const spanRange = document.createRange();\n spanRange.selectNodeContents(currentElement);\n \n // Check if the selection range is within this span's range\n if (spanRange.compareBoundaryPoints(Range.START_TO_START, range) <= 0 &&\n spanRange.compareBoundaryPoints(Range.END_TO_END, range) >= 0) {\n targetSpan = currentElement;\n break;\n }\n }\n currentElement = currentElement.parentElement;\n }\n\n // If we found a target span that contains the entire selection, just update its background color\n if (targetSpan) {\n targetSpan.style.backgroundColor = color;\n\n // Trigger input event to notify editor\n const editorContent = targetSpan.closest('[contenteditable=\"true\"]') || document.querySelector('[contenteditable=\"true\"]');\n if (editorContent) {\n editorContent.dispatchEvent(new Event('input', { bubbles: true }));\n }\n\n console.log('[BackgroundColor] Updated existing span with color:', color);\n return true;\n }\n\n // No existing span contains the entire selection, create a new one\n const span = document.createElement('span');\n span.style.backgroundColor = color;\n span.className = 'rte-bg-color';\n\n const contents = range.extractContents();\n span.appendChild(contents);\n range.insertNode(span);\n\n // Move cursor to end of inserted span\n range.setStartAfter(span);\n range.setEndAfter(span);\n selection.removeAllRanges();\n selection.addRange(range);\n\n // Trigger input event to notify editor\n const editorContent = span.closest('[contenteditable=\"true\"]') || document.querySelector('[contenteditable=\"true\"]');\n if (editorContent) {\n editorContent.dispatchEvent(new Event('input', { bubbles: true }));\n }\n\n console.log('[BackgroundColor] Applied color:', color);\n return true;\n } catch (error) {\n console.error('[BackgroundColor] Failed to apply background color:', error);\n return false;\n }\n}\n\n\n\n/**\n * Close and cleanup the color picker\n */\nfunction closeColorPicker() {\n if (colorPickerElement) {\n // Remove click outside handler\n const handler = (colorPickerElement as any)._clickOutsideHandler;\n if (handler) {\n document.removeEventListener('click', handler);\n }\n\n colorPickerElement.remove();\n colorPickerElement = null;\n }\n currentButton = null;\n savedRange = null;\n}\n\n/**\n * Position the color picker below the button\n */\nfunction positionColorPicker(button: HTMLElement, picker: HTMLDivElement) {\n const buttonRect = button.getBoundingClientRect();\n const pickerHeight = 450; // Approximate height\n const pickerWidth = 280;\n\n let top = buttonRect.bottom + 5;\n let left = buttonRect.left;\n\n // Adjust if picker would go off right edge\n if (left + pickerWidth > window.innerWidth) {\n left = window.innerWidth - pickerWidth - 10;\n }\n\n // Adjust if picker would go off bottom edge\n if (top + pickerHeight > window.innerHeight) {\n // Try to position above the button\n const topAbove = buttonRect.top - pickerHeight - 5;\n \n // If above position is also off-screen, just position at top of viewport with scroll offset\n if (topAbove < 0) {\n top = window.scrollY + 10; // 10px from top of viewport\n } else {\n top = topAbove + window.scrollY;\n }\n } else {\n // Add scroll offset for below position\n top = top + window.scrollY;\n }\n \n // Ensure left is not negative\n if (left < 0) {\n left = 10;\n }\n\n picker.style.top = `${top}px`;\n picker.style.left = `${left}px`;\n}\n\n/**\n * Open background color picker\n */\nfunction openBackgroundColorPicker(): boolean {\n // Ensure styles are injected\n injectStyles();\n \n // Close any existing picker\n if (colorPickerElement) {\n closeColorPicker();\n return true;\n }\n\n // Find the background color button\n const button = document.querySelector('[data-command=\"openBackgroundColorPicker\"]') as HTMLElement;\n \n if (!button) {\n return false;\n }\n\n // Check if there's a selection\n const selection = window.getSelection();\n \n if (!selection || selection.isCollapsed) {\n alert('Please select text to apply background color');\n return false;\n }\n\n // Save current selection\n if (selection.rangeCount > 0) {\n savedRange = selection.getRangeAt(0).cloneRange();\n }\n\n // Get current color\n selectedColor = getCurrentBackgroundColor();\n\n // Create and show picker\n colorPickerElement = createColorPicker();\n document.body.appendChild(colorPickerElement);\n\n currentButton = button;\n positionColorPicker(button, colorPickerElement);\n\n // Initialize preview\n updateColorPreview();\n updateSelectedSwatch();\n\n // Attach listeners\n attachColorPickerListeners();\n\n return true;\n}\n\n/**\n * Auto-initialization\n */\n// Note: Auto-initialization removed - picker is now opened via command handler\n// The openBackgroundColorPicker() function is called directly by RichTextEditor\n// when the toolbar button is clicked, preventing race conditions\n\nexport const BackgroundColorPlugin = (): Plugin => {\n return {\n name: \"backgroundColor\",\n\n marks: {\n backgroundColor: {\n attrs: {\n color: { default: '#ffffff' },\n },\n parseDOM: [\n {\n tag: 'span[style*=\"background-color\"]',\n getAttrs: (dom) => {\n const element = dom as HTMLElement;\n const style = element.getAttribute('style') || '';\n const colorMatch = style.match(/background-color:\\s*([^;]+)/);\n if (colorMatch) {\n return { color: colorMatch[1] };\n }\n return null;\n },\n },\n {\n tag: \"mark\",\n getAttrs: (dom) => {\n const element = dom as HTMLElement;\n const color = element.style.backgroundColor || \"#ffff00\";\n return { color };\n },\n },\n ],\n toDOM: (mark) => {\n return [\n \"span\",\n { \n style: `background-color: ${mark.attrs.color || '#ffffff'}`,\n class: 'rte-bg-color'\n },\n 0,\n ];\n },\n },\n },\n\n toolbar: [\n {\n label: \"Background Color\",\n command: \"openBackgroundColorPicker\",\n icon: `<svg width=\"24\" height=\"24\" focusable=\"false\"><g fill-rule=\"evenodd\"><path class=\"tox-icon-highlight-bg-color__color\" d=\"M3 18h18v3H3z\" fill=\"#000000\"></path><path fill-rule=\"nonzero\" d=\"M7.7 16.7H3l3.3-3.3-.7-.8L10.2 8l4 4.1-4 4.2c-.2.2-.6.2-.8 0l-.6-.7-1.1 1.1zm5-7.5L11 7.4l3-2.9a2 2 0 0 1 2.6 0L18 6c.7.7.7 2 0 2.7l-2.9 2.9-1.8-1.8-.5-.6\"></path></g></svg>`,\n shortcut: \"Mod-Shift-h\",\n },\n ],\n\n commands: {\n openBackgroundColorPicker: () => {\n return openBackgroundColorPicker();\n },\n\n setBackgroundColor: (color?: string) => {\n if (!color) return false;\n return applyBackgroundColor(color);\n },\n },\n\n keymap: {\n 'Mod-Shift-h': 'openBackgroundColorPicker',\n },\n };\n};\n"],"names":["colorPickerElement","currentButton","savedRange","selectedColor","PRESET_COLORS","injectStyles","styleElement","createColorPicker","picker","previewSection","previewLabel","previewBox","previewSwatch","previewHex","presetSection","presetLabel","colorGrid","color","swatch","customSection","customLabel","customDiv","colorInput","textInput","actions","cancelBtn","applyBtn","attachColorPickerListeners","grid","e","target","applyBackgroundColor","closeColorPicker","updateColorPreview","updateSelectedSwatch","value","handleClickOutside","swatchColor","getCurrentBackgroundColor","selection","container","element","bgElement","bgColor","rgbToHex","error","rgb","match","r","g","b","x","hex","range","startElement","endElement","targetSpan","currentElement","spanRange","editorContent","span","contents","handler","positionColorPicker","button","buttonRect","pickerHeight","pickerWidth","top","left","topAbove","openBackgroundColorPicker","BackgroundColorPlugin","dom","colorMatch","mark"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ const c = () => ({
2
+ name: "blockquote",
3
+ // Schema definition for blockquote node
4
+ nodes: {
5
+ blockquote: {
6
+ content: "block+",
7
+ group: "block",
8
+ parseDOM: [{ tag: "blockquote" }],
9
+ toDOM: () => ["blockquote", 0]
10
+ }
11
+ },
12
+ // Toolbar button configuration
13
+ toolbar: [
14
+ {
15
+ label: "Quote",
16
+ command: "toggleBlockquote",
17
+ icon: '<svg fill="#000000" height="24px" width="24px" version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <path d="M13,11c0.6,0,1-0.4,1-1s-0.4-1-1-1c-5,0-9,4-9,9c0,2.8,2.2,5,5,5s5-2.2,5-5s-2.2-5-5-5c-0.3,0-0.7,0-1,0.1 C9.3,11.8,11,11,13,11z"></path> <path d="M23,13c-0.3,0-0.7,0-1,0.1c1.3-1.3,3-2.1,5-2.1c0.6,0,1-0.4,1-1s-0.4-1-1-1c-5,0-9,4-9,9c0,2.8,2.2,5,5,5s5-2.2,5-5 S25.8,13,23,13z"></path> </g> </g></svg>',
18
+ shortcut: "Mod-Shift-9"
19
+ }
20
+ ],
21
+ // Native command implementations
22
+ commands: {
23
+ /**
24
+ * Toggle blockquote formatting on current selection
25
+ */
26
+ toggleBlockquote: () => {
27
+ const e = window.getSelection();
28
+ if (!e || e.rangeCount === 0) return !1;
29
+ let o = e.anchorNode, t = !1;
30
+ for (; o && o !== document.body; ) {
31
+ if (o.nodeName === "BLOCKQUOTE") {
32
+ t = !0;
33
+ break;
34
+ }
35
+ o = o.parentNode;
36
+ }
37
+ return t ? document.execCommand("formatBlock", !1, "p") : document.execCommand("formatBlock", !1, "blockquote"), !0;
38
+ }
39
+ },
40
+ // Keyboard shortcuts
41
+ keymap: {
42
+ "Mod-Shift-9": "toggleBlockquote"
43
+ }
44
+ });
45
+ export {
46
+ c as BlockquotePlugin
47
+ };
48
+ //# sourceMappingURL=BlockquotePlugin.native-JFmOLsxN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlockquotePlugin.native-JFmOLsxN.mjs","sources":["../../plugins/blockquote/src/BlockquotePlugin.native.ts"],"sourcesContent":["import { Plugin } from '@editora/core';\n\n/**\n * Blockquote Plugin - Framework Agnostic\n * \n * Adds blockquote support with native command implementation.\n * No React dependency required.\n */\nexport const BlockquotePlugin = (): Plugin => ({\n name: \"blockquote\",\n\n // Schema definition for blockquote node\n nodes: {\n blockquote: {\n content: \"block+\",\n group: \"block\",\n parseDOM: [{ tag: \"blockquote\" }],\n toDOM: () => [\"blockquote\", 0],\n },\n },\n\n // Toolbar button configuration\n toolbar: [\n {\n label: \"Quote\",\n command: \"toggleBlockquote\",\n icon: '<svg fill=\"#000000\" height=\"24px\" width=\"24px\" version=\"1.1\" id=\"Icons\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" xml:space=\"preserve\"><g id=\"SVGRepo_bgCarrier\" stroke-width=\"0\"></g><g id=\"SVGRepo_tracerCarrier\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></g><g id=\"SVGRepo_iconCarrier\"> <g> <path d=\"M13,11c0.6,0,1-0.4,1-1s-0.4-1-1-1c-5,0-9,4-9,9c0,2.8,2.2,5,5,5s5-2.2,5-5s-2.2-5-5-5c-0.3,0-0.7,0-1,0.1 C9.3,11.8,11,11,13,11z\"></path> <path d=\"M23,13c-0.3,0-0.7,0-1,0.1c1.3-1.3,3-2.1,5-2.1c0.6,0,1-0.4,1-1s-0.4-1-1-1c-5,0-9,4-9,9c0,2.8,2.2,5,5,5s5-2.2,5-5 S25.8,13,23,13z\"></path> </g> </g></svg>',\n shortcut: \"Mod-Shift-9\",\n },\n ],\n\n // Native command implementations\n commands: {\n /**\n * Toggle blockquote formatting on current selection\n */\n toggleBlockquote: () => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return false;\n\n // Check if already in blockquote\n let node = selection.anchorNode;\n let isInBlockquote = false;\n\n while (node && node !== document.body) {\n if (node.nodeName === \"BLOCKQUOTE\") {\n isInBlockquote = true;\n break;\n }\n node = node.parentNode;\n }\n\n if (isInBlockquote) {\n // Remove blockquote\n document.execCommand(\"formatBlock\", false, \"p\");\n } else {\n // Add blockquote\n document.execCommand(\"formatBlock\", false, \"blockquote\");\n }\n\n return true;\n },\n },\n\n // Keyboard shortcuts\n keymap: {\n \"Mod-Shift-9\": \"toggleBlockquote\",\n },\n});\n"],"names":["BlockquotePlugin","selection","node","isInBlockquote"],"mappings":"AAQO,MAAMA,IAAmB,OAAe;AAAA,EAC7C,MAAM;AAAA;AAAA,EAGN,OAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU,CAAC,EAAE,KAAK,cAAc;AAAA,MAChC,OAAO,MAAM,CAAC,cAAc,CAAC;AAAA,IAAA;AAAA,EAC/B;AAAA;AAAA,EAIF,SAAS;AAAA,IACP;AAAA,MACE,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,EACZ;AAAA;AAAA,EAIF,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,kBAAkB,MAAM;AACtB,YAAMC,IAAY,OAAO,aAAA;AACzB,UAAI,CAACA,KAAaA,EAAU,eAAe,EAAG,QAAO;AAGrD,UAAIC,IAAOD,EAAU,YACjBE,IAAiB;AAErB,aAAOD,KAAQA,MAAS,SAAS,QAAM;AACrC,YAAIA,EAAK,aAAa,cAAc;AAClC,UAAAC,IAAiB;AACjB;AAAA,QACF;AACA,QAAAD,IAAOA,EAAK;AAAA,MACd;AAEA,aAAIC,IAEF,SAAS,YAAY,eAAe,IAAO,GAAG,IAG9C,SAAS,YAAY,eAAe,IAAO,YAAY,GAGlD;AAAA,IACT;AAAA,EAAA;AAAA;AAAA,EAIF,QAAQ;AAAA,IACN,eAAe;AAAA,EAAA;AAEnB;"}
@@ -0,0 +1,45 @@
1
+ const e = () => ({
2
+ name: "bold",
3
+ // Schema definition for bold mark
4
+ marks: {
5
+ bold: {
6
+ parseDOM: [
7
+ { tag: "strong" },
8
+ { tag: "b" },
9
+ {
10
+ style: "font-weight",
11
+ getAttrs: (t) => {
12
+ const o = typeof t == "string" ? t : t.style.fontWeight;
13
+ return /^(bold(er)?|[5-9]\d{2,})$/.test(o) && null;
14
+ }
15
+ }
16
+ ],
17
+ toDOM: () => ["strong", 0]
18
+ }
19
+ },
20
+ // Toolbar button configuration
21
+ toolbar: [
22
+ {
23
+ label: "Bold",
24
+ command: "toggleBold",
25
+ icon: '<svg width="24" height="24" focusable="false"><path d="M7.8 19c-.3 0-.5 0-.6-.2l-.2-.5V5.7c0-.2 0-.4.2-.5l.6-.2h5c1.5 0 2.7.3 3.5 1 .7.6 1.1 1.4 1.1 2.5a3 3 0 0 1-.6 1.9c-.4.6-1 1-1.6 1.2.4.1.9.3 1.3.6s.8.7 1 1.2c.4.4.5 1 .5 1.6 0 1.3-.4 2.3-1.3 3-.8.7-2.1 1-3.8 1H7.8Zm5-8.3c.6 0 1.2-.1 1.6-.5.4-.3.6-.7.6-1.3 0-1.1-.8-1.7-2.3-1.7H9.3v3.5h3.4Zm.5 6c.7 0 1.3-.1 1.7-.4.4-.4.6-.9.6-1.5s-.2-1-.7-1.4c-.4-.3-1-.4-2-.4H9.4v3.8h4Z" fill-rule="evenodd"></path></svg>',
26
+ shortcut: "Mod-b"
27
+ }
28
+ ],
29
+ // Native command implementations
30
+ commands: {
31
+ /**
32
+ * Toggle bold formatting on current selection
33
+ */
34
+ toggleBold: () => (document.execCommand("bold", !1), !0)
35
+ },
36
+ // Keyboard shortcuts
37
+ keymap: {
38
+ "Mod-b": "toggleBold",
39
+ "Mod-B": "toggleBold"
40
+ }
41
+ });
42
+ export {
43
+ e as BoldPlugin
44
+ };
45
+ //# sourceMappingURL=BoldPlugin.native-BAzzoqU5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoldPlugin.native-BAzzoqU5.mjs","sources":["../../plugins/bold/src/BoldPlugin.native.ts"],"sourcesContent":["import { Plugin } from '@editora/core';\n\n/**\n * Bold Plugin - Framework Agnostic\n * \n * Adds bold formatting support with native command implementation.\n * No React dependency required.\n */\nexport const BoldPlugin = (): Plugin => ({\n name: \"bold\",\n\n // Schema definition for bold mark\n marks: {\n bold: {\n parseDOM: [\n { tag: \"strong\" },\n { tag: \"b\" },\n {\n style: \"font-weight\",\n getAttrs: (value: string | HTMLElement) => {\n const weight =\n typeof value === \"string\"\n ? value\n : (value as HTMLElement).style.fontWeight;\n return /^(bold(er)?|[5-9]\\d{2,})$/.test(weight) && null;\n },\n },\n ],\n toDOM: () => [\"strong\", 0],\n },\n },\n\n // Toolbar button configuration\n toolbar: [\n {\n label: \"Bold\",\n command: \"toggleBold\",\n icon: '<svg width=\"24\" height=\"24\" focusable=\"false\"><path d=\"M7.8 19c-.3 0-.5 0-.6-.2l-.2-.5V5.7c0-.2 0-.4.2-.5l.6-.2h5c1.5 0 2.7.3 3.5 1 .7.6 1.1 1.4 1.1 2.5a3 3 0 0 1-.6 1.9c-.4.6-1 1-1.6 1.2.4.1.9.3 1.3.6s.8.7 1 1.2c.4.4.5 1 .5 1.6 0 1.3-.4 2.3-1.3 3-.8.7-2.1 1-3.8 1H7.8Zm5-8.3c.6 0 1.2-.1 1.6-.5.4-.3.6-.7.6-1.3 0-1.1-.8-1.7-2.3-1.7H9.3v3.5h3.4Zm.5 6c.7 0 1.3-.1 1.7-.4.4-.4.6-.9.6-1.5s-.2-1-.7-1.4c-.4-.3-1-.4-2-.4H9.4v3.8h4Z\" fill-rule=\"evenodd\"></path></svg>',\n shortcut: \"Mod-b\",\n },\n ],\n\n // Native command implementations\n commands: {\n /**\n * Toggle bold formatting on current selection\n */\n toggleBold: () => {\n // Use document.execCommand for now\n // In production, this would manipulate EditorState directly\n document.execCommand(\"bold\", false);\n return true;\n },\n },\n\n // Keyboard shortcuts\n keymap: {\n \"Mod-b\": \"toggleBold\",\n \"Mod-B\": \"toggleBold\",\n },\n});\n"],"names":["BoldPlugin","value","weight"],"mappings":"AAQO,MAAMA,IAAa,OAAe;AAAA,EACvC,MAAM;AAAA;AAAA,EAGN,OAAO;AAAA,IACL,MAAM;AAAA,MACJ,UAAU;AAAA,QACR,EAAE,KAAK,SAAA;AAAA,QACP,EAAE,KAAK,IAAA;AAAA,QACP;AAAA,UACE,OAAO;AAAA,UACP,UAAU,CAACC,MAAgC;AACzC,kBAAMC,IACJ,OAAOD,KAAU,WACbA,IACCA,EAAsB,MAAM;AACnC,mBAAO,4BAA4B,KAAKC,CAAM,KAAK;AAAA,UACrD;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,OAAO,MAAM,CAAC,UAAU,CAAC;AAAA,IAAA;AAAA,EAC3B;AAAA;AAAA,EAIF,SAAS;AAAA,IACP;AAAA,MACE,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,IAAA;AAAA,EACZ;AAAA;AAAA,EAIF,UAAU;AAAA;AAAA;AAAA;AAAA,IAIR,YAAY,OAGV,SAAS,YAAY,QAAQ,EAAK,GAC3B;AAAA,EACT;AAAA;AAAA,EAIF,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,EAAA;AAEb;"}