/**
    * @file editor.js
    * @brief Основной файл редактора, содержит базовые функции и переменные для работы с элементами страницы
*/

function pluginFun(action, side) {
	if (action === 'add') {
        jsonrpcRequest('getFolders', { folder: 'plugin' })
        .then(folders => {
            let pluginAddSideName = document.getElementById('pluginAdd' + (side === 'left' ? 'Left' : 'Right') + 'Name');
            pluginAddSideName.innerHTML = '';
            folders.forEach(folder => {
                let option = document.createElement('option');
                option.value = folder;
                option.textContent = folder;
                pluginAddSideName.appendChild(option);
            });
        });    
	}
}

addEventListener("LoadeditorJs", function()
{
/* movementMenu("basis3"); */
addEventListener("scroll", del);

let view=document.getElementById("view");           // Ссылка на элементы окна просмотра
let bas=document.getElementById("bas").style;
let pict=document.getElementById("pict");

/* view.addEventListener("click", del); */

function del()                                      // Функция закрытия окна просмотра
   {
    if (view) {
        view.style.visibility="hidden";
    }
   bas.visibility="hidden";
   }


}, { once: true });

/** @brief Список редактируемых элементов */
let editableElements;
/** @brief Режим редактирования: -1 = выключен */
let editMode = -1;
/** @brief Массив ID кнопок редактирования */
let editId = ['pluginDelete', 'titleEdit', 'pluginMove', 'elementEdit', 
   'editTableButtonAddLine', 'editTableButtonDeleteLine', 'editTableButtonAddColumn', 'editTableButtonDeleteColumn'] ;

/** @brief Переключает видимость и редактируемость элементов */
function basisVis() {
   editableElementsFun();
   let basis3 = document.getElementById('basis3');
   let sideFloatClass = basis3 ? basis3.querySelectorAll('[style*="visibility: visible;"]') : null;
   if (!basis3 || !sideFloatClass || !editableElements || editableElements.length === 0) return;
   elementsСhecked = [basis3, ...sideFloatClass, ...editableElements];
   
   if (basis3.style.visibility === "visible") {
      basis3.style.visibility = "hidden";
      sessionStorage.setItem('basis3_visibility', 'hidden');
      editableElements.forEach(function(element) {
         if (element) {
            element.setAttribute("contenteditable", false);
         }
      });
      document.querySelector('#mainTitle').setAttribute('contenteditable', 'false');
      sideFloatClass.forEach(function(element) {
         element.style.visibility = "hidden";
      });
      for (let i = 0; i < editId.length; i++) { 
         editMode = -1;
         if (document.getElementById(editId[i])) {
            document.getElementById(editId[i]).classList.remove('active');
         }
      }
      document.getElementById('bcbody').style.top = '0px';
      document.querySelectorAll('.bfloat').forEach(e=>e.style.fontSize='')
   } else {
      basis3.style.visibility = "visible";
      sessionStorage.setItem('basis3_visibility', 'visible');
      editableElements.forEach(function(element) {
         if (element) {
            element.setAttribute("contenteditable", true);
         }
      });
      document.querySelector('#mainTitle').setAttribute('contenteditable', 'true');
      basis3.style.left = '10px';
      basis3.style.top = '20%';
      basis3.style.transform = 'translate(0%, -20%)';
      document.getElementById('bcbody').style.top = '30px';
      document.querySelectorAll('.bfloat').forEach(e=>e.style.fontSize='1em')
      
   }
}
window.basisVis = basisVis;

/** @brief Сбор всех редактируемых элементов */
function editableElementsFun() {
   let content = document.getElementById('content');
   editableElements = document.querySelectorAll('.pluginEditable');
   editableElements = Array.from(editableElements);
   editableElements.push(content);

   editableElements.forEach(function(element) {
      if (!element) {
         console.log("Element " + element + " not found.");
         return;
      }
   });
}


