add emmed
This commit is contained in:
178
src/scripts/embedded-content.js
Normal file
178
src/scripts/embedded-content.js
Normal 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();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user