Viewing File: /usr/local/cpanel/base/frontend/jupiter/filemanager/editors/html_editor_include.html.tt

[%
    USE JSON;
    USE UIAnalytics;
    SET account_locale = locale.get_user_locale(),
        direction = locale.get_html_dir_attr(),
        form = CPANEL.FORM,
        security_token = CPANEL.ENV.cp_security_token,
        directory_path = form.dir,
        file_name = form.file,
        charset = form.charset,
        file_charset = form.file_charset,
        base_url = form.baseurl _ '/',
        base_url_for_editor = CPANEL.ENV.cp_security_token _ '/frontend/jupiter/filemanager/editors/',
        base_dir = form.basedir,
        theme = CPANEL.CPDATA.RS,
        home_dir_path = CPANEL.ENV.HOME,
        url = "http://" _ CPANEL.ENV.DOMAIN;

    SET file_open_results = execute("Fileman", "get_file_content", {
        dir => directory_path,
        file => file_name,
        from_charset => charset
    });

    SET file_info = file_open_results.data;
    SET jodit_supported_locales = {
        'ar' => 'ar',
        'de' => 'de',
        'en' => 'en',
        'es' => 'es',
        'fi' => 'fi',
        'fr' => 'fr',
        'he' => 'he',
        'hu' => 'hu',
        'id' => 'id',
        'it' => 'it',
        'ja' => 'ja',
        'ko' => 'ko',
        'nl' => 'nl',
        'pl' => 'pl',
        'pt_br' => 'pt_br',
        'ru' => 'ru',
        'tr' => 'tr',
        'zh_tw' => 'zh_tw',

        # map some locales to closest supported by Jodit
        'cs' => 'cs_cz',
        'zh' => 'zh_cn',
        'uk' => 'ua',
        'nb' => 'no',
    };

    # Data for analytics purpose.
    SET cp_analytics_data = UIAnalytics.get_cpanel_analytics_data();
    SET analyticsConfig = {
        cpAnalyticsData => cp_analytics_data,
        debugMode => CPANEL.is_debug_mode_enabled(),
        loginUser => CPANEL.authuser,
        isSandbox => CPANEL.is_sandbox(),
        canTrackUserAnalytics => can_track_user_analytics,
        isUserAnalyticsRequiredByLeika => is_user_analytics_required_by_leika,
        # Add additional page meta to be sent to analytics.
    };
%]

<style type="text/css">
    [% INSERT "filemanager/editors/html_editor.css" %]
</style>

<div id="editor-status" class="editor-status">
    <cp-ui-load-analytics
        analytics-config="[% analyticsConfig.json() | html %]"
    >

    </cp-ui-load-analytics>
</div>

<form id="htmlEditorForm" class="cpanelHide">
    <div class="editor-container">
        <textarea id="jodit-editor" name="content"></textarea>
    </div>
</form>

<!-- Load required scripts -->
<script type="text/javascript" src="[% MagicRevision('/yui-gen/utilities_container/utilities_container.js') %]"></script>
<script type="text/javascript" src="[% MagicRevision('/cjt/cpanel-all.js') %]"></script>
<script type="text/javascript" src="[% MagicRevision('../../libraries/jquery/current/jquery.js') %]"></script>

        <script>
        window.LEXICON = window.LEXICON || {};
        [%
            cldr_path = 'libraries/cldr/' _ locale.get_language_tag() _ '.js';
            INSERT $cldr_path
        %]
        </script>

        [% IF CPANEL.is_debug_mode_enabled() %]
        <script src="[% theme_magic_url("core/web-components/dist/jupiter-web-components.cmb.js") %]"></script>
        [% ELSE %]
        <script src="[% theme_magic_url("core/web-components/dist/jupiter-web-components.cmb.min.js") %]"></script>
        [% END %]
        <script src="[% theme_magic_url("core/web-components/dist/jupiter-web-components.cmb-" _ locale.get_language_tag() _ ".js") %]"></script>
        [% PROCESS "_assets/_ajaxapp.html.tt" -%]