addEventListener("LoadeditorJs", function()
{

let te=document.getElementById("tex");              // Ссылка на текстовое поле
let tex=document.getElementById("tex");       // Ссылка на стили текстового поля

if (document.getElementById("content") == "") {
te.value=document.getElementById("content").innerHTML;                              // Передача данных из области контента в текстовое поле
}

// Символы клавиш со знаками препинания или перевода строки
let symb = ["Enter", "!", "?", ";", ":", ",", ".", " ", "-", "'", "\"", "(", ")", "{", "}", "[", "]", "_", "&", "/", "\\", "*"];

// Запись в память введенного текста при нажатии клавиши со знаком препинания или перевода строки
if (document.getElementById("content")) {
   document.getElementById("content").addEventListener("keyup", function(ev)           
      {
      for(let i=0; i<symb.length; i++)
         {
         if(symb[i]==ev.key)
            inter();
         }
      });
}

let sel = document.getSelection();
function selInContenteditable(insertType) {
   if (!sel.rangeCount) {
      messageFunction("{{cursor_not_in_editable_field}}");
      return 0;
   }
   function isInContenteditable(node) {
      while (node) {
         if (node.nodeType === Node.ELEMENT_NODE && node.getAttribute('contenteditable') === 'true') {
            return true;
         }
         node = node.parentNode;
      }
      return false;
   }
   let range = sel.getRangeAt(0);
   if (!isInContenteditable(range.startContainer) || !isInContenteditable(range.endContainer)) {
      messageFunction("{{cursor_or_selection_not_in_editable_field}}");
      return 0;
   }
   if (insertType == "element") {
      range.deleteContents();
   } else if (insertType == "editText") {
      if (sel.isCollapsed) {
         messageFunction("{{no_text_selected}}");
         return 0;
      }
   }
}

// Функция открытия окон среднего редактирования
let s=document.querySelectorAll(".swit");
for(let i=0; i<s.length; i++)                       
   {
   let idc=s[i].id;
   let nid=idc+"_d";
   document.getElementById(idc).addEventListener("click", ins.bind(null, nid));
}

/* функция вставок элементов */
document.querySelectorAll('.align-dropdown-oneImg').forEach(dropdown => {
    const list = dropdown.querySelector('.align-list');
    dropdown.addEventListener('click', e => {
        if (e.target.closest('.align-list')) {
            const cmd = e.target.closest('li').dataset.cmd;
            handleImageAction(cmd);
            list.style.display = 'none';
            return;
        }
        list.style.display = list.style.display === 'block' ? 'none' : 'block';
    });
    document.addEventListener('click', e => {
        if (!dropdown.contains(e.target)) {
            list.style.display = 'none';
        }
    });
});

async function handleImageAction(id) {
    var sel = window.getSelection();
    if (sel.rangeCount) {
        var node = sel.anchorNode.nodeType === 1 ? sel.anchorNode : sel.anchorNode.parentElement;
        if (!node.closest('[contenteditable="true"]')) {
            return;
        }
    }
    switch (id) {
        case "imgLink":
            messageQueue.push("Enter image URL")
            ;(async () => {
                const url = await messageCreateInput()
                if (url) {
                    const img = document.createElement("img")
                    img.src = url
                    img.style.cssText = "float: left; margin: 10px; width: 250px; border: 0; overflow: hidden;"
                    insertNodeAtSelection(img)
                }
            })()
            break        
        case "imgPc":
            var input = document.createElement("input");
            input.type = "file";
            input.accept = "image/*";
            input.style.display = "none";
            document.body.appendChild(input);

            input.addEventListener("change", function() {
                if (input.files.length > 0) {
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        var base64Data = e.target.result.split(',')[1]; 
                        jsonrpcRequest('uploadImage', { userImgBase64: base64Data, userImgName: input.files[0].name })
                        .then(response => {
                            if (response) {
                                try {
                                    var img = document.createElement("img");
                                    img.src = response; 
                                    img.setAttribute("style", "float: left; margin: 10px; width: 250px; border: 0px solid rgb(0, 0, 0); overflow: hidden;");
                                    insertNodeAtSelection(img);
                                } catch (e) {
                                    messageFunction("{{img_upload_error}}");
                                }
                            } else {
                                messageFunction("{{img_upload_error}}");
                            }
                        })
                        .catch(() => messageFunction("{{img_upload_error}}"));
                    };
                    reader.readAsDataURL(input.files[0]);
                }
                document.body.removeChild(input);
            });
            input.click();
            break;
        case "imgManager":
            window.managerDataAction = "selectImgForm";
            let userName = getCookie('User');
            if (userName) {
        await includePlugin("manager");
                managerData("/img/users_img/" + userName);
                managerDiv.style.visibility = "visible";
                document.getElementById("settingsMain_d").style.visibility = "hidden";
            }
            break;
    }
}

function insertHR() {
    const hr = document.createElement("hr")
    hr.style.cssText = "height: 5px; width: 50%; background: rgb(0, 0, 0); border: 0;"
    insertNodeAtSelection(hr)
}
document.getElementById("hr").addEventListener("click", insertHR)

function insertTable() {
    const table = document.createElement("table")
    table.style.cssText = "width: 50%; margin: 1px; float: left; border: 1px solid rgb(0, 0, 0); background-color: rgb(255, 255, 255); border-collapse: collapse;"
    for (let i = 0; i < 4; i++) {
        const tr = document.createElement("tr")
        for (let j = 0; j < 4; j++) {
            const td = document.createElement("td")
            td.style.cssText = "padding: 1px; border: 1px solid rgb(0, 0, 0);"
            tr.appendChild(td)
        }
        table.appendChild(tr)
    }
    insertNodeAtSelection(table)
}
document.getElementById("tabl").addEventListener("click", insertTable)

function insertNodeAtSelection(node) {
    var sel = window.getSelection();
    if (!sel.rangeCount) return;
    var range = sel.getRangeAt(0);
    range.deleteContents();
    range.insertNode(node);
}

/*let t=document.querySelectorAll(".cldiv");
for(let i=0; i<t.length; i++)                       // Регистрация обработчиков для закрытия вкладок с настройками сложного редактирования
   {

   let idc=t[i].id;
   let nid=idc.replace("_i", "_d");
   document.getElementById(idc).addEventListener("click", clo.bind(null, nid));
   }*/

let q=document.querySelectorAll(".sym");
for(let i=0; i<q.length; i++)                       // Регистрация обработчиков для вставки символов в текст
   {
   let idc=q[i].id;
   let smb=q[i].value;
   document.getElementById(idc).addEventListener("click", sign.bind(null, smb));
   }

function sign(s)                                    // Функция вставки символов в текст
   {
   if (selInContenteditable("element") == 0) {
      return;
   }
   let rng=sel.getRangeAt(0);
   let elm=document.createTextNode(s);
   rng.insertNode(elm);

   clo("copyr_d");
   inter();
   }

// Изменение пространственной ориентации у редактора
let coup = false;
let basis3 = document.getElementById("basis3");
let editi = Array.from(document.getElementsByClassName("editi"));
let edits = Array.from(document.getElementsByClassName("edits"));
let editb = editi.concat(edits);
let indentb = Array.from(document.getElementsByClassName("indent"));
let custb = Array.from(document.getElementsByClassName("cust"));
/* document.getElementById("coup").addEventListener("click", function() {
   if (coup === false) {
      coup = true;
      let basis3Top = parseInt(basis3.style.top, 10);
      basis3.style.top = (basis3Top - 1055) + 'px';
      let basis3Left = parseInt(basis3.style.left, 10);
      basis3.style.left = (basis3Left + 1176) + 'px';

      editb.forEach(function(element) {
         element.style.display = 'block';
         element.style.position = 'relative';
         element.style.marginBottom = '4px';
         element.style.right = '0px';
      });
      indentb.forEach(function(element) {
         element.style.width = '0px';
         element.style.height = '8px';
      });
      document.getElementById("equaj").style.marginBottom = '';
      document.getElementById("ff").style.width = '28px';
      document.getElementById("fs").style.width = '28px';
      document.getElementById("list").style.width = '28px';
      document.getElementById("coup").style.backgroundPosition = '-397px 1663px';

      document.getElementById("tex").style.left = '45px';
      custb.forEach(function(element) {
         element.style.left = '45px';
         element.style.top = '0px';
         element.style.width = '764px';
      });

   } else {
      coup = false;
      let basis3Top = parseInt(basis3.style.top, 10);
      basis3.style.top = (basis3Top + 1055) + 'px';
      let basis3Left = parseInt(basis3.style.left, 10);
      basis3.style.left = (basis3Left - 1176) + 'px';

      editb.forEach(function(element) {
         element.style.display = 'inline-block';
         element.style.position = '';
         element.style.marginBottom = '';
      });
      indentb.forEach(function(element) {
         element.style.width = '5px';
         element.style.height = '0px';
      });
      document.getElementById("ff").style.width = '136px';
      document.getElementById("fs").style.width = '38px';
      document.getElementById("list").style.width = '62px';
      document.getElementById("coup").style.backgroundPosition = '-357px 1662px';

      document.getElementById("tex").style.left = '0px';
      custb.forEach(function(element) {
         element.style.left = '';
         element.style.top = '45px';
         element.style.width = '1189px';
      });
   }
}); */

let sbe=document.getElementsByClassName("sb");
for(let i=0; i<sbe.length; i++) {
   sbe[i].style.visibility="hidden";
}
function ins(k)                                     // Функция открытия вкладок с настройками для сложного редактирования текста 
   {
   let sbe=document.getElementsByClassName("sb");
   for(let i=0; i<sbe.length; i++) {
      if (sbe[i] != document.getElementById(k))
      sbe[i].style.visibility="hidden";
   }
   if (document.getElementById(k).style.visibility=="hidden") {
      document.getElementById(k).style.visibility="visible";
   } else {
      document.getElementById(k).style.visibility="hidden";
   }
   }

function clo(c)                                     // Функция закрытия вкладок с настройками для сложного редактирования текста 
   {
   document.getElementById(c).style.visibility="hidden";
   }

// действия блока плагинов
let pluginDropdownContentId = document.getElementById("pluginDropdownContent");
pluginDropdownContentId.addEventListener('click', function () {
   let targetElement = document.getElementById(this.value);
   if (targetElement) {
      targetElement.click();
   } else {
      console.log("{{action_not_defined}}");
   }
   let activeOption = pluginDropdownContentId.querySelector('option.active');   
   let options = pluginDropdownContentId.querySelectorAll('option');
   options.forEach(option => {
      option.style.backgroundColor = '#efefef';
   });
   if (activeOption) {
      pluginDropdownContentId.style.backgroundColor = '#d8d8d8';
   } else {
      pluginDropdownContentId.style.backgroundColor = '';
   }   
   if (editMode == -1) {
    pluginDropdownContentId.style.backgroundColor = '';
   } 
});

// действия блока элементов
/* let elementDropdownContentId = document.getElementById("elementDropdownContent");
elementDropdownContentId.addEventListener('click', function () {
   let targetElement = document.getElementById(this.value);
   if (targetElement) {
      targetElement.click();
   } else {
      console.log("{{action_not_defined}}2");
   }
}); */

// действия блока главных действий
/* let mainActionsId = document.getElementById("mainActions");
mainActionsId.addEventListener('click', function () {
   switch (this.value) {
      case "save":
         saveChanges();
         break;
      case "saveHow":
         saveChangesHow();
         break;
      case "htm":
         showHtmlCode();
         break;
      default:
         console.log("{{action_not_defined}}");
   }
}); */

document.getElementById("save").addEventListener("click", saveChanges);

// Загрузка изменений как
document.getElementById("saveHow").addEventListener("click", saveChangesHow);
async function saveChangesHow() {
    await includePlugin("manager");
    window.managerDataAction = "saveHow";
    managerData("/content");
    managerDiv.style.visibility = "visible";
    document.getElementById("settingsMain_d").style.visibility = "hidden";
}

// Открытие страницы
document.getElementById("getPage").addEventListener("click", openPageFun);
async function openPageFun() {
   await includePlugin("manager");
   window.managerDataAction = "getPage";
   managerData("/content");
   managerDiv.style.visibility = "visible";
   document.getElementById("settingsMain_d").style.visibility="hidden";
}

// Создание новой страницы
document.getElementById("newPage").addEventListener("click", newPageFun);
function newPageFun() {
   document.getElementById("right-float").innerHTML = "";
   document.getElementById("left-float").innerHTML = "";
   document.getElementById("content").innerHTML = "";
   document.getElementById("mainTitle").innerHTML = "<i>{{new_file}}!</i>";
   window.newPageFunValue = "newPage";
   document.getElementById("settingsMain_d").style.visibility="hidden";
}

// Сохранение выделение

document.addEventListener('selectionchange', () => {
    const content = document.getElementById('content');
    const sel = window.getSelection();
    if (!sel.rangeCount) return;
    const range = sel.getRangeAt(0);
    const startNode = range.startContainer;
    if (content.contains(startNode)) {
        saveSelection();
    }
});

let savedSel = null;

function saveSelection() {
    const content = document.getElementById('content');
    const sel = window.getSelection();
    if (!sel.rangeCount) return;
    const range = sel.getRangeAt(0);
    if (!content.contains(range.commonAncestorContainer)) return;
    const pre = range.cloneRange();
    pre.selectNodeContents(content);
    pre.setEnd(range.startContainer, range.startOffset);
    const start = pre.toString().length;
    const end = start + range.toString().length;
    savedSel = { start, end };
}

function restoreSelection() {
    if (!savedSel) return;
    const content = document.getElementById('content');
    const { start, end } = savedSel;
    let charIndex = 0;
    const range = document.createRange();
    range.setStart(content, 0);
    range.collapse(true);
    try {
        (function traverse(node) {
            if (node.nodeType === Node.TEXT_NODE) {
                const next = charIndex + node.length;
                if (charIndex <= start && next >= start) {
                    range.setStart(node, start - charIndex);
                }
                if (charIndex <= end && next >= end) {
                    range.setEnd(node, end - charIndex);
                    throw 'done';
                }
                charIndex = next;
            } else {
                node.childNodes.forEach(traverse);
            }
        })(content);
    } catch (e) {}
    const sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
}

// Взаимодействие с плагинами
/* document.getElementById('pluginCreateLeft').onclick = function() { pluginFun('create', 'left'); };
document.getElementById('pluginCreateRight').onclick = function() { pluginFun('create', 'right'); }; */
document.getElementById('pluginAddLeft').onclick = function() { pluginFun('add', 'left'); };
document.getElementById('pluginAddRight').onclick = function() { pluginFun('add', 'right'); };


/* document.getElementById('pluginRulesButton1').onclick = function() { pluginRulesFun('pluginRulesBlock1'); };
document.getElementById('pluginRulesButton2').onclick = function() { pluginRulesFun('pluginRulesBlock2'); }; */

function pluginRulesFun(id) {
	let element = document.getElementById(id);
	if (element.classList.contains('show')) {
		element.classList.remove('show');
	} else {
		element.classList.add('show');
/* 		jsonrpcRequest('funcEditor', { action: 'add', side: '', pluginName: '' }).then(pluginsText => {
			let plugins = pluginsText.trim().split("\n");
			element.innerHTML = `<div>{{plugin_name_guidelines}}</div><hr><div>{{used_plugin_names}}</div>`;
			plugins.forEach(plugin => {
				let div = document.createElement('div');
				div.innerHTML = plugin;
				element.appendChild(div);
			});
		}); */
	}
}

document.getElementById('pluginCreateLeftFun_d').onclick = function() { pluginFun_d('pluginCreateLeftName', 'left-float', 'pluginCreateLeftTitle', ' {{plugin_created_left_suffix}}', 'create', 'pluginCreateLeft_d'); };
document.getElementById('pluginAddLeftFun_d').onclick = function() { pluginFun_d('pluginAddLeftName', 'left-float', 'pluginAddLeftTitle', ' {{plugin_added_left_suffix}}', 'add', 'pluginAddLeft_d'); };
document.getElementById('pluginCreateRightFun_d').onclick = function() { pluginFun_d('pluginCreateRightName', 'right-float', 'pluginCreateRightTitle', ' {{plugin_created_right_suffix}}', 'create', 'pluginCreateRight_d'); };
document.getElementById('pluginAddRightFun_d').onclick = function() { pluginFun_d('pluginAddRightName', 'right-float', 'pluginAddRightTitle', ' {{plugin_added_right_suffix}}', 'add', 'pluginAddRight_d'); };

function pluginFun_d(inputIdName, side_float, inputIdTitle, pluginText, action, pluginAddSide_d) {
	let pluginName = document.getElementById(inputIdName).value.trim();
	let pluginTitle = document.getElementById(inputIdTitle).value.trim();

	if (pluginName === "") {
		messageFunction(action === 'create' ? "{{plugin_name_empty_error}}" : "{{plugin_not_selected_error}}")
		return;
	}

	let allowedCharacters = /^[a-zA-Z0-9 _]*$/;
	if (!allowedCharacters.test(pluginName)) {
		messageFunction("{{plugin_name_guidelines}}")
		return;
	}

	if (action === 'create') {
        jsonrpcRequest('checkFile', { path: 'plugin', nameFile: pluginName })
        .then(response => {
            if (response.trim() === "true") {
                messageFunction(pluginName + "{{plugin_name_exists_suffix}}");
            } else {
                sendRequest('create', side_float, pluginName, pluginTitle, pluginText);
            }
        });    
	} else {
		pluginHtml('add', pluginName, side_float, pluginTitle);
		inter();
	}
	document.getElementById(pluginAddSide_d).style.visibility = "hidden";
}
/*   if (pluginTitle === "") {
      messageFunction("{{plugin_title_empty_error}}");
      return;
   } */

function sendRequest(action, side_float, pluginName, pluginTitle, pluginText) {
    jsonrpcRequest('createPlugin', { pluginName, side: side_float, pluginTitle, pluginText }).then(response => {
        if (response.trim() === "Plugin created: " + pluginName) {
            pluginHtml('create', pluginName, side_float, pluginTitle);
            inter();
        }
    });    
}
function pluginHtml(action, pluginName, side_float, pluginTitle) {
   let sideFloat = document.getElementById(side_float);
   let sideFloatElement = sideFloat;

   let pluginUrl = document.createElement("div");
   pluginUrl.classList.add('plugin-url');
   pluginUrl.pluginUrl = '/plugin/' + pluginName + '/';

   let br = document.createElement("br");
   let tclass = null;
   if (pluginTitle != "") {
    tclass = document.createElement("div");
    tclass.setAttribute("tclass", 'tclass');
    tclass.setAttribute("plugin-title", 'pluginTitle');
    tclass.className = 'btitle';
    tclass.textContent = pluginTitle;
   }

   let bclass = document.createElement("div");
   bclass.setAttribute("bclass", 'bclass');
   bclass.className = 'bfloat';

   let bcont = document.createElement("div");
   bcont.className = 'bcont';

   sideFloatElement.appendChild(pluginUrl);
   if (tclass) {
        pluginUrl.appendChild(tclass);
   }
   pluginUrl.appendChild(bclass);
   pluginUrl.appendChild(br);
   bclass.appendChild(bcont);

   if (action === 'add') {
    jsonrpcRequest('getPlugin', { pluginName2: pluginName }).then(pluginContent => {
        bcont.innerHTML = pluginContent;
    });
   } else {
      let pluginEditable = document.createElement("div");
      pluginEditable.className = 'pluginEditable';
      pluginEditable.contentEditable = 'true';
      bcont.appendChild(pluginEditable);
   }
}
   
for (let i = 0; i < editId.length; i++) { 
    if (document.getElementById(editId[i])) {
        document.getElementById(editId[i]).onclick = function() { editFun(editId[i]); };
    }
}

function editFun(whichEditId) {
   for (let i = 0; i < editId.length; i++) { 
      if (whichEditId === editId[i]) {
         if (editMode != i) {
            editFun1_1(i); 
         } else {
            editFun1_2(i); 
         }

      } else {
         editFun3(i); 
      }
      
      if (i == 3 && editMode != 3) {
         editFun4(i); 
      } 
      if (editMode != 0 && editMode != 2 && editMode != 3) {
         editFun5(i); 
      } 
   }
}

function editFun1_1(i) {
   editMode = i;
   document.getElementById(editId[i]).classList.add('active');
}
function editFun1_2(i) {
   editMode = -1;
   document.getElementById(editId[i]).classList.remove('active');
}
/* function editFun2_1(i) {
   let pluginElements = document.querySelectorAll('[plugin-url]');
   for (let i = 0; i < pluginElements.length; i++) {
      let pluginTitleElement = pluginElements[i].querySelector('[plugin-title]');
      if (pluginTitleElement) {
         let pluginUrl = pluginElements[i].getAttribute('plugin-url');
         let newDiv = document.createElement('div');
         newDiv.className = 'pluginTitleUrl';
         newDiv.textContent = pluginUrl;
         pluginTitleElement.insertAdjacentElement('afterbegin', newDiv);
      }
   }
} */
function editFun3(i) {
   /* document.getElementById(editId[i]).classList.remove('active'); */
}
function editFun4(i) {
}
function editFun5(i) {
   pluginDropdownContentId.style.backgroundColor = '';
}

let pluginTakeCheck = 0;
let targetElement;
document.onclick = function(event) {
if (editMode === 0) {
    yourFunction(event);
}

async function yourFunction(event) {
    let target = event.target;
    let pluginElement = target.closest('.plugin-url');
    if (pluginElement) {
        messageQueue.push("{{delete_plugin_confirm}}");
        if (await messageCreateQuestion()) {
            pluginElement.remove();

            /* let floatElements = [document.querySelector('.right-float'), document.querySelector('.left-float')];
            floatElements.forEach(element => {
                if (element && element.children.length === 0 && element.textContent.trim() === "") {
                    element.remove();
                }
            }); */

            inter();
        }
    }
}

   
   if (editMode === 1) {
/*       let target = event.target;
      let pluginTitle = target.closest('[plugin-title]');
      let mainTitle = target.closest('#mainTitle');

      let secondDiv = pluginTitle ? pluginTitle.closest('div').parentElement.closest('div') : null;
      let thirdDiv = secondDiv ? secondDiv.parentElement.closest('div') : null;
      let allDivsInParent = secondDiv ? Array.from(secondDiv.parentElement.children).filter(child => child.tagName === 'DIV') : [];
      let indexOfSecondDiv = secondDiv ? allDivsInParent.indexOf(secondDiv) : null;
      let classOfThirdDiv = thirdDiv ? thirdDiv.className.replace(/-float/g, '') : null;
   
      if (pluginTitle || mainTitle) {
         let editTitle = mainTitle ? mainTitle : pluginTitle;
         let whichTitle = mainTitle ? "mainTitle" : "pluginTitle";
         console.log(whichTitle+" "+functionOpenPage);

         if (whichTitle === "mainTitle" && functionOpenPage === true) {
            messageFunction("{{open_page}}");
         } else {
            let title = prompt("{{enter_new_title}}", editTitle.textContent.trim());
            if (title !== null) {
               let newTitle = title.trim();
               
               if (newTitle !== "") {
                jsonrpcRequest('newTitle', { newTitle, whichTitle, side: classOfThirdDiv, pluginNumber: indexOfSecondDiv }).then(response => {
                    console.log(response);
                    editTitle.innerHTML = newTitle;
                    messageFunction("{{title_saved}}")
                    inter();
                });
               } else {
                  messageFunction("{{plugin_title_empty_error}}");
               }
               
            }
         }
         
      } */
   }

   if (editMode === 2 && pluginTakeCheck == 0) {
      let pluginElement = event.target.closest('.plugin-url');
   
      if (pluginElement) {
         pluginElement.style.border = '3px dashed #000000';
         pluginElement.classList.add('pluginElementl');
   
         let indicator = document.createElement("div");
         indicator.style.width = '20px';
         indicator.style.height = '20px';
         indicator.style.position = 'absolute';
         indicator.style.left = (event.clientX - 10) + 'px';
         indicator.style.top = (event.clientY - 10) + 'px';
         indicator.style.backgroundImage = "url(../../img/pict/b_iconslyb.svg)";
         indicator.style.backgroundPosition = "0px -80px";
         indicator.style.pointerEvents = "none";
         document.body.appendChild(indicator);
   
         function pointerMove(event) {
            indicator.style.left = (event.clientX - 10) + 'px';
            indicator.style.top = (event.clientY - 10) + 'px';
   
            let dropTarget = document.elementFromPoint(event.clientX, event.clientY);
            let leftFloatElement = document.getElementById('left-float');
            let rightFloatElement = document.getElementById('right-float');
            let isLeftFloat = leftFloatElement ? leftFloatElement.contains(dropTarget) : false;
            let isRightFloat = rightFloatElement ? rightFloatElement.contains(dropTarget) : false;
   
            if (isLeftFloat || isRightFloat) {
               let targetCheck = document.elementFromPoint(event.clientX, event.clientY).closest('.plugin-url');
               let floatElement = isLeftFloat ? leftFloatElement : rightFloatElement;
   
               if (pluginElement !== targetCheck) {
                  pluginTakeCheck = 1;
               }
   
                pluginElement.classList.remove('pluginElementl');
   
               if (targetCheck) {
                  let side = getTargetSide(targetCheck, event.clientY);
   
                  if (side === 0) {
                     if (targetCheck.parentNode === floatElement) {
                        floatElement.insertBefore(pluginElement, targetCheck.nextSibling);
                     } else {
                        floatElement.appendChild(pluginElement);
                     }
                     indicator.style.backgroundPosition = "-40px -80px";
                  } else if (side === 1) {
                     if (targetCheck.parentNode === floatElement) {
                        floatElement.insertBefore(pluginElement, targetCheck);
                     } else {
                        floatElement.appendChild(pluginElement);
                     }
                     indicator.style.backgroundPosition = "0px -80px";
                  }
               } else {
                  floatElement.appendChild(pluginElement);
               }
   
/*               let floatElements = [document.querySelector('.right-float'), document.querySelector('.left-float')];
               floatElements.forEach(element => {
                  if (element && element.children.length === 0 && element.textContent.trim() === "") {
                     element.remove();
                  }
               }); */
            }
         }
   
         document.addEventListener('pointermove', pointerMove);
         document.addEventListener('pointerup', function pointerup() {
            document.removeEventListener('pointermove', pointerMove);
            document.removeEventListener('pointerup', pointerup);
   
            pluginElement.style.border = '';
            pluginElement.style.padding = '';
            indicator.remove();
            inter();
         });
      }
   }
   pluginTakeCheck = 0;   

   if (editMode === 3) {
   }

   let table = event.target.closest('table');
   if (table) {
      let rowIndex, cellIndex;
      let targetRow = event.target.closest('tr');
      let targetCell = event.target.closest('td');
   
      if (targetRow) {
         rowIndex = Array.from(targetRow.parentNode.children).indexOf(targetRow);
      }
   
      if (targetCell) {
         cellIndex = Array.from(targetCell.parentNode.children).indexOf(targetCell);
      }
   
      if (editMode === 4 && targetRow) {
         let row = table.insertRow(rowIndex + 1);
         let cellCount = targetRow.cells.length;
         for (let i = 0; i < cellCount; i++) {
            let newCell = row.insertCell(i);
            if (targetRow.cells.length > 0) {
               let referenceCell = targetRow.cells[i];
               newCell.style.cssText = referenceCell.style.cssText;
            }
         }
      }
   
      if (editMode === 5 && targetRow) {
         if (table.rows.length > 1) {
            table.deleteRow(rowIndex);
         }
      }
   
      if (editMode === 6 && targetCell) {
         for (let i = 0; i < table.rows.length; i++) {
            let row = table.rows[i];
            let newCell = row.insertCell(cellIndex + 1);
            if (row.cells.length > cellIndex) {
               let referenceCell = row.cells[cellIndex];
               newCell.style.cssText = referenceCell.style.cssText;
            }
         }
      }
   
      if (editMode === 7 && targetCell) {
         if (targetCell.parentNode.cells.length > 1) {
            for (let i = 0; i < table.rows.length; i++) {
               let row = table.rows[i];
               if (row.cells.length > cellIndex) {
                  row.deleteCell(cellIndex);
               }
            }
         }
      }
   
      inter();
   }   
   
};

function getTargetSide(targetCheck, mouseY) {
   if (targetCheck) {
      let targetRect = targetCheck.getBoundingClientRect();
      let targetY = targetRect.top + targetRect.height / 2;
      return mouseY < targetY ? 1 : 0;
   } else {
      return -1;
   }
}

/* выделение элементов */
let clipboard = ['', '']
let selectedElement = null
let selectedElementOriginalOutline = ''
let selectedElementCut = ''

document.addEventListener('contextmenu',editingElements)
function editingElements(event) {
    var editable = event.target.closest('[contenteditable="true"]')
    if (!editable) return
    event.preventDefault()
    var menu = document.getElementById('editingMenuItems')
    var copy = document.getElementById('editingMenuItemsCopy')
    var cut = document.getElementById('editingMenuItemsCut')
    var paste = document.getElementById('editingMenuItemsPaste')
    copy.style.display = 'none'
    cut.style.display = 'none'
    paste.style.display = 'none'
    var element = event.target.closest('hr, img, table')

    if (editable && element) {
        if (selectedElement && selectedElement !== element) {
            selectedElement.style.outline = selectedElementOriginalOutline
        }
        selectedElementOriginalOutline = element.style.outline || ''
        element.style.outline = '1px dashed black'
        selectedElement = element
        menu.style.visibility = 'visible'
        copy.style.display = ''
        cut.style.display = ''
        if (clipboard[0]) paste.style.display = ''
    } else if (editable && clipboard[0]) {
        if (selectedElement) {
            selectedElement.style.outline = selectedElementOriginalOutline
            selectedElement = null
        }
        menu.style.visibility = 'visible'
        paste.style.display = ''
    } else {
        if (selectedElement) {
            selectedElement.style.outline = selectedElementOriginalOutline
            selectedElement = null
        }
        menu.style.visibility = 'hidden'
    }

    targetElement = null
    if (element) {
        targetElement = element
        var sel = window.getSelection()
        var range = document.createRange()
        range.selectNode(targetElement)
        sel.removeAllRanges()
        sel.addRange(range)
    }
    document.querySelectorAll('.elementEditPanelElement').forEach(function(panel) {
        panel.style.display = 'none'
        document.getElementById('editingMenuItemsHr').style.display = 'none'
    })
    if (targetElement !== null && event.target.closest('[contenteditable="true"]')) {
        editElement()
    }

    const pad=10
    const menuRect=menu.getBoundingClientRect()
    let x=(event.clientX!==undefined?event.clientX:touchX)
    let y=(event.clientY!==undefined?event.clientY:touchY)
    let left=Math.min(x,window.innerWidth-menuRect.width-pad)
    let top=Math.min(y,window.innerHeight-menuRect.height-pad)
    if (!isPhone) {
        menu.style.left = `${Math.max(pad, left)}px`
        menu.style.top = `${Math.max(pad, top)}px`
    } else {
        menu.style.top = '30%'
        menu.style.left = '0'
        menu.style.right = '0'
        menu.style.marginLeft = 'auto'
        menu.style.marginRight = 'auto'
        menu.style.width = 'calc(100% - 20px)'
        menu.style.maxWidth = 'max-content'
    }    
}

function editElement() {
    var panelMap = {
        'HR': 'elementEditPanelHr',
        'IMG': 'elementEditPanelImg',
        'TABLE': 'elementEditPanelTable'
    }
    var panelId = panelMap[targetElement.tagName]
    if (panelId) {
        var panel = document.getElementById(panelId)
        if (panel) {
            panel.style.display = ''
            document.getElementById('editingMenuItemsHr').style.display = ''
        }
    }
    if (panelId === 'elementEditPanelHr') {
        document.getElementById('hr1Edit').value = parseInt(targetElement.style.height, 10) || 1
        document.getElementById('hr2Edit').value = targetElement.style.width || '95%'
        document.getElementById('hr3cEdit').value = targetElement.style.backgroundColor
            ? rgbToHex(targetElement.style.backgroundColor)
            : '#000000'
        document.getElementById('hrMarginTopEdit').value = parseInt(targetElement.style.marginTop, 10) || 0
        document.getElementById('hrMarginRightEdit').value = parseInt(targetElement.style.marginRight, 10) || 0
        document.getElementById('hrMarginBottomEdit').value = parseInt(targetElement.style.marginBottom, 10) || 0
        document.getElementById('hrMarginLeftEdit').value = parseInt(targetElement.style.marginLeft, 10) || 0
        var m = targetElement.style.margin
        if (m === '0.5em auto 0.5em 0px') {
            document.getElementById('hr4Edit').value = 'left_clear'
        } else if (m === '0.5em 0px 0.5em auto') {
            document.getElementById('hr4Edit').value = 'right_clear'
        } else if (targetElement.style.display === 'inline-block'
                && targetElement.style.verticalAlign === 'middle') {
            document.getElementById('hr4Edit').value = 'left_text'
        } else {
            document.getElementById('hr4Edit').value = 'center_clear'
        }
    }
    if (panelId === 'elementEditPanelImg') {
        document.getElementById('ima1Edit').value = targetElement.src || ''
        document.getElementById('ima6Edit').value = parseInt(targetElement.style.width, 10) || 250
        document.getElementById('ima6aEdit').value = parseInt(targetElement.style.height, 10) || ''
        document.getElementById('ima7Edit').value = parseInt(targetElement.style.borderWidth, 10) || 0
        document.getElementById('ima8cEdit').value = targetElement.style.borderColor
            ? rgbToHex(targetElement.style.borderColor)
            : '#000000'
        document.getElementById('imaMarginTopEdit').value = parseInt(targetElement.style.marginTop, 10) || 0
        document.getElementById('imaMarginRightEdit').value = parseInt(targetElement.style.marginRight, 10) || 0
        document.getElementById('imaMarginBottomEdit').value = parseInt(targetElement.style.marginBottom, 10) || 0
        document.getElementById('imaMarginLeftEdit').value = parseInt(targetElement.style.marginLeft, 10) || 0
        document.getElementById('ima4Edit').value = targetElement.style.float
            ? (targetElement.style.float === 'left' ? 'left_clear'
                : 'right_clear')
            : 'center_clear'
        var link = targetElement.closest('a')
        document.getElementById('imaLinkEdit').value = link ? link.href : ''
        var captionEl = targetElement.nextElementSibling
    }
    if (panelId === 'elementEditPanelTable') {
        document.getElementById('tab1Edit').value = targetElement.style.width || '50%'
        document.getElementById('tabMarginTopEdit').value = parseInt(targetElement.style.marginTop, 10) || 0
        document.getElementById('tabMarginRightEdit').value = parseInt(targetElement.style.marginRight, 10) || 0
        document.getElementById('tabMarginBottomEdit').value = parseInt(targetElement.style.marginBottom, 10) || 0
        document.getElementById('tabMarginLeftEdit').value = parseInt(targetElement.style.marginLeft, 10) || 0
        document.getElementById('tab9Edit').value = parseInt(targetElement.style.borderWidth, 10) || 1
        document.getElementById('tab11cEdit').value = targetElement.style.backgroundColor
            ? rgbToHex(targetElement.style.backgroundColor)
            : '#000000'
        var firstCell = targetElement.querySelector('td')
        document.getElementById('tab4Edit').value = firstCell
            ? parseInt(firstCell.style.padding, 10) || 1
            : 1
        document.getElementById('tab10cEdit').value = firstCell
            ? rgbToHex(firstCell.style.borderColor)
            : '#000000'
        document.getElementById('tab6Edit').value = targetElement.style.float
            ? (targetElement.style.float === 'left' ? 'left_clear'
                : 'right_clear')
            : 'center_clear'
    }
}

/* меню изменение элемнтов */
document.addEventListener('pointerdown', clearMenu)
document.addEventListener('keydown', clearMenu)
function clearMenu(event) {
    if (event.type === 'pointerdown' && event.button !== 0) {
        return;
    }
    if (event.target.closest('#editingMenuItems')) {
        return;
    }
    var menu = document.getElementById("editingMenuItems");
    if (selectedElement) {
        selectedElement.style.outline = selectedElementOriginalOutline;
        selectedElement = null;
    }
    if (menu) menu.style.visibility = "hidden";
}

document.getElementById("editingMenuItemsCopy").addEventListener('click', function() {
    if (selectedElement) {
        clipboard = [selectedElement.cloneNode(true), 'copy'];
    }
});

document.getElementById("editingMenuItemsCut").addEventListener('click', function() {
    if (selectedElement) {
        clipboard = [selectedElement.cloneNode(true), 'cut'];
        selectedElementCut = selectedElement;
    }
});

document.getElementById("editingMenuItemsPaste").addEventListener('click', function() {
    if (clipboard && clipboard[0]) {
        var sel = window.getSelection();
        if (!sel.rangeCount) return;
        var range = sel.getRangeAt(0);
        range.collapse(false);
        range.insertNode(clipboard[0]);
        if (clipboard[1] == 'cut' && selectedElementCut) {
            selectedElementCut.remove();
            selectedElementCut = null;
        }
        clipboard[0] = clipboard[0].cloneNode(true);
        document.getElementById("editingMenuItems").style.visibility = "hidden";
    }    
});

//редактирования меню страниц
/* document.getElementById("contentPageCreateFun_d").addEventListener("click", function() {
   inter();
});
document.getElementById("contentPageMove").addEventListener("click", function() {
   inter();
});
document.getElementById("contentPageSettingsFun_d").addEventListener("click", function() {
   inter();
}); */

// панель редактирования для элементов
document.getElementById("buthrEdit").addEventListener("click", function() {
    let hr1_v = document.getElementById("hr1Edit").value
    let hr2_v = document.getElementById("hr2Edit").value
    let hr3_v = document.getElementById("hr3cEdit").value
    let hr4_v = document.getElementById("hr4Edit").value
    let mt = document.getElementById("hrMarginTopEdit").value
    let mr = document.getElementById("hrMarginRightEdit").value
    let mb = document.getElementById("hrMarginBottomEdit").value
    let ml = document.getElementById("hrMarginLeftEdit").value

    let style = ""
    style += "height: " + (hr1_v || 1) + "px; "
    if (hr2_v) style += "width: " + hr2_v + "; "
    style += "background: " + hr3_v + "; "
    style += "margin: " + (mt||0) + "px " + (mr||0) + "px " + (mb||0) + "px " + (ml||0) + "px; "

    switch (hr4_v) {
        case "left_clear": style += "margin-left: 0; "; break
        case "right_clear": style += "margin-right: 0; "; break
        case "center_clear": style += "position: relative; left: 50%; transform: translateX(-50%); "; break
        case "left_text": style += "display: inline-block; vertical-align: middle; float: left; "; break
        case "right_text": style += "display: inline-block; vertical-align: middle; float: right; "; break
        case "text": style += "display: inline-block; vertical-align: middle; "; break
    }

    style += "border: 0;"
    change(targetElement, style, "")
    inter()
})

document.getElementById("butimaEdit").addEventListener("click", function() {
    let url     = document.getElementById("ima1Edit").value
    let pos     = document.getElementById("ima4Edit").value
    let mt      = document.getElementById("imaMarginTopEdit").value
    let mr      = document.getElementById("imaMarginRightEdit").value
    let mb      = document.getElementById("imaMarginBottomEdit").value
    let ml      = document.getElementById("imaMarginLeftEdit").value
    let w       = document.getElementById("ima6Edit").value
    let h       = document.getElementById("ima6aEdit").value
    let bw      = document.getElementById("ima7Edit").value
    let bc      = document.getElementById("ima8cEdit").value
    let link    = document.getElementById("imaLinkEdit").value

    if (!url) {
        messageFunction("{{insert_url}}")
        return
    }

    let style = ""
    if (pos === "left_clear")   style += "float: left; "
    if (pos === "right_clear")  style += "float: right; "
    if (pos === "center_clear") style += "position: relative; left: 50%; transform: translateX(-50%); margin-top: " + (mt||0) + "px; display: block; "
    if (pos === "left_text")    style += "float: left; display: inline-block; vertical-align: middle; "
    if (pos === "right_text")   style += "float: right; display: inline-block; vertical-align: middle; "
    if (pos === "text")         style += "vertical-align: middle; display: inline-block; "
    if (pos !== "center_clear") style += "margin: " + (mt||0) + "px " + (mr||0) + "px " + (mb||0) + "px " + (ml||0) + "px; "

    if (w)  style += "width: " + w + "px; "
    if (h)  style += "height: " + h + "px; "
    if (bw) style += "border: " + bw + "px solid " + bc + "; "

    change(targetElement, style, url)

    if (link) {
        let a = document.createElement("a")
        a.href = link
        targetElement.parentNode.insertBefore(a, targetElement)
        a.appendChild(targetElement)
    }

    inter()
})


document.getElementById("butabEdit").addEventListener("click", function() {
    let width_v  = document.getElementById("tab1Edit").value
    let mt       = document.getElementById("tabMarginTopEdit").value
    let mr       = document.getElementById("tabMarginRightEdit").value
    let mb       = document.getElementById("tabMarginBottomEdit").value
    let ml       = document.getElementById("tabMarginLeftEdit").value
    let pad_i_v  = document.getElementById("tab4Edit").value
    let float_v  = document.getElementById("tab6Edit").value
    let border_v = document.getElementById("tab9Edit").value
    let bc_v     = document.getElementById("tab10cEdit").value
    let bg_v     = document.getElementById("tab11cEdit").value

    let style = ""
    if (width_v) style += "width: " + width_v + "; "
    if (float_v === "left_clear")   style += "float: left; "
    if (float_v === "right_clear")  style += "float: right; "
    if (float_v === "center_clear") style += "position: relative; left: 50%; transform: translateX(-50%); "
    if (float_v === "left_text")    style += "float: left; display: inline-table; vertical-align: middle; "
    if (float_v === "right_text")   style += "float: right; display: inline-table; vertical-align: middle; "
    if (float_v === "text")         style += "display: inline-table; vertical-align: middle; "
    if (float_v !== "center_clear") style += "margin: " + (mt||0) + "px " + (mr||0) + "px " + (mb||0) + "px " + (ml||0) + "px; "

    if (border_v) style += "border: " + border_v + "px solid " + bc_v + "; "
    if (bg_v)     style += "background-color: " + bg_v + "; "
    style += "border-collapse: collapse;"

    change(targetElement, style, "")

    let cells = targetElement.querySelectorAll("td")
    cells.forEach(function(cell) {
        let cellStyle = ""
        if (pad_i_v) cellStyle += "padding: " + pad_i_v + "px; "
        if (border_v) cellStyle += "border: " + border_v + "px solid " + bc_v + "; "
        cell.style.cssText = cellStyle
    })

    inter()
})

function change(element, style, src) {
    if (element) {
        if (style) element.style.cssText = style
        if (src)   element.src = src
    }
}

function rgbToHex(rgb) {
   let rgbArray = rgb.match(/\d+/g); 
   return "#" + rgbArray.map(x => {
       let hex = parseInt(x).toString(16);
       return hex.length === 1 ? "0" + hex : hex;
   }).join('');
}

/* const visibility = sessionStorage.getItem('basis3_visibility');
if (visibility === "visible" && document.getElementById("siteSettingsButton")) {
   basisVis();
} */
}, { once: true }); //addEventListener("LoadeditorJs", function()'

