đéo có hình chó nó tin
Cái nồi có lắp

Cái này là tao dùng ChatGPT nhờ nó viết giùm, sau nó nhờ Grok-3 sửa lại cho chạy ổn định.
Đã test trên PC và điện thoại đều chạy tốt hết.
Tụi bây cài Violentmonkey vào, mở extension lên bấm dấu +, rồi copy & paste script này vào, Save lại
Firefox:
addons.mozilla.org
Chrome: https://chromewebstore.google.com/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag
Sau đó tụi bây vào chọn Quản lý từ khóa & domain
Tao để mặc định là mấy từ khóa này và domain là xamvn.nl, cái này có thể áp dụng cho toàn bộ forum xài Xenforo khác.
Đã test trên PC và điện thoại đều chạy tốt hết.
Tụi bây cài Violentmonkey vào, mở extension lên bấm dấu +, rồi copy & paste script này vào, Save lại
Firefox:

Violentmonkey – Get this Extension for 🦊 Firefox (en-US)
Download Violentmonkey for Firefox. Userscript support for browsers, open source.
Chrome: https://chromewebstore.google.com/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag
JavaScript:
// ==UserScript==
// @name XenForo Keyword Post Filter
// @namespace https://yourdomain.com
// @version 2.3
// @description Ẩn bài trong Newsfeed và bọc bài trong thread bằng Spoiler trên cả PC và mobile
// @author Bạn
// @match *://*/*
// @grant GM_registerMenuCommand
// ==/UserScript==
(function() {
'use strict';
// Khởi tạo từ khóa và domain từ localStorage, mặc định là rỗng nếu không có
let keywords = JSON.parse(localStorage.getItem('xenforo_keywords') || '[]');
let allowedDomains = JSON.parse(localStorage.getItem('xenforo_domains') || '[]');
function saveSettings() {
localStorage.setItem('xenforo_keywords', JSON.stringify(keywords));
localStorage.setItem('xenforo_domains', JSON.stringify(allowedDomains));
}
function wrapInSpoiler(element, originalContent) {
const details = document.createElement('details');
details.style.margin = '10px 0';
const summary = document.createElement('summary');
summary.textContent = 'Cảnh báo từ khóa bị chặn';
summary.style.fontSize = '12px';
summary.style.fontWeight = 'bold';
summary.style.boxShadow = '2px 2px 4px rgba(0, 0, 0, 0.3)';
summary.style.backgroundColor = '#800080';
summary.style.color = '#fff';
summary.style.padding = '5px 10px';
summary.style.cursor = 'pointer';
summary.style.display = 'inline-block';
summary.style.userSelect = 'none';
const content = document.createElement('div');
content.innerHTML = originalContent;
content.style.padding = '10px';
// Thêm sự kiện touch cho mobile
summary.addEventListener('touchstart', (e) => {
e.preventDefault();
details.open = !details.open;
});
details.appendChild(summary);
details.appendChild(content);
element.innerHTML = '';
element.appendChild(details);
}
function hidePosts() {
// 1. Ẩn thread trong Newsfeed (PC và mobile)
const newsfeedSelectors = [
'.structItem--thread', // PC
'.structItem' // Mobile
];
newsfeedSelectors.forEach(selector => {
document.querySelectorAll(selector).forEach(item => {
const textContent = item.textContent.toLowerCase();
if (keywords.some(keyword => textContent.includes(keyword.toLowerCase()))) {
item.style.display = 'none';
}
});
});
// 2. Bọc bài viết trong thread bằng Spoiler (PC và mobile)
const postSelectors = [
'.message-body .bbWrapper', // PC
'.message-content', // Mobile
'.bbWrapper' // Fallback
];
postSelectors.forEach(selector => {
document.querySelectorAll(selector).forEach(post => {
const textContent = post.textContent.toLowerCase();
if (keywords.some(keyword => textContent.includes(keyword.toLowerCase()))) {
if (!post.querySelector('details')) {
const originalContent = post.innerHTML;
wrapInSpoiler(post, originalContent);
}
}
});
});
}
function observeMutations() {
let timeout;
const observer = new MutationObserver(() => {
clearTimeout(timeout);
timeout = setTimeout(hidePosts, 150);
});
observer.observe(document.body, { childList: true, subtree: true });
}
function createPopup() {
let overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.background = 'rgba(0,0,0,0.5)';
overlay.style.display = 'flex';
overlay.style.justifyContent = 'center';
overlay.style.alignItems = 'center';
overlay.style.zIndex = '10000';
let popup = document.createElement('div');
popup.style.background = 'white';
popup.style.padding = '20px';
popup.style.borderRadius = '10px';
popup.style.boxShadow = '0 0 10px rgba(0,0,0,0.3)';
popup.style.width = '80%';
popup.style.maxWidth = '400px';
let title = document.createElement('h3');
title.textContent = 'Cài đặt Bộ Lọc';
popup.appendChild(title);
let keywordLabel = document.createElement('label');
keywordLabel.textContent = 'Danh sách từ khóa (cách nhau bởi dấu phẩy):';
let keywordInput = document.createElement('textarea');
keywordInput.style.width = '100%';
keywordInput.style.height = '60px';
keywordInput.value = keywords.join(',');
let domainLabel = document.createElement('label');
domainLabel.textContent = 'Danh sách website áp dụng (cách nhau bởi dấu phẩy):';
let domainInput = document.createElement('textarea');
domainInput.style.width = '100%';
domainInput.style.height = '40px';
domainInput.value = allowedDomains.join(',');
let saveBtn = document.createElement('button');
saveBtn.textContent = 'Lưu';
saveBtn.style.marginRight = '10px';
saveBtn.onclick = () => {
keywords = keywordInput.value.split(',').map(k => k.trim()).filter(k => k);
allowedDomains = domainInput.value.split(',').map(d => d.trim()).filter(d => d);
saveSettings();
document.body.removeChild(overlay);
alert('Cài đặt đã lưu! Tải lại trang hoặc đợi vài giây để áp dụng.');
hidePosts();
};
let cancelBtn = document.createElement('button');
cancelBtn.textContent = 'Hủy';
cancelBtn.onclick = () => document.body.removeChild(overlay);
popup.appendChild(keywordLabel);
popup.appendChild(keywordInput);
popup.appendChild(document.createElement('br'));
popup.appendChild(domainLabel);
popup.appendChild(domainInput);
popup.appendChild(document.createElement('br'));
popup.appendChild(saveBtn);
popup.appendChild(cancelBtn);
overlay.appendChild(popup);
document.body.appendChild(overlay);
}
GM_registerMenuCommand('Quản lý từ khóa & domain', createPopup);
if (!allowedDomains.length || allowedDomains.some(domain => window.location.hostname.includes(domain))) {
hidePosts();
observeMutations();
}
})();
Sau đó tụi bây vào chọn Quản lý từ khóa & domain

Tao để mặc định là mấy từ khóa này và domain là xamvn.nl, cái này có thể áp dụng cho toàn bộ forum xài Xenforo khác.

Sửa lần cuối: