Habr hide cover image in spoiler

Hides cover image in spoiler; image is loaded on open.

目前為 2025-02-02 提交的版本,檢視 最新版本

// ==UserScript==
// @name           Habr hide cover image in spoiler
// @name:ru        Хабр спрятать КДПВ в спойлер
// @namespace      habr_hide_cover_image
// @version        1.0.1
// @description    Hides cover image in spoiler; image is loaded on open.
// @description:ru Прячет КДПВ в спойлер; картинка загружается при открытии.
// @author         Dystopian
// @license        WTFPL
// @match          https://habr.com/*
// @icon           https://habr.com/favicon.ico
// @grant          none
// ==/UserScript==

'use strict';

const selectors = [
    'div.tm-article-snippet__cover_cover.tm-article-snippet__cover:not(details div)',
    'div.tm-article-snippet__cover.tm-article-snippet__cover_cover:not(details div)',
    'div.article-formatted-body.article-formatted-body_version-1 a:not(details a)',
];

function hide(element) {
    const details = document.createElement('details');
    // details.className = 'spoiler';
    details.style.border = "1px dashed rgba(128, 128, 128, 0.5)";
    const summary = document.createElement('summary');
    summary.textContent = 'Hidden Image';
    element.parentNode.insertBefore(details, element);
    details.appendChild(summary);
    details.appendChild(element);
    details.addEventListener('toggle', () => {
        if (details.open) {
            details.querySelectorAll('img[data-src]:not([src])').forEach(img => {
                img.src = img.getAttribute('data-src');
            });
        }
    });
}
function check() {
    document.querySelectorAll('div.tm-article-body.tm-article-snippet__lead').forEach(parent => {
        selectors.forEach(selector => {
            parent.querySelectorAll(selector).forEach(element => {
                if (element.querySelector('img')) {
                    element.querySelectorAll('img:not([data-src])').forEach(img => {
                        img.setAttribute('data-src', img.src);
                        img.removeAttribute('src');
                    });
                    hide(element);
                }
            });
        });
        parent.querySelectorAll('div.article-formatted-body.article-formatted-body_version-1 img:not(details img)').forEach(element => {
            if (!element.hasAttribute('data-src')) {
                element.setAttribute('data-src', element.src);
                element.removeAttribute('src');
            }
            hide(element);
        });
    });
    document.querySelectorAll('div.tm-post-snippet').forEach(parent => {
        parent.querySelectorAll('figure.full-width:not(details figure)').forEach(element => {
            if (element.querySelector('img')) {
                element.querySelectorAll('img:not([data-src])').forEach(img => {
                    img.setAttribute('data-src', img.src);
                    img.removeAttribute('src');
                });
                hide(element);
            }
        });
    });
}

function ready(fn) {
    const { readyState } = document;
    if (readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            fn();
        });
    } else {
        fn();
    }
}

ready(() => {
    check();
    const observer = new MutationObserver(() => {
        observer.disconnect();
        check();
        observer.observe(document.body, { childList: true, subtree: true });
    });
    observer.observe(document.body, { childList: true, subtree: true });
});