Long press to enter picker mode, click element to hide it forever
// ==UserScript==
// @name Elements Blocker
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Long press to enter picker mode, click element to hide it forever
// @author smoochie
// @match *://*/*
// @run-at document-end
// @grant none
// @license MIT
// ==/UserScript==
(function () {
'use strict';
const STORAGE_KEY = 'element-blocker';
const LONG_PRESS_MS = 600;
let pickerActive = false;
let pressTimer = null;
let highlighted = null;
function getStored() {
try {
return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
} catch { return {}; }
}
function applyStored() {
const all = getStored();
const host = location.hostname;
const selectors = all[host] || [];
selectors.forEach(sel => {
try {
document.querySelectorAll(sel).forEach(el => {
el.style.cssText = 'display:none!important';
});
} catch {}
});
}
function saveSelector(sel) {
const all = getStored();
const host = location.hostname;
if (!all[host]) all[host] = [];
if (!all[host].includes(sel)) {
all[host].push(sel);
localStorage.setItem(STORAGE_KEY, JSON.stringify(all));
}
}
function getSelector(el) {
if (el.id) return `#${CSS.escape(el.id)}`;
const parts = [];
let current = el;
while (current && current !== document.body) {
let part = current.tagName.toLowerCase();
if (current.id) {
part = `#${CSS.escape(current.id)}`;
parts.unshift(part);
break;
}
if (current.className && typeof current.className === 'string') {
const classes = current.className.trim().split(/\s+/).slice(0, 2);
part += '.' + classes.map(c => CSS.escape(c)).join('.');
}
const siblings = current.parentElement
? [...current.parentElement.children].filter(c => c.tagName === current.tagName)
: [];
if (siblings.length > 1) {
const idx = siblings.indexOf(current) + 1;
part += `:nth-of-type(${idx})`;
}
parts.unshift(part);
current = current.parentElement;
}
return parts.join(' > ');
}
function showToast(msg, color = '#1a3a5c') {
const old = document.getElementById('eb-toast');
if (old) old.remove();
const toast = document.createElement('div');
toast.id = 'eb-toast';
toast.textContent = msg;
toast.style.cssText = `
position: fixed;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
background: ${color};
color: #fff;
padding: 10px 20px;
font-size: 14px;
font-family: sans-serif;
z-index: 2147483647;
pointer-events: none;
white-space: nowrap;
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 2500);
}
function highlight(el) {
if (highlighted === el) return;
clearHighlight();
highlighted = el;
el.dataset.ebOutline = el.style.outline || '';
el.style.outline = '2px solid red';
el.style.outlineOffset = '2px';
}
function clearHighlight() {
if (highlighted) {
highlighted.style.outline = highlighted.dataset.ebOutline || '';
delete highlighted.dataset.ebOutline;
highlighted = null;
}
}
function enterPicker() {
pickerActive = true;
showToast('🔴 Selection mode - click on an item to hide it');
document.body.style.cursor = 'crosshair';
}
function exitPicker() {
pickerActive = false;
clearHighlight();
document.body.style.cursor = '';
}
document.addEventListener('touchstart', e => {
pressTimer = setTimeout(() => {
if (!pickerActive) enterPicker();
else exitPicker();
}, LONG_PRESS_MS);
}, { passive: true });
document.addEventListener('touchend', () => {
clearTimeout(pressTimer);
}, { passive: true });
document.addEventListener('touchmove', () => {
clearTimeout(pressTimer);
}, { passive: true });
document.addEventListener('mouseover', e => {
if (!pickerActive) return;
highlight(e.target);
});
document.addEventListener('click', e => {
if (!pickerActive) return;
e.preventDefault();
e.stopPropagation();
const el = e.target;
const sel = getSelector(el);
saveSelector(sel);
el.style.cssText = 'display:none!important';
showToast('✅ The element has been hidden and saved', '#1a6644');
exitPicker();
}, true);
document.addEventListener('keydown', e => {
if (e.key === 'Escape' && pickerActive) {
exitPicker();
showToast('❌ Selection mode has been canceled', '#888');
}
});
applyStored();
setTimeout(applyStored, 1500);
setTimeout(applyStored, 4000);
const observer = new MutationObserver(applyStored);
observer.observe(document.body, { childList: true, subtree: true });
})();