@editora/plugins 1.0.2 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +30 -5
  2. package/dist/a11y-checker.cjs.js +109 -0
  3. package/dist/a11y-checker.esm.js +509 -0
  4. package/dist/anchor.cjs.js +176 -0
  5. package/dist/anchor.esm.js +400 -0
  6. package/dist/background-color.cjs.js +218 -0
  7. package/dist/background-color.esm.js +482 -0
  8. package/dist/blockquote.cjs.js +1 -0
  9. package/dist/blockquote.esm.js +47 -0
  10. package/dist/bold.cjs.js +1 -0
  11. package/dist/bold.esm.js +44 -0
  12. package/dist/capitalization.cjs.js +1 -0
  13. package/dist/capitalization.esm.js +78 -0
  14. package/dist/checklist.cjs.js +1 -0
  15. package/dist/checklist.esm.js +305 -0
  16. package/dist/clear-formatting.cjs.js +1 -0
  17. package/dist/clear-formatting.esm.js +138 -0
  18. package/dist/code-sample.cjs.js +161 -0
  19. package/dist/code-sample.esm.js +381 -0
  20. package/dist/code.cjs.js +606 -0
  21. package/dist/code.esm.js +2164 -0
  22. package/dist/colorSelectionApply-C0iOfMWb.js +1 -0
  23. package/dist/colorSelectionApply-D8r_gV32.mjs +63 -0
  24. package/dist/comments.cjs.js +354 -0
  25. package/dist/comments.esm.js +692 -0
  26. package/dist/direction.cjs.js +1 -0
  27. package/dist/direction.esm.js +129 -0
  28. package/dist/document-manager.cjs.js +1 -0
  29. package/dist/document-manager.esm.js +6 -0
  30. package/dist/{documentManager-CYC9totK.mjs → documentManager-DRUc1-Cs.mjs} +3 -3
  31. package/dist/{documentManager-BGlu3WRB.js → documentManager-_tQQfQi9.js} +3 -3
  32. package/dist/editorContainerHelpers-C7kdWnS0.mjs +26 -0
  33. package/dist/editorContainerHelpers-CFbfiOJI.js +1 -0
  34. package/dist/embed-iframe.cjs.js +361 -0
  35. package/dist/embed-iframe.esm.js +556 -0
  36. package/dist/emojis.cjs.js +284 -0
  37. package/dist/emojis.esm.js +1080 -0
  38. package/dist/font-family.cjs.js +1 -0
  39. package/dist/font-family.esm.js +152 -0
  40. package/dist/font-size.cjs.js +1 -0
  41. package/dist/font-size.esm.js +278 -0
  42. package/dist/footnote.cjs.js +85 -0
  43. package/dist/footnote.esm.js +397 -0
  44. package/dist/fullscreen.cjs.js +1 -0
  45. package/dist/fullscreen.esm.js +73 -0
  46. package/dist/heading.cjs.js +1 -0
  47. package/dist/heading.esm.js +63 -0
  48. package/dist/history.cjs.js +1 -0
  49. package/dist/history.esm.js +246 -0
  50. package/dist/indent.cjs.js +1 -0
  51. package/dist/indent.esm.js +146 -0
  52. package/dist/index-Bskk414V.mjs +145 -0
  53. package/dist/index-D3pJyAsj.js +1 -0
  54. package/dist/index.cjs.js +1 -1
  55. package/dist/{index.es-B-to-4j4.js → index.es-Cz1qItab.js} +1 -1
  56. package/dist/{index.es-BbXJ7tyO.mjs → index.es-DEcRmSTY.mjs} +1 -1
  57. package/dist/index.esm.js +89 -49
  58. package/dist/italic.cjs.js +1 -0
  59. package/dist/italic.esm.js +40 -0
  60. package/dist/line-height.cjs.js +1 -0
  61. package/dist/line-height.esm.js +145 -0
  62. package/dist/link.cjs.js +138 -0
  63. package/dist/link.esm.js +276 -0
  64. package/dist/list.cjs.js +1 -0
  65. package/dist/list.esm.js +102 -0
  66. package/dist/lite.cjs.js +1 -0
  67. package/dist/lite.esm.js +61 -0
  68. package/dist/math.cjs.js +45 -0
  69. package/dist/math.esm.js +249 -0
  70. package/dist/media-manager.cjs.js +619 -0
  71. package/dist/media-manager.esm.js +994 -0
  72. package/dist/merge-tag.cjs.js +93 -0
  73. package/dist/merge-tag.esm.js +412 -0
  74. package/dist/page-break.cjs.js +72 -0
  75. package/dist/page-break.esm.js +295 -0
  76. package/dist/plugins.css +1 -1
  77. package/dist/preview.cjs.js +230 -0
  78. package/dist/preview.esm.js +321 -0
  79. package/dist/print.cjs.js +254 -0
  80. package/dist/print.esm.js +309 -0
  81. package/dist/purify.es-DHhaBdbu.mjs +470 -0
  82. package/dist/purify.es-T2a3nLiC.js +3 -0
  83. package/dist/shared-config.cjs.js +1 -0
  84. package/dist/shared-config.esm.js +30 -0
  85. package/dist/special-characters.cjs.js +257 -0
  86. package/dist/special-characters.esm.js +772 -0
  87. package/dist/spell-check.cjs.js +512 -0
  88. package/dist/spell-check.esm.js +1013 -0
  89. package/dist/strikethrough.cjs.js +1 -0
  90. package/dist/strikethrough.esm.js +71 -0
  91. package/dist/table.cjs.js +35 -0
  92. package/dist/table.esm.js +477 -0
  93. package/dist/template.cjs.js +356 -0
  94. package/dist/template.esm.js +560 -0
  95. package/dist/text-alignment.cjs.js +1 -0
  96. package/dist/text-alignment.esm.js +105 -0
  97. package/dist/text-color.cjs.js +300 -0
  98. package/dist/text-color.esm.js +507 -0
  99. package/dist/underline.cjs.js +1 -0
  100. package/dist/underline.esm.js +34 -0
  101. package/index.d.ts +62 -0
  102. package/package.json +220 -7
  103. package/LICENSE +0 -21
  104. package/dist/index-BbORIHoM.mjs +0 -11763
  105. package/dist/index-C-OCBS_6.js +0 -3753
