1195 lines
44 KiB
JavaScript
1195 lines
44 KiB
JavaScript
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('');"> / </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 });
|
||
}
|
||
});
|