// ==UserScript==
// @name Bilibili av/bv link preview
// @name:zh-CN Bilibili av/bv 链接预览
// @namespace http://tampermonkey.net/
// @version 0.8
// @description 鼠标置于av/bv/cv号链接上时弹出详细信息
// @author xdedss
// @match https://www.bilibili.com/video/*
// @match https://www.bilibili.com/read/*
// @grant none
// @require https://code.jquery.com/jquery-2.2.4.min.js
// @downloadURL https://update.greasyfork.icu/scripts/402355/Bilibili%20avbv%20link%20preview.user.js
// @updateURL https://update.greasyfork.icu/scripts/402355/Bilibili%20avbv%20link%20preview.meta.js
// ==/UserScript==
(function() {
//可更改的设定
var cover_width = 280; //窗口宽度
var cover_padding = 15; //窗口padding
var face_width = 20; //up头像大小
var max_desc_length = 60; //视频描述长度
var active_element = null;
//获取元素坐标
function getTop(e){
var offset=e.offsetTop;
if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
return offset;
}
function getLeft(e){
var offset=e.offsetLeft;
if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
return offset;
}
function pad(num, n) {
num = num.toString();
var len = num.length;
while(len < n) {
num = "0" + num;
len++;
}
return num;
}
function trimDesc(desc){
if (desc.length < max_desc_length){
return desc;
}
return desc.substr(0, max_desc_length - 10) + '...';
}
function formatDuration(seconds){
var sec = seconds % 60;
seconds -= sec;
var min = (seconds / 60) % 60;
seconds -= 60 * min;
var hr = seconds / 3600;
var res = `${pad(min, 2)}:${pad(sec, 2)}`;
if (hr != 0){
res = pad(hr, 2) + ':' + res;
}
return res;
}
function formatTime(timestamp) {
var date = new Date(timestamp * 1000);
var Y = pad(date.getFullYear(), 2);
var M = pad(date.getMonth() + 1, 2);
var D = pad(date.getDate(), 2);
var h = pad(date.getHours(), 2);
var m = pad(date.getMinutes(), 2);
var s = pad(date.getSeconds(), 2);
return `${Y}-${M}-${D} ${h}:${m}:${s}`;
}
function formatNumber(num){
if (num >= 10000){
return (Math.round(num / 1000) / 10.0) + '万';
}
return num + '';
}
//重设框的位置
function initBox(e){
if ($('#avbvinfo').length == 0){
$('body').after(`
`);
}
$('#avbvinfo').css('left', Math.min($('body')[0].offsetWidth-cover_width-2*cover_padding, Math.floor(getLeft(e.target)+Math.max(15, e.target.offsetWidth * 0.1)))+'px')
.css('top', Math.floor(getTop(e.target)+e.target.offsetHeight * 0.9)+'px').css('display','').html('...');
}
//隐藏
function hideBox(){
$('#avbvinfo').css('display', 'none').html('...');
active_element = null;
}
//在框内显示内容
function showBox(data){
//console.log(data);
if (data.code != 0) {
$('#avbvinfo').html(`啊叻?视频不见了?
error ${data.code} ${data.message}`);
return;
}
data = data.data;
$('#avbvinfo').html(`
av${data.aid} / ${data.bvid} / cid${data.cid}
${data.title.replace('"', """)}
${formatTime(data.pubdate)}
${trimDesc(data.desc).replace('"', """)}
${formatNumber(data.stat.view)} |
${formatNumber(data.stat.danmaku)} |
|
${formatDuration(data.duration)} |
${formatNumber(data.stat.like)} |
${formatNumber(data.stat.coin)} |
${formatNumber(data.stat.favorite)} |
${formatNumber(data.stat.reply)} |
`);
}
function showBoxCv(data){
if (data.code != 0) {
$('#avbvinfo').html(`页面不存在或已被删除
error ${data.code} ${data.message}`);
return;
}
data = data.data;
$('#avbvinfo').html(`
${data.title.replace('"', """)}
${formatNumber(data.stats.view)}阅读
${formatNumber(data.stats.like)} |
${formatNumber(data.stats.coin)} |
${formatNumber(data.stats.favorite)} |
${formatNumber(data.stats.reply)} |
`);
}
//按av/bv号查询信息
function queryAv(aid, callback){
$.ajax({
url: "https://api.bilibili.com/x/web-interface/view?aid=" + aid,
success: callback
});
}
function queryBv(bvid, callback){
$.ajax({
url: "https://api.bilibili.com/x/web-interface/view?bvid=" + bvid,
success: callback
});
}
function queryCv(cvid, callback){
$.ajax({
url: "https://api.bilibili.com/x/article/viewinfo?id=" + cvid,
success: callback
});
}
//鼠标监听
function mouseoverAv(e){
if (!e.target || !e.target.href) return;
if (e.target != active_element){
active_element = e.target;
initBox(e);
var aid = e.target.href.match(/av[0-9]+/)[0].replace('av', '');
queryAv(aid, (d)=>showBox(d));
}
}
function mouseoverBv(e){
if (!e.target || !e.target.href) return;
if (e.target != active_element){
active_element = e.target;
initBox(e);
var bvid = e.target.href.match(/bv[0-9a-zA-Z]+/i)[0];
queryBv(bvid, (d)=>showBox(d));
}
}
function mouseoverCv(e){
if (!e.target || !e.target.href) return;
if (e.target != active_element){
active_element = e.target;
initBox(e);
var cvid = e.target.href.match(/cv[0-9]+/)[0].replace('cv', '');
queryCv(cvid, (d)=>showBoxCv(d));
}
}
//给新出现的连接加监听
function tryAddListeners(){
$('a[href^="//www.bilibili.com/video/bv"][mark_avbvinfo!="true"]').mouseover(mouseoverBv).attr('mark_avbvinfo','true');
$('a[href^="//www.bilibili.com/video/BV"][mark_avbvinfo!="true"]').mouseover(mouseoverBv).attr('mark_avbvinfo','true');
$('a[href^="//www.bilibili.com/video/av"][mark_avbvinfo!="true"]').mouseover(mouseoverAv).attr('mark_avbvinfo','true');
$('a[href^="//www.bilibili.com/read/cv"][mark_avbvinfo!="true"]').mouseover(mouseoverCv).attr('mark_avbvinfo','true');
}
//给新出现的元素加给新出现的连接加监听的监听
function tryInit(){
$('.btn-more[mark_avbvinfo!="true"]').click(()=>{window.setTimeout(tryAddListeners, 1500);}).attr('mark_avbvinfo','true');
$('.tcd-number[mark_avbvinfo!="true"]').click(()=>{window.setTimeout(tryAddListeners, 1500);}).attr('mark_avbvinfo','true');
$('body[mark_avbvinfo!="true"]').click((e)=>{
hideBox();
}).mouseenter((e)=>{
//console.log(e.target)
if (e.target != active_element){
hideBox();
}
}).attr('mark_avbvinfo','true');
tryAddListeners();
}
function delayedInit(){
window.setTimeout(tryInit, 2*1000);
window.setTimeout(tryInit, 4*1000);
window.setTimeout(tryInit, 6*1000);
window.setTimeout(tryInit, 10*1000);
}
$('body').click((e)=>{
tryInit();
});
$('.comment-list ').mouseenter((e)=>{
delayedInit()
});
delayedInit()
})();