add emmed

This commit is contained in:
Profile Profile
2026-03-14 18:01:30 +03:00
parent 684a7bffbf
commit f66c3baf8d
10 changed files with 338 additions and 235 deletions

View File

@@ -0,0 +1,178 @@
(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();
}
})();