Files
utext/data/Basic_functions.js
2025-07-27 18:47:50 +03:00

1195 lines
44 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

window.managerDataAction = "";
window.currentPath = '';
window.managerHistoryPaths = [currentPath];
window.managerHistoryIndex = 0;
window.managerTableDivFilePath = "";
window.managerTableDivFileName = "";
window.saveHowNameLast = "index.page.php";
window.openPageButPath = "no/Select";
window.isPhone = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
window.touchX = 0;
window.touchY = 0;
(function(){
const hbody = document.getElementById('hbody')
const menuBtn = document.querySelector('.menu-btn.open')
const sideMenu = document.querySelector('.side-menu')
const smenu = document.getElementById('smenu')
const overlay = document.getElementById('overlay')
let rafId
function update() {
const elems = [
document.querySelector('.menu-btn.open'),
document.getElementById('shome'),
document.getElementById('smenu'),
document.getElementById('slng'),
document.getElementById('authorizationButton')
].filter(Boolean)
const originalDisplay = new Map()
elems.forEach(el => {
originalDisplay.set(el, el.style.display)
el.style.display = ''
})
const totalW = elems.reduce((sum, el) => {
const style = getComputedStyle(el)
return sum
+ el.offsetWidth
+ parseFloat(style.marginLeft)
+ parseFloat(style.marginRight)
}, 0)
const baseTop = elems[0].offsetTop
const wrapped = elems.some(el => el.offsetTop > baseTop)
elems.forEach(el => {
el.style.display = originalDisplay.get(el)
})
if (totalW > hbody.clientWidth || wrapped) {
menuBtn.style.display = ''
sideMenu.style.display = ''
overlay.style.display = ''
smenu.style.display = 'none'
} else {
menuBtn.style.display = 'none'
sideMenu.style.display = 'none'
overlay.style.display = 'none'
smenu.style.display = ''
}
}
function onResize() {
cancelAnimationFrame(rafId)
rafId = requestAnimationFrame(update)
}
window.addEventListener('resize', onResize)
window.addEventListener('load', onResize);
})()
;(function(){
const menuBtnOpen = document.querySelector('.menu-btn.open');
const menuBtnClose = document.querySelector('.menu-btn.close');
const checkbox = document.getElementById('menu-toggle');
const overlay = document.getElementById('overlay');
const sideMenu = document.querySelector('.side-menu');
menuBtnOpen.addEventListener('click', e => {
e.stopPropagation();
e.preventDefault();
checkbox.checked = true;
overlay.classList.add('active')
});
menuBtnClose.addEventListener('click', e => {
e.stopPropagation();
e.preventDefault();
checkbox.checked = false;
overlay.classList.remove('active')
});
checkbox.addEventListener('click', e => {
e.stopPropagation();
});
document.addEventListener('click', e => {
if (!sideMenu.contains(e.target) && !menuBtnOpen.contains(e.target)) {
checkbox.checked = false;
overlay.classList.remove('active')
}
});
})();
function updateEditElements() {
const scale = window.innerWidth <= 549 ? 1.15 : 1;
document.querySelectorAll('.editib, .editimc, .sym').forEach(el => {
if (!el.dataset.origBgX) {
const [origX, origY] = getComputedStyle(el)
.backgroundPosition
.split(' ')
.map(v => parseFloat(v));
el.dataset.origBgX = origX;
el.dataset.origBgY = origY;
}
const origX = parseFloat(el.dataset.origBgX);
const origY = parseFloat(el.dataset.origBgY);
const newX = (origX * scale).toFixed(2) + 'px';
const newY = (origY * scale).toFixed(2) + 'px';
el.style.backgroundPosition = `${newX} ${newY}`;
if (scale > 1) {
el.style.width = '30px';
el.style.height = '30px';
el.style.backgroundSize = 'calc(1122px* 1.15)';
} else {
el.style.width = '';
el.style.height = '';
el.style.backgroundSize = '';
}
});
}
window.addEventListener('load', updateEditElements);
window.addEventListener('resize', updateEditElements);
function movementMenu(id) {
const el = document.getElementById(id);
if (!el) return;
el.addEventListener("pointerdown", e => {
if (!isPhone) {
coor(e, id);
}
});
}
window.movementMenu = movementMenu;
window.addEventListener('load', function(){
const container=document.querySelector('.toolbar-container')
const panel=document.getElementById('panel')
const arrowLeft=document.getElementById('arrow-left')
if(!container||!panel||!arrowLeft||!('ontouchstart' in window))return
let startX=0
let currentTranslate=0
container.addEventListener('touchstart',onTouchStart,{passive:false})
container.addEventListener('touchmove',onTouchMove,{passive:false})
container.addEventListener('touchend',onTouchEnd)
function getBounds(){
const cw=container.scrollWidth
const pw=panel.clientWidth
const aw=arrowLeft.clientWidth
const extra=aw
const maxOffset=24
const minOffset=pw-cw-extra
return{maxOffset,minOffset}
}
function getCurrentTranslate(){
const m=window.getComputedStyle(container).transform
return m&&m!=='none'?parseFloat(m.split(',')[4]):0
}
function onTouchStart(e){
currentTranslate=getCurrentTranslate()
startX=e.touches[0].clientX
container.style.transition='none'
}
function onTouchMove(e){
e.preventDefault()
const deltaX=e.touches[0].clientX-startX
const{maxOffset,minOffset}=getBounds()
let nextTranslate=currentTranslate+deltaX
nextTranslate=Math.min(maxOffset,nextTranslate)
nextTranslate=Math.max(minOffset,nextTranslate)
container.style.transform=`translateX(${nextTranslate}px)`
}
function onTouchEnd(){
currentTranslate=getCurrentTranslate()
}
})
addEventListener("pointerup", stco);
addEventListener("touchend", stco);
let dvV = 0;
let dvH = 0;
let holdTimer = null;
let targetId = "";
function coor(event, id) {
if (event.type === "pointerdown" && event.button !== 0) return;
if (event.target.closest('[contenteditable], input, textarea, select, option, ul, ol')) return;
const el = document.getElementById(id);
if (!el) return;
el.style.touchAction = 'none';
el.style.overscrollBehavior = 'contain';
const rect = el.getBoundingClientRect();
el.style.top = rect.top + "px";
el.style.left = rect.left + "px";
removeTranslateOnly(el);
const clientY = event.touches ? event.touches[0].clientY : event.clientY;
const clientX = event.touches ? event.touches[0].clientX : event.clientX;
dvV = clientY - rect.top;
dvH = clientX - rect.left;
targetId = id;
clearTimeout(holdTimer);
holdTimer = setTimeout(function() {
if (targetId) {
addEventListener("pointermove", neco, { passive: false });
addEventListener("touchmove", neco, { passive: false });
}
}, 100);
}
function neco(event) {
if (!targetId) return;
event.preventDefault();
const el = document.getElementById(targetId);
const clientY = event.touches ? event.touches[0].clientY : event.clientY;
const clientX = event.touches ? event.touches[0].clientX : event.clientX;
const fvV = clientY - dvV;
const fvH = clientX - dvH;
el.style.top = fvV + "px";
el.style.left = fvH + "px";
if (targetId === "basis3" && fvH < 0) {
el.style.left = "0px";
}
}
function stco() {
clearTimeout(holdTimer);
removeEventListener("pointermove", neco, { passive: false });
removeEventListener("touchmove", neco, { passive: false });
targetId = "";
}
function removeTranslateOnly(el) {
const tf = el.style.transform.trim();
if (!tf || tf === 'none') return;
const parts = tf
.split(/\)\s*/)
.map(p => p.trim())
.filter(p => p && !p.startsWith('translate(') && !p.startsWith('translateX(') && !p.startsWith('translateY('))
.map(p => p + ')');
el.style.transform = parts.length > 0 ? parts.join(' ') : '';
}
/* создать запросы на сервер */
function createAjaxRequest(data, successCallback) {
$.ajax({
url: window.location.href,
type: "POST",
data: data,
dataType: "json",
success: successCallback,
error: function(xhr, status, error) {
console.error('Ошибка:', status, error);
messageFunction("{{error}}");
}
});
/* console.log(data + " " + successCallback); */
}
window.createAjaxRequest = createAjaxRequest;
function handleJsonRpcRequest(method, params, id) {
let url = window.location.href;
let fetchOpts = {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method,
params,
id,
handleJsonRpcRequestAction: method
})
};
return fetch(url, fetchOpts)
.then(res => {
if (!res.ok) throw new Error('HTTP ' + res.status);
return res.json();
})
.then(data => {
if (data.result !== undefined) return data.result;
throw new Error('Invalid response: ' + JSON.stringify(data));
});
}
window.handleJsonRpcRequest = handleJsonRpcRequest
/* длинное нажатие на телефоне */
function touchLong(el, fn) {
let timer
el.addEventListener('touchstart', function(e) {
timer = setTimeout(function() {
fn(e)
}, 500)
}, { passive: false })
el.addEventListener('touchend', function() {
clearTimeout(timer)
}, { passive: true })
el.addEventListener('touchmove', function() {
clearTimeout(timer)
}, { passive: true })
}
document.addEventListener('pointerdown', function(e){
window.touchX = e.clientX
window.touchY = e.clientY
}, false)
document.addEventListener('touchstart', function(e){
window.touchX = e.touches[0].clientX
window.touchY = e.touches[0].clientY
}, { passive: true })
/* двойный клик для телефонов */
if(isPhone){
document.querySelectorAll('td[ondblclick]').forEach(td=>{
let lastTap=0
td.addEventListener('touchend',function(e){
const now=Date.now()
if(now-lastTap<300){
const js=td.getAttribute('ondblclick').replace(/;$/,'')
new Function('event',js)(e)
}
lastTap=now
},{passive:true})
})
}
/* определение изменений в content */
window.contentIsEdit = false;
if (document.getElementById("content")) {
document.getElementById("content").addEventListener("input", function() {
window.contentIsEdit = true;
});
const observer = new MutationObserver(() => window.contentIsEdit = true);
observer.observe(document.getElementById("content"), { childList: true, subtree: true });
}
// показ сообщений
let messageQueue = [];
window.messageQueue = messageQueue;
let messageIsCreating = false;
function messageFunction(message) {
messageQueue.push(message);
if (!messageIsCreating) {
messageCreate();
}
}
window.messageFunction = messageFunction;
function messageCreate() {
if (messageQueue.length === 0) return;
messageIsCreating = true;
const messageBlock = document.createElement("div");
messageBlock.classList.add('messageBlock', 'borderStyle');
document.body.appendChild(messageBlock);
requestAnimationFrame(() => {
messageBlock.classList.add('show');
});
const messageBasicText = document.createElement('div');
messageBasicText.classList.add('messageBasicText', 'borderStyle');
messageBasicText.textContent = "{{message}}";
const messageText = document.createElement('div');
messageText.classList.add('messageText');
messageText.textContent = messageQueue.shift();
const messageButton = document.createElement('div');
messageButton.classList.add('messageButton', 'borderStyle');
messageButton.textContent = "{{ok}}";
messageButton.onclick = messageRemove;
messageBlock.appendChild(messageBasicText);
messageBlock.appendChild(messageText);
messageBlock.appendChild(messageButton);
setTimeout(messageRemove, 4000);
function messageRemove() {
if (messageBlock.parentElement) {
messageBlock.classList.remove('show');
setTimeout(() => {
messageBlock.remove();
messageIsCreating = false;
messageCreate();
}, 150);
}
}
}
// показ сообщений вопросов
let userConfirmed = false;
window.messageCreateQuestion = messageCreateQuestion;
function messageCreateQuestion() {
return new Promise((resolve, reject) => {
if (messageQueue.length === 0) return resolve(false);
messageIsCreating = true;
let messageBlock = document.createElement("div");
messageBlock.className = 'messageBlock borderStyle';
document.body.appendChild(messageBlock);
requestAnimationFrame(() => {
messageBlock.classList.add('show');
});
let messageBasicText = document.createElement("div");
messageBasicText.classList.add('messageBasicText', 'borderStyle');
messageBasicText.textContent = "{{message}}";
let messageText = document.createElement("div");
messageText.className = 'messageText';
messageText.textContent = messageQueue.shift();
let messageButtonNo = document.createElement("div");
messageButtonNo.classList.add('messageButton', 'borderStyle');
messageButtonNo.textContent = "{{no}}";
messageButtonNo.onclick = function() {
messageBlock.classList.remove('show');
setTimeout(() => {
messageBlock.remove();
messageIsCreating = false;
reject(false);
}, 150);
};
let messageButton = document.createElement("div");
messageButton.classList.add('messageButton', 'borderStyle');
messageButton.textContent = "{{yes}}";
messageButton.style.float = "left";
messageButton.onclick = function() {
messageBlock.classList.remove('show');
setTimeout(() => {
messageBlock.remove();
messageIsCreating = false;
resolve(true);
}, 0);
};
messageBlock.appendChild(messageBasicText);
messageBlock.appendChild(messageText);
messageBlock.appendChild(messageButtonNo);
messageBlock.appendChild(messageButton);
});
}
/* сообщение с вводом текста */
function messageCreateInput() {
return new Promise((resolve, reject) => {
if (messageQueue.length === 0) return resolve(false);
messageIsCreating = true;
const messageBlock = document.createElement("div");
messageBlock.classList.add("messageBlock", "borderStyle");
document.body.appendChild(messageBlock);
requestAnimationFrame(() => {
messageBlock.classList.add("show");
});
const messageBasicText = document.createElement("div");
messageBasicText.classList.add("messageBasicText", "borderStyle");
messageBasicText.style.fontSize = '1.4em';
messageBasicText.textContent = messageQueue.shift();
const messageInput = document.createElement("input");
messageInput.classList.add("messageInput", "borderStyle");
messageInput.type = "text";
const messageButton = document.createElement("div");
messageButton.classList.add("messageButton", "borderStyle");
messageButton.textContent = "{{ok}}";
messageButton.onclick = function() {
const value = messageInput.value;
messageBlock.classList.remove("show");
setTimeout(() => {
messageBlock.remove();
messageIsCreating = false;
resolve(value);
messageCreate();
}, 150);
};
messageBlock.appendChild(messageBasicText);
messageBlock.appendChild(messageInput);
messageBlock.appendChild(messageButton);
});
}
/* показать код */
let cou=1;
function showHtmlCode() {
if (cou==1) {
document.getElementById("tex").value=document.getElementById("content").innerHTML;
document.getElementById("tex").value = decodeHtmlEntities(document.getElementById("tex").value);
document.getElementById("tex").value = formatHTML(document.getElementById("tex").value);
let sbe=document.getElementsByClassName("sb");
for(let i=0; i<sbe.length; i++) {
if (sbe[i] != document.getElementById("tex"))
sbe[i].style.visibility="hidden";
}
if (document.getElementById("tex").style.visibility=="hidden") {
document.getElementById("tex").style.visibility="visible";
} else {
document.getElementById("tex").style.visibility="hidden";
}
cou=2;
} else {
document.getElementById("content").innerHTML=document.getElementById("tex").value;
document.getElementById("tex").style.visibility="hidden";
cou=1;
}
}
window.showHtmlCode = showHtmlCode;
window.newPageFunValue = "";
function saveChanges() {
if (window.newPageFunValue == "newPage") {
document.getElementById("saveHow").click();
} else {
saveContentId();
saveHeading();
savePlugins();
}
document.getElementById("settingsMain_d").style.visibility="hidden";
}
window.saveChanges = saveChanges;
function saveContentId() {
if(cou==1) {
document.getElementById("content").innerHTML = decodeHtmlEntities(document.getElementById("content").innerHTML);
document.getElementById("tex").value=document.getElementById("content").innerHTML;
}
document.getElementById("tex").value = decodeHtmlEntities(document.getElementById("tex").value);
let saveContentIdData = document.getElementById("tex").value.trim();
let xhr = createXHR(function () {
let ans=this.responseText;
if (ans == 1) {
console.log("{{main_block_saved}}");
} else {
messageFunction("{{main_block_not_saved}}");
}
});
xhr.send(`saveContentIdData=`+saveContentIdData+`&handleRequestAction=saveContentIdData`);
}
function savePlugins() {
let pluginsFloatsId = ["left-float", "right-float"];
let floatsBlockKeys = ["lblock", "rblock"];
let requestsData = {
left: [],
right: []
};
pluginsFloatsId.forEach((pluginsFloatId, i) => {
let plugins = document.getElementById(pluginsFloatId).querySelectorAll('.plugin-url');
plugins.forEach(plugin => {
let pluginData = {
pluginUrl: plugin.pluginUrl,
title: "",
tclass: "",
bclass: ""
};
let tElem = plugin.querySelector('[tclass]');
pluginData.title = tElem ? tElem.textContent.trim() : "";
pluginData.tclass = tElem ? tElem.getAttribute('class') : "";
let bElem = plugin.querySelector('[bclass]');
pluginData.bclass = bElem ? bElem.getAttribute('class') : "";
let blockKey = floatsBlockKeys[i];
let blockArray = (blockKey === "lblock") ? requestsData.left : requestsData.right;
blockArray.push(pluginData);
});
});
let data = `floatsBlock=${encodeURIComponent(JSON.stringify(requestsData))}`;
let xhr = createXHR(function () {
console.log(this.responseText);
});
xhr.send(`${data}&handleRequestAction=floatsBlock`);
}
function saveHeading() {
document.querySelectorAll('#mainTitle').forEach((editTitle) => {
if (functionOpenPage === true) {
messageFunction("{{open_page}}");
} else {
let newTitle = editTitle.innerHTML.trim();
if (newTitle === "") {
messageFunction("{{plugin_title_empty_error}}");
} else {
let xhr = createXHR(function () {
console.log(xhr.responseText);
});
let data = `newTitle=${encodeURIComponent(newTitle)}`;
xhr.send(data + '&handleRequestAction=newTitle');
}
}
});
}
function decodeHtmlEntities(str) { //Изменить символы &...;
var textarea = document.createElement('textarea');
textarea.innerHTML = str;
return textarea.value;
}
function formatHTML(html) { //Переносы и пробелы перед тегами
html = html.replace(/<([^\/][^>\s]*)[^>]*>/g, "\n$&\n");
html = html.replace(/<\/([^>\s]*)>/g, "\n$&\n");
html = html.replace(/^\s*[\r\n]/gm, '');
let lines = html.split('\n');
let indentLevel = 0;
let indentSize = 2;
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if (line.match(/^<\/[^>]+>/)) indentLevel--;
if (line.match(/^<\/[^>]+>/) || line.match(/^<[^\/>]+[^>]*>$/)) lines[i] = ' '.repeat(indentLevel * indentSize) + line;
if (line.match(/^<[^\/>]+[^>]*>$/)) indentLevel++;
}
html = lines.join('\n');
return html;
}
/* сохронить измения как */
window.saveContentIdHow = function (currentPath) {
if (cou == 1) {
document.getElementById("content").innerHTML = decodeHtmlEntities(document.getElementById("content").innerHTML);
document.getElementById("tex").value = document.getElementById("content").innerHTML;
}
document.getElementById("tex").value = decodeHtmlEntities(document.getElementById("tex").value);
let saveContentIdData = document.getElementById("tex").value.trim();
let nameFile = document.getElementById('saveHowName').value;
if (!nameFile.endsWith('.page.php')) {
nameFile += '.page.php';
messageFunction('{{page_must_end_with_page_php}}')
return;
}
if (!confirm('{{save_file_as}} ' + nameFile + '?')) {
return;
}
let xhr = createXHR(function () {
let ans = this.responseText;
if (ans == 0) {
if (confirm(`{{file}} ${nameFile} {{exists_overwrite_prompt}}`)) {
sendSaveRequest(currentPath, nameFile, saveContentIdData, true);
window.newPageFunValue = "";
document.getElementById("mainTitle").innerHTML = "<i>{{new_file}}</i>";
} else {
return;
}
} else if (ans == 1) {
createNewFile(currentPath, nameFile, saveContentIdData);
window.newPageFunValue = "";
document.getElementById("mainTitle").innerHTML = "<i>{{new_file}}</i>";
} else {
messageFunction("{{file_save_failed}}");
}
managerData(currentPath);
document.getElementById("managerDiv").style.visibility = "hidden";
});
xhr.send(`page_url=${currentPath}&nameFile=${nameFile}&handleRequestAction=checkFileExists`);
};
function sendSaveRequest(currentPath, nameFile, saveContentIdData, overwrite = false) {
let xhr = createXHR(function () {
let ans = this.responseText;
messageFunction(ans == 1 ? "{{changes_saved_successfully}}" : "{{data_save_error}}");
managerData(currentPath);
document.getElementById("managerDiv").style.visibility = "hidden";
});
let pluginsFloatsId = ["left-float", "right-float"];
let floatsBlockKeys = ["lblock", "rblock"];
let requestsData = { floatsBlock: [], title: [], pluginUrl: [], tclass: [], bclass: [] };
pluginsFloatsId.forEach((id, i) => {
document.getElementById(id).querySelectorAll('.plugin-url').forEach(plugin => {
requestsData.floatsBlock.push(floatsBlockKeys[i]);
let tElem = plugin.querySelector('[tclass]');
requestsData.title.push(tElem ? tElem.textContent.trim() : "");
requestsData.pluginUrl.push(plugin.pluginUrl);
requestsData.tclass.push(tElem ? tElem.getAttribute('class') : "");
let bElem = plugin.querySelector('[bclass]');
requestsData.bclass.push(bElem.getAttribute('class'));
});
});
let paramNames = ['page_url','nameFile','overwrite','saveContentIdData'];
let paramValues = [currentPath, nameFile, overwrite, saveContentIdData];
Object.keys(requestsData).forEach(key => {
requestsData[key].forEach(value => {
paramNames.push(key + '[]');
paramValues.push(value);
});
});
let query = createQueryString(paramNames, paramValues);
xhr.send(query + '&handleRequestAction=saveContentIdDataHow');
}
function createNewFile(currentPath, nameFile, saveContentIdData) {
let xhr = createXHR(function () {
let ans = this.responseText;
if (ans == 1) {
messageFunction(`{{file}} ${nameFile} {{created_successfully}}!`);
} else {
messageFunction(`{{file_creation_error}} ${nameFile}.`);
}
managerData(currentPath);
document.getElementById("managerDiv").style.visibility = "hidden";
});
xhr.send(`saveContentIdData=${saveContentIdData}&page_url=${currentPath}&nameFile=${nameFile}&handleRequestAction=createNewFile`);
}
// XMLHttpRequest шаблон
function createXHR(callback) {
let xhr = new XMLHttpRequest();
xhr.open("POST", window.location.href, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onload = callback;
return xhr;
}
window.createXHR = createXHR;
// Создать строку запроса для XMLHttpRequest
function createQueryString(dataNames, dataValues) {
let data = "";
for (let i = 0; i < dataNames.length; i++) {
data += `${dataNames[i]}=${encodeURIComponent(dataValues[i])}&`;
}
return data.slice(0, -1);
}
window.toggleMenu = function() {
document.getElementById('siteSettings').style.display = document.getElementById('siteSettings').style.display === 'none' || document.getElementById('siteSettings').style.display === '' ? 'block' : 'none';
};
window.onclick = function(event) {
var btn = document.getElementById('siteSettingsButton');
var settings = document.getElementById('siteSettings');
if (btn && !btn.contains(event.target)) {
settings && (settings.style.display = 'none');
}
};
// Открытие древа сайта
window.treeSettingsMode = "";
function basisVisSiteTree() {
siteTreeGeneration();
window.treeSettingsMode = "";
let treeDiv = document.getElementById("treeDiv");
if (treeDiv.style.visibility=="hidden") {
treeDiv.style.visibility = "visible";
if(isPhone) closeWindows("treeDiv");
} else {
treeDiv.style.visibility = "hidden";
document.getElementById("treeProperties").style.visibility = "hidden";
}
document.getElementById('treeCloseFun').onclick = function() {
treeDiv.style.visibility = "hidden";
document.getElementById("treeProperties").style.visibility = "hidden";
};
treeSettings();
}
window.basisVisSiteTree = basisVisSiteTree;
function linkFromPage() {
siteTreeGeneration();
window.treeSettingsMode = 'linkFromPage';
let treeDiv = document.getElementById("treeDiv");
treeDiv.style.visibility = "visible";
document.getElementById('treeCloseFun').onclick = function() {
treeDiv.style.visibility = "hidden";
document.getElementById("treeProperties").style.visibility = "hidden";
};
treeSettings();
}
window.linkFromPage = linkFromPage;
function toggleChildren(el) {
let details = el.closest('li').querySelector('.details');
if (!details) return;
details.style.display = details.style.display === 'none' ? 'block' : 'none';
el.querySelector('.tree-marker').textContent = details.style.display === 'block' ? '▼' : '►';
}
window.toggleChildren = toggleChildren;
//менеджер папок
function basisVisManager() {
let managerDiv = document.getElementById('managerDiv');
if (managerDiv.style.visibility === "hidden") {
managerDiv.style.visibility = "visible";
window.managerDataAction = "";
managerData(currentPath);
if(isPhone) closeWindows("managerDiv");
} else {
managerDiv.style.visibility = "hidden";
document.getElementById("managerProperties").style.visibility = "hidden";
}
}
window.basisVisManager = basisVisManager;
/* функция закрытия других окон */
function closeWindows(div) {
if (div == "managerDiv") {
document.getElementById("treeDiv").style.visibility = "hidden";
document.getElementById("treeProperties").style.visibility = "hidden";
} else if (div == "treeDiv") {
document.getElementById("managerDiv").style.visibility = "hidden";
document.getElementById("managerProperties").style.visibility = "hidden";
}
}
//функци которая добовляет данные в менеджер
function managerData(path) {
currentPath = path
if (managerHistoryPaths[managerHistoryIndex] !== currentPath) {
managerHistoryPaths = managerHistoryPaths.slice(0, managerHistoryIndex + 1)
managerHistoryPaths.push(currentPath)
managerHistoryIndex++
}
createAjaxRequest({ managerPathFolder: path, handleRequestAction: "managerPathFolder" }, function(data) {
let rows = ''
for (let i = 0; i < data.length; i++) {
if (data[i].name) {
let newPath = `${path}/${data[i].name}`
let attr = 'style="cursor: pointer; display: flex; align-items: center;" '
if (data[i].type === '{{file}}') {
let dbl = 'ondblclick="managerData(\'' + newPath + '\');"'
attr += isPhone
? 'onclick="managerData(\'' + newPath + '\');" ' + dbl
: dbl
} else if (data[i].name.endsWith('.page.php')) {
let page = newPath.replace('.page.php', '')
let dbl = 'ondblclick="openPage(\'' + page + '\');"'
attr += isPhone
? 'onclick="openPage(\'' + page + '\');" ' + dbl
: dbl
}
let icon = data[i].type === '{{file}}'
? '<div style="margin-right:5px;background-position:3px -557px;width:26px;height:26px;background-image:url(../../img/pict/mc_iconslyb.svg);display:inline-block;"></div>'
: '<div style="margin-right:5px;background-position:-678px -559px;width:26px;height:26px;background-image:url(../../img/pict/mc_iconslyb.svg);display:inline-block;"></div>'
let unit = data[i].type === '{{file}}' ? ' files' : ' bytes'
let sizeText = data[i].size + unit
let nameCell = isPhone
? `<div style="display:flex;flex-direction:column;align-items:flex-start;">
<div style="display:flex;align-items:center;">${icon}${data[i].name}</div>
<div style="font-size:0.7em;color:#666;margin-left:31px;">${sizeText}</div>
</div>`
: `${icon}${data[i].name}`
rows += `
<tr style="height:30px;" class="managerTableDivFile" path="${data[i].path}">
<td ${attr}>${nameCell}</td>
${isPhone ? '' : `<td>${sizeText}</td>`}
<td>${data[i].creationTime}</td>
</tr>`
}
}
let actionButton = ''
if (document.getElementById('saveHowName')) {
if (document.getElementById('saveHowName').value === '{{select_file}}') {
document.getElementById('saveHowName').value = 'index.page.php'
}
saveHowNameLast = document.getElementById('saveHowName').value
document.getElementById('saveHowButton').removeEventListener('click', saveHow)
document.getElementById('saveHowButton').removeEventListener('click', openPageBut)
}
let managerTopTitleName = '{{file_manager_title}}'
if (window.managerDataAction === 'saveHow') {
actionButton = `<div id="saveHowDiv"> {{name}}: <input id="saveHowName" value="${saveHowNameLast}"><span id="saveHowButton">{{save}}</span> </div>`
managerTopTitleName = '{{save}} как'
} else if (window.managerDataAction === 'openPage') {
actionButton = `<div id="saveHowDiv"> {{name}}: <input readonly id="saveHowName" value="{{select_file}}"><span id="saveHowButton">{{open}}</span> </div>`
managerTopTitleName = '{{open}}'
} else if (window.managerDataAction === 'propertiesUrl') {
actionButton = `<div id="saveHowDiv"> {{name}}: <input readonly id="saveHowName" value="{{select_file}}"><span id="saveHowButton">Выбрать</span> </div>`
managerTopTitleName = '{{open}}'
} else if (window.managerDataAction === 'selectImgForm') {
actionButton = `<div id="saveHowDiv"> {{name}}: <input readonly id="saveHowName" value="{{select_file}}"><span id="saveHowButton">{{open}}</span> </div>`
managerTopTitleName = '{{choose}}'
}
let sizeHeader = isPhone ? '' : `<td style="width:15%;">{{column_size_bytes}}</td>`
let dateWidth = isPhone ? '55%' : '23%'
managerDiv.innerHTML = `
<div id="managerTop">
<span id="managerTopTitle">${managerTopTitleName}</span>
<span id="managerCloseFun" class="editib"></span>
</div>
<div id="managerTopDiv" style="margin:7px 20px;">
<span id="managerHistoryBackFun" class="editib"></span>
<span id="managerHistoryForwFun" class="editib"></span>
<span id="managerBackFun" class="editib"></span>
<span id="managerPath" contentEditable="false">
<span class="managerPathButton" onclick="managerData('');">&nbsp;/&nbsp;</span>
${currentPath.split('/').filter(Boolean).map((seg, idx) => {
let segPath = '/' + currentPath.split('/').slice(1, idx + 2).join('/')
return ` <span class="managerPathButton" onclick="managerData('${segPath}');">${seg} /</span>`
}).join('')}
</span>
</div>
<div id="managerTableDiv">
<table id="managerTable">
<tr id="managerTableTitle">
<td style="width:45%;">{{name}}</td>
${sizeHeader}
<td style="width:${dateWidth};">{{column_creation_date}}</td>
</tr>
${rows}
</table>
</div>
${actionButton}
`
if (window.managerDataAction === 'saveHow') {
document.getElementById('saveHowButton').addEventListener('click', saveHow)
} else if (window.managerDataAction === 'openPage') {
document.getElementById('saveHowButton').addEventListener('click', openPageBut)
} else if (window.managerDataAction === 'propertiesUrl') {
document.getElementById('saveHowButton').addEventListener('click', propertiesUrlFun)
} else if (window.managerDataAction === 'selectImgForm') {
document.getElementById('saveHowButton').addEventListener('click', selectImgFormButFun)
}
openPageButPath = 'no/Select'
if (window.managerDataAction === 'openPage') {
document.querySelectorAll('.managerTableDivFile').forEach(el => {
el.addEventListener('click', function() {
openPageButPath = 'no/Select'
const td = this.querySelector('td')
const dbl = td.getAttribute('ondblclick') || ''
if (dbl.includes('openPage')) {
const m = dbl.match(/openPage\(['"]([^'"]+)['"]\)/)
if (m) openPageButPath = m[1]
const inp = document.getElementById('saveHowName')
if (inp) inp.value = td.innerText
}
})
})
} else if (window.managerDataAction === 'selectImgForm') {
document.querySelectorAll('.managerTableDivFile').forEach(el => {
el.addEventListener('click', function() {
openPageButPath = 'no/Select'
const td = this.querySelector('td')
if (td) {
openPageButPath = td.getAttribute('data-path') || openPageButPath
const inp = document.getElementById('saveHowName')
if (inp) inp.value = td.innerText
}
})
})
} else if (window.managerDataAction === 'saveHow' || window.managerDataAction === 'propertiesUrl') {
document.querySelectorAll('.managerTableDivFile').forEach(el => {
el.addEventListener('click', function() {
openPageButPath = 'no/Select'
const td = this.querySelector('td')
if (!td) return
let dbl = td.getAttribute('ondblclick') || ''
if (dbl.includes('openPage')) {
let nd = dbl.replace(/openPage\(['"][^'"]+['"]\)/, '')
if (!nd.trim()) td.removeAttribute('ondblclick')
else td.setAttribute('ondblclick', nd)
}
const inp = document.getElementById('saveHowName')
if (inp) inp.value = td.innerText
})
})
}
managerSettings()
managerFun()
})
}
//открытие новой страницы
window.functionOpenPage = false;
function openPage(newPath) {
window.functionOpenPage = true;
let xhr = createXHR(function () {
let page = JSON.parse(xhr.responseText);
document.getElementById("right-float").innerHTML = page.right;
document.getElementById("left-float").innerHTML = page.left;
document.getElementById("content").innerHTML = page.content;
managerDiv.style.visibility = "hidden";
//history.pushState(null, '', page.pagePath);
document.getElementById("mainTitle").innerHTML = "<i>{{new_file}}!</i>";
/* console.log(functionOpenPage); */
});
let data = `newPath=${encodeURIComponent(newPath)}`;
xhr.send(data+`&handleRequestAction=newPath`);
window.newPageFunValue = "";
}
//обьявление функции для того, чтобы обращатся к ней из других файлов
window.openPage = openPage;
window.managerData = managerData;
/* Функция z-index элементов */
document.addEventListener("DOMContentLoaded", function() {
var selectors = [
'#basis3 .cust',
'#managerDiv #managerSettings',
'#managerProperties',
'#treeDiv #treeSettings',
'#treeProperties',
'#authorizationDiv'
];
var groups = selectors.map(function(sel) {
var parts = sel.split(' ');
var elements = [];
parts.forEach(function(part) {
if (part.startsWith('#')) {
var el = document.getElementById(part.slice(1));
if (el) elements.push(el);
}
if (part.startsWith('.')) {
elements.push(...document.getElementsByClassName(part.slice(1)));
}
});
return elements;
});
var queue = [];
document.addEventListener('pointerdown', function(e) {
var clickedGroup = -1;
groups.forEach(function(group, idx) {
if (group.some(el => el.contains(e.target))) {
clickedGroup = idx;
}
});
if (clickedGroup !== -1) {
var i = queue.indexOf(clickedGroup);
if (i !== -1) queue.splice(i, 1);
queue.unshift(clickedGroup);
}
var result = selectors.map((_, idx) => {
var pos = queue.indexOf(idx);
return pos === -1 ? 100 : 199 - pos;
});
groups.forEach(function(group, idx) {
group.forEach(function(el) {
el.style.zIndex = result[idx];
});
});
});
var selectorsElements = [
'#basis3',
'.cust',
'#managerDiv',
'#managerSettings',
'#managerProperties',
'#treeDiv',
'#treeSettings',
'#treeProperties',
'#authorizationDiv'
];
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === 'style') {
var el = mutation.target;
var oldVal = mutation.oldValue || '';
var newVis = el.style.visibility;
if (newVis === 'visible' && !/visibility\s*:\s*visible/.test(oldVal)) {
selectorsElements.forEach(function(sel) {
document.querySelectorAll(sel).forEach(function(item) {
if (item === el) {
item.style.zIndex = 199;
} else {
let z = parseInt(item.style.zIndex, 10) || 100;
item.style.zIndex = z > 100 ? z - 1 : 100;
}
});
});
}
}
});
});
selectorsElements.forEach(function(sel) {
document.querySelectorAll(sel).forEach(function(el) {
observer.observe(el, {
attributes: true,
attributeFilter: ['style'],
attributeOldValue: true
});
});
});
document.querySelectorAll('.cust').forEach(el=>{
let hideTimer, watchTimer, watching=false
const observer = new MutationObserver(muts=>{
muts.forEach(m=>{
if(m.attributeName==='style' && getComputedStyle(el).visibility==='visible'){
watching = false
clearTimeout(watchTimer)
watchTimer = setTimeout(()=> watching = true, 0)
}
})
})
observer.observe(el, { attributes: true, attributeFilter: ['style'] })
document.addEventListener('pointerdown', e=>{
if(watching && getComputedStyle(el).visibility==='visible' && !el.contains(e.target)){
clearTimeout(hideTimer)
hideTimer = setTimeout(()=> el.style.visibility = 'hidden', 0)
}
})
el.addEventListener('pointerdown', e=>{
e.stopPropagation()
clearTimeout(hideTimer)
})
})
});
/* путь элементов */
document.querySelectorAll('#left-float [plugin-url], #right-float [plugin-url]').forEach((el) => {
el.pluginUrl = el.getAttribute('plugin-url');
el.classList.add('plugin-url');
el.removeAttribute('plugin-url');
});
/* редактирования заголовков */
window.addEventListener('load', function() {
const editable = document.querySelector('#mainTitle');
const observer = new MutationObserver(() => {
const txt = editable.textContent.replace(/\u00A0/g, ' ');
if (editable.innerHTML !== txt) {
const sel = window.getSelection();
const anchorNode = sel.anchorNode;
const anchorOffset = sel.anchorOffset;
observer.disconnect();
editable.textContent = txt;
const range = document.createRange();
let node = editable.firstChild || editable;
const offset = Math.min(anchorOffset, node.textContent.length);
range.setStart(node, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
observer.observe(editable, { childList: true, subtree: true, characterData: true });
}
});
if(editable && editable.nodeType === 1){
observer.observe(editable, { childList: true, subtree: true, characterData: true });
}
});