// ==UserScript== // @name Bilibili 显示视频分区、av号等 // @namespace https://space.bilibili.com/517723/ // @version 0.01 // @description 在视频简介下方显示 分区、av 号、分P标题、动态 // @author 僠儖僲 // @include https://www.bilibili.com/video/* // @icon https://www.bilibili.com/favicon.ico // @compatible firefox // @noframes // @run-at document-start // @downloadURL none // ==/UserScript== (()=>{ 'use strict'; const ExterminatePJAX=false const once=(t,s,cb)=>new Promise(ok=>{ cb=e=>{t.removeEventListener(s,cb,1);ok(e)} t.addEventListener(s,cb,1) }),doc=document,$=doc.querySelector.bind(doc) const root=window.unsafeWindow||window const rAF=cb=>setTimeout(cb,500) const waitElem=select=>new Promise((resolve,reject)=>{ const next=()=>{try{ el=$(select) el?resolve(el):rAF(next) }catch(e){reject(e)}} var el;next() }) const vueHooker=app=>new Promise((resolve,reject)=>{ const vm=app.__vue__ if(vm){resolve(vm);return} const set=vm=>{ if(!vm)return Object.defineProperty(app,'__vue__',{ configurable: true, enumerable: true, value: vm, writable: true }) resolve(vm) } Object.defineProperty(app,'__vue__',{ configurable: true, enumerable: true, get(){return void 0}, set(vm){set(vm)} }) }) const menu={ set(list,cb){ if(this.list)this.clear() this.list=list.map(title=>GM_registerMenuCommand(title,cb)) }, clear(){ this.list.forEach(id=>GM_unregisterMenuCommand(id)) this.list=null } } const _call=Function.prototype.call, saftyArrow=fn=>_call.bind(fn,null), eventStopPropagation=_call.bind(Event.prototype.stopPropagation) const getEl=(value,key='title')=>{ var 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,1) document.querySelector('.video-desc').append(el) } return el } const _inject=(data)=>{ /*var el=document.querySelector('.video-data>span[title=详细信息]') if(!el){ el=document.createElement('span') el.title='详细信息' el.style.margin='0 12px' el.setAttribute('data-aid',data.aid) document.querySelector('.video-data').append(el) }*/ data||(data=root.__INITIAL_STATE__.videoData) var av='av'+data.aid var list=[ '分区:'+data.tname,av,data.bvid//,'cid='+root.cid ] //menu.set(list,inject) var p=location.search.match(/[?&]p=(\d+)/) var P=p?('?p='+p[1]):'' getEl('分割线','data-title').innerText='\u3000' getEl('详细信息').innerHTML=list.join('\u3000') .replace(/av(\d+)(?!\w)/gi, 'av$1') .replace(/(bv1)(\w{9})/gi,'$1$2') var page=data.pages[p?(p[1]-1):0] var title=page&&page.part getEl('分P标题').innerText=title==data.title?'分P标题与标题相同':('分P标题:'+title) getEl('动态').innerText=data.dynamic?'-----动态-----\n'+data.dynamic:'-----动态为空-----' } const inject=saftyArrow(_inject) once(doc,'DOMContentLoaded').then(async()=>{ const app=await waitElem('#app,#viewlater-app,.app-wrap') const vm=await vueHooker(app) const {$root}=vm,{$router}=$root root.vm=vm if(ExterminatePJAX){ $router.beforeEach((to,from,next)=>{ var {p}=to.query p=p?'?p='+p:'' location.href=to.path+p next(false) }) } vm.$watch('videoData',inject) inject(vm.videoData) }) })()