/** @brief Список редактируемых элементов */
let editableElduyjements;

addEventListener("LoadeditorJs", function()
{

document.querySelectorAll('.swit').forEach(btn => {
    btn.addEventListener('click', () => {
        const target = document.getElementById(btn.id + '_d');
        if (!target) return;       
        target.style.display = 
            (getComputedStyle(target).display === 'none') ? '' : 'none';
    });
});

const container = document.querySelector('.toolbar-container');
const panel = document.getElementById('panel');
const arrowLeft = document.getElementById('arrow-left');
const arrowRight = document.getElementById('arrow-right');
let interval;
let offset = 0;

function getBounds() {
    const containerWidth = container.scrollWidth;
    const panelWidth = panel.clientWidth;
    const arrowWidth = arrowLeft.clientWidth;
    const extra = arrowWidth;
    const maxOffset = 24;
    const minOffset = panelWidth - containerWidth - extra;
    return { containerWidth, panelWidth, maxOffset, minOffset };
}

function updateArrowsVisibility() {
    const { containerWidth, panelWidth, minOffset, maxOffset } = getBounds();

    if (containerWidth <= panelWidth) {
        arrowLeft.style.display = 'none';
        arrowRight.style.display = 'none';
        panel.style.overflowX = 'visible';
        offset = 0;
        container.style.transform = 'translateX(0px)';
    } else {
        arrowLeft.style.display = 'inline-flex';
        arrowRight.style.display = 'inline-flex';
        panel.style.overflowX = 'clip';
        if (offset > maxOffset) offset = maxOffset;
        if (offset < minOffset) offset = minOffset;
    }
}

const events = ['resize', 'scroll', 'pointerdown', 'pointerup', 'pointermove', 'keydown', 'touchstart'];
events.forEach(evt => {
    window.addEventListener(evt, updateArrowsVisibility, { passive: true });
    document.addEventListener(evt, updateArrowsVisibility, { passive: true });
});
if (window.visualViewport) {
    window.visualViewport.addEventListener('resize', updateArrowsVisibility);
}

updateArrowsVisibility();

function startScroll(direction) {
    const { maxOffset, minOffset } = getBounds();
    interval = setInterval(() => {
        if (direction === 'left') {
            offset += 10;
        } else {
            offset -= 10;
        }
        if (offset > maxOffset) offset = maxOffset;
        if (offset < minOffset) offset = minOffset;
        container.style.transform = `translateX(${offset}px)`;
    }, 16);
}

function stopScroll() {
    clearInterval(interval);
}

arrowLeft.addEventListener('pointerdown', e => {
    if (e.pointerType === 'touch') e.preventDefault();
    startScroll('left');
});
arrowLeft.addEventListener('pointerup', stopScroll);
arrowLeft.addEventListener('pointerleave', stopScroll);
arrowLeft.addEventListener('pointercancel', stopScroll);
arrowLeft.addEventListener('contextmenu', e => {
    if (e.pointerType === 'touch') e.preventDefault();
});

arrowRight.addEventListener('pointerdown', e => {
    if (e.pointerType === 'touch') e.preventDefault();
    startScroll('right');
});
arrowRight.addEventListener('pointerup', stopScroll);
arrowRight.addEventListener('pointerleave', stopScroll);
arrowRight.addEventListener('pointercancel', stopScroll);
arrowRight.addEventListener('contextmenu', e => {
    if (e.pointerType === 'touch') e.preventDefault();
});


}, { once: true });


