Removes ads from Protopage with futureproofing and safe execution
// ==UserScript==
// @name Protopage Remove Advertisements
// @namespace http://tampermonkey.net/protopageadremoval
// @include https://www.protopage.com/*
// @grant none
// @version 1.0.2
// @description Removes ads from Protopage with futureproofing and safe execution
// @author xechostormx
// @license MIT
// @run-at document-body
// ==/UserScript==
(function () {
'use strict';
// Configuration for ad selectors (refined to avoid overreach)
const AD_SELECTORS = [
'#ad-0', // Primary ad element (confirmed via inspection)
'[id^="ad-"]', // Dynamic ad IDs starting with "ad-" (e.g., ad-1, ad-2)
'.ad-banner', // Hypothetical class for ads (adjust based on inspection)
'.advertisement' // Another potential ad class (adjust based on inspection)
];
// Safely remove ad elements
function removeAds() {
let adsRemoved = 0;
const body = document.body;
if (!body) {
console.error('Body not found, aborting ad removal.');
return;
}
AD_SELECTORS.forEach(selector => {
const ads = document.querySelectorAll(selector);
ads.forEach(ad => {
if (ad && ad.parentNode && ad !== body && !ad.contains(body)) {
ad.parentNode.removeChild(ad);
adsRemoved++;
} else {
console.warn(`Skipped potential invalid ad removal for selector: ${selector}`);
}
});
});
if (adsRemoved > 0) {
console.log(`Removed ${adsRemoved} ad(s) from Protopage at ${new Date().toLocaleTimeString()}`);
} else {
console.log('No ads found to remove at ' + new Date().toLocaleTimeString());
}
}
// Observe DOM changes for dynamically loaded ads
function observeAds() {
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.addedNodes.length) {
removeAds();
}
});
});
const targetNode = document.body;
if (targetNode) {
observer.observe(targetNode, { childList: true, subtree: true });
console.log('Ad Zapper observer started at ' + new Date().toLocaleTimeString());
} else {
console.error('Body not found for observation.');
}
// Cleanup on page unload
window.addEventListener('unload', () => {
observer.disconnect();
});
}
// Initialize when DOM is ready and a key element exists
function init() {
// Wait for a key Protopage element (e.g., content area) to ensure page is loaded
const contentArea = document.querySelector('#page-content') || document.querySelector('.page-container');
if (document.body && contentArea) {
removeAds();
observeAds();
} else {
console.warn('Document not fully loaded, retrying...');
setTimeout(init, 500); // Retry after 500ms
}
}
// Start the script
init();
})();