Greasy Fork

来自缓存

Greasy Fork is available in English.

Open2ch Imgur Image Hider

open2ch.netでImgur画像を非表示にし、ポップアップ表示を防ぎ、非表示URLを管理するスクリプト

当前为 2025-02-28 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Open2ch Imgur Image Hider
// @namespace    http://tampermonkey.net/
// @version      0.9
// @description  open2ch.netでImgur画像を非表示にし、ポップアップ表示を防ぎ、非表示URLを管理するスクリプト
// @author       Anonymous
// @match        *://*.open2ch.net/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // ローカルストレージから非表示URLとデフォルト非表示設定を取得
    const hiddenUrls = new Set(GM_getValue('hiddenUrls', []));
    const defaultHide = GM_getValue('defaultHide', false);

    // 画像を非表示にする関数
    function hideImage(img, url) {
        if (img.previousSibling && img.previousSibling.classList?.contains('hide-container')) {
            return;
        }

        const container = document.createElement('div');
        container.classList.add('hide-container');
        container.style.display = 'inline-block';
        container.style.width = (img.width || 200) + 'px';
        container.style.height = (img.height || 'auto');
        container.innerHTML = '<span>[非表示画像]</span> <button class="show-btn">表示</button>';
        img.parentNode.insertBefore(container, img);
        img.style.display = 'none';
        img.removeAttribute('data-shown'); // 表示フラグをリセット

        // 「表示」ボタンのイベントリスナー
        container.querySelector('.show-btn').addEventListener('click', (event) => {
            event.stopPropagation();
            event.preventDefault();
            showImage(container, img, url);
            hiddenUrls.delete(url);
            GM_setValue('hiddenUrls', Array.from(hiddenUrls));
        });

        if (!hiddenUrls.has(url)) {
            hiddenUrls.add(url);
            GM_setValue('hiddenUrls', Array.from(hiddenUrls));
        }
    }

    // 画像を表示する関数
    function showImage(container, img, url) {
        img.style.display = '';
        img.setAttribute('data-shown', 'true'); // 表示フラグを設定
        container.parentNode.insertBefore(img, container);
        container.remove();

        // 既存の「非表示」ボタンがあれば削除
        const existingHideBtn = img.nextSibling;
        if (existingHideBtn && existingHideBtn.classList?.contains('hide-btn')) {
            existingHideBtn.remove();
        }

        // 新しい「非表示」ボタンを追加
        const hideBtn = document.createElement('button');
        hideBtn.textContent = '非表示';
        hideBtn.classList.add('hide-btn');
        hideBtn.style.marginLeft = '5px';
        hideBtn.addEventListener('click', (event) => {
            event.stopPropagation();
            event.preventDefault();
            hideImage(img, url);
        });
        img.parentNode.insertBefore(hideBtn, img.nextSibling);

        // 画像のクリックイベントを無効化
        img.addEventListener('click', (event) => {
            event.stopPropagation();
            event.preventDefault();
        });

        // 親要素のリンク動作を防止
        const parentLink = img.closest('a');
        if (parentLink) {
            parentLink.addEventListener('click', (event) => {
                if (event.target === img || event.target.classList.contains('hide-btn') || event.target.classList.contains('show-btn')) {
                    event.preventDefault();
                    event.stopPropagation();
                }
            });
        }
    }

    // 画像を処理する関数
    function processImages() {
        document.querySelectorAll('img[src^="https://i.imgur.com/"]').forEach(img => {
            const url = img.src;
            const isShown = img.getAttribute('data-shown') === 'true';

            if ((hiddenUrls.has(url) || defaultHide) && !isShown) {
                if (img.style.display !== 'none' && !img.previousSibling?.classList?.contains('hide-container')) {
                    hideImage(img, url);
                }
            } else if (!isShown && (!img.nextSibling || !img.nextSibling.classList?.contains('hide-btn'))) {
                const hideBtn = document.createElement('button');
                hideBtn.textContent = '非表示';
                hideBtn.classList.add('hide-btn');
                hideBtn.style.marginLeft = '5px';
                hideBtn.addEventListener('click', (event) => {
                    event.stopPropagation();
                    event.preventDefault();
                    hideImage(img, url);
                });
                img.parentNode.insertBefore(hideBtn, img.nextSibling);
                img.addEventListener('click', (event) => {
                    event.stopPropagation();
                    event.preventDefault();
                });

                // 親要素のリンク動作を防止
                const parentLink = img.closest('a');
                if (parentLink) {
                    parentLink.addEventListener('click', (event) => {
                        if (event.target === img || event.target.classList.contains('hide-btn')) {
                            event.preventDefault();
                            event.stopPropagation();
                        }
                    });
                }
            }
        });
    }

    // 初回読み込み時に画像を処理
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        processImages();
    } else {
        window.addEventListener('DOMContentLoaded', processImages);
    }

    // 動的に追加される画像に対応
    const observer = new MutationObserver((mutations) => {
        mutations.forEach(() => processImages());
    });
    observer.observe(document.body, { childList: true, subtree: true });

    // デフォルト非表示設定を切り替えるメニュー
    GM_registerMenuCommand('デフォルト非表示の切り替え', () => {
        const newValue = !defaultHide;
        GM_setValue('defaultHide', newValue);
        alert('デフォルト非表示が' + (newValue ? '有効' : '無効') + 'になりました。ページを再読み込みしてください。');
    });

    // 非表示URL一覧を表示する関数
    function showHiddenUrls() {
        const hiddenList = Array.from(hiddenUrls);
        if (hiddenList.length === 0) {
            alert('非表示にしている画像はありません。');
            return;
        }

        const modal = document.createElement('div');
        modal.style.position = 'fixed';
        modal.style.top = '50%';
        modal.style.left = '50%';
        modal.style.transform = 'translate(-50%, -50%)';
        modal.style.backgroundColor = '#fff';
        modal.style.padding = '20px';
        modal.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
        modal.style.zIndex = '10000';
        modal.style.maxHeight = '80%';
        modal.style.overflowY = 'auto';

        const title = document.createElement('h3');
        title.textContent = '非表示にした画像のURL一覧';
        modal.appendChild(title);

        const list = document.createElement('ul');
        hiddenList.forEach(url => {
            const listItem = document.createElement('li');
            listItem.textContent = url;
            const deleteBtn = document.createElement('button');
            deleteBtn.textContent = '削除';
            deleteBtn.style.marginLeft = '10px';
            deleteBtn.addEventListener('click', (event) => {
                event.stopPropagation();
                event.preventDefault();
                hiddenUrls.delete(url);
                GM_setValue('hiddenUrls', Array.from(hiddenUrls));
                listItem.remove();
                document.querySelectorAll(`img[src="${url}"]`).forEach(img => {
                    if (img.style.display === 'none') {
                        const container = img.previousSibling;
                        if (container && container.classList?.contains('hide-container')) {
                            showImage(container, img, url);
                        }
                    }
                });
            });
            listItem.appendChild(deleteBtn);
            list.appendChild(listItem);
        });
        modal.appendChild(list);

        const closeBtn = document.createElement('button');
        closeBtn.textContent = '閉じる';
        closeBtn.style.marginTop = '10px';
        closeBtn.addEventListener('click', () => {
            modal.remove();
        });
        modal.appendChild(closeBtn);

        document.body.appendChild(modal);
    }

    // メニューに「非表示URL一覧を表示」を追加
    GM_registerMenuCommand('非表示URL一覧を表示', showHiddenUrls);
})();