Better Blocks

디시인사이드에 더 나은 단어 차단 기능을 제공합니다

当前为 2024-10-18 提交的版本,查看 最新版本

// ==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 })
    }
})