@meenainwal/rich-text-editor 1.0.0

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.
@@ -0,0 +1,862 @@
1
+ class g {
2
+ /**
3
+ * Returns the current selection object.
4
+ */
5
+ getSelection() {
6
+ return window.getSelection();
7
+ }
8
+ /**
9
+ * Returns the first range of the current selection.
10
+ */
11
+ getRange() {
12
+ const e = this.getSelection();
13
+ return !e || e.rangeCount === 0 ? null : e.getRangeAt(0);
14
+ }
15
+ /**
16
+ * Saves the current selection range.
17
+ */
18
+ saveSelection() {
19
+ const e = this.getRange();
20
+ return e ? e.cloneRange() : null;
21
+ }
22
+ /**
23
+ * Restores a previously saved range.
24
+ */
25
+ restoreSelection(e) {
26
+ if (!e) return;
27
+ const t = this.getSelection();
28
+ t && (t.removeAllRanges(), t.addRange(e));
29
+ }
30
+ /**
31
+ * Checks if the selection is within a specific element.
32
+ */
33
+ isSelectionInElement(e) {
34
+ const t = this.getRange();
35
+ return t ? e.contains(t.commonAncestorContainer) : !1;
36
+ }
37
+ /**
38
+ * Clears the current selection.
39
+ */
40
+ clearSelection() {
41
+ const e = this.getSelection();
42
+ e && e.removeAllRanges();
43
+ }
44
+ }
45
+ class j {
46
+ container;
47
+ editableElement;
48
+ selection;
49
+ options;
50
+ pendingStyles = {};
51
+ constructor(e, t = {}) {
52
+ this.container = e, this.container.classList.add("te-container"), this.options = t, this.selection = new g(), this.editableElement = this.createEditableElement(), this.setupInputHandlers(), this.container.appendChild(this.editableElement), this.options.autofocus && this.focus(), document.execCommand("defaultParagraphSeparator", !1, "p");
53
+ }
54
+ setupInputHandlers() {
55
+ this.editableElement.addEventListener("beforeinput", (e) => {
56
+ if (e.inputType === "insertText" && Object.keys(this.pendingStyles).length > 0) {
57
+ const t = e.data;
58
+ if (!t) return;
59
+ e.preventDefault();
60
+ const i = document.createElement("span");
61
+ for (const [a, n] of Object.entries(this.pendingStyles))
62
+ i.style.setProperty(a, n);
63
+ i.textContent = t;
64
+ const o = this.selection.getRange();
65
+ if (o) {
66
+ o.deleteContents(), o.insertNode(i);
67
+ const a = document.createRange();
68
+ a.setStart(i.firstChild, t.length), a.setEnd(i.firstChild, t.length), this.selection.restoreSelection(a), this.pendingStyles = {}, this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
69
+ }
70
+ }
71
+ }), document.addEventListener("selectionchange", () => {
72
+ const e = window.getSelection();
73
+ e && e.rangeCount > 0 && (e.getRangeAt(0).collapsed || (this.pendingStyles = {}));
74
+ });
75
+ }
76
+ createEditableElement() {
77
+ const e = document.createElement("div");
78
+ return e.setAttribute("contenteditable", "true"), e.setAttribute("role", "textbox"), e.setAttribute("spellcheck", "true"), e.classList.add("te-content"), this.options.placeholder && e.setAttribute("data-placeholder", this.options.placeholder), e.style.minHeight = "150px", e.style.outline = "none", e.style.padding = "1rem", e.innerHTML === "" && (e.innerHTML = "<p><br></p>"), e;
79
+ }
80
+ /**
81
+ * Focuses the editor.
82
+ */
83
+ focus() {
84
+ this.editableElement.focus();
85
+ }
86
+ /**
87
+ * Executes a command on the current selection.
88
+ */
89
+ execute(e, t = null) {
90
+ this.focus(), document.execCommand(e, !1, t ?? void 0), this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
91
+ }
92
+ /**
93
+ * Recursively removes a style property from all elements in a fragment.
94
+ */
95
+ clearStyleRecursive(e, t) {
96
+ const i = document.createTreeWalker(e, NodeFilter.SHOW_ELEMENT);
97
+ let o = i.nextNode();
98
+ for (; o; )
99
+ o.style.getPropertyValue(t) && o.style.removeProperty(t), o = i.nextNode();
100
+ }
101
+ /**
102
+ * Applies an inline style to the selection.
103
+ * This is used for properties like font-size (px) and font-family
104
+ * where execCommand is outdated or limited.
105
+ */
106
+ setStyle(e, t, i) {
107
+ if (e === "font-size") {
108
+ const n = parseInt(t, 10);
109
+ isNaN(n) || (t = `${Math.max(1, Math.min(100, n))}px`);
110
+ }
111
+ if (!i) {
112
+ const n = window.getSelection();
113
+ if (!n || n.rangeCount === 0) return null;
114
+ i = n.getRangeAt(0);
115
+ }
116
+ if (i.collapsed)
117
+ return this.pendingStyles[e] = t, i;
118
+ let o = i.commonAncestorContainer;
119
+ o.nodeType === Node.TEXT_NODE && (o = o.parentElement);
120
+ let a = null;
121
+ if (o.tagName === "SPAN" && o.children.length === 0 && o.textContent === i.toString())
122
+ o.style.setProperty(e, t), a = i.cloneRange();
123
+ else {
124
+ const n = document.createElement("span");
125
+ n.style.setProperty(e, t);
126
+ try {
127
+ const r = o.tagName === "SPAN" ? o : null, y = i.extractContents();
128
+ this.clearStyleRecursive(y, e), n.appendChild(y), i.insertNode(n), r && r.innerHTML === "" && r.remove();
129
+ const l = document.createRange();
130
+ l.selectNodeContents(n), a = l;
131
+ const c = window.getSelection();
132
+ c && c.rangeCount > 0 && (c.removeAllRanges(), c.addRange(l));
133
+ } catch (r) {
134
+ console.warn("Failed to apply style:", r);
135
+ }
136
+ }
137
+ return this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 })), a;
138
+ }
139
+ /**
140
+ * Creates a link at the current selection.
141
+ * Ensures the link opens in a new tab with proper security attributes.
142
+ */
143
+ createLink(e) {
144
+ this.focus(), !/^https?:\/\//i.test(e) && !/^mailto:/i.test(e) && !e.startsWith("#") && (e = "https://" + e), document.execCommand("createLink", !1, e);
145
+ const t = window.getSelection();
146
+ if (t && t.rangeCount > 0) {
147
+ let o = t.getRangeAt(0).commonAncestorContainer;
148
+ o.nodeType === Node.TEXT_NODE && (o = o.parentElement);
149
+ let a = null;
150
+ o.tagName === "A" ? a = o : a = o.querySelector("a"), a && (a.setAttribute("target", "_blank"), a.setAttribute("rel", "noopener noreferrer"));
151
+ }
152
+ this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
153
+ }
154
+ /**
155
+ * Returns the clean HTML content of the editor.
156
+ */
157
+ getHTML() {
158
+ return this.editableElement.innerHTML;
159
+ }
160
+ /**
161
+ * Sets the HTML content of the editor.
162
+ */
163
+ setHTML(e) {
164
+ this.editableElement.innerHTML = e;
165
+ }
166
+ /**
167
+ * Internal access to the editable element.
168
+ */
169
+ get el() {
170
+ return this.editableElement;
171
+ }
172
+ }
173
+ const h = {
174
+ type: "button",
175
+ title: "Undo",
176
+ command: "undo",
177
+ icon: '<svg viewBox="0 0 24 24"><path d="M9 14L4 9l5-5"></path><path d="M20 20v-7a4 4 0 0 0-4-4H4"></path></svg>'
178
+ }, u = {
179
+ type: "button",
180
+ title: "Redo",
181
+ command: "redo",
182
+ icon: '<svg viewBox="0 0 24 24"><path d="M15 14l5-5-5-5"></path><path d="M4 20v-7a4 4 0 0 1 4-4h12"></path></svg>'
183
+ }, p = {
184
+ type: "select",
185
+ title: "Heading",
186
+ command: "formatBlock",
187
+ options: [
188
+ { label: "Paragraph", value: "P" },
189
+ { label: "Heading 1", value: "H1" },
190
+ { label: "Heading 2", value: "H2" },
191
+ { label: "Heading 3", value: "H3" },
192
+ { label: "Heading 4", value: "H4" },
193
+ { label: "Heading 5", value: "H5" },
194
+ { label: "Heading 6", value: "H6" }
195
+ ]
196
+ }, v = {
197
+ type: "select",
198
+ title: "Font",
199
+ command: "fontFamily",
200
+ options: [
201
+ { label: "Inter", value: "'Inter', sans-serif" },
202
+ { label: "Arial", value: "Arial, sans-serif" },
203
+ { label: "Georgia", value: "Georgia, serif" },
204
+ { label: "Courier", value: "'Courier New', monospace" },
205
+ { label: "Times New Roman", value: "'Times New Roman', serif" },
206
+ { label: "Verdana", value: "Verdana, sans-serif" },
207
+ { label: "Tahoma", value: "Tahoma, sans-serif" },
208
+ { label: "Roboto", value: "'Roboto', sans-serif" },
209
+ { label: "Open Sans", value: "'Open Sans', sans-serif" },
210
+ { label: "Montserrat", value: "'Montserrat', sans-serif" },
211
+ { label: "Lato", value: "'Lato', sans-serif" },
212
+ { label: "Poppins", value: "'Poppins', sans-serif" },
213
+ { label: "Oswald", value: "'Oswald', sans-serif" },
214
+ { label: "Playfair Display", value: "'Playfair Display', serif" },
215
+ { label: "Merriweather", value: "'Merriweather', serif" }
216
+ ]
217
+ }, b = {
218
+ type: "input",
219
+ title: "Size (px)",
220
+ command: "fontSize",
221
+ placeholder: "Size",
222
+ value: "16"
223
+ }, f = {
224
+ type: "button",
225
+ title: "Bold",
226
+ command: "bold",
227
+ icon: '<svg viewBox="0 0 24 24"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path></svg>'
228
+ }, S = {
229
+ type: "button",
230
+ title: "Italic",
231
+ command: "italic",
232
+ icon: '<svg viewBox="0 0 24 24"><line x1="19" y1="4" x2="10" y2="4"></line><line x1="14" y1="20" x2="5" y2="20"></line><line x1="15" y1="4" x2="9" y2="20"></line></svg>'
233
+ }, x = {
234
+ type: "button",
235
+ title: "Underline",
236
+ command: "underline",
237
+ icon: '<svg viewBox="0 0 24 24"><path d="M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3"></path><line x1="4" y1="21" x2="20" y2="21"></line></svg>'
238
+ }, w = {
239
+ type: "button",
240
+ title: "Strikethrough",
241
+ command: "strikeThrough",
242
+ icon: '<svg viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"></line><path d="M16 4.9C15.1 4.3 13.9 4 12.6 4c-3.1 0-5.6 1.8-5.6 4s1.8 3.3 4.4 3.8"></path><path d="M7 19.1c.9.6 2.1.9 3.4.9 3.1 0 5.6-1.8 5.6-4s-1.8-3.3-4.4-3.8"></path></svg>'
243
+ }, A = {
244
+ type: "color-picker",
245
+ title: "Text Color",
246
+ command: "foreColor",
247
+ value: "#1e293b"
248
+ }, k = {
249
+ type: "color-picker",
250
+ title: "Highlight Color",
251
+ command: "backColor",
252
+ value: "#ffffff"
253
+ }, E = {
254
+ type: "button",
255
+ title: "Align Left",
256
+ command: "justifyLeft",
257
+ icon: '<svg viewBox="0 0 24 24"><line x1="17" y1="10" x2="3" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="17" y1="18" x2="3" y2="18"></line></svg>'
258
+ }, F = {
259
+ type: "button",
260
+ title: "Align Center",
261
+ command: "justifyCenter",
262
+ icon: '<svg viewBox="0 0 24 24"><line x1="18" y1="10" x2="6" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="18" y1="18" x2="6" y2="18"></line></svg>'
263
+ }, L = {
264
+ type: "button",
265
+ title: "Align Right",
266
+ command: "justifyRight",
267
+ icon: '<svg viewBox="0 0 24 24"><line x1="21" y1="10" x2="7" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="21" y1="18" x2="7" y2="18"></line></svg>'
268
+ }, C = {
269
+ type: "button",
270
+ title: "Justify",
271
+ command: "justifyFull",
272
+ icon: '<svg viewBox="0 0 24 24"><line x1="21" y1="10" x2="3" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="21" y1="18" x2="3" y2="18"></line></svg>'
273
+ }, H = {
274
+ type: "button",
275
+ title: "Bulleted List",
276
+ command: "insertUnorderedList",
277
+ icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><circle cx="3" cy="6" r="1" fill="currentColor"></circle><circle cx="3" cy="12" r="1" fill="currentColor"></circle><circle cx="3" cy="18" r="1" fill="currentColor"></circle></svg>'
278
+ }, T = {
279
+ type: "button",
280
+ title: "Numbered List",
281
+ command: "insertOrderedList",
282
+ icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="10" y1="6" x2="21" y2="6"></line><line x1="10" y1="12" x2="21" y2="21"></line><line x1="10" y1="18" x2="21" y2="18"></line><path d="M4 6h1v4"></path><path d="M4 10h2"></path><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"></path></svg>'
283
+ }, R = {
284
+ type: "button",
285
+ title: "Outdent",
286
+ command: "outdent",
287
+ icon: '<svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"></polyline><line x1="21" y1="12" x2="9" y2="12"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="18" x2="3" y2="18"></line></svg>'
288
+ }, O = {
289
+ type: "button",
290
+ title: "Indent",
291
+ command: "indent",
292
+ icon: '<svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"></polyline><line x1="3" y1="12" x2="15" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>'
293
+ }, M = {
294
+ type: "button",
295
+ title: "Horizontal Rule",
296
+ command: "insertHorizontalRule",
297
+ icon: '<svg viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"></line></svg>'
298
+ }, I = {
299
+ type: "button",
300
+ title: "Clear Formatting",
301
+ command: "removeFormat",
302
+ icon: '<svg viewBox="0 0 24 24"><path d="M17.41 15.41L12 10l-5.41 5.41L5.17 14l5.41-5.41L5.17 3.17 6.59 1.76 12 7.17l5.41-5.41 1.41 1.41-5.41 5.41 5.41 5.41-1.41 1.42z"></path></svg>'
303
+ }, P = {
304
+ type: "button",
305
+ title: "Insert Emoji",
306
+ command: "insertEmoji",
307
+ icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M8 14s1.5 2 4 2 4-2 4-2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line></svg>'
308
+ }, B = {
309
+ type: "button",
310
+ title: "Insert Link",
311
+ command: "createLink",
312
+ icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>'
313
+ }, m = { type: "divider", title: "" }, N = [
314
+ h,
315
+ u,
316
+ m,
317
+ p,
318
+ v,
319
+ b,
320
+ m,
321
+ f,
322
+ S,
323
+ x,
324
+ w,
325
+ m,
326
+ A,
327
+ k,
328
+ m,
329
+ E,
330
+ F,
331
+ L,
332
+ C,
333
+ m,
334
+ H,
335
+ T,
336
+ R,
337
+ O,
338
+ m,
339
+ M,
340
+ P,
341
+ B,
342
+ I
343
+ ], d = [
344
+ // Smileys & Emotion
345
+ { emoji: "😀", name: "grinning", category: "Smileys" },
346
+ { emoji: "😃", name: "smiley", category: "Smileys" },
347
+ { emoji: "😄", name: "smile", category: "Smileys" },
348
+ { emoji: "😁", name: "grin", category: "Smileys" },
349
+ { emoji: "😆", name: "laughing", category: "Smileys" },
350
+ { emoji: "😅", name: "sweat smile", category: "Smileys" },
351
+ { emoji: "🤣", name: "rofl", category: "Smileys" },
352
+ { emoji: "😂", name: "joy", category: "Smileys" },
353
+ { emoji: "🙂", name: "slight smile", category: "Smileys" },
354
+ { emoji: "🙃", name: "upside down", category: "Smileys" },
355
+ { emoji: "😉", name: "wink", category: "Smileys" },
356
+ { emoji: "😊", name: "blush", category: "Smileys" },
357
+ { emoji: "😇", name: "innocent", category: "Smileys" },
358
+ { emoji: "🥰", name: "smiling face with hearts", category: "Smileys" },
359
+ { emoji: "😍", name: "heart eyes", category: "Smileys" },
360
+ { emoji: "🤩", name: "star struck", category: "Smileys" },
361
+ { emoji: "😘", name: "kissing heart", category: "Smileys" },
362
+ { emoji: "😗", name: "kissing", category: "Smileys" },
363
+ { emoji: "😚", name: "kissing closed eyes", category: "Smileys" },
364
+ { emoji: "😋", name: "yum", category: "Smileys" },
365
+ { emoji: "😛", name: "stuck out tongue", category: "Smileys" },
366
+ { emoji: "😜", name: "stuck out tongue winking eye", category: "Smileys" },
367
+ { emoji: "🤪", name: "zany face", category: "Smileys" },
368
+ { emoji: "🤨", name: "raised eyebrow", category: "Smileys" },
369
+ { emoji: "🧐", name: "monocle", category: "Smileys" },
370
+ { emoji: "🤓", name: "nerd", category: "Smileys" },
371
+ { emoji: "😎", name: "sunglasses", category: "Smileys" },
372
+ { emoji: "🥳", name: "partying face", category: "Smileys" },
373
+ { emoji: "😏", name: "smirk", category: "Smileys" },
374
+ { emoji: "😒", name: "unamused", category: "Smileys" },
375
+ { emoji: "😞", name: "disappointed", category: "Smileys" },
376
+ { emoji: "😔", name: "pensive", category: "Smileys" },
377
+ { emoji: "😟", name: "worried", category: "Smileys" },
378
+ { emoji: "😕", name: "confused", category: "Smileys" },
379
+ { emoji: "😫", name: "tired", category: "Smileys" },
380
+ { emoji: "🥵", name: "hot face", category: "Smileys" },
381
+ { emoji: "🥶", name: "cold face", category: "Smileys" },
382
+ { emoji: "😳", name: "flushed", category: "Smileys" },
383
+ { emoji: "😱", name: "scream", category: "Smileys" },
384
+ { emoji: "🤢", name: "nauseated", category: "Smileys" },
385
+ { emoji: "🤮", name: "vomiting", category: "Smileys" },
386
+ { emoji: "🤬", name: "cursing", category: "Smileys" },
387
+ { emoji: "🤫", name: "shushing", category: "Smileys" },
388
+ { emoji: "🤔", name: "thinking", category: "Smileys" },
389
+ { emoji: "🤗", name: "hugs", category: "Smileys" },
390
+ { emoji: "🥱", name: "yawn", category: "Smileys" },
391
+ { emoji: "😴", name: "sleeping", category: "Smileys" },
392
+ { emoji: "🤤", name: "drooling", category: "Smileys" },
393
+ { emoji: "😵", name: "dizzy", category: "Smileys" },
394
+ { emoji: "🤐", name: "zipper mouth", category: "Smileys" },
395
+ { emoji: "🥴", name: "woozy", category: "Smileys" },
396
+ { emoji: "🤒", name: "fever", category: "Smileys" },
397
+ { emoji: "🤕", name: "bandage", category: "Smileys" },
398
+ { emoji: "🤡", name: "clown", category: "Smileys" },
399
+ { emoji: "👻", name: "ghost", category: "Smileys" },
400
+ { emoji: "👽", name: "alien", category: "Smileys" },
401
+ { emoji: "👾", name: "robot", category: "Smileys" },
402
+ { emoji: "💩", name: "poop", category: "Smileys" },
403
+ // Hearts & Symbols
404
+ { emoji: "❤️", name: "heart", category: "Symbols" },
405
+ { emoji: "🧡", name: "orange heart", category: "Symbols" },
406
+ { emoji: "💛", name: "yellow heart", category: "Symbols" },
407
+ { emoji: "💚", name: "green heart", category: "Symbols" },
408
+ { emoji: "💙", name: "blue heart", category: "Symbols" },
409
+ { emoji: "💜", name: "purple heart", category: "Symbols" },
410
+ { emoji: "🖤", name: "black heart", category: "Symbols" },
411
+ { emoji: "🤍", name: "white heart", category: "Symbols" },
412
+ { emoji: "🤎", name: "brown heart", category: "Symbols" },
413
+ { emoji: "💔", name: "broken heart", category: "Symbols" },
414
+ { emoji: "❣️", name: "heart exclamation", category: "Symbols" },
415
+ { emoji: "💕", name: "two hearts", category: "Symbols" },
416
+ { emoji: "💞", name: "revolving hearts", category: "Symbols" },
417
+ { emoji: "✨", name: "sparkles", category: "Symbols" },
418
+ { emoji: "🔥", name: "fire", category: "Symbols" },
419
+ { emoji: "⭐", name: "star", category: "Symbols" },
420
+ { emoji: "🌟", name: "glowing star", category: "Symbols" },
421
+ { emoji: "✅", name: "check", category: "Symbols" },
422
+ { emoji: "❌", name: "cross", category: "Symbols" },
423
+ { emoji: "💯", name: "hundred", category: "Symbols" },
424
+ { emoji: "💢", name: "anger", category: "Symbols" },
425
+ { emoji: "💥", name: "collision", category: "Symbols" },
426
+ { emoji: "💫", name: "dizzy symbol", category: "Symbols" },
427
+ { emoji: "💦", name: "sweat drops", category: "Symbols" },
428
+ { emoji: "💨", name: "dash", category: "Symbols" },
429
+ // Hand Gestures
430
+ { emoji: "👍", name: "thumbs up", category: "Hands" },
431
+ { emoji: "👎", name: "thumbs down", category: "Hands" },
432
+ { emoji: "👌", name: "ok", category: "Hands" },
433
+ { emoji: "✌️", name: "victory", category: "Hands" },
434
+ { emoji: "🤞", name: "fingers crossed", category: "Hands" },
435
+ { emoji: "🤟", name: "rock on", category: "Hands" },
436
+ { emoji: "🤘", name: "horns", category: "Hands" },
437
+ { emoji: "🤙", name: "call me", category: "Hands" },
438
+ { emoji: "👈", name: "point left", category: "Hands" },
439
+ { emoji: "👉", name: "point right", category: "Hands" },
440
+ { emoji: "👆", name: "point up", category: "Hands" },
441
+ { emoji: "👇", name: "point down", category: "Hands" },
442
+ { emoji: "🖐️", name: "hand splayed", category: "Hands" },
443
+ { emoji: "✋", name: "raised hand", category: "Hands" },
444
+ { emoji: "🖖", name: "vulcan salute", category: "Hands" },
445
+ { emoji: "👋", name: "wave", category: "Hands" },
446
+ { emoji: "👏", name: "clap", category: "Hands" },
447
+ { emoji: "🙌", name: "hands up", category: "Hands" },
448
+ { emoji: "👐", name: "open hands", category: "Hands" },
449
+ { emoji: "🤲", name: "palms up", category: "Hands" },
450
+ { emoji: "🤝", name: "handshake", category: "Hands" },
451
+ { emoji: "🙏", name: "pray", category: "Hands" },
452
+ { emoji: "💪", name: "flex", category: "Hands" },
453
+ { emoji: "✍️", name: "writing", category: "Hands" },
454
+ { emoji: "🤳", name: "selfie", category: "Hands" },
455
+ // Animals & Nature
456
+ { emoji: "🐶", name: "dog", category: "Animals" },
457
+ { emoji: "🐱", name: "cat", category: "Animals" },
458
+ { emoji: "🐭", name: "mouse", category: "Animals" },
459
+ { emoji: "🐹", name: "hamster", category: "Animals" },
460
+ { emoji: "🐰", name: "rabbit", category: "Animals" },
461
+ { emoji: "🦊", name: "fox", category: "Animals" },
462
+ { emoji: "🐻", name: "bear", category: "Animals" },
463
+ { emoji: "🐼", name: "panda", category: "Animals" },
464
+ { emoji: "🐨", name: "koala", category: "Animals" },
465
+ { emoji: "🐯", name: "tiger", category: "Animals" },
466
+ { emoji: "🦁", name: "lion", category: "Animals" },
467
+ { emoji: "🐮", name: "cow", category: "Animals" },
468
+ { emoji: "🐷", name: "pig", category: "Animals" },
469
+ { emoji: "🐸", name: "frog", category: "Animals" },
470
+ { emoji: "🐵", name: "monkey", category: "Animals" },
471
+ { emoji: "🐔", name: "chicken", category: "Animals" },
472
+ { emoji: "🐧", name: "penguin", category: "Animals" },
473
+ { emoji: "🐦", name: "bird", category: "Animals" },
474
+ { emoji: "🐤", name: "chick", category: "Animals" },
475
+ { emoji: "🦆", name: "duck", category: "Animals" },
476
+ { emoji: "🦅", name: "eagle", category: "Animals" },
477
+ { emoji: "🦉", name: "owl", category: "Animals" },
478
+ { emoji: "🦇", name: "bat", category: "Animals" },
479
+ { emoji: "🦄", name: "unicorn", category: "Animals" },
480
+ { emoji: "🐝", name: "bee", category: "Animals" },
481
+ { emoji: "🦋", name: "butterfly", category: "Animals" },
482
+ { emoji: "🐌", name: "snail", category: "Animals" },
483
+ { emoji: "🐞", name: "ladybeetle", category: "Animals" },
484
+ { emoji: "🐢", name: "turtle", category: "Animals" },
485
+ { emoji: "🐍", name: "snake", category: "Animals" },
486
+ { emoji: "🐙", name: "octopus", category: "Animals" },
487
+ { emoji: "🐬", name: "dolphin", category: "Animals" },
488
+ { emoji: "🐳", name: "whale", category: "Animals" },
489
+ { emoji: "🐟", name: "fish", category: "Animals" },
490
+ { emoji: "🦓", name: "zebra", category: "Animals" },
491
+ { emoji: "🦒", name: "giraffe", category: "Animals" },
492
+ { emoji: "🐘", name: "elephant", category: "Animals" },
493
+ { emoji: "🦏", name: "rhino", category: "Animals" },
494
+ { emoji: "🐪", name: "camel", category: "Animals" },
495
+ { emoji: "🐒", name: "monkey", category: "Animals" },
496
+ // Food & Drink
497
+ { emoji: "🍎", name: "apple", category: "Food" },
498
+ { emoji: "🍐", name: "pear", category: "Food" },
499
+ { emoji: "🍊", name: "tangerine", category: "Food" },
500
+ { emoji: "🍋", name: "lemon", category: "Food" },
501
+ { emoji: "🍌", name: "banana", category: "Food" },
502
+ { emoji: "🍉", name: "watermelon", category: "Food" },
503
+ { emoji: "🍇", name: "grapes", category: "Food" },
504
+ { emoji: "🍓", name: "strawberry", category: "Food" },
505
+ { emoji: "🍒", name: "cherries", category: "Food" },
506
+ { emoji: "🍑", name: "peach", category: "Food" },
507
+ { emoji: "🥭", name: "mango", category: "Food" },
508
+ { emoji: "🍍", name: "pineapple", category: "Food" },
509
+ { emoji: "🥥", name: "coconut", category: "Food" },
510
+ { emoji: "🥝", name: "kiwi", category: "Food" },
511
+ { emoji: "🍅", name: "tomato", category: "Food" },
512
+ { emoji: "🥑", name: "avocado", category: "Food" },
513
+ { emoji: "🍆", name: "eggplant", category: "Food" },
514
+ { emoji: "🥔", name: "potato", category: "Food" },
515
+ { emoji: "🥕", name: "carrot", category: "Food" },
516
+ { emoji: "🌽", name: "corn", category: "Food" },
517
+ { emoji: "🌶️", name: "hot pepper", category: "Food" },
518
+ { emoji: "🥦", name: "broccoli", category: "Food" },
519
+ { emoji: "🍄", name: "mushroom", category: "Food" },
520
+ { emoji: "🥜", name: "peanuts", category: "Food" },
521
+ { emoji: "🍞", name: "bread", category: "Food" },
522
+ { emoji: "🥐", name: "croissant", category: "Food" },
523
+ { emoji: "🥯", name: "bagel", category: "Food" },
524
+ { emoji: "🥞", name: "pancakes", category: "Food" },
525
+ { emoji: "🧀", name: "cheese", category: "Food" },
526
+ { emoji: "🍖", name: "meat", category: "Food" },
527
+ { emoji: "🍗", name: "poultry leg", category: "Food" },
528
+ { emoji: "🥓", name: "bacon", category: "Food" },
529
+ { emoji: "🍔", name: "hamburger", category: "Food" },
530
+ { emoji: "🍟", name: "fries", category: "Food" },
531
+ { emoji: "🍕", name: "pizza", category: "Food" },
532
+ { emoji: "🌭", name: "hot dog", category: "Food" },
533
+ { emoji: "🥪", name: "sandwich", category: "Food" },
534
+ { emoji: "🌮", name: "taco", category: "Food" },
535
+ { emoji: "🌯", name: "burrito", category: "Food" },
536
+ { emoji: "🍳", name: "egg", category: "Food" },
537
+ { emoji: "🍲", name: "stew", category: "Food" },
538
+ { emoji: "🥣", name: "bowl", category: "Food" },
539
+ { emoji: "🥗", name: "salad", category: "Food" },
540
+ { emoji: "🍿", name: "popcorn", category: "Food" },
541
+ { emoji: "🍱", name: "bento", category: "Food" },
542
+ { emoji: "🍣", name: "sushi", category: "Food" },
543
+ { emoji: "🍤", name: "shrimp", category: "Food" },
544
+ { emoji: "🍦", name: "ice cream", category: "Food" },
545
+ { emoji: "🍧", name: "shaved ice", category: "Food" },
546
+ { emoji: "🍨", name: "ice cream", category: "Food" },
547
+ { emoji: "🍩", name: "donut", category: "Food" },
548
+ { emoji: "🍪", name: "cookie", category: "Food" },
549
+ { emoji: "🎂", name: "cake", category: "Food" },
550
+ { emoji: "🍰", name: "shortcake", category: "Food" },
551
+ { emoji: "🧁", name: "cupcake", category: "Food" },
552
+ { emoji: "🥧", name: "pie", category: "Food" },
553
+ { emoji: "🍫", name: "chocolate", category: "Food" },
554
+ { emoji: "🍬", name: "candy", category: "Food" },
555
+ { emoji: "🍭", name: "lollipop", category: "Food" },
556
+ { emoji: "🍮", name: "custard", category: "Food" },
557
+ { emoji: "🍯", name: "honey", category: "Food" },
558
+ { emoji: "🍼", name: "baby bottle", category: "Food" },
559
+ { emoji: "🥛", name: "milk", category: "Food" },
560
+ { emoji: "☕", name: "coffee", category: "Food" },
561
+ { emoji: "🍵", name: "tea", category: "Food" },
562
+ { emoji: "🍶", name: "sake", category: "Food" },
563
+ { emoji: "🍾", name: "champagne", category: "Food" },
564
+ { emoji: "🍷", name: "wine", category: "Food" },
565
+ { emoji: "🍸", name: "cocktail", category: "Food" },
566
+ { emoji: "🍹", name: "tropical drink", category: "Food" },
567
+ { emoji: "🍺", name: "beer", category: "Food" },
568
+ { emoji: "🍻", name: "beers", category: "Food" },
569
+ { emoji: "🥃", name: "tumbler glass", category: "Food" },
570
+ { emoji: "🥤", name: "soda", category: "Food" },
571
+ // Travel & Places
572
+ { emoji: "🚗", name: "car", category: "Travel" },
573
+ { emoji: "🚕", name: "taxi", category: "Travel" },
574
+ { emoji: "🚙", name: "bus", category: "Travel" },
575
+ { emoji: "🚌", name: "trolleybus", category: "Travel" },
576
+ { emoji: "🏎️", name: "racing car", category: "Travel" },
577
+ { emoji: "🚓", name: "police car", category: "Travel" },
578
+ { emoji: "🚑", name: "ambulance", category: "Travel" },
579
+ { emoji: "🚒", name: "fire engine", category: "Travel" },
580
+ { emoji: "🚐", name: "minibus", category: "Travel" },
581
+ { emoji: "🚚", name: "truck", category: "Travel" },
582
+ { emoji: "🚛", name: "articulated lorry", category: "Travel" },
583
+ { emoji: "🚜", name: "tractor", category: "Travel" },
584
+ { emoji: "🚲", name: "bicycle", category: "Travel" },
585
+ { emoji: "🛵", name: "scooter", category: "Travel" },
586
+ { emoji: "🏍️", name: "motorcycle", category: "Travel" },
587
+ { emoji: "🚄", name: "bullet train", category: "Travel" },
588
+ { emoji: "🚆", name: "train", category: "Travel" },
589
+ { emoji: "✈️", name: "airplane", category: "Travel" },
590
+ { emoji: "🚀", name: "rocket", category: "Travel" },
591
+ { emoji: "🛸", name: "ufo", category: "Travel" },
592
+ { emoji: "🚁", name: "helicopter", category: "Travel" },
593
+ { emoji: "🚢", name: "ship", category: "Travel" },
594
+ { emoji: "⛵", name: "sailboat", category: "Travel" },
595
+ { emoji: "⚓", name: "anchor", category: "Travel" },
596
+ { emoji: "⛽", name: "fuel pump", category: "Travel" },
597
+ { emoji: "🚦", name: "traffic light", category: "Travel" },
598
+ // Objects & Tools
599
+ { emoji: "💻", name: "laptop", category: "Objects" },
600
+ { emoji: "📱", name: "mobile", category: "Objects" },
601
+ { emoji: "☎️", name: "telephone", category: "Objects" },
602
+ { emoji: "⌨️", name: "keyboard", category: "Objects" },
603
+ { emoji: "🖥️", name: "desktop", category: "Objects" },
604
+ { emoji: "🖨️", name: "printer", category: "Objects" },
605
+ { emoji: "📸", name: "camera", category: "Objects" },
606
+ { emoji: "🎥", name: "video camera", category: "Objects" },
607
+ { emoji: "📺", name: "tv", category: "Objects" },
608
+ { emoji: "📻", name: "radio", category: "Objects" },
609
+ { emoji: "⏰", name: "alarm clock", category: "Objects" },
610
+ { emoji: "💡", name: "light bulb", category: "Objects" },
611
+ { emoji: "🔦", name: "flashlight", category: "Objects" },
612
+ { emoji: "🕯️", name: "candle", category: "Objects" },
613
+ { emoji: "🔨", name: "hammer", category: "Objects" },
614
+ { emoji: "🔧", name: "wrench", category: "Objects" },
615
+ { emoji: "🔩", name: "nut and bolt", category: "Objects" },
616
+ { emoji: "🔫", name: "water pistol", category: "Objects" },
617
+ { emoji: "💸", name: "money", category: "Objects" },
618
+ { emoji: "💵", name: "dollar bill", category: "Objects" },
619
+ { emoji: "💳", name: "credit card", category: "Objects" },
620
+ { emoji: "💎", name: "gem", category: "Objects" },
621
+ { emoji: "⚖️", name: "balance scale", category: "Objects" },
622
+ { emoji: "🔗", name: "link", category: "Objects" },
623
+ { emoji: "⛓️", name: "chains", category: "Objects" },
624
+ { emoji: "💉", name: "syringe", category: "Objects" },
625
+ { emoji: "💊", name: "pill", category: "Objects" },
626
+ { emoji: "🚪", name: "door", category: "Objects" },
627
+ { emoji: "🛏️", name: "bed", category: "Objects" },
628
+ { emoji: "🛋️", name: "couch", category: "Objects" },
629
+ { emoji: "🚿", name: "shower", category: "Objects" },
630
+ { emoji: "🛁", name: "bathtub", category: "Objects" },
631
+ { emoji: "🔑", name: "key", category: "Objects" },
632
+ { emoji: "🧹", name: "broom", category: "Objects" },
633
+ // Activities & Hobbies
634
+ { emoji: "⚽", name: "soccer", category: "Activities" },
635
+ { emoji: "🏀", name: "basketball", category: "Activities" },
636
+ { emoji: "🏈", name: "football", category: "Activities" },
637
+ { emoji: "⚾", name: "baseball", category: "Activities" },
638
+ { emoji: "🎾", name: "tennis", category: "Activities" },
639
+ { emoji: "🏐", name: "volleyball", category: "Activities" },
640
+ { emoji: "🏉", name: "rugby", category: "Activities" },
641
+ { emoji: "🎱", name: "pool", category: "Activities" },
642
+ { emoji: "⛳", name: "golf", category: "Activities" },
643
+ { emoji: "🪁", name: "kite", category: "Activities" },
644
+ { emoji: "🏹", name: "bow and arrow", category: "Activities" },
645
+ { emoji: "🎣", name: "fishing", category: "Activities" },
646
+ { emoji: "🥊", name: "boxing", category: "Activities" },
647
+ { emoji: "🥋", name: "martial arts", category: "Activities" },
648
+ { emoji: "⛸️", name: "ice skate", category: "Activities" },
649
+ { emoji: "🎿", name: "ski", category: "Activities" },
650
+ { emoji: "🏂", name: "snowboard", category: "Activities" },
651
+ { emoji: "🏋️", name: "weightlifter", category: "Activities" },
652
+ { emoji: "🤺", name: "fencing", category: "Activities" },
653
+ { emoji: "🤼", name: "wrestling", category: "Activities" },
654
+ { emoji: "🤸", name: "cartwheel", category: "Activities" },
655
+ { emoji: "🏆", name: "trophy", category: "Activities" },
656
+ { emoji: "🏅", name: "medal", category: "Activities" },
657
+ { emoji: "🥇", name: "first place", category: "Activities" },
658
+ { emoji: "🎟️", name: "ticket", category: "Activities" },
659
+ { emoji: "🎮", name: "video game", category: "Activities" },
660
+ { emoji: "🎲", name: "die", category: "Activities" },
661
+ { emoji: "♟️", name: "chess", category: "Activities" },
662
+ { emoji: "🎹", name: "piano", category: "Activities" },
663
+ { emoji: "🎸", name: "guitar", category: "Activities" },
664
+ { emoji: "🎺", name: "trumpet", category: "Activities" },
665
+ { emoji: "🎻", name: "violin", category: "Activities" },
666
+ { emoji: "🥁", name: "drum", category: "Activities" },
667
+ { emoji: "🎭", name: "performing arts", category: "Activities" },
668
+ { emoji: "🎨", name: "artist palette", category: "Activities" },
669
+ { emoji: "🎬", name: "clapper board", category: "Activities" },
670
+ { emoji: "🎤", name: "microphone", category: "Activities" },
671
+ { emoji: "🎧", name: "headphone", category: "Activities" }
672
+ ];
673
+ class z {
674
+ container;
675
+ searchInput;
676
+ emojiGrid;
677
+ onSelect;
678
+ onClose;
679
+ constructor(e, t) {
680
+ this.onSelect = e, this.onClose = t, this.container = this.createPickerElement(), this.searchInput = this.container.querySelector(".te-emoji-search"), this.emojiGrid = this.container.querySelector(".te-emoji-grid"), this.setupEvents(), this.renderEmojis(d);
681
+ }
682
+ createPickerElement() {
683
+ const e = document.createElement("div");
684
+ return e.classList.add("te-emoji-picker"), e.innerHTML = `
685
+ <div class="te-emoji-header">
686
+ <input type="text" class="te-emoji-search" placeholder="Search emoji...">
687
+ </div>
688
+ <div class="te-emoji-body">
689
+ <div class="te-emoji-grid"></div>
690
+ </div>
691
+ `, e;
692
+ }
693
+ setupEvents() {
694
+ this.searchInput.addEventListener("mousedown", (t) => t.stopPropagation()), this.searchInput.addEventListener("click", (t) => t.stopPropagation()), this.searchInput.addEventListener("input", () => {
695
+ const t = this.searchInput.value.toLowerCase(), i = d.filter(
696
+ (o) => o.name.toLowerCase().includes(t) || o.category.toLowerCase().includes(t)
697
+ );
698
+ this.renderEmojis(i);
699
+ });
700
+ const e = (t) => {
701
+ this.container.contains(t.target) || (this.close(), document.removeEventListener("mousedown", e));
702
+ };
703
+ setTimeout(() => document.addEventListener("mousedown", e), 0);
704
+ }
705
+ renderEmojis(e) {
706
+ if (this.emojiGrid.innerHTML = "", e.length === 0) {
707
+ this.emojiGrid.innerHTML = '<div class="te-emoji-empty">No emoji found</div>';
708
+ return;
709
+ }
710
+ this.searchInput.value.length > 0 ? this.renderGridItems(e) : ["Smileys", "Symbols", "Hands", "Animals", "Food", "Travel", "Objects", "Activities"].forEach((o) => {
711
+ const a = e.filter((n) => n.category === o);
712
+ if (a.length > 0) {
713
+ const n = document.createElement("div");
714
+ n.classList.add("te-emoji-category-title"), n.textContent = o, this.emojiGrid.appendChild(n), this.renderGridItems(a);
715
+ }
716
+ });
717
+ }
718
+ renderGridItems(e) {
719
+ e.forEach((t) => {
720
+ const i = document.createElement("button");
721
+ i.type = "button", i.classList.add("te-emoji-item"), i.textContent = t.emoji, i.title = t.name, i.addEventListener("click", () => {
722
+ this.onSelect(t.emoji), this.close();
723
+ }), this.emojiGrid.appendChild(i);
724
+ });
725
+ }
726
+ show(e) {
727
+ document.body.appendChild(this.container);
728
+ const t = e.getBoundingClientRect(), i = 280;
729
+ let o = t.bottom + window.scrollY + 5, a = t.left + window.scrollX;
730
+ a + i > window.innerWidth && (a = window.innerWidth - i - 10), this.container.style.top = `${o}px`, this.container.style.left = `${a}px`, this.searchInput.focus();
731
+ }
732
+ close() {
733
+ this.container.parentElement && (this.container.remove(), this.onClose());
734
+ }
735
+ get el() {
736
+ return this.container;
737
+ }
738
+ }
739
+ class G {
740
+ editor;
741
+ container;
742
+ savedRange = null;
743
+ items = N;
744
+ activePicker = null;
745
+ constructor(e) {
746
+ this.editor = e, this.container = this.createToolbarElement(), this.render();
747
+ }
748
+ createToolbarElement() {
749
+ const e = document.createElement("div");
750
+ return e.classList.add("te-toolbar"), e;
751
+ }
752
+ render() {
753
+ this.items.forEach((e) => {
754
+ if (e.type === "button")
755
+ this.renderButton(e);
756
+ else if (e.type === "select")
757
+ this.renderSelect(e);
758
+ else if (e.type === "input")
759
+ this.renderInput(e);
760
+ else if (e.type === "color-picker")
761
+ this.renderColorPicker(e);
762
+ else if (e.type === "divider") {
763
+ const t = document.createElement("div");
764
+ t.classList.add("te-divider"), this.container.appendChild(t);
765
+ }
766
+ }), this.editor.el.addEventListener("keyup", () => this.updateActiveStates()), this.editor.el.addEventListener("mouseup", () => this.updateActiveStates());
767
+ }
768
+ renderButton(e) {
769
+ const t = document.createElement("button");
770
+ t.classList.add("te-button"), t.innerHTML = e.icon || "", t.title = e.title, t.addEventListener("mousedown", (i) => {
771
+ if (i.preventDefault(), e.command === "insertEmoji") {
772
+ this.activePicker ? this.activePicker.close() : (this.activePicker = new z(
773
+ (o) => {
774
+ this.editor.execute("insertText", o);
775
+ },
776
+ () => {
777
+ this.activePicker = null;
778
+ }
779
+ ), this.activePicker.show(t));
780
+ return;
781
+ }
782
+ if (e.command === "createLink") {
783
+ const o = window.prompt("Enter the URL");
784
+ o && this.editor.createLink(o);
785
+ return;
786
+ }
787
+ e.command && this.editor.execute(e.command, e.value || null), this.updateActiveStates();
788
+ }), this.container.appendChild(t);
789
+ }
790
+ renderInput(e) {
791
+ const t = document.createElement("input");
792
+ t.type = "number", t.classList.add("te-input"), t.title = e.title, t.value = e.value || "", t.min = "1", t.max = "100";
793
+ const i = () => {
794
+ const a = window.getSelection();
795
+ if (a && a.rangeCount > 0) {
796
+ const n = a.getRangeAt(0);
797
+ this.editor.el.contains(n.commonAncestorContainer) && (this.savedRange = n.cloneRange());
798
+ }
799
+ };
800
+ t.addEventListener("mousedown", i), t.addEventListener("focus", i);
801
+ const o = () => {
802
+ let a = parseInt(t.value, 10);
803
+ if (!isNaN(a) && (a = Math.max(1, Math.min(100, a)), t.value = a.toString(), e.command === "fontSize")) {
804
+ if (this.savedRange) {
805
+ const n = this.editor.setStyle("font-size", `${a}px`, this.savedRange);
806
+ n && (this.savedRange = n);
807
+ } else
808
+ this.editor.setStyle("font-size", `${a}px`);
809
+ t.focus();
810
+ }
811
+ };
812
+ t.addEventListener("input", o), t.addEventListener("keydown", (a) => {
813
+ a.key === "Enter" && (o(), this.editor.focus());
814
+ }), this.container.appendChild(t);
815
+ }
816
+ renderSelect(e) {
817
+ const t = document.createElement("select");
818
+ t.classList.add("te-select"), t.title = e.title, e.options && e.options.forEach((i) => {
819
+ const o = document.createElement("option");
820
+ o.value = i.value, o.textContent = i.label, t.appendChild(o);
821
+ }), t.addEventListener("change", () => {
822
+ const i = t.value;
823
+ this.savedRange && this.editor.selection.restoreSelection(this.savedRange), e.command === "formatBlock" ? this.editor.execute(e.command, i) : e.command === "fontFamily" && this.editor.setStyle("font-family", i), this.editor.focus();
824
+ }), t.addEventListener("mousedown", () => {
825
+ this.savedRange = this.editor.selection.saveSelection();
826
+ }), this.container.appendChild(t);
827
+ }
828
+ renderColorPicker(e) {
829
+ const t = document.createElement("input");
830
+ t.type = "color", t.classList.add("te-color-picker"), t.title = e.title, t.value = e.value || "#000000", t.addEventListener("mousedown", () => {
831
+ this.savedRange = this.editor.selection.saveSelection();
832
+ }), t.addEventListener("change", () => {
833
+ this.savedRange && this.editor.selection.restoreSelection(this.savedRange), e.command && this.editor.execute(e.command, t.value), this.editor.focus();
834
+ }), this.container.appendChild(t);
835
+ }
836
+ get el() {
837
+ return this.container;
838
+ }
839
+ updateActiveStates() {
840
+ const e = this.container.querySelectorAll(".te-button");
841
+ let t = 0;
842
+ this.items.forEach((i) => {
843
+ if (i.type === "button") {
844
+ const o = e[t++];
845
+ i.command && document.queryCommandState(i.command) ? o.classList.add("active") : o.classList.remove("active");
846
+ }
847
+ });
848
+ }
849
+ }
850
+ class V extends j {
851
+ toolbar;
852
+ constructor(e, t = {}) {
853
+ super(e, t), this.toolbar = new G(this), this.container.insertBefore(this.toolbar.el, this.editableElement);
854
+ }
855
+ }
856
+ export {
857
+ j as CoreEditor,
858
+ g as SelectionManager,
859
+ V as TestEditor,
860
+ G as Toolbar
861
+ };
862
+ //# sourceMappingURL=test-editor.mjs.map