1
// ==UserScript==
// @name Binguru Copy Post
// @namespace binguru-copy-post
// @version 1.0.0
// @description Заменяет кнопку "Жалоба" на "Копировать" для быстрого копирования поста в AI
// @match https://binguru.net/forums/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
// Сразу скрываем текст "Жалоба" через CSS и показываем иконку копирования
const style = document.createElement('style');
style.textContent = `
a[href*="reportPost"] {
font-size: 0 !important;
display: inline-block;
width: 12px;
height: 12px;
padding: 4px;
border-radius: 4px;
vertical-align: middle;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23775454' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='13' height='13' rx='2' ry='2'/%3E%3Cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1'/%3E%3C/svg%3E");
background-size: 12px 12px;
background-repeat: no-repeat;
background-position: center;
box-sizing: content-box;
transition: background-color 0.2s;
}
a[href*="reportPost"]:hover {
background-color: #775454;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='13' height='13' rx='2' ry='2'/%3E%3Cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1'/%3E%3C/svg%3E");
}
`;
(document.head || document.documentElement).appendChild(style);
/**
* Найти элемент с контентом поста
*/
function getPostContent(container) {
// Контент: вторая строка таблицы (как в obsidian скрипте)
const rows = container.querySelectorAll('table.forums > tbody > tr');
if (rows.length >= 2) {
const cells = rows[1].querySelectorAll('td');
let best = null;
let maxLen = 0;
for (const td of cells) {
if (td.textContent.length > maxLen) {
maxLen = td.textContent.length;
best = td;
}
}
if (best) return best;
}
// Fallback
const cells = container.querySelectorAll('td, div.post-content, div.message-body');
let best = null;
let bestLen = 0;
for (const cell of cells) {
const text = cell.textContent.trim();
if (/^(Автор|Дата:|#\d)/.test(text)) continue;
if (text.length > bestLen) {
bestLen = text.length;
best = cell;
}
}
return best;
}
/**
* Подготовить контент для копирования
*/
function prepareContentForCopy(el) {
const clone = el.cloneNode(true);
// Удаляем лишнее
clone.querySelectorAll('script, style, noscript, .likes-container, .like-button-container, .reactions-display, .likes-list, .spoiler-toggle, img').forEach(n => n.remove());
// Ссылки → markdown
clone.querySelectorAll('a[href]').forEach(a => {
const href = a.href;
const text = a.textContent.trim();
if (href && text && !href.startsWith('javascript:')) {
a.replaceWith(`[${text}](${href})`);
}
});
// HTML → текст
return clone.innerHTML
.replace(/<br\s*\/?>/gi, '\n')
.replace(/<\/p>/gi, '\n\n')
.replace(/<\/div>/gi, '\n')
.replace(/<[^>]+>/g, '')
.replace(/ /gi, ' ')
.replace(/&/gi, '&')
.replace(/</gi, '<')
.replace(/>/gi, '>')
.replace(/"/gi, '"')
.replace(/\n{3,}/g, '\n\n')
.trim();
}
/**
* Копировать текст в буфер обмена
*/
async function copyToClipboard(text) {
try {
await navigator.clipboard.writeText(text);
return true;
} catch {
return false;
}
}
/**
* Показать toast уведомление
*/
function toast(message, success = true) {
const el = document.createElement('div');
el.style.cssText = `
position: fixed; top: 20px; right: 20px; z-index: 999999;
background: #1e1e2e; color: ${success ? '#a6e3a1' : '#f38ba8'};
padding: 12px 18px; border-radius: 8px;
font: 14px/1.4 system-ui, sans-serif;
box-shadow: 0 8px 30px rgba(0,0,0,.5);
border-left: 4px solid ${success ? '#a6e3a1' : '#f38ba8'};
transform: translateX(120%); transition: transform .3s ease;
`;
el.textContent = message;
document.body.appendChild(el);
requestAnimationFrame(() => el.style.transform = 'translateX(0)');
setTimeout(() => {
el.style.transform = 'translateX(120%)';
setTimeout(() => el.remove(), 300);
}, 500);
}
/**
* Обработчик клика — копировать пост
*/
async function handleCopyClick(e, postContainer) {
e.preventDefault();
e.stopPropagation();
const contentEl = getPostContent(postContainer);
if (!contentEl) {
toast('❌ Не удалось найти контент', false);
return;
}
const text = prepareContentForCopy(contentEl);
const ok = await copyToClipboard(text);
if (ok) {
toast('✅ Скопировано');
} else {
toast('❌ Ошибка копирования', false);
}
}
/**
* Заменить кнопки "Жалоба" на "Копировать"
*/
function replaceFlagButtons() {
// Ищем ссылки с reportPost в href
const links = document.querySelectorAll('a[href*="reportPost"]');
for (const link of links) {
if (link.dataset.bgCopyReplaced) continue;
link.dataset.bgCopyReplaced = 'true';
const postContainer = link.closest('.modern-post-container');
if (!postContainer) continue;
// Меняем внешний вид (текст уже скрыт через CSS)
link.title = 'Копировать пост';
link.style.cursor = 'pointer';
// Вешаем обработчик
link.addEventListener('click', (e) => handleCopyClick(e, postContainer), true);
}
}
/**
* Инициализация
*/
function init() {
replaceFlagButtons();
// Debounced MutationObserver
let debounceTimer = null;
const observer = new MutationObserver(() => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(replaceFlagButtons, 300);
});
observer.observe(document.body, { childList: true, subtree: true });
console.log('[Binguru Copy] ✅ Скрипт загружен');
}
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', () => setTimeout(init, 100));
} else {
setTimeout(init, 100);
}
})();For immediate assistance, please email our customer support: [email protected]