/** @brief Простые стили текста */
const simpleFormats = [
    { id: 'bol',   style: { fontWeight: 'bold' },            prop: 'font-weight',            test: v => (parseInt(v) >= 700 || v === 'bold') },
    { id: 'ital',  style: { fontStyle: 'italic' },           prop: 'font-style',             test: v => v === 'italic' },
    { id: 'under', style: { textDecorationLine: 'underline' },prop: 'text-decoration-line',    test: v => v.split(' ').includes('underline') },
    { id: 'strik', style: { textDecorationLine: 'line-through' },prop: 'text-decoration-line', test: v => v.split(' ').includes('line-through') },
    { id: 'sup',   style: { verticalAlign: 'super' },         prop: 'vertical-align',         test: v => v === 'super' },
    { id: 'sub',   style: { verticalAlign: 'sub' },           prop: 'vertical-align',         test: v => v === 'sub' }
];
/** @brief Стили выравнивания для блоков */
const divFormats = [
    { id: 'equal', style: { textAlign: 'left' }   },
    { id: 'equac', style: { textAlign: 'center' } },
    { id: 'equar', style: { textAlign: 'right' }  },
    { id: 'equaj', style: { textAlign: 'justify'} }
];
/** @brief Стили списков */
const listFormats = [
    { id: 'listNone',     style: { listStyleType: 'none' }      },
    { id: 'listDots',     style: { listStyleType: 'disc' }      },
    { id: 'listNumbers',  style: { listStyleType: 'decimal' }   },
    { id: 'listLetters',  style: { listStyleType: 'lower-alpha'} }
];
/** @brief Отдельные свойства текста */
const singleFormats = [
    { id: 'ff',    prop: 'font-family'},
    { id: 'fs',    prop: 'font-size'}
];
/** @brief Специальные форматы */
const specialFormats = ['butlink', 'linkdel', 'forma', 'col', 'backgr'];

addEventListener("LoadeditorJs", function() {
const content = document.getElementById('content');

simpleFormats.forEach(f => {
    document.getElementById(f.id).addEventListener('click', () => {
        const sel = window.getSelection();
        if (!sel.rangeCount) return;
        const range = sel.getRangeAt(0);
        if (!content.contains(range.commonAncestorContainer)) return;
        let all = true;
        const it = document.createNodeIterator(
            range.commonAncestorContainer,
            NodeFilter.SHOW_ALL,
            { acceptNode: n => range.intersectsNode(n) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }
        );
        let n;
        while (n = it.nextNode()) {
            if (n.nodeType === Node.TEXT_NODE && n.textContent.trim()) {
                let cur = n.parentElement, ok = false;
                while (cur) {
                    const v = getComputedStyle(cur)[f.prop] || '';
                    if (f.test(v)) { ok = true; break; }
                    cur = cur.parentElement;
                }
                if (!ok) { all = false; break; }
            }
        }
        all ? simpleUnformat(range, f) : simpleApplyformat(range, f);
        sel.removeAllRanges();
        sel.addRange(range);
        inter();
    });
});

divFormats.forEach(f => {
    document.getElementById(f.id).addEventListener('click', () => {
        const sel = window.getSelection();
        if (!sel.rangeCount) return;
        const range = sel.getRangeAt(0);
        if (!content.contains(range.commonAncestorContainer)) return;
        divApplyformat(range, f);
        inter();
    });
});

listFormats.forEach(f => {
    document.getElementById(f.id).addEventListener('click', () => {
        const sel = window.getSelection();
        if (!sel.rangeCount) return;
        const range = sel.getRangeAt(0);
        if (!content.contains(range.commonAncestorContainer)) return;
        listApplyformat(range, f);
        inter();
    });
});

singleFormats.forEach(f => {
    const el = document.getElementById(f.id)
    el.addEventListener('click', e => {
        const list = el.querySelector('.align-list')
        if (!list || getComputedStyle(list).display === 'none') return
        const cmdEl = e.target.closest('[data-cmd]')
        if (!cmdEl) return
        f.value = cmdEl.dataset.cmd
        const sel = window.getSelection()
        if (!sel.rangeCount) return
        const range = sel.getRangeAt(0)
        if (!content.contains(range.commonAncestorContainer)) return
        singleApplyformat(range, f)
        inter()
    })
})

specialFormats.forEach(f => {
    document.getElementById(f).addEventListener('click', () => {
        const sel = window.getSelection();
        if (!sel.rangeCount) return;
        const range = sel.getRangeAt(0);
        if (!content.contains(range.commonAncestorContainer)) return;
        if (typeof document[f + 'Fun'] === 'function') document[f + 'Fun'](range);
        else  window[f + 'Fun'](range);
        inter();
    });
});

const events = ['pointerup','keyup','input','focus','blur','click'];
events.forEach(evt => {
    if (!content) return;
    content.addEventListener(evt, () => {
        updateToolbarStyles();
        updateSingleSelectors();
    });
});

}, { once: true });

