V2EX - 单页应用

V2EX - 单页应用,仿 Reddit 设计

目前为 2023-02-24 提交的版本,查看 最新版本

// ==UserScript==
// @name         V2EX - 单页应用
// @namespace    http://tampermonkey.net/
// @version      2
// @description  V2EX - 单页应用,仿 Reddit 设计
// @author       You
// @match        https://*.v2ex.com/
// @match        https://*.v2ex.com/?tab=*
// @match        https://*.v2ex.com/t/*
// @match        https://*.v2ex.com/recent*
// @match        https://*.v2ex.com/go/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=v2ex.com
// @require      https://cdn.bootcdn.net/ajax/libs/vue/3.2.47/vue.runtime.global.prod.min.js
// @grant        none
// @license      GPL License
// ==/UserScript==

(function () {

    let style = `

html,body{font-size:62.5%}.flex{display:flex;align-items:center;justify-content:space-between}.flex-end{justify-content:flex-end}.flex-center{justify-content:center}.p1{padding:1rem}.p0{padding:0!important}.post-author{display:flex;align-items:center;position:relative;color:#ccc!important}.post-author>.username{font-size:1.2rem}.sticky{position:sticky;bottom:0}.sticky[stuck]{box-shadow:0 2px 20px #00000059}a{color:#778087;text-decoration:none;cursor:pointer}a:hover{text-decoration:underline}.subtlesHtml{font-size:1.4rem;border-top:1px solid #e2e2e2;margin-bottom:1rem}.subtlesHtml .subtle:last-child{border-bottom:none}.subtlesHtml .subtle .fade{color:#ccc}.subtlesHtml .subtle .sep5{height:5px}.subtlesHtml .subtle .topic_content{color:#000}.base-loading{border:2px solid;border-color:#000 #00000033 #00000033 #00000033;border-radius:100%;animation:circle infinite 1s linear}.loading-c{border:2px solid;border-color:#000 #00000033 #00000033 #00000033;border-radius:100%;animation:circle infinite 1s linear;width:3rem;height:3rem}@keyframes circle{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.button{cursor:pointer;padding:.4rem 2.4rem;border-radius:10rem;display:inline-flex;justify-content:center;align-items:center;font-weight:700;font-size:1.2rem;color:#fff;background:#0079d3;border:1px solid #0079d3;user-select:none}.button:hover{opacity:.9}.button:before{content:" ";border:2px solid;border-color:#000 #00000033 #00000033 #00000033;border-radius:100%;animation:circle infinite 1s linear;border-color:#fff transparent transparent transparent;width:1rem;height:1rem;margin-right:1rem;display:none}.button.loading{cursor:not-allowed;opacity:.5}.button.loading:before{display:block}.button.disabled{cursor:not-allowed;color:#c6c6c6;background:#8d8d8d;border:1px solid transparent}.tool{position:relative;margin-left:.6rem;display:flex;align-items:center;font-size:1.2rem;font-weight:700;border-radius:.2rem;cursor:pointer;height:3rem;padding:0 .5rem}.tool:before{content:" ";border:2px solid;border-color:#000 #00000033 #00000033 #00000033;border-radius:100%;animation:circle infinite 1s linear;border-color:transparent #929596 #929596 #929596;width:1rem;height:1rem;margin-left:1rem;display:none}.tool.loading{cursor:not-allowed;opacity:.5}.tool.loading:before{display:block}.tool.loading:hover{background:unset}.tool>svg{width:1.6rem!important;height:1.6rem!important;margin-right:.4rem;box-sizing:border-box;border-radius:.2rem}.tool:hover{background:#e8e8e8}.tool.no-hover{cursor:default}.tool.no-hover:hover{background:unset}.my-node{border-radius:.2rem;padding:.4rem;font-size:1rem;color:#999;background:#f5f5f5;cursor:pointer}.my-node:hover{text-decoration:none;background:#e2e2e2}.msgs{position:fixed;margin-left:calc(50% - 25rem);width:50rem;z-index:9999;bottom:0;left:0;right:0}.msg{cursor:default;margin-bottom:2rem;background:white;display:flex;color:#000;font-size:1.4rem;box-sizing:border-box;border-radius:.4rem;box-shadow:0 0 1rem 1px silver}.msg.success .left{background:#0079d3}.msg.warning .left{background:#c8c002}.msg.error .left{background:red}.msg .left{border-radius:.4rem 0 0 .4rem;display:flex;align-items:center;background:#0079d3}.msg .left svg{margin:0 .3rem;cursor:pointer}.msg .right{flex:1;padding:1rem 2rem;display:flex;justify-content:space-between;align-items:center}.line{border-bottom:1px solid #e2e2e2}.my-box{box-shadow:0 2px 3px #0000001a;border-radius:.4rem;background:white;margin-bottom:2rem;width:100%;box-sizing:border-box}.my-cell{padding:1rem;font-size:1.4rem;line-height:150%;text-align:left;border-bottom:1px solid #e2e2e2}.f14{font-size:1.4rem}.switch{width:4.5rem;height:2.2rem;border-radius:2rem;position:relative;display:flex;align-items:center;background:#ccc;transition:all .3s}.switch.active{background:#0079d3}.switch.active:before{right:.2rem}.switch:before{position:absolute;content:" ";transition:all .3s;right:calc(100% - 2rem);width:1.8rem;height:1.8rem;border-radius:50%;background:white}.horizontal[data-v-4dbb3f30]{flex-direction:row!important;padding:0!important}.horizontal .num[data-v-4dbb3f30]{margin-left:.2rem}.point[data-v-4dbb3f30]{font-size:1.2rem;padding:1rem 0;min-width:4rem;border-radius:.4rem 0 0 .4rem;display:flex;flex-direction:column;align-items:center}.point .up[data-v-4dbb3f30]{display:flex;flex-direction:column;align-items:center;justify-content:center}.point .num[data-v-4dbb3f30]{font-weight:700;color:#000;user-select:none}.point svg[data-v-4dbb3f30]{width:2rem;padding:.4rem;border-radius:.2rem}.point svg[data-v-4dbb3f30]:hover{background:#e5e5e5}.point .disabled[data-v-4dbb3f30]:hover{background:unset}.Author[data-v-91d99412]{display:flex;align-items:center;justify-content:space-between;font-size:1.2rem;position:relative;margin-bottom:.4rem}.Author.expand[data-v-91d99412]{margin-bottom:0}.Author .Author-left[data-v-91d99412]{display:flex;align-items:center}.Author .Author-left .username[data-v-91d99412]{font-size:1.4rem}.Author .Author-left .expand-icon[data-v-91d99412]{cursor:pointer;margin-right:.8rem;width:2rem;height:2rem;transform:rotate(90deg)}.Author .Author-left .icon[data-v-91d99412]{margin-right:1rem;display:flex}.Author .Author-left .icon img[data-v-91d99412]{width:3.4rem;height:3.4rem;border-radius:.3rem}.Author .Author-left .op[data-v-91d99412]{display:inline-block;background-color:transparent;color:#1484cd;border-radius:.3rem;padding:0 .3rem;cursor:default;border:2px solid #1484cd;font-size:1.2rem;font-weight:700;margin-right:1rem;transform:scale(.8)}.Author .Author-right[data-v-91d99412]{position:absolute;right:0;display:flex;align-items:center}.Author .Author-right .toolbar[data-v-91d99412]{display:flex;align-items:center;color:#929596;opacity:0}.Author .Author-right .toolbar[data-v-91d99412]:hover{background:white;opacity:1}.Author .Author-right .floor[data-v-91d99412]{margin-left:1rem;font-size:1.2rem;line-height:1rem;border-radius:1rem;display:inline-block;background-color:#f0f0f0;color:#ccc;padding:.2rem .5rem;cursor:default}.Author .Author-right .isDev[data-v-91d99412]{color:#000!important}.post-editor-wrapper[data-v-5d67ef48]{width:100%;box-sizing:border-box;position:relative;overflow:hidden;transition:all .3s}.post-editor-wrapper.reply-post .post-editor[data-v-5d67ef48]{border:1px solid #e2e2e2;border-radius:.4rem}.post-editor-wrapper.reply-post.isFocus .post-editor[data-v-5d67ef48]{border:1px solid #968b8b}.post-editor-wrapper.reply-comment[data-v-5d67ef48]{border:1px solid #e2e2e2;border-radius:.4rem;overflow:hidden}.post-editor-wrapper.reply-comment.isFocus[data-v-5d67ef48]{border:1px solid #968b8b}.post-editor-wrapper.reply-comment .toolbar[data-v-5d67ef48]{background:#f6f7f8}.post-editor-wrapper .post-editor[data-v-5d67ef48]{transition:border .3s;width:100%;max-width:100%;padding:.6rem 1.4rem;box-sizing:border-box;border:none;outline:none;font-family:Avenir,Helvetica,Arial,sans-serif;font-size:1.4rem;min-height:13rem;resize:none}.post-editor-wrapper .toolbar[data-v-5d67ef48]{box-sizing:border-box;padding:.5rem 1rem;width:100%;position:relative;display:flex;justify-content:space-between;align-items:center}.post-editor-wrapper .toolbar span[data-v-5d67ef48]{color:gray;font-size:1.3rem}.post-editor-wrapper .get-cursor[data-v-5d67ef48]{transition:border .3s;width:100%;max-width:100%;padding:.6rem 1.4rem;box-sizing:border-box;border:none;outline:none;font-family:Avenir,Helvetica,Arial,sans-serif;font-size:1.4rem;min-height:13rem;resize:none;position:absolute;top:0;z-index:-100}.comment[data-v-610ec7c1]{width:100%;box-sizing:border-box;margin-top:1rem;background:white}.comment .comment-content-w[data-v-610ec7c1]{background:white}.comment .comment-content-w .more[data-v-610ec7c1]{text-align:center;margin:2rem 0}.comment .comment-content[data-v-610ec7c1]{display:flex;position:relative}.comment .comment-content .expand-line[data-v-610ec7c1]{cursor:pointer;width:2.6rem;min-width:2.6rem;position:relative}.comment .comment-content .expand-line[data-v-610ec7c1]:after{position:absolute;left:calc(68% - 1px);content:" ";height:100%;width:0;border-right:2px solid #ddd}.comment .comment-content .expand-line[data-v-610ec7c1]:hover:after{border-right:2px solid #0079D3}.comment .comment-content .right[data-v-610ec7c1]{flex:1;width:calc(100% - 2.6rem)}.comment .comment-content .right .w[data-v-610ec7c1]{padding-left:1.7rem}.comment .comment-content .right .w .text[data-v-610ec7c1]{color:#000;word-break:break-word}.comment .comment-content .right .w .post-editor-wrapper[data-v-610ec7c1]{margin-top:1rem}.toolbar[data-v-ccba788e]{display:flex;align-items:center;color:#929596}.toolbar .tooltip[data-v-ccba788e]{box-shadow:0 3px 6px -4px #0000001f,0 6px 16px #00000014,0 9px 28px 8px #0000000d;background:white;padding:1rem;top:4rem;left:-3rem;width:15rem;position:absolute;z-index:99}.toolbar .tooltip a[data-v-ccba788e]{color:#0079d3!important}.htmlContent{width:100%}.htmlContent img{max-width:100%}.sticky{position:sticky;bottom:-2px}.sticky[stuck]{box-shadow:0 2px 20px #00000059!important}.post-detail[data-v-0a398e7e]{text-align:start;position:fixed;z-index:99;left:0;right:0;bottom:0;top:0;background:rgba(46,47,48,.8);overflow:auto;font-size:1.4rem;display:flex;justify-content:center;flex-wrap:wrap}.post-detail .main[data-v-0a398e7e]{display:flex;padding:6rem 12rem 15rem;background:#e2e2e2;position:relative}.post-detail .main>.left[data-v-0a398e7e]{width:77rem}.post-detail .main>.left .left-wrapper[data-v-0a398e7e]{width:100%;padding-bottom:2rem;display:flex;flex-direction:column;align-items:center}.post-detail .main>.left .post-wrapper .base-info[data-v-0a398e7e]{padding:1rem;box-sizing:border-box;border-bottom:1px solid #e2e2e2}.post-detail .main>.left .post-wrapper .base-info .avatar[data-v-0a398e7e]{float:right;border-radius:.4rem;height:7.3rem}.post-detail .main>.left .post-wrapper .base-info .post-nodes[data-v-0a398e7e]{font-size:1.5rem;margin-bottom:.8rem;display:flex}.post-detail .main>.left .post-wrapper .base-info .title[data-v-0a398e7e]{margin-bottom:1rem;line-height:150%;font-size:2.4rem;color:#000}.post-detail .main>.left .post-wrapper .base-info .post-author[data-v-0a398e7e]{font-size:1.25rem;color:#999!important}.post-detail .main>.left .post-wrapper .content[data-v-0a398e7e]{color:#000;word-break:break-word;line-height:1.6;border-bottom:1px solid #e2e2e2}.post-detail .main>.left .post-wrapper .content .baseContent[data-v-0a398e7e]{padding:1rem}.post-detail .main>.left .post-wrapper .toolbar-wrapper[data-v-0a398e7e]{height:4rem;padding-left:.6rem;display:flex;align-items:center}.post-detail .main>.left .editor-wrapper .float[data-v-0a398e7e]{margin-right:2rem}.post-detail .main>.left .editor-wrapper .w[data-v-0a398e7e]{padding:1.2rem}.post-detail .main>.left .comment-wrapper .comments[data-v-0a398e7e]{width:100%;box-sizing:border-box}.post-detail .main>.left .sort-select[data-v-0a398e7e]{position:relative}.post-detail .main>.left .sort-select .target[data-v-0a398e7e]{color:#0079d3;font-size:1.2rem;font-weight:700;display:inline-flex;align-items:center;cursor:pointer}.post-detail .main>.left .sort-select .target svg[data-v-0a398e7e]{width:1.4rem;height:1.4rem;margin-left:.5rem}.post-detail .main>.left .sort-select .options[data-v-0a398e7e]{box-shadow:0 3px 6px -4px #0000001f,0 6px 16px #00000014,0 9px 28px 8px #0000000d;background:white;z-index:9998;border-radius:.5rem;cursor:pointer;font-size:1.4rem;position:absolute;top:2.6rem;left:2.7rem;width:8rem;color:#778087}.post-detail .main>.left .sort-select .options .option[data-v-0a398e7e]{padding:.8rem 1.4rem}.post-detail .main>.left .sort-select .options .option.active[data-v-0a398e7e]{color:#0079d3}.post-detail .main>.left .sort-select .options .option[data-v-0a398e7e]:hover{background:#e9f5fd}.post-detail .main>.left .loading-wrapper[data-v-0a398e7e]{height:20rem;display:flex;justify-content:center;align-items:center}.post-detail .main>.left #no-comments-yet[data-v-0a398e7e]{color:#a9a9a9;font-weight:700;text-align:center;width:100%;margin-bottom:2rem;box-sizing:border-box}.post-detail .main>.right[data-v-0a398e7e]{margin-left:2rem;margin-top:-2rem;display:flex;flex-direction:column;align-items:center}.post-detail .main .call-list[data-v-0a398e7e]{z-index:9;position:absolute;top:12rem;border:1px solid #ccc;background-color:#fff;box-shadow:0 5px 15px #0000001a;overflow:hidden;max-height:30rem;min-width:8rem;box-sizing:content-box}.post-detail .main .call-list .call-item[data-v-0a398e7e]{border-top:1px solid #ccc;height:3rem;display:flex;padding:0 1rem;align-items:center;cursor:pointer;font-size:14px;box-sizing:border-box}.post-detail .main .call-list .call-item .select[data-v-0a398e7e],.post-detail .main .call-list .call-item[data-v-0a398e7e]:hover,.post-detail .main .call-list .call-item.select[data-v-0a398e7e]{background-color:#f0f0f0;text-decoration:none}.post-detail .main .call-list .call-item[data-v-0a398e7e]:nth-child(1){border-top:1px solid transparent}@media screen and (max-width: 1500px){.post-detail .main[data-v-0a398e7e]{padding:8rem 8rem 15rem}.post-detail .main>.left[data-v-0a398e7e]{width:65vw}.post-detail .main>.right[data-v-0a398e7e]{display:none}}@media screen and (max-width: 1280px){.post-detail .main[data-v-0a398e7e]{padding:5rem 5rem 15rem}.post-detail .main>.left[data-v-0a398e7e]{width:75vw}.post-detail .main>.right[data-v-0a398e7e]{display:none}}.post-detail .scroll-top[data-v-0a398e7e]{position:fixed;bottom:3rem;z-index:99}p:first-child{margin-top:0}p:last-child{margin-bottom:0}.post[data-v-536450bc]{font-size:1.4rem;background:white;text-align:start;padding:1rem;overflow:hidden}.post.table[data-v-536450bc]{border-bottom:1px solid #e2e2e2}.post.table .post-content-wrapper[data-v-536450bc]{display:none}.post.table .title a[data-v-536450bc]{color:#778087;font-size:1.6rem}.post.card[data-v-536450bc]{margin-top:1.1rem;border:1px solid #e2e2e2;border-radius:.4rem;cursor:pointer}.post.card[data-v-536450bc]:hover{border:1px solid #968b8b}.post.card .title a[data-v-536450bc]{color:#000;font-size:1.8rem}.post.visited .title a[data-v-536450bc]{color:#afb9c1!important}.post.visited .post-content-wrapper[data-v-536450bc]{opacity:.6}.post .base-info[data-v-536450bc]{box-sizing:border-box;display:flex;justify-content:space-between;align-items:flex-start}.post .base-info .left[data-v-536450bc]{display:flex;width:95%}.post .base-info .left .avatar[data-v-536450bc]{margin-right:1rem}.post .base-info .left .avatar img[data-v-536450bc]{border-radius:.4rem;width:4.8rem;min-width:4.8rem;min-height:4.8rem}.post .base-info .left .right[data-v-536450bc]{display:flex;flex-direction:column;justify-content:space-between}.post .base-info .left .right .title[data-v-536450bc]{display:inline;align-items:center}.post .base-info .left .right .bottom[data-v-536450bc]{font-size:1.2rem;line-height:1.2rem;display:flex;align-items:center;color:#ccc}.post .base-info .count[data-v-536450bc]{margin-top:1.8rem;line-height:12px;font-weight:700;color:#fff;background-color:#aab0c6;display:inline-block;padding:2px 10px;-moz-border-radius:12px;-webkit-border-radius:12px;border-radius:12px;text-decoration:none;cursor:pointer}.post .base-info .count[data-v-536450bc]:hover{background-color:#969cb1}.post .post-content-wrapper[data-v-536450bc]{max-height:20rem;overflow:hidden;margin-top:.6rem;color:#000;position:relative;line-break:anywhere;font-size:1.4rem}.post .post-content-wrapper.mask[data-v-536450bc]{-webkit-mask-image:linear-gradient(180deg,#000 60%,transparent)}.base64_tooltip[data-v-2d42a498]{box-shadow:0 3px 6px -4px #0000001f,0 6px 16px #00000014,0 9px 28px 8px #0000000d;background:white;min-height:2.2rem;max-width:20rem;padding:.8rem;position:fixed;z-index:9998;display:flex;align-items:center;border-radius:.5rem;cursor:pointer;line-break:anywhere}.base64_tooltip svg[data-v-2d42a498]{margin-left:1rem;min-width:1.8rem}.base64_tooltip .button[data-v-2d42a498]{margin-top:1rem;margin-left:2rem}.app-home.home,.app-home.recent,.app-home.nodePage{background:#e2e2e2}.app-home.card{padding:1rem 0}.page.card{margin-top:1rem}.nav{font-size:1.4rem;background:white;text-align:start;padding:1rem}.nav.card{border:1px solid #e2e2e2;border-radius:.4rem}.nav.table{border-bottom:1px solid #e2e2e2}.nav .nav-item{cursor:pointer;display:flex;margin-left:2rem;padding:.6rem;border-radius:.4rem}.nav .nav-item.active{background:#40a9ff;color:#fff}.nav .nav-item.active:hover{background:#40a9ff;opacity:.8}.nav .nav-item:hover{background:#e2e2e2}.nav .nav-item span{margin-left:.4rem}

    `
    let addStyle = document.createElement ("style");
    addStyle.rel = "stylesheet";
    addStyle.type = "text/css";
    addStyle.innerHTML = style
    document.head.append (addStyle)

    setTimeout(function(){

        (function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))a(n);new MutationObserver(n=>{for(const t of n)if(t.type==="childList")for(const d of t.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(n){const t={};return n.integrity&&(t.integrity=n.integrity),n.referrerPolicy&&(t.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?t.credentials="include":n.crossOrigin==="anonymous"?t.credentials="omit":t.credentials="same-origin",t}function a(n){if(n.ep)return;n.ep=!0;const t=s(n);fetch(n.href,t)}})();const i={eventMap:new Map,on(o,e){let s=this.eventMap.get(o);s?s.push(e):s=[e],this.eventMap.set(o,s)},emit(o,e){let s=this.eventMap.get(o);s&&s.map(a=>a(e))},off(o){this.eventMap.has(o)&&this.eventMap.delete(o)},clear(){this.eventMap=new Map}},r={SHOW_TOOLTIP:"SHOW_TOOLTIP",SHOW_MSG:"SHOW_MSG",SET_CALL:"SET_CALL",SHOW_CALL:"SHOW_CALL",REFRESH_ONCE:"REFRESH_ONCE",ADD_REPLY:"ADD_REPLY",IGNORE:"IGNORE",MERGE:"MERGE",REMOVE:"REMOVE",CHANGE_COMMENT_THANK:"CHANGE_COMMENT_THANK",CHANGE_POST_THANK:"CHANGE_POST_THANK"};const k=(o,e)=>{const s=o.__vccOpts||o;for(const[a,n]of e)s[a]=n;return s},F={name:"Point",inject:["post","isLogin"],props:{item:{type:Object,default(){return{}}},type:{type:String,default(){return"horizontal"}},apiUrl:""},computed:{disabled(){return this.item.username===window.win().user.username||this.item.isThanked}},methods:{getColor(o){return o?"#ff4500":"#929596"},getIsFull(o){return o?"#ff4500":"none"},async thank(){if(!this.isLogin)return i.emit(r.SHOW_MSG,{type:"warning",text:"请先登录(不可用)!"});if(this.item.username===window.win().user.username)return i.emit(r.SHOW_MSG,{type:"warning",text:"不能感谢自己"});if(this.item.isThanked)return i.emit(r.SHOW_MSG,{type:"warning",text:"已经感谢过了"});this.$emit("addThank");let o=`${window.win().url}/thank/${this.apiUrl}?once=${this.post.once}`;$.post(o).then(e=>{console.log("感谢",e),e.success||(this.$emit("recallThank"),i.emit(r.SHOW_MSG,{type:"error",text:e.message})),i.emit(r.REFRESH_ONCE,e.once)},e=>{this.$emit("recallThank"),i.emit(r.SHOW_MSG,{type:"error",text:"感谢失败"}),i.emit(r.REFRESH_ONCE)})}}},W=["fill","stroke"],z={class:"num"};function U(o,e,s,a,n,t){return Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["point",s.type])},[Vue.createElementVNode("div",{class:"up",onClick:e[0]||(e[0]=Vue.withModifiers((...d)=>t.thank&&t.thank(...d),["stop"]))},[(Vue.openBlock(),Vue.createElementBlock("svg",{class:Vue.normalizeClass({disabled:t.disabled}),width:"19",height:"19",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[Vue.createElementVNode("path",{d:"M15 8C8.92487 8 4 12.9249 4 19C4 30 17 40 24 42.3262C31 40 44 30 44 19C44 12.9249 39.0751 8 33 8C29.2797 8 25.9907 9.8469 24 12.6738C22.0093 9.8469 18.7203 8 15 8Z",fill:t.getIsFull(s.item.isThanked),stroke:t.getColor(s.item.isThanked),"stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null,8,W)],2))]),Vue.createElementVNode("div",z,Vue.toDisplayString(s.item.thankCount?s.item.thankCount:"感谢"),1)],2)}const S=k(F,[["render",U],["__scopeId","data-v-4dbb3f30"]]);const K={name:"Author",components:{Point:S},inject:["isDev","isLogin"],props:{modelValue:!1,comment:{type:Object,default(){return{}}}},data(){return{}},computed:{pointInfo(){return{isThanked:this.comment.isThanked,thankCount:this.comment.thankCount,username:this.comment.username}}},methods:{checkIsLogin(o=""){if(!this.isLogin)return i.emit(r.SHOW_MSG,{type:"warning",text:"请先登录(不可用)!"}),!1;this.$emit(o)},addThank(){i.emit(r.CHANGE_COMMENT_THANK,{id:this.comment.id,type:"add"})},recallThank(){i.emit(r.CHANGE_COMMENT_THANK,{id:this.comment.id,type:"recall"})}}},L=o=>(Vue.pushScopeId("data-v-91d99412"),o=o(),Vue.popScopeId(),o),Z={class:"Author-left"},Y=L(()=>Vue.createElementVNode("path",{d:"M22 42H6V26",stroke:"#177EC9","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)),q=L(()=>Vue.createElementVNode("path",{d:"M26 6H42V22",stroke:"#177EC9","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)),X=[Y,q],J=["href"],Q=["src"],ee=["href"],te={key:0,class:"op"},oe={class:"ago"},ne={class:"Author-right"},se={class:"toolbar"},le=Vue.createStaticVNode('<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" data-v-91d99412><path d="M4 6H44V36H29L24 41L19 36H4V6Z" fill="none" stroke="#929596" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-v-91d99412></path><path d="M23 21H25.0025" stroke="#929596" stroke-width="2" stroke-linecap="round" data-v-91d99412></path><path d="M33.001 21H34.9999" stroke="#929596" stroke-width="2" stroke-linecap="round" data-v-91d99412></path><path d="M13.001 21H14.9999" stroke="#929596" stroke-width="2" stroke-linecap="round" data-v-91d99412></path></svg><span data-v-91d99412>回复</span>',2),ie=[le],re=L(()=>Vue.createElementVNode("span",null,"隐藏",-1)),ae=[re];function ce(o,e,s,a,n,t){const d=Vue.resolveComponent("Point");return Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["Author",{expand:!s.modelValue}])},[Vue.createElementVNode("div",Z,[s.modelValue?Vue.createCommentVNode("",!0):(Vue.openBlock(),Vue.createElementBlock("svg",{key:0,class:"expand-icon",onClick:e[0]||(e[0]=p=>o.$emit("update:modelValue",!0)),width:"24",height:"24",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},X)),Vue.createElementVNode("a",{class:"icon",href:`/member/${s.comment.username}`},[Vue.createElementVNode("img",{src:s.comment.avatar,alt:""},null,8,Q)],8,J),Vue.createElementVNode("span",null,[Vue.createElementVNode("strong",null,[Vue.createElementVNode("a",{href:`/member/${s.comment.username}`,class:"username"},Vue.toDisplayString(s.comment.username),9,ee)]),Vue.createTextVNode("     "),s.comment.isOp?(Vue.openBlock(),Vue.createElementBlock("div",te,"OP")):Vue.createCommentVNode("",!0),Vue.createElementVNode("span",oe,Vue.toDisplayString(s.comment.date),1)])]),Vue.createElementVNode("div",ne,[Vue.createElementVNode("div",se,[Vue.createElementVNode("div",{class:"tool",onClick:e[1]||(e[1]=p=>t.checkIsLogin("reply"))},ie),Vue.createElementVNode("div",{class:"tool",onClick:e[2]||(e[2]=p=>t.checkIsLogin("hide"))},ae),s.comment.thankCount?Vue.createCommentVNode("",!0):(Vue.openBlock(),Vue.createBlock(d,{key:0,item:t.pointInfo,onAddThank:t.addThank,onRecallThank:t.recallThank,"api-url":"reply/"+s.comment.id},null,8,["item","onAddThank","onRecallThank","api-url"]))]),s.comment.thankCount?(Vue.openBlock(),Vue.createBlock(d,{key:0,item:t.pointInfo,onAddThank:t.addThank,onRecallThank:t.recallThank,"api-url":"reply/"+s.comment.id},null,8,["item","onAddThank","onRecallThank","api-url"])):Vue.createCommentVNode("",!0),Vue.createElementVNode("div",{class:Vue.normalizeClass(["floor",{isDev:t.isDev}])},Vue.toDisplayString(s.comment.floor),3)])],2)}const de=k(K,[["render",ce],["__scopeId","data-v-91d99412"]]);const ue=o=>(Vue.pushScopeId("data-v-5d67ef48"),o=o(),Vue.popScopeId(),o),he={class:"get-cursor"},pe=["innerHTML"],me={class:"toolbar"},Ve=ue(()=>Vue.createElementVNode("span",null,"请尽量让自己的回复能够对别人有帮助",-1)),we={__name:"PostEditor",props:{replyInfo:null,replyFloor:null,useType:{type:String,default(){return"reply-comment"}}},emits:["close"],setup(o,{emit:e}){const{replyInfo:s,replyFloor:a,useType:n,isShow:t}=o,d=Vue.inject("post");Vue.inject("allReplyUsers");let p=Vue.ref(!1);const u=Vue.ref(!1),h=Vue.ref("editorId_"+Date.now()),l=Vue.ref(s),c=Vue.ref(null),_=Vue.ref(null),g=Vue.ref('<span style="white-space:pre-wrap;"> </span>'),R=Vue.computed(()=>[n,p.value?"isFocus":""]),D=Vue.computed(()=>{var m;if(!c.value||!l.value)return"";let f=((m=c.value)==null?void 0:m.selectionStart)||0;return l.value.substring(0,f).replace(/</g,"<").replace(/>/g,">").replace(/\n/g,"<br/>").replace(/\s/g,g.value)}),M=Vue.computed(()=>l.value?l.value===s:!0);async function P(){if(M.value||u.value)return;u.value=!0;let f={thankCount:0,isThanked:!1,isOp:d.value.username===window.win().user.username,id:Date.now(),username:window.win().user.username,avatar:window.win().user.avatar,date:"几秒前",floor:d.value.replyCount+1,reply_content:l.value||Date.now(),children:[],replyUsers:[],replyFloor:a||-1},m=l.value.match(/@([\w]+?[\s])/g);m&&m.map(V=>{let w=V.replace("@","").replace(" ","");f.reply_content=f.reply_content.replace(w,`<a href="/member/${w}">${w}</a>`)});let v=`${window.win().url}/t/${d.value.id}`;$.post(v,{content:l.value,once:d.value.once}).then(V=>{if(u.value=!1,V.search("你上一条回复的内容和这条相同")>-1)return i.emit(r.SHOW_MSG,{type:"error",text:"你上一条回复的内容和这条相同"});if(V.search("创建新回复")>-1)return i.emit(r.SHOW_MSG,{type:"error",text:"回复失败"});l.value=s,e("close"),i.emit(r.REFRESH_ONCE,V),i.emit(r.SHOW_MSG,{type:"success",text:"回复成功"}),i.emit(r.ADD_REPLY,f)},V=>{u.value=!1,i.emit(r.SHOW_MSG,{type:"error",text:"回复失败"})})}function y(){i.emit(r.SHOW_CALL,{show:!1}),i.off(r.SET_CALL)}function E(f){let m=_.value.getBoundingClientRect();i.emit(r.SHOW_CALL,{show:!0,top:m.top,left:m.left,text:f}),i.off(r.SET_CALL),i.on(r.SET_CALL,v=>{let V=c.value.selectionStart,w=l.value.slice(0,V),T=l.value.slice(V,l.value.length),G=w.lastIndexOf("@");w=l.value.slice(0,G+1),l.value=w+v+" "+T;let b=w.length+v.length+1;setTimeout(()=>{c.value.setSelectionRange(b,b)}),i.off(r.SET_CALL)})}function A(f){switch(f.keyCode){case 8:l.value==="@"&&y();break;case 37:case 38:case 39:case 40:setTimeout(()=>H({data:""}),100);break}}function H(f){let m=c.value.selectionStart;if(l.value){if(f.data===" ")return y();if(f.data==="@"){if(l.value.length!==1){if(l.value[m-2]===" "||l.value[m-2]===`
`)return E("")}else return E("");y()}else{let v=l.value.slice(0,m),V=v.lastIndexOf("@");if(V===-1)return y();let w=v.slice(V,m);if(w.includes(" "))y();else{if(V===0)return E(w.replace("@",""));if(l.value.length!==1){if(l.value[V-1]===" "||l.value[V-1]===`
`)return E(w.replace("@",""))}else return E(w.replace("@",""));y()}}}}function j(){p.value=!1}return Vue.onMounted(()=>{$(`.${h.value}`).each(function(){this.setAttribute("style","height:"+this.scrollHeight+"px;overflow-y:hidden;")}).on("input",function(){this.style.height=0,this.style.height=this.scrollHeight+"px"}),c.value&&c.value.focus()}),Vue.onBeforeUnmount(()=>{$(`.${h.value}`).off()}),(f,m)=>(Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["post-editor-wrapper",Vue.unref(R)])},[Vue.withDirectives(Vue.createElementVNode("textarea",{class:Vue.normalizeClass(["post-editor",h.value]),ref_key:"txtRef",ref:c,onFocus:m[0]||(m[0]=v=>Vue.isRef(p)?p.value=!0:p=!0),onBlur:j,onInput:H,onKeydown:A,"onUpdate:modelValue":m[1]||(m[1]=v=>l.value=v)},null,34),[[Vue.vModelText,l.value]]),Vue.createElementVNode("div",he,[Vue.createElementVNode("span",{innerHTML:Vue.unref(D)},null,8,pe),Vue.createElementVNode("span",{class:"cursor",ref_key:"cursorRef",ref:_},"|",512)]),Vue.createElementVNode("div",me,[Ve,Vue.createElementVNode("div",{class:Vue.normalizeClass(["button",{disabled:Vue.unref(M),loading:u.value}]),onClick:P},"回复 ",2)])],2))}},I=k(we,[["__scopeId","data-v-5d67ef48"]]),fe=["innerHTML"],O={__name:"BaseHtmlRender",props:["html"],setup(o){const e=o;function s(a){let n=window.win().getSelection().toString();if(n){let t=n.match(/([A-Za-z0-9+/=]+)/g);if(t){if(t[0].length<4)return;i.emit(r.SHOW_TOOLTIP,{text:t[0],e:a})}}}return(a,n)=>(Vue.openBlock(),Vue.createElementBlock("div",Vue.mergeProps(a.$attrs,{innerHTML:e.html,onMouseup:s}),null,16,fe))}};const _e={name:"Comment",components:{BaseHtmlRender:O,Author:de,PostEditor:I,Point:S},props:{modelValue:{reply_content:""}},data(){return{edit:!1,expand:!0,replyInfo:`@${this.modelValue.username} #${this.modelValue.floor} `,cssStyle:null}},inject:["post","postDetailWidth"],watch:{},created(){},mounted(){let o=this.$refs.comment.getBoundingClientRect(),e=this.postDetailWidth/2;if(e<o.width&&o.width<e+25&&this.modelValue.children.length){this.expand=!1;let s=2;this.cssStyle={padding:"1rem 0",width:`calc(${this.postDetailWidth}px - ${s}rem)`,transform:`translateX(calc(${o.width-this.postDetailWidth}px + ${s}rem))`}}},methods:{hide(){let o=`${window.win().url}/ignore/reply/${this.modelValue.id}?once=${this.post.once}`;i.emit(r.REMOVE,this.modelValue.floor),$.post(o).then(e=>{i.emit(r.REFRESH_ONCE),i.emit(r.SHOW_MSG,{type:"success",text:"隐藏成功"})},e=>{i.emit(r.SHOW_MSG,{type:"warning",text:"隐藏成功,仅本次有效(接口调用失败!)"})})},toggle(){this.expand=!this.expand}}},ve={class:"comment",ref:"comment"},ke={class:"comment-content"},ge={class:"right"},ye={class:"w"};function Ce(o,e,s,a,n,t){const d=Vue.resolveComponent("Author"),p=Vue.resolveComponent("BaseHtmlRender"),u=Vue.resolveComponent("PostEditor"),h=Vue.resolveComponent("Comment",!0);return Vue.openBlock(),Vue.createElementBlock("div",ve,[Vue.createVNode(d,{modelValue:n.expand,"onUpdate:modelValue":e[0]||(e[0]=l=>n.expand=l),comment:s.modelValue,onReply:e[1]||(e[1]=l=>n.edit=!n.edit),onHide:t.hide},null,8,["modelValue","comment","onHide"]),n.cssStyle&&!n.expand?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:"more ago",onClick:e[2]||(e[2]=l=>n.expand=!n.expand)}," 由于嵌套回复层级太深,自动将后续回复隐藏 ")):Vue.createCommentVNode("",!0),Vue.withDirectives(Vue.createElementVNode("div",{class:"comment-content-w",style:Vue.normalizeStyle(n.cssStyle)},[n.cssStyle?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:"more ago",onClick:e[3]||(e[3]=l=>n.expand=!n.expand)}," 由于嵌套回复层级太深,自动将以下回复移至可见范围 ")):Vue.createCommentVNode("",!0),Vue.createElementVNode("div",ke,[Vue.createElementVNode("div",{class:"left expand-line",onClick:e[4]||(e[4]=(...l)=>t.toggle&&t.toggle(...l))}),Vue.createElementVNode("div",ge,[Vue.createElementVNode("div",ye,[Vue.createVNode(p,{class:"text",html:s.modelValue.reply_content},null,8,["html"]),n.edit?(Vue.openBlock(),Vue.createBlock(u,{key:0,onClose:e[5]||(e[5]=l=>n.edit=!1),replyInfo:n.replyInfo,replyFloor:s.modelValue.floor},null,8,["replyInfo","replyFloor"])):Vue.createCommentVNode("",!0)]),(Vue.openBlock(!0),Vue.createElementBlock(Vue.Fragment,null,Vue.renderList(s.modelValue.children,(l,c)=>(Vue.openBlock(),Vue.createBlock(h,{modelValue:s.modelValue.children[c],"onUpdate:modelValue":_=>s.modelValue.children[c]=_,key:c},null,8,["modelValue","onUpdate:modelValue"]))),128))])]),n.cssStyle?(Vue.openBlock(),Vue.createElementBlock("div",{key:1,class:"more ago",onClick:e[6]||(e[6]=l=>n.expand=!n.expand)}," 由于嵌套回复层级太深,自动将以上回复移至可见范围 ")):Vue.createCommentVNode("",!0)],4),[[Vue.vShow,n.expand]])],512)}const Ee=k(_e,[["render",Ce],["__scopeId","data-v-610ec7c1"]]);const Ne={name:"Toolbar",inject:["isLogin","post","pageType"],data(){return{timer:null,showTooltip:!1,loading:!1,loading2:!1,loading3:!1}},methods:{checkIsLogin(o=""){if(!this.isLogin)return i.emit(r.SHOW_MSG,{type:"warning",text:"请先登录(不可用)!"}),!1;this.$emit(o)},getColor(o){return o?"#ff4500":"#929596"},getIsFull(o){return o?"#ff4500":"none"},showTooltipHandler(){this.timer&&clearTimeout(this.timer),this.showTooltip=!0},hideTooltip(){this.timer=setTimeout(()=>{this.showTooltip=!1},500)},tweet(){if(!this.checkIsLogin())return;let o=window.win().user.username,e=`https://twitter.com/share?url=${window.win().url}/t/${this.post.id}?r=${o}&amp;related=v2ex&amp;hashtags=apple&amp;text=${this.post.title}`;window.win().open(e,"_blank","width=550,height=370")},report(){if(!this.checkIsLogin()||!this.isLogin||this.post.isReport)return;let o=window.win().user.username,e=`https://twitter.com/share?url=${window.win().url}/t/${this.post.id}?r=${o}&amp;related=v2ex&amp;hashtags=apple&amp;text=${this.post.title}`;window.win().open(e,"_blank","width=550,height=370")},async toggleIgnore(){if(!this.checkIsLogin())return;let o=`${window.win().url}/${this.post.isIgnore?"unignore":"ignore"}/topic/${this.post.id}?once=${this.post.once}`;this.pageType==="post"?(this.loading2=!0,(await window.win().fetch(o)).redirected?(this.post.isIgnore||(window.win().location=window.win().url),i.emit(r.SHOW_MSG,{type:"success",text:this.post.isIgnore?"取消成功":"忽略成功"}),i.emit(r.MERGE,{isIgnore:!this.post.isIgnore})):i.emit(r.SHOW_MSG,{type:"warning",text:"忽略失败"}),this.loading2=!1):(this.post.isIgnore?this.loading2=!0:i.emit(r.IGNORE),(await window.win().fetch(o)).redirected?(this.post.isIgnore&&i.emit(r.REFRESH_ONCE),i.emit(r.SHOW_MSG,{type:"success",text:this.post.isIgnore?"取消成功":"忽略成功"}),i.emit(r.MERGE,{isIgnore:!this.post.isIgnore})):i.emit(r.SHOW_MSG,{type:"warning",text:"忽略成功,仅本次有效(接口调用失败!)"}),this.loading2=!1)},async toggleFavorite(){if(!this.checkIsLogin())return;this.loading=!0;let o=`${window.win().url}/${this.post.isFavorite?"unfavorite":"favorite"}/topic/${this.post.id}?once=${this.post.once}`,e=await window.win().fetch(o);if(this.loading=!1,e.redirected){let s=await e.text();if(s.search(this.post.isFavorite?"加入收藏":"取消收藏")){i.emit(r.MERGE,{collectCount:this.post.isFavorite?this.post.collectCount-1:this.post.collectCount+1}),i.emit(r.SHOW_MSG,{type:"success",text:this.post.isFavorite?"取消成功":"收藏成功"}),i.emit(r.REFRESH_ONCE,s),i.emit(r.MERGE,{isFavorite:!this.post.isFavorite});return}}i.emit(r.SHOW_MSG,{type:"error",text:"操作失败"})}}},N=o=>(Vue.pushScopeId("data-v-ccba788e"),o=o(),Vue.popScopeId(),o),xe={class:"toolbar"},Te=Vue.createStaticVNode('<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" data-v-ccba788e><path d="M4 6H44V36H29L24 41L19 36H4V6Z" fill="none" stroke="#929596" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-v-ccba788e></path><path d="M23 21H25.0025" stroke="#929596" stroke-width="2" stroke-linecap="round" data-v-ccba788e></path><path d="M33.001 21H34.9999" stroke="#929596" stroke-width="2" stroke-linecap="round" data-v-ccba788e></path><path d="M13.001 21H14.9999" stroke="#929596" stroke-width="2" stroke-linecap="round" data-v-ccba788e></path></svg><span data-v-ccba788e>回复</span>',2),Se=[Te],Le={viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Be=["fill","stroke"],Me={key:1,class:"tool no-hover"},He=N(()=>Vue.createElementVNode("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[Vue.createElementVNode("path",{d:"M28 6H42V20",stroke:"#929596","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M42 29.4737V39C42 40.6569 40.6569 42 39 42H9C7.34315 42 6 40.6569 6 39V9C6 7.34315 7.34315 6 9 6L18 6",stroke:"#929596","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M25.7998 22.1999L41.0998 6.8999",stroke:"#929596","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"})],-1)),be=N(()=>Vue.createElementVNode("span",null,"Tweet",-1)),Ie=[He,be],Oe={viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Re=["fill","stroke"],De=["fill","stroke"],Pe=["fill","stroke"],Ae=Vue.createStaticVNode('<svg width="19" height="19" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" data-v-ccba788e><path d="M36 35H12V21C12 14.3726 17.3726 9 24 9C30.6274 9 36 14.3726 36 21V35Z" fill="#929596" stroke="#929596" stroke-width="4" stroke-linejoin="round" data-v-ccba788e></path><path d="M8 42H40" stroke="#929596" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" data-v-ccba788e></path><path d="M4 13L7 14" stroke="#929596" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" data-v-ccba788e></path><path d="M13 3.9999L14 6.9999" stroke="#929596" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" data-v-ccba788e></path><path d="M10.0001 9.99989L7.00009 6.99989" stroke="#929596" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" data-v-ccba788e></path></svg>',1),je=N(()=>Vue.createElementVNode("a",{target:"_blank",href:"https://github.com/zyronon/v2ex-script/issues"},"点击这里提一个Issue",-1)),Ge=N(()=>Vue.createElementVNode("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[Vue.createElementVNode("path",{d:"M8 44H12H16",stroke:"#929596","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M12 44V4",stroke:"#929596","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M40 6H12V22H40L36 14L40 6Z",fill:"none",stroke:"#929596","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"})],-1)),Fe=N(()=>Vue.createElementVNode("span",null,"脚本有问题?",-1));function We(o,e,s,a,n,t){return Vue.openBlock(),Vue.createElementBlock("div",xe,[Vue.createElementVNode("div",{class:"tool",onClick:e[0]||(e[0]=d=>t.checkIsLogin("reply"))},Se),t.post.once?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:Vue.normalizeClass(["tool",{loading:n.loading}]),onClick:e[1]||(e[1]=(...d)=>t.toggleFavorite&&t.toggleFavorite(...d))},[(Vue.openBlock(),Vue.createElementBlock("svg",Le,[Vue.createElementVNode("path",{d:"M23.9986 5L17.8856 17.4776L4 19.4911L14.0589 29.3251L11.6544 43L23.9986 36.4192L36.3454 43L33.9586 29.3251L44 19.4911L30.1913 17.4776L23.9986 5Z",fill:t.getIsFull(t.post.isFavorite),stroke:t.getColor(t.post.isFavorite),"stroke-width":"2","stroke-linejoin":"round"},null,8,Be)])),Vue.createElementVNode("span",null,Vue.toDisplayString(t.post.isFavorite?"取消收藏":"加入收藏"),1)],2)):Vue.createCommentVNode("",!0),t.post.once&&t.post.collectCount!==0?(Vue.openBlock(),Vue.createElementBlock("div",Me,[Vue.createElementVNode("span",null,Vue.toDisplayString(t.post.collectCount+"人收藏"),1)])):Vue.createCommentVNode("",!0),Vue.createElementVNode("div",{class:"tool",onClick:e[2]||(e[2]=(...d)=>t.tweet&&t.tweet(...d))},Ie),t.post.once?(Vue.openBlock(),Vue.createElementBlock("div",{key:2,class:Vue.normalizeClass(["tool",{loading:n.loading2}]),onClick:e[3]||(e[3]=(...d)=>t.toggleIgnore&&t.toggleIgnore(...d))},[(Vue.openBlock(),Vue.createElementBlock("svg",Oe,[Vue.createElementVNode("path",{fill:t.getIsFull(t.post.isIgnore),stroke:t.getColor(t.post.isIgnore),d:"M9.85786 18C6.23858 21 4 24 4 24C4 24 12.9543 36 24 36C25.3699 36 26.7076 35.8154 28 35.4921M20.0318 12.5C21.3144 12.1816 22.6414 12 24 12C35.0457 12 44 24 44 24C44 24 41.7614 27 38.1421 30","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null,8,Re),Vue.createElementVNode("path",{fill:t.getIsFull(t.post.isIgnore),d:"M20.3142 20.6211C19.4981 21.5109 19 22.6972 19 23.9998C19 26.7612 21.2386 28.9998 24 28.9998C25.3627 28.9998 26.5981 28.4546 27.5 27.5705",stroke:t.getColor(t.post.isIgnore),"stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null,8,De),Vue.createElementVNode("path",{d:"M42 42L6 6",fill:t.getIsFull(t.post.isIgnore),stroke:t.getColor(t.post.isIgnore),"stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null,8,Pe)])),Vue.createElementVNode("span",null,Vue.toDisplayString(t.post.isIgnore?"取消忽略":"忽略主题"),1)],2)):Vue.createCommentVNode("",!0),t.post.once&&t.post.isLogin?(Vue.openBlock(),Vue.createElementBlock("div",{key:3,class:Vue.normalizeClass(["tool",{loading:n.loading3,"no-hover":t.post.isLogin}]),onClick:e[4]||(e[4]=(...d)=>t.report&&t.report(...d))},[Ae,Vue.createElementVNode("span",null,Vue.toDisplayString(t.post.isReport?"你已对本主题进行了报告":"报告这个主题"),1)],2)):Vue.createCommentVNode("",!0),t.post.once?(Vue.openBlock(),Vue.createElementBlock("div",{key:4,class:"tool no-hover",onMouseenter:e[7]||(e[7]=(...d)=>t.showTooltipHandler&&t.showTooltipHandler(...d)),onMouseleave:e[8]||(e[8]=(...d)=>t.hideTooltip&&t.hideTooltip(...d))},[n.showTooltip?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:"tooltip",onMouseenter:e[5]||(e[5]=(...d)=>t.showTooltipHandler&&t.showTooltipHandler(...d)),onMouseleave:e[6]||(e[6]=(...d)=>t.hideTooltip&&t.hideTooltip(...d))},[Vue.createTextVNode(" 脚本有问题?"),je],32)):Vue.createCommentVNode("",!0),Ge,Fe],32)):Vue.createCommentVNode("",!0)])}const ze=k(Ne,[["render",We],["__scopeId","data-v-ccba788e"]]);const Ue={name:"detail",components:{Comment:Ee,PostEditor:I,Point:S,Toolbar:ze,BaseHtmlRender:O},inject:["allReplyUsers","post","clone","isLogin"],provide(){return{postDetailWidth:Vue.computed(()=>{var o;return((o=this.$refs.comments)==null?void 0:o.getBoundingClientRect().width)||0})}},props:{modelValue:!1,loading:!1},data(){return{showSortOption:!1,isSticky:!1,target:0,sortOptions:[{value:0,label:"楼中楼"},{value:1,label:"感谢"},{value:2,label:"V2原版"}],selectCallIndex:0,postDetailWidth:0,showCallList:!1,replyText:"",callStyle:{top:0,left:0}}},computed:{filterCallList(){return this.showCallList?this.replyText?this.allReplyUsers.filter(o=>o.search(this.replyText)>-1):this.allReplyUsers:[]},replies(){if(this.target===0)return this.post.nestedReplies;if(this.target===1)return this.clone(this.post.nestedReplies).sort((o,e)=>e.thankCount-o.thankCount);if(this.target===2)return this.post.replies}},watch:{modelValue(o){o?this.$nextTick(()=>{this.$refs.detail.scrollTo({top:0})}):(window.win().doc.body.style.overflow="unset",this.isSticky=!1,window.win().pageType)}},mounted(){this.isLogin&&(new IntersectionObserver(([e])=>e.target.toggleAttribute("stuck",e.intersectionRatio<1),{threshold:[1]}).observe(this.$refs.replyBox),window.win().addEventListener("keydown",this.onKeyDown)),i.on(r.SHOW_CALL,o=>{o.show?(this.showCallList=!0,this.replyText=o.text,this.callStyle.top=o.top+$(".post-detail").scrollTop()+15+"px",this.callStyle.left=o.left-$(".main")[0].getBoundingClientRect().left+10+"px",this.selectCallIndex>=this.filterCallList.length&&(this.selectCallIndex=0)):(this.replyText="",this.showCallList=!1,this.selectCallIndex=0)})},beforeUnmount(){this.$refs.right.innerHTML="",window.win().removeEventListener("keydown",this.onKeyDown),i.off(r.SHOW_CALL)},methods:{setCall(o){i.emit(r.SET_CALL,o),this.showCallList=!1},onKeyDown(o){if(!this.modelValue||!this.showCallList)return;let e=this.filterCallList.slice(0,10).length;o.keyCode===13&&(this.setCall(this.filterCallList[this.selectCallIndex]),o.preventDefault()),o.keyCode===38&&(this.selectCallIndex--,this.selectCallIndex<0&&(this.selectCallIndex=e-1),o.preventDefault()),o.keyCode===40&&(this.selectCallIndex++,this.selectCallIndex>e-1&&(this.selectCallIndex=0),o.preventDefault())},changeOption(o){this.showSortOption=!1,this.target=o.value},stop(){this.showSortOption=!1},scroll(){this.showSortOption=!1},addThank(){i.emit(r.CHANGE_POST_THANK,{id:this.post.id,type:"add"})},recallThank(){i.emit(r.CHANGE_POST_THANK,{id:this.post.id,type:"recall"})},scrollTop(){this.$refs.detail.scrollTo({top:0,behavior:"smooth"})}}},C=o=>(Vue.pushScopeId("data-v-0a398e7e"),o=o(),Vue.popScopeId(),o),$e={class:"left"},Ke={class:"left-wrapper"},Ze={class:"my-box post-wrapper"},Ye={class:"base-info"},qe=["href"],Xe=["src"],Je={class:"post-nodes"},Qe=C(()=>Vue.createElementVNode("a",{href:"/"},"V2EX",-1)),et=C(()=>Vue.createElementVNode("span",{class:"chevron"},"  ›  ",-1)),tt=["href"],ot=["innerHTML"],nt={class:"post-author"},st={class:"username"},lt=["href"],it={class:"date"},rt={class:"date"},at={key:0,class:"content"},ct={class:"toolbar-wrapper"},dt={key:0,class:"my-box comment-wrapper"},ut={class:"my-cell flex"},ht={class:"gray"},pt={key:0},mt=C(()=>Vue.createElementVNode("strong",{class:"snow"},"•",-1)),Vt={class:"sort-select"},wt=C(()=>Vue.createElementVNode("svg",{width:"20",height:"20",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[Vue.createElementVNode("path",{d:"M36 19L24 31L12 19H36Z",fill:"#0079d3",stroke:"#0079d3","stroke-width":"2","stroke-linejoin":"round"})],-1)),ft={key:0,class:"options"},_t=["onClick"],vt={key:0,class:"loading-wrapper"},kt=C(()=>Vue.createElementVNode("div",{class:"loading-c"},null,-1)),gt=[kt],yt={key:1,class:"comments",ref:"comments"},Ct={key:1,id:"no-comments-yet"},Et={class:"my-cell flex"},Nt=C(()=>Vue.createElementVNode("span",null,"添加一条新回复",-1)),xt={class:"notice-right"},Tt={class:"w"},St={class:"right",ref:"right"},Lt=["innerHTML"],Bt=["onClick"];function Mt(o,e,s,a,n,t){const d=Vue.resolveComponent("BaseHtmlRender"),p=Vue.resolveComponent("Point"),u=Vue.resolveComponent("Toolbar"),h=Vue.resolveComponent("Comment"),l=Vue.resolveComponent("PostEditor");return Vue.withDirectives((Vue.openBlock(),Vue.createElementBlock("div",{class:"post-detail",ref:"detail",onScroll:e[7]||(e[7]=(...c)=>t.scroll&&t.scroll(...c)),onClick:e[8]||(e[8]=c=>o.$emit("update:modelValue",!1))},[Vue.createElementVNode("div",{class:"main",onClick:e[6]||(e[6]=Vue.withModifiers((...c)=>t.stop&&t.stop(...c),["stop"]))},[Vue.createElementVNode("div",$e,[Vue.createElementVNode("div",Ke,[Vue.createElementVNode("div",Ze,[Vue.createElementVNode("div",Ye,[Vue.createElementVNode("a",{href:`/member/${t.post.username}`},[Vue.createElementVNode("img",{class:"avatar",src:t.post.avatar,alt:""},null,8,Xe)],8,qe),Vue.createElementVNode("div",Je,[Qe,et,Vue.createElementVNode("a",{href:t.post.nodeUrl},Vue.toDisplayString(t.post.node),9,tt)]),Vue.createElementVNode("div",{class:"title",innerHTML:t.post.title},null,8,ot),Vue.createElementVNode("div",nt,[Vue.createElementVNode("div",st,[Vue.createElementVNode("a",{href:`/member/${t.post.username}`},Vue.toDisplayString(t.post.username),9,lt)]),Vue.createTextVNode("   ·   "),Vue.createElementVNode("div",it,Vue.toDisplayString(t.post.date),1),Vue.createTextVNode("   ·   "),Vue.createElementVNode("div",rt,Vue.toDisplayString(t.post.clickCount)+"次点击",1)])]),t.post.content_rendered||t.post.subtlesHtml?(Vue.openBlock(),Vue.createElementBlock("div",at,[Vue.createVNode(d,{html:t.post.content_rendered,class:"baseContent"},null,8,["html"]),Vue.createVNode(d,{html:t.post.subtlesHtml},null,8,["html"])])):Vue.createCommentVNode("",!0),Vue.createElementVNode("div",ct,[Vue.createVNode(p,{onAddThank:t.addThank,onRecallThank:t.recallThank,item:{isThanked:t.post.isThanked,thankCount:t.post.thankCount,username:t.post.username},"api-url":"topic/"+t.post.id},null,8,["onAddThank","onRecallThank","item","api-url"]),Vue.createVNode(u,{onReply:e[0]||(e[0]=c=>n.isSticky=!n.isSticky)})])]),t.replies.length||s.loading?(Vue.openBlock(),Vue.createElementBlock("div",dt,[Vue.createElementVNode("div",ut,[Vue.createElementVNode("span",ht,[Vue.createTextVNode(Vue.toDisplayString(t.post.replyCount)+" 条回复 ",1),t.post.createDate?(Vue.openBlock(),Vue.createElementBlock("span",pt,[Vue.createTextVNode("  "),mt,Vue.createTextVNode("  "+Vue.toDisplayString(t.post.createDate),1)])):Vue.createCommentVNode("",!0)]),Vue.createElementVNode("div",Vt,[Vue.createElementVNode("div",{class:"target",onClick:e[1]||(e[1]=Vue.withModifiers(c=>n.showSortOption=!0,["stop"]))},[Vue.createElementVNode("span",null,"排序:"+Vue.toDisplayString(n.sortOptions.find(c=>c.value===n.target).label),1),wt]),n.showSortOption?(Vue.openBlock(),Vue.createElementBlock("div",ft,[(Vue.openBlock(!0),Vue.createElementBlock(Vue.Fragment,null,Vue.renderList(n.sortOptions,c=>(Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["option",{active:n.target===c.value}]),onClick:_=>t.changeOption(c)},Vue.toDisplayString(c.label),11,_t))),256))])):Vue.createCommentVNode("",!0)])]),s.loading?(Vue.openBlock(),Vue.createElementBlock("div",vt,gt)):(Vue.openBlock(),Vue.createElementBlock("div",yt,[(Vue.openBlock(!0),Vue.createElementBlock(Vue.Fragment,null,Vue.renderList(t.replies,(c,_)=>(Vue.openBlock(),Vue.createBlock(h,{key:c.floor,style:{"border-bottom":"1px solid #e2e2e2",padding:"1rem","margin-top":"0"},modelValue:t.replies[_],"onUpdate:modelValue":g=>t.replies[_]=g},null,8,["modelValue","onUpdate:modelValue"]))),128))],512))])):(Vue.openBlock(),Vue.createElementBlock("div",Ct,"目前尚无回复")),t.isLogin?(Vue.openBlock(),Vue.createElementBlock("div",{key:2,class:Vue.normalizeClass(["my-box editor-wrapper",{sticky:n.isSticky}]),ref:"replyBox"},[Vue.createElementVNode("div",Et,[Nt,Vue.createElementVNode("div",xt,[n.isSticky?(Vue.openBlock(),Vue.createElementBlock("a",{key:0,class:"float",onClick:e[2]||(e[2]=c=>n.isSticky=!1)},"取消回复框停靠")):Vue.createCommentVNode("",!0),Vue.createElementVNode("a",{onClick:e[3]||(e[3]=(...c)=>t.scrollTop&&t.scrollTop(...c))},"回到顶部")])]),Vue.createElementVNode("div",Tt,[Vue.createVNode(l,{useType:"reply-post",onClick:e[4]||(e[4]=c=>n.isSticky=!0)})])],2)):Vue.createCommentVNode("",!0)])]),Vue.createElementVNode("div",St,[Vue.createElementVNode("div",{id:"Rightbar",innerHTML:t.post.RightbarHTML},null,8,Lt),Vue.createElementVNode("div",{class:"scroll-top button",onClick:e[5]||(e[5]=Vue.withModifiers((...c)=>t.scrollTop&&t.scrollTop(...c),["stop"]))}," 回到顶部 ")],512),n.showCallList&&t.filterCallList.length?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:"call-list",style:Vue.normalizeStyle(n.callStyle)},[(Vue.openBlock(!0),Vue.createElementBlock(Vue.Fragment,null,Vue.renderList(t.filterCallList.slice(0,10),(c,_)=>(Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["call-item",{select:_===n.selectCallIndex}]),onClick:g=>t.setCall(c)},[Vue.createElementVNode("a",null,Vue.toDisplayString(c),1)],10,Bt))),256))],4)):Vue.createCommentVNode("",!0)])],544)),[[Vue.vShow,s.modelValue]])}const Ht=k(Ue,[["render",Mt],["__scopeId","data-v-0a398e7e"]]);const bt={class:"base-info"},It={class:"left"},Ot=["onClick","href"],Rt={class:"avatar"},Dt=["src"],Pt={class:"right"},At={class:"title"},jt=["href"],Gt={class:"bottom"},Ft=["onClick","href"],Wt=["onClick","href"],zt={class:"date"},Ut={key:0,class:"count"},$t=["innerHTML"],Kt={__name:"Post",props:["post","viewType"],setup(o){const e=o,s=200,a=Vue.ref(!1),n=Vue.ref(null),t=Vue.computed(()=>e.post.bg?{backgroundImage:e.post.bg,backgroundRepeat:"no-repeat",backgroundSize:"20px 20px",backgroundPosition:"right top"}:{});Vue.watch([()=>e.post,()=>n.value,()=>e.viewType],()=>{if(!n.value||e.viewType==="table")return;let p=n.value.getBoundingClientRect();n.value.querySelectorAll("img").forEach(u=>{u.addEventListener("load",d)}),a.value=p.height>=s},{immediate:!0,flush:"post"});function d(){if(a.value)return;let p=n.value.getBoundingClientRect();a.value=p.height>=s}return(p,u)=>(Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["post",e.viewType]),style:Vue.normalizeStyle(Vue.unref(t)),onClick:u[0]||(u[0]=h=>p.$emit("show",h))},[Vue.createElementVNode("div",bt,[Vue.createElementVNode("div",It,[Vue.createElementVNode("a",{onClick:Vue.withModifiers(h=>null,["stop"]),href:`/member/${e.post.username}`},[Vue.createElementVNode("div",Rt,[Vue.createElementVNode("img",{src:e.post.avatar,alt:""},null,8,Dt)])],8,Ot),Vue.createElementVNode("div",Pt,[Vue.createElementVNode("div",At,[Vue.createElementVNode("a",{href:`t/${e.post.id}`},Vue.toDisplayString(e.post.title),9,jt)]),Vue.createElementVNode("div",Gt,[e.post.node?(Vue.openBlock(),Vue.createElementBlock(Vue.Fragment,{key:0},[Vue.createElementVNode("a",{onClick:Vue.withModifiers(h=>null,["stop"]),href:e.post.nodeUrl,class:"my-node"},Vue.toDisplayString(e.post.node),9,Ft),Vue.createTextVNode("   •   ")],64)):Vue.createCommentVNode("",!0),Vue.createElementVNode("strong",null,[Vue.createElementVNode("a",{onClick:Vue.withModifiers(h=>null,["stop"]),class:"username",href:`/member/${e.post.username}`},Vue.toDisplayString(e.post.username),9,Wt)]),Vue.createTextVNode("   •   "),Vue.createElementVNode("span",zt,Vue.toDisplayString(e.post.date),1)])])]),e.post.replyCount?(Vue.openBlock(),Vue.createElementBlock("div",Ut,Vue.toDisplayString(e.post.replyCount),1)):Vue.createCommentVNode("",!0)]),e.post.content_rendered?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:Vue.normalizeClass(["post-content-wrapper",{mask:a.value}])},[Vue.createElementVNode("div",{innerHTML:e.post.content_rendered,ref_key:"contentRef",ref:n},null,8,$t)],2)):Vue.createCommentVNode("",!0)],6))}},Zt=k(Kt,[["__scopeId","data-v-536450bc"]]),Yt={name:"Msg",props:{type:"",text:""},created(){setTimeout(()=>{this.$emit("close")},3e3)}},qt=Vue.createElementVNode("svg",{width:"24",height:"24",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[Vue.createElementVNode("path",{d:"M14 14L34 34",stroke:"#ffffff","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M14 34L34 14",stroke:"#ffffff","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"})],-1),Xt=[qt],Jt={class:"right"};function Qt(o,e,s,a,n,t){return Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["msg",s.type])},[Vue.createElementVNode("div",{class:"left",onClick:e[0]||(e[0]=d=>o.$emit("close"))},Xt),Vue.createElementVNode("div",Jt,Vue.toDisplayString(s.text),1)],2)}const eo=k(Yt,[["render",Qt]]),to=[{avatar:"https://cdn.v2ex.com/avatar/cdca/41db/41900_normal.png?m=1644293935",id:"887913",content_rendered:"",thankCount:0,title:"正文显示异常12123",node:"经典回顾",username:"经典回顾",date:"几小时前"},{avatar:"https://cdn.v2ex.com/avatar/cdca/41db/41900_normal.png?m=1644293935",id:"667520",content_rendered:"",thankCount:0,title:"嵌套有问题",node:"经典回顾",username:"经典回顾",date:"几小时前"},{avatar:"https://cdn.v2ex.com/avatar/cdca/41db/41900_normal.png?m=1644293935",id:"724408",content_rendered:"",thankCount:0,title:"内容超级多",node:"经典回顾",username:"经典回顾",date:"几小时前"},{avatar:"https://cdn.v2ex.com/avatar/cdca/41db/41900_normal.png?m=1644293935",id:"886622",thankCount:0,title:"回复里面如果是 本站帖子,那么不打开新的页面",node:"经典回顾",username:"经典回顾",date:"几小时前"}];const oo=o=>(Vue.pushScopeId("data-v-2d42a498"),o=o(),Vue.popScopeId(),o),no=oo(()=>Vue.createElementVNode("svg",{width:"24",height:"24",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[Vue.createElementVNode("path",{d:"M17 32L19.1875 27M31 32L28.8125 27M19.1875 27L24 16L28.8125 27M19.1875 27H28.8125",stroke:"#929596","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M43.1999 20C41.3468 10.871 33.2758 4 23.5999 4C13.9241 4 5.85308 10.871 4 20L10 18",stroke:"#929596","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"}),Vue.createElementVNode("path",{d:"M4 28C5.85308 37.129 13.9241 44 23.5999 44C33.2758 44 41.3468 37.129 43.1999 28L38 30",stroke:"#929596","stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"})],-1)),so={key:1},lo={__name:"Base64Tooltip",setup(o){const e=Vue.ref(null),s=Vue.ref(!1),a=Vue.ref(""),n=Vue.ref(""),t=Vue.reactive({left:"-100vw",top:"-100vh"});Vue.onMounted(()=>{i.on(r.SHOW_TOOLTIP,({text:h,e:l})=>{setTimeout(()=>s.value=!0),a.value=h,n.value="",t.left=l.clientX+"px",t.top=l.clientY+20+"px"}),window.win().addEventListener("click",h=>{e.value&&!e.value.contains(h.target)&&s.value&&(s.value=!1)},{capture:!0});const u=()=>s.value&&(s.value=!1);$(".post-detail",window.win().doc).on("scroll",u)});function d(){window.win().navigator.clipboard?(window.win().navigator.clipboard.writeText(n.value),i.emit(r.SHOW_MSG,{type:"success",text:"复制成功"})):i.emit(r.SHOW_MSG,{type:"error",text:"复制失败!浏览器不支持!"})}function p(){try{n.value=window.atob(a.value)}catch{i.emit(r.SHOW_MSG,{type:"error",text:"Base64解码失败!不是标准数据!"})}}return(u,h)=>Vue.withDirectives((Vue.openBlock(),Vue.createElementBlock("div",{class:"base64_tooltip",style:Vue.normalizeStyle(t),onClick:p,ref_key:"tooltip",ref:e},[n.value?(Vue.openBlock(),Vue.createElementBlock("div",so,[Vue.createElementVNode("span",null,Vue.toDisplayString(n.value),1),Vue.createElementVNode("div",{class:"button",onClick:d},"点击复制")])):(Vue.openBlock(),Vue.createElementBlock(Vue.Fragment,{key:0},[Vue.createTextVNode(" Base64解码:"+Vue.toDisplayString(a.value)+" ",1),no],64))],4)),[[Vue.vShow,s.value]])}},io=k(lo,[["__scopeId","data-v-2d42a498"]]);const ro={name:"home",provide(){return{isDev:Vue.computed(()=>!1),isLogin:Vue.computed(()=>!!window.win().user.username),pageType:Vue.computed(()=>this.pageType),clone:window.win().clone,post:Vue.computed(()=>this.current),allReplyUsers:Vue.computed(()=>Array.from(new Set(this.current.replies.map(o=>o.username))))}},components:{PostDetail:Ht,Post:Zt,Msg:eo,Base64Tooltip:io},data(){return{viewType:"card",loading:window.win().pageType==="post",loadMore:!1,pageType:window.win().pageType,msgList:[],show:!1,autoOpenDetail:!1,current:window.win().initPost,list:[],readList:new Set}},computed:{isDev(){return!1},showList(){return this.pageType==="home"||this.pageType==="recent"||this.pageType==="nodePage"}},watch:{"current.replies":{handler(o,e){if(o.length){this.current.replyCount=o.length;let s=window.parse.createNestedList(o,this.current.allReplyUsers);s&&(this.current.nestedReplies=s)}else this.current.replyCount=0,this.current.nestedReplies=[];if(this.list){let s=this.list.findIndex(a=>a.id===this.current.id);s>-1&&(this.list[s].replyCount=o.length)}},deep:!0}},created(){console.log("create"),window.win().cb=this.winCb;let o=window.win().localStorage.getItem("v2ex-config");if(o){let e=JSON.parse(o);e=e[window.win().user.username??"default"],e&&(this.readList=new Set(e.readList),this.viewType=e.viewType,this.autoOpenDetail=e.autoOpenDetail||!1,this.autoOpenDetail&&this.pageType==="post"&&(this.loading=!0,this.openPostDetail()))}if(window.win().onbeforeunload=this.saveConfig,window.win().canParseV2exPage){if(this.list=window.win().postList,window.win().waitDelElList.map(e=>e.remove()),window.win().waitDelElList=[],this.showList){let e=window.win().appNode.nextElementSibling,s=1e3;if(this.pageType!=="home"){let n=e.querySelectorAll("a");s=Number(n[n.length-1].innerText)}let a=window.win().IntersectionObserver;new a(async n=>{if(n[0].isIntersecting){if(this.loadMore)return;console.log("加载更多"),this.loadMore=!0;let t;if(this.pageType==="home")t=window.win().url+"/recent?p=1",this.pageType="recent";else{let{href:h,search:l,origin:c,pathname:_}=window.win().location;t=h+"?p=2";let g=l.match(/p=([\d]+)/);if(g){if(Number(g[1])>=s)return i.emit(r.SHOW_MSG,{type:"success",text:"已经是最后一页了"}),this.loadMore=!1;t=c+_+l.replace(g[1],Number(g[1])+1)}}console.log("url",t),window.win().history.pushState({},0,t);let p=await(await window.win().fetch(t)).text(),u=window.parse.parseOtherPage(p,this.pageType);console.log("res",u),e.innerHTML=u.page,this.list.push({type:"page",innerHTML:e.innerHTML}),u.postList.map(h=>{this.list.findIndex(c=>c.id==h.id)===-1&&this.list.push(h)}),this.loadMore=!1,Promise.allSettled(u.apiList.map(h=>$.get(h))).then(async h=>{let l=h.filter(c=>c.status==="fulfilled").map(c=>c.value[0]);this.winCb({type:"list",value:l})})}})}}else this.list=to;this.initEvent()},beforeUnmount(){console.log("unmounted"),i.clear()},methods:{winCb({type:o,value:e}){o==="list"&&(e.map(s=>{let a=this.list.findIndex(n=>n.id==s.id);a>-1&&(this.list[a]=Object.assign(this.list[a],{content_rendered:s.content_rendered,nodeUrl:s.node.url,avatar:s.member.avatar_large}))}),window.win().vueCb&&window.win().vueCb()),o==="postContent"&&(this.saveConfig(this.readList.add(e.id)),this.current=Object.assign(this.clone(window.win().initPost),this.clone(e))),o==="postReplies"&&(this.current=Object.assign(this.current,this.clone(e)),this.loading=!1),o==="ad"&&(window.win().adList.map(s=>{let a=window.win().query("#"+s.id),n=this.list.findIndex(t=>t.id==s.id);n>-1&&(this.list[n]=Object.assign(this.list[n],{innerHTML:a.innerHTML}))}),window.win().$adListEl.innerHTML="",window.win().adList=[])},saveConfig(){let o={[window.win().user.username??"default"]:{viewType:this.viewType,readList:Array.from(this.readList),autoOpenDetail:this.autoOpenDetail}};window.win().localStorage.setItem("v2ex-config",JSON.stringify(o))},clone(o){return window.win().clone(o)},initEvent(){i.on(r.CHANGE_COMMENT_THANK,o=>{const{id:e,type:s}=o;let a=this.current.replies.findIndex(n=>n.id===e);a>-1&&(this.current.replies[a].isThanked=s==="add",s==="add"?this.current.replies[a].thankCount++:this.current.replies[a].thankCount--)}),i.on(r.CHANGE_POST_THANK,o=>{const{id:e,type:s}=o;this.current.isThanked=s==="add",s==="add"?this.current.thankCount++:this.current.thankCount--;let a=this.list.findIndex(n=>n.id===e);a>-1&&(this.list[a].isThanked=s==="add",s==="add"?this.list[a].thankCount++:this.list[a].thankCount++)}),i.on(r.REMOVE,o=>{let e=this.current.replies.findIndex(a=>a.floor===o);e>-1&&this.current.replies.splice(e,1);let s=this.list.findIndex(a=>a.id===this.current.id);s>-1&&(this.list[s]=Object.assign(this.list[s],o))}),i.on(r.SHOW_MSG,o=>{this.msgList.push({...o,id:Date.now()})}),i.on(r.IGNORE,()=>{this.show=!1;let o=this.list.findIndex(e=>e.id===this.current.id);o>-1&&this.list.splice(o,1),this.current=this.clone(window.win().initPost)}),i.on(r.MERGE,o=>{this.current=Object.assign(this.current,o);let e=this.list.findIndex(s=>s.id===this.current.id);e>-1&&(this.list[e]=Object.assign(this.list[e],o))}),i.on(r.ADD_REPLY,o=>{this.current.replies.push(o)}),i.on(r.REFRESH_ONCE,async o=>{if(o){if(typeof o=="string"){let e=o.match(/var once = "([\d]+)";/);if(e&&e[1]){this.current.once=Number(e[1]);return}}if(typeof o=="number"){this.current.once=o;return}}window.win().fetchOnce().then(e=>{this.current.once=e})})},svgColor(o){return o===this.viewType?"white":"#929596"},removeMsg(o){let e=this.msgList.findIndex(s=>s.id===o);e>-1&&this.msgList.splice(e,1)},openPostDetail(){this.show=!0,window.win().doc.body.style.overflow="hidden"},async getPostDetail(o,e){if(this.openPostDetail(),e){let u=e.target||e.srcElement;if(u.nodeName.toLocaleLowerCase()==="a"){e.preventDefault();let l=u.innerText.match(/t\/([\d]+)/);l&&(o={id:l[1]})}}this.saveConfig(this.readList.add(o.id)),this.current=Object.assign(window.win().clone(window.win().initPost),{RightbarHTML:this.current.RightbarHTML},window.win().clone(o)),this.current.replies.length||(this.loading=!0);let s=window.win().url+"/t/"+o.id,a=await window.win().fetch(s+"?p=1");if(a.redirected)return i.emit(r.SHOW_MSG,{type:"error",text:"没有权限"}),this.loading=!1;let n=await a.text();if(n.search("你要查看的页面需要先登录(不可用)")>-1)return i.emit(r.SHOW_MSG,{type:"error",text:"你要查看的页面需要先登录(不可用)"}),this.loading=!1;let d=n.match(/<body[^>]*>([\s\S]+?)<\/body>/g),p=$(d[0]);if(this.current=await window.parse.getPostDetail(this.current,p,n),this.current.replies.length){let u=this.list.findIndex(h=>h.id===o.id);u>-1&&(this.list[u].replies=this.current.replies,this.list[u].nestedReplies=this.current.nestedReplies,this.list[u].once=this.current.once,this.list[u].createDate=this.current.createDate)}this.loading=!1,console.log("当前帖子",this.current)}}},ao={width:"19",height:"19",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},co=["stroke"],uo=["stroke"],ho=["stroke"],po=Vue.createElementVNode("span",null,"表格",-1),mo={width:"19",height:"19",viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg"},Vo=["stroke"],wo=["stroke"],fo=["fill"],_o=["fill"],vo=["fill"],ko=Vue.createElementVNode("span",null,"卡片",-1),go={class:"posts"},yo=["innerHTML"],Co={key:0,class:"flex flex-center p1"},Eo=Vue.createElementVNode("div",{class:"loading-c"},null,-1),No=[Eo],xo={key:1,class:"my-box flex f14",style:{margin:"1rem 0 0 0",padding:"1rem"}},To={class:"flex"},So={class:"msgs"};function Lo(o,e,s,a,n,t){const d=Vue.resolveComponent("Post"),p=Vue.resolveComponent("PostDetail"),u=Vue.resolveComponent("Msg"),h=Vue.resolveComponent("Base64Tooltip");return Vue.openBlock(),Vue.createElementBlock("div",{class:Vue.normalizeClass(["app-home",[n.viewType,n.pageType]])},[t.showList?(Vue.openBlock(),Vue.createElementBlock(Vue.Fragment,{key:0},[Vue.createElementVNode("div",{class:Vue.normalizeClass(["nav flex flex-end",n.viewType])},[Vue.createElementVNode("div",{class:Vue.normalizeClass(["nav-item",{active:n.viewType==="table"}]),onClick:e[0]||(e[0]=l=>t.saveConfig(n.viewType="table"))},[(Vue.openBlock(),Vue.createElementBlock("svg",ao,[Vue.createElementVNode("path",{d:"M42 5H6V13H42V5Z",fill:"none",stroke:t.svgColor("table"),"stroke-width":"4","stroke-linejoin":"round"},null,8,co),Vue.createElementVNode("path",{d:"M42 20H6V28H42V20Z",fill:"none",stroke:t.svgColor("table"),"stroke-width":"4","stroke-linejoin":"round"},null,8,uo),Vue.createElementVNode("path",{d:"M42 35H6V43H42V35Z",fill:"none",stroke:t.svgColor("table"),"stroke-width":"4","stroke-linejoin":"round"},null,8,ho)])),po],2),Vue.createElementVNode("div",{class:Vue.normalizeClass(["nav-item",{active:n.viewType==="card"}]),onClick:e[1]||(e[1]=l=>t.saveConfig(n.viewType="card"))},[(Vue.openBlock(),Vue.createElementBlock("svg",mo,[Vue.createElementVNode("path",{d:"M42 18V40C42 41.1046 41.1046 42 40 42H8C6.89543 42 6 41.1046 6 40V18",stroke:t.svgColor("card"),"stroke-width":"4","stroke-linecap":"round","stroke-linejoin":"round"},null,8,Vo),Vue.createElementVNode("path",{d:"M6 8C6 6.89543 6.89543 6 8 6H40C41.1046 6 42 6.89543 42 8V18H6V8Z",fill:"none",stroke:t.svgColor("card"),"stroke-width":"4","stroke-linejoin":"round"},null,8,wo),Vue.createElementVNode("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z",fill:t.svgColor("card")},null,8,fo),Vue.createElementVNode("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18 14C19.1046 14 20 13.1046 20 12C20 10.8954 19.1046 10 18 10C16.8954 10 16 10.8954 16 12C16 13.1046 16.8954 14 18 14Z",fill:t.svgColor("card")},null,8,_o),Vue.createElementVNode("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M24 14C25.1046 14 26 13.1046 26 12C26 10.8954 25.1046 10 24 10C22.8954 10 22 10.8954 22 12C22 13.1046 22.8954 14 24 14Z",fill:t.svgColor("card")},null,8,vo)])),ko],2)],2),Vue.createElementVNode("div",go,[(Vue.openBlock(!0),Vue.createElementBlock(Vue.Fragment,null,Vue.renderList(n.list,l=>(Vue.openBlock(),Vue.createElementBlock(Vue.Fragment,null,[l.type==="ad"&&l.innerHTML?(Vue.openBlock(),Vue.createElementBlock("div",{key:0,class:Vue.normalizeClass(["nav p0 page",n.viewType])},[Vue.createElementVNode("div",{innerHTML:l.innerHTML},null,8,yo)],2)):(Vue.openBlock(),Vue.createBlock(d,{key:1,viewType:n.viewType,post:l,class:Vue.normalizeClass({visited:n.readList.has(l.id)}),onShow:c=>t.getPostDetail(l,c)},null,8,["viewType","post","class","onShow"]))],64))),256)),n.loadMore?(Vue.openBlock(),Vue.createElementBlock("div",Co,No)):Vue.createCommentVNode("",!0)])],64)):Vue.createCommentVNode("",!0),n.pageType==="post"?(Vue.openBlock(),Vue.createElementBlock("div",xo,[Vue.createElementVNode("div",To,[Vue.createTextVNode(" 自动加载详情页 : "),Vue.createElementVNode("div",{class:Vue.normalizeClass(["switch",{active:n.autoOpenDetail}]),onClick:e[2]||(e[2]=l=>t.saveConfig(n.autoOpenDetail=!n.autoOpenDetail))},null,2)]),Vue.createElementVNode("div",{class:Vue.normalizeClass(["button",{loading:n.loading}]),onClick:e[3]||(e[3]=(...l)=>t.openPostDetail&&t.openPostDetail(...l))}," 点击显示详情页 ",2)])):Vue.createCommentVNode("",!0),Vue.createVNode(p,{modelValue:n.show,"onUpdate:modelValue":e[4]||(e[4]=l=>n.show=l),loading:n.loading},null,8,["modelValue","loading"]),Vue.createElementVNode("div",So,[(Vue.openBlock(!0),Vue.createElementBlock(Vue.Fragment,null,Vue.renderList(n.msgList,l=>(Vue.openBlock(),Vue.createBlock(u,{key:l.id,type:l.type,text:l.text,onClose:c=>t.removeMsg(l.id)},null,8,["type","text","onClose"]))),128))]),Vue.createVNode(h)],2)}const Bo=k(ro,[["render",Lo]]);let x;window.win().isFrame?x=$("#app",window.win().doc)[0]:x=$("#app")[0];window.win().vue&&window.win().vue.unmount();let B=Vue.createApp(Bo);window.win().vue=B;window.win().appNode=x;B.config.unwrapInjectedRef=!0;B.mount(x);


})


    const isDev = false

    if (window.top[0]) {
        window.win = () => window.top
        window.win().url = 'https://www.v2ex.com'
        // window.win().url = location.origin
        window.win().isFrame = true
        //直接使用v2的jquery,因为v2对jquery作了修改,加了一些header,缺少这些header发送请求会报403
        window.$ = window.win().$
    } else {
        window.win = () => window
        window.win().url = 'https://www.v2ex.com'
        // window.win().url = location.origin
        window.win().isFrame = false
    }

    window.win().initPost = {
        replies: [],
        nestedReplies: [],
        username: '',
        title: '',
        id: '',
        type: 'post',
        once: '',
        replyCount: 0,
        clickCount: 0,
        thankCount: 0,
        collectCount: 0,
        isFavorite: false,
        isIgnore: false,
        isThanked: false,
        isReport: false,
        RightbarHTML: '',
    }
    window.win().doc = window.win().document
    window.win().query = (v) => window.win().document.querySelector(v)
    window.win().queryAll = window.win().document.querySelectorAll
    window.win().clone = (val) => JSON.parse(JSON.stringify(val))
    window.win().user = {}
    window.win().pageType = ''
    window.win().pageData = {pageNo: 1}
    window.win().adIndex = 0 //广告下标,用于区分广告id
    window.win().adList = []//广告列表,用于延时通知vue复制广告的innerHTML,因为一开始就复制,google的js不能正常加载
    //待删除元素列表。等vue加载好了,再删除。之所以要用数组,是因为帖子中间夹杂着广告。
    // 只删除帖子,广告会被移除到其他地方,保证google的js能正常加载出广告来
    window.win().waitDelElList = []

  window.parse = {
    //解析帖子内容
    async parsePostContent(post = {}, body, htmlText) {
      //如果没有正文(点的本站的a标签),才会解析正文
      if (!post.title) {
        let main = body.find('#Main')
        let topic_content = main.find('.topic_content')
        if (topic_content.length) {
          post.content_rendered = topic_content.html()
        }
        let title = main.find('.header h1')
        if (title.length) {
          post.title = title.html()
        }
        let as = main.find('.header a')
        debugger
        if (as[2]) {
          post.nodeUrl = as[2].href
          post.node = as[2].innerText
        }
        //标题里面可能也有a标签...不能用as[5]
        let lastA = as[as.length-1]
        if (lastA) {
          post.username = lastA.innerText
          post.date = lastA.nextElementSibling.innerText
        }

        let avatarNode = main.find('.header .fr img')
        if (avatarNode.length) {
          post.avatar = avatarNode[0].src
        }
      }

      let subtles = body.find('.subtle')
      if (subtles.length) {
        post.subtlesHtml = `
        <div class="subtlesHtml">${Array.from(subtles).reduce((p, i) => {
            p += `<div class="subtle">${i.innerHTML}</div>`
          return p
        }, '')}</div>
        `
      }

      let once = htmlText.match(/var once = "([\d]+)";/)
      // console.log(once)
      if (once && once[1]) {
        post.once = once[1]
      }

      post.isReport = htmlText.includes('你已对本主题进行了报告')

      let topic_buttons = body.find('.topic_buttons')
      if (topic_buttons.length) {
        let favoriteNode = topic_buttons.find('.tb:first')
        if (favoriteNode.length) {
          post.isFavorite = favoriteNode[0].innerText === '取消收藏'
        }
        let ignoreNode = topic_buttons.find('.tb:nth-child(3)')
        if (ignoreNode.length) {
          post.isIgnore = ignoreNode[0].innerText === '取消忽略'
        }
        //
        let thankNode = topic_buttons.find('#topic_thank .tb')
        if (!thankNode.length) {
          post.isThanked = true
        }

        let topic_stats = topic_buttons.find('.topic_stats')
        //topic_stats = $(`<div class="fr topic_stats" style="padding-top: 4px;">9569 次点击 &nbsp;∙&nbsp; 28 人收藏 &nbsp; ∙&nbsp; 1 人感谢 &nbsp; </div>`)
        //收藏数、感谢数
        if (topic_stats.length) {
            let text = topic_stats[0].innerText
            let reg1 = text.matchAll(/([\d]+)[\s]*人收藏/g)
            let collectCountReg = [...reg1]
            if (collectCountReg.length) {
                post.collectCount = Number(collectCountReg[0][1])
            }
            // console.log([...collectCountReg])
            let reg2 = text.matchAll(/([\d]+)[\s]*人感谢/g)
            let thankCountReg = [...reg2]
            if (thankCountReg.length) {
                post.thankCount = Number(thankCountReg[0][1])
            }
            // console.log([...thankCountReg])
        }
      }

                                          //点击数
                                          let baseInfo = body.find('.header small.gray')
                                          if (baseInfo.length) {
                                              let text = baseInfo.text()
                                              let reg = text.matchAll(/([\d]+)[\s]*次点击/g)
                                              let clickCountReg = [...reg]
                                              if (clickCountReg.length) {
                                                  post.clickCount = Number(clickCountReg[0][1])
                                              }
                                          }

                                          // let Rightbar = window.win().query('#Rightbar')
                                          let Rightbar = body.find('#Rightbar')
                                          if (Rightbar.length) {
                                              post.RightbarHTML = Rightbar[0].innerHTML
                                              //让修改背景的样式失效
                                              post.RightbarHTML = post.RightbarHTML.replace('type="text/css"', 'type="text/css1"')
                                          }
                                          // console.log('基本信息', post)
                                          return post
                                         },
                                             //获取帖子所有回复
                                             async getPostAllReplies(post = {}, body, htmlText, pageNo = 1) {
                                                 if (body.find('#no-comments-yet').length) {
                                                     return post
                                                 }

                                                 let box = body.find('#Main > .box')[1]
                                                 let cells = box.querySelectorAll('.cell')
                                                 cells = Array.from(cells)

                                                 //获取创建时间
                                                 let snow = cells[0].querySelector('.snow')
                                                 post.createDate = snow?.nextSibling.nodeValue.trim() || ''

                                                 let repliesMap = []
                                                 if (cells[1].id) {
                                                     repliesMap.push({i: pageNo, replyList: this.parsePageReplies(cells.slice(1))})
                                                     let replies = this.getAllReply(repliesMap)
                                                     post.replies = replies
                                                     post.replyCount = replies.length
                                                     post.allReplyUsers = Array.from(new Set(replies.map(v => v.username)))
                                                     let nestedList = this.createNestedList(replies, post.allReplyUsers)
                                                     if (nestedList) post.nestedReplies = nestedList
                                                     return post
                                                 } else {
                                                     let promiseList = []
                                                     // console.log(this.current.repliesMap)
                                                     return new Promise((resolve, reject) => {
                                                         repliesMap.push({i: pageNo, replyList: this.parsePageReplies(cells.slice(2, cells.length - 1))})

                                                         let pages = cells[1].querySelectorAll('a')
                                                         pages = Array.from(pages)
                                                         // console.log(pages)
                                                         let url = window.win().url + '/t/' + post.id
                                                         for (let i = 0; i < pages.length; i++) {
                                                             let currentPageNo = Number(pages[i].innerText)
                                                             if (currentPageNo == pageNo) continue
                                                             promiseList.push(this.fetchPostOtherPageReplies(url + '?p=' + currentPageNo, currentPageNo))
                                                         }
                                                         Promise.allSettled(promiseList).then(
                                                             (results) => {
                                                                 results.filter((result) => result.status === "fulfilled").map(v => repliesMap.push(v.value))
                                                                 let replies = this.getAllReply(repliesMap)
                                                                 post.replies = replies
                                                                 post.replyCount = replies.length
                                                                 post.allReplyUsers = Array.from(new Set(replies.map(v => v.username)))
                                                                 let nestedList = this.createNestedList(replies, post.allReplyUsers)
                                                                 if (nestedList) post.nestedReplies = nestedList
                                                                 resolve(post)
                                                             }
                                                         );
                                                     })
                                                 }
                                             },
                                                 //请求帖子其他页的回复
                                                 fetchPostOtherPageReplies(url, pageNo) {
                                                     return new Promise(resolve => {
                                                         $.get(url).then(res => {
                                                             let s = res.match(/<body[^>]*>([\s\S]+?)<\/body>/g)
                                                             let box = $(s[0]).find('#Main .box')[1]
                                                             let cells = box.querySelectorAll('.cell')
                                                             cells = Array.from(cells)
                                                             resolve({i: pageNo, replyList: this.parsePageReplies(cells.slice(2, cells.length - 1))})
                                                         })
                                                     })
                                                 },
                                                     //解析页面的回复
                                                     parsePageReplies(nodes) {
                                                         let replyList = []
                                                         nodes.forEach((node, index) => {
                                                             if (!node.id) return
                                                             let item = {
                                                                 thankCount: 0,
                                                                 isThanked: false,
                                                                 isOp: false,
                                                                 id: node.id.replace('r_', '')
                                                             }
                                                             let reply_content = node.querySelector('.reply_content')
                                                             // console.log('reply_content',reply_content)
                                                             item.reply_content = reply_content.innerHTML
                                                             item.reply_text = reply_content.innerText

                                                             let {users, floor} = this.parseReplyContent(item.reply_content)
                                                             item.replyUsers = users
                                                             item.replyFloor = floor
                                                             if (index === 5) {
                                                                 // console.log(item)
                                                                 // console.log(reply_content.innerText)
                                                                 // console.log(reply_content.innerHTML)
                                                             }
                                                             let ago = node.querySelector('.ago')
                                                             item.date = ago.innerText

                                                             let userNode = node.querySelector('strong a')
                                                             item.username = userNode.innerText
                                                             let avatar = node.querySelector('td img')
                                                             item.avatar = avatar.src
                                                             let no = node.querySelector('.no')
                                                             item.floor = Number(no.innerText)

                                                             let thank_area = node.querySelector('.thank_area')
                                                             if (thank_area) {
                                                                 item.isThanked = thank_area.classList.contains('thanked')
                                                             }
                                                             let small = node.querySelector('.small')
                                                             if (small) {
                                                                 item.thankCount = Number(small.innerText)
                                                             }
                                                             let op = node.querySelector('.op')
                                                             if (op) {
                                                                 item.isOp = true
                                                             }
                                                             // console.log('item', item)

                                                             replyList.push(item)
                                                         })
                                                         return replyList
                                                     },
                                                         //解析回复内容,解析出@用户,回复楼层。用于后续生成嵌套楼层
                                                         parseReplyContent(str) {
                                                             if (!str) return
                                                             let users = []
                                                             let getUsername = (userStr) => {
                                                                 let endIndex = userStr.indexOf('">')
                                                                 if (endIndex > -1) {
                                                                     let user = userStr.substring(0, endIndex)
                                                                     if (!users.find(i => i === user)) {
                                                                         users.push(user)
                                                                     }
                                                                 }
                                                             }
                                                             // str = `@<a hr a> #4 @<a1 href="/member/Eiden1">Eiden1</a1>   @<a href="/member/Eiden111">Eiden21</a> #11   这也是执行阶段,所谓的安装也是程序业务的 setup 。<br>windows 、Android 并没有系统级的 CD-KEY 。`
                                                             let floorReg = /@<a href="\/member\/[\s\S]+?<\/a>[\s]+#([\d]+)/g
                                                             let userReg = /@<a href="\/member\/([\s\S]+?)<\/a>/g
                                                             let hasFloor = str.matchAll(floorReg)
                                                             let res = [...hasFloor]
                                                             // console.log('总匹配', res)
                                                             let floor = -1
                                                             if (res.length) {
                                                                 floor = Number(res[0][1])
                                                             }
                                                             let has = str.matchAll(userReg)
                                                             let res2 = [...has]
                                                             // console.log('总匹配', res2)
                                                             if (res2.length > 1) {
                                                                 res2.map(item => {
                                                                     getUsername(item[1])
                                                                 })
                                                             }
                                                             if (res2.length === 1) {
                                                                 getUsername(res2[0][1])
                                                             }
                                                             // console.log('用户', users)
                                                             // console.log('楼层', floor)
                                                             return {users, floor}
                                                         },
                                                             //获取帖子详情
                                                             async getPostDetail(post = {}, body, htmlText, pageNo = 1) {
                                                                 post = await this.parsePostContent(post, body, htmlText)
                                                                 return await this.getPostAllReplies(post, body, htmlText, pageNo)
                                                             },
                                                                 getAllReply(repliesMap = []) {
                                                                     return repliesMap.sort((a, b) => a.i - b.i).reduce((pre, i) => {
                                                                         pre = pre.concat(i.replyList)
                                                                         return pre
                                                                     }, [])
                                                                 },
                                                                     //生成嵌套回复
                                                                     createNestedList(allList = []) {
                                                                         if (!allList.length) return []
                                                                         if ((Date.now() - window.win().lastCallDate) < 1000) {
                                                                             // console.log('短时间内,重复调用,因为监听了replies,所以打开时会触发两次。第二次不管他')
                                                                             return false
                                                                         }
                                                                         // console.log('cal-createNestedList', Date.now())

                                                                         let list = JSON.parse(JSON.stringify(allList))
                                                                         let nestedList = []
                                                                         list.map((item, index) => {
                                                                             let startList = list.slice(0, index)
                                                                             let startReplyUsers = Array.from(new Set(startList.map(v => v.username)))

                                                                             let endList = list.slice(index + 1)

                                                                             if (index === 0) {
                                                                                 item.level = 0
                                                                                 nestedList.push(this.findChildren(item, endList, list))
                                                                             } else {
                                                                                 let isParentReply = false
                                                                                 // if (item.replyFloor === -1) {
                                                                                 //   isParentReply = true
                                                                                 // }
                                                                                 if (item.replyUsers.length) {
                                                                                     if (item.replyUsers.length > 1) {
                                                                                         isParentReply = true
                                                                                     } else {
                                                                                         isParentReply = !startReplyUsers.find(v => v === item.replyUsers[0]);
                                                                                     }
                                                                                 }else {
                                                                                     isParentReply = true
                                                                                 }
                                                                                 if (isParentReply) {
                                                                                     item.level === 0
                                                                                     nestedList.push(this.findChildren(item, endList, list))
                                                                                 }
                                                                             }
                                                                         })
                                                                         console.log('replies长度', allList)
                                                                         console.log('nestedList长度', nestedList)
                                                                         window.win().lastCallDate = Date.now()
                                                                         return nestedList
                                                                     },
                                                                         //查找子回复
                                                                         findChildren(item, endList, all) {
                                                                             const fn = (child, endList2, parent) => {
                                                                                 child.level = parent.level + 1
                                                                                 let rIndex = all.findIndex(v => v.floor === child.floor)
                                                                                 if (rIndex > -1) {
                                                                                     all[rIndex].isUse = true
                                                                                 }
                                                                                 parent.children.push(this.findChildren(child, endList2, all))
                                                                             }
                                                                             // console.log('endList', endList)
                                                                             item.children = []
                                                                             // if (item.floor ==8)debugger
                                                                             for (let i = 0; i < endList.length; i++) {
                                                                                 let currentItem = endList[i]

                                                                                 //如果已被使用,直接跳过
                                                                                 if (currentItem.isUse) continue

                                                                                 let endList2 = endList.slice(i + 1)
                                                                                 //注: 2022-10-26,回复被忽略了之后,会占据原来的楼层
                                                                                 //但是,未忽略这条回复的人,看到的楼层和忽略回复的人看到的不一样,导致以楼层号来判断会出问题
                                                                                 // if (currentItem.replyFloor !== -1) {
                                                                                 if (false) {
                                                                                     if (currentItem.replyFloor === item.floor) {
                                                                                         fn(currentItem, endList2, item)
                                                                                     }
                                                                                 } else {
                                                                                     if (currentItem.replyUsers.length === 1) {
                                                                                         // //找出自己最近一条正常回复,以那条为搜索终点
                                                                                         // let rIndex = endList.findIndex(v => v.username === item.username && (currentItem.replyUsers.length === 0 && currentItem.replyFloor === -1))
                                                                                         // if (rIndex > -1) {
                                                                                         //   endList2 = endList.slice(i + 1, rIndex)
                                                                                         // }
                                                                                         //如果是下一条是同一人的回复,那么跳出循环。children从下一条开始找
                                                                                         if (currentItem.username === item.username) {
                                                                                             //自己回复自己的特殊情况
                                                                                             if (currentItem.replyUsers[0] === item.username) {
                                                                                                 fn(currentItem, endList2, item)
                                                                                                 continue
                                                                                             }
                                                                                             //有种特殊情况,就是自己连着评论了两条。然后后面的人以#号的方式 回复了自己第一条。
                                                                                             //如果检测到下条是自己的回复,直接略过的话就会丢失第一条的所有楼中楼回复
                                                                                             //具体如下
                                                                                             // 自己:1楼,在for的时候,如果碰到 2楼不能直接跳过,直接略过的话就会丢失第一条的所有楼中楼回复,即3楼。所以应该以3楼为起点
                                                                                             //进行楼中楼查找,查找完了再跳过
                                                                                             // 自己:2楼
                                                                                             // 别人:指定回复1楼
                                                                                             // endList2.map((v, vi) => {
                                                                                             //   if (v.replyFloor === item.floor) {
                                                                                             //     fn(v, endList.slice(vi + 1), item)
                                                                                             //   }
                                                                                             // })
                                                                                             break
                                                                                         } else {
                                                                                             if (currentItem.replyUsers[0] === item.username) {
                                                                                                 fn(currentItem, endList2, item)
                                                                                             }
                                                                                         }
                                                                                     }
                                                                                 }
                                                                             }
                                                                             return item
                                                                         },
                                                                             //解析其他页面
                                                                             parseOtherPage(html, pageType) {
                                                                                 let bodyText = html.match(/<body[^>]*>([\s\S]+?)<\/body>/g)
                                                                                 let body = $(bodyText[0])

                                                                                 if (pageType === 'recent') {
                                                                                     let list = body.find('.item')
                                                                                     let res = this.parsePagePostList(list)
                                                                                     let page = body.find('.cell:last').html()
                                                                                     return {...res, page}
                                                                                 }
                                                                                 if (pageType === 'nodePage') {
                                                                                     let topics = body.find('#TopicsNode')
                                                                                     let list = topics.children()
                                                                                     let res = this.parsePagePostList(list)
                                                                                     let page = topics.next().html()
                                                                                     return {...res, page}
                                                                                 }
                                                                             },
                                                                                 //解析页面帖子列表
                                                                                 parsePagePostList(list) {
                                                                                     let postList = []
                                                                                     let apiList = []
                                                                                     list.forEach(function (listItem) {
                                                                                         if (!listItem.classList.contains('cell')) {
                                                                                             window.win().$adListEl.append(listItem)

                                                                                             window.win().adIndex += 1
                                                                                             let adId = 'ad' + window.win().adIndex
                                                                                             listItem.id = adId
                                                                                             let item = {
                                                                                                 type: 'ad',
                                                                                                 id: adId,
                                                                                                 innerHTML: listItem.innerHTML
                                                                                             }
                                                                                             postList.push(item)
                                                                                             window.win().adList.push(item)
                                                                                             // listItem.remove()
                                                                                             return
                                                                                         }
                                                                                         let item = window.win().clone(window.win().initPost)
                                                                                         let bg = listItem.style['background-image']
                                                                                         item.bg = bg
                                                                                         let item_title = listItem.querySelector('.item_title a')
                                                                                         let href = item_title.href
                                                                                         item.id = href.substring(href.indexOf('/t/') + 3, href.indexOf('#'))
                                                                                         item.title = item_title.innerText

                                                                                         let topic_info = listItem.querySelector('.topic_info')
                                                                                         let userNode = topic_info.querySelector('strong a')
                                                                                         item.username = userNode.innerText
                                                                                         let timeNode = listItem.querySelector('.topic_info span')
                                                                                         item.date = timeNode.innerText
                                                                                         let tagNode = topic_info.querySelector('.node')
                                                                                         if (tagNode) {
                                                                                             item.node = tagNode.innerText
                                                                                         }
                                                                                         let countNode = listItem.querySelector('.count_livid')
                                                                                         item.replyCount = countNode ? countNode.innerText : 0

                                                                                         let avatar = listItem.querySelector('img')
                                                                                         item.avatar = avatar.src

                                                                                         let url = window.win().location.origin + '/api/topics/show.json?id=' + item.id
                                                                                         // console.log(url)
                                                                                         apiList.push(url)
                                                                                         postList.push(item)
                                                                                         window.win().waitDelElList.push(listItem)
                                                                                         // listItem.remove()
                                                                                     })
                                                                                     setTimeout(() => {
                                                                                         cbChecker({type: 'ad'})
                                                                                     }, 3000)
                                                                                     return {postList, apiList}
                                                                                 },

                                                                                     fetchAll(list) {
                                                                                         return new Promise(resolve => {
                                                                                             Promise.allSettled(list.map(url => $.get(url))).then(async (res) => {
                                                                                                 let ok = res.filter((r) => r.status === "fulfilled").map(v => v.value[0])
                                                                                                 let fail = res.filter((r) => r.status === "rejected")
                                                                                                 console.log('fail', fail)
                                                                                                 resolve(ok)
                                                                                             });
                                                                                         })
                                                                                     }
  }

  async function sleep(time) {
      return new Promise(resolve => {
          // console.log('等待vue加载完成,第' + count + '次', Date.now())
          setTimeout(resolve, time)
      })
  }

  async function cbChecker(val, count = 0) {
      if (window.win().cb) {
          window.win().cb(val)
      } else {
          while ((!window.win().cb) && count < 20) {
              await sleep(500)
              count++
          }
          window.win().cb && window.win().cb(val)
      }
  }

  let location2 = window.win().location
  if (location2.pathname === '/') {
      window.win().pageType = 'home'
  } else if (location2.href.match(/.com\/?tab=/)) {
      window.win().pageType = 'home'
  } else if (location2.href.match(/.com\/go\//)) {
      window.win().pageType = 'nodePage'
  } else if (location2.href.match(/.com\/recent/)) {
      window.win().pageType = 'recent'
  } else {
      let r = location2.href.match(/.com\/t\/([\d]+)/)
      if (r) {
          window.win().pageType = 'post'
          window.win().pageData.id = r[1]
          if (location2.search) {
              let pr = location2.href.match(/\?p=([\d]+)/)
              if (pr) window.win().pageData.pageNo = Number(pr[1])
          }
      }
  }

  // console.log('type===', window.win().pageType, 'pageData===', window.win().pageData)
  // console.log('postList', window.win().postList)
  // console.log('init', window.win().init)

  //let $vue = document.createElement('iframe');$vue.src = 'http://localhost:3000/';document.body.appendChild($vue);

  window.win().canParseV2exPage = true
  //开发环境并且没有嵌套到v2ex的网页里面时,不要解析
  if (isDev && !window.win().isFrame) {
      window.win().canParseV2exPage = false
  }
  if (window.win().canParseV2exPage) {
      let top2 = window.win().query('.tools .top:nth-child(2)').text
      if (top2 !== '注册(不可用)') {
          window.win().user = {
              username: top2,
              avatar: $('#Rightbar .box:nth-child(1) .avatar', window.win().doc).attr('src')
          }
      }

      window.win().cb = null
      window.win().vueCb = null
      window.win().postList = []

      let $section = document.createElement('section')
      $section.id = 'app'

      window.win().$adListEl = document.createElement('section')
      window.win().$adListEl.id = 'ad_list'
      window.win().$adListEl.style.position = 'fixed'
      window.win().$adListEl.style.left = '-100vw'
      window.win().$adListEl.style.top = '0'
      window.win().doc.body.append(window.win().$adListEl)

      let wrapper
      let box
      let list
      let res
      switch (window.win().pageType) {
          case 'nodePage':
              box = $('#Wrapper #Main .box:first')
              box.css({'box-shadow': 'unset'})

              let topics = $('#TopicsNode')
              topics.attr('id', 'app')
              list = topics.children()
              res = window.parse.parsePagePostList(Array.from(list))
              window.win().postList = res.postList
              window.parse.fetchAll(res.apiList).then(async r => {
                  await cbChecker({type: 'list', value: r})
              })
              break
          case 'recent':
          case 'home':
              box = window.win().query('#Wrapper #Main .box')
              box.style.boxShadow = 'unset'
              let arr = Array.from(box.children)
              let start = arr.findIndex(v => v.classList.contains('item'))
              let end = arr.slice().reverse().findIndex(v => v.classList.length === 0)
              wrapper = box.querySelector('.item')
              wrapper.before($section)
              // list = box.querySelectorAll('.item')
              list = arr.slice(start, arr.length - end)
              res = window.parse.parsePagePostList(list)
              window.win().postList = res.postList
              window.parse.fetchAll(res.apiList).then(async r => {
                  await cbChecker({type: 'list', value: r})
              })
              break
          case 'post':
              box = window.win().query('#Wrapper #Main .box')
              box.after($section)
              window.parse.parsePostContent(
                  {id: window.win().pageData.id},
                  $(window.win().doc.body),
                  window.win().doc.documentElement.outerHTML
              ).then(async res => {
                  // console.log('详情页-基本信息解析完成', new Date())
                  window.win().pageData.post = res
                  await cbChecker({type: 'postContent', value: res}, 0)
              })

              window.parse.getPostAllReplies(
                  {id: window.win().pageData.id},
                  $(window.win().doc.body),
                  window.win().doc.documentElement.outerHTML,
                  window.win().pageData.pageNo
              ).then(async res => {
                  // console.log('详情页-回复解析完成', new Date())
                  window.win().pageData.post = Object.assign(window.win().pageData.post, res)
                  await cbChecker({type: 'postReplies', value: res}, 0)
              })
              break
          default:
              console.error('未知页面')
              break
      }
  }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址