您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
有时候用手机的浏览器打开百度贴吧,只想看一眼就走,并不想打开APP,这个脚本用于帮助用户自动展开楼层。注意:只支持手机浏览器,测试环境为Iceraven+Tampermonkey
当前为
// ==UserScript== // @name 手机百度贴吧自动展开楼层 // @namespace http://tampermonkey.net/ // @homepage http://greasyfork.icu/scripts/445657 // @version 3.0 // @description 有时候用手机的浏览器打开百度贴吧,只想看一眼就走,并不想打开APP,这个脚本用于帮助用户自动展开楼层。注意:只支持手机浏览器,测试环境为Iceraven+Tampermonkey // @author voeoc // @match https://tieba.baidu.com/p/* // @match https://jump2.bdimg.com/p/* // @match https://tiebac.baidu.com/p/* // @connect https://tieba.baidu.com/mg/o/getFloorData // @connect https://jump2.bdimg.com/mg/o/getFloorData // @connect https://tiebac.baidu.com/mg/o/getFloorData // @icon https://tieba.baidu.com/favicon.ico // @resource swal_css https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark/dark.css // @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 // @license MIT // ==/UserScript== //引用https://cdn.jsdelivr.net/npm/sweetalert2/dist/sweetalert2.min.js !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Sweetalert2=t()}(this,function(){"use strict";const q="SweetAlert2:",H=e=>e.charAt(0).toUpperCase()+e.slice(1),i=e=>Array.prototype.slice.call(e),a=e=>{console.warn("".concat(q," ").concat("object"==typeof e?e.join(" "):e))},l=e=>{console.error("".concat(q," ").concat(e))},V=[],N=(e,t)=>{e='"'.concat(e,'" is deprecated and will be removed in the next major release. Please use "').concat(t,'" instead.'),V.includes(e)||(V.push(e),a(e))},R=e=>"function"==typeof e?e():e,F=e=>e&&"function"==typeof e.toPromise,u=e=>F(e)?e.toPromise():Promise.resolve(e),U=e=>e&&Promise.resolve(e)===e,r={title:"",titleText:"",text:"",html:"",footer:"",icon:void 0,iconColor:void 0,iconHtml:void 0,template:void 0,toast:!1,showClass:{popup:"swal2-show",backdrop:"swal2-backdrop-show",icon:"swal2-icon-show"},hideClass:{popup:"swal2-hide",backdrop:"swal2-backdrop-hide",icon:"swal2-icon-hide"},customClass:{},target:"body",color:void 0,backdrop:!0,heightAuto:!0,allowOutsideClick:!0,allowEscapeKey:!0,allowEnterKey:!0,stopKeydownPropagation:!0,keydownListenerCapture:!1,showConfirmButton:!0,showDenyButton:!1,showCancelButton:!1,preConfirm:void 0,preDeny:void 0,confirmButtonText:"OK",confirmButtonAriaLabel:"",confirmButtonColor:void 0,denyButtonText:"No",denyButtonAriaLabel:"",denyButtonColor:void 0,cancelButtonText:"Cancel",cancelButtonAriaLabel:"",cancelButtonColor:void 0,buttonsStyling:!0,reverseButtons:!1,focusConfirm:!0,focusDeny:!1,focusCancel:!1,returnFocus:!0,showCloseButton:!1,closeButtonHtml:"×",closeButtonAriaLabel:"Close this dialog",loaderHtml:"",showLoaderOnConfirm:!1,showLoaderOnDeny:!1,imageUrl:void 0,imageWidth:void 0,imageHeight:void 0,imageAlt:"",timer:void 0,timerProgressBar:!1,width:void 0,padding:void 0,background:void 0,input:void 0,inputPlaceholder:"",inputLabel:"",inputValue:"",inputOptions:{},inputAutoTrim:!0,inputAttributes:{},inputValidator:void 0,returnInputValueOnDeny:!1,validationMessage:void 0,grow:!1,position:"center",progressSteps:[],currentProgressStep:void 0,progressStepsDistance:void 0,willOpen:void 0,didOpen:void 0,didRender:void 0,willClose:void 0,didClose:void 0,didDestroy:void 0,scrollbarPadding:!0},W=["allowEscapeKey","allowOutsideClick","background","buttonsStyling","cancelButtonAriaLabel","cancelButtonColor","cancelButtonText","closeButtonAriaLabel","closeButtonHtml","color","confirmButtonAriaLabel","confirmButtonColor","confirmButtonText","currentProgressStep","customClass","denyButtonAriaLabel","denyButtonColor","denyButtonText","didClose","didDestroy","footer","hideClass","html","icon","iconColor","iconHtml","imageAlt","imageHeight","imageUrl","imageWidth","preConfirm","preDeny","progressSteps","returnFocus","reverseButtons","showCancelButton","showCloseButton","showConfirmButton","showDenyButton","text","title","titleText","willClose"],z={},_=["allowOutsideClick","allowEnterKey","backdrop","focusConfirm","focusDeny","focusCancel","returnFocus","heightAuto","keydownListenerCapture"],K=e=>Object.prototype.hasOwnProperty.call(r,e),Y=e=>-1!==W.indexOf(e),Z=e=>z[e],J=e=>{!e.backdrop&&e.allowOutsideClick&&a('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');for(const n in e)t=n,K(t)||a('Unknown parameter "'.concat(t,'"')),e.toast&&(t=n,_.includes(t)&&a('The parameter "'.concat(t,'" is incompatible with toasts'))),t=n,Z(t)&&N(t,Z(t));var t};var e=e=>{const t={};for(const n in e)t[e[n]]="swal2-"+e[n];return t};const p=e(["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","show","hide","close","title","html-container","actions","confirm","deny","cancel","default-outline","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error"]),o=e(["success","warning","info","question","error"]),m=()=>document.body.querySelector(".".concat(p.container)),t=e=>{const t=m();return t?t.querySelector(e):null},n=e=>t(".".concat(e)),g=()=>n(p.popup),s=()=>n(p.icon),X=()=>n(p.title),$=()=>n(p["html-container"]),G=()=>n(p.image),Q=()=>n(p["progress-steps"]),ee=()=>n(p["validation-message"]),h=()=>t(".".concat(p.actions," .").concat(p.confirm)),f=()=>t(".".concat(p.actions," .").concat(p.deny));const d=()=>t(".".concat(p.loader)),b=()=>t(".".concat(p.actions," .").concat(p.cancel)),v=()=>n(p.actions),te=()=>n(p.footer),ne=()=>n(p["timer-progress-bar"]),oe=()=>n(p.close),ie=()=>{const e=i(g().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])')).sort((e,t)=>{e=parseInt(e.getAttribute("tabindex")),t=parseInt(t.getAttribute("tabindex"));return t<e?1:e<t?-1:0});var t=i(g().querySelectorAll('\n a[href],\n area[href],\n input:not([disabled]),\n select:not([disabled]),\n textarea:not([disabled]),\n button:not([disabled]),\n iframe,\n object,\n embed,\n [tabindex="0"],\n [contenteditable],\n audio[controls],\n video[controls],\n summary\n')).filter(e=>"-1"!==e.getAttribute("tabindex"));return(t=>{const n=[];for(let e=0;e<t.length;e++)-1===n.indexOf(t[e])&&n.push(t[e]);return n})(e.concat(t)).filter(e=>E(e))},ae=()=>w(document.body,p.shown)&&!w(document.body,p["toast-shown"])&&!w(document.body,p["no-backdrop"]),re=()=>g()&&w(g(),p.toast);function se(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1];const n=ne();E(n)&&(t&&(n.style.transition="none",n.style.width="100%"),setTimeout(()=>{n.style.transition="width ".concat(e/1e3,"s linear"),n.style.width="0%"},10))}const c={previousBodyPadding:null},y=(t,e)=>{if(t.textContent="",e){const n=new DOMParser,o=n.parseFromString(e,"text/html");i(o.querySelector("head").childNodes).forEach(e=>{t.appendChild(e)}),i(o.querySelector("body").childNodes).forEach(e=>{t.appendChild(e)})}},w=(t,e)=>{if(!e)return!1;var n=e.split(/\s+/);for(let e=0;e<n.length;e++)if(!t.classList.contains(n[e]))return!1;return!0},ce=(t,n)=>{i(t.classList).forEach(e=>{Object.values(p).includes(e)||Object.values(o).includes(e)||Object.values(n.showClass).includes(e)||t.classList.remove(e)})},C=(e,t,n)=>{if(ce(e,t),t.customClass&&t.customClass[n]){if("string"!=typeof t.customClass[n]&&!t.customClass[n].forEach)return a("Invalid type of customClass.".concat(n,'! Expected string or iterable object, got "').concat(typeof t.customClass[n],'"'));A(e,t.customClass[n])}},le=(e,t)=>{if(!t)return null;switch(t){case"select":case"textarea":case"file":return e.querySelector(".".concat(p.popup," > .").concat(p[t]));case"checkbox":return e.querySelector(".".concat(p.popup," > .").concat(p.checkbox," input"));case"radio":return e.querySelector(".".concat(p.popup," > .").concat(p.radio," input:checked"))||e.querySelector(".".concat(p.popup," > .").concat(p.radio," input:first-child"));case"range":return e.querySelector(".".concat(p.popup," > .").concat(p.range," input"));default:return e.querySelector(".".concat(p.popup," > .").concat(p.input))}},ue=e=>{var t;e.focus(),"file"!==e.type&&(t=e.value,e.value="",e.value=t)},de=(e,t,n)=>{e&&t&&(t="string"==typeof t?t.split(/\s+/).filter(Boolean):t).forEach(t=>{Array.isArray(e)?e.forEach(e=>{n?e.classList.add(t):e.classList.remove(t)}):n?e.classList.add(t):e.classList.remove(t)})},A=(e,t)=>{de(e,t,!0)},k=(e,t)=>{de(e,t,!1)},P=(e,t)=>{var n=i(e.childNodes);for(let e=0;e<n.length;e++)if(w(n[e],t))return n[e]},pe=(e,t,n)=>{(n=n==="".concat(parseInt(n))?parseInt(n):n)||0===parseInt(n)?e.style[t]="number"==typeof n?"".concat(n,"px"):n:e.style.removeProperty(t)},B=function(e){e.style.display=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"flex"},x=e=>{e.style.display="none"},me=(e,t,n,o)=>{const i=e.querySelector(t);i&&(i.style[n]=o)},ge=(e,t,n)=>{t?B(e,n):x(e)},E=e=>!(!e||!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)),he=()=>!E(h())&&!E(f())&&!E(b()),fe=e=>!!(e.scrollHeight>e.clientHeight),be=e=>{const t=window.getComputedStyle(e);var e=parseFloat(t.getPropertyValue("animation-duration")||"0"),n=parseFloat(t.getPropertyValue("transition-duration")||"0");return 0<e||0<n},ve=()=>"undefined"==typeof window||"undefined"==typeof document,ye=100,T={},we=()=>{T.previousActiveElement&&T.previousActiveElement.focus?(T.previousActiveElement.focus(),T.previousActiveElement=null):document.body&&document.body.focus()},Ce=o=>new Promise(e=>{if(!o)return e();var t=window.scrollX,n=window.scrollY;T.restoreFocusTimeout=setTimeout(()=>{we(),e()},ye),window.scrollTo(t,n)}),Ae='\n <div aria-labelledby="'.concat(p.title,'" aria-describedby="').concat(p["html-container"],'" class="').concat(p.popup,'" tabindex="-1">\n <button type="button" class="').concat(p.close,'"></button>\n <ul class="').concat(p["progress-steps"],'"></ul>\n <div class="').concat(p.icon,'"></div>\n <img class="').concat(p.image,'" />\n <h2 class="').concat(p.title,'" id="').concat(p.title,'"></h2>\n <div class="').concat(p["html-container"],'" id="').concat(p["html-container"],'"></div>\n <input class="').concat(p.input,'" />\n <input type="file" class="').concat(p.file,'" />\n <div class="').concat(p.range,'">\n <input type="range" />\n <output></output>\n </div>\n <select class="').concat(p.select,'"></select>\n <div class="').concat(p.radio,'"></div>\n <label for="').concat(p.checkbox,'" class="').concat(p.checkbox,'">\n <input type="checkbox" />\n <span class="').concat(p.label,'"></span>\n </label>\n <textarea class="').concat(p.textarea,'"></textarea>\n <div class="').concat(p["validation-message"],'" id="').concat(p["validation-message"],'"></div>\n <div class="').concat(p.actions,'">\n <div class="').concat(p.loader,'"></div>\n <button type="button" class="').concat(p.confirm,'"></button>\n <button type="button" class="').concat(p.deny,'"></button>\n <button type="button" class="').concat(p.cancel,'"></button>\n </div>\n <div class="').concat(p.footer,'"></div>\n <div class="').concat(p["timer-progress-bar-container"],'">\n <div class="').concat(p["timer-progress-bar"],'"></div>\n </div>\n </div>\n').replace(/(^|\n)\s*/g,""),ke=()=>{const e=m();return!!e&&(e.remove(),k([document.documentElement,document.body],[p["no-backdrop"],p["toast-shown"],p["has-column"]]),!0)},S=()=>{T.currentInstance.resetValidationMessage()},Pe=()=>{const e=g(),t=P(e,p.input),n=P(e,p.file),o=e.querySelector(".".concat(p.range," input")),i=e.querySelector(".".concat(p.range," output")),a=P(e,p.select),r=e.querySelector(".".concat(p.checkbox," input")),s=P(e,p.textarea);t.oninput=S,n.onchange=S,a.onchange=S,r.onchange=S,s.oninput=S,o.oninput=()=>{S(),i.value=o.value},o.onchange=()=>{S(),o.nextSibling.value=o.value}},Be=e=>"string"==typeof e?document.querySelector(e):e,xe=e=>{const t=g();t.setAttribute("role",e.toast?"alert":"dialog"),t.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||t.setAttribute("aria-modal","true")},Ee=e=>{"rtl"===window.getComputedStyle(e).direction&&A(m(),p.rtl)},Te=(e,t)=>{if(e instanceof HTMLElement)t.appendChild(e);else if("object"==typeof e){var n=e,o=t;if(n.jquery)Se(o,n);else y(o,n.toString())}else e&&y(t,e)},Se=(t,n)=>{if(t.textContent="",0 in n)for(let e=0;e in n;e++)t.appendChild(n[e].cloneNode(!0));else t.appendChild(n.cloneNode(!0))},Le=(()=>{if(ve())return!1;var e=document.createElement("div"),t={WebkitAnimation:"webkitAnimationEnd",animation:"animationend"};for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&void 0!==e.style[n])return t[n];return!1})(),Oe=(e,t)=>{var n,o,i,a,r,s=v(),c=d();(t.showConfirmButton||t.showDenyButton||t.showCancelButton?B:x)(s),C(s,t,"actions"),s=s,n=c,o=t,i=h(),a=f(),r=b(),je(i,"confirm",o),je(a,"deny",o),je(r,"cancel",o),function(e,t,n,o){if(!o.buttonsStyling)return k([e,t,n],p.styled);A([e,t,n],p.styled),o.confirmButtonColor&&(e.style.backgroundColor=o.confirmButtonColor,A(e,p["default-outline"]));o.denyButtonColor&&(t.style.backgroundColor=o.denyButtonColor,A(t,p["default-outline"]));o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,A(n,p["default-outline"]))}(i,a,r,o),o.reverseButtons&&(o.toast?(s.insertBefore(r,i),s.insertBefore(a,i)):(s.insertBefore(r,n),s.insertBefore(a,n),s.insertBefore(i,n))),y(c,t.loaderHtml),C(c,t,"loader")};function je(e,t,n){ge(e,n["show".concat(H(t),"Button")],"inline-block"),y(e,n["".concat(t,"ButtonText")]),e.setAttribute("aria-label",n["".concat(t,"ButtonAriaLabel")]),e.className=p[t],C(e,n,"".concat(t,"Button")),A(e,n["".concat(t,"ButtonClass")])}const Me=(e,t)=>{var n,o,i=m();i&&(o=i,"string"==typeof(n=t.backdrop)?o.style.background=n:n||A([document.documentElement,document.body],p["no-backdrop"]),o=i,(n=t.position)in p?A(o,p[n]):(a('The "position" parameter is not valid, defaulting to "center"'),A(o,p.center)),n=i,(o=t.grow)&&"string"==typeof o&&(o="grow-".concat(o))in p&&A(n,p[o]),C(i,t,"container"))};var L={awaitingPromise:new WeakMap,promise:new WeakMap,innerParams:new WeakMap,domCache:new WeakMap};const De=["input","file","range","select","radio","checkbox","textarea"],Ie=(e,r)=>{const s=g();var t,e=L.innerParams.get(e);const c=!e||r.input!==e.input;De.forEach(e=>{var t=p[e];const n=P(s,t);{var o=r.inputAttributes;const i=le(g(),e);if(i){qe(i);for(const a in o)i.setAttribute(a,o[a])}}n.className=t,c&&x(n)}),r.input&&(c&&(e=>{if(!O[e.input])return l('Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "'.concat(e.input,'"'));const t=Ne(e.input),n=O[e.input](t,e);B(n),setTimeout(()=>{ue(n)})})(r),e=r,t=Ne(e.input),e.customClass&&A(t,e.customClass.input))},qe=t=>{for(let e=0;e<t.attributes.length;e++){var n=t.attributes[e].name;["type","value","style"].includes(n)||t.removeAttribute(n)}},He=(e,t)=>{e.placeholder&&!t.inputPlaceholder||(e.placeholder=t.inputPlaceholder)},Ve=(e,t,n)=>{if(n.inputLabel){e.id=p.input;const i=document.createElement("label");var o=p["input-label"];i.setAttribute("for",e.id),i.className=o,A(i,n.customClass.inputLabel),i.innerText=n.inputLabel,t.insertAdjacentElement("beforebegin",i)}},Ne=e=>{e=p[e]||p.input;return P(g(),e)},O={},Re=(O.text=O.email=O.password=O.number=O.tel=O.url=(e,t)=>("string"==typeof t.inputValue||"number"==typeof t.inputValue?e.value=t.inputValue:U(t.inputValue)||a('Unexpected type of inputValue! Expected "string", "number" or "Promise", got "'.concat(typeof t.inputValue,'"')),Ve(e,e,t),He(e,t),e.type=t.input,e),O.file=(e,t)=>(Ve(e,e,t),He(e,t),e),O.range=(e,t)=>{const n=e.querySelector("input"),o=e.querySelector("output");return n.value=t.inputValue,n.type=t.input,o.value=t.inputValue,Ve(n,e,t),e},O.select=(e,t)=>{if(e.textContent="",t.inputPlaceholder){const n=document.createElement("option");y(n,t.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,e.appendChild(n)}return Ve(e,e,t),e},O.radio=e=>(e.textContent="",e),O.checkbox=(e,t)=>{const n=le(g(),"checkbox");n.value="1",n.id=p.checkbox,n.checked=Boolean(t.inputValue);var o=e.querySelector("span");return y(o,t.inputPlaceholder),e},O.textarea=(n,e)=>{n.value=e.inputValue,He(n,e),Ve(n,n,e);return setTimeout(()=>{if("MutationObserver"in window){const t=parseInt(window.getComputedStyle(g()).width);new MutationObserver(()=>{var e=n.offsetWidth+(e=n,parseInt(window.getComputedStyle(e).marginLeft)+parseInt(window.getComputedStyle(e).marginRight));e>t?g().style.width="".concat(e,"px"):g().style.width=null}).observe(n,{attributes:!0,attributeFilter:["style"]})}}),n},(e,t)=>{const n=$();C(n,t,"htmlContainer"),t.html?(Te(t.html,n),B(n,"block")):t.text?(n.textContent=t.text,B(n,"block")):x(n),Ie(e,t)}),Fe=(e,t)=>{var n=te();ge(n,t.footer),t.footer&&Te(t.footer,n),C(n,t,"footer")},Ue=(e,t)=>{const n=oe();y(n,t.closeButtonHtml),C(n,t,"closeButton"),ge(n,t.showCloseButton),n.setAttribute("aria-label",t.closeButtonAriaLabel)},We=(e,t)=>{var e=L.innerParams.get(e),n=s();return e&&t.icon===e.icon?(Ze(n,t),void ze(n,t)):t.icon||t.iconHtml?t.icon&&-1===Object.keys(o).indexOf(t.icon)?(l('Unknown icon! Expected "success", "error", "warning", "info" or "question", got "'.concat(t.icon,'"')),x(n)):(B(n),Ze(n,t),ze(n,t),void A(n,t.showClass.icon)):x(n)},ze=(e,t)=>{for(const n in o)t.icon!==n&&k(e,o[n]);A(e,o[t.icon]),Je(e,t),_e(),C(e,t,"icon")},_e=()=>{const e=g();var t=window.getComputedStyle(e).getPropertyValue("background-color");const n=e.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix");for(let e=0;e<n.length;e++)n[e].style.backgroundColor=t},Ke='\n <div class="swal2-success-circular-line-left"></div>\n <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>\n <div class="swal2-success-ring"></div> <div class="swal2-success-fix"></div>\n <div class="swal2-success-circular-line-right"></div>\n',Ye='\n <span class="swal2-x-mark">\n <span class="swal2-x-mark-line-left"></span>\n <span class="swal2-x-mark-line-right"></span>\n </span>\n',Ze=(e,t)=>{var n;e.textContent="",t.iconHtml?y(e,Xe(t.iconHtml)):"success"===t.icon?y(e,Ke):"error"===t.icon?y(e,Ye):(n={question:"?",warning:"!",info:"i"},y(e,Xe(n[t.icon])))},Je=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(const n of[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"])me(e,n,"backgroundColor",t.iconColor);me(e,".swal2-success-ring","borderColor",t.iconColor)}},Xe=e=>'<div class="'.concat(p["icon-content"],'">').concat(e,"</div>"),$e=(e,t)=>{const n=G();if(!t.imageUrl)return x(n);B(n,""),n.setAttribute("src",t.imageUrl),n.setAttribute("alt",t.imageAlt),pe(n,"width",t.imageWidth),pe(n,"height",t.imageHeight),n.className=p.image,C(n,t,"image")},Ge=(e,o)=>{const i=Q();if(!o.progressSteps||0===o.progressSteps.length)return x(i);B(i),i.textContent="",o.currentProgressStep>=o.progressSteps.length&&a("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.progressSteps.forEach((e,t)=>{e=e,n=document.createElement("li"),A(n,p["progress-step"]),y(n,e);var n,e=n;i.appendChild(e),t===o.currentProgressStep&&A(e,p["active-progress-step"]),t!==o.progressSteps.length-1&&(n=(e=>{const t=document.createElement("li");return A(t,p["progress-step-line"]),e.progressStepsDistance&&(t.style.width=e.progressStepsDistance),t})(o),i.appendChild(n))})},Qe=(e,t)=>{const n=X();ge(n,t.title||t.titleText,"block"),t.title&&Te(t.title,n),t.titleText&&(n.innerText=t.titleText),C(n,t,"title")},et=(e,t)=>{var n=m();const o=g();t.toast?(pe(n,"width",t.width),o.style.width="100%",o.insertBefore(d(),s())):pe(o,"width",t.width),pe(o,"padding",t.padding),t.color&&(o.style.color=t.color),t.background&&(o.style.background=t.background),x(ee());n=o;(n.className="".concat(p.popup," ").concat(E(n)?t.showClass.popup:""),t.toast)?(A([document.documentElement,document.body],p["toast-shown"]),A(n,p.toast)):A(n,p.modal);C(n,t,"popup"),"string"==typeof t.customClass&&A(n,t.customClass);t.icon&&A(n,p["icon-".concat(t.icon)])},tt=(e,t)=>{et(e,t),Me(e,t),Ge(e,t),We(e,t),$e(e,t),Qe(e,t),Ue(e,t),Re(e,t),Oe(e,t),Fe(e,t),"function"==typeof t.didRender&&t.didRender(g())},j=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),nt=()=>{const e=i(document.body.children);e.forEach(e=>{e===m()||e.contains(m())||(e.hasAttribute("aria-hidden")&&e.setAttribute("data-previous-aria-hidden",e.getAttribute("aria-hidden")),e.setAttribute("aria-hidden","true"))})},ot=()=>{const e=i(document.body.children);e.forEach(e=>{e.hasAttribute("data-previous-aria-hidden")?(e.setAttribute("aria-hidden",e.getAttribute("data-previous-aria-hidden")),e.removeAttribute("data-previous-aria-hidden")):e.removeAttribute("aria-hidden")})},it=["swal-title","swal-html","swal-footer"],at=e=>{const n={};return i(e.querySelectorAll("swal-param")).forEach(e=>{M(e,["name","value"]);var t=e.getAttribute("name"),e=e.getAttribute("value");"boolean"==typeof r[t]&&"false"===e&&(n[t]=!1),"object"==typeof r[t]&&(n[t]=JSON.parse(e))}),n},rt=e=>{const n={};return i(e.querySelectorAll("swal-button")).forEach(e=>{M(e,["type","color","aria-label"]);var t=e.getAttribute("type");n["".concat(t,"ButtonText")]=e.innerHTML,n["show".concat(H(t),"Button")]=!0,e.hasAttribute("color")&&(n["".concat(t,"ButtonColor")]=e.getAttribute("color")),e.hasAttribute("aria-label")&&(n["".concat(t,"ButtonAriaLabel")]=e.getAttribute("aria-label"))}),n},st=e=>{const t={},n=e.querySelector("swal-image");return n&&(M(n,["src","width","height","alt"]),n.hasAttribute("src")&&(t.imageUrl=n.getAttribute("src")),n.hasAttribute("width")&&(t.imageWidth=n.getAttribute("width")),n.hasAttribute("height")&&(t.imageHeight=n.getAttribute("height")),n.hasAttribute("alt")&&(t.imageAlt=n.getAttribute("alt"))),t},ct=e=>{const t={},n=e.querySelector("swal-icon");return n&&(M(n,["type","color"]),n.hasAttribute("type")&&(t.icon=n.getAttribute("type")),n.hasAttribute("color")&&(t.iconColor=n.getAttribute("color")),t.iconHtml=n.innerHTML),t},lt=e=>{const n={},t=e.querySelector("swal-input");t&&(M(t,["type","label","placeholder","value"]),n.input=t.getAttribute("type")||"text",t.hasAttribute("label")&&(n.inputLabel=t.getAttribute("label")),t.hasAttribute("placeholder")&&(n.inputPlaceholder=t.getAttribute("placeholder")),t.hasAttribute("value")&&(n.inputValue=t.getAttribute("value")));e=e.querySelectorAll("swal-input-option");return e.length&&(n.inputOptions={},i(e).forEach(e=>{M(e,["value"]);var t=e.getAttribute("value"),e=e.innerHTML;n.inputOptions[t]=e})),n},ut=(e,t)=>{const n={};for(const o in t){const i=t[o],a=e.querySelector(i);a&&(M(a,[]),n[i.replace(/^swal-/,"")]=a.innerHTML.trim())}return n},dt=e=>{const t=it.concat(["swal-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);i(e.children).forEach(e=>{e=e.tagName.toLowerCase();-1===t.indexOf(e)&&a("Unrecognized element <".concat(e,">"))})},M=(t,n)=>{i(t.attributes).forEach(e=>{-1===n.indexOf(e.name)&&a(['Unrecognized attribute "'.concat(e.name,'" on <').concat(t.tagName.toLowerCase(),">."),"".concat(n.length?"Allowed attributes are: ".concat(n.join(", ")):"To set the value, use HTML within the element.")])})};var pt={email:(e,t)=>/^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid email address"),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid URL")};function mt(e){(t=e).inputValidator||Object.keys(pt).forEach(e=>{t.input===e&&(t.inputValidator=pt[e])}),e.showLoaderOnConfirm&&!e.preConfirm&&a("showLoaderOnConfirm is set to true, but preConfirm is not defined.\nshowLoaderOnConfirm should be used together with preConfirm, see usage example:\nhttps://sweetalert2.github.io/#ajax-request"),(n=e).target&&("string"!=typeof n.target||document.querySelector(n.target))&&("string"==typeof n.target||n.target.appendChild)||(a('Target parameter is not valid, defaulting to "body"'),n.target="body"),"string"==typeof e.title&&(e.title=e.title.split("\n").join("<br />"));var t,n=e,e=ke();if(ve())l("SweetAlert2 requires document to initialize");else{const o=document.createElement("div"),i=(o.className=p.container,e&&A(o,p["no-transition"]),y(o,Ae),Be(n.target));i.appendChild(o),xe(n),Ee(i),Pe()}}class gt{constructor(e,t){this.callback=e,this.remaining=t,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=(new Date).getTime()-this.started.getTime()),this.remaining}increase(e){var t=this.running;return t&&this.stop(),this.remaining+=e,t&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}}const ht=()=>{null===c.previousBodyPadding&&document.body.scrollHeight>window.innerHeight&&(c.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight="".concat(c.previousBodyPadding+(()=>{const e=document.createElement("div");e.className=p["scrollbar-measure"],document.body.appendChild(e);var t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t})(),"px"))},ft=()=>{null!==c.previousBodyPadding&&(document.body.style.paddingRight="".concat(c.previousBodyPadding,"px"),c.previousBodyPadding=null)},bt=()=>{if((/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream||"MacIntel"===navigator.platform&&1<navigator.maxTouchPoints)&&!w(document.body,p.iosfix)){var e,t=document.body.scrollTop;document.body.style.top="".concat(-1*t,"px"),A(document.body,p.iosfix);{const n=m();let t;n.ontouchstart=e=>{t=vt(e)},n.ontouchmove=e=>{t&&(e.preventDefault(),e.stopPropagation())}}{const o=navigator.userAgent,i=!!o.match(/iPad/i)||!!o.match(/iPhone/i),a=!!o.match(/WebKit/i),r=i&&a&&!o.match(/CriOS/i);r&&(e=44,g().scrollHeight>window.innerHeight-44&&(m().style.paddingBottom="".concat(44,"px")))}}},vt=e=>{var t,n=e.target,o=m();return!((t=e).touches&&t.touches.length&&"stylus"===t.touches[0].touchType||(t=e).touches&&1<t.touches.length)&&(n===o||!(fe(o)||"INPUT"===n.tagName||"TEXTAREA"===n.tagName||fe($())&&$().contains(n)))},yt=()=>{var e;w(document.body,p.iosfix)&&(e=parseInt(document.body.style.top,10),k(document.body,p.iosfix),document.body.style.top="",document.body.scrollTop=-1*e)},wt=10,Ct=e=>{const t=g();if(e.target===t){const n=m();t.removeEventListener(Le,Ct),n.style.overflowY="auto"}},At=(e,t)=>{Le&&be(t)?(e.style.overflowY="hidden",t.addEventListener(Le,Ct)):e.style.overflowY="auto"},kt=(e,t,n)=>{bt(),t&&"hidden"!==n&&ht(),setTimeout(()=>{e.scrollTop=0})},Pt=(e,t,n)=>{A(e,n.showClass.backdrop),t.style.setProperty("opacity","0","important"),B(t,"grid"),setTimeout(()=>{A(t,n.showClass.popup),t.style.removeProperty("opacity")},wt),A([document.documentElement,document.body],p.shown),n.heightAuto&&n.backdrop&&!n.toast&&A([document.documentElement,document.body],p["height-auto"])},D=e=>{let t=g();t||new wn,t=g();var n=d();if(re())x(s());else{var o=t;const i=v(),a=d();!e&&E(h())&&(e=h());B(i),e&&(x(e),a.setAttribute("data-button-to-replace",e.className));a.parentNode.insertBefore(a,e),A([o,i],p.loading)}B(n),t.setAttribute("data-loading",!0),t.setAttribute("aria-busy",!0),t.focus()},Bt=(t,n)=>{const o=g(),i=e=>Et[n.input](o,Tt(e),n);F(n.inputOptions)||U(n.inputOptions)?(D(h()),u(n.inputOptions).then(e=>{t.hideLoading(),i(e)})):"object"==typeof n.inputOptions?i(n.inputOptions):l("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(typeof n.inputOptions))},xt=(t,n)=>{const o=t.getInput();x(o),u(n.inputValue).then(e=>{o.value="number"===n.input?parseFloat(e)||0:"".concat(e),B(o),o.focus(),t.hideLoading()}).catch(e=>{l("Error in inputValue promise: ".concat(e)),o.value="",B(o),o.focus(),t.hideLoading()})},Et={select:(e,t,i)=>{const a=P(e,p.select),r=(e,t,n)=>{const o=document.createElement("option");o.value=n,y(o,t),o.selected=St(n,i.inputValue),e.appendChild(o)};t.forEach(e=>{var t=e[0];const n=e[1];if(Array.isArray(n)){const o=document.createElement("optgroup");o.label=t,o.disabled=!1,a.appendChild(o),n.forEach(e=>r(o,e[1],e[0]))}else r(a,n,t)}),a.focus()},radio:(e,t,a)=>{const r=P(e,p.radio),n=(t.forEach(e=>{var t=e[0],e=e[1];const n=document.createElement("input"),o=document.createElement("label"),i=(n.type="radio",n.name=p.radio,n.value=t,St(t,a.inputValue)&&(n.checked=!0),document.createElement("span"));y(i,e),i.className=p.label,o.appendChild(n),o.appendChild(i),r.appendChild(o)}),r.querySelectorAll("input"));n.length&&n[0].focus()}},Tt=n=>{const o=[];return"undefined"!=typeof Map&&n instanceof Map?n.forEach((e,t)=>{let n=e;"object"==typeof n&&(n=Tt(n)),o.push([t,n])}):Object.keys(n).forEach(e=>{let t=n[e];"object"==typeof t&&(t=Tt(t)),o.push([e,t])}),o},St=(e,t)=>t&&t.toString()===e.toString();function Lt(){var e,t=L.innerParams.get(this);if(t){const n=L.domCache.get(this);x(n.loader),re()?t.icon&&B(s()):(t=n,(e=t.popup.getElementsByClassName(t.loader.getAttribute("data-button-to-replace"))).length?B(e[0],"inline-block"):he()&&x(t.actions)),k([n.popup,n.actions],p.loading),n.popup.removeAttribute("aria-busy"),n.popup.removeAttribute("data-loading"),n.confirmButton.disabled=!1,n.denyButton.disabled=!1,n.cancelButton.disabled=!1}}var Ot={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap};const jt=()=>h()&&h().click();const Mt=e=>{e.keydownTarget&&e.keydownHandlerAdded&&(e.keydownTarget.removeEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1)},Dt=(e,t,n)=>{const o=ie();if(o.length)return(t+=n)===o.length?t=0:-1===t&&(t=o.length-1),o[t].focus();g().focus()},It=["ArrowRight","ArrowDown"],qt=["ArrowLeft","ArrowUp"],Ht=(e,n,t)=>{var o=L.innerParams.get(e);if(o&&(!n.isComposing&&229!==n.keyCode))if(o.stopKeydownPropagation&&n.stopPropagation(),"Enter"===n.key)e=e,s=n,i=o,R(i.allowEnterKey)&&s.target&&e.getInput()&&s.target.outerHTML===e.getInput().outerHTML&&(["textarea","file"].includes(i.input)||(jt(),s.preventDefault()));else if("Tab"===n.key){e=n;var i=o;var a=e.target,r=ie();let t=-1;for(let e=0;e<r.length;e++)if(a===r[e]){t=e;break}e.shiftKey?Dt(i,t,-1):Dt(i,t,1);e.stopPropagation(),e.preventDefault()}else if([...It,...qt].includes(n.key)){var s=n.key;const l=h(),u=f(),d=b();if([l,u,d].includes(document.activeElement)){var c=It.includes(s)?"nextElementSibling":"previousElementSibling";let t=document.activeElement;for(let e=0;e<v().children.length;e++){if(!(t=t[c]))return;if(E(t)&&t instanceof HTMLButtonElement)break}t instanceof HTMLButtonElement&&t.focus()}}else if("Escape"===n.key){e=n,n=o,o=t;if(R(n.allowEscapeKey)){e.preventDefault();o(j.esc)}}};function Vt(e,t,n,o){re()?Ut(e,o):(Ce(n).then(()=>Ut(e,o)),Mt(T)),/^((?!chrome|android).)*safari/i.test(navigator.userAgent)?(t.setAttribute("style","display:none !important"),t.removeAttribute("class"),t.innerHTML=""):t.remove(),ae()&&(ft(),yt(),ot()),k([document.documentElement,document.body],[p.shown,p["height-auto"],p["no-backdrop"],p["toast-shown"]])}function Nt(e){e=void 0!==(n=e)?Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},n):{isConfirmed:!1,isDenied:!1,isDismissed:!0};const t=Ot.swalPromiseResolve.get(this);var n=(e=>{const t=g();if(!t)return false;const n=L.innerParams.get(e);if(!n||w(t,n.hideClass.popup))return false;k(t,n.showClass.popup),A(t,n.hideClass.popup);const o=m();return k(o,n.showClass.backdrop),A(o,n.hideClass.backdrop),Ft(e,t,n),true})(this);this.isAwaitingPromise()?e.isDismissed||(Rt(this),t(e)):n&&t(e)}const Rt=e=>{e.isAwaitingPromise()&&(L.awaitingPromise.delete(e),L.innerParams.get(e)||e._destroy())},Ft=(e,t,n)=>{var o,i,a,r=m(),s=Le&&be(t);"function"==typeof n.willClose&&n.willClose(t),s?(s=e,o=t,t=r,i=n.returnFocus,a=n.didClose,T.swalCloseEventFinishedCallback=Vt.bind(null,s,t,i,a),o.addEventListener(Le,function(e){e.target===o&&(T.swalCloseEventFinishedCallback(),delete T.swalCloseEventFinishedCallback)})):Vt(e,r,n.returnFocus,n.didClose)},Ut=(e,t)=>{setTimeout(()=>{"function"==typeof t&&t.bind(e.params)(),e._destroy()})};function Wt(e,t,n){const o=L.domCache.get(e);t.forEach(e=>{o[e].disabled=n})}function zt(e,t){if(!e)return!1;if("radio"===e.type){const n=e.parentNode.parentNode,o=n.querySelectorAll("input");for(let e=0;e<o.length;e++)o[e].disabled=t}else e.disabled=t}const _t=e=>{e.isAwaitingPromise()?(Kt(L,e),L.awaitingPromise.set(e,!0)):(Kt(Ot,e),Kt(L,e))},Kt=(e,t)=>{for(const n in e)e[n].delete(t)};e=Object.freeze({hideLoading:Lt,disableLoading:Lt,getInput:function(e){var t=L.innerParams.get(e||this);return(e=L.domCache.get(e||this))?le(e.popup,t.input):null},close:Nt,isAwaitingPromise:function(){return!!L.awaitingPromise.get(this)},rejectPromise:function(e){const t=Ot.swalPromiseReject.get(this);Rt(this),t&&t(e)},handleAwaitingPromise:Rt,closePopup:Nt,closeModal:Nt,closeToast:Nt,enableButtons:function(){Wt(this,["confirmButton","denyButton","cancelButton"],!1)},disableButtons:function(){Wt(this,["confirmButton","denyButton","cancelButton"],!0)},enableInput:function(){return zt(this.getInput(),!1)},disableInput:function(){return zt(this.getInput(),!0)},showValidationMessage:function(e){const t=L.domCache.get(this);var n=L.innerParams.get(this);y(t.validationMessage,e),t.validationMessage.className=p["validation-message"],n.customClass&&n.customClass.validationMessage&&A(t.validationMessage,n.customClass.validationMessage),B(t.validationMessage);const o=this.getInput();o&&(o.setAttribute("aria-invalid",!0),o.setAttribute("aria-describedby",p["validation-message"]),ue(o),A(o,p.inputerror))},resetValidationMessage:function(){var e=L.domCache.get(this);e.validationMessage&&x(e.validationMessage);const t=this.getInput();t&&(t.removeAttribute("aria-invalid"),t.removeAttribute("aria-describedby"),k(t,p.inputerror))},getProgressSteps:function(){return L.domCache.get(this).progressSteps},update:function(e){var t=g(),n=L.innerParams.get(this);if(!t||w(t,n.hideClass.popup))return a("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");t=(t=>{const n={};return Object.keys(t).forEach(e=>{if(Y(e))n[e]=t[e];else a('Invalid parameter to update: "'.concat(e,'". Updatable params are listed here: https://github.com/sweetalert2/sweetalert2/blob/master/src/utils/params.js\n\nIf you think this parameter should be updatable, request it here: https://github.com/sweetalert2/sweetalert2/issues/new?template=02_feature_request.md'))}),n})(e),n=Object.assign({},n,t),tt(this,n),L.innerParams.set(this,n),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})},_destroy:function(){var e=L.domCache.get(this);const t=L.innerParams.get(this);t?(e.popup&&T.swalCloseEventFinishedCallback&&(T.swalCloseEventFinishedCallback(),delete T.swalCloseEventFinishedCallback),T.deferDisposalTimer&&(clearTimeout(T.deferDisposalTimer),delete T.deferDisposalTimer),"function"==typeof t.didDestroy&&t.didDestroy(),e=this,_t(e),delete e.params,delete T.keydownHandler,delete T.keydownTarget,delete T.currentInstance):_t(this)}});const Yt=(e,t)=>{var n=L.innerParams.get(e);if(!n.input)return l('The "input" parameter is needed to be set when using returnInputValueOn'.concat(H(t)));var o=((e,t)=>{const n=e.getInput();if(!n)return null;switch(t.input){case"checkbox":return n.checked?1:0;case"radio":return(o=n).checked?o.value:null;case"file":return(o=n).files.length?null!==o.getAttribute("multiple")?o.files:o.files[0]:null;default:return t.inputAutoTrim?n.value.trim():n.value}var o})(e,n);if(n.inputValidator){var i=e;var a=o;var r=t;const s=L.innerParams.get(i),c=(i.disableInput(),Promise.resolve().then(()=>u(s.inputValidator(a,s.validationMessage))));c.then(e=>{i.enableButtons(),i.enableInput(),e?i.showValidationMessage(e):("deny"===r?Zt:$t)(i,a)})}else e.getInput().checkValidity()?("deny"===t?Zt:$t)(e,o):(e.enableButtons(),e.showValidationMessage(n.validationMessage))},Zt=(t,n)=>{const e=L.innerParams.get(t||void 0);if(e.showLoaderOnDeny&&D(f()),e.preDeny){L.awaitingPromise.set(t||void 0,!0);const o=Promise.resolve().then(()=>u(e.preDeny(n,e.validationMessage)));o.then(e=>{!1===e?(t.hideLoading(),Rt(t)):t.closePopup({isDenied:!0,value:void 0===e?n:e})}).catch(e=>Xt(t||void 0,e))}else t.closePopup({isDenied:!0,value:n})},Jt=(e,t)=>{e.closePopup({isConfirmed:!0,value:t})},Xt=(e,t)=>{e.rejectPromise(t)},$t=(t,n)=>{const e=L.innerParams.get(t||void 0);if(e.showLoaderOnConfirm&&D(),e.preConfirm){t.resetValidationMessage(),L.awaitingPromise.set(t||void 0,!0);const o=Promise.resolve().then(()=>u(e.preConfirm(n,e.validationMessage)));o.then(e=>{E(ee())||!1===e?(t.hideLoading(),Rt(t)):Jt(t,void 0===e?n:e)}).catch(e=>Xt(t||void 0,e))}else Jt(t,n)},Gt=(n,e,o)=>{e.popup.onclick=()=>{var e,t=L.innerParams.get(n);t&&((e=t).showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton||t.timer||t.input)||o(j.close)}};let Qt=!1;const en=t=>{t.popup.onmousedown=()=>{t.container.onmouseup=function(e){t.container.onmouseup=void 0,e.target===t.container&&(Qt=!0)}}},tn=t=>{t.container.onmousedown=()=>{t.popup.onmouseup=function(e){t.popup.onmouseup=void 0,e.target!==t.popup&&!t.popup.contains(e.target)||(Qt=!0)}}},nn=(n,o,i)=>{o.container.onclick=e=>{var t=L.innerParams.get(n);Qt?Qt=!1:e.target===o.container&&R(t.allowOutsideClick)&&i(j.backdrop)}},on=e=>"object"==typeof e&&e.jquery,an=e=>e instanceof Element||on(e);const rn=()=>{if(T.timeout){{const n=ne();var e=parseInt(window.getComputedStyle(n).width),t=(n.style.removeProperty("transition"),n.style.width="100%",parseInt(window.getComputedStyle(n).width)),e=e/t*100;n.style.removeProperty("transition"),n.style.width="".concat(e,"%")}return T.timeout.stop()}},sn=()=>{var e;if(T.timeout)return e=T.timeout.start(),se(e),e};let cn=!1;const ln={};const un=t=>{for(let e=t.target;e&&e!==document;e=e.parentNode)for(const o in ln){var n=e.getAttribute(o);if(n)return void ln[o].fire({template:n})}};var dn=Object.freeze({isValidParameter:K,isUpdatableParameter:Y,isDeprecatedParameter:Z,argsToParams:n=>{const o={};return"object"!=typeof n[0]||an(n[0])?["title","html","icon"].forEach((e,t)=>{t=n[t];"string"==typeof t||an(t)?o[e]=t:void 0!==t&&l("Unexpected type of ".concat(e,'! Expected "string" or "Element", got ').concat(typeof t))}):Object.assign(o,n[0]),o},isVisible:()=>E(g()),clickConfirm:jt,clickDeny:()=>f()&&f().click(),clickCancel:()=>b()&&b().click(),getContainer:m,getPopup:g,getTitle:X,getHtmlContainer:$,getImage:G,getIcon:s,getInputLabel:()=>n(p["input-label"]),getCloseButton:oe,getActions:v,getConfirmButton:h,getDenyButton:f,getCancelButton:b,getLoader:d,getFooter:te,getTimerProgressBar:ne,getFocusableElements:ie,getValidationMessage:ee,isLoading:()=>g().hasAttribute("data-loading"),fire:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return new this(...t)},mixin:function(n){class e extends this{_main(e,t){return super._main(e,Object.assign({},n,t))}}return e},showLoading:D,enableLoading:D,getTimerLeft:()=>T.timeout&&T.timeout.getTimerLeft(),stopTimer:rn,resumeTimer:sn,toggleTimer:()=>{var e=T.timeout;return e&&(e.running?rn:sn)()},increaseTimer:e=>{if(T.timeout)return e=T.timeout.increase(e),se(e,!0),e},isTimerRunning:()=>T.timeout&&T.timeout.isRunning(),bindClickHandler:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"data-swal-template";ln[e]=this,cn||(document.body.addEventListener("click",un),cn=!0)}});let pn;class I{constructor(){if("undefined"!=typeof window){pn=this;for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];var o=Object.freeze(this.constructor.argsToParams(t)),o=(Object.defineProperties(this,{params:{value:o,writable:!1,enumerable:!0,configurable:!0}}),this._main(this.params));L.promise.set(this,o)}}_main(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},e=(J(Object.assign({},t,e)),T.currentInstance&&(T.currentInstance._destroy(),ae()&&ot()),T.currentInstance=this,gn(e,t)),t=(mt(e),Object.freeze(e),T.timeout&&(T.timeout.stop(),delete T.timeout),clearTimeout(T.restoreFocusTimeout),hn(this));return tt(this,e),L.innerParams.set(this,e),mn(this,t,e)}then(e){const t=L.promise.get(this);return t.then(e)}finally(e){const t=L.promise.get(this);return t.finally(e)}}const mn=(l,u,d)=>new Promise((e,t)=>{const n=e=>{l.closePopup({isDismissed:!0,dismiss:e})};var o,i,a;Ot.swalPromiseResolve.set(l,e),Ot.swalPromiseReject.set(l,t),u.confirmButton.onclick=()=>{var e=l,t=L.innerParams.get(e);e.disableButtons(),t.input?Yt(e,"confirm"):$t(e,!0)},u.denyButton.onclick=()=>{var e=l,t=L.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?Yt(e,"deny"):Zt(e,!1)},u.cancelButton.onclick=()=>{var e=l,t=n;e.disableButtons(),t(j.cancel)},u.closeButton.onclick=()=>n(j.close),e=l,t=u,a=n,L.innerParams.get(e).toast?Gt(e,t,a):(en(t),tn(t),nn(e,t,a)),o=l,e=T,t=d,i=n,Mt(e),t.toast||(e.keydownHandler=e=>Ht(o,e,i),e.keydownTarget=t.keydownListenerCapture?window:g(),e.keydownListenerCapture=t.keydownListenerCapture,e.keydownTarget.addEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!0),a=l,"select"===(t=d).input||"radio"===t.input?Bt(a,t):["text","email","number","tel","textarea"].includes(t.input)&&(F(t.inputValue)||U(t.inputValue))&&(D(h()),xt(a,t));{var r=d;const s=m(),c=g();"function"==typeof r.willOpen&&r.willOpen(c),e=window.getComputedStyle(document.body).overflowY,Pt(s,c,r),setTimeout(()=>{At(s,c)},wt),ae()&&(kt(s,r.scrollbarPadding,e),nt()),re()||T.previousActiveElement||(T.previousActiveElement=document.activeElement),"function"==typeof r.didOpen&&setTimeout(()=>r.didOpen(c)),k(s,p["no-transition"])}fn(T,d,n),bn(u,d),setTimeout(()=>{u.container.scrollTop=0})}),gn=(e,t)=>{var n=(e=>{e="string"==typeof e.template?document.querySelector(e.template):e.template;if(!e)return{};e=e.content,dt(e),e=Object.assign(at(e),rt(e),st(e),ct(e),lt(e),ut(e,it));return e})(e);const o=Object.assign({},r,t,n,e);return o.showClass=Object.assign({},r.showClass,o.showClass),o.hideClass=Object.assign({},r.hideClass,o.hideClass),o},hn=e=>{var t={popup:g(),container:m(),actions:v(),confirmButton:h(),denyButton:f(),cancelButton:b(),loader:d(),closeButton:oe(),validationMessage:ee(),progressSteps:Q()};return L.domCache.set(e,t),t},fn=(e,t,n)=>{var o=ne();x(o),t.timer&&(e.timeout=new gt(()=>{n("timer"),delete e.timeout},t.timer),t.timerProgressBar&&(B(o),C(o,t,"timerProgressBar"),setTimeout(()=>{e.timeout&&e.timeout.running&&se(t.timer)})))},bn=(e,t)=>{if(!t.toast)return R(t.allowEnterKey)?void(vn(e,t)||Dt(t,-1,1)):yn()},vn=(e,t)=>t.focusDeny&&E(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&E(e.cancelButton)?(e.cancelButton.focus(),!0):!(!t.focusConfirm||!E(e.confirmButton))&&(e.confirmButton.focus(),!0),yn=()=>{document.activeElement instanceof HTMLElement&&"function"==typeof document.activeElement.blur&&document.activeElement.blur()},wn=(Object.assign(I.prototype,e),Object.assign(I,dn),Object.keys(e).forEach(e=>{I[e]=function(){if(pn)return pn[e](...arguments)}}),I.DismissReason=j,I.version="11.4.8",I);return wn.default=wn}),void 0!==this&&this.Sweetalert2&&(this.swal=this.sweetAlert=this.Swal=this.SweetAlert=this.Sweetalert2); (function () { 'use strict'; const IS_DEBUG = true; // 调试信息开关 const STR_VOEOCMARK = "VOEOCMARK"; // 临时标记 const VOEOC_REG = { // 自定义正则 POSTPAGE: RegExp(`postPage\?(?=.*tid\=)(?=.*postAuthorId\=)(?=.*forumId\=)`, 'i'), // 评论页url FLOORREPLAYPAGE: RegExp(`lzlPage\?(?=.*floor\=)(?=.*pid\=)`, 'i'), // 楼中楼页url JSON_FLOORDATA: RegExp(`getFloorData\?(?=.*pn\=)(?=.*rn\=)(?=.*tid\=)(?=.*pid\=)`, 'i'), // 楼中楼json数据url POSTPBDATA: RegExp(`getPbData\?(?=.*pn\=)(?=.*rn\=)(?=.*only_post\=)(?=.*kz\=)`, 'i'), // 评论页数据url MAINPBDATA: RegExp(`getPbData\?(?=.*eqid\=)(?=.*refer\=)(?=.*pn\=)(?=.*rn\=)(?=.*format\=)(?=.*obj_param2\=)(?=.*kz\=)`, 'i'), // 主页数据url PBDATA: RegExp(`getPbData\?.*pn\=.*`, 'i'), // 通用页面数据url } const PAGE_TYPE = { // 页面类型 UNKNOW: -1, // 未知 MAINPAGE: 0, // 主页 POSTPAGE: 1, // 评论页 FLOORREPLAYPAGE: 2, // 楼中楼页 }; let tieNode = undefined; // 一楼 let tiebaNameNode = undefined; // 吧名 let lzId = ""; // 楼主id let currentHash = unsafeWindow.location.hash; // 存储当前页的Hash,页面变动的依据 let currentScrollYPos = undefined; // 存储当前滚动位置 let floorDataList = {} // 存储所有楼层数据以便搜索,索引为楼层数字符串,值为抓取的json。主要信息为pid,获取路径floorDataList[floor].id let someKey = { // 一些用于网络请求的关键字,页面加载或变动时自自动更新 host: "tieba.baidu.com", tid: "", postAuthorId: "", forumId: "", } function ignoreError(func) { try { func(); } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } } function assert(condition, msg) { if (!condition) { throw new Error(`${msg}`) } } const STR_DEBUG_LABEL_ERROR = "error"; function DEBUGLOG(msg, label = "") { if (!IS_DEBUG) { return; } let outputFunc = console.log; if (label == STR_DEBUG_LABEL_ERROR) { outputFunc = console.error; } outputFunc(`voeoc(DEBUG)<${label}>: ${msg}`); } function waitElementLoaded(selector, func, TIME_OUT = 30) { let findTimeNum = 0; // 记录查找的次数 let timer = setInterval(() => { let element = document.querySelector(selector); DEBUGLOG(`${selector}=${element}`, "waitElementLoaded"); if (element != null) { // 清除定时器 clearInterval(timer); func(element); } else { findTimeNum++; if (TIME_OUT < findTimeNum) { // 清除定时器 clearInterval(timer); } } }, 200); } // 获取url参数 function getUrlAttr(url, attrName) { return RegExp(`${attrName}=([^&]*)&?`, 'i').exec(url)[1].trim(); } // 简单判断当前页面的类型 function getPageType(hash = unsafeWindow.location.hash) { if (hash === "" || hash === "#/") { return PAGE_TYPE.MAINPAGE; } else if (VOEOC_REG.POSTPAGE.test(hash)) { return PAGE_TYPE.POSTPAGE; } else if (VOEOC_REG.FLOORREPLAYPAGE.test(hash)) { return PAGE_TYPE.FLOORREPLAYPAGE; } return PAGE_TYPE.UNKNOW; } class SettingValue { #key; get key() { return this.#key; } #value; set value(newValue) { GM_setValue(this.#key, newValue); } get value() { return this.#value; } #defaultValue; get defaultValue() { return this.#defaultValue; } #range = { min: undefined, max: undefined, } get range() { return this.#range; } checkRange(value, self = this) { if(!self.#range || !self.#range.min || !self.#range.max) { return true; } return self.#range.min <= value && value <= self.#range.max; } constructor(key, defaultValue, range=undefined) { let self = this; self.#key = key; self.#value = ""; self.#defaultValue = defaultValue; self.#range = range; self.loadValue(); } loadValue(newKey = undefined, self = this) { if (newKey) { self.#key = newKey; } let gValue = GM_getValue(self.#key, self.#defaultValue); if(typeof self.#defaultValue !== typeof gValue || Number.isNaN(gValue) || !self.checkRange(gValue)) { // 存储的值格式不对,执行重设 self.value = self.#defaultValue; } else { // 读取正常值 self.#value = gValue; } } } const settingsData = { isFixedTitle: new SettingValue("VOEOC_GMKEY_isFixedTitle", false), // 是否将标题置顶,TODO:暂不支持 isLongClickToOpenLzlPage: new SettingValue("VOEOC_GMKEY_isLongClickToOpenLzlPage", true), // 是否开启展开按钮的长按事件,长按展开按钮时直接切换到对应的楼中楼页 isAutoExpand: new SettingValue("VOEOC_GMKEY_isAutoExpand", true), // 自动展开的开关 isRemaindAutoExpand: new SettingValue("VOEOC_GMKEY_isRemaindAutoExpand", true), // 剩余评论过少时自动展开的开关 eachExpandSize: new SettingValue("VOEOC_GMKEY_eachExpandSize", 12, {min:10, max:30}), // 每次展开的评论数量,至少为10,少于10按10计算 remaindAutoExpandSize: new SettingValue("VOEOC_GMKEY_remaindAutoExpandSize", 7, {min:0, max:20}), // 当剩余评论少于这个数时,执行自动展开 } function reloadSettingsData() { for(let key in settingsData) { settingsData[key].loadValue(); } settingsData.isFixedTitle.value = false; } settingsData.isFixedTitle.value = false; class CustomLzlExpandManager { // 实现楼中楼展开的逻辑管理器 static #STR_NEWOPENLZLTEXT = "展开评论"; // 打开楼中楼按钮的文本 static #STR_REMAINDOPENLZLTEXT = function (num) { return `剩余${num}个评论`; } static #LZL_CONTENT_TYPE = { // 楼中楼评论内容元素类型 TEXT: 0, // 文本 EMOJI: 2, // 表情 USERNAME: 4, // 用户名,一般用作回复 }; #enable; // 按钮开关 #currentPageNum; // 当前展开页,用于网络请求 #pageSize; // 单个页面评论数量,至少为10 #originItemNodeList; // 原始楼中楼评论显示节点 #sampleItemNode; // 原始楼中楼评论样本 #lzTagHTML; // 一个楼主方框标记 #data_v_a; // 评论中的第一个dataset数据(data-v-***),用于还原样式 #data_v_b; // 评论中的第二个dataset数据(data-v-***),用于还原样式 #pid; // 楼层id #floorNum; // 当前楼层的楼层数 get floorNum() { return this.#floorNum; } // 存储的网页节点 #floorNode; // 当前楼层 #lzlNode; // 楼中楼 #expandBtnNode; // 楼中楼展开按钮 #expandBtnTextNode; // 楼中楼展开按钮的文本 constructor(floorNode, expandBtnNode) { assert(floorNode, "floorNode is null"); assert(expandBtnNode, "expandBtnNode is null"); let self = this; self.#enable = true; self.#currentPageNum = 1; self.#pageSize = settingsData.eachExpandSize.value < 10 ? 10 : settingsData.eachExpandSize.value; // 单个展开的页面评论数量,至少为10 self.#floorNode = floorNode; // 当前楼层节点 self.#expandBtnNode = expandBtnNode; // 楼中楼展开按钮 self.#lzlNode = self.#floorNode.querySelector("div.lzl-post"); self.#originItemNodeList = self.#lzlNode.getElementsByClassName("lzl-post-item"); self.#sampleItemNode = self.#originItemNodeList[0].cloneNode(true); // 读取复制data-v let dvlist = []; for (let dv in self.#originItemNodeList[0].querySelector(".thread-text").dataset) { dvlist.push(`data-v-${dv.slice(1).replace('-', '')}`); } self.#data_v_a = "data-v-aeeee"; self.#data_v_b = "data-v-beeee"; try { self.#data_v_a = dvlist[0]; } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } try { self.#data_v_b = dvlist[1]; } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } self.#lzTagHTML = `<svg ${self.#data_v_b}="" class="landlord"><use xlink:href="#icon_landlord"></use></svg>`; let floorinfoNode = floorNode.querySelector(".floor-info"); // 楼层数元素 self.#floorNum = RegExp(`第([0-9]+)楼`, 'i').exec(floorinfoNode.innerHTML)[1].trim(); // 楼层数 self.#pid = floorDataList[self.#floorNum].id; // 楼层id // 创建新按钮节点 self.#expandBtnTextNode = document.createElement("span"); self.#expandBtnTextNode.className = "open-app-text-real"; self.#expandBtnTextNode.innerHTML = CustomLzlExpandManager.#STR_NEWOPENLZLTEXT; // 绑定长按事件 if(settingsData.isLongClickToOpenLzlPage.value) { let timeOutEvent = 0; const TIME_OUT = 500; self.#expandBtnNode.ontouchstart = function () { DEBUGLOG("ontouchstart", "ontouchstart") timeOutEvent = setTimeout(function(){ timeOutEvent = 0; // 执行长按 self.openLzlPage(); },TIME_OUT); return false; } self.#expandBtnNode.ontouchend = function () { DEBUGLOG("ontouchend", "ontouchend") clearTimeout(timeOutEvent); if(timeOutEvent!=0){ // 判断为单击 self.expandLzl(); } return false; } self.#expandBtnNode.ontouchmove = function () { DEBUGLOG("ontouchmove", "ontouchmove") clearTimeout(timeOutEvent); timeOutEvent = 0; } } else { // 绑定展开按钮点击事件 self.#expandBtnNode.onclick = function () { self.expandLzl(); } } // 替换新按钮 self.#expandBtnNode.insertBefore(self.#expandBtnTextNode, self.#expandBtnNode.children[0]); } /** * 原地展开楼中楼评论 * @param {Boolean} isTheLast 是否为最后一次展开,避免无限递归 * @param {this} self * */ expandLzl(isTheLast = false, self = this) { assert(self.#enable, `尝试展开不存在的评论区,楼层号${self.#floorNum}`); DEBUGLOG(self.#floorNum, "expandLzl"); let url = `${unsafeWindow.origin}/mg/o/getFloorData?pn=${self.#currentPageNum}&rn=${self.#pageSize}&tid=${someKey.tid}&pid=${self.#pid}`; DEBUGLOG(url, "expandLzl"); self.#startExpandAnimation(); GM_xmlhttpRequest({ method: "get", url: url, onload: function (details) { self.#endExpandAnimation(); // 爬取解析楼中楼评论数据 let floorData = undefined; let subpostlist = undefined; try { floorData = JSON.parse(details.responseText); subpostlist = floorData.data.sub_post_list; // 评论列表 if (!subpostlist || subpostlist.length == 0) { throw ("sub_post_list为空"); } } catch (e) { // 无法获取楼中楼数据 DEBUGLOG(`无法获取楼中楼数据,url:${url}\n错误:${e}`, STR_DEBUG_LABEL_ERROR); self.#showError(true); return; } // 复原颜色 self.#showError(false); // 去掉前两个评论 if (self.#currentPageNum == 1) { try { for (let i = self.#originItemNodeList.length - 1; i > -1; i--) { self.#lzlNode.removeChild(self.#originItemNodeList[i]); } } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } } subpostlist.forEach(function (subpost) { // 遍历每一行评论 let contentHTML = ""; // 单行评论的HTML subpost.content.forEach(function (subContent) { // 遍历单行评论的每一个元素 let itemHTML = ""; // 元素的HTML switch (subContent.type) { case CustomLzlExpandManager.#LZL_CONTENT_TYPE.EMOJI: itemHTML = `<img ${self.#data_v_a}="" src="${subContent.src}" alt="${subContent.text}"class="emotion-img">`; break; case CustomLzlExpandManager.#LZL_CONTENT_TYPE.USERNAME: if (subContent.uid == lzId) { itemHTML = `<span ${self.#data_v_b}="" class="link username"> ${subContent.text} ${self.#lzTagHTML} </span>`; } else { itemHTML = `<span ${self.#data_v_a}="" class="user rich-link-disabled"> ${subContent.text} </span>`; } break; case CustomLzlExpandManager.#LZL_CONTENT_TYPE.TEXT: default: // 如有其他的类型暂时用文本代替 itemHTML = `<span ${self.#data_v_a}="" class="text-content">${subContent.text}</span>`; break; } contentHTML += itemHTML; }) let newItemNode = self.#sampleItemNode.cloneNode(true); // 新的评论行 newItemNode.querySelector(".username").innerHTML = `${subpost.author.show_nickname} ${(lzId == subpost.author.id) ? self.#lzTagHTML : ""}:`; newItemNode.querySelector(".thread-text").innerHTML = contentHTML; self.#lzlNode.insertBefore(newItemNode, self.#expandBtnNode); }); // 展开结束后处理剩余评论 let pageinfo = floorData.data.page; // 楼中楼信息,包括楼层数、页面大小、页面数量 let total_page = parseInt(pageinfo.total_page); // 总页数 if (total_page > self.#currentPageNum) { // 仍有剩余评论未展开 self.#currentPageNum++; let total_num = parseInt(pageinfo.total_num); let remaind_num = total_num - self.#pageSize * (self.#currentPageNum-1); self.#expandBtnNode.children[0].innerHTML = CustomLzlExpandManager.#STR_REMAINDOPENLZLTEXT(remaind_num); if (settingsData.isRemaindAutoExpand.value && settingsData.remaindAutoExpandSize.value > remaind_num) { // 当剩余评论过少时自动展开 if (!isTheLast) { // 检查当前是否强制设置为为最后一次展开 self.expandLzl(true); } } } else { // 所有评论已展开时隐藏展开按钮 self.#destroy.apply(self); } }, onerror: function (details) { self.#endExpandAnimation(); self.#showError(true); DEBUGLOG(`无法加载评论区,爬取的url为${details.responseURL}`, STR_DEBUG_LABEL_ERROR); }, onabort: onerror, ontimeout: onerror, }); } // 另一种打开楼中楼的方法,但是需要页面切换 openLzlPage(self = this) { if(!someKey.tid || !someKey.postAuthorId || !someKey.forumId) { self.#showError(); return; } let newHash = `#/lzlPage?tid=${someKey.tid}&pid=${self.#pid}&floor=${self.floorNum}&postAuthorId=${someKey.postAuthorId}&forumId=${someKey.forumId}`; DEBUGLOG(newHash, "openLzlPage hash"); unsafeWindow.location.hash = newHash; } #showError(isError = true, self = this) { if (isError) { self.#expandBtnTextNode.classList.add("error"); } else { self.#expandBtnTextNode.classList.remove("error"); } } // 开始动画 #startExpandAnimation(self = this) { self.#expandBtnNode.disabled = true; self.#expandBtnNode.classList.add("loading"); } // 结束动画 #endExpandAnimation(self = this) { self.#expandBtnNode.disabled = false; self.#expandBtnNode.classList.remove("loading"); } #destroy(self = this) { try { self.#enable = false; self.click = undefined; self.#expandBtnNode.style.display = "none"; self.#expandBtnNode.parentNode.removeChild(self.#expandBtnNode); } finally { delete this; } } } // 开始监听楼层改变 function startListenFloorParentNodeChange(floorParentNode) { // 当有新楼层加载时调用 function onNewFloorAdded(floorNode) { if (floorNode.classList.contains(STR_VOEOCMARK)) { // 已被打上标记 return; } floorNode.classList.add(STR_VOEOCMARK); // 手动标记,避免重复操作 try { let expandBtnNode = floorNode.querySelector(".open-app-guide"); // 楼中楼展开按钮 if (expandBtnNode) { let newCustomLzlExpandManager = new CustomLzlExpandManager(floorNode, expandBtnNode); if (settingsData.isAutoExpand.value) { DEBUGLOG(newCustomLzlExpandManager.floorNum, "AutoExpand"); newCustomLzlExpandManager.expandLzl(); } } } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } }; // 使用新按钮刷新楼层 function searchAndUpdatePostPage() { // 遍历所有新加的楼层元素 let floorNodeList = floorParentNode.querySelectorAll(`div.post-item:not(.${STR_VOEOCMARK})`); floorNodeList.forEach(onNewFloorAdded); } // 注册楼层元素添加事件 let observer = new MutationObserver(function (mutationList) { searchAndUpdatePostPage(); }); observer.observe(floorParentNode, { attributes: false, childList: true, characterData: false, subtree: false, }); searchAndUpdatePostPage(); } // 检测URL Hash变化,当force为true时,无论是否变化均执行后续任务 function checkUrlHashChange(force = false) { if (currentHash != unsafeWindow.location.hash) { currentHash = unsafeWindow.location.hash; } else { if (!force) { return false; } } let pageType = getPageType(); if (pageType == PAGE_TYPE.POSTPAGE) { // 页面变动为评论页 // 收集url数据 someKey = { host: unsafeWindow.location.hostname, tid: getUrlAttr(currentHash, "tid"), postAuthorId: getUrlAttr(currentHash, "postAuthorId"), forumId: getUrlAttr(currentHash, "forumId"), } // 当页面变动时,刷新展开楼层的按钮 waitElementLoaded(".post-page-list", (postpagelist) => { // 等待页面加载完成 startListenFloorParentNodeChange(postpagelist); }, 10); // 恢复一楼显示 restore(); // 页面切换后恢复滚动位置 scrollTo(currentScrollYPos); } else if (pageType == PAGE_TYPE.MAINPAGE) { // 页面变动为主页 if (tieNode) { // 当页面变动时,刷新展开楼层的按钮 waitElementLoaded(".pb-page-wrapper", (pbpageNode) => { // 等待页面加载完成 startListenFloorParentNodeChange(pbpageNode); }, 10); // 将剪切走的一楼复制回来 waitElementLoaded("#replySwitch", (splitlineNode) => { // 等待页面加载完成 splitlineNode.parentNode.insertBefore(tieNode, splitlineNode); }, 10); scrollTo(0); } } return true; } // 滚动到指定y坐标(如果当前楼层数比较大,只能滚动到贴末尾的最大加载位置) function scrollTo(yPos) { waitElementLoaded(".post-page", (_) => { // 等待页面加载完成 document.documentElement.scrollTop = yPos; // 在一定时间内维持滚动位置 setTimeout(function () { document.documentElement.scrollTop = yPos; DEBUGLOG(yPos, "scrollTo"); }, 200); }); } // 显示一楼的内容 function restore() { DEBUGLOG("restore") waitElementLoaded(".text", (titletextNode) => { // 等待标题位置加载 // 显示贴吧名 try { let tiebaNameCloneNode = tiebaNameNode.cloneNode(true); titletextNode.parentNode.replaceChild(tiebaNameCloneNode, titletextNode); // 关联点击贴吧名的事件 tiebaNameCloneNode.onclick = function () { tiebaNameNode.click(); } } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } // 显示楼主发帖层 try { // 复原样式丢失 tieNode.style.cssText = ` margin-left: 0.12rem; margin-right: 0.12rem; margin-bottom: 0.25rem; ` // 尝试找回楼主丢失的头像 try { let lzavatarNode = tieNode.querySelector(".avatar"); lzavatarNode.style.backgroundImage = `url("${lzavatarNode.getAttribute("data-src")}")` } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } // 尝试复原发帖内容的字体样式 try { let textContentNode = tieNode.querySelector(".thread-text"); // 一楼的文字内容 textContentNode.style.cssText = ` margin-top: 0.18rem; font-size: 0.16rem; line-height: 0.28rem; ` } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } let replySwitchNode = document.querySelector("#replySwitch"); // 标题下方的分割 replySwitchNode.parentNode.insertBefore(tieNode, replySwitchNode); } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } // 尝试复原标题样式 try { let threadtitleNode = document.querySelector(".thread-title"); let isTopTitle = true; if (!threadtitleNode) { threadtitleNode = document.querySelector(".bottom-thread-title"); isTopTitle = false; } threadtitleNode.style.cssText = ` margin-bottom: 0.13rem; font-size: 0.22rem; font-weight: 700; line-height: 0.33rem; ` // 置顶标题显示 if (settingsData.isFixedTitle.value && isTopTitle) { let threadtitleCloneNode = threadtitleNode.cloneNode(true) threadtitleNode.style.visibility = "hidden"; threadtitleCloneNode.style.cssText += ` position: fixed !important; z-index: 99 !important; opacity: 0.8 !important; background-color: #FFFFFF !important; ` threadtitleNode.parentNode.insertBefore(threadtitleCloneNode, threadtitleNode) } } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); } }) } // 解析传过来的PBDATA的json function parsePbData(responseText, responseURL) { let data = undefined; try { DEBUGLOG(typeof responseText, "typeof responseText"); if(typeof responseText == "object") { data = responseText.data; } else { data = JSON.parse(responseText).data; } } catch (e) { DEBUGLOG(e, STR_DEBUG_LABEL_ERROR); return; } let post_list = data.post_list; // 获取楼主id try { if (getUrlAttr(responseURL, "pn") == "1") { // 楼主id存在1楼数据中 lzId = post_list[0].author.id; DEBUGLOG(lzId, "lzId"); } } catch (e) { DEBUGLOG("无法获取楼主id", STR_DEBUG_LABEL_ERROR); } // 获取内部参数 try { someKey.tid = data.forum.id; } catch (e) { DEBUGLOG("该json并暂无tid信息", STR_DEBUG_LABEL_ERROR); } // 获取楼层信息 for (let i = 0; i < post_list.length; i++) { let d = post_list[i]; floorDataList[d.floor] = d; } } function registerMenuCommand() { function generateCheckboxHTML(label, settingValue, onChangeHTML = "") { return `<input id="${settingValue.key}" class="voeoc-swal-input-checkbox" type="checkbox" ${settingValue.value ? "checked" : ""} value="" onload="onchange()" onchange="${onChangeHTML}"> <label for="${settingValue.key}">${label}</label> <br>`; } function generateNumberInputboxHTML(label, settingValue, disabled=false) { let id_input = settingValue.key; let id_show_value = `${settingValue.key}-show`; let min = settingValue.range.min; let max = settingValue.range.max; return `<span>${label}(<span id='${id_show_value}'>${settingValue.value}</span>):</span> <br> <input class="voeoc-swal-range" id="${id_input}" ${disabled ? "disabled='true'": ""} type="range" min="${min}" max="${max}" step="1" value="${settingValue.value}" onload="onchange()" oninput="onchange()" onchange="document.getElementById('${id_show_value}').innerHTML=this.value;"> <br>`; } function getCheckboxValue(settingValue) { ignoreError(function(){ let newValue = Boolean(document.getElementById(`${settingValue.key}`).checked); DEBUGLOG(newValue, "newValue"); settingValue.value = newValue; }); } function getNumberInputboxValue(settingValue) { ignoreError(function(){ let newValue = parseInt(document.getElementById(`${settingValue.key}`).value); DEBUGLOG(newValue, "newValue"); settingValue.value = newValue; }); } let menuId = GM_registerMenuCommand(`设置`, async function () { const Toast = Swal.mixin({ position: 'bottom', animation: false, }) const { value: result } = await Toast.fire({ html: ` <div style="text-align: left;"> ${generateCheckboxHTML("长按打开楼中楼页", settingsData.isLongClickToOpenLzlPage)} ${generateCheckboxHTML("楼中楼自动展开", settingsData.isAutoExpand)} ${generateCheckboxHTML("楼中楼评论过少时展开", settingsData.isRemaindAutoExpand, `document.getElementById('${settingsData.remaindAutoExpandSize.key}').disabled=!this.checked;`)} ${generateNumberInputboxHTML("楼中楼展开的大小", settingsData.eachExpandSize)} ${generateNumberInputboxHTML("自动展开剩余评论", settingsData.remaindAutoExpandSize, !settingsData.isRemaindAutoExpand.value)} </div>`, focusConfirm: true, showCancelButton: true, confirmButtonText: "保存", cancelButtonText: "取消", width: "100%", padding: '0.03rem', background: "#19191acc", preConfirm: () => { getCheckboxValue(settingsData.isLongClickToOpenLzlPage); getCheckboxValue(settingsData.isAutoExpand); getCheckboxValue(settingsData.isRemaindAutoExpand); getNumberInputboxValue(settingsData.eachExpandSize); getNumberInputboxValue(settingsData.remaindAutoExpandSize); reloadSettingsData(); return true; } }) if (!result) { // 点击了取消按钮 } }, "VOEOC_MENU_ACCESS_KEY_SETTINGS"); } (function main() { GM_listValues(); GM_addStyle(GM_getResourceText("swal_css")); registerMenuCommand(); GM_addStyle(` .comment-box, .only-lz, .nav-bar-bottom, .open-app, .more-image-desc { display: none !important; } .open-app-text { display: none !important; } .open-app-text-real { display: block !important; -webkit-box-flex: 0; -webkit-flex: none; -ms-flex: none; flex: none; font-size: .13rem; color: #614ec2; } .open-app-text-real.error { color: #ff3366 !important; text-decoration: line-through; } @keyframes rotate { 0%{-webkit-transform:rotate3d(1, 0, 0, 0deg);} 25%{-webkit-transform:rotate3d(1, 0, 0, 90deg);} 50%{-webkit-transform:rotate3d(1, 0, 0, 180deg);} 75%{-webkit-transform:rotate3d(1, 0, 0, 270deg);} 100%{-webkit-transform:rotate3d(1, 0, 0, 360deg);} } .open-app-guide.loading { animation: rotate 0.5s linear infinite; } .voeoc-swal-input { position: center; } .voeoc-swal-input-checkbox { height: 0.15rem; width: 0.15rem; } .voeoc-swal-range { width: 100%; } .swal2-html-container { font-size: 0.15rem !important; line-height: 0.5rem !important; } .swal2-styled { font-size: 0.15rem !important; } .swal2-container { max_width: 640px !important; } `); // 监听楼层加载的网络事件 (function () { let oldXHR = unsafeWindow.XMLHttpRequest; unsafeWindow.XMLHttpRequest = function () { let realXHR = new oldXHR(); realXHR.addEventListener('readystatechange', function () { DEBUGLOG(realXHR.responseURL, "realXHR.responseURL"); if (VOEOC_REG.PBDATA.test(realXHR.responseURL) && realXHR.response != "") { DEBUGLOG(realXHR.responseURL, "realXHR.response parse"); parsePbData(realXHR.response, realXHR.responseURL); } }, false); return realXHR; } })(); // 通过监听页面滚动变化获取页面变动情况 unsafeWindow.onscroll = function () { checkUrlHashChange(); if (getPageType() == PAGE_TYPE.POSTPAGE) { // 只会记录评论页的滚动位置 if (unsafeWindow.pageYOffset != 0) { // 记录当前滚动位置 currentScrollYPos = unsafeWindow.pageYOffset; //DEBUGLOG(scrollPos, "scrollPos"); } } } // 页面变动时触发检查 unsafeWindow.onhashchange = function (e) { checkUrlHashChange(); } // 首次进入,对于不同的页面采取不同的行为 switch (getPageType()) { case PAGE_TYPE.MAINPAGE: // 首次进入主页 waitElementLoaded("div.nav-bar-v2-fixed:nth-child(1)", (navbarfixed) => { tiebaNameNode = document.querySelector(".forum-block"); // 获取吧名 tieNode = document.querySelector(".main-thread-content"); // 获取楼主发帖内容 let postbtn = document.querySelector(".post-page-entry-btn"); // 展开评论页的按钮 // 点击展开按钮 try { postbtn.click(); // 手动触发页面刷新检测 checkUrlHashChange(); } catch (e) { // 展开按钮不存在,可能是楼层太少了 DEBUGLOG(postbtn, "postbtn"); // 页面开始加载时监听会大概率失效,所以这里只能主动触发抓取楼层信息的请求,发起后交给监听程序 let url = `${unsafeWindow.origin}/mg/p/getPbData?kz=${RegExp(`${unsafeWindow.origin}/p/([0-9]*)?#?/?`, 'i').exec(unsafeWindow.location.href)[1].trim()}&obj_param2=firefox&format=json&eqid=&refer=&pn=1&rn=5`; DEBUGLOG(url, "url"); GM_xmlhttpRequest({ method: "get", url: url, onload: function (details) { DEBUGLOG(details.responseText, "GM_xmlhttpRequest onload"); parsePbData(details.responseText, url); // 强制手动触发页面刷新 checkUrlHashChange(true); }, onerror: function (details) { DEBUGLOG(`获取主页数据失败,url:${details.responseURL}`, STR_DEBUG_LABEL_ERROR); }, }); } }) break; case PAGE_TYPE.POSTPAGE: // 如果当前刷新加载的是评论页,则需要先打开主页面获取数据 unsafeWindow.location.hash = ""; unsafeWindow.location.reload(); break; case PAGE_TYPE.FLOORREPLAYPAGE: break; default: break; } })() })();