// ==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
${n}
\n
${s}
\n
加载中...
\n `,r.style.display="block",r.querySelector(".close").onclick=()=>r.style.display="none",i.forEach(t=>{r.querySelector(`.tab-${t.key}`).onclick=()=>_(r,n,t.key)}),m=o,b=1,f="reply",h=!1,y=0,await z(r,n)}function _(t,e,o){p||f===o||(f=o,b=1,h=!1,y=0,i.forEach(e=>{t.querySelector(`.tab-${e.key}`).classList.toggle("active",e.key===o)}),z(t,e))}function C(t,e,o){return`${t}_${e}_${o}`}function D(t,e){t.querySelectorAll(".tabs button").forEach(t=>{t.disabled=e,t.style.opacity=e?"0.5":"",t.style.pointerEvents=e?"none":""})}async function z(t,e){const o=C(m,f,b);if(u.has(o)){const n=u.get(o);return y=n.total,h=n.isEnd,void B(t,n.list,e)}p=!0,j(!0),D(t,!0),t.querySelector(".body").innerHTML="加载中...";try{const n=await H(m,b,f);if(!n.success)throw new Error(n.message||`接口异常: code=${n.code}`);const r=A(n,f);y=n.data?.cursor?.all_count||y,h=n.data?.cursor?.is_end||!r.length,u.set(o,{list:r,total:y,isEnd:h}),B(t,r,e)}catch(e){t.querySelector(".body").textContent=`获取失败:${e.message}`}finally{p=!1,j(!1),D(t,!1)}}function A(t,e){const o=t.data;if("reply"===e)return(o?.replies||[]).map(t=>new s(t));if("danmu"===e)return(o?.videodmlist||[]).map(t=>new c(t));if("live"===e){const t=[],e=o?.list||[];for(const o of e){const e=o.danmu||[];for(const n of e)t.push(new d(o.roominfo,n))}return t}return[]}$(),w();const j=t=>l.forEach(e=>{e.disabled=t,e.style.opacity=t?"0.5":"",e.style.pointerEvents=t?"none":""});function H(t,e,o){return O(t,e,o,0)}function O(t,e,o,i){return new Promise((s,c)=>{const d=void 0;GM_xmlhttpRequest({method:"GET",url:`${n[i]+r[o]}?uid=${t}&pn=${e}&ps=100&mode=0&keyword=`,headers:{Origin:"https://www.aicu.cc",Referer:"https://www.aicu.cc/"},responseType:"json",onload:r=>{const d=new a(r.response);d.success?s(d):i{it.key===f)?.name||"",a=`
共 ${y} 条${r} · 第 ${b} 页
`,s=e.map(t=>G(t)).join(""),c=`
\n \n \n
`;n.innerHTML=a+s+c,n.querySelector(".prev").onclick=()=>{b>1&&(b--,z(t,o))},n.querySelector(".next").onclick=()=>{h||(b++,z(t,o))}}function G(t){if(t instanceof s){const e=void 0,o=void 0;return`
${t.time?new Date(1e3*t.time).toLocaleString():""} ${t.link?`跳转`:""}
${P(t.message)}
`}if(t instanceof c){const e=void 0,o=void 0;return`
${t.ctime?new Date(1e3*t.ctime).toLocaleString():""} ${t.link?`跳转`:""}
${P(t.content)}
`}if(t instanceof d){const e=t.ts?new Date(1e3*t.ts).toLocaleString():"",o=void 0;return`
${t.link?`${P(t.roomName)}`:P(t.roomName)} (${P(t.upName)})
${e}
${P(t.text)}
`}return""}function P(t){return t.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t]))} })();