Greasy Fork

来自缓存

Greasy Fork is available in English.

贴吧显示真实ID

贴吧昵称掩盖了真实ID,认不出人了?这个脚本适合你

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         贴吧显示真实ID
// @version      0.18
// @namespace    https://github.com/8qwe24657913
// @description  贴吧昵称掩盖了真实ID,认不出人了?这个脚本适合你
// @author       8qwe24657913
// @match        http://tieba.baidu.com/*
// @match        https://tieba.baidu.com/*
// @run-at       document-start
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @grant        unsafeWindow
// ==/UserScript==
/* globals GM_getValue GM_setValue GM_registerMenuCommand unsafeWindow */
// eslint-disable-next-line no-extra-semi
;(function() {
    'use strict'
    // add css
    const css = `
@keyframes showUserName {
    from {
        clip: rect(1px, auto, auto, auto);
    }
    to {
        clip: rect(0px, auto, auto, auto);
    }
}
.frs-author-name:not(.shownUN), .p_author_name:not(.shownUN), .userinfo_username:not(.shownUN), .lzl_cnt > .at:not(.shownUN), .lzl_content_main > .at:not(.shownUN), #j_u_username .u_ddl_con_top > ul:not(.shownUN) {
    animation-duration: 0.001s;
    animation-name: showUserName;
}
.card_userinfo_title .userinfo_username, .card_userinfo_title .userinfo_username:hover {
    max-width: 100%!important;
}
.userinfo_username + div[style]:not([class]):not([id]), img[src="//tb1.bdstatic.com/tb/cms/nickemoji/nickname_sign.png"], .card_userinfo_tbvip {
    display: none!important;
}
.frs-author-name > div[style*="color"], .userinfo_username > div[style*="color"] {
    color: inherit!important;
}
`
    const style = document.createElement('style')
    style.appendChild(document.createTextNode(css))
    document.documentElement.appendChild(style)
    // add setting
    // eslint-disable-next-line no-template-curly-in-string
    const setting = GM_getValue('showUNSetting', localStorage.showUNSetting || '${un} (${nickname})')

    function changeSetting() {
        // eslint-disable-next-line no-template-curly-in-string
        const newSetting = prompt('${un}表示真实ID,${nickname}表示昵称,可使用html标签', setting)
        if (newSetting && newSetting !== setting) {
            GM_setValue('showUNSetting', newSetting)
            location.reload()
        }
    }
    GM_registerMenuCommand('设置贴吧显示真实ID格式', changeSetting)

    function closestAttr(elem, attr) {
        while (elem && !elem.hasAttribute(attr)) elem = elem.parentElement
        return elem ? elem.getAttribute(attr) : false
    }

    function decodeURL(str) {
        try {
            // decode utf-8
            return decodeURIComponent(str)
        } catch (e) {
            // decode gbk
            const decoder = new TextDecoder('gbk')
            return str.replace(/(?:%[A-Z0-9]{2})+/gi, s =>
                decoder.decode(
                    new Uint8Array(
                        s
                            .substr(1)
                            .split('%')
                            .map(c => parseInt(c, 16)),
                    ),
                ),
            )
        }
    }
    // main
    document.addEventListener(
        'animationstart',
        event => {
            // shouldn't use jQuery
            if (event.animationName !== 'showUserName') return
            const target = event.target
            target.classList.add('shownUN')
            if (target.nodeName === 'UL') {
                // 设置按钮
                target.insertAdjacentHTML('beforeend', '<li class="u_showUN"><a href="javascript:">显ID设置</a></li>')
                target.getElementsByClassName('u_showUN')[0].addEventListener('click', changeSetting, false)
                return
            }
            let un
            let nickname
            let data
            let hack = false
            let isAt = false
            // 获取 un
            if (target.hasAttribute('username') && target.getAttribute('onmouseover') === 'showattip(this)') {
                // 贴吧最近又在乱改,一会回复显示id,一会回复显示昵称,一会id不编码,一会id utf-8编码,一会id gbk编码……
                hack = true
                un = target.getAttribute('username')
                if (/%[A-Z0-9]{2}/i.test(un)) {
                    // url encoded
                    try {
                        un = decodeURL(un)
                    } catch (e) {
                        // do nothing
                    }
                }
            } else if ((data = closestAttr(target, 'data-field'))) {
                // frs & pb & card
                un = JSON.parse(data.replace(/'/g, '"')).un // 贴吧的畸形JSON用的是单引号,姑且先用replace凑合
            } else if (location.pathname.startsWith('/home/')) {
                // ihome 百度取消了真实用户名显示
                if (!un) {
                    try {
                        un = unsafeWindow.PageData.current_page_uname
                        throw new Error("can't get un from PageData")
                    } catch (e) {
                        un = new URLSearchParams(location.search).get('un')
                    }
                }
            } else if (target.href) {
                // unknown, trying to parse href
                console.warn('贴吧显示真实ID: 尝试解析未知元素', target)
                un = new URLSearchParams(target.href.split('?')[1]).get('un')
            } else {
                // can't find un
                return console.error('贴吧显示真实ID: 找不到真实ID', target)
            }
            // 获取 nickname
            if (target.classList.contains('frs-author-name')) {
                // frs 用户名可能被切掉,统一不用图片,保证格式美观
                nickname = closestAttr(target.parentElement, 'title').split(' ')[1]
                if (nickname === un) target.textContent = nickname // 用户名尽量显示完整,不用图片
            } else {
                // pb & card & ihome
                nickname = target.innerHTML
                    .replace(/^<div[^>]*>(.*)<\/div>$/, '$1')
                    .replace(/<img src="\/\/tb1\.bdstatic\.com\/tb\/cms\/nickemoji\/nickname_sign\.png"[^>]*>/, '')
            }
            nickname = nickname.trim()
            if (nickname.startsWith('@')) {
                isAt = true
                nickname = nickname.slice(1)
            }
            // 修改显示内容
            if (hack) {
                // showattip 函数写的过于制杖,不开这脚本都显示不出来……似乎还和帖子有关,测试贴 http://tieba.baidu.com/p/6051286922 感谢 @谷歌大法好 的反馈
                Object.defineProperty(target, 'textContent', {
                    get() {
                        return un
                    },
                })
            }
            if (!nickname) {
                target.textContent = un
            } else if (un && un !== 'null' && nickname !== un && nickname !== '@' + un) {
                let html = setting.replace(/\${un}/g, un).replace(/\${nickname}/g, nickname)
                if (
                    !(
                        target.classList.contains('p_author_name') ||
                        (data && target.classList.contains('userinfo_username'))
                    )
                ) {
                    html = html.replace(/<br[^>]*>/g, ' ')
                } // 仅 pb & card 适合换行,不适合的地方replace成空格
                target.innerHTML = (isAt ? '@' : '') + html
            }
        },
        false,
    )
})()