您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
sis001第一会所综合社区,帖子图片预览,板块收纳,搜索优化
// ==UserScript== // @name sis001-预览 // @version 1.2.10 // @namespace https://sleazyfork.org/zh-CN/users/1461640-%E6%98%9F%E5%AE%BF%E8%80%81%E9%AD%94 // @author 星宿老魔 // @description sis001第一会所综合社区,帖子图片预览,板块收纳,搜索优化 // @match https://sis001.com/* // @match https://*.sis001.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=sis001.com // @license MIT // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @run-at document-start // ==/UserScript== (function(){"use strict";const e={ACCENT:"#00599F",BG_LIGHT:"#f8f9fa",BORDER_LIGHT:"#e3e6ea",BORDER_NORMAL:"#e9ecef", TEXT_PRIMARY:"#2c3e50",TEXT_SECONDARY:"#666",TEXT_LIGHT:"#999",TEXT_ERROR:"#333"};const t={SM:"6px",MD:"8px",XL:"12px", ROUND:"50%",PILL:"999px"};const n={MD:"8px",LG:"10px",XL:"12px",XXL:"16px"};const o={LIGHT:"0 2px 6px rgba(0,0,0,0.08)", NORMAL:"0 3px 12px rgba(0,0,0,0.08)",IMAGE:"0 2px 8px rgba(0,0,0,0.12)"};const a={ GRADIENT:"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)",WHITE_ALPHA:"rgba(255,255,255,0.9)", LIGHT_ALPHA:"rgba(248,249,250,0.6)"};const i={select(e){return document.querySelector(e)},selectAll(e){ return document.querySelectorAll(e)},create(e,t={},n={}){const o=document.createElement(e) ;Object.entries(t).forEach(([e,t])=>{o.setAttribute(e,t)});Object.entries(n).forEach(([e,t])=>{o.style[e]=t});return o}, addStyle(e,t){const n=document.createElement("style");if(t)n.id=t;n.textContent=e;document.head.appendChild(n);return n} };const s={resolve(e,t){try{return new URL(t,e).href}catch(n){void 0;return t}},isHttp(e){return/^https?:\/\//i.test(e)} };const r={applyButtonStyle(t,options={}){const{primary:n=false}=options ;const o=["display:inline-flex","align-items:center","justify-content:center","height:28px","padding:0 12px","border-radius:6px","font-size:12px","line-height:1","cursor:pointer","user-select:none","white-space:nowrap","box-sizing:border-box"] ;const a=n?`background:${e.ACCENT};color:#fff;border:1px solid ${e.ACCENT}`:`background:#fff;color:${e.TEXT_PRIMARY};border:1px solid ${e.BORDER_LIGHT}` ;t.style.cssText=[...o,a].join(";")},ensureToggleStyles(){ if(document.querySelector('style[data-sis-toggle-style="1"]'))return ;const n=`.sis-toggle{display:inline-flex;align-items:center;gap:${t.SM};cursor:pointer;user-select:none;height:28px;padding:0 12px;border:1px solid ${e.BORDER_LIGHT};border-radius:${t.SM};background:#fff;box-shadow:${o.LIGHT};vertical-align:middle;box-sizing:border-box}.sis-toggle .sis-input{position:absolute;opacity:0;width:0;height:0}.sis-toggle .sis-switch{position:relative;width:30px;height:16px;background:#e5e7eb;border-radius:${t.PILL};box-shadow:inset 0 0 0 1px #d1d5db;flex:0 0 30px}.sis-toggle .sis-switch::before{content:"";position:absolute;top:2px;left:2px;width:12px;height:12px;background:#fff;border-radius:${t.ROUND};box-shadow:0 1px 2px rgba(0,0,0,.2)}.sis-toggle .sis-input:checked + .sis-text + .sis-switch{background:${e.ACCENT}}.sis-toggle .sis-input:checked + .sis-text + .sis-switch::before{transform:translateX(14px)}.sis-toggle .sis-text{color:${e.TEXT_ERROR};font-size:12px}` ;i.addStyle(n,"sis-toggle-styles").setAttribute("data-sis-toggle-style","1")}};const c={createOverlay(){ return i.create("div",{},{position:"fixed",inset:"0",background:"rgba(0,0,0,0.4)",zIndex:"10001",display:"flex", alignItems:"center",justifyContent:"center"})},createPanel(e="480px"){return i.create("div",{},{width:e,maxWidth:"92vw", maxHeight:"80vh",overflow:"auto",background:"#fff",borderRadius:"10px",boxShadow:"0 10px 30px rgba(0,0,0,.2)"})}, createHeader(e,t){const n=i.create("div",{},{padding:"12px 16px",borderBottom:"1px solid #e9ecef",fontWeight:"600", display:"flex",justifyContent:"space-between",alignItems:"center"});n.textContent=e;const o=i.create("button") ;o.textContent="×";r.applyButtonStyle(o);o.onclick=t;n.appendChild(o);return n},createFooter(e,t,n="保存并刷新"){ const o=i.create("div",{},{padding:"12px 16px",borderTop:"1px solid #e9ecef",display:"flex",justifyContent:"flex-end", gap:"10px"});const a=i.create("button");a.textContent="取消";r.applyButtonStyle(a);a.onclick=e;const s=i.create("button") ;s.textContent=n;r.applyButtonStyle(s);s.onclick=t;o.appendChild(a);o.appendChild(s);return o}};const l={ waitForDOMContentLoaded(){if("loading"===document.readyState)return new Promise(e=>{ document.addEventListener("DOMContentLoaded",()=>e(),{once:true})});return Promise.resolve()},waitForWindowLoad(){ if("complete"!==document.readyState)return new Promise(e=>{window.addEventListener("load",()=>e(),{once:true})}) ;return Promise.resolve()}};const d=class _MagnetConverter{static init(){this.setupMagnetLinks()} static setupMagnetLinks(){if(!i.select(".t_msgfont"))return;const e=i.selectAll(".t_msgfont");e.forEach(e=>{ this.processPost(e)})}static processPost(e){if(this.processed.has(e))return;const t=/([a-fA-F0-9]{40})/g ;if(t.test(e.innerHTML))e.innerHTML=e.innerHTML.replace(t,e=>`magnet:?xt=urn:btih:${e}`);this.processed.add(e)} static refresh(){this.setupMagnetLinks()}};d.processed=new WeakSet;let p=d;class AdRemover{static init(){ this.injectHidingCSS();this.removeRulesTable();this.removePublicMessages();this.removeStickyTopics() ;this.removeImportantTopics();this.removeAdministrativeThreads();setTimeout(()=>{this.removeRulesTable() ;this.removePublicMessages();this.removeStickyTopics();this.removeImportantTopics();this.removeAdministrativeThreads() },1e3)}static injectHidingCSS(){if(i.select('style[data-sis-ad-remover="1"]'))return ;const e=`\n /* 立即隐藏本版规则表格 */\n table[summary="Rules and Recommend"] { display: none !important; }\n \n /* 立即隐藏公共消息 */\n .maintable#pmprompt,\n .box#pmprompt { display: none !important; }\n \n /* 立即隐藏固定主题和重要主题区块 */\n thead.separation { display: none !important; }\n tbody[id^="stickthread_"] { display: none !important; }\n \n /* 立即隐藏版务相关帖子(备用CSS) */\n .sis-hide-admin { display: none !important; }\n ` ;i.addStyle(e).setAttribute("data-sis-ad-remover","1")}static removeRulesTable(){ const e=document.querySelector('table[summary="Rules and Recommend"]');if(e)e.remove()}static removePublicMessages(){ const e=document.querySelector(".maintable#pmprompt");if(e)e.remove();const t=document.querySelector(".box#pmprompt") ;if(t)t.remove()}static removeTopicsByType(e){const t=document.querySelectorAll("thead.separation");t.forEach(t=>{ const n=t.querySelectorAll("font");let o=false;n.forEach(t=>{if(e.some(e=>t.textContent?.includes(e)))o=true});if(o){ t.remove();let e=t.nextElementSibling;while(e)if("TBODY"===e.tagName&&e.id&&e.id.startsWith("stickthread_")){const t=e ;e=e.nextElementSibling;t.remove()}else break}})}static removeStickyTopics(){this.removeTopicsByType(["固定主題"])} static removeImportantTopics(){this.removeTopicsByType(["重要主題"])}static removeAdministrativeThreads(){ const e=document.querySelectorAll('tbody[id^="stickthread_"], tbody[id^="normalthread_"]');e.forEach(e=>{ const t=e.querySelectorAll('em a[href*="typeid=528"]');if(t.length>0){e.classList.add("sis-hide-admin");setTimeout(()=>{ e.remove()},10)}})}static refresh(){this.removeRulesTable();this.removePublicMessages();this.removeStickyTopics() ;this.removeImportantTopics();this.removeAdministrativeThreads()}}class PostLayoutManager{ static async transformPostLayout(e,t,n,o){const a=this.getTableColumnCount(e);e.innerHTML="";const s=i.create("tr") ;const r=i.create("td",{colspan:String(a)},{padding:"4px !important",border:"none !important", background:"transparent !important"});const c=this.createPostContainer();const l=this.createTitleSection(t,n) ;const d=this.createImageSection();c.appendChild(l);c.appendChild(d);r.appendChild(c);s.appendChild(r);e.appendChild(s) ;await o(d)}static getTableColumnCount(e){const t=e.closest("table");if(t){ const e=t.querySelector("thead tr")||t.querySelector("tr:first-child");if(e){let t=0 ;const n=e.querySelectorAll("th, td");n.forEach(e=>{const n=parseInt(e.getAttribute("colspan")||"1");t+=n}) ;if(t>0)return t}}return 6}static createPostContainer(){const n=i.create("div",{class:"new-post-layout"},{ background:a.GRADIENT,border:`1px solid ${e.BORDER_LIGHT}`,borderRadius:t.XL,boxShadow:o.NORMAL,overflow:"hidden"}) ;return n}static createTitleSection(t,o){const s=i.create("div",{},{padding:`${n.XL} ${n.XXL}`,background:a.WHITE_ALPHA, borderBottom:`1px solid ${e.BORDER_NORMAL}`});const r=i.create("a",{href:t},{fontWeight:"500",color:e.TEXT_PRIMARY, fontSize:"15px",lineHeight:"1.3",textDecoration:"none",display:"block",wordBreak:"break-word"});r.textContent=o||"无标题" ;s.appendChild(r);return s}static createImageSection(){const t=i.create("div",{},{padding:`${n.MD} ${n.XXL}`, background:a.LIGHT_ALPHA,display:"flex",gap:n.LG,minHeight:"60px",flexWrap:"nowrap",alignItems:"center",overflow:"auto" });const o=i.create("div",{},{color:e.TEXT_SECONDARY,fontSize:"14px"});o.textContent="正在加载图片预览...";t.appendChild(o) ;return t}}const g={collectNames:"sis_board_collect_names",favoriteNames:"sis_board_favorite_names", collectionOpen:"sis_board_collection_open",favoriteOpen:"sis_board_favorite_open", searchFavForums:"sis_search_fav_forums",searchLastSelection:"sis_search_last_selection", searchFavAuto:"sis_search_fav_auto",previewMaxImages:"sis_preview_max_images"};const h={MAX_IMAGES_PER_POST:4} ;class Config{static getMaxImagesPerPost(){const e=parseInt(GM_getValue(g.previewMaxImages,"")||"",10) ;return 4===e||5===e?e:h.MAX_IMAGES_PER_POST}static setMaxImagesPerPost(e){try{GM_setValue(g.previewMaxImages,String(e)) }catch(t){void 0}}static getCollectedBoardNames(){try{const e=GM_getValue(g.collectNames,"");if(!e)return[] ;const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){void 0;return[]}}static setCollectedBoardNames(e){try{ GM_setValue(g.collectNames,JSON.stringify(e||[]))}catch(t){void 0}}static getFavoriteBoardNames(){try{ const e=GM_getValue(g.favoriteNames,"");if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){ void 0;return[]}}static setFavoriteBoardNames(e){try{GM_setValue(g.favoriteNames,JSON.stringify(e||[]))}catch(t){void 0} }static getCollectionOpen(){try{return"1"===GM_getValue(g.collectionOpen,"0")}catch(e){void 0;return false}} static setCollectionOpen(e){try{GM_setValue(g.collectionOpen,e?"1":"0")}catch(t){void 0}}static getFavoriteOpen(){try{ return"1"===GM_getValue(g.favoriteOpen,"0")}catch(e){void 0;return false}}static setFavoriteOpen(e){try{ GM_setValue(g.favoriteOpen,e?"1":"0")}catch(t){void 0}}static getSearchFavForums(){try{ const e=GM_getValue(g.searchFavForums,"");return e?JSON.parse(e):[]}catch(e){void 0;return[]}} static setSearchFavForums(e){try{GM_setValue(g.searchFavForums,JSON.stringify(e||[]))}catch(t){void 0}} static getSearchFavAuto(){try{return"1"===GM_getValue(g.searchFavAuto,"0")}catch(e){void 0;return false}} static setSearchFavAuto(e){try{GM_setValue(g.searchFavAuto,e?"1":"0")}catch(t){void 0}}static getSearchLastSelection(){ try{const e=GM_getValue(g.searchLastSelection,"");return e?JSON.parse(e):[]}catch(e){void 0;return[]}} static setSearchLastSelection(e){try{GM_setValue(g.searchLastSelection,JSON.stringify(e||[]))}catch(t){void 0}}} class ImageExtractor{static extractAndGroupImages(e){ const t=e.querySelector(".t_msgfont")||e.querySelector(".postmessage");if(!t)return{images:[],domainGroups:new Map} ;const n=t.cloneNode(true);this.cleanContentClone(n);const o=Array.from(n.querySelectorAll("img")) ;const a=o.filter(e=>this.isValidContentImage(e));const i=this.groupImagesByDomain(a);this.applyImageLimits(i) ;const s=Array.from(i.keys());const r=s[0]||"";const c=i.get(r)||[];this.logExtractionResults(c,o,s);return{images:c, domainGroups:i}}static cleanContentClone(e){e.querySelectorAll(".quote").forEach(e=>e.remove()) ;e.querySelectorAll(".ad_pip, .ad_thread3_0, .ad_thread4_0").forEach(e=>e.remove()) ;e.querySelectorAll(".postratings, .comment_digg").forEach(e=>e.remove())}static isValidContentImage(e){ const t=e.getAttribute("onclick")||"";const n=e.getAttribute("onload")||"";const o=e.getAttribute("src")||e.src||"" ;const a=t.includes("zoom(this");const i=n.includes("attachimg(this") ;const s=o.includes("images/green001/")||o.includes("images/attachicons/")||o.includes("images/smilies/")||o.includes("images/joinvip.gif") ;const r=/attachments\/month_\d{4}\/\d{8}_[a-zA-Z0-9]+\.(gif|jpg|jpeg|png)$/i.test(o) ;const c=Boolean(o&&o.length>10&&!o.includes("data:"));const l=/\.(jpg|jpeg|png|gif|webp)(\?|$)/i.test(o) ;return a&&i&&!s&&!r&&c&&l}static groupImagesByDomain(e){const t=new Map;e.forEach(e=>{const n=this.getImageSource(e) ;const o=this.extractDomain(n);if(!t.has(o))t.set(o,[]);t.get(o).push(e)});return t}static applyImageLimits(e){ const t=Config.getMaxImagesPerPost();const n=Array.from(e.keys());n.forEach(n=>{const o=e.get(n)||[] ;e.set(n,o.slice(0,t))})}static logExtractionResults(e,t,n){if(0===e.length)void 0;else if(n.length>1)void 0} static extractDomain(e){try{return new URL(e).hostname}catch{return"unknown"}}static getImageSource(e){ return e.getAttribute("src")||e.src||""}}class ImageLoader{static async loadImagesForPost(e,t,n,o=0){const a=2;try{ const o=await fetch(e);if(!o.ok)throw new Error(`请求失败,状态码: ${o.status}`);const a=await o.text() ;if(a.includes("<b>Parse error</b>"))throw new Error(`服务器返回PHP解析错误`);const i=new DOMParser ;const r=i.parseFromString(a,"text/html");const{images:c,domainGroups:l}=ImageExtractor.extractAndGroupImages(r) ;t.innerHTML="";if(0===c.length){this.showSimpleNoImageMessage(t);return} const d=c.map(t=>s.resolve(e,ImageExtractor.getImageSource(t)));if(n)n(d,l);return}catch(i){ const s=i instanceof Error?i.message:"未知错误";void 0;const r=o<a;const c=0===o?"重试":`重试 (${o}/${a})` ;this.showStaticFailureMessage(t,s.includes("403")||s.includes("权限")?"访问受限":"加载失败",r?()=>{setTimeout(()=>{ this.loadImagesForPost(e,t,n,o+1)},Math.min(1e3+1e3*o,3e3))}:void 0,c);return}} static showStaticFailureMessage(t,n,o,a="重试"){t.innerHTML="" ;t.style.cssText=`\n padding: 8px 20px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n height: auto;\n min-height: 30px;\n max-height: 30px;\n gap: 10px;\n ` ;const s=i.create("div",{},{color:e.TEXT_LIGHT,fontSize:"13px",fontStyle:"italic",lineHeight:"1.2"});s.textContent=n ;t.appendChild(s);if(o){const n=i.create("button");n.textContent=a ;n.style.cssText=`\n padding: 2px 8px;\n font-size: 11px;\n margin-left: 8px;\n cursor: pointer;\n border: 1px solid ${e.TEXT_LIGHT};\n background: transparent;\n border-radius: 3px;\n color: ${e.TEXT_LIGHT};\n ` ;n.onclick=e=>{e.stopPropagation();o()};t.appendChild(n)}}static showSimpleNoImageMessage(t){t.innerHTML="" ;t.style.cssText=`\n padding: 8px 20px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n height: auto;\n min-height: 30px;\n max-height: 30px;\n ` ;const n=i.create("div",{},{color:e.TEXT_LIGHT,fontSize:"13px",fontStyle:"italic",textAlign:"center",lineHeight:"1.2"}) ;n.textContent="帖子内无图片内容";t.appendChild(n)}}class ImageViewer{static getImageSource(e){ return e.getAttribute("src")||e.src||""}static show(e,t,n){const o=this.createViewerOverlay() ;const{container:a,img:i,info:r,prevBtn:c,nextBtn:l}=this.createViewerElements();let d=t;const updateImage=()=>{ const t=this.getImageSource(e[d]);const o=s.resolve(n||location.href,t);this.updateImageSize(i,o) ;r.textContent=`${d+1} / ${e.length}`};c.addEventListener("click",()=>{d=(d-1+e.length)%e.length;updateImage()}) ;l.addEventListener("click",()=>{d=(d+1)%e.length;updateImage()});const handleKeydown=e=>{ if("ArrowLeft"===e.key)c.click();else if("ArrowRight"===e.key)l.click();else if("Escape"===e.key){o.remove() ;document.removeEventListener("keydown",handleKeydown)}};o.addEventListener("click",e=>{if(e.target===o){o.remove() ;document.removeEventListener("keydown",handleKeydown)}});a.appendChild(r);a.appendChild(c);a.appendChild(l) ;a.appendChild(i);o.appendChild(a);document.body.appendChild(o);document.addEventListener("keydown",handleKeydown) ;updateImage()}static createViewerOverlay(){return i.create("div",{},{position:"fixed",top:"0",left:"0",width:"100%", height:"100%",background:"rgba(0,0,0,0.9)",zIndex:"10000",display:"flex",alignItems:"center",justifyContent:"center"})} static createViewerElements(){const e=i.create("div",{},{position:"relative",maxWidth:"90%",maxHeight:"90%", textAlign:"center"});const t=i.create("img",{},{objectFit:"contain",borderRadius:"8px", boxShadow:"0 4px 20px rgba(0,0,0,0.5)"});const n=i.create("div",{},{position:"absolute",top:"-40px",left:"50%", transform:"translateX(-50%)",color:"white",fontSize:"16px",fontWeight:"bold",background:"rgba(0,0,0,0.7)", padding:"8px 16px",borderRadius:"20px"});const o={position:"fixed",top:"50%",transform:"translateY(-50%)", background:"rgba(255,255,255,0.2)",color:"white",border:"none",fontSize:"24px",width:"44px",height:"44px", borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",zIndex:"10002"} ;const a=i.create("button",{},{...o,left:"16px"});a.innerHTML="❮";const s=i.create("button",{},{...o,right:"16px" });s.innerHTML="❯";return{container:e,img:t,info:n,prevBtn:a,nextBtn:s}}static updateImageSize(e,t){ e.style.width="";e.style.height="";e.style.maxWidth="";e.style.maxHeight="";e.style.display="none";e.onload=()=>{ e.style.display="block";const t=.9*window.innerWidth;const n=.9*window.innerHeight;const o=e.naturalWidth ;const a=e.naturalHeight;if(o<300&&a<300){const i=2*o;const s=2*a;if(i<=t&&s<=n){e.style.width=i+"px" ;e.style.height=s+"px"}else this.scaleImageToFit(e,i,s,t,n)}else if(o>t||a>n)this.scaleImageToFit(e,o,a,t,n);else{ e.style.width=o+"px";e.style.height=a+"px"}};e.onerror=()=>{e.style.display="block";e.style.maxWidth="90%" ;e.style.maxHeight="90%"};e.src=t}static scaleImageToFit(e,t,n,o,a){const i=o/t;const s=a/n;const r=Math.min(i,s) ;const c=t*r;const l=n*r;e.style.width=c+"px";e.style.height=l+"px"}}class ImageRenderer{static renderImages(e,n,o,a){ e.innerHTML="" ;e.style.cssText=`\n padding: 16px 20px;\n background: rgba(248, 250, 252, 0.7);\n display: flex;\n gap: 16px;\n height: 300px;\n flex-wrap: nowrap;\n align-items: stretch;\n overflow: auto;\n ` ;const i=Array.from(a.keys());const r=i[0];const c=a.get(r)||[];const l=[];for(let t=0;t<c.length;t++)l.push(t) ;if(0===l.length){this.showGlobalFailure(e);return}const d=l.map(()=>({completed:false,success:false}));let p=false ;const checkAllComplete=()=>{const t=d.every(e=>e.completed);if(t&&!p)this.showGlobalFailure(e)};l.forEach((r,c)=>{ const g=this.createImageContainer(l.length);const loadDomainGroup=e=>{if(e>=i.length){g.remove();d[c].completed=true ;d[c].success=false;checkAllComplete();return}const l=i[e];const h=a.get(l)||[];const u=h[r];if(!u){loadDomainGroup(e+1) ;return}const f=s.resolve(o,ImageExtractor.getImageSource(u));g.innerHTML="";const m=document.createElement("img") ;m.style.cssText=`\n width: 100%;\n height: 100%;\n object-fit: cover;\n border-radius: ${t.MD};\n cursor: pointer;\n display: block;\n ` ;m.onload=()=>{m.style.opacity="1";if(m.naturalHeight>m.naturalWidth)m.style.objectFit="contain";d[c].completed=true ;d[c].success=true;p=true;g.setAttribute("data-actual-url",f);this.setupImageInteraction(g,n,r,o)};m.onerror=()=>{ loadDomainGroup(e+1)};m.style.opacity="0.7";m.src=f;g.appendChild(m)};g.setAttribute("data-image-index",String(r)) ;loadDomainGroup(0);e.appendChild(g)})}static showIndividualFailure(n){n.innerHTML="" ;n.style.cssText=`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.1);\n border: 1px dashed rgba(0, 0, 0, 0.2);\n border-radius: ${t.MD};\n cursor: default;\n ` ;const o=i.create("div",{},{fontSize:"11px",color:e.TEXT_LIGHT,textAlign:"center",opacity:"0.6"});o.textContent="—" ;n.appendChild(o)}static showGlobalFailure(t){t.innerHTML="" ;t.style.cssText=`\n padding: 8px 20px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n height: auto;\n min-height: 30px;\n max-height: 30px;\n ` ;const n=i.create("div",{},{fontSize:"12px",color:e.TEXT_SECONDARY,textAlign:"center",fontStyle:"italic"}) ;n.textContent="所有域名都无法加载-帖子内可能无图";t.appendChild(n)}static showFinalFailure(e){this.showIndividualFailure(e)} static createImageContainer(n=1){const a=1===n?"0 0 50%":"1";return i.create("div",{},{position:"relative",flex:a, minWidth:"120px",cursor:"pointer",borderRadius:t.MD,overflow:"hidden",boxShadow:o.IMAGE,backgroundColor:e.BG_LIGHT})} static setupImageInteraction(e,t,n,o){e.addEventListener("click",()=>{const a=e.getAttribute("data-actual-url")||t[n] ;const s=t.map((e,t)=>{if(t===n)return a;return e});const r=s.map(e=>i.create("img",{src:e}));ImageViewer.show(r,n,o)})} }class ImagePreview{static async init(){await this.displayThreadImages()}static async displayThreadImages(){ if(i.select(".postmessage")||i.select("#postlist")||i.select(".plhin")||i.select(".t_msgfont"))return ;const e=window.location.href.includes("/search.php");const t=window.location.href.includes("/tag.php");let n=[] ;if(e||t){const e=i.selectAll("tbody");n=Array.from(e).filter(e=>{ const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]');const n=e.querySelector(".icon");return t&&n}) }else{const e=i.selectAll('tbody[id^="normalthread_"]');n=Array.from(e)}const o=n.map(e=>async()=>{ if(e.id&&e.id.startsWith("stickthread_"))return;if(e.querySelector(".new-post-layout"))return ;const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]');if(!t)return;const n=t.href ;let o=t.textContent?.trim()||"";if(!o){const t=e.querySelector('span[id^="thread_"]');if(t)o=t.textContent?.trim()||""} await PostLayoutManager.transformPostLayout(e,n,o,async e=>{await ImageLoader.loadImagesForPost(n,e,(t,o)=>{ ImageRenderer.renderImages(e,t,n,o)})})});await Promise.all(o.map(e=>e()))}}class BoardManager{static init(){ this.normalizeExclusiveLists();this.setupBoardCollectionCollapse();this.setupBoardFavoriteSection()} static normalizeExclusiveLists(){const e=new Set(Config.getFavoriteBoardNames()) ;const t=new Set(Config.getCollectedBoardNames());let n=false;e.forEach(e=>{if(t.has(e)){t.delete(e);n=true}}) ;if(n)Config.setCollectedBoardNames(Array.from(t))}static findBoardElementsMap(){const e=new Map ;const t=i.selectAll("div.mainbox.forumlist");t.forEach(t=>{const n=t.querySelector("h3 > a") ;const o=n?.textContent?.trim()||"";if(o&&!e.has(o))e.set(o,t)});return e}static moveBoardsToContainer(e,t){ const n=this.findBoardElementsMap();const o=[];e.forEach(e=>{const a=n.get(e);if(a){t.appendChild(a);o.push(e)}}) ;return o}static setupBoardCollectionCollapse(){this.setupBoardSection({containerId:"board-collection-container", title:"板块收纳区",getBoardNames:()=>Config.getCollectedBoardNames(),getOpenState:()=>Config.getCollectionOpen(), setOpenState:e=>Config.setCollectionOpen(e),onSettings:()=>this.openBoardCollectSettings(), insertMethod:e=>this.insertContainer(e),emptyMessage:'未选择任何板块,可点击右侧"设置"进行选择。'})}static setupBoardFavoriteSection(){ this.setupBoardSection({containerId:"board-favorite-container",title:"板块收藏区", getBoardNames:()=>Config.getFavoriteBoardNames(),getOpenState:()=>Config.getFavoriteOpen(), setOpenState:e=>Config.setFavoriteOpen(e),onSettings:()=>this.openBoardFavoriteSettings(), insertMethod:e=>this.insertFavoriteContainer(e),emptyMessage:'未选择任何收藏板块,可点击右侧"设置"进行选择。'})} static setupBoardSection(config){if(i.select(`#${config.containerId}`))return;const e=new Set(config.getBoardNames()) ;const t=Array.from(i.selectAll("div.mainbox.forumlist"));if(0===t.length)return;const n=t.filter(t=>{ const n=t.querySelector("h3 > a");const o=n?.textContent?.trim()||"";return o&&e.has(o)}) ;const o=this.createBoardContainer(config.containerId,config.title,n.length) ;const{content:a}=this.setupContainerElements(o,{isOpen:config.getOpenState(),onToggle:config.setOpenState, onSettings:config.onSettings,title:config.title,count:n.length});config.insertMethod(o) ;if(0===n.length)this.showEmptyMessage(a,config.emptyMessage);else{const e=n.map(e=>{const t=e.querySelector("h3 > a") ;return t?.textContent?.trim()||""});this.moveBoardsToContainer(e,a)}}static createBoardContainer(e,t,n){ return i.create("div",{id:e},{margin:"12px 0",border:"1px solid #e3e6ea",borderRadius:"10px", boxShadow:"0 3px 12px rgba(0,0,0,0.08)",overflow:"hidden",background:"#fff"})}static setupContainerElements(e,options){ const t=i.create("div",{},{padding:"10px 14px", background:options.isOpen?"#f0f0f0":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)", border:options.isOpen?"2px solid #d0d0d0":"none",borderBottom:"1px solid #e9ecef",cursor:"pointer",userSelect:"none", display:"flex",alignItems:"center",justifyContent:"space-between"});const n=i.create("span",{},{fontWeight:"600", color:"#2c3e50",fontSize:"14px"});n.textContent=`${options.title}(共 ${options.count} 个)`;const o=i.create("span",{},{ fontSize:"12px",color:"#666"});o.textContent=options.isOpen?"[点击收起]":"[点击展开]";const a=i.create("button") ;a.textContent="设置";a.title="选择需要管理的板块";r.applyButtonStyle(a);a.addEventListener("click",e=>{e.stopPropagation() ;options.onSettings()});const s=i.create("div",{},{display:"flex",alignItems:"center",gap:"10px"});s.appendChild(o) ;s.appendChild(a);t.appendChild(n);t.appendChild(s);const c=i.create("div",{},{padding:"10px",background:"#fafafa", border:"2px solid #d0d0d0",borderTop:"none",display:options.isOpen?"":"none"});t.addEventListener("click",()=>{ const e="none"===c.style.display;c.style.display=e?"":"none";o.textContent=e?"[点击收起]":"[点击展开]" ;t.style.background=e?"#f0f0f0":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)" ;t.style.border=e?"2px solid #d0d0d0":"none";t.style.borderBottom="1px solid #e9ecef";options.onToggle(e)}) ;e.appendChild(t);e.appendChild(c);return{header:t,content:c,toggleHint:o}}static insertContainer(e){ const t=i.select('table.portalbox[summary="HeadBox"]')||i.select("#hottags")?.closest("table")||i.select("#hottags") ;if(t?.parentNode){const n=t.parentNode;if(t.nextSibling)n.insertBefore(e,t.nextSibling);else n.appendChild(e) }else document.body.appendChild(e)}static insertFavoriteContainer(e){const t=i.select("#board-collection-container") ;if(t?.parentNode){const n=t.parentNode;if(t.nextSibling)n.insertBefore(e,t.nextSibling);else n.appendChild(e) }else this.insertContainer(e)}static showEmptyMessage(e,t){const n=i.create("div",{},{color:"#666",fontSize:"12px"}) ;n.textContent=t;e.appendChild(n)}static openBoardCollectSettings(){const e=this.getAllBoardNames() ;this.openBoardSettings(e,Config.getCollectedBoardNames(),"板块收纳设置","勾选需要收纳到顶部的板块:",e=>{ const t=new Set(Config.getFavoriteBoardNames());e.forEach(e=>t.delete(e));Config.setFavoriteBoardNames(Array.from(t)) ;Config.setCollectedBoardNames(e);location.reload()})}static openBoardFavoriteSettings(){const e=this.getAllBoardNames() ;this.openBoardSettings(e,Config.getFavoriteBoardNames(),"板块收藏设置",'勾选需要加入"板块收藏区"的板块:',e=>{ const t=new Set(Config.getCollectedBoardNames());e.forEach(e=>t.delete(e));Config.setCollectedBoardNames(Array.from(t)) ;Config.setFavoriteBoardNames(e);location.reload()})}static getAllBoardNames(){ const e=Array.from(i.selectAll("div.mainbox.forumlist > h3 > a")).map(e=>e.textContent?.trim()||"").filter(Boolean) ;return Array.from(new Set(e))}static openBoardSettings(e,t,n,o,a){const s=c.createOverlay() ;const r=c.createPanel("520px");const l=c.createHeader(n,()=>s.remove());const d=i.create("div",{},{padding:"12px 16px" });const p=i.create("div",{},{color:"#666",marginBottom:"8px"});p.textContent=o;d.appendChild(p) ;const g=i.create("div",{},{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px"});const h=new Set(t);e.forEach(e=>{ const t=i.create("label",{},{display:"flex",alignItems:"center",gap:"6px",padding:"6px",border:"1px solid #eee", borderRadius:"6px"});const n=i.create("input",{type:"checkbox"});n.checked=h.has(e);n.onchange=()=>{ if(n.checked)h.add(e);else h.delete(e)};const o=i.create("span");o.textContent=e;t.appendChild(n);t.appendChild(o) ;g.appendChild(t)});d.appendChild(g);const u=c.createFooter(()=>s.remove(),()=>a(Array.from(h)));r.appendChild(l) ;r.appendChild(d);r.appendChild(u);s.appendChild(r);document.body.appendChild(s)}}class SearchOptimizer{static init(){ this.setupSearchFavorites()}static setupSearchFavorites(){ if(!/\/search\.php(\?|$)/.test(location.pathname+location.search))return;const e=i.select("#srchfid") ;if(!e||"SELECT"!==e.tagName||!e.multiple)return;this.createSearchTools(e);this.setupTopGrouping(e) ;this.setupAutoRemember(e)}static createSearchTools(e){const t=i.create("div",{},{margin:"6px 0",display:"flex", gap:"12px",alignItems:"center"});const n=i.create("button",{type:"button"},{height:"30px"});n.textContent="置顶设置" ;r.applyButtonStyle(n);n.addEventListener("click",t=>{t.preventDefault();t.stopPropagation() ;this.openSearchFavSettings(e)});r.ensureToggleStyles();const{switchWrap:o}=this.createToggleSwitch();t.appendChild(n) ;t.appendChild(o);e.parentNode?.insertBefore(t,e)}static createToggleSwitch(){const e=i.create("label",{ class:"sis-toggle"});const t=i.create("input",{type:"checkbox",class:"sis-input"});t.checked=Config.getSearchFavAuto() ;const n=i.create("span",{class:"sis-text"});n.textContent="多选记忆";const o=i.create("span",{class:"sis-switch"}) ;e.appendChild(t);e.appendChild(n);e.appendChild(o);t.addEventListener("change",()=>{Config.setSearchFavAuto(t.checked) ;if(t.checked){const e=i.select("#srchfid");if(e){const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean) ;if(t.length>0)Config.setSearchLastSelection(t)}}});return{switchWrap:e,switchInput:t}}static setupTopGrouping(e){ const t=Config.getSearchFavForums();if(0===t.length)return;const n=i.create("optgroup",{label:"常用置顶"}) ;e.insertBefore(n,e.firstChild);const options=Array.from(e.querySelectorAll("option"));t.forEach(e=>{ const t=options.find(t=>t.value===e);if(t)n.appendChild(t)})}static setupAutoRemember(e){ if(!Config.getSearchFavAuto())return;const t=Config.getSearchLastSelection() ;if(t.length>0)Array.from(e.options).forEach(e=>{e.selected=t.includes(e.value)});e.addEventListener("change",()=>{ const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean);Config.setSearchLastSelection(t)})} static openSearchFavSettings(e){const t=Array.from(e.querySelectorAll("option")).filter(e=>e.value) ;const n=c.createOverlay();const o=c.createPanel("1100px");const a=c.createHeader("置顶设置",()=>n.remove()) ;const{body:i,favSet:s}=this.createPanelBody(e,t);const r=c.createFooter(()=>n.remove(),()=>{ Config.setSearchFavForums(Array.from(s));location.reload()});o.appendChild(a);o.appendChild(i);o.appendChild(r) ;n.appendChild(o);document.body.appendChild(n)}static createPanelBody(e,t){const n=i.create("div",{},{ padding:"12px 16px",display:"grid",gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))",gap:"12px"}) ;const o=new Set(Config.getSearchFavForums());const a=this.organizeOptions(e,t);a.forEach(e=>{ const t=this.createGroupCard(e,o);n.appendChild(t)});return{body:n,favSet:o}}static organizeOptions(e,t){const n=[] ;const o=Array.from(e.querySelectorAll("optgroup"));o.forEach(e=>{ const options=Array.from(e.querySelectorAll("option")).filter(e=>e.value);if(options.length>0)n.push({ label:e.label||"分组",options:options})}) ;const a=Array.from(e.children).filter(e=>"OPTION"===e.tagName&&e.value&&"all"!==e.value);if(a.length>0)n.unshift({ label:"其他",options:a});return n}static createGroupCard(e,t){const n=i.create("div",{},{border:"1px solid #e9ecef", borderRadius:"8px",overflow:"hidden",background:"#fff"});const o=i.create("div",{},{padding:"8px 10px", background:"#f8f9fa",borderBottom:"1px solid #e9ecef",fontWeight:"600",color:"#2c3e50",fontSize:"12px"}) ;o.textContent=e.label;const a=i.create("div",{},{padding:"8px 10px",display:"flex",flexDirection:"column",gap:"6px"}) ;e.options.forEach(e=>{const n=i.create("label",{},{display:"flex",alignItems:"center",gap:"6px",padding:"6px", border:"1px solid #eee",borderRadius:"6px"});const o=i.create("input",{type:"checkbox"});o.checked=t.has(e.value) ;o.onchange=()=>{if(o.checked)t.add(e.value);else t.delete(e.value)};const s=i.create("span") ;s.textContent=e.textContent?.trim()||"";n.appendChild(o);n.appendChild(s);a.appendChild(n)});n.appendChild(o) ;n.appendChild(a);return n}}class SettingsPanel{static init(){this.hideVirtualSoccerEarly() ;this.injectPreviewToggleButton()}static hideVirtualSoccerEarly(){if(i.select('style[data-sis-hide-soccer="1"]'))return ;const e=`\n a[href="z_soccer.php"], \n a[href*="z_soccer"] {\n display: none !important;\n }\n ` ;i.addStyle(e,"sis-hide-soccer").setAttribute("data-sis-hide-soccer","1")}static injectPreviewToggleButton(){ const e=document.querySelector('a[href="z_soccer.php"]');if(e)this.setupPreviewToggle(e);else{ const e=document.querySelectorAll('a[href*="z_soccer"]');if(e.length>0){const t=e[0];this.setupPreviewToggle(t)}}} static setupPreviewToggle(e){this.updateToggleButtonText(e);e.href="javascript:void(0)";const t=e.cloneNode(true) ;t.addEventListener("click",e=>{e.preventDefault();this.togglePreviewCount(t)});e.parentNode?.replaceChild(t,e) ;t.style.display="";const n=t.closest("li");if(n)n.id="sis-preview-toggle"}static updateToggleButtonText(e){ const t=Config.getMaxImagesPerPost();e.textContent=`预览${t}张图`}static togglePreviewCount(e){ const t=Config.getMaxImagesPerPost();const n=4===t?5:4;Config.setMaxImagesPerPost(n);this.updateToggleButtonText(e) ;void 0;setTimeout(()=>{location.reload()},500)}}async function initScript(){try{autoRedirectToDesktop() ;AdRemover.init();if("loading"===document.readyState)await l.waitForDOMContentLoaded();p.init() ;await l.waitForWindowLoad();await ImagePreview.init();BoardManager.init();SearchOptimizer.init();SettingsPanel.init() }catch(e){void 0}}function autoRedirectToDesktop(){const e=document.querySelectorAll("a");for(let t=0;t<e.length;t++){ const n=e[t];if(n.textContent&&n.textContent.includes("电脑版")){window.location.href=n.href;break}}}initScript()})();