Skip to content

Instantly share code, notes, and snippets.

@toriato
Last active October 18, 2024 19:37
Show Gist options
  • Save toriato/deda5e8b35cb6ce6f7e911a2dd072454 to your computer and use it in GitHub Desktop.
Save toriato/deda5e8b35cb6ce6f7e911a2dd072454 to your computer and use it in GitHub Desktop.
Script to update personal block words on DC Inside
// ==UserScript==
// @name Better Blocks
// @namespace better-blocks
// @description 디시인사이드에 더 나은 단어 차단 기능을 제공합니다
// @version 0.1.0
// @author Sangha Lee
// @copyright 2024, Sangha Lee
// @license MIT
// @match https://gall.dcinside.com/board/*
// @match https://gall.dcinside.com/mgallery/board/*
// @match https://gall.dcinside.com/mini/board/*
// @match https://gall.dcinside.com/person/board/*
// @icon https://nstatic.dcinside.com/dc/m/img/dcinside_icon.png
// @run-at document-start
// ==/UserScript==
// 디시인사이드에선 escape() 처리된 문자열을 정규표현식으로 검사하는데
// 단어에 0이 들어갈 경우 앞선 이스케이프된 글자의 끝이 0이거나 숫자인 경우 포함되는 버그가 존재함
const url = new URL(location.href)
const gallery = url.searchParams.get('id')
const configs = {
_: JSON.parse(localStorage.getItem('block_all') ?? '{}'),
...JSON.parse(localStorage.getItem('block_parts') ?? '{}')
}
const config = {
on: 1,
word: '',
id: '',
ip: '',
nick: '',
...(configs._.on === 1 ? configs._ : {}),
...(configs[gallery]?.on === 1 ? configs[gallery] : {})
}
function isNotEmpty (v) {
return v !== ''
}
const blockedWords = config.word.split('||').filter(isNotEmpty)
const blockedIDs = config.ip.split('||').filter(isNotEmpty)
const blockedIPs = config.ip.split('||').filter(isNotEmpty)
const blockedNicknames = config.nick.split('||').filter(isNotEmpty)
function isblockedNode ($node) {
const $content = $node.querySelector('.ub-word')
if ($content && blockedWords.some(v => $content.textContent.includes(v))) {
return true
}
const $author = $node.querySelector('.ub-writer')
if ($author) {
const i = $author.dataset
switch (true) {
case i.uid && blockedIDs.some(v => i.uid.includes(v)):
case i.ip && blockedIPs.some(v => i.ip.includes(v)):
case i.nick && blockedNicknames.some(v => i.nick.includes(v)):
return true
}
}
return false
}
function filterNodes ($nodes) {
$nodes
.filter(isblockedNode)
.map(v => v.classList.add('block-disable'))
}
Object.defineProperty(window, 'chk_user_block', {
writable: false,
value: () => undefined
})
document.addEventListener('DOMContentLoaded', () => {
const $comments = document.querySelector('.comment_wrap')
if ($comments) {
filterNodes([...$comments.querySelectorAll('li')])
new MutationObserver(m => filterNodes([...$comments.querySelectorAll('li')]))
.observe($comments, { childList: true })
}
const $articles = document.querySelector('.gall_list')
if ($articles) {
filterNodes([...$articles.querySelectorAll('tr')])
new MutationObserver(m => filterNodes(m.map(v => v.addedNodes).flat()))
.observe($articles, { childList: true })
}
})
javascript:fetch("https://gall.dcinside.com/mini/springkat/39").then(e=>e.text()).then(e=>{function t(e){let l="";for(let r of e.childNodes){switch(r.tagName){case"BR":case"P":l+="\n"}if(r.nodeType===Node.TEXT_NODE){l+=r.textContent;continue}r.childNodes.length>0&&(l+=t(r))}return l}let l=(new DOMParser).parseFromString(e,"text/html"),r=JSON.parse(localStorage.getItem("block_all")??"{}");r.on=1,r.word="word"in r?r.word:"";let n=r.word.split("||"),o=t(l.querySelector(".write_div")).split("\n").map(e=>e.replace(/\/\/.{0,}/,"").trim()).filter(e=>e&&!n.includes(e));r.word=[...n,...o].sort((e,t)=>e.localeCompare(t)).join("||"),localStorage.setItem("block_all",JSON.stringify(r)),alert(`차단 단어 ${o.length}개를 추가했습니다`)}).catch(e=>{alert(e),console.error(e)});
fetch('https://gall.dcinside.com/mini/springkat/39')
.then(res => res.text())
.then(html => {
function text ($parent) {
let content = ''
for (const $child of $parent.childNodes) {
switch ($child.tagName) {
case 'BR':
case 'P':
content += '\n'
}
if ($child.nodeType === Node.TEXT_NODE) {
content += $child.textContent
continue
}
if ($child.childNodes.length > 0) {
content += text($child)
}
}
return content
}
const $ = (new DOMParser).parseFromString(html, 'text/html')
const config = JSON.parse(localStorage.getItem('block_all') ?? '{}')
config.on = 1
config.word = ('word' in config ? config.word : '')
const existingWords = config.word.split('||')
const addedWords = text($.querySelector('.write_div'))
.split('\n')
.map(v => v.replace(/\/\/.{0,}/, '').trim())
.filter(v => v && !existingWords.includes(v))
config.word = [...existingWords, ...addedWords]
.sort((a, b) => a.localeCompare(b))
.join('||')
localStorage.setItem('block_all', JSON.stringify(config))
alert(`차단 단어 ${addedWords.length}개를 추가했습니다`)
})
.catch(e => {
alert(e)
console.error(e)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment