/* показ окна древа */ let idCounter = 0; siteTreeGeneration(); /* генерация html древа */ function siteTreeGeneration() { handleJsonRpcRequest('scanDirTree', {}, 1).then(data => { if (data && Array.isArray(data.items)) { let treeContainer = document.getElementById('treeTableDiv'); treeContainer.innerHTML = generateTreeHtml(data.items, ""); let firstSpan = treeContainer.querySelector('span'); if (!treeContainer.innerHTML.includes('background-color: #e5f0ff;')) { firstSpan.style.backgroundColor = '#e5f0ff'; } } }).catch(err => { console.error(err); }); idCounter = 0; } window.siteTreeGeneration = siteTreeGeneration; let selectedTreeItem = ""; let selectedTreeItemAdd = ""; let firstLi = true; function generateTreeHtml(items, checkChildren) { let html = '`; if (checkChildren == "") { firstLi = true; } moveTreePage(); return html; } function generateTreeHtmlSitename(item, id) { let html = `
  • `; html += ``; html += `${item.tag}: ${item.content}`; html += ``; html += `
  • `; return html; } /* перемещение страниц */ function moveTreePage() { let treeTableDiv = document.getElementById('treeTableDiv'); let draggedItem = null; let offsetY = 0; let startX = 0; function isDescendant(parent, child) { while (child) { if (child === parent) return true; child = child.parentNode; } return false; } treeTableDiv.addEventListener('pointerdown', function(event) { if (window.treeSettingsMode != '') return; let li = event.target.closest('li'); if (li && event.button === 0) { if (li.id === 'treeHtmlIndex') return; let treeItem = event.target.closest('.tree-item'); if (!treeItem) return; draggedItem = li; offsetY = event.clientY - treeItem.getBoundingClientRect().top; li.style.opacity = '0.5'; event.preventDefault(); } }); document.addEventListener('pointermove', function(event) { if (window.treeSettingsMode != '') return; if (draggedItem && event.target.tagName !== "LI" && event.target.tagName !== "UL") { let elemBelow = document.elementFromPoint(event.clientX, event.clientY); let liBelow = elemBelow ? elemBelow.closest('li') : null; if (liBelow && liBelow !== draggedItem && !isDescendant(draggedItem, liBelow)) { let rect = liBelow.getBoundingClientRect(); let isTargetIndex = liBelow.parentElement?.closest('#treeHtmlIndex') !== null && liBelow.parentElement?.closest('#treeTableDiv')?.querySelector('#treeHtmlIndex')?.contains(liBelow.parentElement); if (isTargetIndex) { let parentDetails = draggedItem.parentElement.closest('.details'); if (event.clientY < rect.top + rect.height / 2) { liBelow.parentNode.insertBefore(draggedItem, liBelow); } else { liBelow.parentNode.insertBefore(draggedItem, liBelow.nextSibling); } if (parentDetails) { let parentUl = parentDetails.querySelector('ul'); if (parentUl && parentUl.children.length === 0) { let parentLi = parentDetails.closest('li'); parentDetails.remove(); if (parentLi) { let marker = parentLi.querySelector('.tree-marker'); if (marker) marker.textContent = '■'; } } } } } } }); document.addEventListener('pointerup', function() { if (window.treeSettingsMode != '') return; if (draggedItem) { draggedItem.style.opacity = ''; draggedItem = null; } }); treeTableDiv.addEventListener('pointermove', function(event) { if (window.treeSettingsMode != '') return; let li = event.target.closest('li'); if (li && event.button === 0 && draggedItem) { let treeItem = event.target.closest('.tree-item'); if (!treeItem) return; startX = event.clientX - treeItem.getBoundingClientRect().left; let upperLi = draggedItem.previousElementSibling; if (upperLi) { if (startX > 60) { let details = upperLi.querySelector('.details'); if (!details) { details = document.createElement('div'); details.className = 'details'; let ul = document.createElement('ul'); ul.setAttribute('style', 'margin-top: 10px; margin-bottom: 10px; list-style-type: none;'); details.appendChild(ul); upperLi.appendChild(details); } else { if (details.style.display === 'none') { details.style.display = 'block'; } } let marker = upperLi.querySelector('.tree-marker'); if (marker) { marker.textContent = '▼'; } draggedItem._attachedTo = upperLi; let detailsUl = details.querySelector('ul'); if (detailsUl && draggedItem.parentNode !== detailsUl) { detailsUl.appendChild(draggedItem); } } else if (startX < 20) { let details = upperLi.querySelector('.details'); if (details && details.contains(draggedItem)) { let parentUl = upperLi.parentNode; parentUl.insertBefore(draggedItem, upperLi.nextSibling); delete draggedItem._attachedTo; let detailsUl = details.querySelector('ul'); if (detailsUl && detailsUl.children.length === 0) { details.style.display = 'none'; let marker = upperLi.querySelector('.tree-marker'); if (marker) { marker.textContent = '►'; } } } } } } }); } addEventListener("load", function() { movementMenu("treeDiv"); movementMenu("treeProperties"); /* сохронения древа */ let treeSettingsSaveId = document.getElementById("treeSettingsSave"); treeSettingsSaveId.addEventListener('click', saveTree); function saveTree() { let treeTableDiv = document.getElementById('treeTableDiv'); let ul = treeTableDiv.querySelector('ul'); let treeData = ul ? parseUl(ul) : []; let siteNameElement = document.getElementById("treeHtmlSitename"); let siteName = siteNameElement ? siteNameElement.querySelector('.tree-text').textContent.trim() : ''; let sloganElement = document.getElementById("treeHtmlSlogan"); let slogan = sloganElement ? sloganElement.querySelector('.tree-text').textContent.trim() : ''; let fullData = { sitename: siteName, slogan: slogan, children: treeData }; handleJsonRpcRequest('saveTree', fullData, 1).then(response => { console.log(response); }); } function parseUl(ul) { let result = []; let items = ul.children; for (let item of items) { let span = item.querySelector('.tree-item .tree-text'); let textName = item.querySelector('.tree-text-name'); let dataDiv = item.querySelector('.tree-data'); let childrenUl = item.querySelector('.details > ul'); if (span && dataDiv) { let data = parseDataDiv(dataDiv); let mainText = span.childNodes[0].textContent.trim(); let extraText = textName ? textName.textContent.trim() : ""; data['tag'] = mainText; data['name'] = mainText + (extraText ? " " + extraText : ""); if (childrenUl) data['children'] = parseUl(childrenUl); result.push(data); } } return result; } function parseDataDiv(div) { let data = {}; let lines = div.innerHTML.split(//i); for (let line of lines) { let parts = line.split(': '); if (parts.length === 2) data[parts[0].trim()] = parts[1].trim(); } return data; } /* окно настроек древа */ let targetTreeItem = ""; let treeSettingsDiv = document.getElementById('treeSettings'); function treeSettings() { const treeDivDiv = document.getElementById('treeDiv'); if (!treeDivDiv) return; if (window.treeSettingsMode == 'linkFromPage') { document.getElementById('treeTopTitle').innerHTML = "{{select_page_for_link}}"; document.getElementById('treeSettingsSave').style.display = "none"; } else { document.getElementById('treeTopTitle').innerHTML = "{{tree_site_title}}"; document.getElementById('treeSettingsSave').style.display = "block"; } function showTreeSettings(event) { event.preventDefault(); let treeItem = event.target.closest('.tree-item'); targetTreeItem = treeItem ? treeItem : ""; treeSettingsDiv.style.left = `${touchX}px`; treeSettingsDiv.style.top = `${touchY}px`; document.getElementById('treeSettingsAdd').style.display = ''; document.getElementById('treeSettingsPaste').style.display = ''; document.getElementById('treeSettingsCopy').style.display = ''; document.getElementById('treeSettingsRename').style.display = ''; document.getElementById('treeSettingsProperties').style.display = ''; document.getElementById('treeSettingsDelete').style.display = ''; document.getElementById('treeSettingsChoose').style.display = ''; treeSettingsDiv.style.visibility = targetTreeItem ? "visible" : "hidden"; let tag = targetTreeItem instanceof Element ? targetTreeItem.querySelector('.tree-text')?.textContent.trim() : null; if (tag == "index" && !targetTreeItem.closest('li li')) { document.getElementById('treeSettingsRename').style.display = 'none'; document.getElementById('treeSettingsDelete').style.display = 'none'; } if (targetTreeItem) { let firstId = targetTreeItem.closest('li')?.firstElementChild?.id; if (firstId == "treeHtmlSitename" || firstId == "treeHtmlSlogan") { ['Add','Copy','Paste','Delete','Properties','Choose'].forEach(id=>{ document.getElementById('treeSettings'+id).style.display = 'none'; }); } } if (selectedTreeItem == "") { document.getElementById('treeSettingsPaste').style.display = 'none'; } document.addEventListener('pointerdown', function hideMenu(e) { if (!treeSettingsDiv.contains(e.target)) { treeSettingsDiv.style.visibility = "hidden"; document.removeEventListener('pointerdown', hideMenu); } }); if (window.treeSettingsMode == 'linkFromPage') { ['Add','Copy','Paste','Delete','Rename','Properties'].forEach(id=>{ document.getElementById('treeSettings'+id).style.display = 'none'; }); } else { document.getElementById('treeSettingsChoose').style.display = 'none'; } if ([].slice.call(document.getElementById('treeSettingsDiv').children).every(el=> getComputedStyle(el).display === 'none' )) { treeSettingsDiv.style.visibility = 'hidden'; } } function setupTreeSettingsHandler(){ const treeDiv=document.getElementById('treeDiv') if(!treeDiv) return treeDiv.removeEventListener('click',showTreeSettings) treeDiv.oncontextmenu=null if(isPhone){ touchLong(treeDiv,showTreeSettings) }else{ treeDiv.oncontextmenu=showTreeSettings } } setupTreeSettingsHandler(); window.addEventListener('resize', setupTreeSettingsHandler); } window.treeSettings = treeSettings; /* кнопки окна настроек древа */ /* кнопки добовление страниц / начало */ let treeSettingsAddId = document.getElementById('treeSettingsAdd'); treeSettingsAddId.addEventListener('click', treeSettingsAddFun); function treeSettingsAddFun() { if (window.newPageFunValue == "newPage") { document.getElementById("saveHow").click(); messageFunction("{{save_new_page}}"); return; } let container = getContainer(); let pageUrl = selectedTreeItemAdd; let treeText = prompt("{{enter_tag_for_new_page}}"); treeText = treeText ? treeText.trim() : ""; if (!/^[A-Za-z]+$/.test(treeText)) { messageFunction("{{tag_only_english_letters}}"); return; } if (treeText !== "") { let exists = false; let lis = container.querySelectorAll('li'); lis.forEach(function(li) { let txt = li.querySelector('.tree-text'); if (txt && txt.textContent.trim() === treeText) { exists = true; } }); if (exists) { alert("{{tag_already_exists}}"); return; } let newItem = createNewTreeItem(pageUrl, treeText); let newLi = document.createElement('li'); newLi.style.position = 'relative'; newLi.style.margin = '0px 0px 8px -20px'; newLi.appendChild(newItem); container.appendChild(newLi); if (targetTreeItem) { targetTreeItem.querySelector('.tree-marker').textContent = '▼'; } } treeSettingsDiv.style.visibility = "hidden"; } let treeSettingsPasteId = document.getElementById('treeSettingsPaste'); treeSettingsPasteId.addEventListener('click', treeSettingsPasteFun); function treeSettingsPasteFun() { let container = getContainer(); let clonedItem = selectedTreeItem.cloneNode(true); let treeText = prompt("{{enter_tag_for_new_page}}"); treeText = treeText ? treeText.trim() : ""; if (!/^[A-Za-z]+$/.test(treeText)) { messageFunction("{{tag_only_english_letters}}"); return; } if (treeText !== "") { let exists = false; let lis = container.querySelectorAll('li'); lis.forEach(function(li) { let txt = li.querySelector('.tree-text'); if (txt && txt.textContent.trim() === treeText) { exists = true; } }); if (exists) { messageFunction("{{tag_already_exists}}"); return; } let textSpan = clonedItem.querySelector('.tree-text'); let extractedTitle = selectedTreeItem.querySelector('.tree-data').innerHTML.match(/title:\s*([^<]+)/)?.[1].trim(); textSpan.innerHTML = `${treeText}  (${extractedTitle})`; let newLi = document.createElement('li'); newLi.style.position = 'relative'; newLi.style.margin = '0px 0px 8px -20px'; newLi.appendChild(clonedItem); container.appendChild(newLi); if (targetTreeItem) { targetTreeItem.querySelector('.tree-marker').textContent = '▼'; } } treeSettingsDiv.style.visibility = "hidden"; } function createNewTreeItem(pageUrl, treeText) { let newItem = document.createElement('span'); newItem.className = 'tree-item'; newItem.style.cursor = 'pointer'; newItem.style.padding = '3px 6px 3px 3px'; let marker = document.createElement('span'); marker.className = 'tree-marker'; marker.textContent = '■'; let textSpan = document.createElement('span'); textSpan.className = 'tree-text'; let extractedTitle = selectedTreeItemAdd.match(/title:\s*([^<]+)/)?.[1].trim() || ""; textSpan.innerHTML = `${treeText}  (${extractedTitle})`; let dataDiv = document.createElement('div'); dataDiv.className = 'tree-data'; dataDiv.style.display = 'none'; dataDiv.innerHTML = `${pageUrl}`; newItem.appendChild(marker); newItem.insertAdjacentText('beforeend', ' '); newItem.appendChild(textSpan); newItem.appendChild(dataDiv); newItem.setAttribute('onclick', 'toggleChildren(this)'); return newItem; } function getContainer() { let container; if (targetTreeItem) { let li = targetTreeItem.closest('li'); let details = li.querySelector('.details'); if (!details) { details = document.createElement('div'); details.className = 'details'; details.style.display = 'block'; li.appendChild(details); } let detailsUl = details.querySelector('ul'); if (!detailsUl) { detailsUl = document.createElement('ul'); detailsUl.style.marginTop = '10px'; detailsUl.style.marginBottom = '10px'; detailsUl.style.listStyleType = 'none'; details.appendChild(detailsUl); } container = detailsUl; } else { let treeTableDiv = document.getElementById('treeTableDiv'); let mainUl = treeTableDiv.querySelector('ul'); if (!mainUl) { mainUl = document.createElement('ul'); mainUl.style.marginTop = '10px'; mainUl.style.marginBottom = '10px'; mainUl.style.listStyleType = 'none'; treeTableDiv.appendChild(mainUl); } container = mainUl; } return container; } /* кнопки добовление страниц / конец */ let treeSettingsCopyId = document.getElementById('treeSettingsCopy'); treeSettingsCopyId.addEventListener('click', treeSettingsCopyFun); function treeSettingsCopyFun() { selectedTreeItem = targetTreeItem.cloneNode(true); selectedTreeItem.querySelector('.tree-marker').textContent = '■'; if (selectedTreeItem.classList.contains('tree-item')) { selectedTreeItem.style.backgroundColor = ''; } else { let treeItem = selectedTreeItem.querySelector('.tree-item'); if (treeItem) treeItem.style.backgroundColor = ''; } treeSettingsDiv.style.visibility = "hidden"; } let treeSettingsRenameId = document.getElementById('treeSettingsRename'); treeSettingsRenameId.addEventListener('click', treeSettingsRenameFun); function treeSettingsRenameFun() { if (targetTreeItem) { let li = targetTreeItem.closest('li'); if (li) { let treeText = li.querySelector('.tree-text'); if (treeText) { let firstTextNode = treeText.firstChild; let currentName = firstTextNode.nodeValue.trim(); let newText = prompt("{{enter_new_name}}", currentName); if (newText !== null) { newText = newText.trim(); if (!/^[A-Za-z]+$/.test(newText)) { messageFunction("{{name_only_english_letters}}"); return; } firstTextNode.nodeValue = newText + ' '; } } } } else { messageFunction("{{no_item_selected}}"); } treeSettingsDiv.style.visibility = "hidden"; } let treeSettingsDeleteId = document.getElementById('treeSettingsDelete'); treeSettingsDeleteId.addEventListener('click', treeSettingsDeleteFun); async function treeSettingsDeleteFun() { if (targetTreeItem) { let li = targetTreeItem.closest('li'); if (li) { let parentUl = li.parentElement; if (li.querySelector('li')) { messageQueue.push(`{{delete_all_subpages}} ${targetTreeItem.querySelector('.tree-text').textContent}?`); const userConfirmed = await messageCreateQuestion(); if (userConfirmed) { li.remove(); } } else { li.remove(); } if (parentUl && parentUl.children.length === 0) { let detailsDiv = parentUl.parentElement; if (detailsDiv && detailsDiv.classList.contains('details')) { let parentLi = detailsDiv.closest('li'); if (parentLi) { let marker = parentLi.querySelector('.tree-marker'); if (marker) marker.textContent = '■'; } detailsDiv.remove(); } } } } else { messageFunction("{{no_item_selected}}"); } let treeSettingsDiv = document.getElementById('treeSettings'); treeSettingsDiv.style.visibility = "hidden"; } /* свойтсва страниц */ let treeSettingsPropertiesId = document.getElementById('treeSettingsProperties');; treeSettingsPropertiesId.onclick = function() { let treePropertiesId = document.getElementById('treeProperties'); let treePropertiesDivId = document.getElementById('treePropertiesDiv'); let treePropertiesTopNameId = document.getElementById('treePropertiesTopName'); let treePropertiesWindowPropertiesId = document.getElementById('treePropertiesWindowProperties'); let treePropertiesWindowRightsId = document.getElementById('treePropertiesWindowRights'); let tableProperties = document.createElement('table'); tableProperties.style.width = "100%"; tableProperties.innerHTML= treePropertiesDiv(); let tableRights = document.createElement('div'); tableRights.innerHTML = `{{no_rights}}`; treePropertiesTopNameId.textContent = `{{properties}}`; treePropertiesDivId.innerHTML = ''; treePropertiesWindowPropertiesId.onclick = function() { treePropertiesDivId.innerHTML = ''; treePropertiesDivId.appendChild(tableProperties); treePropertiesWindowPropertiesId.style.backgroundColor = "#f3f3f3"; treePropertiesWindowRightsId.style.backgroundColor = ""; }; treePropertiesWindowRightsId.onclick = function() { treePropertiesDivId.innerHTML = ''; treePropertiesDivId.appendChild(tableRights); treePropertiesWindowPropertiesId.style.backgroundColor = ""; treePropertiesWindowRightsId.style.backgroundColor = "#f3f3f3"; }; treePropertiesWindowPropertiesId.click(); if (treePropertiesId.style.visibility == 'hidden') { treePropertiesId.style.visibility = 'visible'; } let treePropertiesTopCloseId = document.getElementById('treePropertiesTopClose'); let treePropertiesDivButtonOkId = document.getElementById('treePropertiesDivButtonOk'); let treePropertiesDivButtonCancelId = document.getElementById('treePropertiesDivButtonCancel'); treePropertiesTopCloseId.onclick = function() { treePropertiesId.style.visibility = 'hidden'; if (window.managerDataAction == "propertiesUrl") { window.managerDataAction = ""; managerDiv.style.visibility = "hidden"; } }; treePropertiesDivButtonOkId.onclick = function() { saveTreePropertiesDiv(); treePropertiesId.style.visibility = 'hidden'; if (window.managerDataAction == "propertiesUrl") { window.managerDataAction = ""; managerDiv.style.visibility = "hidden"; } }; treePropertiesDivButtonCancelId.onclick = function() { treePropertiesId.style.visibility = 'hidden'; if (window.managerDataAction == "propertiesUrl") { window.managerDataAction = ""; managerDiv.style.visibility = "hidden"; } }; }; function saveTreePropertiesDiv() { let treeDataDiv = lastRightClickedItem.querySelector('.tree-data'); let rows = document.querySelectorAll('#treePropertiesDiv table tr'); let newData = []; rows.forEach(row => { let key = row.querySelector('td:first-child').textContent.trim(); let valueCell = row.querySelector('td:last-child'); let value = ''; if (key.toLowerCase() === 'pagemenu') { let inputs = valueCell.querySelectorAll('input'); value = Array.from(inputs) .map(input => input.value.trim()) .filter(v => v) .join(','); } else if (key.toLowerCase() === 'template') { value = valueCell.querySelector('select').value; } else if (key.toLowerCase() === 'url') { value = document.getElementById('treePropertiesDivUrlValue').textContent; } else { let input = valueCell.querySelector('input'); value = input ? input.value : valueCell.textContent.trim(); } newData.push(`${key}: ${value}`); }); if (treeDataDiv) { treeDataDiv.innerHTML = newData.join('
    '); let name = newData.find(d => d.startsWith('name: '))?.split(': ')[1] || ''; let title = newData.find(d => d.startsWith('title: '))?.split(': ')[1] || ''; let textSpan = lastRightClickedItem.querySelector('.tree-text'); if (textSpan) { textSpan.childNodes[0].textContent = name + ' '; let nameSpan = textSpan.querySelector('.tree-text-name'); if (nameSpan) nameSpan.innerHTML = ` (${title})`; } } } /* Выбор страницы для ссылки */ let treeSettingsChooseId = document.getElementById('treeSettingsChoose'); treeSettingsChooseId.addEventListener('click', treeSettingsChooseFun); function treeSettingsChooseFun() { var parts = []; var span = targetTreeItem; var li = span.closest('li'); while (li) { var itemSpan = li.querySelector(':scope > span.tree-item'); var text = itemSpan.querySelector('.tree-text').firstChild.textContent.trim(); parts.unshift(text); li = li.parentElement.closest('li'); } if (parts[0] === 'index') { parts.shift(); } var url; if (parts.length) { url = 'http://slava.home/' + parts.join('/') + '.html'; } else { url = 'http://slava.home'; } document.getElementById('link2').value = url; document.getElementById("treeDiv").style.visibility = "hidden"; document.getElementById("treeProperties").style.visibility = "hidden"; document.getElementById("treeSettings").style.visibility = "hidden"; } function treePropertiesDiv() { if (!treePropertiesDivElement) return ""; let dataHTML = treePropertiesDivElement.querySelector('.tree-data')?.innerHTML || ""; let lines = dataHTML.split('
    '); let rows = []; for (let line of lines) { if (!line.trim()) continue; let parts = line.split(':'); let key = parts[0].trim(); let value = parts.slice(1).join(':').trim(); let inputHtml = value; if (key.toLowerCase() === "url") { inputHtml = `${value} `; } else if (key.toLowerCase() === "title") { inputHtml = ``; } else if (key.toLowerCase() === "name") { inputHtml = ``; } else if (key.toLowerCase() === "template") { let defaultTemplate = value; inputHtml = ``; setTimeout(function() { handleJsonRpcRequest('getFolderNames', { folder: '/template' }, 1).then(data => { let select = document.getElementById('templateSelect'); if (select && data && data.folders) { select.innerHTML = ''; data.folders.forEach(folder => { select.innerHTML += `${folder}`; }); } }); }, 0); } else if (key.toLowerCase() === "pagemenu") { let values = value.split(","); while (values.length < 3) { values.push(""); } inputHtml = values.map((val, index) => `` ).join(" , "); } else if (key.toLowerCase() === "users") { inputHtml = ``; } else if (key.toLowerCase() === "group") { inputHtml = ``; } rows.push(`${key}${inputHtml}`); } setTimeout(treePropertiesDivFunc, 0); return `${rows.join('')}
    `; } function treePropertiesDivFunc() { document.getElementById('treePropertiesDivUrl').onclick = function() { window.managerDataAction = "propertiesUrl"; managerData("/content"); managerDiv.style.visibility = "visible"; document.getElementById("settingsMain_d").style.visibility="hidden"; }; } let lastRightClickedItem = null; let treePropertiesDivElement = null; function treeContext(event){ let treeItem=event.target.closest('.tree-item') if(treeItem){ lastRightClickedItem=treeItem treePropertiesDivElement=treeItem } } document.addEventListener('contextmenu',treeContext) touchLong(document,treeContext) }); /* начало */