PageSourceSearch

https://xoigac.top/dist/js/chat-quote.js?v=dadiJb-uFgutTAG6E7B9CHZwgLt-lEQCHB7Qea425VE

js xoigac.top collected 2026-10-10 02:21:48 UTC 6,768 bytes, 1 lines download raw bytes

1!function(global){const JSON_QUOTE_RE=/^\[回复:({.*?})]\s*([\s\S]*)$/,LEGACY_QUOTE_RE=/^\[回复 ([^\]]+)]\s*([\s\S]*)$/;function extractQuote(content){if(!content)return{quoteUser:null,quoteText:null,quoteMsgId:0,pureText:""};const payload=function findJsonQuotePayload(content){if(!content.startsWith("[回复:")||"{"!==content[4])return null;let depth=0,inString=!1,escaped=!1;for(let i=4;i<content.length;i++){const ch=content[i];if(inString){if(escaped){escaped=!1;continue}if("\\"===ch){escaped=!0;continue}'"'===ch&&(inString=!1)}else if('"'!==ch){if("{"===ch)depth++;else if("}"===ch&&(depth--,0===depth))return"]"===content[i+1]?{json:content.slice(4,i+1),rest:content.slice(i+2).replace(/^\s+/,"")}:null}else inString=!0}return null}(content);if(payload){const parsed=parseQuoteMeta(payload.json,payload.rest);if(parsed)return parsed}const jsonMatch=content.match(JSON_QUOTE_RE);if(jsonMatch){const parsed=parseQuoteMeta(jsonMatch[1],jsonMatch[2]||"");if(parsed)return parsed}const legacyMatch=content.match(LEGACY_QUOTE_RE);return legacyMatch?{quoteUser:legacyMatch[1],quoteText:null,quoteMsgId:0,pureText:legacyMatch[2]||""}:{quoteUser:null,quoteText:null,quoteMsgId:0,pureText:content}}function parseQuoteMeta(json,rest){try{const meta=JSON.parse(function sanitizeQuoteJson(json){return String(json).replace(/"i"\s*:\s*\*+/g,'"i":0')}(json));return{quoteUser:meta.u||null,quoteText:unwrapQuoteText(meta.t??""),quoteMsgId:Number(meta.i)||0,pureText:rest||""}}catch(_){return null}}function unwrapQuoteText(text){if(!text||"string"!=typeof text||!text.startsWith("[回复:"))return text;const inner=extractQuote(text);return inner.quoteUser&&(inner.pureText||inner.quoteText)||text}function findQuotedMessageElement(messagesContainer,meta){if(!messagesContainer||!meta)return null;if(meta.quoteMsgId){const byId=messagesContainer.querySelector(`[data-msg-id="${meta.quoteMsgId}"], [data-message-id="${meta.quoteMsgId}"]`);if(byId)return byId}if(!meta.quoteUser||null==meta.quoteText||""===meta.quoteText)return null;const items=messagesContainer.querySelectorAll(".chat-message-item, .focus-chat-msg");for(const item of items){const itemUser=item.dataset.userName||item.dataset.realUserName||"",itemPure=item.dataset.pureContent||extractQuote(item.dataset.content||"").pureText||item.dataset.content||"";if(itemUser===meta.quoteUser&&itemPure===meta.quoteText)return item}return null}function scrollToQuotedMessage(messagesContainer,scrollWrapper,meta){const target=findQuotedMessageElement(messagesContainer,meta);if(!target||!scrollWrapper)return!1;const wrapperRect=scrollWrapper.getBoundingClientRect(),targetRect=target.getBoundingClientRect(),offsetFromBottom=wrapperRect.bottom-targetRect.bottom;return scrollWrapper.scrollTo({top:-(offsetFromBottom-50),behavior:"smooth"}),target.classList.add("message-highlight"),setTimeout(()=>target.classList.remove("message-highlight"),1200),!0}async function fetchAndMergeUntilMessage(roomId,messageId,container,buildElement){const response=await fetch(`/Match/GetChatHistoryUntil?roomId=${encodeURIComponent(roomId)}&messageId=${messageId}`);if(404===response.status)return{ok:!1,reason:"not_found"};if(!response.ok)return{ok:!1,reason:"error"};const messages=await response.json(),existingIds=function getLoadedMessageIds(container){const ids=new Set;return container.querySelectorAll("[data-msg-id],[data-message-id]").forEach(el=>{const id=Number(el.dataset.msgId||el.dataset.messageId);id&&ids.add(id)}),ids}(container),toAdd=messages.filter(m=>m.id&&!existingIds.has(m.id));if(0===toAdd.length)return{ok:!0,added:0};const fragment=document.createDocumentFragment();return toAdd.forEach(msg=>{const placeholder=document.createElement("div"),built=buildElement(msg,placeholder);fragment.appendChild(1===built?.nodeType?built:placeholder)}),container.insertBefore(fragment,container.firstChild),{ok:!0,added:toAdd.length}}async function scrollToQuotedMessageAsync(messagesContainer,scrollWrapper,meta,options){const opts=options||{},{roomId:roomId,buildElement:buildElement,loadMore:loadMore,hasMore:hasMore,maxLoadAttempts:maxLoadAttempts=30}=opts;if(scrollToQuotedMessage(messagesContainer,scrollWrapper,meta))return!0;
1if(meta.quoteMsgId&&roomId&&buildElement){if("not_found"===(await fetchAndMergeUntilMessage(roomId,meta.quoteMsgId,messagesContainer,buildElement)).reason)return!1;if(scrollToQuotedMessage(messagesContainer,scrollWrapper,meta))return!0}if("function"==typeof loadMore&&"function"==typeof hasMore)for(let i=0;i<maxLoadAttempts&&hasMore();i++)if(await loadMore(),scrollToQuotedMessage(messagesContainer,scrollWrapper,meta))return!0;return!1}global.ChatQuoteUtil={extractQuote:extractQuote,formatQuoteMessage:function formatQuoteMessage(quote,replyText){if(!quote?.userName)return replyText;const rawContent=quote.content||"",extracted=extractQuote(rawContent),cleanContent=extracted.quoteUser?extracted.pureText||extracted.quoteText||"":rawContent;return`[回复:${JSON.stringify({u:quote.userName,t:cleanContent,i:Number(quote.messageId)||0})}] ${replyText}`},buildQuoteHtml:function buildQuoteHtml(quoteUser,quoteText,options){if(!quoteUser||null==quoteText||""===quoteText)return"";const opts=options||{},escapeHtml=opts.escapeHtml||(value=>value),maskUser=opts.maskUser||(value=>value),maxLen=opts.maxLen||42,className=opts.className||"message-quote focus-chat-msg-quote",maskedUser=maskUser(quoteUser),truncated=quoteText.length>maxLen?`${quoteText.substring(0,maxLen)}...`:quoteText;return`\n            <div class="${className}" role="button" tabindex="0" title="${window.L?.T?window.L.T("match.chat.jumpToOriginal"):"定位到原消息"}">\n                <i class="fas fa-reply"></i>\n                <span class="quote-author">${escapeHtml(maskedUser)}</span>\n                <span class="quote-text">${escapeHtml(truncated)}</span>\n            </div>\n        `},findQuotedMessageElement:findQuotedMessageElement,scrollToQuotedMessage:scrollToQuotedMessage,scrollToQuotedMessageAsync:scrollToQuotedMessageAsync,fetchAndMergeUntilMessage:fetchAndMergeUntilMessage,bindQuoteJump:function bindQuoteJump(quoteBlock,meta,context){if(!quoteBlock)return;const jumpToQuote=async event=>{event?.stopPropagation?.(),quoteBlock.classList.add("quote-jump-loading"),quoteBlock.classList.remove("quote-jump-miss");try{await scrollToQuotedMessageAsync(context.messagesContainer,context.scrollWrapper,meta,context.options)||(quoteBlock.classList.add("quote-jump-miss"),setTimeout(()=>quoteBlock.classList.remove("quote-jump-miss"),1500))}finally{quoteBlock.classList.remove("quote-jump-loading")}};quoteBlock.addEventListener("click",jumpToQuote),quoteBlock.addEventListener("keydown",event=>{"Enter"!==event.key&&" "!==event.key||(event.preventDefault(),jumpToQuote(event))})}}}(window);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.