From d319934631a6274a21e4028d95476c722c1a5589 Mon Sep 17 00:00:00 2001 From: blankie Date: Sun, 27 Aug 2023 14:30:42 +1000 Subject: [PATCH] Update Image Loader Placeholder Remover to 1.17.0 - Slightly simplify class and attribute finding code - Selectively unapply/reverse CSS attributes from lazyloader classes - Make images visible on www.washingtonpost.com --- Image Loader Placeholder Remover.user.js | 140 ++++++++++++++++------- 1 file changed, 100 insertions(+), 40 deletions(-) diff --git a/Image Loader Placeholder Remover.user.js b/Image Loader Placeholder Remover.user.js index e6028dd..4e14b89 100644 --- a/Image Loader Placeholder Remover.user.js +++ b/Image Loader Placeholder Remover.user.js @@ -3,7 +3,7 @@ // @namespace blankie-scripts // @match http*://*/* // @grant none -// @version 1.16.2 +// @version 1.17.0 // @author blankie // @run-at document-end // @description Removes image loading placeholders @@ -59,7 +59,7 @@ function findUrl(element) { // - https://www.pcgamer.com/windows-95-theme-for-windows-10/ // Example of img-url: // - https://www.makeuseof.com/windows-11-resize-taskbar/ - if (!attr.name.includes("lazy") && !(attr.name.includes("src") && attr.name !== "src") && !attr.name.includes("loading") && !attr.name.includes("original") && !attr.name.includes("img-url")) { + if (/lazy|src|loading|original|img-url/.test(attr.name) && attr.name !== "src") { continue; } if (!isUrlLike(attr.value)) { @@ -71,34 +71,6 @@ function findUrl(element) { 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"; - } - - // Example: https://www.makeuseof.com/windows-11-resize-taskbar/ - if (window.location.host === "www.makeuseof.com") { - element.style.paddingBottom = 0; - } -} - function getLazyloaderClasses(element) { let classes = []; @@ -124,7 +96,10 @@ function getLazyloaderClasses(element) { // 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")) { + // Examples of image (though admittedly a hack for cloneLazyloaderTree): + // - https://restofworld.org/ + // - https://restofworld.org/2023/parent-facing-matchmaking-apps-china/ + if (/loading|lazy|responsive|preload|placeholder|image/.test(className)) { classes.push(className); } } @@ -132,6 +107,92 @@ function getLazyloaderClasses(element) { return classes; } +function cloneLazyloaderTree(element, elementLazyLoaderClasses) { + let topMostParent = null; + let followingTopMostParent = element.parentElement; + let bottomMostChild = null; + + while (followingTopMostParent.localName !== "body") { + let clone = document.createElement(followingTopMostParent.localName); + clone.classList.add(...getLazyloaderClasses(followingTopMostParent)); + if (topMostParent) { + clone.append(topMostParent); + } + topMostParent = clone; + if (!bottomMostChild) { + bottomMostChild = clone; + } + + followingTopMostParent = followingTopMostParent.parentElement; + } + + let clone = document.createElement(element.localName); + clone.classList.add(...elementLazyLoaderClasses); + + if (bottomMostChild) { + bottomMostChild.append(clone); + bottomMostChild = clone; + } else { + topMostParent = bottomMostChild = clone; + } + + return [topMostParent, bottomMostChild]; +} + +function unhideElement(element, lazyLoaderClasses) { + 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"; + } + + // Example: https://www.makeuseof.com/windows-11-resize-taskbar/ + if (window.location.host === "www.makeuseof.com") { + element.style.paddingBottom = 0; + } + + // We check if the classes discriminate lazyloaded images, just in case + // We can't remove the lazyload classes from the image, because: + // - https://legendsoflocalization.com/japans-mysterious-love-of-the-word-lets/#why-lets-is-so-common + // - https://www.wired.com/story/why-do-printers-still-suck/ + // However, some sites use the classes to blur and/or change the opacity of images + + let [toRemove, toExamine] = cloneLazyloaderTree(element, lazyLoaderClasses); + document.body.append(toRemove); + let classStyle = getComputedStyle(toExamine); + + // Example of opacity === "0.75": + // https://www.404media.co/welcome-to-404-media/ + if (classStyle.opacity !== "1") { + element.style.opacity = 1; + } + + // Examples of blur: + // - https://www.404media.co/welcome-to-404-media/ + // - https://restofworld.org/ + // - https://restofworld.org/2023/parent-facing-matchmaking-apps-china/ + if (classStyle.filter.includes("blur(")) { + element.style.filter = classStyle.filter.replaceAll(/blur\(.+?\)/g, "blur(0px)"); + } + + toRemove.remove(); +} + function removePlaceholder(img) { @@ -144,17 +205,19 @@ function removePlaceholder(img) { // - 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); + unhideElement(parentElement, lazyLoaderClasses); } parentElement = parentElement.parentElement; } let picture = img.closest("picture"); + // Example of a would've been viewable image being blurred: + // https://www.washingtonpost.com/nation/2023/07/21/ocean-color-changing-climate-change/ + if (window.location.host === "www.washingtonpost.com") { + img.parentElement.style.filter = img.parentElement.style.filter.replaceAll(/blur\(.+?\)/g, "blur(0)"); + } + let url = findUrl(img); if (!url) { return; @@ -183,10 +246,7 @@ function removePlaceholder(img) { } img.src = url; - unhideElement(img); - // commented out as some sites may visually break, such as: - // https://legendsoflocalization.com/japans-mysterious-love-of-the-word-lets/#why-lets-is-so-common - //img.classList.remove(...getLazyloaderClasses(img)); + unhideElement(img, getLazyloaderClasses(img)); // apparently, remaining s can fuck up image rendering (firefox still thinks that the contains an empty image?) // https://gizmodo.com/reddit-news-blackout-protest-is-finally-over-reddit-won-1850707509