// ==UserScript==
// @name Block buyee/worldshopping popups everywhere
// @namespace https://dakidex.com
// @match *://*/*
// @run-at document-start
// @grant none
// @description Block buyee and worldshopping popups on all websites
// @version 1.1
// @license MIT
// ==/UserScript==
(function () {
'use strict';
const BLOCK_HOSTS = [
'connect.buyee.jp',
'worldshopping.jp',
'shop-js.worldshopping.jp',
'checkout-js.worldshopping.jp',
'checkout-api.worldshopping.jp'
];
function isBlockedUrl(u) {
if (!u) return false;
try {
const urlStr = String(u);
return BLOCK_HOSTS.some(host => urlStr.indexOf(host) !== -1);
} catch (e) { return false; }
}
// Remove any existing matching elements and Buyee banners
function removeExisting() {
try {
document.querySelectorAll('iframe,script').forEach(el => {
const src = el.src || (el.getAttribute && el.getAttribute('src')) || '';
if (isBlockedUrl(src)) el.remove();
});
// Remove Buyee banners by image src or alt text or containing text
document.querySelectorAll('img,div,span').forEach(el => {
const src = el.src || '';
const alt = el.alt || '';
const text = el.textContent || '';
if (
(src && src.includes('buyee')) ||
(alt && alt.toLowerCase().includes('buyee')) ||
(text && text.toLowerCase().includes('purchase via buyee'))
) {
// Remove parent container if it looks like a banner
let parent = el.closest('.border, .u-p-400, .u-px-400, .u-fw-bold, .typography-14');
if (parent) parent.remove();
else el.remove();
}
});
} catch (e) { /* ignore */ }
}
// Patch Document.createElement to neutralize src assignment for iframe/script
const origCreateElement = Document.prototype.createElement;
Document.prototype.createElement = function (tagName, options) {
const el = origCreateElement.call(this, tagName, options);
const tag = String(tagName).toLowerCase();
if (tag === 'iframe' || tag === 'script') {
// intercept setAttribute for src/data attributes
try {
const origSetAttr = el.setAttribute.bind(el);
el.setAttribute = function (name, value) {
if ((name === 'src' || name === 'data') && isBlockedUrl(value)) return;
return origSetAttr(name, value);
};
} catch (e) { /* ignore */ }
// override property setter for .src if prototype exposes it
try {
const proto = Object.getPrototypeOf(el);
const desc = Object.getOwnPropertyDescriptor(proto, 'src');
if (desc && typeof desc.set === 'function') {
Object.defineProperty(el, 'src', {
configurable: true,
enumerable: true,
get: function () { return desc.get.call(this); },
set: function (v) { if (isBlockedUrl(v)) return; return desc.set.call(this, v); }
});
}
} catch (e) { /* ignore */ }
}
return el;
};
// Intercept DOM insertion methods to block direct appends/insertions of blocked nodes
['appendChild', 'insertBefore', 'replaceChild'].forEach(fn => {
const orig = Node.prototype[fn];
if (!orig) return;
Node.prototype[fn] = function (node, ...args) {
try {
if (!node) return orig.call(this, node, ...args);
// If the node itself is a blocked iframe/script, drop it
if (node.nodeType === 1) {
const tag = (node.tagName || '').toLowerCase();
if (tag === 'iframe' || tag === 'script') {
const src = node.src || (node.getAttribute && node.getAttribute('src')) || '';
if (isBlockedUrl(src)) return node;
}
// Remove nested blocked elements before insertion
try {
const nested = node.querySelectorAll && node.querySelectorAll('iframe,script');
if (nested && nested.length) {
nested.forEach(n => {
const s = n.src || (n.getAttribute && n.getAttribute('src')) || '';
if (isBlockedUrl(s)) n.remove();
});
}
} catch (e) { /* ignore */ }
}
} catch (e) { /* ignore */ }
return orig.call(this, node, ...args);
};
});
// Observe DOM mutations and remove any newly added blocked frames/scripts and Buyee banners
const observer = new MutationObserver(mutations => {
for (const m of mutations) {
for (const n of m.addedNodes) {
try {
if (n.nodeType !== 1) continue;
const tag = (n.tagName || '').toLowerCase();
if (tag === 'iframe' || tag === 'script') {
const src = n.src || (n.getAttribute && n.getAttribute('src')) || '';
if (isBlockedUrl(src)) { n.remove(); continue; }
}
// remove blocked nested nodes
const nested = n.querySelectorAll && n.querySelectorAll('iframe,script');
if (nested && nested.length) {
nested.forEach(el => {
const s = el.src || (el.getAttribute && el.getAttribute('src')) || '';
if (isBlockedUrl(s)) el.remove();
});
}
// Remove Buyee banners in newly added nodes
const buyeeImgs = n.querySelectorAll && n.querySelectorAll('img,div,span');
if (buyeeImgs && buyeeImgs.length) {
buyeeImgs.forEach(el => {
const src = el.src || '';
const alt = el.alt || '';
const text = el.textContent || '';
if (
(src && src.includes('buyee')) ||
(alt && alt.toLowerCase().includes('buyee')) ||
(text && text.toLowerCase().includes('purchase via buyee'))
) {
let parent = el.closest('.border, .u-p-400, .u-px-400, .u-fw-bold, .typography-14');
if (parent) parent.remove();
else el.remove();
}
});
}
} catch (e) { /* ignore */ }
}
}
});
try {
observer.observe(document.documentElement || document, { childList: true, subtree: true });
} catch (e) { /* ignore */ }
// Patch existing elements' src setter defensively
function patchExistingProps() {
try {
document.querySelectorAll('iframe,script').forEach(el => {
try {
const proto = Object.getPrototypeOf(el);
const desc = Object.getOwnPropertyDescriptor(proto, 'src');
if (desc && typeof desc.set === 'function') {
Object.defineProperty(el, 'src', {
configurable: true,
enumerable: true,
get: function () { return desc.get.call(this); },
set: function (v) { if (isBlockedUrl(v)) return; return desc.set.call(this, v); }
});
}
} catch (e) { /* ignore */ }
});
} catch (e) { /* ignore */ }
}
// initial cleanup (run as early as possible)
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => { removeExisting(); patchExistingProps(); }, { once: true });
} else {
removeExisting();
patchExistingProps();
}
})();