// ==UserScript== // @name Image Loader Placeholder Remover // @namespace blankie-scripts // @match http*://*/* // @grant none // @version 1.15.1 // @author blankie // @run-at document-end // @description Removes image loading placeholders // ==/UserScript== "use strict"; function isUrlLike(url) { return url && /^(?:\/|https?:\/\/)\S+$/.test(url); } function findUrl(element) { if (window.location.host === "www.vice.com") { let picture = element.parentElement; let source = picture && picture.localName === "picture" ? picture.querySelector("source") : null; if (source) { return source.srcset; } } // Examples of data-src: // - https://closeronline.co.uk // - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex // - https://daramiblog.com // - https://daramiblog.com/how-to-group-irregular-verbs-for-more-efficient-learning/ // - https://www.bleepingcomputer.com/ // - https://www.bleepingcomputer.com/news/microsoft/windows-11-snipping-tool-privacy-bug-exposes-cropped-image-content/ // - https://blog.joshumax.me/general/2021/08/11/running-doom-on-captioncall.html // - https://legendsoflocalization.com/common-problems-when-translating-games-into-japanese/ // - https://knowyourmeme.com/ // - https://knowyourmeme.com/memes/saddam-husseins-hiding-place if (isUrlLike(element.dataset.src)) { return element.dataset.src; } for (let attr of element.attributes) { // Examples of lazy: // - https://daramiblog.com/ // - https://daramiblog.com/how-to-group-irregular-verbs-for-more-efficient-learning/ // - https://www.theautopian.com/ // - https://www.theautopian.com/nobody-wants-touch-screen-glove-box-latches-and-it-needs-to-stop-now/ // - https://vulcan.io/blog/ // - https://vulcan.io/blog/ai-hallucinations-package-risk // Examples of src: // - https://vulcan.io/blog/ // - https://vulcan.io/blog/ai-hallucinations-package-risk // Examples of loading: // - https://closeronline.co.uk // - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex // Examples of original: // - https://www.pcgamer.com/ // - https://www.pcgamer.com/windows-95-theme-for-windows-10/ if (!attr.name.includes("lazy") && !(attr.name.includes("src") && attr.name !== "src") && !attr.name.includes("loading") && !attr.name.includes("original")) { continue; } if (!isUrlLike(attr.value)) { continue; } return attr.value; } return null; } function unhideElement(element) { let style = getComputedStyle(element); // Examples of opacity: // - https://closeronline.co.uk // - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex // - https://www.vice.com/en/article/dy73n7/ehallpass-1000-thousand-schools-monitor-bathroom // - https://daramiblog.com/ // - https://daramiblog.com/how-to-group-irregular-verbs-for-more-efficient-learning/ // - https://www.wired.com/ // - https://www.wired.com/story/researcher-fooled-a-google-ai-into-thinking-a-rifle-was-a-helicopter/ if (style.opacity === "0") { element.style.opacity = 1; } // Examples of display: // - https://closeronline.co.uk // - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex if (style.display === "none") { element.style.display = "block"; } } function getLazyloaderClasses(element) { let classes = []; for (let className of element.classList) { // Examples of loading: // - https://closeronline.co.uk // - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex // Examples of lazy: // - https://www.vice.com/en/article/dy73n7/ehallpass-1000-thousand-schools-monitor-bathroom // - https://www.pcgamer.com/ // - https://www.pcgamer.com/windows-95-theme-for-windows-10/ // - https://www.theautopian.com/ // - https://www.theautopian.com/nobody-wants-touch-screen-glove-box-latches-and-it-needs-to-stop-now/ // - https://vulcan.io/blog/ // - https://vulcan.io/blog/ai-hallucinations-package-risk // Examples of responsive: // - https://www.vice.com/en/article/dy73n7/ehallpass-1000-thousand-schools-monitor-bathroom // - https://www.wired.com (it's a parent of lazyloaded s) // - https://www.wired.com/story/researcher-fooled-a-google-ai-into-thinking-a-rifle-was-a-helicopter/ (it's a parent of lazyloaded s) // Examples of preload: // - https://restofworld.org/ // - https://restofworld.org/2023/parent-facing-matchmaking-apps-china/ // Examples of placeholder: // - https://theconversation.com // - https://theconversation.com/yall-that-most-southern-of-southernisms-is-going-mainstream-and-its-about-time-193265 if (className.includes("loading") || className.includes("lazy") || className.includes("responsive") || className.includes("preload") || className.includes("placeholder")) { classes.push(className); } } return classes; } function removePlaceholder(img) { let hasLinkParent = false; let parentElement = img.parentElement; while (parentElement) { hasLinkParent = hasLinkParent || parentElement.localName === "a"; // Examples of hidden parents: // - https://www.wired.com/ // - https://www.wired.com/story/researcher-fooled-a-google-ai-into-thinking-a-rifle-was-a-helicopter/ let lazyLoaderClasses = getLazyloaderClasses(parentElement); if (lazyLoaderClasses.length !== 0) { unhideElement(parentElement); // Examples of pages with a blur applied to lazyloader classes: // - https://restofworld.org/ // - https://restofworld.org/2023/parent-facing-matchmaking-apps-china/ parentElement.classList.remove(...lazyLoaderClasses); } parentElement = parentElement.parentElement; } let url = findUrl(img); if (!url) { return; } let originalUrl = url; if (window.location.host === "www.vice.com") { let picture = img.parentElement; img.style.filter = "none"; picture.style.opacity = 1; let urlObject = new URL(url, window.location); urlObject.search = ""; originalUrl = urlObject.href; urlObject.search = "?resize=1024:*"; url = urlObject.href; for (let source of picture.querySelectorAll("source")) { source.remove(); } } else if (window.location.host === "closeronline.co.uk") { let urlObject = new URL(url, window.location); urlObject.search = ""; originalUrl = urlObject.href; img.closest(".image-container").querySelector(".image-loading").remove(); } else if (window.location.host === "theconversation.com") { let urlObject = new URL(url, window.location); urlObject.search = ""; originalUrl = urlObject.href; } img.src = url; unhideElement(img); img.classList.remove(...getLazyloaderClasses(img)); if (!hasLinkParent) { let wrapper = document.createElement("a"); img.replaceWith(wrapper); wrapper.href = originalUrl; wrapper.appendChild(img); } } for (let img of document.querySelectorAll("img")) { removePlaceholder(img); } // the reason we check for mutations for 1s after the page loads is because of