2 Commits

41 changed files with 1618 additions and 561 deletions

View File

@@ -15,80 +15,10 @@
<content tclass="btitle" bclass="bfloat">
<ru><![CDATA[
<div>
текст текст текст текст текст текст текст текст текст текст текст тексритчрсотат текст текст текст текст </div>
<div>
 текст текст текст текст текыККПАФЦКАКПАМст текст текст текст текст текст текст текст урпкцуептекст текст текст
test1цыкцып
</div>
<div>
 текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст
</div>
<div>
<hr style="height: 5px; width: 50%; background: rgb(0, 0, 0); border: 0px;">
<br>
</div>
<div>
<table style="width: 50%; margin: 1px; float: left; border: 1px solid rgb(0, 0, 0); background-color: rgb(255, 255, 255); border-collapse: collapse;">
<tbody>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
</tbody>
</table>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div><br>
test2
</div>
]]></ru>
<lv><![CDATA[

View File

@@ -8,24 +8,12 @@
</general>
<!--Содержание страницы-->
<!--Левые блоки-->
<lblock>
<block url="/plugin/foto/" title="df" tclass="btitle" bclass="bfloat"/>
<block url="/plugin/plugintest/" title="кнерцу" tclass="btitle" bclass="bfloat"/>
<block url="/plugin/foto/" title="цкпм" tclass="btitle" bclass="bfloat"/>
</lblock>
<lblock/>
<!--Правые блоки-->
<rblock>
<block url="/plugin/plugintest/" title="a5ysd" tclass="btitle" bclass="bfloat"/>
</rblock>
<rblock/>
<!--Текст страницы-->
<content tclass="btitle" bclass="bfloat">
<ru><![CDATA[
<!--?php
header('Content-Type: text/html; charset=utf-8');
readfile(__DIR__ . '/DgrmJS-main/src/index.html');
?-->
text
]]></ru>
<ru/>
<lv><![CDATA[
echo file_get_contents(__DIR__ . '/DgrmJS-main/src/index.html');
]]></lv>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<page>
<general>
<!--Kлючевые слова-->
<keywords>
</keywords>
<!--Условия доступа-->
<access>
<read>
<users>
</users>
<groups>
</groups>
</read>
<edit>
<users>
</users>
<groups>
</groups>
</edit>
</access>
</general>
<!--Содержание страницы-->
<!--Основное меню-->
<mainmenu>
<item name="имя" url="урл" title="описание">
</item>
</mainmenu>
<!--Текст страницы-->
<content tclass="btitle" bclass="bfloat">
<ru>
<![CDATA[<div>
<h3>
Markdown
</h3>
<textarea id="md" style="width:100%; height:300px;">
# Заголовок
Тестовый абзац текста.
Здесь есть **жирный текст**, *курсив*, `моноширинный текст`.
Ссылка: [Перейти](https://example.com)
Список:
- пункт один
- пункт два
- пункт три
</textarea>
</div>
]]>
<![CDATA[<div>
<h3>
HTML
</h3>
<div id="html" style="width:100%; height:300px; border:1px solid #ccc; padding:5px; overflow:auto;">
<h1>
Заголовок
</h1>
<p>
Тестовый абзац текста.
Здесь есть
<strong>
жирный текст
</strong>
,
<em>
курсив
</em>
,
<code>
моноширинный текст
</code>
.
</p>
<p>
Ссылка:
<a href="https://example.com">
Перейти
</a>
</p>
<p>
Список:
</p>
<ul>
<li>
пункт один
</li>
<li>
пункт два
</li>
<li>
пункт три
</li>
</ul>
</div>
</div>
<script>
function updateHtml() {
document.getElementById('html').innerHTML = marked.parse(document.getElementById('md').value);
}
document.getElementById('md').addEventListener('input', updateHtml);
window.addEventListener('DOMContentLoaded', updateHtml);
</script>
]]>
</ru>
<lv><![CDATA[
<p>Uz šo brīdi šeit ne kā nav</p>
]]></lv>
<en><![CDATA[
<p>??????</p>
]]></en>
</content>
<rblock/>
<lblock/>
</page>

View File

@@ -8,95 +8,20 @@
</general>
<!--Содержание страницы-->
<!--Левые блоки-->
<lblock>
</lblock>
<lblock/>
<!--Правые блоки-->
<rblock>
</rblock>
<rblock/>
<!--Текст страницы-->
<content tclass="btitle" bclass="bfloat">
<ru><![CDATA[
<div>
текст текст текст текст текст текст текст текст текст текст текст тексритчрсотат текст текст текст текст </div>
<div>
 текст текст текст текст текыККПАФЦКАКПАМст текст текст текст текст текст текст текст урпкцуептекст текст текст
</div>
<div>
 текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст
</div>
<div>
<hr style="height: 5px; width: 50%; background: rgb(0, 0, 0); border: 0px;">
<br>
</div>
<div>
<table style="width: 50%; margin: 1px; float: left; border: 1px solid rgb(0, 0, 0); background-color: rgb(255, 255, 255); border-collapse: collapse;">
<tbody>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
<tr>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
<td style="padding: 1px; border: 1px solid rgb(0, 0, 0);">
</td>
</tr>
</tbody>
</table>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div><br>
</div>
]]></ru>
<ru>
<![CDATA[<div>
test1цыуквацыфавп
</div>]]><![CDATA[<div>
test2
</div>]]><![CDATA[<div>
test2
</div>]]>
</ru>
<lv><![CDATA[
<p>  cb <b>bbvcdjyfdyhyhdывепиwstdg</b></p>
]]></lv>

View File

@@ -32,6 +32,7 @@ window.touchY = 0;
* @return Promise Разрешается после загрузки всех скриптов плагина
*/
function includePlugin(plugin) {
console.log(plugin)
return jsonrpcRequest("includePlugin", { plugin })
.then(html => {
const div = document.createElement('div');
@@ -533,12 +534,12 @@ if(isPhone){
/** @brief Флаг, указывающий, были ли изменения в контенте */
window.contentIsEdit = false;
if (document.getElementById("content")) {
document.getElementById("content").addEventListener("input", function() {
window.contentIsEdit = true;
});
if (document.querySelectorAll(".content").length) {
document.querySelectorAll(".content").forEach(el => {
el.addEventListener("input", () => window.contentIsEdit = true);
const observer = new MutationObserver(() => window.contentIsEdit = true);
observer.observe(document.getElementById("content"), { childList: true, subtree: true });
observer.observe(el, { childList: true, subtree: true });
});
}
/** @brief Очередь сообщений для отображения */
@@ -737,29 +738,82 @@ let cou=1;
/**
* @brief Показать/скрыть HTML-код страницы в textarea
*/
function showHtmlCode() {
let lastType = 'html';
function showCode(type) {
let contents = document.getElementsByClassName("content");
let tex = document.getElementById("tex");
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 combined = "";
for (let i = 0; i < contents.length; i++) {
combined += "<![CDATA[" + contents[i].innerHTML + "]]>";
}
tex.value = combined;
tex.value = decodeHtmlEntities(tex.value);
if (type === 'html') {
tex.value = formatHTML(tex.value);
} else if (type === 'marked') {
tex.value = marked.parse(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";
if (sbe[i] != tex) sbe[i].style.visibility = "hidden";
}
tex.style.visibility = tex.style.visibility == "hidden" ? "visible" : "hidden";
lastType = type;
cou = 2;
} else {
document.getElementById("content").innerHTML=document.getElementById("tex").value;
document.getElementById("tex").style.visibility="hidden";
let text = tex.value;
let split = text.match(/<!\[CDATA\[(.*?)\]\]>/gs);
const centerFloat = document.querySelector('.center-float');
if (!centerFloat) return;
let need = split ? split.length : 1;
let floats = centerFloat.getElementsByClassName('bfloat');
while (floats.length < need) {
let bf = document.createElement('div');
bf.className = 'bfloat';
if (floats.length > 0) bf.style.borderRadius = "10px";
let c = document.createElement('div');
c.className = 'content';
c.contentEditable = 'true';
centerFloat.appendChild(bf);
bf.appendChild(c);
centerFloat.appendChild(document.createElement('br'));
floats = centerFloat.getElementsByClassName('bfloat');
}
while (floats.length > need) {
let next = floats[floats.length - 1].nextSibling;
if (next && next.tagName === 'BR') centerFloat.removeChild(next);
centerFloat.removeChild(floats[floats.length - 1]);
floats = centerFloat.getElementsByClassName('bfloat');
}
contents = centerFloat.getElementsByClassName("content");
if (split) {
for (let i = 0; i < need; i++) {
let val = split[i] ? split[i].replace(/<!\[CDATA\[|\]\]>/g, '') : '';
if (lastType === 'marked') val = '<div>' + marked.parse(val.replace(/^\s*<div[^>]*>|<\/div>\s*$/g, '')) + '</div>';
contents[i].innerHTML = val;
}
} else {
let val = text;
if (lastType === 'marked') val = '<div>' + marked.parse(val.replace(/^\s*<div[^>]*>|<\/div>\s*$/g, '')) + '</div>';
contents[0].innerHTML = val;
}
let children = Array.from(centerFloat.children);
for (let i = 0; i < children.length - 1; i++) {
let current = children[i];
let next = children[i + 1];
if (current.id !== 'mainTitle' && current.classList.contains('bfloat')) {
if (!(next && next.tagName === 'BR')) {
let br = document.createElement('br');
centerFloat.insertBefore(br, next);
}
}
}
tex.style.visibility = "hidden";
cou = 1;
}
}
window.showHtmlCode = showHtmlCode;
window.showCode = showCode;
/** @brief Флаг нового состояния страницы при сохранении */
window.newPageFunValue = "";
@@ -783,8 +837,10 @@ 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;
let contents = document.getElementsByClassName("content");
let combined = "";
for (let i = 0; i < contents.length; i++) combined += "<![CDATA[" + contents[i].innerHTML.trim() + "]]>";
document.getElementById("tex").value = combined;
}
document.getElementById("tex").value = decodeHtmlEntities(document.getElementById("tex").value);
let saveContentIdData = document.getElementById("tex").value.trim();
@@ -897,11 +953,10 @@ function formatHTML(html) {
*/
window.saveContentIdHow = async function (currentPath) {
if (cou == 1) {
document.getElementById("content").innerHTML = decodeHtmlEntities(document.getElementById("content").innerHTML);
document.getElementById("tex").value = document.getElementById("content").innerHTML;
let contents = Array.from(document.getElementsByClassName("content")).map(el => el.innerHTML.trim());
document.getElementById("tex").value = contents.map(c => `<![CDATA[${c}]]>`).join('');
}
document.getElementById("tex").value = decodeHtmlEntities(document.getElementById("tex").value);
let saveContentIdData = document.getElementById("tex").value.trim();
let saveContentIdData = decodeHtmlEntities(document.getElementById("tex").value).trim();
let nameFile = document.getElementById('saveHowName').value;
if (!nameFile.endsWith('.page.php')) {
nameFile += '.page.php';
@@ -1315,17 +1370,49 @@ window.functionOpenPage = false;
function getPage(newPath) {
window.functionOpenPage = true;
jsonrpcRequest("getPage", { newPath }).then(page => {
const centerFloat = document.querySelector('.center-float');
const oldBlocks = centerFloat.querySelectorAll('.bfloat');
oldBlocks.forEach(b => {
if (b.querySelector('.content')) {
const next = b.nextSibling;
if (next && next.nodeType === 1 && next.tagName === 'BR') next.remove();
if (next && next.nodeType === 3 && next.textContent.trim() === '') {
const next2 = next.nextSibling;
if (next2 && next2.nodeType === 1 && next2.tagName === 'BR') next2.remove();
}
b.remove();
}
});
page.content.forEach((c, i) => {
const placeholder = document.getElementById('news-placeholder');
if (i > 0) {
const br = document.createElement('br');
centerFloat.insertBefore(br, placeholder);
}
const block = document.createElement('div');
block.className = 'bfloat';
block.style.fontSize = '1em';
if (i !== 0) block.style.borderRadius = '10px';
const inner = document.createElement('div');
inner.className = 'content';
inner.innerHTML = c;
block.appendChild(inner);
centerFloat.insertBefore(block, placeholder);
});
document.getElementById("right-float").innerHTML = page.right;
document.getElementById("left-float").innerHTML = page.left;
document.getElementById("content").innerHTML = page.content;
document.getElementById("managerDiv").style.visibility = "hidden";
// history.pushState(null, '', page.pagePath);
document.getElementById("mainTitle").innerHTML = "<i>{{new_file}}!</i>";
removePluginDom("manager")
removePluginDom("manager");
});
window.newPageFunValue = "";
}
//обьявление функции для того, чтобы обращатся к ней из других файлов
window.getPage = getPage;
window.managerData = managerData;

View File

@@ -3,5 +3,13 @@
<sitename>RaspberryqePi</sitename>
<slogan>Raspberry Pi</slogan>
<index url='content/index' title='Sākuma lapa' name='index' template='rpi' PageMenu='0,1,2' users='' group=''>
<page1 url="content/rpi/index" title="Новый ф6нрцуеыкеа" name="page1" template="MedWait" PageMenu="0,1,2" users="" group="" news="" plugins="">
<underpage1 url="content/rpi/index" title="Загловок" name="underpage1" template="rpi" PageMenu="0,1,2" users="" group="" news="" plugins="">
</underpage1>
<underpage2 url="content/rpi/index" title="Загловок" name="underpage2" template="rpi" PageMenu="0,1,2" users="" group="" news="" plugins="SvgEditorM">
</underpage2>
<createSite url="data/createSite" title="Страница создание нового сайта" name="createSite" template="MedWait" PageMenu="0,1,2" users="" group="" news="" plugins="dgrm">
</createSite>
</page1>
</index>
</site>

View File

@@ -2,18 +2,20 @@
<site>
<sitename>site</sitename>
<slogan>site</slogan>
<index url="content/index" title="Новый ф6нрцуеыке" name="index" template="start" PageMenu="0,0" users="" group="" news="" plugins="">
<page1 url="content/rpi/index" title="Новый фрцуеыкеа" name="page1" template="MedWait" PageMenu="0,1,2" users="" group="" news="" plugins="">
<underpage1 url="content/rpi/index" title="Загловок" name="underpage1" template="rpi" PageMenu="0,1,2" users="" group="" news="" plugins="">
<index url="content/index" title="Новый ф6нрцуеыке" name="index" template="start" PageMenu="0,0" users="" group="" news="">
<page1 url="content/rpi/index" title="Новый файл" name="page1" template="MedWait" PageMenu="0,1,2" users="" group="" news="">
<underpage1 url="content/rpi/index" title="Загловок" name="underpage1" template="rpi" PageMenu="0,1,2" users="" group="" news="">
</underpage1>
<underpage2 url="content/rpi/index" title="Загловок" name="underpage2" template="rpi" PageMenu="0,1,2" users="" group="" news="" plugins="SvgEditorM">
<underpage2 url="content/rpi/index" title="Загловок" name="underpage2" template="rpi" PageMenu="0,1,2" users="" group="" news="">
</underpage2>
<createSite url="data/createSite" title="Страница создание нового сайта" name="createSite" template="MedWait" PageMenu="0,1,2" users="" group="" news="" plugins="dgrm">
<createSite url="data/createSite" title="Страница создание нового сайта" name="createSite" template="MedWait" PageMenu="0,1,2" users="" group="" news="">
</createSite>
</page1>
<page2 url="content/index" title="Загловок" name="page2" template="rpi" PageMenu="0,1,2" users="" group="" news="" plugins="dgrm,SvgEditorM">
<page2 url="content/index" title="Загловок" name="page2" template="rpi" PageMenu="0,1,2" users="" group="" news="">
</page2>
<uyr url="content/index" title="Новый syu6e5" name="uyr" template="MedWait" PageMenu="0,1,2" users="" group="" news="" plugins="">
<uyr url="content/index" title="Новый syu6e5" name="uyr" template="MedWait" PageMenu="0,1,2" users="" group="" news="">
</uyr>
<markdownMarkedJS url="content/markdownMarkedJS" title="markdownMarkedJS" name="markdownMarkedJS" template="MedWait" PageMenu="0,1,2" users="" group="" news="">
</markdownMarkedJS>
</index>
</site>

View File

@@ -307,17 +307,6 @@ function GetBlock ($BlockVar, $side) {
}
}
return $Block;
// $Block.='<div class="'.$BlockVar[$i]['bclass'].'"><div class="bcont">ku ku</div></div>';
/*is_countable($$BlockVar) && count($BlockVar)
$Block = "";
if (is_countable($$BlockVar) && count($BlockVar) > 0){
$Block = "true";
}
else{
$Block = "false";
}
$Block = count($BlockVar);*/
}
@@ -719,7 +708,6 @@ if (!isset($xmlstr->index)) {
$index->addAttribute('users', '');
$index->addAttribute('group', '');
$index->addAttribute('news', '');
$index->addAttribute('plugins', '');
$xmlstr->asXML($FPfile);
}
$ansv['sitename'] =$xmlstr->sitename;
@@ -746,7 +734,6 @@ if ($RURLstr!='error'){
$ansv['template'] = $xmlstr->{$RURLstr[$i]}['template'];
$ansv['title'] = $xmlstr->{$RURLstr[$i]}['title'];
$ansv['page'] = $xmlstr->{$RURLstr[$i]};
$ansv['page_plugins'] = (string)($xmlstr->{$RURLstr[$i]}['plugins'] ?? '');
}
$xmlstr = $xmlstr->{$RURLstr[$i]};
}
@@ -766,17 +753,17 @@ if ($RURLstr!='error'){
* @param mixed $RURLstr Массив сегментов URL или строка 'error'
* @return array Массив с информацией о странице, включая URL, шаблон, заголовок и плагины
*/
function loadPluginsInCenterBlock() {
/* function loadPluginsInCenterBlock() {
global $_SESSION, $path, $config;
if ($_SESSION['Login'] == 'true') {
$availablePlugins = ['dgrm', 'SvgEditorM'];
$availablePlugins = ['dgrm', 'SvgEditorM', 'form_editor'];
$pluginDir = $path . 'main_plugin/';
if (is_dir($pluginDir)) {
$dirs = array_diff(scandir($pluginDir), ['.', '..']);
foreach ($dirs as $dir) {
if (is_dir($pluginDir . $dir)) {
if (!in_array($dir, $availablePlugins) || strpos($config['page_plugins'] ?? '', $dir) !== false) {
if ($dir === 'SvgEditorM' || $dir === 'dgrm') {
if ($dir === 'SvgEditorM' || $dir === 'dgrm' || $dir === 'form_editor') {
$html .= includePlugin(['plugin' => $dir]);
}
}
@@ -784,7 +771,6 @@ function loadPluginsInCenterBlock() {
}
}
}
$html .= includePlugin(['plugin' => 'form_editor']);
return $html;
}
} */
?>

View File

@@ -0,0 +1,15 @@
<![CDATA[<div>
test1цыуквацыфавп
</div>]]><![CDATA[<div>
test2
</div>]]>
<![CDATA[<div>
test1цыуквацыфавп
</div>]]><![CDATA[<div>
test2
</div>]]>
<![CDATA[<div>
test1цыуквацыфавп
</div>]]><![CDATA[<div>
test2
</div>]]>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 738 KiB

After

Width:  |  Height:  |  Size: 739 KiB

View File

@@ -7,7 +7,7 @@
/** @brief Путь к текущей директории */
$path = dirname(__FILE__) . '/';
/* if(isset($_SESSION)) { file_put_contents($path . '/error.txt', "" . PHP_EOL, FILE_APPEND); }*/
/* file_put_contents($path . '/error.txt', "" . PHP_EOL, FILE_APPEND); */
session_start();
@@ -40,6 +40,12 @@ if (!isset($_SESSION['page_url'])) {
$_SESSION['page_url'] = $config['page_url'];
}
$pluginBlocks = ['dgrm', 'SvgEditorM', 'form_editor'];
$pluginBlocksPath = $path . 'main_plugin/';
$pluginBlocks = array_filter($pluginBlocks, function($block) use ($pluginBlocksPath) {
return is_dir($pluginBlocksPath . $block);
});
$methodRpc = null;
if ($_SERVER["REQUEST_METHOD"] === "POST" && strpos($_SERVER["CONTENT_TYPE"] ?? "", "application/json") !== false) {
@@ -150,7 +156,7 @@ if ($access) {
$config['right'] = "<div id='right-float'>" . $config['right'] . "</div>";
$center = '<div class="center-float">' . GetBlock($xmlstr->cblock->block, 'center') . '<div>';
$config['content'] = $xmlstr->content->{$config['lng']};
/* $config['content'] = $xmlstr->content->{$config['lng']}; */
} else {
if ($_SESSION['log_in']) {
$xmlstr = simplexml_load_file($path . 'content/adm/user.page.php');
@@ -161,7 +167,18 @@ if ($access) {
$config['left'] = '';
$config['right'] = '';
$center = '<div class="center-float">' . GetBlock($xmlstr->cblock->block, 'center') . '<div>';
$config['content'] = $xmlstr->content->$config['lng'];
/* $config['content'] = $xmlstr->content->{$config['lng']}; */
}
$xmlString = file_get_contents($path . $config['page_url'] . ".page.php");
preg_match('#<' . $config['lng'] . '>(.*?)</' . $config['lng'] . '>#s', $xmlString, $tagMatch);
$config['content'] = '';
if (preg_match_all('#<!\[CDATA\[(.*?)\]\]>#s', $tagMatch[1], $matches)) {
foreach ($matches[1] as $i => $cdata) {
if ($i > 0)
$config['content'] .= "<br>";
$config['content'] .= '<div class="%cfloat%" style="' . ($i == 0 ? '' : 'border-radius: 10px;') . '"><div class="content">' . $cdata . '</div></div>';
}
}
foreach ($config as $key=>$value) if ($key!="request_url")
$config['content'] =str_replace('%'.$key.'%', $value, $config['content']);
@@ -189,7 +206,7 @@ foreach ($lang[$lng] as $key => $value) {
}
$html .= '<script>' . $Js . '</script>';
$html .= loadPluginsInCenterBlock();
$html .= '<script src="/main_plugin/marked-master/marked.umd.js"></script>';
$html .= includePlugin(['plugin' => 'siteSettings']);
$html .= includePlugin(['plugin' => 'auth']);
/* $html .= includePlugin(['plugin' => 'editor']); */

View File

@@ -257,7 +257,7 @@ class Editor {
Инициализация (выполняется после загрузки DOM)
----------------------------- */
window.addEventListener('DOMContentLoaded', () => {
window.addEventListener('LoadSvgEditorMJs', () => {
let main = document.getElementById('main') || document.body;
let selection = document.getElementById('selector');

View File

@@ -8,18 +8,6 @@ global $path, $_SESSION, $configAdmins;
if (in_array($_SESSION['username'], $configAdmins, true)) {
include $path . 'main_plugin/SvgEditorM/index.php';
echo '<link rel="stylesheet" type="text/css" href="/main_plugin/SvgEditorM/SvgEditorM.css">';
echo "<script type='module'>
document.addEventListener('DOMContentLoaded', () => {
const c = document.querySelector('.center-float');
const d = document.getElementById('sidebar');
if (c && d) {
c.appendChild(document.createElement('br'));
c.appendChild(d);
import('/main_plugin/SvgEditorM/SvgEditorM.js');
} else if (d) {
d.remove();
}
});
</script>";
echo "<script type='module'>import('/main_plugin/SvgEditorM/SvgEditorM.js');</script>";
}
?>

View File

@@ -57,7 +57,7 @@ a {
}
textarea {
text-align: center;
/* text-align: center;
border: none;;
padding: 10px;
padding-top: 0.8em;
@@ -69,7 +69,7 @@ a {
overflow: hidden;
resize: none;
line-height: 1em;
caret-color: #fff;
caret-color: #fff; */
}
[data-connect] { display: none; }

View File

@@ -7,19 +7,7 @@
global $path, $_SESSION, $configAdmins;
if (in_array($_SESSION['username'], $configAdmins, true)) {
echo file_get_contents($path . 'main_plugin/dgrm/index.php');
echo "<script type='module'>
document.addEventListener('DOMContentLoaded', () => {
const c = document.querySelector('.center-float');
const d = document.getElementById('dgrmDiv');
if (c && d) {
c.appendChild(document.createElement('br'));
c.appendChild(d);
import('/main_plugin/dgrm/index.js');
} else if (d) {
d.remove();
}
});
</script>";
echo "<script type='module'>import('/main_plugin/dgrm/index.js');</script>";
echo '<link rel="stylesheet" type="text/css" href="/main_plugin/dgrm/dgrm.css">';
}
?>

View File

@@ -246,6 +246,9 @@
#toolbar-group-button-paste {
background-position: 166px 517px;
}
#toolbar-group-button-structure {
background-position: 166px 517px;
}
.align-dropdown, .align-dropdown-oneImg {
position: relative;
@@ -376,6 +379,10 @@
background-position: -318px 1824px;
}
#markedBut {
background-position: -318px 1824px;
}
#bac {
background-position: 645px 716px;
}
@@ -452,7 +459,7 @@
background-position: 1045px 557px;
}
/* #pluginSave {
#pluginSave {
background-position: -479px 1665px;
}
#pluginCreateLeft {
@@ -467,12 +474,15 @@
#pluginAddRight {
background-position: -638px 1665px;
}
#pluginAddCenter {
background-position: -838px 1665px;
}
#pluginDelete {
background-position: -518px 1665px;
}
#pluginMove {
background-position: -438px 1665px;
} */
}
#contentPageCreate {
background-position: 926px 676px;

View File

@@ -54,13 +54,13 @@ function basisVis() {
editableElementsFun();
let basis3 = document.getElementById('basis3');
let sideFloatClass = basis3 ? basis3.querySelectorAll('[style*="visibility: visible;"]') : null;
if (!basis3 || !sideFloatClass || !editableElements || editableElements.length === 0) return;
elementsСhecked = [basis3, ...sideFloatClass, ...editableElements];
if (!basis3 || !sideFloatClass || !window.editableElements || window.editableElements.length === 0) return;
let elementsСhecked = [basis3, ...sideFloatClass, ...window.editableElements];
if (basis3.style.visibility === "visible") {
basis3.style.visibility = "hidden";
sessionStorage.setItem('basis3_visibility', 'hidden');
editableElements.forEach(function(element) {
window.editableElements.forEach(function(element) {
if (element) {
element.setAttribute("contenteditable", false);
}
@@ -80,7 +80,7 @@ function basisVis() {
} else {
basis3.style.visibility = "visible";
sessionStorage.setItem('basis3_visibility', 'visible');
editableElements.forEach(function(element) {
window.editableElements.forEach(function(element) {
if (element) {
element.setAttribute("contenteditable", true);
}
@@ -91,19 +91,19 @@ function basisVis() {
basis3.style.transform = 'translate(0%, -20%)';
document.getElementById('bcbody').style.top = '30px';
document.querySelectorAll('.bfloat').forEach(e => e.style.fontSize = '1em')
}
}
window.basisVis = basisVis;
/** @brief Сбор всех редактируемых элементов */
function editableElementsFun() {
let content = document.getElementById('content');
editableElements = document.querySelectorAll('.pluginEditable');
editableElements = Array.from(editableElements);
editableElements.push(content);
window.editableElements = [];
let contents = document.querySelectorAll('.content');
let pluginEls = document.querySelectorAll('.pluginEditable');
pluginEls = Array.from(pluginEls);
window.editableElements.push(...pluginEls, ...contents);
editableElements.forEach(function(element) {
window.editableElements.forEach(function(element) {
if (!element) {
console.log("Element " + element + " not found.");
return;
@@ -111,31 +111,28 @@ function editableElementsFun() {
});
}
addEventListener("LoadeditorJs", function()
{
let te=document.getElementById("tex"); // Ссылка на текстовое поле
let tex=document.getElementById("tex"); // Ссылка на стили текстового поля
if (document.getElementById("content") == "") {
te.value=document.getElementById("content").innerHTML; // Передача данных из области контента в текстовое поле
}
// Передаём содержимое пустых блоков в поле
document.querySelectorAll('.content').forEach(el => {
if (!el.innerHTML) te.value = el.innerHTML;
});
// Символы клавиш со знаками препинания или перевода строки
let symb = ["Enter", "!", "?", ";", ":", ",", ".", " ", "-", "'", "\"", "(", ")", "{", "}", "[", "]", "_", "&", "/", "\\", "*"];
// Запись в память введенного текста при нажатии клавиши со знаком препинания или перевода строки
if (document.getElementById("content")) {
document.getElementById("content").addEventListener("keyup", function(ev)
{
for(let i=0; i<symb.length; i++)
{
if(symb[i]==ev.key)
inter();
document.querySelectorAll('.content').forEach(el => {
el.addEventListener('keyup', ev => {
for (let i = 0; i < symb.length; i++) {
if (symb[i] == ev.key) inter();
}
});
}
});
let sel = document.getSelection();
function selInContenteditable(insertType) {
@@ -418,7 +415,7 @@ function clo(c) // Функция закры
}
// действия блока плагинов
let pluginDropdownContentId = document.getElementById("pluginDropdownContent");
/* let pluginDropdownContentId = document.getElementById("pluginDropdownContent");
pluginDropdownContentId.addEventListener('click', function () {
let targetElement = document.getElementById(this.value);
if (targetElement) {
@@ -439,7 +436,7 @@ pluginDropdownContentId.addEventListener('click', function () {
if (editMode == -1) {
pluginDropdownContentId.style.backgroundColor = '';
}
});
}); */
// действия блока элементов
/* let elementDropdownContentId = document.getElementById("elementDropdownContent");
@@ -458,7 +455,7 @@ mainActionsId.addEventListener('click', function () {
switch (this.value) {
case "save":
saveChanges();
break;
break;fshowHtmlCode
case "saveHow":
saveChangesHow();
break;
@@ -497,78 +494,153 @@ document.getElementById("newPage").addEventListener("click", newPageFun);
function newPageFun() {
document.getElementById("right-float").innerHTML = "";
document.getElementById("left-float").innerHTML = "";
document.getElementById("content").innerHTML = "";
document.querySelectorAll('.content').forEach(el => el.innerHTML = "");
document.getElementById("mainTitle").innerHTML = "<i>{{new_file}}!</i>";
window.newPageFunValue = "newPage";
document.getElementById("settingsMain_d").style.visibility="hidden";
}
// Сохранение выделение
document.addEventListener('selectionchange', () => {
const content = document.getElementById('content');
const contents = document.querySelectorAll('.content');
if (!contents || contents.length === 0) return;
const sel = window.getSelection();
if (!sel.rangeCount) return;
const range = sel.getRangeAt(0);
const startNode = range.startContainer;
for (let content of contents) {
if (content.contains(startNode)) {
saveSelection();
break;
}
}
});
let savedSel = null;
function saveSelection() {
const content = document.getElementById('content');
const contents = document.querySelectorAll('.content');
const sel = window.getSelection();
if (!sel.rangeCount) return;
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return;
for (let content of contents) {
if (content.contains(range.commonAncestorContainer)) {
const pre = range.cloneRange();
pre.selectNodeContents(content);
pre.setEnd(range.startContainer, range.startOffset);
const start = pre.toString().length;
const end = start + range.toString().length;
savedSel = { start, end };
break;
}
}
}
function restoreSelection() {
if (!savedSel) return;
const content = document.getElementById('content');
const contents = document.querySelectorAll('.content');
const { start, end } = savedSel;
let charIndex = 0;
const range = document.createRange();
try {
for (const content of contents) {
range.setStart(content, 0);
range.collapse(true);
try {
(function traverse(node) {
if (node.nodeType === Node.TEXT_NODE) {
const next = charIndex + node.length;
if (charIndex <= start && next >= start) {
range.setStart(node, start - charIndex);
}
if (charIndex <= start && next >= start) range.setStart(node, start - charIndex);
if (charIndex <= end && next >= end) {
range.setEnd(node, end - charIndex);
throw 'done';
}
charIndex = next;
} else {
node.childNodes.forEach(traverse);
}
} else node.childNodes.forEach(traverse);
})(content);
}
} catch (e) {}
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
/* плагины для центра */
document.getElementById('pluginAddCenter').onclick = function pluginFunCenter() {
jsonrpcRequest('getPluginBlocks', {})
.then(folders => {
const pluginAddSideName = document.getElementById('pluginAddCenterName');
pluginAddSideName.innerHTML = '';
folders.forEach(folder => {
const option = document.createElement('option');
option.value = folder;
option.textContent = folder;
pluginAddSideName.appendChild(option);
});
});
};
document.getElementById('pluginAddCenterFun_d').addEventListener('click', function() {
const select = document.getElementById('pluginAddCenterName');
const pluginName = select.value;
if (!pluginName) return;
if (document.querySelector('.' + pluginName)) return;
includePluginBlock(pluginName).then(fragment => {
const centerFloat = document.querySelector('.center-float');
if (!centerFloat) return;
const wrapper = document.createElement('div');
wrapper.setAttribute('pluginblock', pluginName);
wrapper.appendChild(document.createElement('br'));
const scripts = [];
Array.from(fragment.childNodes).forEach(node => {
if (node.tagName === 'SCRIPT') {
const s = document.createElement('script');
if (node.src) {
s.src = node.src;
s.async = false;
scripts.push(new Promise(res => s.onload = res));
} else {
s.textContent = node.textContent;
}
document.body.appendChild(s);
} else {
wrapper.appendChild(node);
}
});
centerFloat.appendChild(wrapper);
Promise.all(scripts).then(() => {
const event = new Event("Load" + pluginName + "Js");
document.dispatchEvent(event);
window.dispatchEvent(event);
});
});
});
// Пример изменения includePlugin
function includePluginBlock(plugin) {
return jsonrpcRequest("includePlugin", { plugin })
.then(html => {
const frag = document.createDocumentFragment();
const temp = document.createElement('div');
temp.innerHTML = html;
Array.from(temp.childNodes).forEach(node => {
if (node.nodeType === 1) node.setAttribute('plugin', plugin);
frag.appendChild(node);
});
return frag;
});
}
// Взаимодействие с плагинами
/* document.getElementById('pluginCreateLeft').onclick = function() { pluginFun('create', 'left'); };
document.getElementById('pluginCreateRight').onclick = function() { pluginFun('create', 'right'); }; */
document.getElementById('pluginAddLeft').onclick = function() { pluginFun('add', 'left'); };
document.getElementById('pluginAddRight').onclick = function() { pluginFun('add', 'right'); };
/* document.getElementById('pluginRulesButton1').onclick = function() { pluginRulesFun('pluginRulesBlock1'); };
document.getElementById('pluginRulesButton2').onclick = function() { pluginRulesFun('pluginRulesBlock2'); }; */
@@ -738,7 +810,7 @@ function editFun3(i) {
function editFun4(i) {
}
function editFun5(i) {
pluginDropdownContentId.style.backgroundColor = '';
/* pluginDropdownContentId.style.backgroundColor = ''; */
}
let pluginTakeCheck = 0;
@@ -1457,14 +1529,14 @@ const singleFormats = [
const specialFormats = ['butlink', 'linkdel', 'forma', 'col', 'backgr'];
addEventListener("LoadeditorJs", function() {
const content = document.getElementById('content');
const content = document.querySelectorAll('.content');
simpleFormats.forEach(f => {
document.getElementById(f.id).addEventListener('click', () => {
const sel = window.getSelection();
if (!sel.rangeCount) return;
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return;
if (![...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) return;
let all = true;
const it = document.createNodeIterator(
range.commonAncestorContainer,
@@ -1495,7 +1567,7 @@ divFormats.forEach(f => {
const sel = window.getSelection();
if (!sel.rangeCount) return;
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return;
if (![...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) return;
divApplyformat(range, f);
inter();
});
@@ -1506,7 +1578,7 @@ listFormats.forEach(f => {
const sel = window.getSelection();
if (!sel.rangeCount) return;
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return;
if (![...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) return;
listApplyformat(range, f);
inter();
});
@@ -1523,7 +1595,7 @@ singleFormats.forEach(f => {
const sel = window.getSelection()
if (!sel.rangeCount) return
const range = sel.getRangeAt(0)
if (!content.contains(range.commonAncestorContainer)) return
if (![...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) return;
singleApplyformat(range, f)
inter()
})
@@ -1534,7 +1606,7 @@ specialFormats.forEach(f => {
const sel = window.getSelection();
if (!sel.rangeCount) return;
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return;
if (![...content].some(c => c.contains(range.commonAncestorContainer))) return;
if (typeof document[f + 'Fun'] === 'function') document[f + 'Fun'](range);
else window[f + 'Fun'](range);
inter();
@@ -1543,12 +1615,15 @@ specialFormats.forEach(f => {
const events = ['pointerup','keyup','input','focus','blur','click'];
events.forEach(evt => {
if (!content) return;
const contents = document.querySelectorAll('.content');
if (!contents || contents.length === 0) return;
contents.forEach(content => {
content.addEventListener(evt, () => {
updateToolbarStyles();
updateSingleSelectors();
});
});
});
}, { once: true });
@@ -1561,7 +1636,8 @@ let currentIndex = 0
/** @brief Сохраняет текущее состояние контента, если оно изменилось */
function inter() {
const editable = document.getElementById("content")
const editables = document.querySelectorAll(".content")
editables.forEach(editable => {
if (editable) {
let currentContent = editable.innerHTML
if (currentContent !== arr[currentIndex]) {
@@ -1570,27 +1646,32 @@ function inter() {
arr.push(currentContent)
}
}
})
}
if (document.getElementById("content")) {
arr[0] = document.getElementById("content").innerHTML
}
document.querySelectorAll(".content").forEach((editable, i) => {
if (i === 0) arr[0] = editable.innerHTML
})
document.getElementById("forw").addEventListener("click", function() {
if (currentIndex < arr.length - 1) {
currentIndex++
const editable = document.getElementById("content")
const editables = document.querySelectorAll(".content")
editables.forEach(editable => {
editable.innerHTML = arr[currentIndex]
editable.setAttribute("contenteditable", "true")
})
}
})
document.getElementById("bac").addEventListener("click", function() {
if (currentIndex > 0) {
currentIndex--
const editable = document.getElementById("content")
const editables = document.querySelectorAll(".content")
editables.forEach(editable => {
editable.innerHTML = arr[currentIndex]
editable.setAttribute("contenteditable", "true")
})
}
})
@@ -1785,9 +1866,11 @@ function divApplyformat(range, format) {
range.compareBoundaryPoints(Range.START_TO_END, er) > 0;
};
Array.from(document.querySelectorAll('.content')).forEach(content => {
Array.from(content.children).forEach(child => {
if (intersects(child)) externals.add(child);
});
});
externals.forEach(div => {
div.style.textAlign = style.textAlign;
@@ -1811,9 +1894,11 @@ function listApplyformat(range, format) {
if (type === 'listNone') {
const lists = new Set();
Array.from(document.querySelectorAll('.content')).forEach(content => {
Array.from(content.querySelectorAll('li')).forEach(li => {
if (intersects(li)) lists.add(li.parentNode);
});
});
lists.forEach(list => {
const parent = list.parentNode;
@@ -1849,6 +1934,7 @@ function listApplyformat(range, format) {
parent.removeChild(list);
});
} else {
Array.from(document.querySelectorAll('.content')).forEach(content => {
const items = Array.from(content.children).filter(child => intersects(child));
if (!items.length) return;
@@ -1875,6 +1961,7 @@ function listApplyformat(range, format) {
listEl.appendChild(li);
}
});
});
}
}
@@ -1959,13 +2046,16 @@ function formaFun(range) {
return range.compareBoundaryPoints(Range.END_TO_START, er) < 0
&& range.compareBoundaryPoints(Range.START_TO_END, er) > 0;
};
Array.from(document.querySelectorAll('.content')).forEach(content => {
Array.from(content.children).forEach(child => {
if (intersects(child)) externals.add(child);
});
});
externals.forEach(el => {
el.style.textAlign = '';
});
Array.from(document.querySelectorAll('.content')).forEach(content => {
const itList = document.createNodeIterator(
content,
NodeFilter.SHOW_ELEMENT,
@@ -1985,6 +2075,7 @@ function formaFun(range) {
});
parent.removeChild(listEl);
}
});
function unwrapAllSpansAndLinks(node) {
const frag = document.createDocumentFragment();
@@ -2079,7 +2170,7 @@ function detectFormatState(format) {
const sel = window.getSelection();
if (!sel.rangeCount) return 'none';
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return 'none';
if (![...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) return 'none';
const it = document.createNodeIterator(
range.commonAncestorContainer,
NodeFilter.SHOW_TEXT,
@@ -2091,7 +2182,7 @@ function detectFormatState(format) {
if (!text) continue;
total++;
let cur = node.parentElement, ok = false;
while (cur && cur !== content) {
while (cur && ![...document.querySelectorAll('.content')].includes(cur)) {
const fmt = simpleFormats.find(f => f.id === format);
const v = fmt ? getComputedStyle(cur)[fmt.prop] || '' : '';
if (fmt && fmt.test(v)) { ok = true; break; }
@@ -2128,7 +2219,7 @@ function detectSingleState(format) {
const sel = window.getSelection();
if (!sel.rangeCount) return '';
const range = sel.getRangeAt(0);
if (!content.contains(range.commonAncestorContainer)) return '';
if (![...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) return '';
const it = document.createNodeIterator(
range.commonAncestorContainer,
NodeFilter.SHOW_TEXT,
@@ -2190,20 +2281,23 @@ addEventListener("LoadeditorJs", function()
document.querySelectorAll("#panel .toolbar-group").forEach(g => {
const btn = g.querySelector(".toolbar-group-button");
const content = g.querySelector(".toolbar-group-content");
if (btn && content) {
btn.addEventListener("click", () => {
const toggle = () => {
const isHidden = content.style.display === "none";
content.style.display = isHidden ? "" : "none";
const hidden = content.style.display === "none";
g.classList.toggle("open", !hidden);
};
if (btn && content) {
const isHidden = content.style.display === "none";
g.classList.toggle("open", !isHidden);
}
btn.addEventListener("click", e => {
toggle();
});
g.addEventListener("click", e => {
if (e.target === g) toggle();
});
if (btn && content) {
const isHidden = content.style.display === "none";
g.classList.toggle("open", !isHidden);
}
}
});
document.querySelectorAll('.swit').forEach(btn => {
@@ -2263,7 +2357,7 @@ document.querySelectorAll('.align-dropdown-text').forEach(dropdown => {
const sel = window.getSelection()
if (sel.rangeCount) {
const range = sel.getRangeAt(0)
if (content.contains(range.commonAncestorContainer)) {
if ([...document.querySelectorAll('.content')].some(c => c.contains(range.commonAncestorContainer))) {
singleApplyformat(range, f)
inter()
}

View File

@@ -156,6 +156,16 @@
</div>
</div>
<?php /** @brief Список выбора плагина в ентре */ $pluginAddCenter_d; ?>
<div id="pluginAddCenter_d" class="cust sb borderStyle">
<div class="deploy">
{{add_plugin_center}}:<br>
<label for="pluginAddCenterName">{{select_plugin}}</label>
<select id="pluginAddCenterName" class="sele"></select>
<button id="pluginAddCenterFun_d" class="butin">{{select}}</button>
</div>
</div>
<?php /** @brief Редактирование меню страницы */ $contentPageCreate_d; ?>
<div id="contentPageCreate_d" class="cust sb borderStyle">
<div class="deploy">
@@ -201,7 +211,8 @@
<span class="toolbar-group-content">
<div id="settingsMain" class="editi editib swit"></div>
<div id="htm" onclick="showHtmlCode()" class="editi editib pers" alt="{{html_code_main_block_alt}}" title="{{html_code_main_block_title}}"></div>
<div id="htm" onclick="showCode('html')" class="editi editib pers" alt="{{html_code_main_block_alt}}" title="{{html_code_main_block_title}}"></div>
<!-- <div id="markedBut" onclick="showCode('marked')" class="editi editib pers" alt="{{marked_code_main_block_alt}}" title="{{marked_code_main_block_title}}"></div> -->
<div id="bac" class="editi editib pers" alt="{{undo_action_alt}}" title="{{undo_action_title}}"></div>
<div id="forw" class="editi editib pers" alt="{{redo_action_alt}}" title="{{redo_action_title}}"></div>
@@ -283,16 +294,21 @@
<div id="hr" class="editi editib pers editf"></div>
<div id="tabl" class="editi editib pers editf"></div>
<div id="copyr" class="editi editib swit"></div>
<select id="pluginDropdownContent" class="edits pers3">
<option id="pluginAddLeft" value="pluginAddLeft" class="swit">{{add_plugin_left}}</option>
<option id="pluginAddRight" value="pluginAddRight" class="swit">{{add_plugin_right}}</option>
<option id="pluginDelete" value="pluginDelete" class="editfText">{{delete_plugin}}</option>
<option id="pluginMove" value="pluginMove" class="editfText">{{move_plugin}}</option>
</select>
</span>
</div>
<div class="toolbar-group">
<span id="toolbar-group-button-structure" class="editi editib pers toolbar-group-button"></span>
<span class="toolbar-group-content">
<div id="pluginAddLeft" class="editi editib swit editf"></div>
<div id="pluginAddRight" class="editi editib swit editf"></div>
<div id="pluginAddCenter" class="editi editib swit editf"></div>
<div id="pluginDelete" class="editi editib pers editf"></div>
<div id="pluginMove" class="editi editib pers editf"></div>
</span>
</div>
</div><div id="arrow-right" class="arrow borderStyle">&vrtri;</div></div>
<!-- текстовый редактор -->

View File

@@ -14,20 +14,14 @@ function savePageCenterBlock($params) {
global $config, $path, $_SESSION;
$saveContentIdXml = $path . $_SESSION['page_url'] . ".page.php";
$saveContentIdData = $params['saveContentIdData'] ?? '';
$file = @simplexml_load_file($saveContentIdXml);
$node = $file->content->{$_SESSION['lng']};
$saveContentIdData = html_entity_decode($params['saveContentIdData'] ?? '', ENT_QUOTES, 'UTF-8');
$file->content->{$_SESSION['lng']} = '';
$node = dom_import_simplexml($node);
$doc = $node->ownerDocument;
$appended = $node->appendChild($doc->createCDATASection("\n" . $saveContentIdData . "\n"));
$saved = $file->asXML($saveContentIdXml);
$xml = file_get_contents($saveContentIdXml);
if ($appended && $saved) {
return 'true';
}
$xml = preg_replace('#<' . $_SESSION['lng'] . '>.*?</' . $_SESSION['lng'] . '>#s', '<' . $_SESSION['lng'] . '></' . $_SESSION['lng'] . '>', $xml);
$xml = preg_replace('#(<' . $_SESSION['lng'] . '>)#', "$1\n" . $saveContentIdData . "\n", $xml, 1);
if (file_put_contents($saveContentIdXml, $xml) !== false) return 'true';
throw new Exception("Problem saving content", -32003);
}
@@ -130,40 +124,34 @@ function saveHowPageContent($params) {
$_SESSION['page_url'] = $params['page_url'] . str_replace('.page.php', '', $params['nameFile']);
$filePath = $path . $params['page_url'] . $params['nameFile'];
$contentData = $params['saveContentIdData'] ?? '';
$file = simplexml_load_file($filePath);
$langNode = $file->content->{$_SESSION['lng']};
$file->content->{$_SESSION['lng']} = '';
$node = dom_import_simplexml($langNode);
$doc = $node->ownerDocument;
$node->appendChild($doc->createCDATASection("\n" . $contentData . "\n"));
$contentData = html_entity_decode($params['saveContentIdData'] ?? '', ENT_QUOTES, 'UTF-8');
$xml = file_get_contents($filePath);
$xml = preg_replace('#<' . $_SESSION['lng'] . '>.*?</' . $_SESSION['lng'] . '>#s', '<' . $_SESSION['lng'] . '></' . $_SESSION['lng'] . '>', $xml);
$xml = preg_replace('#(<' . $_SESSION['lng'] . '>)#', "$1\n" . $contentData . "\n", $xml, 1);
$xml = preg_replace('#<rblock>.*?</rblock>#s', '<rblock></rblock>', $xml);
$xml = preg_replace('#<lblock>.*?</lblock>#s', '<lblock></lblock>', $xml);
$file->rblock = '';
$file->lblock = '';
$blocks = $params['floatsBlock'] ?? [];
$titles = $params['title'] ?? [];
$urls = $params['pluginUrl'] ?? [];
$tclasses = $params['tclass'] ?? [];
$bclasses = $params['bclass'] ?? [];
foreach ($blocks as $i => $blockName) {
$newBlock = $file->$blockName->addChild('block');
$newBlock->addAttribute('url', htmlspecialchars($urls[$i] ?? '', ENT_QUOTES,'UTF-8'));
$newBlock->addAttribute('title', htmlspecialchars($titles[$i] ?? '', ENT_QUOTES,'UTF-8'));
$newBlock->addAttribute('tclass',htmlspecialchars($tclasses[$i] ?? '',ENT_QUOTES,'UTF-8'));
$newBlock->addAttribute('bclass',htmlspecialchars($bclasses[$i] ?? '',ENT_QUOTES,'UTF-8'));
$url = htmlspecialchars($urls[$i] ?? '', ENT_QUOTES, 'UTF-8');
$title = htmlspecialchars($titles[$i] ?? '', ENT_QUOTES, 'UTF-8');
$tclass = htmlspecialchars($tclasses[$i] ?? '', ENT_QUOTES, 'UTF-8');
$bclass = htmlspecialchars($bclasses[$i] ?? '', ENT_QUOTES, 'UTF-8');
$blockXml = '<block url="' . $url . '" title="' . $title . '" tclass="' . $tclass . '" bclass="' . $bclass . '"/>';
$xml = preg_replace('#<' . $blockName . '>#', '<' . $blockName . '>' . "\n" . $blockXml, $xml, 1);
}
$dom = new DOMDocument('1.0','UTF-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($file->asXML());
$saved = $dom->save($filePath);
if ($saved === false) {
if (file_put_contents($filePath, $xml) !== false) return 'true';
throw new Exception("Failed to save content", -32003);
}
return 'true';
}
/**
* @brief Создаёт новую страницу на основе шаблона
@@ -184,11 +172,12 @@ function createNewPage($params) {
}
$file = simplexml_load_file($saveContentIdXml);
$node = $file->content->{$_SESSION['lng']};
$file->content->{$_SESSION['lng']} = '';
foreach ($file->content->{$_SESSION['lng']} as $node) {
$node = dom_import_simplexml($node);
$no = $node->ownerDocument;
while ($node->firstChild) $node->removeChild($node->firstChild);
$node->appendChild($no->createCDATASection("\n" . $saveContentIdData . "\n"));
}
$saved = $file->asXML($saveContentIdXml);
if ($saved === false) {
@@ -263,6 +252,20 @@ function getPlugin($params) {
return ob_get_clean();
}
/**
* Возвращает список доступных плагинов в виде JSON
* @param array $params Входные параметры запроса (не используются)
* @return string JSON-массив с названиями плагинов
* @throws Exception Если глобальная переменная $pluginBlocks не определена или пуста
*/
function getPluginBlocks($params) {
global $pluginBlocks;
if (!isset($pluginBlocks) || !is_array($pluginBlocks) || empty($pluginBlocks)) {
throw new Exception("Нет доступных плагинов", -1);
}
return $pluginBlocks;
}
/**
* @brief Загружает изображение пользователя из Base64 и сохраняет на сервер
* @param array $params Массив с данными изображения, включая 'userImgBase64' и 'userImgName'

View File

@@ -17,5 +17,5 @@ foreach ($lang[$lng] as $key => $value) {
$placeholders['{{' . $key . '}}'] = $value;
}
echo 'window.addEventListener("load", function() {' . strtr(file_get_contents($path . 'form_editor.js'), $placeholders) . '});';
echo 'window.addEventListener("Loadform_editorJs", function() {' . strtr(file_get_contents($path . 'form_editor.js'), $placeholders) . '});';
?>

View File

@@ -13,27 +13,11 @@ $lang = include $path . 'main_plugin/form_editor/lang.php';
$lng = $_SESSION['lng'] ?? 'en';
if (in_array($_SESSION['username'], $configAdmins, true)) {
$Html = file_get_contents($path . 'main_plugin/form_editor/form_editor.php');
foreach ($lang[$lng] as $key => $value) {
$Html = str_replace('{{' . $key . '}}', $value, $Html);
}
echo $Html;
echo "<script>
document.addEventListener('DOMContentLoaded', () => {
const c = document.querySelector('.center-float');
const d = document.getElementById('formEditor');
if (c && d) {
c.appendChild(document.createElement('br'));
c.appendChild(d);
} else if (d) {
d.remove();
}
});
</script>";
echo '<link rel="stylesheet" type="text/css" href="/main_plugin/form_editor/form_editor.css">';
echo '<script type="text/javascript" src="/main_plugin/form_editor/lang.js.php?lng=' . $lng . '"></script>';
}

View File

@@ -254,7 +254,15 @@ function getPage($params) {
$page = [];
$page['right'] = GetBlock($pageXml->rblock->block, 'right');
$page['left'] = GetBlock($pageXml->lblock->block, 'left');
$page['content'] = (string)$pageXml->content->{$_SESSION['lng']};
$xmlContent = file_get_contents($file);
$lng = $_SESSION['lng'];
preg_match('#<' . $lng . '>(.*?)</' . $lng . '>#s', $xmlContent, $block);
$langBlock = $block[1] ?? '';
preg_match_all('#<!\[CDATA\[(.*?)\]\]>#s', $langBlock, $matches);
$contents = $matches[1] ?? [];
$page['content'] = $contents;
$_SESSION['page_url'] = $rel;
session_write_close();
return $page;

753
main_plugin/marked-master/marked.d.ts vendored Normal file
View File

@@ -0,0 +1,753 @@
// Generated by dts-bundle-generator v9.5.1
export type MarkedToken = (Tokens.Blockquote | Tokens.Br | Tokens.Checkbox | Tokens.Code | Tokens.Codespan | Tokens.Def | Tokens.Del | Tokens.Em | Tokens.Escape | Tokens.Heading | Tokens.Hr | Tokens.HTML | Tokens.Image | Tokens.Link | Tokens.List | Tokens.ListItem | Tokens.Paragraph | Tokens.Space | Tokens.Strong | Tokens.Table | Tokens.Tag | Tokens.Text);
export type Token = (MarkedToken | Tokens.Generic);
export declare namespace Tokens {
interface Blockquote {
type: "blockquote";
raw: string;
text: string;
tokens: Token[];
}
interface Br {
type: "br";
raw: string;
}
interface Checkbox {
type: "checkbox";
raw: string;
checked: boolean;
}
interface Code {
type: "code";
raw: string;
codeBlockStyle?: "indented";
lang?: string;
text: string;
escaped?: boolean;
}
interface Codespan {
type: "codespan";
raw: string;
text: string;
}
interface Def {
type: "def";
raw: string;
tag: string;
href: string;
title: string;
}
interface Del {
type: "del";
raw: string;
text: string;
tokens: Token[];
}
interface Em {
type: "em";
raw: string;
text: string;
tokens: Token[];
}
interface Escape {
type: "escape";
raw: string;
text: string;
}
interface Generic {
[index: string]: any;
type: string;
raw: string;
tokens?: Token[];
}
interface Heading {
type: "heading";
raw: string;
depth: number;
text: string;
tokens: Token[];
}
interface Hr {
type: "hr";
raw: string;
}
interface HTML {
type: "html";
raw: string;
pre: boolean;
text: string;
block: boolean;
}
interface Image {
type: "image";
raw: string;
href: string;
title: string | null;
text: string;
tokens: Token[];
}
interface Link {
type: "link";
raw: string;
href: string;
title?: string | null;
text: string;
tokens: Token[];
}
interface List {
type: "list";
raw: string;
ordered: boolean;
start: number | "";
loose: boolean;
items: ListItem[];
}
interface ListItem {
type: "list_item";
raw: string;
task: boolean;
checked?: boolean;
loose: boolean;
text: string;
tokens: Token[];
}
interface Paragraph {
type: "paragraph";
raw: string;
pre?: boolean;
text: string;
tokens: Token[];
}
interface Space {
type: "space";
raw: string;
}
interface Strong {
type: "strong";
raw: string;
text: string;
tokens: Token[];
}
interface Table {
type: "table";
raw: string;
align: Array<"center" | "left" | "right" | null>;
header: TableCell[];
rows: TableCell[][];
}
interface TableCell {
text: string;
tokens: Token[];
header: boolean;
align: "center" | "left" | "right" | null;
}
interface TableRow<P = string> {
text: P;
}
interface Tag {
type: "html";
raw: string;
inLink: boolean;
inRawBlock: boolean;
text: string;
block: boolean;
}
interface Text {
type: "text";
raw: string;
text: string;
tokens?: Token[];
escaped?: boolean;
}
}
export type Links = Record<string, Pick<Tokens.Link | Tokens.Image, "href" | "title">>;
export type TokensList = Token[] & {
links: Links;
};
/**
* Renderer
*/
declare class _Renderer<ParserOutput = string, RendererOutput = string> {
options: MarkedOptions<ParserOutput, RendererOutput>;
parser: _Parser<ParserOutput, RendererOutput>;
constructor(options?: MarkedOptions<ParserOutput, RendererOutput>);
space(token: Tokens.Space): RendererOutput;
code({ text, lang, escaped }: Tokens.Code): RendererOutput;
blockquote({ tokens }: Tokens.Blockquote): RendererOutput;
html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput;
def(token: Tokens.Def): RendererOutput;
heading({ tokens, depth }: Tokens.Heading): RendererOutput;
hr(token: Tokens.Hr): RendererOutput;
list(token: Tokens.List): RendererOutput;
listitem(item: Tokens.ListItem): RendererOutput;
checkbox({ checked }: Tokens.Checkbox): RendererOutput;
paragraph({ tokens }: Tokens.Paragraph): RendererOutput;
table(token: Tokens.Table): RendererOutput;
tablerow({ text }: Tokens.TableRow<ParserOutput>): RendererOutput;
tablecell(token: Tokens.TableCell): RendererOutput;
/**
* span level renderer
*/
strong({ tokens }: Tokens.Strong): RendererOutput;
em({ tokens }: Tokens.Em): RendererOutput;
codespan({ text }: Tokens.Codespan): RendererOutput;
br(token: Tokens.Br): RendererOutput;
del({ tokens }: Tokens.Del): RendererOutput;
link({ href, title, tokens }: Tokens.Link): RendererOutput;
image({ href, title, text, tokens }: Tokens.Image): RendererOutput;
text(token: Tokens.Text | Tokens.Escape): RendererOutput;
}
/**
* TextRenderer
* returns only the textual part of the token
*/
declare class _TextRenderer<RendererOutput = string> {
strong({ text }: Tokens.Strong): RendererOutput;
em({ text }: Tokens.Em): RendererOutput;
codespan({ text }: Tokens.Codespan): RendererOutput;
del({ text }: Tokens.Del): RendererOutput;
html({ text }: Tokens.HTML | Tokens.Tag): RendererOutput;
text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag): RendererOutput;
link({ text }: Tokens.Link): RendererOutput;
image({ text }: Tokens.Image): RendererOutput;
br(): RendererOutput;
checkbox({ raw }: Tokens.Checkbox): RendererOutput;
}
/**
* Parsing & Compiling
*/
declare class _Parser<ParserOutput = string, RendererOutput = string> {
options: MarkedOptions<ParserOutput, RendererOutput>;
renderer: _Renderer<ParserOutput, RendererOutput>;
textRenderer: _TextRenderer<RendererOutput>;
constructor(options?: MarkedOptions<ParserOutput, RendererOutput>);
/**
* Static Parse Method
*/
static parse<ParserOutput = string, RendererOutput = string>(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>): ParserOutput;
/**
* Static Parse Inline Method
*/
static parseInline<ParserOutput = string, RendererOutput = string>(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>): ParserOutput;
/**
* Parse Loop
*/
parse(tokens: Token[]): ParserOutput;
/**
* Parse Inline Tokens
*/
parseInline(tokens: Token[], renderer?: _Renderer<ParserOutput, RendererOutput> | _TextRenderer<RendererOutput>): ParserOutput;
}
declare const other: {
codeRemoveIndent: RegExp;
outputLinkReplace: RegExp;
indentCodeCompensation: RegExp;
beginningSpace: RegExp;
endingHash: RegExp;
startingSpaceChar: RegExp;
endingSpaceChar: RegExp;
nonSpaceChar: RegExp;
newLineCharGlobal: RegExp;
tabCharGlobal: RegExp;
multipleSpaceGlobal: RegExp;
blankLine: RegExp;
doubleBlankLine: RegExp;
blockquoteStart: RegExp;
blockquoteSetextReplace: RegExp;
blockquoteSetextReplace2: RegExp;
listReplaceTabs: RegExp;
listReplaceNesting: RegExp;
listIsTask: RegExp;
listReplaceTask: RegExp;
listTaskCheckbox: RegExp;
anyLine: RegExp;
hrefBrackets: RegExp;
tableDelimiter: RegExp;
tableAlignChars: RegExp;
tableRowBlankLine: RegExp;
tableAlignRight: RegExp;
tableAlignCenter: RegExp;
tableAlignLeft: RegExp;
startATag: RegExp;
endATag: RegExp;
startPreScriptTag: RegExp;
endPreScriptTag: RegExp;
startAngleBracket: RegExp;
endAngleBracket: RegExp;
pedanticHrefTitle: RegExp;
unicodeAlphaNumeric: RegExp;
escapeTest: RegExp;
escapeReplace: RegExp;
escapeTestNoEncode: RegExp;
escapeReplaceNoEncode: RegExp;
unescapeTest: RegExp;
caret: RegExp;
percentDecode: RegExp;
findPipe: RegExp;
splitPipe: RegExp;
slashPipe: RegExp;
carriageReturn: RegExp;
spaceLine: RegExp;
notSpaceStart: RegExp;
endingNewline: RegExp;
listItemRegex: (bull: string) => RegExp;
nextBulletRegex: (indent: number) => RegExp;
hrRegex: (indent: number) => RegExp;
fencesBeginRegex: (indent: number) => RegExp;
headingBeginRegex: (indent: number) => RegExp;
htmlBeginRegex: (indent: number) => RegExp;
};
declare const blockNormal: {
blockquote: RegExp;
code: RegExp;
def: RegExp;
fences: RegExp;
heading: RegExp;
hr: RegExp;
html: RegExp;
lheading: RegExp;
list: RegExp;
newline: RegExp;
paragraph: RegExp;
table: RegExp;
text: RegExp;
};
export type BlockKeys = keyof typeof blockNormal;
declare const inlineNormal: {
_backpedal: RegExp;
anyPunctuation: RegExp;
autolink: RegExp;
blockSkip: RegExp;
br: RegExp;
code: RegExp;
del: RegExp;
emStrongLDelim: RegExp;
emStrongRDelimAst: RegExp;
emStrongRDelimUnd: RegExp;
escape: RegExp;
link: RegExp;
nolink: RegExp;
punctuation: RegExp;
reflink: RegExp;
reflinkSearch: RegExp;
tag: RegExp;
text: RegExp;
url: RegExp;
};
export type InlineKeys = keyof typeof inlineNormal;
export interface Rules {
other: typeof other;
block: Record<BlockKeys, RegExp>;
inline: Record<InlineKeys, RegExp>;
}
/**
* Tokenizer
*/
declare class _Tokenizer<ParserOutput = string, RendererOutput = string> {
options: MarkedOptions<ParserOutput, RendererOutput>;
rules: Rules;
lexer: _Lexer<ParserOutput, RendererOutput>;
constructor(options?: MarkedOptions<ParserOutput, RendererOutput>);
space(src: string): Tokens.Space | undefined;
code(src: string): Tokens.Code | undefined;
fences(src: string): Tokens.Code | undefined;
heading(src: string): Tokens.Heading | undefined;
hr(src: string): Tokens.Hr | undefined;
blockquote(src: string): Tokens.Blockquote | undefined;
list(src: string): Tokens.List | undefined;
html(src: string): Tokens.HTML | undefined;
def(src: string): Tokens.Def | undefined;
table(src: string): Tokens.Table | undefined;
lheading(src: string): Tokens.Heading | undefined;
paragraph(src: string): Tokens.Paragraph | undefined;
text(src: string): Tokens.Text | undefined;
escape(src: string): Tokens.Escape | undefined;
tag(src: string): Tokens.Tag | undefined;
link(src: string): Tokens.Link | Tokens.Image | undefined;
reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined;
emStrong(src: string, maskedSrc: string, prevChar?: string): Tokens.Em | Tokens.Strong | undefined;
codespan(src: string): Tokens.Codespan | undefined;
br(src: string): Tokens.Br | undefined;
del(src: string): Tokens.Del | undefined;
autolink(src: string): Tokens.Link | undefined;
url(src: string): Tokens.Link | undefined;
inlineText(src: string): Tokens.Text | undefined;
}
declare class _Hooks<ParserOutput = string, RendererOutput = string> {
options: MarkedOptions<ParserOutput, RendererOutput>;
block?: boolean;
constructor(options?: MarkedOptions<ParserOutput, RendererOutput>);
static passThroughHooks: Set<string>;
static passThroughHooksRespectAsync: Set<string>;
/**
* Process markdown before marked
*/
preprocess(markdown: string): string;
/**
* Process HTML after marked is finished
*/
postprocess(html: ParserOutput): ParserOutput;
/**
* Process all tokens before walk tokens
*/
processAllTokens(tokens: Token[] | TokensList): Token[] | TokensList;
/**
* Mask contents that should not be interpreted as em/strong delimiters
*/
emStrongMask(src: string): string;
/**
* Provide function to tokenize markdown
*/
provideLexer(): typeof _Lexer.lexInline;
/**
* Provide function to parse tokens
*/
provideParser(): (tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput> | undefined) => ParserOutput;
}
export interface TokenizerThis {
lexer: _Lexer;
}
export type TokenizerExtensionFunction = (this: TokenizerThis, src: string, tokens: Token[] | TokensList) => Tokens.Generic | undefined;
export type TokenizerStartFunction = (this: TokenizerThis, src: string) => number | void;
export interface TokenizerExtension {
name: string;
level: "block" | "inline";
start?: TokenizerStartFunction;
tokenizer: TokenizerExtensionFunction;
childTokens?: string[];
}
export interface RendererThis<ParserOutput = string, RendererOutput = string> {
parser: _Parser<ParserOutput, RendererOutput>;
}
export type RendererExtensionFunction<ParserOutput = string, RendererOutput = string> = (this: RendererThis<ParserOutput, RendererOutput>, token: Tokens.Generic) => RendererOutput | false | undefined;
export interface RendererExtension<ParserOutput = string, RendererOutput = string> {
name: string;
renderer: RendererExtensionFunction<ParserOutput, RendererOutput>;
}
export type TokenizerAndRendererExtension<ParserOutput = string, RendererOutput = string> = TokenizerExtension | RendererExtension<ParserOutput, RendererOutput> | (TokenizerExtension & RendererExtension<ParserOutput, RendererOutput>);
export type HooksApi<ParserOutput = string, RendererOutput = string> = Omit<_Hooks<ParserOutput, RendererOutput>, "constructor" | "options" | "block">;
export type HooksObject<ParserOutput = string, RendererOutput = string> = {
[K in keyof HooksApi<ParserOutput, RendererOutput>]?: (this: _Hooks<ParserOutput, RendererOutput>, ...args: Parameters<HooksApi<ParserOutput, RendererOutput>[K]>) => ReturnType<HooksApi<ParserOutput, RendererOutput>[K]> | Promise<ReturnType<HooksApi<ParserOutput, RendererOutput>[K]>>;
};
export type RendererApi<ParserOutput = string, RendererOutput = string> = Omit<_Renderer<ParserOutput, RendererOutput>, "constructor" | "options" | "parser">;
export type RendererObject<ParserOutput = string, RendererOutput = string> = {
[K in keyof RendererApi<ParserOutput, RendererOutput>]?: (this: _Renderer<ParserOutput, RendererOutput>, ...args: Parameters<RendererApi<ParserOutput, RendererOutput>[K]>) => ReturnType<RendererApi<ParserOutput, RendererOutput>[K]> | false;
};
export type TokenizerApi<ParserOutput = string, RendererOutput = string> = Omit<_Tokenizer<ParserOutput, RendererOutput>, "constructor" | "options" | "rules" | "lexer">;
export type TokenizerObject<ParserOutput = string, RendererOutput = string> = {
[K in keyof TokenizerApi<ParserOutput, RendererOutput>]?: (this: _Tokenizer<ParserOutput, RendererOutput>, ...args: Parameters<TokenizerApi<ParserOutput, RendererOutput>[K]>) => ReturnType<TokenizerApi<ParserOutput, RendererOutput>[K]> | false;
};
export interface MarkedExtension<ParserOutput = string, RendererOutput = string> {
/**
* True will tell marked to await any walkTokens functions before parsing the tokens and returning an HTML string.
*/
async?: boolean;
/**
* Enable GFM line breaks. This option requires the gfm option to be true.
*/
breaks?: boolean;
/**
* Add tokenizers and renderers to marked
*/
extensions?: TokenizerAndRendererExtension<ParserOutput, RendererOutput>[] | null;
/**
* Enable GitHub flavored markdown.
*/
gfm?: boolean;
/**
* Hooks are methods that hook into some part of marked.
* preprocess is called to process markdown before sending it to marked.
* processAllTokens is called with the TokensList before walkTokens.
* postprocess is called to process html after marked has finished parsing.
* emStrongMask is called to mask contents that should not be interpreted as em/strong delimiters.
* provideLexer is called to provide a function to tokenize markdown.
* provideParser is called to provide a function to parse tokens.
*/
hooks?: HooksObject<ParserOutput, RendererOutput> | null;
/**
* Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.
*/
pedantic?: boolean;
/**
* Type: object Default: new Renderer()
*
* An object containing functions to render tokens to HTML.
*/
renderer?: RendererObject<ParserOutput, RendererOutput> | null;
/**
* Shows an HTML error message when rendering fails.
*/
silent?: boolean;
/**
* The tokenizer defines how to turn markdown text into tokens.
*/
tokenizer?: TokenizerObject | null;
/**
* The walkTokens function gets called with every token.
* Child tokens are called before moving on to sibling tokens.
* Each token is passed by reference so updates are persisted when passed to the parser.
* The return value of the function is ignored.
*/
walkTokens?: ((token: Token) => void | Promise<void>) | null;
}
export interface MarkedOptions<ParserOutput = string, RendererOutput = string> extends Omit<MarkedExtension<ParserOutput, RendererOutput>, "hooks" | "renderer" | "tokenizer" | "extensions" | "walkTokens"> {
/**
* Hooks are methods that hook into some part of marked.
*/
hooks?: _Hooks<ParserOutput, RendererOutput> | null;
/**
* Type: object Default: new Renderer()
*
* An object containing functions to render tokens to HTML.
*/
renderer?: _Renderer<ParserOutput, RendererOutput> | null;
/**
* The tokenizer defines how to turn markdown text into tokens.
*/
tokenizer?: _Tokenizer<ParserOutput, RendererOutput> | null;
/**
* Custom extensions
*/
extensions?: null | {
renderers: {
[name: string]: RendererExtensionFunction<ParserOutput, RendererOutput>;
};
childTokens: {
[name: string]: string[];
};
inline?: TokenizerExtensionFunction[];
block?: TokenizerExtensionFunction[];
startInline?: TokenizerStartFunction[];
startBlock?: TokenizerStartFunction[];
};
/**
* walkTokens function returns array of values for Promise.all
*/
walkTokens?: null | ((token: Token) => void | Promise<void> | (void | Promise<void>)[]);
}
/**
* Block Lexer
*/
declare class _Lexer<ParserOutput = string, RendererOutput = string> {
tokens: TokensList;
options: MarkedOptions<ParserOutput, RendererOutput>;
state: {
inLink: boolean;
inRawBlock: boolean;
top: boolean;
};
private tokenizer;
private inlineQueue;
constructor(options?: MarkedOptions<ParserOutput, RendererOutput>);
/**
* Expose Rules
*/
static get rules(): {
block: {
normal: {
blockquote: RegExp;
code: RegExp;
def: RegExp;
fences: RegExp;
heading: RegExp;
hr: RegExp;
html: RegExp;
lheading: RegExp;
list: RegExp;
newline: RegExp;
paragraph: RegExp;
table: RegExp;
text: RegExp;
};
gfm: Record<"code" | "blockquote" | "hr" | "html" | "table" | "text" | "def" | "heading" | "list" | "paragraph" | "fences" | "lheading" | "newline", RegExp>;
pedantic: Record<"code" | "blockquote" | "hr" | "html" | "table" | "text" | "def" | "heading" | "list" | "paragraph" | "fences" | "lheading" | "newline", RegExp>;
};
inline: {
normal: {
_backpedal: RegExp;
anyPunctuation: RegExp;
autolink: RegExp;
blockSkip: RegExp;
br: RegExp;
code: RegExp;
del: RegExp;
emStrongLDelim: RegExp;
emStrongRDelimAst: RegExp;
emStrongRDelimUnd: RegExp;
escape: RegExp;
link: RegExp;
nolink: RegExp;
punctuation: RegExp;
reflink: RegExp;
reflinkSearch: RegExp;
tag: RegExp;
text: RegExp;
url: RegExp;
};
gfm: Record<"link" | "code" | "url" | "br" | "del" | "text" | "escape" | "tag" | "reflink" | "nolink" | "_backpedal" | "anyPunctuation" | "autolink" | "blockSkip" | "emStrongLDelim" | "emStrongRDelimAst" | "emStrongRDelimUnd" | "punctuation" | "reflinkSearch", RegExp>;
breaks: Record<"link" | "code" | "url" | "br" | "del" | "text" | "escape" | "tag" | "reflink" | "nolink" | "_backpedal" | "anyPunctuation" | "autolink" | "blockSkip" | "emStrongLDelim" | "emStrongRDelimAst" | "emStrongRDelimUnd" | "punctuation" | "reflinkSearch", RegExp>;
pedantic: Record<"link" | "code" | "url" | "br" | "del" | "text" | "escape" | "tag" | "reflink" | "nolink" | "_backpedal" | "anyPunctuation" | "autolink" | "blockSkip" | "emStrongLDelim" | "emStrongRDelimAst" | "emStrongRDelimUnd" | "punctuation" | "reflinkSearch", RegExp>;
};
};
/**
* Static Lex Method
*/
static lex<ParserOutput = string, RendererOutput = string>(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>): TokensList;
/**
* Static Lex Inline Method
*/
static lexInline<ParserOutput = string, RendererOutput = string>(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>): Token[];
/**
* Preprocessing
*/
lex(src: string): TokensList;
/**
* Lexing
*/
blockTokens(src: string, tokens?: Token[], lastParagraphClipped?: boolean): Token[];
blockTokens(src: string, tokens?: TokensList, lastParagraphClipped?: boolean): TokensList;
inline(src: string, tokens?: Token[]): Token[];
/**
* Lexing/Compiling
*/
inlineTokens(src: string, tokens?: Token[]): Token[];
}
/**
* Gets the original marked default options.
*/
declare function _getDefaults<ParserOutput = string, RendererOutput = string>(): MarkedOptions<ParserOutput, RendererOutput>;
declare let _defaults: MarkedOptions<any, any>;
export type MaybePromise = void | Promise<void>;
export declare class Marked<ParserOutput = string, RendererOutput = string> {
defaults: MarkedOptions<ParserOutput, RendererOutput>;
options: (opt: MarkedOptions<ParserOutput, RendererOutput>) => this;
parse: {
(src: string, options: MarkedOptions<ParserOutput, RendererOutput> & {
async: true;
}): Promise<ParserOutput>;
(src: string, options: MarkedOptions<ParserOutput, RendererOutput> & {
async: false;
}): ParserOutput;
(src: string, options?: MarkedOptions<ParserOutput, RendererOutput> | null): ParserOutput | Promise<ParserOutput>;
};
parseInline: {
(src: string, options: MarkedOptions<ParserOutput, RendererOutput> & {
async: true;
}): Promise<ParserOutput>;
(src: string, options: MarkedOptions<ParserOutput, RendererOutput> & {
async: false;
}): ParserOutput;
(src: string, options?: MarkedOptions<ParserOutput, RendererOutput> | null): ParserOutput | Promise<ParserOutput>;
};
Parser: {
new (options?: MarkedOptions<ParserOutput, RendererOutput> | undefined): _Parser<ParserOutput, RendererOutput>;
parse<ParserOutput_1 = string, RendererOutput_1 = string>(tokens: Token[], options?: MarkedOptions<ParserOutput_1, RendererOutput_1>): ParserOutput_1;
parseInline<ParserOutput_1 = string, RendererOutput_1 = string>(tokens: Token[], options?: MarkedOptions<ParserOutput_1, RendererOutput_1>): ParserOutput_1;
};
Renderer: {
new (options?: MarkedOptions<ParserOutput, RendererOutput> | undefined): _Renderer<ParserOutput, RendererOutput>;
};
TextRenderer: {
new (): _TextRenderer<RendererOutput>;
};
Lexer: typeof _Lexer;
Tokenizer: {
new (options?: MarkedOptions<ParserOutput, RendererOutput> | undefined): _Tokenizer<ParserOutput, RendererOutput>;
};
Hooks: {
new (options?: MarkedOptions<ParserOutput, RendererOutput> | undefined): _Hooks<ParserOutput, RendererOutput>;
passThroughHooks: Set<string>;
passThroughHooksRespectAsync: Set<string>;
};
constructor(...args: MarkedExtension<ParserOutput, RendererOutput>[]);
/**
* Run callback for every token
*/
walkTokens(tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]): MaybePromise[];
use(...args: MarkedExtension<ParserOutput, RendererOutput>[]): this;
setOptions(opt: MarkedOptions<ParserOutput, RendererOutput>): this;
lexer(src: string, options?: MarkedOptions<ParserOutput, RendererOutput>): TokensList;
parser(tokens: Token[], options?: MarkedOptions<ParserOutput, RendererOutput>): ParserOutput;
private parseMarkdown;
private onError;
}
/**
* Compiles markdown to HTML asynchronously.
*
* @param src String of markdown source to be compiled
* @param options Hash of options, having async: true
* @return Promise of string of compiled HTML
*/
export declare function marked(src: string, options: MarkedOptions & {
async: true;
}): Promise<string>;
/**
* Compiles markdown to HTML.
*
* @param src String of markdown source to be compiled
* @param options Optional hash of options
* @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.
*/
export declare function marked(src: string, options: MarkedOptions & {
async: false;
}): string;
export declare function marked(src: string, options: MarkedOptions & {
async: true;
}): Promise<string>;
export declare function marked(src: string, options?: MarkedOptions | null): string | Promise<string>;
export declare namespace marked {
var options: (options: MarkedOptions) => typeof marked;
var setOptions: (options: MarkedOptions) => typeof marked;
var getDefaults: typeof _getDefaults;
var defaults: MarkedOptions<any, any>;
var use: (...args: MarkedExtension[]) => typeof marked;
var walkTokens: (tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) => MaybePromise[];
var parseInline: {
(src: string, options: MarkedOptions<string, string> & {
async: true;
}): Promise<string>;
(src: string, options: MarkedOptions<string, string> & {
async: false;
}): string;
(src: string, options?: MarkedOptions<string, string> | null | undefined): string | Promise<string>;
};
var Parser: typeof _Parser;
var parser: typeof _Parser.parse;
var Renderer: typeof _Renderer;
var TextRenderer: typeof _TextRenderer;
var Lexer: typeof _Lexer;
var lexer: typeof _Lexer.lex;
var Tokenizer: typeof _Tokenizer;
var Hooks: typeof _Hooks;
var parse: typeof marked;
}
export declare const options: (options: MarkedOptions) => typeof marked;
export declare const setOptions: (options: MarkedOptions) => typeof marked;
export declare const use: (...args: MarkedExtension[]) => typeof marked;
export declare const walkTokens: (tokens: Token[] | TokensList, callback: (token: Token) => MaybePromise | MaybePromise[]) => MaybePromise[];
export declare const parseInline: {
(src: string, options: MarkedOptions<string, string> & {
async: true;
}): Promise<string>;
(src: string, options: MarkedOptions<string, string> & {
async: false;
}): string;
(src: string, options?: MarkedOptions<string, string> | null | undefined): string | Promise<string>;
};
export declare const parse: typeof marked;
export declare const parser: typeof _Parser.parse;
export declare const lexer: typeof _Lexer.lex;
export {
_Hooks as Hooks,
_Lexer as Lexer,
_Parser as Parser,
_Renderer as Renderer,
_TextRenderer as TextRenderer,
_Tokenizer as Tokenizer,
_defaults as defaults,
_getDefaults as getDefaults,
};
export {};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -38,7 +38,6 @@ function getSiteTree($params) {
'users' => (string) $child->attributes()->users,
'group' => (string) $child->attributes()->group,
'news' => (string) $child->attributes()->news,
'plugins' => (string) $child->attributes()->plugins,
'content' => (string)$child
];
@@ -150,7 +149,6 @@ function buildSiteTreeXml($data, $level = 1) {
'users' => isset($item['users']) ? htmlspecialchars($item['users'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'group' => isset($item['group']) ? htmlspecialchars($item['group'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'news' => isset($item['news']) ? htmlspecialchars($item['news'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'plugins' => isset($item['plugins']) ? htmlspecialchars($item['plugins'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : ''
];
$attrString = "";

View File

@@ -67,7 +67,6 @@ function generateTreeHtml(items, checkChildren) {
html += `PageMenu: ${item.PageMenu}<br>`;
html += `users: ${item.users}<br>`;
html += `group: ${item.group}<br>`;
html += `plugins: ${item.plugins}<br>`;
let now = new Date();
let pad = n => n < 10 ? '0' + n : n;
@@ -100,7 +99,7 @@ function generateTreeHtml(items, checkChildren) {
html += `</li>`;
if (style) {
selectedTreeItemAdd = `url: ${item.url}<br>title: ${item.title}<br>name: ${item.name}<br>template: ${item.template}<br>PageMenu: ${item.PageMenu}<br>users: ${item.users}<br>group: ${item.group}<br>plugins: ${item.plugins}`;
selectedTreeItemAdd = `url: ${item.url}<br>title: ${item.title}<br>name: ${item.name}<br>template: ${item.template}<br>PageMenu: ${item.PageMenu}<br>users: ${item.users}<br>group: ${item.group}`;
}
});
@@ -888,13 +887,6 @@ function saveTreePropertiesDiv() {
.map(x => `<label><input type="checkbox" value="${x.value}"${x.checked?' checked':''}>${x.value}</label>`);
parts.push(`<div>${blocks.join(' ')}</div>`);
value = parts.join('');
}
else if (key.toLowerCase() === 'plugins') {
let cbs = valueCell.querySelectorAll('input[type="checkbox"][value]');
let active = Array.from(cbs)
.filter(cb => cb.checked)
.map(cb => cb.value);
value = active.join(',');
} else {
let input = valueCell.querySelector('input');
value = input ? input.value : valueCell.textContent.trim();
@@ -991,12 +983,6 @@ function treePropertiesDiv() {
inputHtml = `<input type="text" value="${value}" style="font-size: inherit;" readonly disabled>`;
} else if (key.toLowerCase() === "group") {
inputHtml = `<input type="text" value="${value}" style="font-size: inherit;" readonly disabled>`;
} else if (key.toLowerCase() === "plugins") {
let plugins = (value || '').split(',');
let allPlugins = ['dgrm','SvgEditorM'];
inputHtml = allPlugins.map(p =>
`<label><input type="checkbox" value="${p}"${plugins.includes(p)?' checked':''}>${p}</label>`
).join(' ');
}

View File

@@ -187,11 +187,12 @@ ul, ol {
.bfloat {
overflow-x: hidden;
left: -1px;
top: -1px;
position: relative;
border-radius: 0 0 10px 10px;
border-radius: 10px;
padding: 10px;
font-size: 1em;
top: -1px;
border-radius: 0 0 10px 10px;
}
.cfloat {
@@ -228,11 +229,11 @@ ul, ol {
font-weight: bold;
}
#content {
#content, .content {
overflow-x: hidden;
overflow-y: hidden;
}
#content td {
#content td, .content td {
height: 19px;
}
#editor a {

View File

@@ -14,9 +14,7 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
%left%
%right%

View File

@@ -27,8 +27,6 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -27,8 +27,6 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -27,8 +27,6 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -27,8 +27,6 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -27,8 +27,6 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -23,7 +23,5 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>

View File

@@ -49,9 +49,7 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -28,9 +28,7 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -49,9 +49,7 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>

View File

@@ -26,9 +26,7 @@
<div class="%ctitle%" id="mainTitle">
%title%
</div>
<div class="%cfloat%">
<div id="content">%content%</div>
</div>
%content%
</div>
</div>