Greasy Fork

Greasy Fork is available in English.

Bilibili 显示视频分区、av号等

在视频下方显示 分区、av 号、分P标题、动态

目前为 2021-03-08 提交的版本,查看 最新版本

// ==UserScript==
// @name        Bilibili 显示视频分区、av号等
// @namespace https://space.bilibili.com/517723/
// @version        0.04
// @description 在视频下方显示 分区、av 号、分P标题、动态
// @note 才发现分区在tag里,现在会醒目显示此tag
// @author        僠儖僲
// @include        https://www.bilibili.com/video/*
// @icon        https://www.bilibili.com/favicon.ico
// @compatible firefox Firefox78-esr
// @compatible edge Edge88
// @noframes
// @grant        GM_addStyle
// @run-at        document-start
// ==/UserScript==
(()=>{
    'use strict';
    const list=['详细信息','分P标题','动态']
    const isAppend=0//为1则在简介下方
    const tname_color='#d600a1'//分区TAG颜色
    const ExterminatePJAX=false//关闭PJAX

    const root=window.unsafeWindow||window
    const {call}=Function.prototype,etp=EventTarget.prototype
    const on=call.bind(etp.addEventListener),off=call.bind(etp.removeEventListener)
    const once=(t,s,cb)=>new Promise(ok=>{on(t,s,cb=e=>{off(t,s,cb,!0);ok(e)},!0)})
    const tick0_5=cb=>setTimeout(cb,500)
    const wait=(cb,tick=requestAnimationFrame,next)=>new Promise((ok,reject)=>{
        (next=v=>{try{(v=cb())?ok(v):tick(next)}catch(e){reject(e)}})()
    })
    const waitElem=select=>wait(()=>document.querySelector(select),tick0_5)
    const vmp=once(document,'DOMContentLoaded').then(e=>waitElem('#app')).then(el=>wait(()=>el.__vue__))
    vmp.then(vm=>{root.__BILIBILI_VIDEO_GLOBAL_VIEWMODEL__=vm})

    const eventStopPropagation=call.bind(Event.prototype.stopPropagation)
    const getEl=(value,key='title',el)=>{
        el=document.querySelector(`.video-desc>.info[${key}="${value}"]`)
        if(!el){
            el=document.createElement('div')
            el.className='info open'
            el.setAttribute(key,value)
            el.setAttribute('data-old',location.href)
            el.addEventListener('click',eventStopPropagation,!0)
            document.querySelector('.video-desc')[isAppend?'append':'prepend'](el)
        }
        return el
    }
    var curPart=null,curPartQuery=''
    const map={
        tnameSelect:[
            '[href^="//www.bilibili.com/v/"]:not([href^="//www.bilibili.com/v/channel/"])',
            '[href^="//www.bilibili.com/anime/"]',
            '[href^="//www.bilibili.com/guochuang/"]',
            '[href^="//www.bilibili.com/movie/"]',
            '[href^="//www.bilibili.com/documentary/"]'
        ].map(s=>`.s_tag .tag-area>li .tag-link${s}`).join(','),
        ['详细信息'](el,{tname,aid,bvid}){
            var tnames=Array.from(document.querySelectorAll(this.tnameSelect),a=>a.innerText)
            var list=[
                `<span title="分区">${tnames[1]===tname?tnames.join('>'):tname}</span>`,
                `<a href="/video/av${aid}/${curPartQuery}" target="_blank">av${aid}</a>`,
                `<a href="/video/${bvid}/${curPartQuery}" target="_blank">${bvid}</a>`
            ]
            el.innerHTML=list.join('\u3000')
        },
        ['分P标题'](el,{pages,title}){
            var page=pages[curPart?curPart[1]-1:0]||pages[0],partTitle=page&&page.part
            el.title=`分P标题${partTitle!==title?partTitle?'':'为空':'与标题相同'}`
            el.innerText=partTitle||'\ufe0f'
        },
        ['动态'](el,{dynamic}){
            el.style.cssText='border-top:1px solid #e5e9f0;margin-top:15px;padding-top:15px;'
            el.title=dynamic?'动态':'动态为空'
            el.innerText=dynamic||'\ufe0f'
        }
    }
    const inject=(data)=>{
        data||(data=root.__INITIAL_STATE__.videoData)
        curPart=location.search.match(/[?&]p=(\d+)/)
        curPartQuery=curPart?`?p=${curPart[1]}`:''
        getEl('分割线','data-title').style.cssText='height:1px;background-color:#e5e9f0;margin:15px 0px;'
        list[isAppend?'reduce':'reduceRight']((acc,cur)=>{map[cur](getEl(cur,'data-title'),data)},void 0)
    }
    vmp.then(vm=>{
        if(ExterminatePJAX){
            vm.$router.beforeEach((to,from,next)=>{
                var {p}=to.query
                p=p?'?p='+p:''
                location.href=to.path+p
                next(false)
            })
        }
        vm.$store.watch(state=>state.videoData,data=>{vmp.then(()=>{inject(data)})})
        inject()
        tname_color&&GM_addStyle(`${map.tnameSelect}{color:${tname_color};}`)
    })
})()