Remove the ads side bar on desktop, and the bottom ads banner on mobile. Also removes ad related popups.
// ==UserScript==
// @name Photopea adds remover
// @namespace https://www.photopea.com/
// @version 4/13/2026
// @description Remove the ads side bar on desktop, and the bottom ads banner on mobile. Also removes ad related popups.
// @author pooiod7
// @match https://*.photopea.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=photopea.com
// @run-at document-end
// @grant none
// ==/UserScript==
(function() {
'use strict';
window.originalVisualViewport = window.visualViewport;
async function addCustomEvent() {
// mobile devices get adds on the bottom, so push them out
if (window.screen.width < 750 && /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent)) {
document.addEventListener('resizecanvas', () => {
window.innerHeight = document.documentElement.clientHeight + (100);
document.body.style.overflow = "hidden";
});
} else {
document.addEventListener('resizecanvas', async () => {
var app = document.querySelector('.flexrow.app');
var viewportWidth = window.innerWidth;
var docWidth = document.documentElement.clientWidth;
var target = Array.from(app.children).find(function(d) {
return d.querySelector('.alertcont');
})
Array.from(app.children).forEach(function(el) {
if(el !== target){
el.style.display = 'none';
}
})
var inner = app.querySelector('.flexrow .panelblock.mainblock');
if(inner){
var rect = inner.getBoundingClientRect();
var offset = viewportWidth - rect.width;
var pageWidth = docWidth;
var adsWidth = offset;
var newWidth = pageWidth + adsWidth;
document.documentElement.style.width = newWidth + 'px';
document.body.style.width = newWidth + 'px';
Object.defineProperty(window, 'visualViewport', {
configurable: true,
value:new Proxy(originalVisualViewport, {
get: function(target, property){
if (property == 'width'){
return pageWidth + adsWidth;
}
return target[property];
}
})
})
Object.defineProperty(window, 'innerWidth', {
configurable: true,
get: function(){
return pageWidth + adsWidth;
}
})
// imagine using intervals
if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
setTimeout(()=> {
rect = inner.getBoundingClientRect();
if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
}, 100);
setTimeout(()=> {
rect = inner.getBoundingClientRect();
if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
}, 500);
setTimeout(()=> {
rect = inner.getBoundingClientRect();
if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
}, 1000);
}
});
}
}
document.documentElement.setAttribute('onreset', `(${addCustomEvent})()`);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
function resize(event = {}) {
if (!event.skip) {
document.dispatchEvent(new CustomEvent('resizecanvas'));
var resizeEvent = new Event('resize');
resizeEvent.skip = true;
window.dispatchEvent(resizeEvent);
}
}
let debounce;
window.addEventListener('resize', event => {
clearTimeout(debounce);
debounce = setTimeout(() => resize(event), 100);
});
function doresizewhenready() {
new Promise((resolve) => {
const observer = new MutationObserver(() => {
const element = document.querySelector(".flexrow.app .flexrow .panelblock.mainblock");
if (element) {
observer.disconnect();
resolve(element);
window.dispatchEvent(new Event("resize"));
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
});
} doresizewhenready();
setTimeout(doresizewhenready, 1000);
setTimeout(doresizewhenready, 2000);
document.querySelectorAll("div.alertpanel.tpanel").forEach(removeAlert);
// remove the "something is changing our source code" popup
const observer = new MutationObserver(mutations => {
for (const m of mutations) {
for (const node of m.addedNodes) {
if (node.nodeType !== 1) continue;
if (node.matches?.("div.alertpanel.tpanel")) {
if (node.textContent.includes("changing our source")) {
node.remove();
}
}
node.querySelectorAll?.("div.alertpanel.tpanel").forEach(removeAlert);
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
setTimeout(() => observer.disconnect(), 10000);
// Hide adblocker popup
const check = () => {
const els = Array.from(document.querySelectorAll("*"));
for (const el of els) {
if (el.innerText && el.innerText.includes("Are you using an ad blocker")) {
console.log("Detected target text");
const btn = el.parentElement?.parentElement?.querySelector("button");
if (btn) {
setTimeout(() => {
btn.click();
}, 200);
}
}
}
};
const obs = new MutationObserver(check);
obs.observe(document.body, { childList: true, subtree: true });
check();
})();