@@ -0,0 +1,560 @@
1
+ import S from "./purify.es-DHhaBdbu.mjs";
2
+ let o = null, d = null, s = null, n = null, p = "", m = "", g = "insert";
3
+ const M = [
4
+ {
5
+ id: "formal-letter",
6
+ name: "Formal Letter",
7
+ category: "Letters",
8
+ description: "Professional business letter template",
9
+ html: `<p><strong>{{ Company Name }}</strong></p>
10
+ <p>{{ Today }}</p>
11
+ <p>Dear {{ first_name }} {{ last_name }},</p>
12
+ <p>I hope this letter finds you well. [Your letter content here]</p>
13
+ <p>Thank you for your time and consideration.</p>
14
+ <p>Sincerely,<br>Your Name</p>`
15
+ },
16
+ {
17
+ id: "meeting-notes",
18
+ name: "Meeting Notes",
19
+ category: "Notes",
20
+ description: "Template for meeting notes with attendees and action items",
21
+ html: `<h2>Meeting Notes - {{ today }}</h2>
22
+ <p><strong>Attendees:</strong> [List attendees]</p>
23
+ <p><strong>Agenda:</strong></p>
24
+ <ul>
25
+ <li>[Item 1]</li>
26
+ <li>[Item 2]</li>
27
+ <li>[Item 3]</li>
28
+ </ul>
29
+ <p><strong>Action Items:</strong></p>
30
+ <ul>
31
+ <li>[Owner]: [Task] - [Due Date]</li>
32
+ </ul>
33
+ <p><strong>Next Meeting:</strong> [Date]</p>`
34
+ },
35
+ {
36
+ id: "proposal",
37
+ name: "Project Proposal",
38
+ category: "Business",
39
+ description: "Structured project proposal template",
40
+ html: `<h1>Project Proposal</h1>
41
+ <h2>Executive Summary</h2>
42
+ <p>[Summary of the proposal]</p>
43
+ <h2>Objectives</h2>
44
+ <ul>
45
+ <li>[Objective 1]</li>
46
+ <li>[Objective 2]</li>
47
+ </ul>
48
+ <h2>Scope</h2>
49
+ <p>[Project scope details]</p>
50
+ <h2>Timeline</h2>
51
+ <p>[Project timeline]</p>
52
+ <h2>Budget</h2>
53
+ <p>[Budget details]</p>
54
+ <h2>Contact</h2>
55
+ <p>{{ first_name }} {{ last_name }}<br>{{ email }}<br>{{ phone }}</p>`
56
+ },
57
+ {
58
+ id: "faq",
59
+ name: "FAQ Template",
60
+ category: "Documentation",
61
+ description: "FAQ document structure",
62
+ html: `<h1>Frequently Asked Questions</h1>
63
+ <h2>General Questions</h2>
64
+ <h3>Q: What is this about?</h3>
65
+ <p>A: [Answer here]</p>
66
+ <h3>Q: Who should use this?</h3>
67
+ <p>A: [Answer here]</p>
68
+ <h2>Technical Questions</h2>
69
+ <h3>Q: How do I get started?</h3>
70
+ <p>A: [Answer here]</p>
71
+ <h3>Q: What are the requirements?</h3>
72
+ <p>A: [Answer here]</p>`
73
+ }
74
+ ];
75
+ let w = [...M];
76
+ const y = () => w, k = () => {
77
+ const t = new Set(w.map((e) => e.category));
78
+ return Array.from(t);
79
+ }, R = (t) => {
80
+ const e = t.toLowerCase();
81
+ return w.filter(
82
+ (r) => r.name.toLowerCase().includes(e) || r.description?.toLowerCase().includes(e) || r.tags?.some((l) => l.toLowerCase().includes(e))
83
+ );
84
+ }, L = (t) => S.sanitize(t, {
85
+ ALLOWED_TAGS: ["p", "br", "strong", "em", "u", "h1", "h2", "h3", "h4", "ul", "ol", "li", "blockquote", "table", "thead", "tbody", "tr", "th", "td", "a", "span"],
86
+ ALLOWED_ATTR: ["href", "target", "class", "data-key", "data-category"]
87
+ });
88
+ function D(t) {
89
+ d = document.createElement("div"), d.className = "rte-dialog-overlay", N(t) && d.classList.add("rte-ui-theme-dark"), d.addEventListener("click", () => c()), o = document.createElement("div"), o.className = "rte-dialog rte-template-dialog", o.addEventListener("click", (r) => r.stopPropagation());
90
+ const e = k();
91
+ e.length > 0 && !p && (p = e[0]), b(), d.appendChild(o), document.body.appendChild(d), z();
92
+ }
93
+ const H = '[data-theme="dark"], .dark, .editora-theme-dark', A = () => {
94
+ const t = window.getSelection();
95
+ if (!t || t.rangeCount === 0) return null;
96
+ const e = t.anchorNode;
97
+ return (e instanceof HTMLElement ? e : e?.parentElement)?.closest(
98
+ ".rte-content, .editora-content"
99
+ ) || null;
100
+ }, N = (t) => {
101
+ const e = t || A();
102
+ return e ? !!e.closest(H) : !1;
103
+ };
104
+ function b() {
105
+ if (!o) return;
106
+ const t = k(), e = E();
107
+ o.innerHTML = `
108
+ <div class="rte-dialog-header">
109
+ <h2>Insert Template</h2>
110
+ <button class="rte-dialog-close" aria-label="Close">✕</button>
111
+ </div>
112
+
113
+ <div class="rte-dialog-body">
114
+ <!-- Search -->
115
+ <input
116
+ type="text"
117
+ placeholder="Search templates..."
118
+ value="${m}"
119
+ class="rte-input rte-template-search"
120
+ aria-label="Search templates"
121
+ />
122
+
123
+ <!-- Category Tabs -->
124
+ <div class="rte-tabs">
125
+ ${t.map((r) => `
126
+ <button class="rte-tab ${p === r ? "active" : ""}" data-category="${r}">
127
+ ${r}
128
+ </button>
129
+ `).join("")}
130
+ </div>
131
+
132
+ <!-- Template List -->
133
+ <div class="rte-template-list">
134
+ ${e.length > 0 ? e.map((r) => `
135
+ <div
136
+ class="rte-template-item ${n?.id === r.id ? "selected" : ""}"
137
+ data-template-id="${r.id}"
138
+ >
139
+ <div class="template-name">${r.name}</div>
140
+ ${r.description ? `<div class="template-description">${r.description}</div>` : ""}
141
+ </div>
142
+ `).join("") : '<div class="rte-empty-state">No templates found</div>'}
143
+ </div>
144
+
145
+ <!-- Preview -->
146
+ ${n ? `
147
+ <div class="rte-template-preview">
148
+ <strong>Preview:</strong>
149
+ <div class="template-preview-content">${n.html}</div>
150
+ </div>
151
+ ` : ""}
152
+
153
+ <!-- Insert Mode Toggle -->
154
+ <div class="rte-insert-mode">
155
+ <label>
156
+ <input type="radio" name="insertMode" value="insert" ${g === "insert" ? "checked" : ""} />
157
+ Insert at cursor
158
+ </label>
159
+ <label>
160
+ <input type="radio" name="insertMode" value="replace" ${g === "replace" ? "checked" : ""} />
161
+ Replace document
162
+ </label>
163
+ </div>
164
+ </div>
165
+
166
+ <div class="rte-dialog-footer">
167
+ <button class="rte-button-secondary rte-cancel-btn">Cancel</button>
168
+ <button class="rte-button-primary rte-insert-btn" ${n ? "" : "disabled"}>
169
+ ${g === "insert" ? "Insert" : "Replace"}
170
+ </button>
171
+ </div>
172
+ `, V();
173
+ }
174
+ function I() {
175
+ if (!o) return;
176
+ o.innerHTML = `
177
+ <div class="rte-dialog-header">
178
+ <h2>Replace Document?</h2>
179
+ </div>
180
+ <div class="rte-dialog-body">
181
+ <p>This will replace your current document content. Continue?</p>
182
+ </div>
183
+ <div class="rte-dialog-footer">
184
+ <button class="rte-button-secondary rte-cancel-warning-btn">Cancel</button>
185
+ <button class="rte-button-primary rte-confirm-replace-btn">Replace</button>
186
+ </div>
187
+ `;
188
+ const t = o.querySelector(".rte-cancel-warning-btn"), e = o.querySelector(".rte-confirm-replace-btn");
189
+ t?.addEventListener("click", () => b()), e?.addEventListener("click", () => $());
190
+ }
191
+ function E() {
192
+ const t = y();
193
+ return m.trim() ? R(m) : p ? t.filter((e) => e.category === p) : t;
194
+ }
195
+ function V() {
196
+ if (!o) return;
197
+ o.querySelector(".rte-dialog-close")?.addEventListener("click", () => c()), o.querySelector(".rte-cancel-btn")?.addEventListener("click", () => c()), o.querySelector(".rte-insert-btn")?.addEventListener("click", () => x());
198
+ const l = o.querySelector(".rte-template-search");
199
+ l?.addEventListener("input", (a) => {
200
+ m = a.target.value, T();
201
+ }), l?.addEventListener("keydown", (a) => {
202
+ a.key === "Enter" && n ? x() : a.key === "Escape" && c();
203
+ }), o.querySelectorAll(".rte-tab").forEach((a) => {
204
+ a.addEventListener("click", () => {
205
+ const i = a.getAttribute("data-category");
206
+ i && (p = i, m = "", T());
207
+ });
208
+ }), o.querySelectorAll(".rte-template-item").forEach((a) => {
209
+ a.addEventListener("click", () => {
210
+ const i = a.getAttribute("data-template-id");
211
+ if (i) {
212
+ const u = y().find((v) => v.id === i);
213
+ u && (n = u, b());
214
+ }
215
+ }), a.addEventListener("dblclick", () => {
216
+ const i = a.getAttribute("data-template-id");
217
+ if (i) {
218
+ const u = y().find((v) => v.id === i);
219
+ u && (n = u, x());
220
+ }
221
+ });
222
+ }), o.querySelectorAll('input[name="insertMode"]').forEach((a) => {
223
+ a.addEventListener("change", (i) => {
224
+ g = i.target.value, b();
225
+ });
226
+ });
227
+ }
228
+ function T() {
229
+ const t = E();
230
+ t.length > 0 ? (!n || !t.find((e) => e.id === n.id)) && (n = t[0]) : n = null, b();
231
+ }
232
+ function x() {
233
+ if (n)
234
+ if (g === "replace") {
235
+ let t = null;
236
+ if (s) {
237
+ let e = s.startContainer;
238
+ for (; e && e !== document.body; ) {
239
+ if (e.nodeType === Node.ELEMENT_NODE) {
240
+ const r = e;
241
+ if (r.getAttribute("contenteditable") === "true") {
242
+ t = r;
243
+ break;
244
+ }
245
+ }
246
+ e = e.parentNode;
247
+ }
248
+ }
249
+ if (t || (t = document.querySelector('[contenteditable="true"]')), t?.innerHTML?.trim()) {
250
+ I();
251
+ return;
252
+ }
253
+ C(n), c();
254
+ } else
255
+ j(n), c();
256
+ }
257
+ function $() {
258
+ n && (C(n), c());
259
+ }
260
+ function j(t) {
261
+ if (s) {
262
+ const f = window.getSelection();
263
+ f && (f.removeAllRanges(), f.addRange(s));
264
+ }
265
+ const e = window.getSelection();
266
+ if (!e || e.rangeCount === 0) return;
267
+ const r = e.getRangeAt(0), l = document.createRange().createContextualFragment(L(t.html));
268
+ r.deleteContents(), r.insertNode(l);
269
+ const h = document.createRange();
270
+ h.setStartAfter(r.endContainer), h.collapse(!0), e.removeAllRanges(), e.addRange(h);
271
+ }
272
+ function C(t) {
273
+ let e = null;
274
+ if (s) {
275
+ let r = s.startContainer;
276
+ for (; r && r !== document.body; ) {
277
+ if (r.nodeType === Node.ELEMENT_NODE) {
278
+ const l = r;
279
+ if (l.getAttribute("contenteditable") === "true") {
280
+ e = l;
281
+ break;
282
+ }
283
+ }
284
+ r = r.parentNode;
285
+ }
286
+ }
287
+ e || (e = document.querySelector('[contenteditable="true"]')), e && (e.innerHTML = L(t.html), e.dispatchEvent(new Event("input", { bubbles: !0 })));
288
+ }
289
+ function c() {
290
+ d && (d.remove(), d = null), o = null, s = null, m = "";
291
+ }
292
+ function q(t) {
293
+ const e = window.getSelection();
294
+ e && e.rangeCount > 0 ? s = e.getRangeAt(0).cloneRange() : s = null;
295
+ const r = E();
296
+ r.length > 0 && !n && (n = r[0]);
297
+ const l = t?.contentElement instanceof HTMLElement ? t.contentElement : A();
298
+ D(l);
299
+ }
300
+ function z() {
301
+ if (typeof document > "u") return;
302
+ const t = "template-plugin-dialog-styles";
303
+ if (document.getElementById(t)) return;
304
+ const e = document.createElement("style");
305
+ e.id = t, e.textContent = `
306
+ .rte-dialog-overlay {
307
+ --rte-tmpl-overlay-bg: rgba(15, 23, 36, 0.56);
308
+ --rte-tmpl-dialog-bg: #fff;
309
+ --rte-tmpl-dialog-text: #101828;
310
+ --rte-tmpl-border: #d6dbe4;
311
+ --rte-tmpl-subtle-bg: #f7f9fc;
312
+ --rte-tmpl-subtle-hover: #eef2f7;
313
+ --rte-tmpl-muted-text: #5f6b7d;
314
+ --rte-tmpl-accent: #1976d2;
315
+ --rte-tmpl-accent-strong: #1565c0;
316
+ --rte-tmpl-ring: rgba(31, 117, 254, 0.18);
317
+ position: fixed;
318
+ top: 0;
319
+ left: 0;
320
+ right: 0;
321
+ bottom: 0;
322
+ background-color: var(--rte-tmpl-overlay-bg);
323
+ backdrop-filter: blur(2px);
324
+ display: flex;
325
+ align-items: center;
326
+ justify-content: center;
327
+ z-index: 10000;
328
+ padding: 16px;
329
+ box-sizing: border-box;
330
+ }
331
+ .rte-dialog-overlay.rte-ui-theme-dark {
332
+ --rte-tmpl-overlay-bg: rgba(2, 8, 20, 0.72);
333
+ --rte-tmpl-dialog-bg: #202938;
334
+ --rte-tmpl-dialog-text: #e8effc;
335
+ --rte-tmpl-border: #49566c;
336
+ --rte-tmpl-subtle-bg: #2a3444;
337
+ --rte-tmpl-subtle-hover: #344256;
338
+ --rte-tmpl-muted-text: #a5b1c5;
339
+ --rte-tmpl-accent: #58a6ff;
340
+ --rte-tmpl-accent-strong: #4598f4;
341
+ --rte-tmpl-ring: rgba(88, 166, 255, 0.22);
342
+ }
343
+ .rte-template-dialog {
344
+ background: var(--rte-tmpl-dialog-bg);
345
+ color: var(--rte-tmpl-dialog-text);
346
+ border: 1px solid var(--rte-tmpl-border);
347
+ border-radius: 12px;
348
+ box-shadow: 0 24px 48px rgba(10, 15, 24, 0.28);
349
+ width: 600px;
350
+ max-height: 700px;
351
+ display: flex;
352
+ flex-direction: column;
353
+ overflow: hidden;
354
+ }
355
+ .rte-dialog-header {
356
+ display: flex;
357
+ justify-content: space-between;
358
+ align-items: center;
359
+ padding: 16px 20px;
360
+ border-bottom: 1px solid var(--rte-tmpl-border);
361
+ background: linear-gradient(180deg, rgba(127, 154, 195, 0.08) 0%, rgba(127, 154, 195, 0) 100%);
362
+ }
363
+ .rte-dialog-header h2 {
364
+ margin: 0;
365
+ font-size: 18px;
366
+ font-weight: 600;
367
+ color: var(--rte-tmpl-dialog-text);
368
+ }
369
+ .rte-dialog-close {
370
+ background: none;
371
+ border: none;
372
+ font-size: 24px;
373
+ cursor: pointer;
374
+ color: var(--rte-tmpl-muted-text);
375
+ padding: 0;
376
+ width: 32px;
377
+ height: 32px;
378
+ display: flex;
379
+ align-items: center;
380
+ justify-content: center;
381
+ border-radius: 8px;
382
+ transition: background-color 0.16s ease, color 0.16s ease;
383
+ }
384
+ .rte-dialog-close:hover {
385
+ background-color: var(--rte-tmpl-subtle-hover);
386
+ color: var(--rte-tmpl-dialog-text);
387
+ }
388
+ .rte-dialog-body {
389
+ padding: 20px;
390
+ flex: 1;
391
+ overflow-y: auto;
392
+ }
393
+ .rte-input {
394
+ width: 100%;
395
+ padding: 8px 12px;
396
+ border: 1px solid var(--rte-tmpl-border);
397
+ border-radius: 4px;
398
+ font-size: 14px;
399
+ box-sizing: border-box;
400
+ background: var(--rte-tmpl-subtle-bg);
401
+ color: var(--rte-tmpl-dialog-text);
402
+ }
403
+ .rte-input:focus {
404
+ outline: none;
405
+ border-color: var(--rte-tmpl-accent);
406
+ }
407
+ .rte-tabs {
408
+ display: flex;
409
+ gap: 8px;
410
+ margin-top: 12px;
411
+ border-bottom: 1px solid var(--rte-tmpl-border);
412
+ padding-bottom: 8px;
413
+ }
414
+ .rte-tab {
415
+ padding: 6px 12px;
416
+ border: none;
417
+ background: none;
418
+ cursor: pointer;
419
+ font-size: 14px;
420
+ color: var(--rte-tmpl-muted-text);
421
+ border-bottom: 2px solid transparent;
422
+ transition: all 0.2s;
423
+ }
424
+ .rte-tab:hover {
425
+ color: var(--rte-tmpl-dialog-text);
426
+ }
427
+ .rte-tab.active {
428
+ color: var(--rte-tmpl-accent);
429
+ border-bottom-color: var(--rte-tmpl-accent);
430
+ font-weight: 600;
431
+ }
432
+ .rte-template-list {
433
+ border: 1px solid var(--rte-tmpl-border);
434
+ border-radius: 4px;
435
+ max-height: 250px;
436
+ overflow-y: auto;
437
+ margin: 12px 0;
438
+ background: var(--rte-tmpl-subtle-bg);
439
+ }
440
+ .rte-template-item {
441
+ padding: 12px;
442
+ border-bottom: 1px solid var(--rte-tmpl-border);
443
+ cursor: pointer;
444
+ transition: background-color 0.2s;
445
+ background: none;
446
+ }
447
+ .rte-template-item:last-child {
448
+ border-bottom: none;
449
+ }
450
+ .rte-template-item:hover,
451
+ .rte-template-item.selected {
452
+ background-color: var(--rte-tmpl-subtle-hover);
453
+ }
454
+ .template-name {
455
+ font-weight: 600;
456
+ color: var(--rte-tmpl-dialog-text);
457
+ margin-bottom: 4px;
458
+ }
459
+ .template-description {
460
+ font-size: 12px;
461
+ color: var(--rte-tmpl-muted-text);
462
+ }
463
+ .rte-template-preview {
464
+ padding: 12px;
465
+ background-color: var(--rte-tmpl-subtle-bg);
466
+ border: 1px solid var(--rte-tmpl-border);
467
+ border-radius: 4px;
468
+ margin-top: 12px;
469
+ max-height: 200px;
470
+ overflow-y: auto;
471
+ }
472
+ .template-preview-content {
473
+ font-size: 13px;
474
+ line-height: 1.5;
475
+ margin-top: 8px;
476
+ }
477
+ .template-preview-content * {
478
+ margin: 4px 0;
479
+ }
480
+ .rte-insert-mode {
481
+ margin-top: 12px;
482
+ padding: 12px;
483
+ background-color: var(--rte-tmpl-subtle-bg);
484
+ border-radius: 4px;
485
+ display: flex;
486
+ gap: 16px;
487
+ }
488
+ .rte-insert-mode label {
489
+ display: flex;
490
+ align-items: center;
491
+ cursor: pointer;
492
+ font-size: 14px;
493
+ }
494
+ .rte-insert-mode input {
495
+ margin-right: 6px;
496
+ cursor: pointer;
497
+ }
498
+ .rte-empty-state {
499
+ padding: 40px;
500
+ text-align: center;
501
+ color: var(--rte-tmpl-muted-text);
502
+ font-size: 14px;
503
+ }
504
+ .rte-dialog-footer {
505
+ padding: 16px 20px;
506
+ border-top: 1px solid var(--rte-tmpl-border);
507
+ background: var(--rte-tmpl-subtle-bg);
508
+ display: flex;
509
+ justify-content: flex-end;
510
+ gap: 12px;
511
+ }
512
+ .rte-button-primary {
513
+ padding: 8px 16px;
514
+ border: none;
515
+ border-radius: 4px;
516
+ font-size: 14px;
517
+ cursor: pointer;
518
+ background-color: var(--rte-tmpl-accent);
519
+ color: white;
520
+ transition: all 0.2s;
521
+ }
522
+ .rte-button-primary:hover:not([disabled]) {
523
+ background-color: var(--rte-tmpl-accent-strong);
524
+ }
525
+ .rte-button-primary[disabled] {
526
+ opacity: 0.5;
527
+ cursor: not-allowed;
528
+ }
529
+ .rte-button-secondary {
530
+ padding: 8px 16px;
531
+ border: 1px solid var(--rte-tmpl-border);
532
+ border-radius: 4px;
533
+ font-size: 14px;
534
+ cursor: pointer;
535
+ background-color: var(--rte-tmpl-subtle-bg);
536
+ color: var(--rte-tmpl-dialog-text);
537
+ transition: all 0.2s;
538
+ }
539
+ .rte-button-secondary:hover {
540
+ background-color: var(--rte-tmpl-subtle-hover);
541
+ }
542
+ `, document.head.appendChild(e);
543
+ }
544
+ const P = () => ({
545
+ name: "template",
546
+ toolbar: [
547
+ {
548
+ label: "Template",
549
+ command: "insertTemplate",
550
+ icon: '<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M3 3V9H21V3H3ZM19 5H5V7H19V5Z" fill="#000000"></path> <path fill-rule="evenodd" clip-rule="evenodd" d="M3 11V21H11V11H3ZM9 13H5V19H9V13Z" fill="#000000"></path> <path d="M21 11H13V13H21V11Z" fill="#000000"></path> <path d="M13 15H21V17H13V15Z" fill="#000000"></path> <path d="M21 19H13V21H21V19Z" fill="#000000"></path> </g></svg>'
551
+ }
552
+ ],
553
+ commands: {
554
+ insertTemplate: (t, e) => (q(e), !0)
555
+ },
556
+ keymap: {}
557
+ });
558
+ export {
559
+ P as TemplatePlugin
560
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=["P","DIV","H1","H2","H3","H4","H5","H6","LI","BLOCKQUOTE","PRE","TD","TH"];function d(n){let t=n;if(t.nodeType===Node.ELEMENT_NODE){const e=t;if(a.includes(e.tagName))return e}for(;t;){if(t.nodeType===Node.ELEMENT_NODE){const e=t;if(a.includes(e.tagName))return e;if(e.hasAttribute("contenteditable"))return null}t=t.parentNode}return null}function g(n){const t=[],e=d(n.startContainer),i=d(n.endContainer);if(!e&&!i)return t;if(n.collapsed)return e&&t.push(e),t;if(e===i)e&&t.push(e);else{let o=e;const s=new Set;for(e&&(t.push(e),s.add(e));o&&o!==i&&!s.has(i);){let r=o.nextElementSibling;for(;r;){if(a.includes(r.tagName)){o=r,s.has(o)||(t.push(o),s.add(o));break}r=r.nextElementSibling}if(!r)break}i&&!t.includes(i)&&t.push(i)}return t}function h(n){const t=n.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?n.commonAncestorContainer:n.commonAncestorContainer.parentElement;return t?t.closest(".rte-content, .editora-content")||t.closest('[contenteditable="true"]'):null}function f(n,t){if(!n||t===n.innerHTML)return;const e=window.execEditorCommand||window.executeEditorCommand;if(typeof e=="function")try{e("recordDomTransaction",n,t,n.innerHTML)}catch{}}const E=n=>{if(!n||!["left","center","right","justify"].includes(n))return!1;const e=window.getSelection();if(!e||e.rangeCount===0)return!1;const i=e.getRangeAt(0).cloneRange(),o=h(i),s=o?.innerHTML||"",r=g(i);if(r.length>0)r.forEach(l=>{l&&(l.style.textAlign=n)}),e.removeAllRanges(),e.addRange(i),f(o,s),o&&o.dispatchEvent(new Event("input",{bubbles:!0}));else try{const l=document.createElement("div");l.style.textAlign=n;const m=i.extractContents();l.appendChild(m),i.insertNode(l);const u=document.createRange();u.selectNodeContents(l),e.removeAllRanges(),e.addRange(u);const c=l.closest(".rte-content, .editora-content")||l.closest('[contenteditable="true"]');f(c||o,s),(c||o)&&(c||o)?.dispatchEvent(new Event("input",{bubbles:!0}))}catch(l){return console.error("Failed to wrap content for alignment:",l),!1}return!0},b=()=>({name:"textAlignment",toolbar:[{label:"Text Alignment",command:"setTextAlignment",type:"inline-menu",options:[{label:"Left",value:"left"},{label:"Center",value:"center"},{label:"Right",value:"right"},{label:"Justify",value:"justify"}],icon:'<svg width="24" height="24" focusable="false"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 4h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Zm0-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Z" fill-rule="evenodd"></path></svg>'}],commands:{setTextAlignment:E},keymap:{}});exports.TextAlignmentPlugin=b;
@@ -0,0 +1,105 @@
1
+ const a = ["P", "DIV", "H1", "H2", "H3", "H4", "H5", "H6", "LI", "BLOCKQUOTE", "PRE", "TD", "TH"];
2
+ function d(n) {
3
+ let t = n;
4
+ if (t.nodeType === Node.ELEMENT_NODE) {
5
+ const e = t;
6
+ if (a.includes(e.tagName))
7
+ return e;
8
+ }
9
+ for (; t; ) {
10
+ if (t.nodeType === Node.ELEMENT_NODE) {
11
+ const e = t;
12
+ if (a.includes(e.tagName))
13
+ return e;
14
+ if (e.hasAttribute("contenteditable"))
15
+ return null;
16
+ }
17
+ t = t.parentNode;
18
+ }
19
+ return null;
20
+ }
21
+ function g(n) {
22
+ const t = [], e = d(n.startContainer), i = d(n.endContainer);
23
+ if (!e && !i) return t;
24
+ if (n.collapsed)
25
+ return e && t.push(e), t;
26
+ if (e === i)
27
+ e && t.push(e);
28
+ else {
29
+ let o = e;
30
+ const s = /* @__PURE__ */ new Set();
31
+ for (e && (t.push(e), s.add(e)); o && o !== i && !s.has(i); ) {
32
+ let r = o.nextElementSibling;
33
+ for (; r; ) {
34
+ if (a.includes(r.tagName)) {
35
+ o = r, s.has(o) || (t.push(o), s.add(o));
36
+ break;
37
+ }
38
+ r = r.nextElementSibling;
39
+ }
40
+ if (!r) break;
41
+ }
42
+ i && !t.includes(i) && t.push(i);
43
+ }
44
+ return t;
45
+ }
46
+ function h(n) {
47
+ const t = n.commonAncestorContainer.nodeType === Node.ELEMENT_NODE ? n.commonAncestorContainer : n.commonAncestorContainer.parentElement;
48
+ return t ? t.closest(".rte-content, .editora-content") || t.closest('[contenteditable="true"]') : null;
49
+ }
50
+ function f(n, t) {
51
+ if (!n || t === n.innerHTML) return;
52
+ const e = window.execEditorCommand || window.executeEditorCommand;
53
+ if (typeof e == "function")
54
+ try {
55
+ e("recordDomTransaction", n, t, n.innerHTML);
56
+ } catch {
57
+ }
58
+ }
59
+ const E = (n) => {
60
+ if (!n || !["left", "center", "right", "justify"].includes(n)) return !1;
61
+ const e = window.getSelection();
62
+ if (!e || e.rangeCount === 0) return !1;
63
+ const i = e.getRangeAt(0).cloneRange(), o = h(i), s = o?.innerHTML || "", r = g(i);
64
+ if (r.length > 0)
65
+ r.forEach((l) => {
66
+ l && (l.style.textAlign = n);
67
+ }), e.removeAllRanges(), e.addRange(i), f(o, s), o && o.dispatchEvent(new Event("input", { bubbles: !0 }));
68
+ else
69
+ try {
70
+ const l = document.createElement("div");
71
+ l.style.textAlign = n;
72
+ const m = i.extractContents();
73
+ l.appendChild(m), i.insertNode(l);
74
+ const u = document.createRange();
75
+ u.selectNodeContents(l), e.removeAllRanges(), e.addRange(u);
76
+ const c = l.closest(".rte-content, .editora-content") || l.closest('[contenteditable="true"]');
77
+ f(c || o, s), (c || o) && (c || o)?.dispatchEvent(new Event("input", { bubbles: !0 }));
78
+ } catch (l) {
79
+ return console.error("Failed to wrap content for alignment:", l), !1;
80
+ }
81
+ return !0;
82
+ }, p = () => ({
83
+ name: "textAlignment",
84
+ toolbar: [
85
+ {
86
+ label: "Text Alignment",
87
+ command: "setTextAlignment",
88
+ type: "inline-menu",
89
+ options: [
90
+ { label: "Left", value: "left" },
91
+ { label: "Center", value: "center" },
92
+ { label: "Right", value: "right" },
93
+ { label: "Justify", value: "justify" }
94
+ ],
95
+ icon: '<svg width="24" height="24" focusable="false"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 4h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2Zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Zm0-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2Z" fill-rule="evenodd"></path></svg>'
96
+ }
97
+ ],
98
+ commands: {
99
+ setTextAlignment: E
100
+ },
101
+ keymap: {}
102
+ });
103
+ export {
104
+ p as TextAlignmentPlugin
105
+ };