/////////////////// Начало блока, выполняющего навигацию по внесенным изменениям ====================

/** @brief История изменений контента */
let arr = []
/** @brief Текущий индекс в истории изменений */
let currentIndex = 0

/** @brief Сохраняет текущее состояние контента, если оно изменилось */
function inter() {
    const editable = document.getElementById("content")
    if (editable) {
        let currentContent = editable.innerHTML
        if (currentContent !== arr[currentIndex]) {
            currentIndex++
            arr = arr.slice(0, currentIndex)
            arr.push(currentContent)
        }
    }
}

if (document.getElementById("content")) {
    arr[0] = document.getElementById("content").innerHTML
}

document.getElementById("forw").addEventListener("click", function() {
    if (currentIndex < arr.length - 1) {
        currentIndex++
        const editable = document.getElementById("content")
        editable.innerHTML = arr[currentIndex]
        editable.setAttribute("contenteditable", "true")
    }
})

document.getElementById("bac").addEventListener("click", function() {
    if (currentIndex > 0) {
        currentIndex--
        const editable = document.getElementById("content")
        editable.innerHTML = arr[currentIndex]
        editable.setAttribute("contenteditable", "true")
    }
})

/////////////////// Конец блока, выполняющего навигацию по внесенным изменениям ====================

/**
    * @brief Применяет форматирование к выделенному диапазону текста
    * @param range Диапазон выделения текста
    * @param createElement Функция создания нового элемента для форматирования
*/
function applyformat(range, createElement) {
    const arr = [], it = document.createNodeIterator(
        range.commonAncestorContainer,
        NodeFilter.SHOW_TEXT,
        n => range.intersectsNode(n) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
    );
    let n;
    while (n = it.nextNode()) arr.push(n);
    let firstEl, lastEl;
    arr.forEach((tn, i) => {
        const p = tn.parentNode;
        const start = tn === range.startContainer ? range.startOffset : 0;
        const end   = tn === range.endContainer   ? range.endOffset   : tn.textContent.length;
        let newEl;
        if (tn === range.startContainer && tn === range.endContainer) {
            const b = tn.splitText(start), m = b.splitText(end - start);
            newEl = createElement();
            newEl.textContent = b.textContent;
            p.replaceChild(newEl, b);
            p.insertBefore(m, newEl.nextSibling);
        } else if (tn === range.startContainer) {
            const aNode = tn.splitText(start);
            newEl = createElement();
            newEl.textContent = aNode.textContent;
            p.replaceChild(newEl, aNode);
        } else if (tn === range.endContainer) {
            const b = tn.splitText(end);
            newEl = createElement();
            newEl.textContent = tn.textContent;
            p.replaceChild(newEl, tn);
            p.insertBefore(b, newEl.nextSibling);
        } else {
            newEl = createElement();
            newEl.textContent = tn.textContent;
            p.replaceChild(newEl, tn);
        }
        if (i === 0) firstEl = newEl;
        if (i === arr.length - 1) lastEl = newEl;
    });
    if (firstEl && lastEl) {
        range.setStartBefore(firstEl);
        range.setEndAfter(lastEl);
    }
    mergeTextNodes(range.commonAncestorContainer);
}

/**
    * @brief Применяет простой стиль (bold, italic и т.д.) к диапазону текста
    * @param range Диапазон выделения текста
    * @param format Объект с описанием формата
*/
function simpleApplyformat(range, format) {
    const span = document.createElement('span');
    Object.assign(span.style, format.style);
    applyformat(range, () => span.cloneNode());
}

