Last active
December 19, 2021 09:31
-
-
Save sakuro/73bad1ecff74ce86b4c9fd889b129a06 to your computer and use it in GitHub Desktop.
IMASBBS Block System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name IMASBBS Block System | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description IMASBBSのIDブロック機能を改良します。 | |
// @author sakuro | |
// @match http://imasbbs.com/patio.cgi* | |
// @icon https://www.google.com/s2/favicons?domain=imasbbs.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// タイトル (未活用) とスレ番 | |
const title = document.querySelector('title').textContent; | |
const thread = new URLSearchParams(location.search).get('read'); | |
console.log({'title': title, 'thread': thread}); | |
// スレ番不明 (=トップページなど) の場合は動作させない。 | |
if ( ! thread) { | |
return; | |
} | |
class BlockSystem { | |
constructor(posts) { | |
this.load(); | |
this.posts = posts; | |
this.posts.forEach((post) => this.isBlocked(post.id) ? post.hideComment() : post.showComment()); | |
} | |
isBlocked(id) { | |
return this.blocks.has(id); | |
} | |
block(id) { | |
if (this.isBlocked(id)) { | |
return; | |
} | |
this.blocks.set(id, new Date()); | |
this.save(); | |
this.posts.filter((post) => post.id === id).forEach((post) => post.hideComment()); | |
} | |
unblock(id) { | |
this.blocks.delete(id); | |
this.save(); | |
this.posts.filter((post) => post.id === id).forEach((post) => post.showComment()); | |
} | |
save() { | |
if (this.blocks.size === 0) { | |
localStorage.removeItem('blocks'); | |
} else { | |
const data = JSON.stringify([...this.blocks]); | |
localStorage.setItem('blocks', data); | |
} | |
} | |
load() { | |
const data = localStorage.getItem('blocks'); | |
this.blocks = data ? new Map(JSON.parse(data)) : new Map(); | |
this.blocks.forEach((id, timestamp) => this.blocks.set(id, new TimeRanges(timestamp))); | |
} | |
clear() { | |
this.blocks = new Map(); | |
this.save(); | |
this.posts.forEach((post) => post.showComment()); | |
} | |
} | |
class Post { | |
constructor(dom) { | |
const idSpan = dom.querySelector('span'); | |
this.id = idSpan.textContent.replace('ID:', ''); | |
this.comment = dom.querySelector('div.com-res, div.com-top, div.com-ng'); // com-res: 通常コメ、 com-top: 1つめのコメ、 com-ng: NGコメ | |
this.button = document.createElement('button'); | |
this.button.setAttribute('type', 'button'); | |
this.button.addEventListener('click', () => blockSystem.isBlocked(this.id) ? blockSystem.unblock(this.id) : blockSystem.block(this.id)); | |
dom.insertBefore(this.button, idSpan.nextSibling); | |
const separator = document.createTextNode(' ') | |
dom.insertBefore(separator, idSpan.nextSibling); | |
} | |
hideComment() { | |
this.comment.style.display = 'none'; | |
this.button.textContent = '\u{267B}'; // Recycling Symbol | |
} | |
showComment() { | |
this.comment.style.display = 'block'; | |
this.button.textContent = '\u{1F6AE}'; // Wastebucket | |
} | |
} | |
// 既存のNGボタンを削除 | |
document.querySelectorAll('input.xng-btn, input.ng-btn').forEach((e) => e.remove()); // .xng-btn: OKボタン, .ng-btn: NGボタン | |
const posts = [...document.querySelectorAll('.tr-art')].map((dom) => new Post(dom)); | |
const blockSystem = new BlockSystem(posts); | |
// トップとボトムにNG全クリアボタンを追加 | |
document.querySelectorAll('.pager').forEach((pager) => { | |
const separator = document.createTextNode('|') | |
pager.appendChild(separator); | |
const unblockAllButton = document.createElement('button'); | |
unblockAllButton.setAttribute('type', 'button'); | |
unblockAllButton.textContent = '全て \u{267B}'; | |
unblockAllButton.addEventListener('click', () => blockSystem.clear()); | |
pager.appendChild(unblockAllButton); | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment