(function() { 'use strict'; class SISTinyMceTool { static get toolbox() { return { title: 'TinyMCE Editor', icon: '' }; } constructor({ data, api, readOnly }) { this.api = api; this.readOnly = readOnly; this.data = { html: data.html || '' }; this.editorId = 'tinymce-editor-' + Math.random().toString(36).substring(7); this.editorInstance = null; } render() { const wrapper = document.createElement('div'); wrapper.className = 'sis-tinymce-block-wrapper border rounded p-2 bg-white'; wrapper.style.minHeight = '280px'; const textarea = document.createElement('textarea'); textarea.id = this.editorId; textarea.value = this.data.html; textarea.style.width = '100%'; textarea.style.minHeight = '250px'; wrapper.appendChild(textarea); this.textareaElement = textarea; this._initTinyMCE(); return wrapper; } _initTinyMCE() { const self = this; if (typeof tinymce !== 'undefined') { self._createEditor(); return; } // Global loading queue to prevent duplicate script tags window.SISTinyMceLoading = window.SISTinyMceLoading || { loaded: false, callbacks: [] }; if (window.SISTinyMceLoading.loaded) { self._createEditor(); return; } window.SISTinyMceLoading.callbacks.push(() => { self._createEditor(); }); if (window.SISTinyMceLoading.callbacks.length === 1) { const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/tinymce@6/tinymce.min.js'; script.referrerPolicy = 'origin'; script.onload = () => { window.SISTinyMceLoading.loaded = true; while (window.SISTinyMceLoading.callbacks.length > 0) { const cb = window.SISTinyMceLoading.callbacks.shift(); try { cb(); } catch (e) { console.error(e); } } }; document.head.appendChild(script); } } _createEditor() { const self = this; const textarea = this.textareaElement || document.getElementById(this.editorId); if (!textarea) return; // Wait until the element is actually attached to the document DOM const checkAndInit = () => { if (!document.body.contains(textarea)) { requestAnimationFrame(checkAndInit); return; } tinymce.init({ target: textarea, height: 250, menubar: false, readonly: !!self.readOnly, plugins: 'advlist autolink lists link image charmap preview anchor searchreplace visualblocks code fullscreen insertdatetime media table code help wordcount', toolbar: 'undo redo | blocks | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table link image | code removeformat', setup: function(editor) { self.editorInstance = editor; editor.on('change keyup undo redo', function() { self.data.html = editor.getContent(); }); } }); }; checkAndInit(); } save(blockContent) { if (this.editorInstance) { this.data.html = this.editorInstance.getContent(); } return { html: this.data.html }; } destroy() { if (this.editorInstance) { tinymce.remove(this.editorInstance); this.editorInstance = null; } } } // Register globally window.SISEditorPlugins = window.SISEditorPlugins || {}; window.SISEditorPlugins['tinymce'] = { class: SISTinyMceTool }; })();