<!-- Load Jodit Editor -->
<script type="text/javascript" src="[% MagicRevision('../../libraries/jodit-editor/4.6.2/jodit.min.js') %]"></script>

<!-- Load our custom Jodit editor handler -->
[% SET lex_path = locale.cpanel_get_lex_path('/usr/local/cpanel/base/frontend/' _ theme _ '/filemanager/editors/html_editor.js', './html_editor.js') %]
[% IF lex_path %]<script src="[% lex_path %]"></script>[% END %]
<script type="text/javascript" src="./html_editor.js"></script>

<script type="text/javascript">
(function() {
    var appData = {
        fileContentInfo: [% file_info.json() || '{}' %],
        fileMetaData: {
            dirPath: [% directory_path.json() || '""' %],
            fileName: [% file_name.json() || '""' %],
            charset: [% file_info.from_charset.json() || '""' %]
        },
        securityToken: [% security_token.json() || '""' %],
        baseUrlForEditor: '[% base_url_for_editor %]',
        baseUrl: '[% base_url %]',
        formID: "htmlEditorForm"
    };

    var directoryPath = '[% directory_path %]';
    var domain = '[% CPANEL.ENV.DOMAIN %]';
    var baseUrl = '[% base_url %]';
    var baseUrlForEditor = '[% base_url_for_editor %]';
    var validImgExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp', 'ico'];

    var joditConfig = {
        elementId: 'jodit-editor',
        joditOptions: {
            editHTMLDocumentMode: true,
            iframe: true,
            iframeStyle: 'html{margin:0;padding:0;min-height: 100%;}body{box-sizing:border-box;font-size:13px;line-height:1.6;padding:10px;margin:0;background:transparent;color:#000;position:relative;z-index:2;user-select:auto;margin:0px;overflow:auto;outline:none;}table{width:100%;border:none;border-collapse:collapse;empty-cells: show;max-width: 100%;}th,td{padding: 2px 5px;border:1px solid #ccc;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}p{margin-top:0;}.jodit_editor .jodit_iframe_wrapper{display: block;clear: both;user-select: none;position: relative;}.jodit_editor .jodit_iframe_wrapper:after {position:absolute;content:"";z-index:1;top:0;left:0;right: 0;bottom: 0;cursor: pointer;display: block;background: rgba(0, 0, 0, 0);} .jodit_disabled{user-select: none;-o-user-select: none;-moz-user-select: none;-khtml-user-select: none;-webkit-user-select: none;-ms-user-select: none}',
            iframeSandbox: 'allow-same-origin',
            basePath: baseUrl,

            height: '100%',
            width: '100%',
            fullsize: true,
            removeButtons: ['fullsize'],

            language: '[% jodit_supported_locales.exists(account_locale) ? jodit_supported_locales.$account_locale : "en" %]',
            direction: '[% direction %]',

            toolbar: true,
            toolbarSticky: true,
            toolbarAdaptive: true,
            showCharsCounter: true,
            showWordsCounter: true,
            showXPathInStatusbar: false,

            buttons: [
                {
                    name: 'save',
                    tooltip: '[% locale.maketext("Save File") %]',
                    iconURL: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiPjxwYXRoIGQ9Ik01MTIgMTUzNmg3Njh2LTM4NGgtNzY4djM4NHptODk2IDBoMTI4di04OTZxMC0xNC0xMC0zOC41dC0yMC0zNC41bC0yODEtMjgxcS0xMC0xMC0zNC0yMHQtMzktMTB2NDE2cTAgNDAtMjggNjh0LTY4IDI4aC01NzZxLTQwIDAtNjgtMjh0LTI4LTY4di00MTZoLTEyOHYxMjgwaDEyOHYtNDE2cTAtNDAgMjgtNjh0NjgtMjhoODMycTQwIDAgNjggMjh0MjggNjh2NDE2em0tMzg0LTkyOHYtMzIwcTAtMTMtOS41LTIyLjV0LTIyLjUtOS41aC0xOTJxLTEzIDAtMjIuNSA5LjV0LTkuNSAyMi41djMyMHEwIDEzIDkuNSAyMi41dDIyLjUgOS41aDE5MnExMyAwIDIyLjUtOS41dDkuNS0yMi41em02NDAgMzJ2OTI4cTAgNDAtMjggNjh0LTY4IDI4aC0xMzQ0cS00MCAwLTY4LTI4dC0yOC02OHYtMTM0NHEwLTQwIDI4LTY4dDY4LTI4aDkyOHE0MCAwIDg4IDIwdDc2IDQ4bDI4MCAyODBxMjggMjggNDggNzZ0MjAgODh6Ij48L3BhdGg+PC9zdmc+',
                    exec: function(editor) {
                        CPANEL.joditEditor.saveFile();
                    }
                },
                '|','bold','italic','underline','strikethrough',
                '|','eraser','copyformat',
                '|','font','fontsize','brush','paragraph','lineHeight',
                '|','ul','ol',
                '|','hr',
                '|','left','center','right','justify',
                '|','indent','outdent',
                '|','\n','undo','redo',
                '|','cut','copy','paste',
                '|','image','video','file',
                '|','table',
                '|','link','unlink',
                '|','superscript','subscript',
                '|','find','---','source',
                '|','selectall'
            ],

            uploader: {
                url: "[% security_token %]/execute/Fileman/upload_files",
                format: 'json',
                imagesExtensions: validImgExtensions,
                maxFileSize: 5 * 1024 * 1024, // (5MB)
                multiple: true,
                headers: {
                    'X-Requested-With': 'XMLHttpRequest'
                },
                data: {
                    dir: "[% directory_path %]",
                    overwrite: 0
                },
                filesVariableName: function(i) {
                    return 'file';
                },

                isSuccess: function(resp) {
                    var success = !resp.errors;

                    if (!success) {
                          let joditEditor = CPANEL.joditEditor.getEditor()

                          resp.errors.forEach((errorMsg) => {
                               console.error(`Upload error: ${errorMsg}`);
                               window.JoditUXHelpers.showToast(`Image upload failed: ${errorMsg}`);
                          });

                          if (this._progressInterval) {
                              clearInterval(this._progressInterval);
                              this._progressInterval = null;
                          }

                          if (this._currentImageUploadIds) {
                              this._currentImageUploadIds.forEach(function(fileId) {
                                  window.JoditUXHelpers.updateProgress(fileId, 100, 'Error');
                              });
                          }
                    }

                    if (success && this._currentImageUploadIds) {
                        var completedFileIds = this._currentImageUploadIds.slice();

                        this._currentImageUploadIds = null;

                        setTimeout(function() {
                           completedFileIds.forEach(function(fileId) {
                              CPANEL.joditEditor.updateUploadProgress(fileId, 100, 'Complete');
                           });
                        }, 350);
                    }
                      return resp && success;
                },

                getMessage: function(resp) {
                    return resp && resp.data && resp.data?.msg ? resp.data?.msg : '';
                },

                prepareData: function(formData) {
                    formData.append('upload_timestamp', Date.now());
                    formData.append('upload_source', 'jodit_image_uploader');
                    formData.append('upload_type', 'image');

                    var images = [];
                    for (var pair of formData.entries()) {
                        if (pair[1] instanceof File) {
                            images.push(pair[1]);
                        }
                    }

                    if (images.length > 0 && typeof CPANEL !== 'undefined' && CPANEL.joditEditor && window.JoditUXHelpers) {
                        var fileIds = window.JoditUXHelpers.showProgress(images);
                        this._currentImageUploadIds = fileIds;

                        window.JoditUXHelpers.startSimulatedProgress(fileIds);
                    }
                    return formData;
                },

                error: function(e) {
                    console.error('Upload error:', e);

                    if (this._progressInterval) {
                        clearInterval(this._progressInterval);
                        this._progressInterval = null;
                    }

                    if (this._currentImageUploadIds) {
                        this._currentImageUploadIds.forEach(function(fileId) {
                            window.JoditUXHelpers.updateProgress(fileId, 100, 'Error');
                        });
                    }
                },

                processFileName: function(key, file, name) {
                    var timestamp = Date.now();
                    var sanitizedName = name.replace(/[^a-zA-Z0-9.-]/g, '_');
                    var extension = sanitizedName.split('.').pop();
                    var baseName = sanitizedName.replace('.' + extension, '');
                    var finalName = baseName + '_' + timestamp + '.' + extension;

                    return [key, file, finalName];
                },

                process: function(resp) {
                        var fileUrl = './';
                        var uploadedFileUrls = [];

                        if (resp?.data?.uploads) {
                            if (fileUrl && !fileUrl.endsWith('/')) {
                                fileUrl += '/';
                            }
                            resp.data.uploads.forEach((uploadedFile) => {
                                uploadedFileUrls.push(fileUrl + uploadedFile.file);
                            });
                        }

                    return {
                        files: [...uploadedFileUrls] || [],
                        path: resp.data?.path || '',
                        baseurl: baseUrl || '',
                        error: resp.errors,
                        messages: resp.messages
                    };
                },

                defaultHandlerSuccess: function (data) {
                    var joditEditor = CPANEL.joditEditor.getEditor();

                    if (data.files && data.files.length) {
                        data.files.forEach(function(imageUrl){
                            extension = imageUrl.split('.').pop().toLowerCase();
                            isImage = validImgExtensions.some(function(validExt) {
                                 return extension === validExt.toLowerCase();
                            });

                            if (!isImage) {
                                return;
                            }

                            var img = joditEditor.createInside.element('img');

                            img.setAttribute('src', imageUrl);
                            img.setAttribute('alt', imageUrl.replace(/\.[^/.]+$/, ''));
                            img.setAttribute('loading', 'lazy');

                            joditEditor.selection.insertImage(img);
                        });
                    }
                    this._currentImageUploadIds = null;
                },
            },

            defaultHandlerError: function(e) {
                console.error('Default handler error: ', e);
            },

            filebrowser: {
                ajax: {
                    url: "[% security_token %]/execute/Jodit/filebrowser",
                    method: 'GET',
                    dataType: 'json',
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    prepareData: function(data, resp, options) {
                        var currentPath = data.path || '';
                        var baseDir = "[% directory_path %]" || "[% base_dir %]";

                        var fullPath = baseDir;
                        if (currentPath && currentPath !== '') {
                            fullPath = baseDir + '/' + currentPath;
                        }

                        var requestData = {
                            action: data.action || 'files',
                            dir: directoryPath,
                            dirPath: fullPath,
                            source: data.source || 'default',
                            path: currentPath
                        };
                        return requestData;
                    },

                    process: function(resp) {
                        if (!resp || !resp.success) {
                            console.error('Filebrowser error:', resp && resp.data ? resp.data.error : 'Unknown error');
                            return {
                                success: false,
                                time: new Date().toISOString(),
                                data: {
                                    code: 500,
                                    error: resp && resp.data ? resp.data.error : 'Failed to load files'
                                }
                            };
                        }

                        if (!resp.data || !resp.data.sources || !Array.isArray(resp.data.sources)) {
                            console.warn('Sources is not an array or missing:', resp.data ? resp.data.sources : 'No data');
                        }
                        return resp;
                    }
                },

                showFoldersPanel: true,
                view: 'list',
                allowFolders: true,
                showFolders: true,

                defaultView: 'list',

                createNewFolder: false,
                deleteFolder: false,
                renameFolder: false,
                moveFolder: false,
                moveFile: false,
                renameFile: false,
                deleteFile: false,

                showPreviewButton: true,
                showSelectButtonInPreview: true,
                howLongShowMsg: 3000,
                sortBy: 'name',

                folderTree: true,
                filter: function(item, search) {
                    var isImageContext = this.options && this.options.isImageBrowser;
                    if (isImageContext) {
                        return item.isImage || /\.(jpg|jpeg|png|gif|bmp|webp|svg|ico)$/i.test(item.file);
                    }
                    var name = item.file.toLowerCase();
                    return /\.(jpg|jpeg|png|gif|bmp|webp|svg|ico|pdf|txt|html|htm|css|js|doc|docx|xls|xlsx|zip|rar)$/i.test(name);
                }
            },

            allowResizeX: false,
            allowResizeY: false,
            minHeight: 1000,

            askBeforePasteHTML: false,
            askBeforePasteFromWord: false,
            defaultActionOnPaste: 'insert_clear_html',

            link: {
                followOnDblClick: false,
                processVideoLink: true,
                processPastedLink: true,
                openInNewTabCheckbox: true,
                noFollowCheckbox: true
            },

            image: {
                openOnDblClick: false,
                editSrc: true,
                useImageEditor: false,
                editTitle: true,
                editAlt: true,
                editLink: true,
                editSize: true,
                editBorderRadius: true,
                editMargins: true,
                editClass: true,
                editStyle: true,
                editId: true,
                resizer: true,
                selectImageAfterClose: true,
                processImageOnPaste: true,
                maxImageSize: 5 * 1024 * 1024, // 5MB limit
                resizeOnUpload: true,
                maxWidth: 1200,
                maxHeight: 800,
                quality: 0.8,
                defaultAlt: 'Uploaded image'
            },

            enableDragAndDropFileToEditor: true,
            draggableTags: ['img', 'a', 'jodit-media'],
            dragAndDropElement: document.body,

            table: {
                selectionCellStyle: 'border: 1px double #1e88e5 !important;',
                useExtraClassesOptions: false
            },

            beautifyHTML: true,
            extraPlugins: ['about', 'xpath'],
            disablePlugins: ['mobile', 'image-properties'],

            events: {
                afterInit: function(jodit) {
                    processExistingTables(jodit);

                    setTimeout(function() {
                        processExistingTables(jodit);
                    }, 500);
                },

                afterSetMode: function(jodit) {
                    if (!jodit || typeof jodit.getRealMode !== 'function') {
                        return;
                    }

                    if (jodit.getRealMode() === 'wysiwyg') {
                        processExistingTables(jodit);
                    }
                },

                processHTML: function(html) {
                    return cleanTableStyles(html);
                }
            }
        }
    };

    function processExistingTables(jodit) {
        try {
            var editorDocument = jodit.iframe ?
                (jodit.iframe.contentDocument || jodit.iframe.contentWindow.document) :
                jodit.editor;

            if (!editorDocument) return;

            var tables = editorDocument.querySelectorAll('table');

            tables.forEach(function(table) {
                table.removeAttribute('style');
                table.removeAttribute('border');
                table.removeAttribute('cellpadding');
                table.removeAttribute('cellspacing');

                table.style.borderCollapse = 'collapse';
                table.style.width = '100%';
                table.style.border = '1px solid #ddd';

                var cells = table.querySelectorAll('th, td');
                cells.forEach(function(cell) {
                    var existingStyle = cell.getAttribute('style') || '';
                    var textAlign = cell.style.textAlign || '';

                    cell.removeAttribute('style');
                    cell.style.border = '1px solid #ddd';
                    cell.style.padding = '8px';

                    if (textAlign) {
                        cell.style.textAlign = textAlign;
                    }

                    if (cell.tagName === 'TH') {
                        cell.style.backgroundColor = '#f5f5f5';
                        cell.style.fontWeight = 'bold';
                    }
                });
            });

            if (editorDocument.body) {
                editorDocument.body.style.display = 'none';
                editorDocument.body.offsetHeight;
                editorDocument.body.style.display = '';
            }
        } catch (e) {
            console.error('Error processing existing tables:', e);
        }
    }

    function cleanTableStyles(html) {
        if (!html) return html;

        try {
            var temp = document.createElement('div');
            temp.innerHTML = html;

            var tables = temp.querySelectorAll('table');
            tables.forEach(function(table) {
                table.removeAttribute('border');
                table.removeAttribute('cellpadding');
                table.removeAttribute('cellspacing');
                table.removeAttribute('width');

                var cells = table.querySelectorAll('th, td');
                cells.forEach(function(cell) {
                    cell.removeAttribute('width');
                    cell.removeAttribute('height');
                });
            });
            return temp.innerHTML;
        } catch (e) {
            console.error('Error cleaning table styles:', e);
            return html;
        }
    }

    window.JoditUXHelpers = {
        progressContainer: null,
        uploadFiles: new Map(),

        startSimulatedProgress: function(fileIds) {
            var self = this;
            var progressValue = 10;

            if (this._progressInterval) {
                clearInterval(this._progressInterval);
                this._progressInterval = null;
            }

            this._progressStopped = false;

            this._progressInterval = setInterval(function() {

                if (self._progressStopped) {
                    clearInterval(self._progressInterval);
                    self._progressInterval = null;
                    return;
                }

                if (fileIds && progressValue < 90) {
                    progressValue += Math.random() * 15;
                    progressValue = Math.min(90, progressValue);

                    if (!self._progressStopped) {
                       fileIds.forEach(function(fileId) {
                           window.JoditUXHelpers.updateProgress(
                               fileId,
                               progressValue,
                               'Uploading...'
                           );
                       });
                    }
                } else {
                    clearInterval(self._progressInterval);
                    self._progressInterval = null;
                }
            }, 300);
        },

        createProgressContainer: function() {
            if (this.progressContainer) return this.progressContainer;

            var container = document.createElement('div');
            container.className = 'jodit-upload-progress';
            container.innerHTML =
                '<div class="jodit-upload-progress-header">' +
                    '<span>Uploading Images</span>' +
                    '<button class="jodit-upload-progress-close" onclick="JoditUXHelpers.hideProgress()">&times;</button>' +
                '</div>' +
                '<div class="jodit-upload-progress-files"></div>';

            var closeBtn = container.querySelector('.jodit-upload-progress-close');
            if (closeBtn) {
                closeBtn.addEventListener('click', function() {
                    JoditUXHelpers.hideProgress();
                });
            }
            document.body.appendChild(container);
            this.progressContainer = container;
            return container;
        },

        showProgress: function(files) {
            var container = this.createProgressContainer();
            var filesContainer = container.querySelector('.jodit-upload-progress-files');

            filesContainer.innerHTML = '';
            this.uploadFiles.clear();

            var fileIds = [];

            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                var fileId = 'upload-' + Date.now() + '-' + i;
                fileIds.push(fileId);

                var fileItem = document.createElement('div');
                fileItem.className = 'jodit-upload-file-item';
                fileItem.innerHTML =
                    '<div class="jodit-upload-file-name">' + file.name + '</div>' +
                    '<div class="jodit-upload-file-progress">' +
                        '<div class="jodit-upload-file-progress-bar" id="' + fileId + '-bar"></div>' +
                    '</div>' +
                    '<div class="jodit-upload-file-status" id="' + fileId + '-status">Preparing...</div>';

                filesContainer.appendChild(fileItem);
                this.uploadFiles.set(fileId, { file: file, element: fileItem });
            }

            container.classList.add('show');

            var self = this;
            setTimeout(function() {
                if (self.progressContainer && self.progressContainer.classList.contains('show')) {
                    self.hideProgress();
                }
            }, 30000);
            return fileIds;
        },

        updateProgress: function(fileId, progress, status) {
            var progressBar = document.getElementById(fileId + '-bar');
            var statusElement = document.getElementById(fileId + '-status');

            if (progressBar) {
                progressBar.style.width = progress + '%';
                if (status && status.includes('Error')) {
                    progressBar.classList.add('error');
                }
            } else {
                console.error('Progress bar not found for', fileId);
            }

            if (statusElement) {
                statusElement.textContent = status || 'Uploading...';
                if (status && status.includes('Complete')) {
                    statusElement.classList.add('success');
                } else if (status && status.includes('Error')) {
                    statusElement.classList.add('error');
                }
            } else {
                console.error('Status element not found for', fileId);
            }

            if (progress === 100) {
                this._progressStopped = true;

                if (this._progressInterval) {
                    clearInterval(this._progressInterval);
                    this._progressInterval = null;
                }

                setTimeout(function() {
                    JoditUXHelpers.hideProgress();
                }, 3000);
            }
        },

        hideProgress: function() {
            if (this.progressContainer) {
                this.progressContainer.classList.remove('show');
                setTimeout(() => {
                    if (this.progressContainer && this.progressContainer.parentNode) {
                        this.progressContainer.parentNode.removeChild(this.progressContainer);
                        this.progressContainer = null;
                    }
                }, 300);
            }
        },

        showToast: function(message, type) {
            var toast = document.createElement('div');
            toast.className = 'jodit-upload-toast ' + (type || 'info');
            toast.textContent = message;

            document.body.appendChild(toast);

            setTimeout(() => toast.classList.add('show'), 100);

            setTimeout(() => {
                toast.classList.remove('show');
                setTimeout(() => {
                    if (toast.parentNode) {
                        toast.parentNode.removeChild(toast);
                    }
                }, 300);
            }, 7000);
        },

        setupDragAndDrop: function(editor) {
            var container = editor.container;
            var dragCounter = 0;

            container.addEventListener('dragenter', function(e) {
                e.preventDefault();
                dragCounter++;
                container.classList.add('drag-over');
            });

            container.addEventListener('dragleave', function(e) {
                e.preventDefault();
                dragCounter--;
                if (dragCounter === 0) {
                    container.classList.remove('drag-over');
                }
            });

            container.addEventListener('dragover', function(e) {
                e.preventDefault();
            });

            container.addEventListener('drop', function(e) {
                e.preventDefault();
                dragCounter = 0;
                container.classList.remove('drag-over');
            });
        }
    };

    function initializeEditor() {

        if (typeof CPANEL !== 'undefined' && CPANEL.joditEditor) {
            CPANEL.joditEditor.initialize(joditConfig, appData);

            setTimeout(function() {
                if (CPANEL.joditEditor.editor) {
                    var editor = CPANEL.joditEditor.editor;
                    JoditUXHelpers.setupDragAndDrop(editor);

                    try {
                        editor.events.on('afterUpload', function(data, resp) {
                            var uploadBtn = editor.toolbar.getButton('image');
                            if (uploadBtn && uploadBtn.container) {
                                uploadBtn.container.classList.remove('uploading');
                            }
                        });

                        editor.events.on('errorUpload', function(error, resp) {
                            console.error('Upload error:', error, resp);

                            var uploadBtn = editor.toolbar.getButton('image');
                            if (uploadBtn && uploadBtn.container) {
                                uploadBtn.container.classList.remove('uploading');
                            }
                        });
                    } catch (e) {
                        console.error('Some upload events not available:', e);
                    }

                    var originalUploader = editor.uploader;
                    if (originalUploader && originalUploader.bind) {
                        var originalBind = originalUploader.bind.bind(originalUploader);
                        originalUploader.bind = function(form, handlerSuccess, handlerError) {
                            var wrappedSuccess = function(data, resp) {
                                JoditUXHelpers.hideProgress();
                                if (handlerSuccess) {
                                    handlerSuccess.call(this, data, resp);
                                }
                            };

                            var wrappedError = function(error) {
                                JoditUXHelpers.hideProgress();
                                JoditUXHelpers.showToast('Upload failed: ' + (error.message || 'Unknown error'), 'error');
                                if (handlerError) {
                                    handlerError.call(this, error);
                                }
                            };
                            return originalBind(form, wrappedSuccess, wrappedError);
                        };
                    }
                }
            }, 1000);

        } else {
            setTimeout(function() {
                if (typeof CPANEL !== 'undefined' && CPANEL.joditEditor) {
                    initializeEditor();
                } else {
                    console.error('CPANEL.joditEditor still not available after retry');
                }
            }, 500);
        }
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initializeEditor);
    } else {
        initializeEditor();
    }

})();
</script>
Back to Directory File Manager