Greasy Fork

Greasy Fork is available in English.

修复B站评论区楼层

修复评论区楼层号,包括视频、动态、专栏、话题、活动……

目前为 2020-05-14 提交的版本。查看 最新版本

// ==UserScript==
// @name         修复B站评论区楼层
// @namespace    MotooriKashin
// @version      0.0.1
// @description  修复评论区楼层号,包括视频、动态、专栏、话题、活动……
// @author       MotooriKashin
// @match        *://*.bilibili.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let src,timer,mode,type;

    const url = {
        "reply" : "https://api.bilibili.com/x/v2/reply",
        "replymain" : "https://api.bilibili.com/x/v2/reply/main",
        "replycursor" : "https://api.bilibili.com/x/v2/reply/reply/cursor",
    }
    const xhr = {
        "true" : (url,callback) => {
            const xhr = new XMLHttpRequest();
            xhr.open('GET',url,true);
            xhr.withCredentials = true;
            xhr.onload = () => callback(xhr.responseText)
            xhr.send();
        }
    }
    const handle = {
        "obj2search" : (url,obj) =>{
            if (obj) {
                let arr = [],i = 0;
                for (let key in obj) {
                    if(obj[key] !== "" && obj[key] !== "undefined" && obj[key] !== null) {
                        arr[i] = key + "=" + obj[key];
                        i++;
                    }
                }
                url = url + "?" + arr.join("&");
            }
            return url;
        },
        "setReplyFloor" : {
            "start" : (src) => {
                try {
                    let oid,sort,pn;
                    src = src.split('?')[1].split('&');
                    for (let i=0;i<src.length;i++) {
                        let key = src[i].split('=');
                        if (key[0] == "oid") oid = key[1];
                        if (key[0] == "sort") sort = key[1];
                        if (key[0] == "pn") pn = key[1];
                        if (key[0] == "type") type = key[1];
                    }
                    if (sort==0) mode = 1;
                    if (sort==1) return;
                    if (sort==2) mode = 3;
                    if (sort==2) xhr.true(handle.obj2search(url.replymain,{"oid":oid,"next":pn,"type":type,"mode":mode}),handle.setReplyFloor.floor);
                    else {
                        if (pn==1) xhr.true(handle.obj2search(url.replymain,{"oid":oid,"type":type,"mode":mode}),handle.setReplyFloor.floor);
                        else{
                            pn = pn - 1;
                            xhr.true(handle.obj2search(url.reply,{"type":type,"sort":sort,"oid":oid,"pn":pn}),handle.setReplyFloor.prefloor);
                        }
                    }
                } catch(e) {console.error(e)}
            },
            "prefloor" : (data) => {
                try {
                    data = JSON.parse(data).data;
                    let i = data.replies.length - 1;
                    let oid = data.replies[0].oid;
                    let root = data.replies[i].rpid;
                    xhr.true(handle.obj2search(url.replycursor,{"oid":oid,"root":root,"type":type}),handle.setReplyFloor.cursorfloor);
                } catch(e) {console.error(e);}
            },
            "cursorfloor" : (data) => {
                try {
                    data = JSON.parse(data).data;
                    let oid = data.root.oid;
                    let next = data.root.floor;
                    xhr.true(handle.obj2search(url.replymain,{"oid":oid,"next":next,"type":type,"mode":mode}),handle.setReplyFloor.floor);
                } catch(e) {console.error(e)}
            },
            "floor" : (data) => {
                try {
                    data = JSON.parse(data).data;
                    let floor = {},top = data.top,hots = data.hots,replies = data.replies;
                    let list_item = document.getElementsByClassName("list-item");
                    let main_floor = document.getElementsByClassName("main-floor");
                    if (hots && hots[0]) for (let i=0;i<hots.length;i++) floor[hots[i].rpid] = hots[i].floor;
                    if (replies && replies[0]) for (let i=0;i<replies.length;i++) floor[replies[i].rpid] = replies[i].floor;
                    if (top && top.admin) floor[top.admin.rpid] = top.admin.floor;
                    if (top && top.upper) floor[top.upper.rpid] = top.upper.floor;
                    if (top && top.vote) floor[top.vote.rpid] = top.vote.floor;
                    if (main_floor[0]) {
                        for (let i=0;i<main_floor.length;i++) {
                            let rpid = main_floor[i].getAttribute("id").split('_')[2];
                            if (rpid in floor) main_floor[i].getElementsByClassName("floor-num")[0].innerText = "#" + floor[rpid];
                        }
                    }
                    if (list_item[0]) {
                        for (let i=0;i<list_item.length;i++) {
                            let rpid = list_item[i].getAttribute("data-id");
                            if (rpid in floor) {
                                let node = list_item[i].getElementsByClassName("info")[0];
                                let span = document.createElement("span");
                                span.setAttribute("class","floor");
                                span.innerText = "#" + floor[rpid];
                                node.insertBefore(span,node.firstChild);
                            }
                        }
                    }
                } catch(e) {console.error(e)}
            }
        },
    }
    document.addEventListener("DOMNodeInserted",(msg) => {
        if (msg.target.src && msg.target.src.startsWith('https://api.bilibili.com/x/v2/reply?')) src = msg.target.src;
        if (src) {
            if (msg.target.className && (msg.target.className == "main-floor" || msg.target.className == "list-item reply-wrap ")){
                window.clearTimeout(timer);
                timer = window.setTimeout(() => {handle.setReplyFloor.start(src)},1000);
            }
        }
    });
})();