Files
profile-front/src/scripts/embedded-content.js
Profile Profile f66c3baf8d add emmed
2026-03-14 18:01:30 +03:00

178 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

(function() {
// Предотвращаем множественное выполнение
if (window._embeddedContentReplacerInitialized) return;
window._embeddedContentReplacerInitialized = true;
const processedUrls = new Set();
// Главная функция инициализации
function initEmbeddedReplacer() {
// Проверяем наличие шаблонов
if (!document.getElementById('embedded-loading-template') ||
!document.getElementById('embedded-card-template')) {
console.error('Embedded content templates not found');
return;
}
processBlockquotes();
observeMutations();
}
// Поиск и обработка всех blockquote
function processBlockquotes() {
const blockquotes = document.querySelectorAll('blockquote.wp-embedded-content');
blockquotes.forEach(processBlockquote);
}
// Наблюдение за новыми элементами
function observeMutations() {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) {
const blockquotes = node.querySelectorAll
? node.querySelectorAll('blockquote.wp-embedded-content')
: [];
blockquotes.forEach(processBlockquote);
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
// Клонирование шаблона
function cloneTemplate(templateId) {
const template = document.getElementById(templateId);
return template.content.cloneNode(true);
}
// Функция для очистки slug от ID в конце
function cleanSlug(slug) {
if (!slug) return slug;
const pattern = /-\d+$/;
if (pattern.test(slug)) {
const cleanedSlug = slug.replace(pattern, '');
console.log('Cleaned slug:', slug, '->', cleanedSlug);
return cleanedSlug;
}
return slug;
}
// Обработка одного blockquote
async function processBlockquote(blockquote) {
const link = blockquote.querySelector('a');
if (!link) return;
const href = link.getAttribute('href');
if (!href || !href.includes('profile.ru') || processedUrls.has(href)) {
return;
}
processedUrls.add(href);
// Сохраняем оригинальное содержимое
const originalContent = blockquote.innerHTML;
// Показываем загрузку из шаблона
const loadingContent = cloneTemplate('embedded-loading-template');
blockquote.innerHTML = '';
blockquote.appendChild(loadingContent);
try {
const urlObj = new URL(href);
const pathParts = urlObj.pathname.split('/').filter(part => part);
let slug = pathParts[pathParts.length - 1];
console.log('Original slug:', slug);
slug = cleanSlug(slug);
console.log('Processed slug:', slug);
const postData = await fetchPostData(slug);
if (postData && postData.title) {
replaceWithCard(blockquote, postData);
} else {
// Если данных нет - восстанавливаем оригинал
blockquote.innerHTML = originalContent;
}
} catch (error) {
console.error('Error processing embedded content:', error);
// В случае ошибки восстанавливаем оригинал
blockquote.innerHTML = originalContent;
}
}
// Функция запроса к API
async function fetchPostData(slug) {
if (!slug) {
throw new Error('Slug is required');
}
const encodedSlug = encodeURIComponent(slug);
const apiUrl = `/api/embedded-post?url=${encodedSlug}`;
console.log('Fetching from API:', apiUrl);
const response = await fetch(apiUrl);
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'Failed to fetch post data');
}
return data;
}
// Замена на карточку из шаблона
function replaceWithCard(blockquote, post) {
// Клонируем шаблон карточки
const cardContent = cloneTemplate('embedded-card-template');
// Заполняем данными
const link = cardContent.querySelector('a');
const imageContainer = cardContent.querySelector('.embedded-post-image-container');
const image = cardContent.querySelector('.embedded-post-image');
const title = cardContent.querySelector('.embedded-post-title');
if (link) {
link.href = post.originalUrl || post.url;
}
if (post.image && image && imageContainer) {
image.src = post.image;
image.alt = post.imageAlt || post.title;
imageContainer.style.display = '';
image.onerror = function() {
this.style.display = 'none';
imageContainer.style.display = 'none';
};
} else if (imageContainer) {
imageContainer.style.display = 'none';
}
if (title) {
title.textContent = post.title;
}
// Очищаем blockquote и вставляем карточку
blockquote.innerHTML = '';
blockquote.appendChild(cardContent);
}
// Запускаем после загрузки DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initEmbeddedReplacer);
} else {
initEmbeddedReplacer();
}
})();