// ==UserScript==
// @name Open2ch Imgur Image Hider
// @namespace http://tampermonkey.net/
// @version 0.10
// @description open2ch.netでImgur画像を非表示にし、ポップアップ表示を防ぎ、非表示URLを管理するスクリプト
// @author Anonymous
// @match *://*.open2ch.net/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @license MIT
// @downloadURL https://update.greasyfork.icu/scripts/528361/Open2ch%20Imgur%20Image%20Hider.user.js
// @updateURL https://update.greasyfork.icu/scripts/528361/Open2ch%20Imgur%20Image%20Hider.meta.js
// ==/UserScript==
(function() {
'use strict';
// ローカルストレージから非表示URLとデフォルト非表示設定を取得
const hiddenUrls = new Set(GM_getValue('hiddenUrls', []));
const defaultHide = GM_getValue('defaultHide', true);
// 画像を非表示にする関数
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 = '[非表示画像] ';
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);
})();