rename page
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* my-editor.js — VvvebJS 儲存與新增頁面橋接腳本
|
||||
* 覆蓋 Vvveb.Builder.saveAjax 行為,使儲存與新增頁面功能無縫串接至 Flask 後端
|
||||
* 覆蓋 Vvveb.Builder.saveAjax 與 Vvveb.FileManager 行為,無縫串接到 Flask 後端,並引入精美網頁型暗黑系模態框
|
||||
*/
|
||||
(function () {
|
||||
"use strict";
|
||||
@@ -49,10 +49,292 @@
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// ── 頂級網頁型模態框 (Web-based Custom Dialogs) ──────────────────────
|
||||
function showModalPrompt(title, defaultValue, callback) {
|
||||
const existing = document.getElementById("vvveb-custom-modal");
|
||||
if (existing) existing.remove();
|
||||
|
||||
const overlay = document.createElement("div");
|
||||
overlay.id = "vvveb-custom-modal";
|
||||
Object.assign(overlay.style, {
|
||||
position: "fixed",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
zIndex: "100000",
|
||||
background: "rgba(10, 11, 18, 0.65)",
|
||||
backdropFilter: "blur(12px)",
|
||||
webkitBackdropFilter: "blur(12px)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
opacity: "0",
|
||||
transition: "opacity 0.25s ease-out"
|
||||
});
|
||||
|
||||
const card = document.createElement("div");
|
||||
Object.assign(card.style, {
|
||||
background: "rgba(22, 24, 38, 0.95)",
|
||||
border: "1px solid rgba(255, 255, 255, 0.08)",
|
||||
boxShadow: "0 20px 50px rgba(0, 0, 0, 0.6), 0 0 40px rgba(99, 102, 241, 0.1)",
|
||||
borderRadius: "16px",
|
||||
width: "420px",
|
||||
padding: "2rem",
|
||||
color: "#f8fafc",
|
||||
fontFamily: "Inter, system-ui, sans-serif",
|
||||
transform: "scale(0.95)",
|
||||
transition: "transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "1.25rem"
|
||||
});
|
||||
|
||||
card.innerHTML = `
|
||||
<div style="font-size: 1.15rem; font-weight: 600; color: #fff; display: flex; align-items: center; gap: 0.6rem;">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#818cf8" stroke-width="2">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
</svg>
|
||||
${title}
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" id="vvveb-modal-input" style="
|
||||
width: 100%;
|
||||
background: rgba(13, 14, 24, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
padding: 0.65rem 0.9rem;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
outline: none;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
" />
|
||||
</div>
|
||||
<div style="display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 0.5rem;">
|
||||
<button id="vvveb-modal-cancel" style="
|
||||
background: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
padding: 0.55rem 1.1rem;
|
||||
color: #94a3b8;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
">取消</button>
|
||||
<button id="vvveb-modal-confirm" style="
|
||||
background: #4f46e5;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 0.55rem 1.25rem;
|
||||
color: #fff;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.3);
|
||||
">確定</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
overlay.appendChild(card);
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
const input = card.querySelector("#vvveb-modal-input");
|
||||
input.value = defaultValue;
|
||||
input.addEventListener("focus", () => {
|
||||
input.style.borderColor = "#818cf8";
|
||||
input.style.boxShadow = "0 0 12px rgba(129, 140, 248, 0.25)";
|
||||
});
|
||||
input.addEventListener("blur", () => {
|
||||
input.style.borderColor = "rgba(255, 255, 255, 0.1)";
|
||||
input.style.boxShadow = "none";
|
||||
});
|
||||
|
||||
const cancelBtn = card.querySelector("#vvveb-modal-cancel");
|
||||
cancelBtn.addEventListener("mouseover", () => {
|
||||
cancelBtn.style.background = "rgba(255, 255, 255, 0.05)";
|
||||
cancelBtn.style.color = "#fff";
|
||||
});
|
||||
cancelBtn.addEventListener("mouseout", () => {
|
||||
cancelBtn.style.background = "transparent";
|
||||
cancelBtn.style.color = "#94a3b8";
|
||||
});
|
||||
|
||||
const confirmBtn = card.querySelector("#vvveb-modal-confirm");
|
||||
confirmBtn.addEventListener("mouseover", () => {
|
||||
confirmBtn.style.background = "#4338ca";
|
||||
});
|
||||
confirmBtn.addEventListener("mouseout", () => {
|
||||
confirmBtn.style.background = "#4f46e5";
|
||||
});
|
||||
|
||||
// Fade in
|
||||
setTimeout(() => {
|
||||
overlay.style.opacity = "1";
|
||||
card.style.transform = "scale(1)";
|
||||
}, 10);
|
||||
|
||||
input.focus();
|
||||
input.select();
|
||||
|
||||
function close(value) {
|
||||
overlay.style.opacity = "0";
|
||||
card.style.transform = "scale(0.95)";
|
||||
setTimeout(() => {
|
||||
overlay.remove();
|
||||
if (value !== undefined) {
|
||||
const finalVal = value.trim ? value.trim() : value;
|
||||
callback(finalVal);
|
||||
}
|
||||
}, 250);
|
||||
}
|
||||
|
||||
cancelBtn.onclick = () => close();
|
||||
confirmBtn.onclick = () => close(input.value);
|
||||
|
||||
input.onkeydown = (e) => {
|
||||
if (e.key === "Enter") {
|
||||
close(input.value);
|
||||
} else if (e.key === "Escape") {
|
||||
close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function showModalConfirm(title, message, callback) {
|
||||
const existing = document.getElementById("vvveb-custom-modal");
|
||||
if (existing) existing.remove();
|
||||
|
||||
const overlay = document.createElement("div");
|
||||
overlay.id = "vvveb-custom-modal";
|
||||
Object.assign(overlay.style, {
|
||||
position: "fixed",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
zIndex: "100000",
|
||||
background: "rgba(10, 11, 18, 0.65)",
|
||||
backdropFilter: "blur(12px)",
|
||||
webkitBackdropFilter: "blur(12px)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
opacity: "0",
|
||||
transition: "opacity 0.25s ease-out"
|
||||
});
|
||||
|
||||
const card = document.createElement("div");
|
||||
Object.assign(card.style, {
|
||||
background: "rgba(22, 24, 38, 0.95)",
|
||||
border: "1px solid rgba(255, 255, 255, 0.08)",
|
||||
boxShadow: "0 20px 50px rgba(0, 0, 0, 0.6), 0 0 40px rgba(239, 68, 68, 0.1)",
|
||||
borderRadius: "16px",
|
||||
width: "420px",
|
||||
padding: "2rem",
|
||||
color: "#f8fafc",
|
||||
fontFamily: "Inter, system-ui, sans-serif",
|
||||
transform: "scale(0.95)",
|
||||
transition: "transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "1.25rem"
|
||||
});
|
||||
|
||||
card.innerHTML = `
|
||||
<div style="font-size: 1.15rem; font-weight: 600; color: #fff; display: flex; align-items: center; gap: 0.6rem;">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2">
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
||||
<line x1="12" y1="9" x2="12" y2="13"/>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
||||
</svg>
|
||||
${title}
|
||||
</div>
|
||||
<div style="font-size: 0.9rem; color: #cbd5e1; line-height: 1.5;">
|
||||
${message}
|
||||
</div>
|
||||
<div style="display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 0.5rem;">
|
||||
<button id="vvveb-modal-cancel" style="
|
||||
background: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
padding: 0.55rem 1.1rem;
|
||||
color: #94a3b8;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
">取消</button>
|
||||
<button id="vvveb-modal-confirm" style="
|
||||
background: #ef4444;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 0.55rem 1.25rem;
|
||||
color: #fff;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
|
||||
">確定</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
overlay.appendChild(card);
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
const cancelBtn = card.querySelector("#vvveb-modal-cancel");
|
||||
cancelBtn.addEventListener("mouseover", () => {
|
||||
cancelBtn.style.background = "rgba(255, 255, 255, 0.05)";
|
||||
cancelBtn.style.color = "#fff";
|
||||
});
|
||||
cancelBtn.addEventListener("mouseout", () => {
|
||||
cancelBtn.style.background = "transparent";
|
||||
cancelBtn.style.color = "#94a3b8";
|
||||
});
|
||||
|
||||
const confirmBtn = card.querySelector("#vvveb-modal-confirm");
|
||||
confirmBtn.addEventListener("mouseover", () => {
|
||||
confirmBtn.style.background = "#dc2626";
|
||||
});
|
||||
confirmBtn.addEventListener("mouseout", () => {
|
||||
confirmBtn.style.background = "#ef4444";
|
||||
});
|
||||
|
||||
// Fade in
|
||||
setTimeout(() => {
|
||||
overlay.style.opacity = "1";
|
||||
card.style.transform = "scale(1)";
|
||||
}, 10);
|
||||
|
||||
confirmBtn.focus();
|
||||
|
||||
function close(confirmed) {
|
||||
overlay.style.opacity = "0";
|
||||
card.style.transform = "scale(0.95)";
|
||||
setTimeout(() => {
|
||||
overlay.remove();
|
||||
if (confirmed) callback();
|
||||
}, 250);
|
||||
}
|
||||
|
||||
cancelBtn.onclick = () => close(false);
|
||||
confirmBtn.onclick = () => close(true);
|
||||
|
||||
const keyHandler = (e) => {
|
||||
if (e.key === "Escape") {
|
||||
close(false);
|
||||
window.removeEventListener("keydown", keyHandler);
|
||||
}
|
||||
};
|
||||
window.addEventListener("keydown", keyHandler);
|
||||
}
|
||||
|
||||
// ── 覆蓋 Vvveb.Builder.saveAjax ──────────────────────────────────
|
||||
function patchSaveAjax() {
|
||||
if (typeof Vvveb === "undefined" || !Vvveb.Builder) {
|
||||
// 等待 Vvveb 載入
|
||||
setTimeout(patchSaveAjax, 200);
|
||||
return;
|
||||
}
|
||||
@@ -73,7 +355,7 @@
|
||||
}
|
||||
data.slug = SLUG;
|
||||
|
||||
// 扁平化處理新檔案檔名(確保所有頁面皆存於專案根目錄下)
|
||||
// 扁平化處理新檔案檔名
|
||||
if (data.file) {
|
||||
const parts = data.file.split("/");
|
||||
data.file = parts[parts.length - 1];
|
||||
@@ -89,7 +371,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 顯示儲存中狀態(一般儲存時觸發)
|
||||
// 顯示儲存中狀態
|
||||
const saveBtn = document.querySelector(".save-btn");
|
||||
if (saveBtn && !isNewPage) {
|
||||
saveBtn.querySelector(".loading")?.classList.remove("d-none");
|
||||
@@ -147,6 +429,243 @@
|
||||
console.log("[my-editor] Robust Vvveb.Builder.saveAjax patched for slug:", SLUG);
|
||||
}
|
||||
|
||||
// ── 覆蓋 Vvveb.FileManager 頁面操作 ──────────────────────────────
|
||||
function patchFileManager() {
|
||||
if (typeof Vvveb === "undefined" || !Vvveb.FileManager) {
|
||||
setTimeout(patchFileManager, 200);
|
||||
return;
|
||||
}
|
||||
|
||||
// 覆蓋 init 方法以修正 VvvebJS 使用全球廢棄的 `event.target` 導致在某些瀏覽器/嚴格模式下點擊無效的 Bug
|
||||
const originalInit = Vvveb.FileManager.init;
|
||||
Vvveb.FileManager.init = function (allowedComponents = {}) {
|
||||
originalInit.call(this, allowedComponents);
|
||||
|
||||
// 利用 Clone 移除舊有包含 Bug 的匿名字選區接聽器
|
||||
const newTree = this.tree.cloneNode(true);
|
||||
this.tree.parentNode.replaceChild(newTree, this.tree);
|
||||
this.tree = newTree;
|
||||
|
||||
// 綁定符合標準且高度相容 (e.target) 的新接聽器
|
||||
this.tree.addEventListener("click", function (e) {
|
||||
let element = e.target.closest("a");
|
||||
if (element) {
|
||||
e.stopImmediatePropagation();
|
||||
if (element.classList.contains('view')) return;
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this.tree.addEventListener("click", function (e) {
|
||||
let element = e.target.closest(".delete");
|
||||
if (element) {
|
||||
Vvveb.FileManager.deletePage(element.closest("li"), e);
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this.tree.addEventListener("click", function (e) {
|
||||
let element = e.target.closest(".rename");
|
||||
if (element) {
|
||||
Vvveb.FileManager.renamePage(element.closest("li"), e, false);
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this.tree.addEventListener("click", function (e) {
|
||||
let element = e.target.closest(".duplicate");
|
||||
if (element) {
|
||||
Vvveb.FileManager.renamePage(element.closest("li"), e, true);
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this.tree.addEventListener("click", function (e) {
|
||||
let element = e.target.closest("li[data-page] label");
|
||||
if (element) {
|
||||
let page = element.parentNode.dataset.page;
|
||||
if (page) {
|
||||
Vvveb.FileManager.loadPage(page);
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 覆蓋重新命名 / 複製頁面
|
||||
Vvveb.FileManager.renamePage = function (element, e, duplicate = false) {
|
||||
let page = element.dataset;
|
||||
showModalPrompt(`請輸入 "${page.file}" 的新檔名:`, page.file, function (newfile) {
|
||||
if (!newfile) return;
|
||||
|
||||
// 確保副檔名為 .html
|
||||
if (!newfile.endsWith(".html")) {
|
||||
newfile += ".html";
|
||||
}
|
||||
|
||||
const bodyData = {
|
||||
slug: SLUG,
|
||||
file: page.file,
|
||||
newfile: newfile,
|
||||
duplicate: duplicate ? "true" : "false"
|
||||
};
|
||||
|
||||
fetch(`/api/save?action=rename`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams(bodyData).toString()
|
||||
})
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
return res.json().then((err) => {
|
||||
throw new Error(err.error || "操作失敗");
|
||||
});
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then((data) => {
|
||||
showToast(`✓ ${data.message}`);
|
||||
let baseName = data.newfile.replace('.html', '');
|
||||
let newName = friendlyName(data.newfile.replace(/.*[\/\\]+/, '')).replace('.html', '');
|
||||
|
||||
if (duplicate) {
|
||||
// 複製頁面:在 FileManager 中加入新頁面
|
||||
let pageData = Object.assign({}, Vvveb.FileManager.pages[page.page]);
|
||||
pageData["file"] = data.newfile;
|
||||
pageData["title"] = newName;
|
||||
pageData["url"] = data.url;
|
||||
pageData["name"] = baseName;
|
||||
Vvveb.FileManager.addPage(baseName, pageData);
|
||||
} else {
|
||||
// 重新命名:更新現有節點資訊
|
||||
const oldPageKey = page.page;
|
||||
Vvveb.FileManager.pages[oldPageKey]["file"] = data.newfile;
|
||||
Vvveb.FileManager.pages[oldPageKey]["title"] = newName;
|
||||
Vvveb.FileManager.pages[oldPageKey]["url"] = data.url;
|
||||
Vvveb.FileManager.pages[oldPageKey]["name"] = baseName;
|
||||
|
||||
let link = element.querySelector("a.view");
|
||||
if (link) {
|
||||
link.setAttribute("href", data.url);
|
||||
}
|
||||
let span = element.querySelector("label > span");
|
||||
if (!span) {
|
||||
span = element.querySelector("span");
|
||||
}
|
||||
if (span) {
|
||||
span.textContent = newName;
|
||||
}
|
||||
element.dataset.file = data.newfile;
|
||||
element.dataset.page = baseName;
|
||||
|
||||
// 將 key 重新綁定
|
||||
Vvveb.FileManager.pages[baseName] = Vvveb.FileManager.pages[oldPageKey];
|
||||
if (baseName !== oldPageKey) {
|
||||
delete Vvveb.FileManager.pages[oldPageKey];
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(`操作失敗:${err.message}`, "error");
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 覆蓋刪除頁面
|
||||
Vvveb.FileManager.deletePage = function (element, e) {
|
||||
let page = element.dataset;
|
||||
if (page.file.toLowerCase() === "index.html") {
|
||||
showToast("錯誤:無法刪除主頁 index.html", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
showModalConfirm("確認刪除頁面", `確定要刪除 "${page.file}" 頁面嗎?此動作將無法復原。`, function () {
|
||||
const bodyData = {
|
||||
slug: SLUG,
|
||||
file: page.file
|
||||
};
|
||||
|
||||
fetch(`/api/save?action=delete`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams(bodyData).toString()
|
||||
})
|
||||
.then((res) => {
|
||||
if (!res.ok) {
|
||||
return res.json().then((err) => {
|
||||
throw new Error(err.error || "刪除失敗");
|
||||
});
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then((data) => {
|
||||
showToast(`✓ ${data.message}`);
|
||||
|
||||
// 從內部 pages 列表中移除
|
||||
delete Vvveb.FileManager.pages[page.page];
|
||||
element.remove();
|
||||
|
||||
// 如果刪除的是目前正在編輯的頁面,切換回第一個頁面
|
||||
if (Vvveb.FileManager.currentPage === page.page) {
|
||||
let firstPage = Object.keys(Vvveb.FileManager.pages)[0];
|
||||
if (firstPage) {
|
||||
Vvveb.FileManager.loadPage(firstPage);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showToast(`刪除失敗:${err.message}`, "error");
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
console.log("[my-editor] Vvveb.FileManager operations patched.");
|
||||
}
|
||||
|
||||
// ── 覆蓋 Vvveb.NewSection 防止佈局崩潰 ─────────────────────────────
|
||||
function patchNewSection() {
|
||||
if (typeof Vvveb === "undefined" || !Vvveb.NewSection) {
|
||||
setTimeout(patchNewSection, 200);
|
||||
return;
|
||||
}
|
||||
|
||||
Vvveb.NewSection.insert = function () {
|
||||
let position = 'before';
|
||||
let lastSection = Vvveb.Builder.frameBody.querySelector(':scope > footer:last-of-type');
|
||||
if (!lastSection) {
|
||||
position = 'after';
|
||||
lastSection = Vvveb.Builder.frameBody.querySelector(':scope > main:last-of-type') ||
|
||||
Vvveb.Builder.frameBody.querySelector(':scope > section:last-of-type') ||
|
||||
Vvveb.Builder.frameBody.querySelector(':scope > div:last-of-type') ||
|
||||
Vvveb.Builder.frameBody; // 最安全的回退點:整個 body 節點
|
||||
}
|
||||
|
||||
this.container = generateElements(this.template)[0];
|
||||
if (lastSection === Vvveb.Builder.frameBody) {
|
||||
Vvveb.Builder.frameBody.appendChild(this.container);
|
||||
} else {
|
||||
if (position == 'after') {
|
||||
lastSection.after(this.container);
|
||||
} else {
|
||||
lastSection.before(this.container);
|
||||
}
|
||||
}
|
||||
|
||||
return this.container;
|
||||
};
|
||||
|
||||
console.log("[my-editor] Vvveb.NewSection.insert patched to prevent layout crashes.");
|
||||
}
|
||||
|
||||
// ── 啟用 Save 按鈕(vvvebjs 預設 disabled)──────────────────────
|
||||
function enableSaveBtn() {
|
||||
const btn = document.querySelector(".save-btn");
|
||||
@@ -177,10 +696,14 @@
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
patchSaveAjax();
|
||||
patchFileManager();
|
||||
patchNewSection();
|
||||
enableSaveBtn();
|
||||
});
|
||||
} else {
|
||||
patchSaveAjax();
|
||||
patchFileManager();
|
||||
patchNewSection();
|
||||
enableSaveBtn();
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user