// ==UserScript== // @name 手机百度贴吧自动展开楼层 // @namespace http://tampermonkey.net/ // @homepage https://greasyfork.org/scripts/445657 // @version 4.2 // @description 有时候用手机的浏览器打开百度贴吧,只想看一眼就走,并不想打开APP,这个脚本用于帮助用户自动展开楼层。注意:只支持手机浏览器,测试环境为Iceraven+Tampermonkey // @author voeoc // @icon https://tieba.baidu.com/favicon.ico // @match https://tieba.baidu.com/* // @match https://jump2.bdimg.com/* // @match https://tiebac.baidu.com/* // @exclude /^https?:\/\/[\.a-z]*\/(index|f\?.*kw=)/ // @exclude /^https?:\/\/[.a-z]*\/(index|f?.*kw=)/ // @connect tieba.baidu.com // @connect jump2.bdimg.com // @connect tiebac.baidu.com // @grant unsafeWindow // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_listValues // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_getResourceText // @run-at document-start // @noframes // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } var _Stack_items, _ElementSearcher_options; class Stack { constructor() { _Stack_items.set(this, void 0); __classPrivateFieldSet(this, _Stack_items, [], "f"); } push(element) { __classPrivateFieldGet(this, _Stack_items, "f").push(element); } pop() { return __classPrivateFieldGet(this, _Stack_items, "f").pop(); } peek() { return __classPrivateFieldGet(this, _Stack_items, "f")[__classPrivateFieldGet(this, _Stack_items, "f").length - 1]; } isEmpty() { return __classPrivateFieldGet(this, _Stack_items, "f").length === 0; } size() { return __classPrivateFieldGet(this, _Stack_items, "f").length; } clear() { __classPrivateFieldSet(this, _Stack_items, [], "f"); } } _Stack_items = new WeakMap(); function ASSERT(condition, msg) { if (!condition) { throw new Error(`${msg}`); } } function AUTO_CATCH_ERROR(func, msg, dirObj) { try { func(); } catch (e) { if (msg) { void 0; } else { void 0; } if (dirObj) { void 0; } } } class ElementSearcher { constructor(options) { _ElementSearcher_options.set(this, void 0); __classPrivateFieldSet(this, _ElementSearcher_options, options, "f"); } search(selector) { return ElementSearcher.SEARCH(selector, __classPrivateFieldGet(this, _ElementSearcher_options, "f")); } static SEARCH(selector, options) { const realOptions = Object.assign(Object.assign({}, ElementSearcher.DEFAULT_OPTIONS), options); if (!selector) { selector = realOptions.selector; } return new Promise((resolve, reject) => { let findTimeNum = 0; let timer = setInterval(() => { let element = realOptions.searchFunc(selector); if (element) { clearInterval(timer); resolve(element); return; } findTimeNum++; if (realOptions.searchNum < findTimeNum) { clearInterval(timer); reject(new Error(`search time out: ${selector}=${element}`)); } }, realOptions.interval); }); } } _ElementSearcher_options = new WeakMap(); ElementSearcher.DEFAULT_OPTIONS = { selector: "", searchNum: 100, searchFunc: document.querySelector.bind(document), interval: 50 }; ElementSearcher.CommonSearcher = new ElementSearcher(); function WAIT_DOCUMENT_READY(documentNode = document) { return new Promise((resolve, reject) => { document.addEventListener("readystatechange", function onDocumentReady(event) { if (documentNode.readyState === "complete") { document.removeEventListener("readystatechange", onDocumentReady); resolve(true); } }); }); } function MATCH_REG(regExp, str) { let regExpMatchArray = regExp.exec(str); if (regExpMatchArray && regExpMatchArray.length > 1) { return regExpMatchArray[1].trim(); } return undefined; } class IframeUtils { constructor(parentNode, id) { this.iframeNode = parentNode.ownerDocument.createElement("iframe"); this.iframeNode.id = id; this.parentNode = parentNode; this.parentNode.appendChild(this.iframeNode); } get contentDocument() { return this.iframeNode.contentDocument; } get contentWindow() { return this.iframeNode.contentWindow; } get ownerDocument() { return this.iframeNode.ownerDocument; } writeDoc(data) { try { this.contentDocument.open().write(data); } finally { this.contentDocument.close(); } } } function GET_INPUT_ELEMENT_VALUE(inputElement) { switch (inputElement.type) { case "checkbox": return inputElement.checked; case "range": return Number(inputElement.value); default: return inputElement.value; } } function SET_INPUT_ELEMENT_VALUE(inputElement, value) { switch (inputElement.type) { case "checkbox": inputElement.checked = value; break; default: inputElement.value = String(value); break; } } function STOPPROPAGATION(event) { if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } return false; } function GET_URL_ATTR(url, attrName) { return MATCH_REG(RegExp(`${attrName}=([^&]*)&?`, 'i'), url); } var _MainPage_instances, _MainPage_tryCollectSomeKey; const CommonSearcher = ElementSearcher.CommonSearcher; const STR_VOEOCMARK = "VOEOCMARK"; const REGEXP_PBDATA = RegExp(`getPbData\?.*pn\=.*`, 'i'); const REGEXP_POSTPAGE = RegExp(`postPage\?(?=.*tid\=)(?=.*postAuthorId\=)(?=.*forumId\=)`, 'i'); const REGEXP_LZLPAGE = RegExp(`lzlPage\?(?=.*floor\=)(?=.*pid\=)`, 'i'); var PAGE_TYPE; (function (PAGE_TYPE) { PAGE_TYPE[PAGE_TYPE["UNKNOW"] = 0] = "UNKNOW"; PAGE_TYPE[PAGE_TYPE["MAINPAGE"] = 1] = "MAINPAGE"; PAGE_TYPE[PAGE_TYPE["POSTPAGE"] = 2] = "POSTPAGE"; PAGE_TYPE[PAGE_TYPE["LZLPAGE"] = 3] = "LZLPAGE"; PAGE_TYPE[PAGE_TYPE["TIEBAPAGE"] = 4] = "TIEBAPAGE"; })(PAGE_TYPE || (PAGE_TYPE = {})); function GET_PAGE_TYPE() { let isTiePage = false; if (RegExp(`^/f`).test(window.location.pathname)) { if (GET_URL_ATTR(window.location.href, "kw")) { return PAGE_TYPE.TIEBAPAGE; } else if (GET_URL_ATTR(window.location.href, "kz")) { isTiePage = true; } } else if (RegExp(`^/p`).test(window.location.pathname)) { isTiePage = true; } if (isTiePage) { let hash = window.location.hash; if (hash === "" || hash === "#/") { return PAGE_TYPE.MAINPAGE; } else if (REGEXP_POSTPAGE.test(hash)) { return PAGE_TYPE.POSTPAGE; } else if (REGEXP_LZLPAGE.test(hash)) { return PAGE_TYPE.LZLPAGE; } } return PAGE_TYPE.UNKNOW; } class MainPage { constructor() { _MainPage_instances.add(this); this.currentHash = window.location.hash; this.currentScrollYPos = NaN; this.storagePageData = { tieNode: undefined, tiebaNameNode: undefined, lzId: "", floorDataList: new Map(), someKey: { host: "tieba.baidu_mobile_expand.com", tid: "", postAuthorId: "", forumId: "", source: "", } }; const thisClass = this; const oldXHR = unsafeWindow["XMLHttpRequest"]; unsafeWindow["XMLHttpRequest"] = function () { const realXHR = new oldXHR(); realXHR.addEventListener('readystatechange', () => { if (REGEXP_PBDATA.test(realXHR.responseURL) && realXHR.response !== "") { thisClass.parsePbData(realXHR.response, realXHR.responseURL); } }, false); return realXHR; }; unsafeWindow.onscroll = () => { this.checkUrlHashChange(); if (GET_PAGE_TYPE() === PAGE_TYPE.POSTPAGE) { if (window.scrollY !== 0) { this.currentScrollYPos = window.scrollY; } } }; unsafeWindow.onhashchange = () => { this.checkUrlHashChange(); }; } listenReady(callback) { WAIT_DOCUMENT_READY().then(callback); } static REPLACE_HASH(hash) { window.location.replace(MainPage.GET_MAIN_URL() + hash); } static GET_MAIN_URL() { return window.location.href.replace(window.location.hash, ""); } tryGetFirstFloorAndGoPostPage() { __classPrivateFieldGet(this, _MainPage_instances, "m", _MainPage_tryCollectSomeKey).call(this); let url = `${window.origin}/mg/p/getPbData?kz=${this.storagePageData.someKey.tid}&obj_param2=firefox&format=json&eqid=&refer=&pn=1&rn=5`; GM_xmlhttpRequest({ method: "GET", url: url, onload: (details) => { this.parsePbData(details.responseText, url); }, onerror: () => { }, }); const pbdataSearcher = new ElementSearcher({ selector: "pbdata", searchNum: 100, searchFunc: () => { if (this.storagePageData.someKey.tid && this.storagePageData.someKey.postAuthorId && this.storagePageData.someKey.forumId) { return true; } return undefined; } }); CommonSearcher.search("div.nav-bar-v2-fixed:nth-child(1)").then(() => { this.storagePageData.tiebaNameNode = document.querySelector(".forum-block"); this.storagePageData.tieNode = document.querySelector(".main-thread-content"); let postbtn = document.querySelector(".post-page-entry-btn"); if (postbtn) { pbdataSearcher.search().then(() => { MainPage.REPLACE_HASH(`#/postPage?tid=${this.storagePageData.someKey.tid}&postAuthorId=${this.storagePageData.someKey.postAuthorId}&forumId=${this.storagePageData.someKey.forumId}&locateConfig=%5B%5D&source=`); }).catch(() => { if (postbtn) { postbtn.click(); this.checkUrlHashChange(false, PAGE_TYPE.MAINPAGE); } }); } else { pbdataSearcher.search().then(() => { this.checkUrlHashChange(true); }); } }); } listenFloorChange(floorParentNode) { const searchAndUpdatePostPage = () => { let floorNodeList = floorParentNode.querySelectorAll(`div.post-item:not(.${STR_VOEOCMARK})`); floorNodeList.forEach((value) => { this.onNewFloorAdded.call(this, value); }); }; let observer = new MutationObserver((_mutationList) => { searchAndUpdatePostPage(); }); observer.observe(floorParentNode, { attributes: false, childList: true, characterData: false, subtree: false, }); searchAndUpdatePostPage(); } checkUrlHashChange(force = false, lastPageType) { var _a; if (this.currentHash !== window.location.hash) { this.currentHash = window.location.hash; } else if (!force) { return false; } let pageType = GET_PAGE_TYPE(); if (pageType === PAGE_TYPE.POSTPAGE) { if (lastPageType === PAGE_TYPE.MAINPAGE) ; __classPrivateFieldGet(this, _MainPage_instances, "m", _MainPage_tryCollectSomeKey).call(this); CommonSearcher.search(".post-page-list").then((postpagelist) => { this.listenFloorChange(postpagelist); }); this.restorePostPage(); MainPage.scrollTo(this.currentScrollYPos); } else if (pageType === PAGE_TYPE.MAINPAGE) { if (this.storagePageData.tieNode) { CommonSearcher.search(".pb-page-wrapper").then((pbpageNode) => { this.listenFloorChange(pbpageNode); }); CommonSearcher.search("#replySwitch").then((splitlineNode) => { AUTO_CATCH_ERROR(() => { if (!this.storagePageData.tieNode) { throw new Error("1楼不存在"); } if (!splitlineNode.parentNode) { throw new Error("复原1楼时页面加载失败"); } splitlineNode.parentNode.insertBefore(this.storagePageData.tieNode, splitlineNode); }); }); MainPage.scrollTo(0); } } (_a = this.onEnterFinalPage) === null || _a === void 0 ? void 0 : _a.call(this); return true; } static scrollTo(yPos, documentNode = document) { CommonSearcher.search(".post-page").then(() => { documentNode.documentElement.scrollTop = yPos; setTimeout(() => { documentNode.documentElement.scrollTop = yPos; }, 200); }); } restorePostPage() { CommonSearcher.search(".text").then((titletextNode) => { var _a; (_a = this.onEnterFinalPage) === null || _a === void 0 ? void 0 : _a.call(this); AUTO_CATCH_ERROR(() => { if (!this.storagePageData.tiebaNameNode || !titletextNode.parentNode) { throw new Error("贴吧名无法加载"); } let tiebaNameCloneNode = this.storagePageData.tiebaNameNode.cloneNode(true); titletextNode.parentNode.replaceChild(tiebaNameCloneNode, titletextNode); tiebaNameCloneNode.onclick = this.storagePageData.tiebaNameNode.click.bind(this.storagePageData.tiebaNameNode); }); AUTO_CATCH_ERROR(() => { if (!this.storagePageData.tieNode) { throw new Error("1楼内容为空!"); } this.storagePageData.tieNode.style.cssText = `margin-left:0.12rem;margin-right:0.12rem;margin-bottom:0.25rem;`; CommonSearcher.search(".avatar").then(lzavatarNode => { if (lzavatarNode) { lzavatarNode.style.backgroundImage = `url("${lzavatarNode.getAttribute("data-src")}")`; } else { } }); let textContentNode = (this.storagePageData.tieNode.querySelector(".thread-text")); if (textContentNode) { textContentNode.style.cssText = `margin-top:0.18rem;font-size:0.16rem;line-height:0.28rem;`; } else { } let replySwitchNode = document.querySelector("#replySwitch"); if (replySwitchNode && replySwitchNode.parentNode) { replySwitchNode.parentNode.insertBefore(this.storagePageData.tieNode, replySwitchNode); } else { } }); AUTO_CATCH_ERROR(() => { let threadtitleNode = document.querySelector(".thread-title"); if (!threadtitleNode) { threadtitleNode = document.querySelector(".bottom-thread-title"); } if (!threadtitleNode) { throw new Error("标题为空!"); } threadtitleNode.style.cssText = `margin-bottom: 0.13rem;font-size:0.22rem;font-weight:700;line-height:0.33rem;`; }); }); } parsePbData(responseText, responseURL) { AUTO_CATCH_ERROR(() => { var _a, _b; let data; if (typeof responseText == "object") { data = responseText.data; } else { data = JSON.parse(responseText).data; } ASSERT(data, "无法获取PBDATA"); if ((_a = data === null || data === void 0 ? void 0 : data.forum) === null || _a === void 0 ? void 0 : _a.id) { this.storagePageData.someKey.forumId = data.forum.id; } if ((_b = data === null || data === void 0 ? void 0 : data.thread) === null || _b === void 0 ? void 0 : _b.id) { this.storagePageData.someKey.tid = data.thread.id; } AUTO_CATCH_ERROR(() => { let post_list = data.post_list; if (!post_list) { throw new Error(`该PBDATA没有post_list数据, ${data}`); } AUTO_CATCH_ERROR(() => { if (GET_URL_ATTR(responseURL, "pn") === "1") { this.storagePageData.lzId = post_list[0].author.id; this.storagePageData.someKey.postAuthorId = this.storagePageData.lzId; } }, "无法获取楼主id", post_list); for (let i = 0; i < post_list.length; i++) { let d = post_list[i]; this.storagePageData.floorDataList.set(d.floor.toString(), d); } }); }); } } _MainPage_instances = new WeakSet(), _MainPage_tryCollectSomeKey = function _MainPage_tryCollectSomeKey() { this.storagePageData.someKey.host = window.location.hostname; let tid; let postAuthorId; let forumId; let source; if ((tid = GET_URL_ATTR(this.currentHash, "tid")) || ((tid = window.location.pathname.replace("/p/", "")) && !isNaN(tid))) { this.storagePageData.someKey.tid = tid; } if ((postAuthorId = GET_URL_ATTR(this.currentHash, "postAuthorId")) !== undefined) { this.storagePageData.someKey.postAuthorId = postAuthorId; } if ((forumId = GET_URL_ATTR(this.currentHash, "forumId")) !== undefined) { this.storagePageData.someKey.forumId = forumId; } if ((source = GET_URL_ATTR(this.currentHash, "source")) !== undefined) { this.storagePageData.someKey.source = source; } }; var CSS_BAIDU = ":root {\r\n --str_lzl_page_transition_duration: 0.2s;\r\n}\r\n.open-app-text-real {\r\n display: block !important;\r\n -webkit-box-flex: 0;\r\n -webkit-flex: none;\r\n -ms-flex: none;\r\n flex: none;\r\n font-size: .13rem;\r\n color: #614ec2;\r\n}\r\n.open-app-text-real.error {\r\n color: #ff3366 !important;\r\n text-decoration: line-through;\r\n}\r\n\r\n@keyframes rotate3d {\r\n 0%{-webkit-transform:rotate3d(1, 0, 0, 0deg);}\r\n 25%{-webkit-transform:rotate3d(1, 0, 0, 90deg);}\r\n 50%{-webkit-transform:rotate3d(1, 0, 0, 180deg);}\r\n 75%{-webkit-transform:rotate3d(1, 0, 0, 270deg);}\r\n 100%{-webkit-transform:rotate3d(1, 0, 0, 360deg);}\r\n}\r\n.open-app-guide.loading {\r\n animation: rotate3d 0.5s linear infinite;\r\n pointer-events: none;\r\n}\r\n.VOEOC_DIALOG {\r\n position: fixed;\r\n z-index: 999;\r\n height: 0;\r\n visibility: hidden;\r\n transition: visibility var(--str_lzl_page_transition_duration);\r\n}\r\n.VOEOC_DIALOG.VOEOC_DIALOG_SHOW {\r\n display: block;\r\n height: 100%;\r\n visibility: visible;\r\n}\r\n#VOEOC-ID-LZLPAGE {\r\n overscroll-behavior: none;\r\n width: 100%;\r\n overflow: scroll;\r\n}\r\n#VOEOC-ID-LZLPAGE::-webkit-scrollbar { width: 0 !important }\r\n#VOEOC-ID-LZLPAGEBACKGROUND {\r\n position: fixed;\r\n width: 100%;\r\n height: 200%;\r\n background-color: #00000077;\r\n z-index: 1;\r\n opacity: 0;\r\n transition: opacity var(--str_lzl_page_transition_duration);\r\n}\r\n.VOEOC-CLASSNAME-LZLPAGEIFRAME {\r\n position: fixed;\r\n width: 100%;\r\n height: 0%;\r\n background-color: #ffffff;\r\n bottom: 0;\r\n transition: height var(--str_lzl_page_transition_duration);\r\n overflow: hidden;\r\n}\r\n#VOEOC-ID-LZLPAGE.loading, #VOEOC-ID-LZLPAGE.loading > .VOEOC-CLASSNAME-LZLPAGEIFRAME {\r\n pointer-events: none;\r\n}\r\n#VOEOC-ID-LZLPAGE.VOEOC_DIALOG_SHOW > .VOEOC-CLASSNAME-LZLPAGEIFRAME.VOEOC_DIALOG_SHOW {\r\n height: 80%;\r\n}\r\n#VOEOC-ID-LZLPAGE.VOEOC_DIALOG_SHOW > #VOEOC-ID-LZLPAGEBACKGROUND {\r\n opacity: 1;\r\n}\r\n#VOEOC-ID-LZLPAGE.VOEOC_DIALOG_SHOW > .lzl-reload-btn {\r\n margin-left: 0.1rem;\r\n}\r\n.lzl-nav-btn.lzl-reload-btn {\r\n position:fixed;\r\n top:20%;\r\n margin: 0.1rem 0.1rem 0.1rem -0.5rem;\r\n transition: margin-left var(--str_lzl_page_transition_duration);\r\n}\r\n.lzl-nav-btn {\r\n width: .32rem;\r\n height: .32rem;\r\n display: flex;\r\n background-color:#d0d0d04a;\r\n border-radius:50%;\r\n cursor: pointer;\r\n}\r\n.lzl-nav-btn > *{\r\n position: relative;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n height: fit-content;\r\n width: fit-content;\r\n}\r\n@keyframes rotate {\r\n 0%{-webkit-transform:rotate(0deg);}\r\n 25%{-webkit-transform:rotate(90deg);}\r\n 50%{-webkit-transform:rotate(180deg);}\r\n 75%{-webkit-transform:rotate(270deg);}\r\n 100%{-webkit-transform:rotate(360deg);}\r\n}\r\n#VOEOC-ID-LZLPAGE.loading > .lzl-reload-btn {\r\n animation: rotate 0.2s linear infinite;\r\n pointer-events: none;\r\n }\r\n#VOEOC-ID-LZLPAGE.error > .lzl-reload-btn {\r\n background-color: #ff000070 !important;\r\n }\r\n.slide-down-btn{\r\n position: fixed;\r\n top: 20%;\r\n left: 50%;\r\n margin-left: -0.32rem;\r\n opacity: 0;\r\n transition: opacity,margin-top,background-color 0.1s;\r\n}\r\n.slide-down-btn.confirm{\r\n background-color: #0000004a;\r\n}\r\n#VOEOC-ID-SETTING-FRAME {\r\n height: 100%;\r\n width: 100%;\r\n position: fixed;\r\n z-index: 9999;\r\n display: block;\r\n left: 0;\r\n top: 0;\r\n overscroll-behavior: none;\r\n background-color: white;\r\n}\r\n\r\n.VOEOC_DIALOG_BACKGROUND {\r\n position: fixed;\r\n width: 100%;\r\n height: 101%;\r\n left: 0;\r\n top: 0;\r\n z-index: 9999;\r\n overflow: scroll;\r\n overscroll-behavior: none;\r\n background-color: #00000077;\r\n transition: opacity var(--str_lzl_page_transition_duration);\r\n}\r\n.VOEOC_DIALOG_BACKGROUND::before {\r\n content: \" \";\r\n width: 100%;\r\n height: 101%;\r\n display: block;\r\n overscroll-behavior: none;\r\n}\r\n.VOEOC_DIALOG_BACKGROUND::-webkit-scrollbar,\r\n.VOEOC_DIALOG_BACKGROUND::before::-webkit-scrollbar {\r\n width: 0 !important;\r\n}"; var CSS_REMOVE = ".comment-box, .only-lz, .nav-bar-bottom, .open-app, .more-image-desc {\r\n display: none !important;\r\n}\r\n.logo-wrapper {\r\n visibility: hidden !important;\r\n pointer-events: none !important;\r\n height: 0;\r\n}\r\n.open-app-text {\r\n display: none !important;\r\n}"; var HTML_SETTINGS_DIALOG = "Title
"; var _a, _HistoryStateManager_showDialogList, _HistoryStateManager_instance; class VoeocDialog { constructor(historyState, dialogNode) { this.historyState = historyState; this.dialogNode = dialogNode; if (this.dialogNode && !this.dialogNode.classList.contains(VoeocDialog.STR_CLASSNAME_DIALOG)) { this.dialogNode.classList.add(VoeocDialog.STR_CLASSNAME_DIALOG); } } static initHistoryStateManager() { HistoryStateManager.getInstance().init(); } getHistoryState() { return this.historyState; } show() { var _b, _c; (_c = (_b = this.dialogNode) === null || _b === void 0 ? void 0 : _b.classList) === null || _c === void 0 ? void 0 : _c.add(VoeocDialog.STR_CLASSNAME_SHOW_TAG); } hide() { var _b, _c; (_c = (_b = this.dialogNode) === null || _b === void 0 ? void 0 : _b.classList) === null || _c === void 0 ? void 0 : _c.remove(VoeocDialog.STR_CLASSNAME_SHOW_TAG); } isShown() { var _b, _c; return ((_c = (_b = this.dialogNode) === null || _b === void 0 ? void 0 : _b.classList) === null || _c === void 0 ? void 0 : _c.contains(VoeocDialog.STR_CLASSNAME_SHOW_TAG)) || false; } open() { HistoryStateManager.getInstance().showNewDialog(this); } close() { HistoryStateManager.getInstance().closeLastDialog(); } } VoeocDialog.STR_CLASSNAME_DIALOG = "VOEOC_DIALOG"; VoeocDialog.STR_CLASSNAME_SHOW_TAG = "VOEOC_DIALOG_SHOW"; class HistoryStateManager { constructor() { _HistoryStateManager_showDialogList.set(this, void 0); } static getInstance() { if (!__classPrivateFieldGet(HistoryStateManager, _a, "f", _HistoryStateManager_instance)) { __classPrivateFieldSet(HistoryStateManager, _a, new HistoryStateManager(), "f", _HistoryStateManager_instance); } return __classPrivateFieldGet(HistoryStateManager, _a, "f", _HistoryStateManager_instance); } init() { __classPrivateFieldSet(this, _HistoryStateManager_showDialogList, new Stack(), "f"); window.addEventListener("popstate", () => { var _b, _c; if ((_b = __classPrivateFieldGet(this, _HistoryStateManager_showDialogList, "f")) === null || _b === void 0 ? void 0 : _b.isEmpty()) { return; } DEBUGLOG(window.history.state); if ((_c = __classPrivateFieldGet(this, _HistoryStateManager_showDialogList, "f")) === null || _c === void 0 ? void 0 : _c.peek().isShown()) { this.closeLastDialog(); } }, false); } showNewDialog(voeocDialog) { var _b, _c, _d; if (!voeocDialog.isShown()) { voeocDialog.show(); window.history.pushState(voeocDialog.getHistoryState(), (_c = (_b = voeocDialog.getHistoryState()) === null || _b === void 0 ? void 0 : _b.title) !== null && _c !== void 0 ? _c : ""); (_d = __classPrivateFieldGet(this, _HistoryStateManager_showDialogList, "f")) === null || _d === void 0 ? void 0 : _d.push(voeocDialog); } } closeLastDialog() { var _b, _c, _d, _e; if ((_b = __classPrivateFieldGet(this, _HistoryStateManager_showDialogList, "f")) === null || _b === void 0 ? void 0 : _b.isEmpty()) { return; } let hiddenDialog = (_c = __classPrivateFieldGet(this, _HistoryStateManager_showDialogList, "f")) === null || _c === void 0 ? void 0 : _c.peek(); if (hiddenDialog === null || hiddenDialog === void 0 ? void 0 : hiddenDialog.isShown()) { if (window.history.state && window.history.state.id && window.history.state.id === ((_d = hiddenDialog === null || hiddenDialog === void 0 ? void 0 : hiddenDialog.getHistoryState()) === null || _d === void 0 ? void 0 : _d.id)) { window.history.back(); return; } hiddenDialog === null || hiddenDialog === void 0 ? void 0 : hiddenDialog.hide(); (_e = __classPrivateFieldGet(this, _HistoryStateManager_showDialogList, "f")) === null || _e === void 0 ? void 0 : _e.pop(); } } } _a = HistoryStateManager, _HistoryStateManager_showDialogList = new WeakMap(); _HistoryStateManager_instance = { value: void 0 }; class SettingValue { constructor(key, defaultValue) { this.keyGM = key; this.defaultValue = defaultValue; } get value() { return GM_getValue(this.keyGM, this.defaultValue); } set value(newVal) { GM_setValue(this.keyGM, newVal); } } const settingDatas = (() => { const datas = { isClickToExpandLzlPage: new SettingValue("VOEOC_GMKEY_isClickToExpandLzlPage", true), isLongClickToExpandLzlPage: new SettingValue("VOEOC_GMKEY_isLongClickToExpandLzlPage", true), isAutoExpand: new SettingValue("VOEOC_GMKEY_isAutoExpand", true), isRemaindAutoExpand: new SettingValue("VOEOC_GMKEY_isRemaindAutoExpand", true), eachExpandSize: new SettingValue("VOEOC_GMKEY_eachExpandSize", 10), autoExpandNum: new SettingValue("VOEOC_GMKEY_autoExpandNum", 1), remaindAutoExpandSize: new SettingValue("VOEOC_GMKEY_remaindAutoExpandSize", 7), lzlCacheSize: new SettingValue("VOEOC_GMKEY_lzlCacheSize", 10), }; datas.isClickToExpandLzlPage.value = true; datas.isLongClickToExpandLzlPage.value = true; datas.lzlCacheSize.value = 10; return datas; })(); const STR_ID_SETTING_FRAME = "VOEOC-ID-SETTING-FRAME"; const STR_CLASSNAME_DIALOG_BACKGROUND = "VOEOC_DIALOG_BACKGROUND"; function SettingFrameInit(iframeUtils) { const contentDocument = iframeUtils.contentDocument; function onRangeChange() { const numNode = this.parentNode.previousElementSibling.querySelector("span"); numNode.innerHTML = this.value; } function onMulSwitchChange() { const radioElements = this.parentNode.querySelectorAll("input[type=radio]"); if (radioElements[0]) { radioElements[0].checked = this.checked; } if (radioElements[1]) { radioElements[1].checked = !this.checked; } } function bindSwitch(switchElement, bindElement) { switchElement.onchange = () => { if (switchElement.checked) { bindElement.classList.remove("disable"); } else { bindElement.classList.add("disable"); } }; switchElement.onchange(); } function getElementByName(name) { return contentDocument.querySelector(`input[name=${name}]`); } function getAllInputElements() { const allInputElements = new Map(); for (let settingKey in settingDatas) { allInputElements.set(settingKey, getElementByName(settingKey)); } return allInputElements; } (() => { const rangeElements = contentDocument.querySelectorAll("input[type=range]"); rangeElements.forEach((rangeElement) => { rangeElement.addEventListener("change", onRangeChange); rangeElement.addEventListener("oninput", onRangeChange); onRangeChange.call(rangeElement); }); const mulSwitchElements = contentDocument.querySelectorAll("input.mul_switch"); mulSwitchElements.forEach((mulSwitchElement) => { mulSwitchElement.addEventListener("change", onMulSwitchChange); onMulSwitchChange.call(mulSwitchElement); }); const allInputElements = getAllInputElements(); bindSwitch(allInputElements.get("isAutoExpand"), allInputElements.get("autoExpandNum").parentElement.parentElement); bindSwitch(allInputElements.get("isRemaindAutoExpand"), allInputElements.get("remaindAutoExpandSize").parentElement.parentElement); })(); } class SettingsDialog extends VoeocDialog { constructor(parentNode, settingDatas) { super({ title: "设置窗口", id: "SettingsDialog" }, parentNode.ownerDocument.createElement("div")); this.dialogNode.classList.add(STR_CLASSNAME_DIALOG_BACKGROUND); parentNode.appendChild(this.dialogNode); const iframeUtils = new IframeUtils(this.dialogNode, STR_ID_SETTING_FRAME); iframeUtils.iframeNode.ontouchmove = STOPPROPAGATION; iframeUtils.iframeNode.onpointermove = STOPPROPAGATION; iframeUtils.iframeNode.onscroll = STOPPROPAGATION; iframeUtils.writeDoc(HTML_SETTINGS_DIALOG); SettingFrameInit(iframeUtils); const contentDocument = iframeUtils.contentDocument; const btnSaveAndClose = contentDocument.getElementById("btnSaveAndClose"); const btnSave = contentDocument.getElementById("btnSave"); const btnClose = contentDocument.getElementById("btnClose"); const allInputElements = new Map(); const originSettingsData = new Map(Object.entries(settingDatas)); originSettingsData.forEach((settingValue, key) => { const inputElement = contentDocument.querySelector(`input[name=${key}]`); if (inputElement) { allInputElements.set(key, inputElement); SET_INPUT_ELEMENT_VALUE(inputElement, settingValue.value); } }); btnSaveAndClose.onclick = () => { btnSave.click(); btnClose.click(); window.location.reload(); }; btnSave.onclick = () => { allInputElements.forEach((element, key) => { const settingValue = originSettingsData.get(key); if (settingValue) { settingValue.value = GET_INPUT_ELEMENT_VALUE(element); } }); }; btnClose.onclick = () => { this.close(); }; } } var _CustomLzlExpandManager_instances, _CustomLzlExpandManager_showError, _CustomLzlExpandManager_startExpandAnimation, _CustomLzlExpandManager_endExpandAnimation, _CustomLzlExpandManager_destroy; const STR_TEXT_BTN_EXPAND = "展开评论"; const STR_TEXT_BTN_AFTER_EXPAND = (num) => { return `剩余${num}个评论`; }; class CustomLzlExpandManager { constructor(floorNode, expandBtnNode, floorPbData, someKey) { var _a, _b, _c, _d, _e; _CustomLzlExpandManager_instances.add(this); ASSERT(floorNode, "floorNode is null"); this.lzlInfo = { floorPbData: floorPbData, someKey: someKey, lzTagHTML: "", data_v_a: "lines-v-a", data_v_b: "lines-v-b", expandNum: 0, currentPageNum: 1, floorNum: String(floorPbData.floor), pageSize: ((_a = settingDatas.eachExpandSize) === null || _a === void 0 ? void 0 : _a.value) < 10 ? 10 : (_b = settingDatas.eachExpandSize) === null || _b === void 0 ? void 0 : _b.value, pid: floorPbData === null || floorPbData === void 0 ? void 0 : floorPbData.id, floorNode: floorNode, lzlNode: floorNode.querySelector("div.lzl-post"), expandBtnNode: expandBtnNode, expandBtnTextNode: document.createElement("span") }; this.lzlInfo.originItemNodeList = this.lzlInfo.lzlNode.getElementsByClassName("lzl-post-item"); this.lzlInfo.sampleItemNode = this.lzlInfo.originItemNodeList[0].cloneNode(true); let dvList = []; for (let dv in (_d = (_c = this.lzlInfo.originItemNodeList[0]) === null || _c === void 0 ? void 0 : _c.querySelector(".thread-text")) === null || _d === void 0 ? void 0 : _d.dataset) { dvList.push(`data-v-${dv.slice(1).replace('-', '')}`); } this.lzlInfo.data_v_a = dvList[0]; this.lzlInfo.data_v_b = dvList[1]; this.lzlInfo.lzTagHTML = ``; this.lzlInfo.expandBtnTextNode.className = "open-app-text-real"; this.lzlInfo.expandBtnTextNode.innerHTML = STR_TEXT_BTN_EXPAND; let clickFunc = this.expandLzl.bind(this); let longClickFunc = this.expandLzl.bind(this); let timeOutEvent; const TIME_OUT = 500; expandBtnNode.ontouchstart = () => { timeOutEvent = setTimeout(() => { timeOutEvent = 0; longClickFunc(); }, TIME_OUT); return false; }; expandBtnNode.ontouchend = () => { clearTimeout(timeOutEvent); if (timeOutEvent !== 0) { clickFunc(); } return false; }; expandBtnNode.ontouchmove = () => { clearTimeout(timeOutEvent); timeOutEvent = 0; }; expandBtnNode.insertBefore(this.lzlInfo.expandBtnTextNode, expandBtnNode.children[0]); if ((_e = settingDatas.isAutoExpand) === null || _e === void 0 ? void 0 : _e.value) { this.expandLzl(); } } expandLzl(isTheLast = false, waitFinishFunc) { ASSERT(this.lzlInfo.expandBtnNode, `尝试展开不存在的评论区,楼层号${this.lzlInfo.floorNum}`); const url = `${window.origin}/mg/o/getFloorData?pn=${this.lzlInfo.currentPageNum}&rn=${this.lzlInfo.pageSize}&tid=${this.lzlInfo.someKey.tid}&pid=${this.lzlInfo.pid}`; const onerror = () => { __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_endExpandAnimation).call(this); __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_showError).call(this, true); void 0; }; const abortFunc = GM_xmlhttpRequest({ method: "GET", url: url, onload: (details) => { var _a, _b, _c, _d; __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_endExpandAnimation).call(this); let floorData = undefined; let subPostList = undefined; try { floorData = JSON.parse(details.responseText); subPostList = floorData.data.sub_post_list; ASSERT(subPostList && subPostList.length !== 0, "sub_post_list为空"); } catch (e) { void 0; __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_showError).call(this, true); return; } __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_showError).call(this, false); if (this.lzlInfo.currentPageNum === 1 && this.lzlInfo.originItemNodeList && this.lzlInfo.lzlNode) { for (let i = this.lzlInfo.originItemNodeList.length - 1; i > -1; i--) { this.lzlInfo.lzlNode.removeChild(this.lzlInfo.originItemNodeList[i]); } } subPostList.forEach((subpost) => { var _a, _b; let contentHTML = ""; subpost.content.forEach((subContent) => { let itemHTML; switch (subContent.type) { case 2 : itemHTML = `${subContent.text}`; break; case 4 : if (subContent.uid === this.lzlInfo.someKey.postAuthorId) { itemHTML = ` ${subContent.text} ${this.lzlInfo.lzTagHTML} `; } else { itemHTML = ` ${subContent.text} `; } break; case 0 : default: itemHTML = `${subContent.text}`; break; } contentHTML += itemHTML; }); let newItemNode = (_a = this.lzlInfo.sampleItemNode) === null || _a === void 0 ? void 0 : _a.cloneNode(true); if (newItemNode && this.lzlInfo.expandBtnNode) { newItemNode.querySelector(".username").innerHTML = `${subpost.author.show_nickname} ${(this.lzlInfo.someKey.postAuthorId === subpost.author.id) ? this.lzlInfo.lzTagHTML : ""}:`; newItemNode.querySelector(".thread-text").innerHTML = contentHTML; (_b = this.lzlInfo.lzlNode) === null || _b === void 0 ? void 0 : _b.insertBefore(newItemNode, this.lzlInfo.expandBtnNode); } }); let pageinfo = floorData.data.page; let total_page = parseInt(pageinfo.total_page); if (total_page > this.lzlInfo.currentPageNum) { this.lzlInfo.currentPageNum++; let total_num = parseInt(pageinfo.total_num); let remaind_num = total_num - this.lzlInfo.pageSize * (this.lzlInfo.currentPageNum - 1); if (this.lzlInfo.expandBtnNode) { this.lzlInfo.expandBtnNode.children[0].innerHTML = STR_TEXT_BTN_AFTER_EXPAND(remaind_num); } if (((_a = settingDatas.isRemaindAutoExpand) === null || _a === void 0 ? void 0 : _a.value) && ((_b = settingDatas.remaindAutoExpandSize) === null || _b === void 0 ? void 0 : _b.value) > remaind_num) { if (!isTheLast) { this.expandLzl(true); } } else if (((_c = settingDatas.isAutoExpand) === null || _c === void 0 ? void 0 : _c.value) && this.lzlInfo.expandNum < ((_d = settingDatas.autoExpandNum) === null || _d === void 0 ? void 0 : _d.value)) { this.expandLzl(); } } else { __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_destroy).apply(this); } this.lzlInfo.expandNum++; }, onerror: onerror, onabort: onerror, ontimeout: onerror, }); if (abortFunc) { __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_startExpandAnimation).call(this, abortFunc.abort); } } } _CustomLzlExpandManager_instances = new WeakSet(), _CustomLzlExpandManager_showError = function _CustomLzlExpandManager_showError(isError = true) { var _a, _b; if (isError) { (_a = this.lzlInfo.expandBtnTextNode) === null || _a === void 0 ? void 0 : _a.classList.add("error"); } else { (_b = this.lzlInfo.expandBtnTextNode) === null || _b === void 0 ? void 0 : _b.classList.remove("error"); } }, _CustomLzlExpandManager_startExpandAnimation = function _CustomLzlExpandManager_startExpandAnimation(abortFunc) { if (this.lzlInfo.expandBtnNode) { this.lzlInfo.expandBtnNode.classList.add("loading"); } this.expandTimeoutTimer = setTimeout(() => { __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_endExpandAnimation).call(this); __classPrivateFieldGet(this, _CustomLzlExpandManager_instances, "m", _CustomLzlExpandManager_showError).call(this, true); void 0; abortFunc(); }, 5000); }, _CustomLzlExpandManager_endExpandAnimation = function _CustomLzlExpandManager_endExpandAnimation() { if (this.lzlInfo.expandBtnNode) { this.lzlInfo.expandBtnNode.classList.remove("loading"); } if (this.expandTimeoutTimer) { clearTimeout(this.expandTimeoutTimer); this.expandTimeoutTimer = undefined; } }, _CustomLzlExpandManager_destroy = function _CustomLzlExpandManager_destroy() { var _a; try { if (this.lzlInfo.expandBtnNode) { this.lzlInfo.expandBtnNode.style.display = "none"; (_a = this.lzlInfo.expandBtnNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.lzlInfo.expandBtnNode); this.lzlInfo.expandBtnNode = undefined; } } finally { } }; const SCRIPT_ALREADY_LOAD_TAG = "VOEOC_SCRIPT_ALREADY_LOAD_TAG_BAIDU_TIEBA"; if (window[SCRIPT_ALREADY_LOAD_TAG]) { throw new Error(SCRIPT_ALREADY_LOAD_TAG); } window[SCRIPT_ALREADY_LOAD_TAG] = true; let settingDialog; let mainPage; const HIDE_MAIN_PAGE = (() => { let timer = undefined; GM_addStyle(`html {transition: opacity 0.4s}`); let styleElement; return (isHidden = true) => { if (styleElement) { styleElement.remove(); styleElement = undefined; } if (isHidden) { styleElement = GM_addStyle(`html {opacity: 0.2;}`); clearTimeout(timer); timer = setTimeout(() => { HIDE_MAIN_PAGE(false); }, 5000); } }; })(); const REGISTER_MENUCOMMAND = () => { GM_registerMenuCommand(`设置`, () => { settingDialog === null || settingDialog === void 0 ? void 0 : settingDialog.open(); }, "VOEOC_MENU_ACCESS_KEY_SETTINGS"); }; (() => { switch (GET_PAGE_TYPE()) { case PAGE_TYPE.MAINPAGE: HIDE_MAIN_PAGE(true); GM_addStyle(CSS_REMOVE); GM_addStyle(CSS_BAIDU); mainPage = new MainPage(); mainPage.listenReady(() => { REGISTER_MENUCOMMAND(); }); mainPage.onEnterFinalPage = () => { CommonSearcher.search(".nav-bar-top").then((navbar) => { const id = "VOEOC-ID-SETTINGBTNNODE"; if (document.getElementById(id)) { return; } let settingBtnNode = document.createElement("div"); settingBtnNode.id = id; settingBtnNode.className = "lzl-nav-btn"; settingBtnNode.style.cssText = "background-color:transparent !important;position:fixed;margin: 0.1rem !important;"; settingBtnNode.innerHTML = "设置"; settingBtnNode.onclick = () => { settingDialog === null || settingDialog === void 0 ? void 0 : settingDialog.open(); }; navbar.appendChild(settingBtnNode); settingBtnNode.style.margin = "0"; settingBtnNode.style.marginLeft = "0.5rem"; HIDE_MAIN_PAGE(false); VoeocDialog.initHistoryStateManager(); settingDialog = new SettingsDialog(document.body, settingDatas); CommonSearcher.search(".post-show-more").then((btnShowMore) => { btnShowMore.click(); }); }); }; mainPage.onNewFloorAdded = (floorNode) => { if (floorNode.classList.contains(STR_VOEOCMARK)) { return; } floorNode.classList.add(STR_VOEOCMARK); AUTO_CATCH_ERROR(() => { let expandBtnNode = floorNode.querySelector(".open-app-guide"); if (!expandBtnNode) { return; } let floorinfoNode = floorNode.querySelector(".floor-info"); if (!floorinfoNode) { throw new Error("楼层数节点不存在"); } const floorNum = MATCH_REG(RegExp(/第(\d+)楼/, 'i'), floorinfoNode.innerHTML); if (!floorNum) { throw new Error("无法获取楼层数"); } new CustomLzlExpandManager(floorNode, expandBtnNode, mainPage.storagePageData.floorDataList.get(floorNum), mainPage.storagePageData.someKey); }); }; mainPage.tryGetFirstFloorAndGoPostPage(); break; case PAGE_TYPE.POSTPAGE: HIDE_MAIN_PAGE(true); MainPage.REPLACE_HASH(""); break; case PAGE_TYPE.LZLPAGE: return; default: return; } })(); })();