/**
    * @brief Убирает простой стиль (bold, italic и т.д.) из диапазона текста
    * @param range Диапазон выделения текста
    * @param format Объект с описанием формата
*/
function simpleUnformat(range, format) {
    const { prop, test } = format;

    const spans = new Set();
    const it = document.createNodeIterator(
        range.commonAncestorContainer,
        NodeFilter.SHOW_TEXT,
        n => {
            if (!range.intersectsNode(n)) return NodeFilter.FILTER_REJECT;
            let node = n.parentNode;
            while (node && node !== range.commonAncestorContainer) {
                if (node.tagName === 'SPAN' && test(node.style.getPropertyValue(prop) || '')) {
                    return NodeFilter.FILTER_ACCEPT;
                }
                node = node.parentNode;
            }
            return NodeFilter.FILTER_REJECT;
        }
    );
    
    let tn;
    while (tn = it.nextNode()) {
        let node = tn.parentNode;
        while (node && node !== range.commonAncestorContainer) {
            if (node.tagName === 'SPAN' && test(node.style.getPropertyValue(prop) || '')) {
                if (range.intersectsNode(node)) {
                    spans.add(node);
                }
            }
            node = node.parentNode;
        }
    }
    
    spans.forEach(span => {
        const full = span.textContent;
        let total = 0, startAbs = 0, endAbs = full.length;
        const walker = document.createTreeWalker(span, NodeFilter.SHOW_TEXT, null);
        let t;
        while (walker.nextNode()) {
            t = walker.currentNode;
            if (t === range.startContainer) startAbs = total + range.startOffset;
            if (t === range.endContainer) endAbs = total + range.endOffset;
            total += t.textContent.length;
        }
        if (startAbs >= endAbs) return;

        const bef = full.slice(0, startAbs);
        const sel = full.slice(startAbs, endAbs);
        const aft = full.slice(endAbs);

        const p = span.parentNode;
        if (!p) return;

        function cloneWithText(node, text) {
            const clone = node.cloneNode(false);
            for (let child of node.childNodes) {
                if (text.length === 0) break;
                if (child.nodeType === Node.TEXT_NODE) {
                    const len = child.textContent.length;
                    const take = text.slice(0, len);
                    clone.appendChild(document.createTextNode(take));
                    text = text.slice(len);
                } else {
                    const sub = child.textContent;
                    const taken = text.slice(0, sub.length);
                    clone.appendChild(cloneWithText(child, taken));
                    text = text.slice(sub.length);
                }
            }
            return clone;
        }

        if (bef) p.insertBefore(cloneWithText(span, bef), span);
        if (sel) {
            const unwrapped = document.createDocumentFragment();
            const mid = cloneWithText(span, sel);
            while (mid.firstChild) unwrapped.appendChild(mid.firstChild);
            p.insertBefore(unwrapped, span);
        }
        if (aft) p.insertBefore(cloneWithText(span, aft), span);
        span.remove();
    });
}

/**
    * @brief Объединяет соседние текстовые узлы
    * @param node Элемент, внутри которого объединяются текстовые узлы
*/
function mergeTextNodes(node) {
    let c = node.firstChild;
    while (c) {
        let nx = c.nextSibling;
        if (c.nodeType === Node.TEXT_NODE) {
            while (nx && nx.nodeType === Node.TEXT_NODE) {
                c.textContent += nx.textContent;
                const next = nx.nextSibling;
                if (nx.parentNode) nx.parentNode.removeChild(nx);
                nx = next;
            }
        } else if (c.nodeType === Node.ELEMENT_NODE) {
            mergeTextNodes(c);
        }
        c = nx;
    }
}

/**
    * @brief Применяет стиль выравнивания к блочным элементам
    * @param range Диапазон выделения текста
    * @param format Объект с описанием формата
*/
function divApplyformat(range, format) {
    const style = format.style;
    if (!style || !style.textAlign) return;
    const externals = new Set();
    const intersects = element => {
        const er = document.createRange();
        er.selectNodeContents(element);
        return range.compareBoundaryPoints(Range.END_TO_START, er) < 0 &&
               range.compareBoundaryPoints(Range.START_TO_END, er) > 0;
    };

    Array.from(content.children).forEach(child => {
        if (intersects(child)) externals.add(child);
    });

    externals.forEach(div => {
        div.style.textAlign = style.textAlign;
    });
}

/**
    * @brief Применяет стиль списка к выделенным элементам
    * @param range Диапазон выделения текста
    * @param format Объект с описанием формата
*/
function listApplyformat(range, format) {
    const intersects = el => {
        const er = document.createRange();
        er.selectNodeContents(el);
        return range.compareBoundaryPoints(Range.END_TO_START, er) < 0 &&
               range.compareBoundaryPoints(Range.START_TO_END, er) > 0;
    };

    const type = format.id;

    if (type === 'listNone') {
        const lists = new Set();
        Array.from(content.querySelectorAll('li')).forEach(li => {
            if (intersects(li)) lists.add(li.parentNode);
        });

        lists.forEach(list => {
            const parent = list.parentNode;
            const lis = Array.from(list.children);
            const selected = lis.filter(li => intersects(li));
            if (!selected.length) return;

            const firstIdx = lis.indexOf(selected[0]);
            const lastIdx  = lis.indexOf(selected[selected.length - 1]);
            const before   = lis.slice(0, firstIdx);
            const after    = lis.slice(lastIdx + 1);

            if (before.length) {
                const ul1 = list.cloneNode(false);
                before.forEach(li => ul1.appendChild(li));
                parent.insertBefore(ul1, list);
            }

            selected.forEach(li => {
                const wrapper = li.firstElementChild && li.firstElementChild.cloneNode(true) || document.createElement('div');
                if (!li.firstElementChild) {
                    while (li.firstChild) wrapper.appendChild(li.firstChild);
                }
                parent.insertBefore(wrapper, list);
            });

            if (after.length) {
                const ul2 = list.cloneNode(false);
                after.forEach(li => ul2.appendChild(li));
                parent.insertBefore(ul2, list);
            }

            parent.removeChild(list);
        });
    } else {
        const items = Array.from(content.children).filter(child => intersects(child));
        if (!items.length) return;

        let listEl;
        if (type === 'listNumbers' || type === 'listLetters') {
            listEl = document.createElement('ol');
            listEl.style.listStyleType = format.style.listStyleType;
        } else {
            listEl = document.createElement('ul');
            listEl.style.listStyleType = format.style.listStyleType;
        }
        content.insertBefore(listEl, items[0]);

        items.forEach(node => {
            if (node.tagName === 'UL' || node.tagName === 'OL') {
                Array.from(node.children).forEach(li => {
                    listEl.appendChild(li);
                });
                content.removeChild(node);
            } else {
                const li = document.createElement('li');
                content.removeChild(node);
                li.appendChild(node);
                listEl.appendChild(li);
            }
        });
    }
}

/**
    * @brief Применяет одиночный стиль к диапазону текста
    * @param range Диапазон выделения текста
    * @param f Объект с описанием формата
    * @return span Элемент span с применённым стилем
*/
function singleApplyformat(range, f) {
    const val = f.value;
    if (!val) return;
    applyformat(range, () => {
        const span = document.createElement('span');
        span.style[f.prop] = val;
        return span;
    });
}

/**
    * @brief Применяет ссылку к диапазону текста
    * @param range Диапазон выделения текста
    * @return a Элемент a с применёнными атрибутами и стилем
*/
function butlinkFun(range) {
    const url = document.getElementById('link2').value;
    const targetBlank = document.getElementById('link3').value === 'yes';
    const underline = document.getElementById('link5').value === 'yes';
    const color = document.getElementById('link6c').value;
    applyformat(range, () => {
        const a = document.createElement('a');
        a.href = url;
        if (targetBlank) a.target = '_blank';
        if (underline) a.style.textDecoration = 'underline';
        if (color) a.style.color = color;
        return a;
    });
    inter();
}

/**
    * @brief Удаляет все ссылки из диапазона текста
    * @param range Диапазон выделения текста
    * @return frag Фрагмент документа без ссылок
*/
function linkdelFun(range) {
    const frag = range.extractContents();
    const cleaned = unwrapAllLinks(frag);
    range.insertNode(cleaned);

    function unwrapAllLinks(node) {
        const frag = document.createDocumentFragment();
        Array.from(node.childNodes).forEach(ch => {
            if (ch.nodeType === Node.ELEMENT_NODE && ch.tagName === 'A') {
                frag.appendChild(unwrapAllLinks(ch));
            } else if (ch.nodeType === Node.ELEMENT_NODE) {
                const copy = ch.cloneNode(false);
                copy.appendChild(unwrapAllLinks(ch));
                frag.appendChild(copy);
            } else {
                frag.appendChild(ch.cloneNode(true));
            }
        });
        return frag;
    }
}

/**
    * @brief Убирает все спаны и ссылки из диапазона текста
    * @param range Диапазон выделения текста
    * @return frag Фрагмент документа без span и a
*/
function formaFun(range) {
    const frag = range.extractContents();
    const cleaned = unwrapAllSpansAndLinks(frag);
    range.insertNode(cleaned);

    const externals = new Set();
    const intersects = element => {
        const er = document.createRange();
        er.selectNodeContents(element);
        return range.compareBoundaryPoints(Range.END_TO_START, er) < 0
            && range.compareBoundaryPoints(Range.START_TO_END, er) > 0;
    };
    Array.from(content.children).forEach(child => {
        if (intersects(child)) externals.add(child);
    });
    externals.forEach(el => {
        el.style.textAlign = '';
    });
    
    const itList = document.createNodeIterator(
        content,
        NodeFilter.SHOW_ELEMENT,
        {
            acceptNode: n =>
                (n.tagName === 'UL' || n.tagName === 'OL') &&
                range.intersectsNode(n)
                ? NodeFilter.FILTER_ACCEPT
                : NodeFilter.FILTER_REJECT
        }
    );
    let listEl;
    while (listEl = itList.nextNode()) {
        const parent = listEl.parentNode;
        Array.from(listEl.children).forEach(li => {
            while (li.firstChild) parent.insertBefore(li.firstChild, listEl);
        });
        parent.removeChild(listEl);
    }

    function unwrapAllSpansAndLinks(node) {
        const frag = document.createDocumentFragment();
        Array.from(node.childNodes).forEach(ch => {
            if (
                ch.nodeType === Node.ELEMENT_NODE &&
                (ch.tagName === 'SPAN' || ch.tagName === 'A')
            ) {
                frag.appendChild(unwrapAllSpansAndLinks(ch));
            } else if (ch.nodeType === Node.ELEMENT_NODE) {
                const copy = ch.cloneNode(false);
                copy.appendChild(unwrapAllSpansAndLinks(ch));
                frag.appendChild(copy);
            } else {
                frag.appendChild(ch.cloneNode(true));
            }
        });
        return frag;
    }
}

