// ==UserScript== // @name bilibili - 查看历史评论/弹幕 // @description 文明交流,人人有责。 // @version 1.5.0 // @author 会飞的蛋蛋面 // @license All Rights Reserved - 未经授权禁止复制、修改或分发 // @match https://www.bilibili.com/video/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @connect api.aicu.cc // @connect apibackup2.aicu.cc // @run-at document-idle // @namespace https://greasyfork.org/users/751952 // @downloadURL none // ==/UserScript== (() => { // 避免滥用 "use strict";const t="history-reply-panel",e="https://www.bilibili.com/video",o="https://live.bilibili.com",n=["https://api.aicu.cc/api/v3/search","https://apibackup2.aicu.cc:88/api/v3/search"],r={reply:"/getreply",danmu:"/getvideodm",live:"/getlivedm"},i=[{key:"reply",name:"评论"},{key:"danmu",name:"视频弹幕"},{key:"live",name:"直播弹幕"}];class a{constructor(t){this.code=t?.code??-1,this.message=t?.message||"",this.ttl=t?.ttl||1,this.data=t?.data||null}get success(){return 0===this.code}}class s{constructor(t){this.time=t.time||0,this.message=t.message||"",this.oid=t.dyn?.oid||"",this.rpid=t.rpid||""}get link(){return this.oid?`${e}/av${this.oid}/#reply${this.rpid}`:""}}class c{constructor(t){this.ctime=t.ctime||0,this.content=t.content||"",this.oid=t.oid||""}get link(){return this.oid?`${e}/av${this.oid}`:""}}class d{constructor(t,e){this.roomId=t.roomid||"",this.roomName=t.roomname||"",this.upName=t.upname||"",this.text=e.text||"",this.ts=e.ts||0}get link(){return this.roomId?`${o}/${this.roomId}`:""}}const l=[],u=new Map;let p=!1,m=null,b=1,f="reply",h=!1,y=0;GM_addStyle(`\n #${t} { position: absolute; width: 380px; max-height: 70vh; overflow: auto; background: #fff; color: #333; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 6px 24px rgba(0,0,0,.18); z-index: 99999; padding: 12px; display: none; font-family: inherit; }\n body.dark #${t} { background: #1f1f1f; color: #e9eaec; border-color: #333; }\n #${t} .header { display: flex; justify-content: space-between; align-items: center; font-weight: 700; margin-bottom: 8px; }\n #${t} .close { padding: 4px 8px; border: 0; background: #bbb; color: #fff; border-radius: 4px; cursor: pointer; }\n body.dark #${t} .close { background: #444; color: #e9eaec; }\n #${t} .tabs { display: flex; gap: 6px; margin-bottom: 8px; }\n #${t} .tabs button { flex: 1; padding: 6px; border: 1px solid #ddd; background: #f5f5f5; border-radius: 4px; cursor: pointer; font-size: 12px; }\n #${t} .tabs button.active { background: #00a1d6; color: #fff; border-color: #00a1d6; }\n body.dark #${t} .tabs button { background: #333; border-color: #444; color: #e9eaec; }\n body.dark #${t} .tabs button.active { background: #00a1d6; border-color: #00a1d6; }\n #${t} .item { margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid #f2f2f2; }\n body.dark #${t} .item { border-color: #2c2c2c; }\n #${t} .meta { font-size: 12px; color: #666; margin-bottom: 4px; }\n #${t} .meta a { color: #00a1d6; text-decoration: none; }\n body.dark #${t} .meta { color: #9ca3af; }\n #${t} .text { font-size: 14px; white-space: pre-wrap; word-break: break-all; }\n #${t} .room { font-size: 12px; color: #00a1d6; margin-bottom: 2px; }\n #${t} .info { font-size: 12px; color: #999; margin-bottom: 8px; }\n #${t} .pager { display: flex; justify-content: space-between; margin-top: 8px; }\n #${t} .pager button { padding: 4px 12px; border: 1px solid #ddd; background: #f5f5f5; border-radius: 4px; cursor: pointer; }\n #${t} .pager button:disabled { opacity: 0.5; cursor: not-allowed; }\n body.dark #${t} .pager button { background: #333; border-color: #444; color: #e9eaec; }\n `);let v=location.href,g=null;async function $(){g&&(g.disconnect(),g=null);const t=await E(document,"bili-comments");await k(t),S(t),g=R(t)}function w(){window.addEventListener("popstate",x);const t=history.pushState,e=history.replaceState;history.pushState=function(...e){t.apply(this,e),x()},history.replaceState=function(...t){e.apply(this,t),x()}}function x(){location.href!==v&&(v=location.href,setTimeout(()=>$(),1e3))}async function k(t){const e=await E(t.shadowRoot,"bili-comment-thread-renderer"),o=await E(e.shadowRoot,"bili-comment-renderer");await E(o.shadowRoot,"#body")}function E(t,e){return new Promise(o=>{const n=()=>{const r=t.querySelector(e);r?o(r):setTimeout(n,500)};n()})}function S(t){const e=void 0;t.shadowRoot.querySelectorAll("bili-comment-thread-renderer").forEach(t=>L(t))}function R(t){const e=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)"BILI-COMMENT-THREAD-RENDERER"===t.nodeName&&q(t).then(()=>L(t))});return e.observe(t.shadowRoot,{childList:!0,subtree:!0}),e}async function q(t){await E(t.shadowRoot,"bili-comment-renderer")}function L(t){if(t.dataset.processed)return;t.dataset.processed="true";const e=t.shadowRoot.querySelector("bili-comment-renderer");e&&M(e);const o=t.shadowRoot.querySelector("bili-comment-replies-renderer"),n=void 0;(o?.shadowRoot?.querySelectorAll("bili-comment-reply-renderer")||[]).forEach(M),o?.shadowRoot&&N(o)}function N(t){if(t.dataset.observed)return;t.dataset.observed="true";const e=void 0;new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)"BILI-COMMENT-REPLY-RENDERER"===t.nodeName&&M(t)}).observe(t.shadowRoot,{childList:!0,subtree:!0})}function M(t){if(t.dataset.btnAdded)return;const e=t.shadowRoot?.querySelector("#body"),o=t.shadowRoot?.querySelector("bili-comment-action-buttons-renderer"),n=o?.shadowRoot?.querySelector("#reply");if(!e||!n)return void setTimeout(()=>M(t),200);t.dataset.btnAdded="true";const r=e.querySelector('a#user-avatar[href*="space.bilibili.com"]'),i=r?.href.match(/space\.bilibili\.com\/(\d+)/)?.[1],a=void 0;T(n,i,e.querySelector("#user-name a")?.textContent?.trim()||`UID${i}`)}function T(t,e,o){const n=document.createElement("div"),r=document.createElement("button");r.className="history-reply-btn",r.textContent="查看成分",r.onclick=t=>I(t,e,o),n.appendChild(r),t.after(n),l.push(r)}async function I(e,o,n){if(p)return;let r=document.getElementById(t);r||(r=document.createElement("div"),r.id=t,document.body.appendChild(r));const a=e.target.getBoundingClientRect();r.style.left=a.left+window.scrollX+"px",r.style.top=a.bottom+window.scrollY+5+"px";const s=i.map(t=>``).join("");r.innerHTML=`\n