Greasy Fork

Greasy Fork is available in English.

F**k 三观

try to take over the world!

当前为 2018-07-18 提交的版本,查看 最新版本

// ==UserScript==
// @name         F**k 三观
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  try to take over the world!
// @author       yetone
// @match        https://*.douban.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    const kwsKey = 'fk-setting-kws';
    const forwardKey = 'fk-setting-forward';
    let $style = document.createElement('style');
    $style.innerText = `
.my-hl {
-webkit-animation: highlight 1.6s ease-out;
animation: highlight 1.6s ease-out
}
@-webkit-keyframes highlight {
0% {
background: #ebebeb
}

html[data-theme=dark] 0% {
background: #444
}

to {
background: transparent none repeat 0 0/auto auto padding-box border-box scroll;
background: initial
}
}

@keyframes highlight {
0% {
background: #ebebeb
}

html[data-theme=dark] 0% {
background: #444
}

to {
background: transparent none repeat 0 0/auto auto padding-box border-box scroll;
background: initial
}
}`;
    document.head.appendChild($style);
    renderSettingArea();
    process();

    function renderSettingArea() {
        let $w = document.querySelector('.aside');
        if ($w === null) {
            return;
        }
        let $div = document.createElement('div');
        $div.style.padding = '8px 0';
        let $a = document.createElement('a');
        $div.append($a);
        $a.innerText = 'F**k 设置';
        $a.href = 'javascript:;';
        $a.style.color = '#ccc';
        $a.addEventListener('click', function() {
            let setting = getSetting();
            let $area = $div.querySelector('.fk-setting');
            if ($area !== null) {
                $area.remove();
                return;
            }
            $area = document.createElement('div');
            $area.classList.add('fk-setting');
            $area.style.padding = '8px 0';
            let $form = document.createElement('form');
            $form.innerHTML = `<p><label for="fk-kws">关键词(懒得做好看了,英文逗号隔开,别怪我没提醒你):</label><input style="width: 200px" id="fk-kws" name="fk-kws" value="${setting.kws.join(',')}"/></p>
<p><label for="fk-forward">包括转发的原内容?:</label><input type="checkbox" id="fk-forward" name="fk-forward" value="true" ${setting.forward ? 'checked' : ''}/></p>
<p><input type="submit" value="提交"/></p>`;
            $area.appendChild($form);
            $form.addEventListener('submit', function(e) {
                e.preventDefault();
                let $kwsIpt = $form.querySelector('[name=fk-kws]');
                let kws = $kwsIpt.value.split(',').map(x => x.trim());
                GM_setValue(kwsKey, kws);
                let $forwardIpt = $form.querySelector('[name=fk-forward]');
                GM_setValue(forwardKey, $forwardIpt.checked);
                alert('保存成功!');
            }, true);
            $div.append($area);
        }, true);
        $w.prepend($div);
    }

    function getType(obj) {
        return Object.prototype.toString.call(obj).slice(8, -1);
    }

    function getSetting() {
        let kws = GM_getValue(kwsKey)
        let forward = GM_getValue(forwardKey);
        kws = getType(kws) !== 'Array' ? ['三观'] : kws;
        kws = kws.filter(x => !!x);
        forward = getType(forward) !== 'Boolean' ? true : forward;
        return {
            kws, forward
        };
    }

    function process() {
        let $statuses = document.querySelectorAll('.status-wrapper, .item-status');
        $statuses.forEach($x => {
            if ($x.dataset.fk) {
                return;
            }
            let kws = search($x);
            $x.dataset.fk = true;
            if (kws.size === 0) {
                return;
            }
            let info = getStatusInfo($x);
            let $div = document.createElement('div');
            $div.style.color = '#bfbfbf';
            $div.style.fontSize = '12px';
            $div.style.textAlign = 'center';
            $div.style.borderBottom = '1px solid #e5e5e5';
            $div.style.padding = '8px 0';
            let $tip = document.createElement('div');
            $tip.innerText = `${info.user.name}的广播包含你设置的${Array.from(kws).map(x => `「${x}」`).join('、')},已折叠`;
            $tip.style.cursor = 'pointer';
            $tip.style.display = 'inline-block';
            $div.addEventListener('click', function() {
                $div.style.display = 'none';
                $x.style.display = 'block';
                $x.classList.add('my-hl');
            }, false);
            $div.appendChild($tip);
            let key = `imangry-${info.user.id}`;
            let sids = GM_getValue(key) || [];
            if (sids.indexOf(info.id) === -1) {
                sids.push(info.id);
            }
            GM_setValue(key, sids);
            if (sids.length >= 3) {
                let $dd = document.createElement('div');
                $dd.style.display = 'inline-block';
                $dd.style.marginLeft = '8px';
                let $span = document.createElement('span');
                $span.innerText = `已发布${sids.length}次`;
                $dd.appendChild($span);
                let $btn = document.createElement('a');
                $btn.href = 'javasript:;';
                $btn.innerText = '拉黑';
                $btn.style.marginLeft = '8px';
                $btn.addEventListener('click', function(e) {
                    e.stopPropagation();
                    if (!confirm(`确定拉黑${info.user.name}?`)) {
                        return;
                    }
                    $.postJSON_withck('https://www.douban.com/j/contact/addtoblacklist', {
                        people: info.user.id
                    }, function() {
                        alert(`已拉黑${info.user.name}`);
                    });
                }, false);
                $dd.appendChild($btn);
                $div.appendChild($dd);
            }
            insertAfter($div, $x);
            $x.style.display = 'none';
        });
    }

    function getUserInfo($node) {
        let $pic = $node.querySelector('.usr-pic img') || $node.querySelector('img.avatar');
        let id = $pic === null ? '' : $pic.src.match(/u(\d+)-\d+/)[1];
        let $lnk = $node.querySelector('.lnk-people') || $node.querySelector('a.author');
        let name = $lnk === null ? 'unknow' : $lnk.innerText;
        return {id, name};
    }
    function getStatusInfo($node) {
        let id = $node.dataset.sid;
        let $text = $node.querySelector('.status-saying') || $node.querySelector('.status-preview');
        let text = $text === null ? '' : $text.innerText;
        let user = getUserInfo($node);
        return { id, text, user };
    }
    function insertAfter($new, $target) {
        let $p = $target.parentNode;

        if($p.lastChild === $target) {
            $p.appendChild($new);
        } else {
            $p.insertBefore($new, $target.nextSibling);
        }
    }
    function search($parent) {
        let setting = getSetting();
        let nodes = [];
        let need = false;
        let kws = new Set();

        if (setting.kws.length === 0) {
            console.log('您没有设置关键词!!!');
            return kws;
        }
        let pattern = new RegExp(setting.kws.join('|'), 'g');
        for (let $node of $parent.childNodes) {
            if ($node.nodeType !== 3) {
                if ($node.nodeType === 1 && !setting.forward && $node.classList.contains('status-real-wrapper')) {
                    continue;
                }
                for (let kw of search($node)) {
                    kws.add(kw);
                }
                continue;
            }
            let text = $node.textContent;
            let lastIdx = 0;
            text.replace(pattern, (c, idx, t) => {
                kws.add(c);
                need = true;
                nodes.push(new Text(t.substring(lastIdx, idx)));
                lastIdx = idx + c.length;
                let $b = document.createElement('b');
                $b.style.background = '#ffb56e';
                $b.style.fontWeight = 'normal';
                $b.innerText = c;
                nodes.push($b);
            });
            nodes.push(new Text(text.substring(lastIdx)));
        }
        if (need) {
            while ($parent.childNodes.length > 0) {
                $parent.childNodes.forEach($x => {
                    $parent.removeChild($x);
                });
            }
            nodes.forEach($x => {
                $parent.appendChild($x);
            });
        }
        return kws;
    }
})();