/** @brief Текущий формат для применения */
let currentFormat = null;
/** @brief Текущий диапазон выделения */
let currentRange = null;
/**
    * @brief Открывает палитру выбора цвета текста
    * @param range Диапазон выделения текста
*/
window.colFun = function(range) {    
    currentFormat = { prop: 'color', test: v => !!v };
    currentRange = range;
    const app = document.querySelector('.pcr-app');
    app.style.marginLeft = '-61px';
    app.style.left = '';
    app.classList.remove('hide');
}
/**
    * @brief Открывает палитру выбора фона текста
    * @param range Диапазон выделения текста
*/
window.backgrFun = function(range) {    
    currentFormat = { prop: 'background-color', test: v => !!v };
    currentRange = range;
    const app = document.querySelector('.pcr-app');
    app.style.marginLeft = '-29px';
    app.style.left = '';
    app.classList.remove('hide');
}
/**
    * @brief Применяет выбранный цвет текста или фона
*/
function setColorFun() {
    const input = document.querySelector('.pcr-result');
    const val = input.value;
    if (!currentRange || !currentFormat) return;
    if (!val) {
        simpleUnformat(currentRange, currentFormat);
    } else {
        applyformat(currentRange, () => {
            const span = document.createElement('span');
            span.style[currentFormat.prop] = val;
            return span;
        });
    }
    const app = document.querySelector('.pcr-app');
    app.classList.add('hide');
}
document.addEventListener('LoadeditorJs', () => {
    document.addEventListener('pointerdown', e => {
        if (document.querySelector('.pcr-app') && !e.target.closest('.pcr-app') && !e.target.closest('#col') && !e.target.closest('#backgr')) {
            setColorFun();
        }
    });
}, { once: true });

/** @brief Кнопки панели инструментов */
const toolbarButtons = ['bol','ital','under','strik','sup','sub'];
/** @brief Цвета фона кнопок панели инструментов */
const bgColors = {
    none:    'rgb(255 255 255)',
    partial: 'rgb(231 231 231)',
    full:    'rgb(203 203 203)'
};

/**
    * @brief Определяет текущее состояние формата (выделено/не выделено/частично)
    * @param format Идентификатор формата
    * @return string Состояние формата: 'none', 'partial', 'full'
*/
function detectFormatState(format) {
    const sel = window.getSelection();
    if (!sel.rangeCount) return 'none';
    const range = sel.getRangeAt(0);
    if (!content.contains(range.commonAncestorContainer)) return 'none';
    const it = document.createNodeIterator(
        range.commonAncestorContainer,
        NodeFilter.SHOW_TEXT,
        { acceptNode: n => range.intersectsNode(n) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }
    );
    let node, total = 0, styled = 0;
    while (node = it.nextNode()) {
        const text = node.textContent.trim();
        if (!text) continue;
        total++;
        let cur = node.parentElement, ok = false;
        while (cur && cur !== content) {
            const fmt = simpleFormats.find(f => f.id === format);
            const v = fmt ? getComputedStyle(cur)[fmt.prop] || '' : '';
            if (fmt && fmt.test(v)) { ok = true; break; }
            cur = cur.parentElement;
        }
        if (ok) styled++;
    }
    if (total === 0) return 'none';
    if (styled === 0) return 'none';
    if (styled === total) return 'full';
    return 'partial';
}

/**
    * @brief Обновляет стили кнопок панели инструментов в зависимости от состояния форматирования
*/
function updateToolbarStyles() {
    toolbarButtons.forEach(id => {
        const btn = document.getElementById(id);
        const state = detectFormatState(id);
        btn.style.backgroundColor = bgColors[state];
    });
}

/** @brief Одиночные селекторы панели инструментов */
const singleSelectors = ['ff','fs'];

/**
    * @brief Определяет текущее состояние одиночного селектора (шрифт, размер)
    * @param format Идентификатор селектора
    * @return string Текущее значение или пустая строка
*/
function detectSingleState(format) {
    const sel = window.getSelection();
    if (!sel.rangeCount) return '';
    const range = sel.getRangeAt(0);
    if (!content.contains(range.commonAncestorContainer)) return '';
    const it = document.createNodeIterator(
        range.commonAncestorContainer,
        NodeFilter.SHOW_TEXT,
        { acceptNode: n => range.intersectsNode(n) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }
    );
    let node, values = [], uniform = true;
    while (node = it.nextNode()) {
        const text = node.textContent.trim();
        if (!text) continue;
        const cur = node.parentElement;
        const fmt = singleFormats.find(f => f.id === format);
        const v = getComputedStyle(cur)[fmt.prop] || '';
        values.push(v);
    }
    if (values.length === 0) return '';
    const first = values[0];
    for (let i = 1; i < values.length; i++) {
        if (values[i] !== first) { uniform = false; break; }
    }
    return uniform ? values[0] : '';
}

/**
    * @brief Обновляет отображение одиночных селекторов на панели инструментов
*/
function updateSingleSelectors() {
    singleSelectors.forEach(id => {
        const dropdown = document.getElementById(id);
        const current = dropdown.querySelector('.current');
        const list = dropdown.querySelectorAll('li');
        let value = detectSingleState(id);
        if (!value) return;
        let cmd = id === 'ff'
            ? value.replace(/["']/g, '')
            : value;
        if (id === 'fs') {
            const num = parseFloat(cmd);
            const unit = (cmd.match(/[a-z%]+$/) || [''])[0];
            cmd = num.toFixed(1) + unit;
        }
        let found = Array.from(list).some(li => li.dataset.cmd === cmd);
        if (!found && id === 'ff') {
            const li = document.createElement('li');
            li.dataset.cmd = cmd;
            const div = document.createElement('div');
            div.textContent = cmd.split(',')[0].trim();
            li.appendChild(div);
            dropdown.querySelector('.align-list').appendChild(li);
        }
        current.textContent = id === 'ff'
            ? cmd.split(',')[0].trim()
            : cmd;
        current.dataset.cmd = cmd;
    });
}

addEventListener("LoadeditorJs", function()
{
document.querySelectorAll("#panel .toolbar-group").forEach(g => {
    const btn = g.querySelector(".toolbar-group-button");
    const content = g.querySelector(".toolbar-group-content");
    if (btn && content) {
        btn.addEventListener("click", () => {
            const isHidden = content.style.display === "none";
            content.style.display = isHidden ? "" : "none";
            if (btn && content) {
                const isHidden = content.style.display === "none";
                g.classList.toggle("open", !isHidden);
            }
        });
        if (btn && content) {
            const isHidden = content.style.display === "none";
            g.classList.toggle("open", !isHidden);
        }
    }
});

document.querySelectorAll('.swit').forEach(btn => {
    btn.addEventListener('click', () => {
        const target = document.getElementById(btn.id + '_d');
        if (!target) return;       
        target.style.display = 
            (getComputedStyle(target).display === 'none') ? '' : 'none';
    });
});

document.querySelectorAll('.align-dropdown').forEach(dropdown => {
    const current = dropdown.querySelector('.current');
    const list = dropdown.querySelector('.align-list');
    current.addEventListener('click', () => {
        list.style.display = list.style.display === 'block' ? 'none' : 'block';
        if (list.style.display === 'none' && current.dataset.cmd) {
            const cmd = current.dataset.cmd;
            const iconEl = document.getElementById(cmd);
            if (iconEl) iconEl.click();
        }
    });
    document.addEventListener('click', e => {
        if (!dropdown.contains(e.target)) list.style.display = 'none';
    });
    list.querySelectorAll('li').forEach(li => {
        li.addEventListener('click', () => {
            const icon = li.firstElementChild;
            const cmd = icon.id;
            current.dataset.cmd = cmd;
            current.removeAttribute('style');
            current.className = 'current editi editib pers';
            current.classList.add(cmd);
            list.style.display = 'none';
        });
    });
});

document.querySelectorAll('.align-dropdown-text').forEach(dropdown => {
    const current = dropdown.querySelector('.current')
    const list = dropdown.querySelector('.align-list')
    dropdown.addEventListener('click', e => {
        if (e.target.closest('.align-list')) return
        list.style.display = list.style.display === 'block' ? 'none' : 'block'
    })
    document.addEventListener('click', e => {
        if (!dropdown.contains(e.target)) list.style.display = 'none'
    })
    list.querySelectorAll('li').forEach(li => {
        li.addEventListener('click', () => {
            const cmd = li.dataset.cmd
            current.innerHTML = li.querySelector('img')?.outerHTML || li.textContent
            current.dataset.cmd = cmd
            list.style.display = 'none'
            const f = singleFormats.find(ff => ff.id === dropdown.id)
            f.value = cmd
            const sel = window.getSelection()
            if (sel.rangeCount) {
                const range = sel.getRangeAt(0)
                if (content.contains(range.commonAncestorContainer)) {
                    singleApplyformat(range, f)
                    inter()
                }
            }
        })
    })
})

}, { once: true });