openvk/Web/static/js/st_manager.js

191 lines
6.5 KiB
JavaScript
Raw Normal View History

2023-08-11 00:23:43 +03:00
function executeScripts(html) {
let tempContainer = document.createElement('div');
tempContainer.innerHTML = html;
let scripts = tempContainer.querySelectorAll('script');
scripts.forEach((script) => {
if (!isScriptAlreadyLoaded(script)) {
let newScript = document.createElement('script');
if (script.src) {
newScript.src = script.src;
} else {
newScript.textContent = script.textContent;
}
document.body.appendChild(newScript);
}
});
}
function isScriptAlreadyLoaded(script) {
if (script.src) {
let existingScript = document.querySelector(`script[src="${script.src.split('?')[0]}"]`);
return !!existingScript;
}
return false;
}
// Функция для выполнения стилей в переданном HTML-коде
function executeStyles(html) {
let tempContainer = document.createElement('div');
tempContainer.innerHTML = html;
let styles = tempContainer.querySelectorAll('link[rel="stylesheet"]');
styles.forEach((style) => {
if (!isStyleAlreadyLoaded(style)) {
let newStyle = document.createElement('link');
newStyle.rel = 'stylesheet';
newStyle.href = style.href;
document.head.appendChild(newStyle);
}
});
}
function isStyleAlreadyLoaded(style) {
if (style.href) {
let styleHref = style.href.split('?')[0]; // Извлечь URL без query параметров
let existingStyle = document.querySelector(`link[rel="stylesheet"][href="${styleHref}"]`);
return !!existingStyle;
}
return false;
}
function cleanAndLoadContent(html) {
let tempContainer = document.createElement('div');
tempContainer.innerHTML = html;
let scripts = tempContainer.querySelectorAll('script');
let styles = tempContainer.querySelectorAll('link[rel="stylesheet"]');
scripts.forEach((script) => {
if (isScriptAlreadyLoaded(script)) {
script.parentNode.removeChild(script);
}
});
styles.forEach((style) => {
if (isStyleAlreadyLoaded(style)) {
style.parentNode.removeChild(style);
}
});
return tempContainer.innerHTML;
}
async function goto(url, ps = true, isRedirect = false) {
$("#ajaxLoader").show();
try {
await $.ajax({
url: url,
data: {
al: 1
},
dataType: 'html',
complete: async (data, textStatus) => {
console.log(data);
let cleanedContent = cleanAndLoadContent(data.responseText);
document.getElementById("bodyContent").innerHTML = cleanedContent;
const redirectUrl = data.getResponseHeader('Location');
if (redirectUrl) {
console.log("REDIRECT", redirectUrl);
goto(redirectUrl, true);
} else {
initForms();
executeScripts(data.responseText);
executeStyles(data.responseText);
$("title").text($(data.responseText).filter('title').text());
}
}
});
} catch (error) {
console.error("goto", url, ps, "ERROR", error);
MessageBox("Ошибка", "Не удалось загрузить эту страницу", ["OK"], [Function.noop]);
}
if (ps) {
history.pushState(null, null, ($("#__current_url").val().replace(/[?&]al=1(?=$|&)/, '') || url));
}
$("#ajaxLoader").hide();
}
document.addEventListener("click", async (e) => {
console.log(e);
let target = e.target;
while (target && target.tagName !== "A") {
target = target.parentNode;
}
if (target) {
const url = target.getAttribute("href");
if (url) {
if (target.tagName.toLowerCase() === "a" && target.getAttribute("target") !== "_blank" && !url.startsWith("javascript:")) {
e.preventDefault();
goto(url);
}
}
}
})
async function submitAjaxForm(url, formData) {
if (!url) url = window.location.href;
const separator = url.includes('?') ? '&' : '?';
const newUrl = url + separator + 'al=1';
try {
await $.ajax({
type: 'POST', // Может быть GET, POST, и т.д.
url: newUrl,
data: formData,
processData: false,
contentType: false,
success: async (data, textStatus, jqXHR) => {
const redirectUrl = jqXHR.getResponseHeader('Location') || (jqXHR.status === 301 || jqXHR.status === 302);
if (redirectUrl) {
history.pushState(null, null, redirectUrl);
submitAjaxForm(redirectUrl, formData);
} else {
const bodyContent = $("#bodyContent");
bodyContent.html(data);
$("#ajaxLoader").hide();
history.pushState(null, null, $("#__current_url").val().replace(/[?&]al=1(?=$|&)/, ''));
$("title").text($(data.responseText).filter('title').text());
}
},
error: async (error) => {
console.error(error);
// Обработка ошибки
MessageBox("Ошибка", "При загрузке страницы произошла ошибка", ["OK :("], [Function.noop]);
}
});
} catch (error) {
console.error("submitAjaxForm ERROR", error);
MessageBox("Ошибка", "При загрузке страницы произошла ошибка", ["OK :("], [Function.noop]);
}
}
function initForms() {
// Удаляем старые обработчики событий на формах
$("form").off("submit");
// Обходим все формы и добавляем обработчик на событие отправки
$("form").on("submit", async function (event) {
event.preventDefault();
const form = event.target;
const url = form.getAttribute("action");
const formData = new FormData(form);
$("#ajaxLoader").show();
await submitAjaxForm(url, formData);
});
}
// Обработка события popstate (браузерная навигация назад/вперед)
window.addEventListener('popstate', async function (event) {
event.preventDefault();
goto(location.href, false);
});