// ==UserScript== // @name 哔哩哔哩新版首页排版调整和去广告(bilibili) // @namespace http://tampermonkey.net/ // @version 1.6.5 // @author Ling2Ling4 // @description 对新版B站首页的每行显示的视频数量进行调整, 同时删除所有广告, 并可设置屏蔽内容 (大尺寸屏幕每行将显示更多的视频) // @license MIT // @icon data:image/png;base64,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 // @match *://www.bilibili.com/* // @exclude *://www.bilibili.com/all* // @exclude *://www.bilibili.com/anime* // @exclude *://www.bilibili.com/pgc* // @exclude *://t.bilibili.com/* // @exclude *://www.bilibili.com/opus* // @exclude *://www.bilibili.com/live* // @exclude *://www.bilibili.com/article* // @exclude *://www.bilibili.com/upuser* // @exclude *://www.bilibili.com/match* // @exclude *://www.bilibili.com/platform* // @exclude *://www.bilibili.com/bangumi* // @exclude *://www.bilibili.com/cheese* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @compatible chrome // @compatible edge // @compatible firefox // @downloadURL none // ==/UserScript== (() => { "use strict"; const info = { pageName: "", keyBase: "setting_", zoom: window.devicePixelRatio, loadVideoNum: 10, homeClassList: { 标题: "h3 a", 作者: "bili-video-card__info--owner", 分类: "floor-title", carousel: "recommended-swipe", vDom: ["container", "no-banner-container", "is-version8"], video: "feed-card", nav: "bili-header__bar", banner: "bili-header__banner", btn: "roll-btn", btn2: "flexible-roll-btn", specialCard: "floor-single-card", }, homeDelClassList: { 广告: "bili-video-card__info--ad", 推广: "bili-video-card__info--creative-ad", 特殊: "floor-single-card", 直播: "living", 番剧: "分类=番剧", 综艺: "分类=综艺", 课堂: "分类=课堂", 漫画: "分类=漫画", 国创: "分类=国创", 电影: "分类=电影", 纪录片: "分类=纪录片", 电视剧: "分类=电视剧", }, btnDoms: {}, apiUrl: "https://api.bilibili.com/x/web-interface/wbi/index/top/feed/rcmd", imgDetails: "@672w_378h_1c_!web-home-common-cover", marginTop1: 24, marginTop2: 24, errKeyArr: ["", 2, 3], errKeyInfo: { disNum: "setting_err_disNum", errNum: "setting_err_num", errTime: "setting_err_time", isTip: "setting_err_isTip", }, disErrTipNum: 3, errTipNum: 15, errTipInterval: 2, errNumReset: 5, videoInfo: { startTime: 500, pathInterval: 500, interval: 1e3, timeoutNum: 8, delDom: [ { name: "几乎全部广告", pre: ".", str: "ad-report", type: "ad", isAll: !0, }, { name: "横幅广告", pre: "#", str: "bannerAd" }, { name: "活动广告", pre: "#", str: "slide_ad", type: "ad" }, { name: "视频广告", pre: ".", str: "video-card-ad-small" }, { name: "右下广告", pre: "#", str: "right-bottom-banner" }, { name: "横幅通告", pre: ".", str: "reply-notice", type: "ad" }, { name: "活动推广", pre: "#", str: "activity_vote", type: "other" }, { name: "直播推广", pre: ".", str: "pop-live-small-mode", type: "other", }, ], }, }, keyBase = info.keyBase, settings = { isCarousel: { value: !0, base: !0, key: keyBase + "isCarousel", txt: "是否显示轮播图 (修改后需要调整排列规则才能达到预期效果,轮播图占两个视频的宽度,所以每行显示视频数加减2即可)", type: "基础设置", valType: "boolean", compType: "radio", valueText: { true: "显示轮播图", false: "隐藏轮播图" }, }, isAutoLayout: { value: !0, base: !0, key: keyBase + "isAutoLayout", txt: "是否根据缩放自动调整视频布局", type: "基础设置", valType: "boolean", compType: "radio", valueText: { true: "缩放时自动调整布局", false: "仅窗口变化时调整布局", }, }, isClearAd: { value: !0, base: !0, key: keyBase + "isClearAd", txt: "是否删除广告, 若不删除则会将所有广告移至视频列表的最后", type: "基础设置", valType: "boolean", compType: "radio", valueText: { true: "删除广告", false: "广告后移" }, }, isTrueEnd: { value: !1, base: !1, key: keyBase + "isTrueEnd", txt: "是否将广告移至预加载视频的后面, 关闭后广告将放置在预加载视频的前面 一般视频的后面 (该设置仅在不删除广告时生效)", type: "基础设置", valType: "boolean", compType: "radio", valueText: { true: "放置页尾", false: "放置预加载视频前" }, }, isLoadOne: { value: !0, base: !0, key: keyBase + "isLoadOne", txt: "是否在进入网站时加载视口区域的全部视频, 开启时视口区域不会出现预加载视频", type: "基础设置", valType: "boolean", compType: "radio", valueText: { true: "加载视口的全部视频", false: "保留视口的预加载视频", }, }, addVideoNum: { value: 0, base: 0, valType: "number", key: keyBase + "addVideoNum", txt: "加载用于填充视口空白视频的视频数量, 0表示自动计算数量 (自动计算时可能会因为屏蔽了部分视频导致视口区域还留有空白视频)", type: "基础设置", compType: "textarea", compH: "30px", }, homeDelAdTime: { value: 0, base: 0, valType: "number", key: keyBase + "homeDelAdTime", txt: "点击换一换按钮并加载完新视频后 进行广告屏蔽的间隔时间, 0表示立即屏蔽 (毫秒, 1秒=1000毫秒)", type: "基础设置", compType: "textarea", compH: "30px", }, isReorderVideo: { value: !0, base: !0, valType: "boolean", key: keyBase + "isReorderVideo", txt: "是否按照排列规则调整布局 (每行能够显示更多视频)", type: "排列规则", compType: "radio", valueText: { true: "按照排列规则调整布局", false: "使用原来的视频排列", }, }, videoNumRule: { title: "排列规则", value: "0,1300,2\n1300,1800,3\n1800,3000,4\n3000,3700,5\n3700,6300,6", base: "0,1300,2\n1300,1800,3\n1800,3000,4\n3000,3700,5\n3700,6300,6", base2: "0,1300,4\n1300,1800,5\n1800,3000,6\n3000,3700,7\n3700,6300,8", key: keyBase + "videoNumRule", txt: "视频排列规则, 每条规则用 ; 分隔 或 换行书写. 未包含的尺寸将按照初始方式排列 (轮播图会影响视频的排列)\n示例: 1300,1800,3; 1800,3000,4 表示浏览器宽度在1300~1800像素时每行显示3个视频(前两行), 1800~3000像素每行4个视频", type: "排列规则", valType: "string", compType: "textarea", compH: "120px", }, delClassArr: { value: "广告, 推广", base: "广告, 推广", key: keyBase + "delClassArr", txt: "屏蔽设置, 可根据需要自行修改, 可自定义, 每项用 , 分隔 或 换行书写\n例如: 广告, 推广, 直播\n----可选: ('特殊'包含了直播 番剧 课堂...)\n广告、推广、特殊、直播、番剧、综艺、课堂、漫画、国创、电影、纪录片、电视剧\n----自定义:\n1. 标题=xxx, 可屏蔽标题含xxx的视频, xxx部分支持&&运算符, 如: 标题=A&&B, 表示屏蔽标题同时含有A B内容的视频\n2. 作者=xxx, 可屏蔽作者名和发布日期中含xxx的视频", type: "屏蔽设置", valType: "string", compType: "textarea", compH: "100px", }, video_isDelAd: { value: !0, base: !0, key: keyBase + "video_isDelAd", txt: "是否删除视频页的广告", type: "视频页", valType: "boolean", compType: "radio", valueText: { true: "删除广告", false: "保留广告" }, }, video_delSetting: { title: "广告屏蔽设置", value: "部分广告", base: "部分广告", key: keyBase + "video_delSetting", txt: "可根据需要自行修改, 每项用 , 分隔 (该设置仅在删除广告时生效)\n例如: 部分广告, 活动推广\n----可选:\n全部广告: 所有直接广告和间接广告\n部分广告: 所有直接广告 (横幅广告,活动广告,视频广告,右下广告,横幅通告)\n横幅广告: 视频下方的横幅广告\n活动广告: 右侧视频列表上方的广告\n视频广告: 右侧视频列表上方的小视频广告\n右下广告: 右侧视频列表下方的广告\n横幅通告: 评论区上方的横幅通告\n活动推广: 评论区上方的活动推广\n直播推广: 右侧视频列表下方的直播推广", type: "视频页", valType: "string", compType: "textarea", compH: "30px", }, }; function getValue({ base, key, valType = "string", isReSet = !0, getValue = null, setValue = null, getVal = null, setVal = null, } = {}) { getValue && (getVal = getValue), setValue && (setVal = setValue); let val = getVal ? getVal(key) : localStorage.getItem(key); return ( void 0 !== base && null == val && ((val = base), isReSet && ("string" != typeof base && (base = JSON.stringify(base)), setVal ? setVal(key, base) : localStorage.setItem(key, base))), (valType = valType.toLowerCase()), "string" == typeof val ? "string" === valType ? val : "boolean" === valType || "number" === valType ? JSON.parse(val) : "object" === valType ? val ? JSON.parse(val) : {} : "array" === valType ? val ? JSON.parse(val) : [] : val : val ); } function getData() { for (const valName in settings) { const setting = settings[valName]; setting.value = getValue({ base: setting.base, key: setting.key, valType: setting.valType, getVal: GM_getValue, setVal: GM_setValue, }); } } const utils = { getW(isAutoLayout) { let width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; return ( console.log("浏览器实际宽度:", width * window.devicePixelRatio), console.log("浏览器像素宽度:", width * info.zoom), !isAutoLayout && (width *= window.devicePixelRatio), width ); }, getValue(key, defa = null) { let value = GM_getValue(key); return null == value ? defa : value; }, boolTxt: (val) => (val ? "是 (确定)" : "否 (取消)"), strToDom(str) { let tmpDom = document.createElement("div"); tmpDom.innerHTML = str; const dom = tmpDom.children[0]; return (tmpDom = null), dom; }, formatDate( timestamp, { delimiter = "-", isYear = !1, isAlign = !0 } = {} ) { if (!timestamp) return -1; const date = new Date(timestamp), year = date.getFullYear(); let month = (date.getMonth() + 1).toString(), day = date.getDate().toString(); return ( isAlign && ((month = month.padStart(2, "0")), (day = day.padStart(2, "0"))), (isYear ? year + delimiter : "") + month + delimiter + day ); }, formatTime(time, { delimiter = ":", isAlign = !0 } = {}) { if (!time) return -1; let h = Math.floor(time / 60 / 60), m = Math.floor((time / 60) % 60), s = Math.floor(time % 60); return ( isAlign && ((h = h ? h.toString().padStart(2, "0") : ""), (m = m.toString().padStart(2, "0")), (s = s.toString().padStart(2, "0"))), (h ? h + delimiter : "") + m + delimiter + s ); }, async request(url, options = {}) { options.method = options.method || "GET"; try { const res = await fetch(url, options); if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`); return await res.json(); } catch (error) { throw error; } }, errHandle({ e = null, errTxt = "", logTxt = "", key = "" } = {}) { key && (key = "_" + key); let errNum = GM_getValue(info.errKeyInfo.errNum) || 0; if (errNum >= info.errTipNum) return; let disErrNum = GM_getValue(info.errKeyInfo.disNum + key) || 0; const curTime = Date.now(); let disS = (curTime - (GM_getValue(info.errKeyInfo.errTime + key) || curTime)) / 1e3; if (((disS = 0 === disS ? 5 : disS), disS < 5)) return; let flag = GM_getValue(info.errKeyInfo.isTip + key); (flag = void 0 === flag || flag), e && console.log(e), console.log(logTxt || errTxt), disS >= 60 * info.errTipInterval * 60 && ((flag = !0), GM_setValue(info.errKeyInfo.isTip + key, !0), GM_setValue(info.errKeyInfo.disNum + key, 0)), flag && disErrNum <= info.disErrTipNum && disS < (info.errTipInterval / 10) * 60 * 60 && (errNum++, disErrNum++, GM_setValue(info.errKeyInfo.errNum, errNum), GM_setValue(info.errKeyInfo.disNum + key, disErrNum), GM_setValue(info.errKeyInfo.errTime + key, curTime), alert(errTxt), disErrNum === info.disErrTipNum && GM_setValue(info.errKeyInfo.isTip + key, !1)); }, resetErrInfo() { const curTime = Date.now(); (curTime - info.errKeyArr.reduce((a, b) => { const t = +GM_getValue(info.errKeyInfo.errTime + b); return t < a ? t : a; }, curTime)) / 1e3 >= 24 * info.errNumReset * 60 * 60 && (GM_setValue(info.errKeyInfo.errNum, 0), info.errKeyArr.forEach((key) => { key && (key = "_" + key), GM_setValue(info.errKeyInfo.disNum + key, 0); })); }, }, videoObj = { info: { isDelAd: null, delSetting: null, base_isDelAd: null, base_delSetting: null, startTime: info.videoInfo.startTime, pathInterval: info.videoInfo.pathInterval, interval: info.videoInfo.interval, timeoutNum: info.videoInfo.timeoutNum, }, doms: { ad: [] }, delDom: info.videoInfo.delDom, initValue() { (this.info.isDelAd = settings.video_isDelAd.value), (this.info.delSetting = settings.video_delSetting.value), (this.info.base_isDelAd = settings.video_isDelAd.base), (this.info.base_delSetting = settings.video_delSetting.base); }, getAdInfo() { if (this.info.delSetting.includes("全部广告")) return this.delDom.filter( (item) => "ad" === item.type || "other" === item.type ); if ("部分广告" === this.info.delSetting) return this.delDom.filter( (item) => "ad" === item.type || "other" !== item.type ); { let arr = this.delDom.filter((item) => this.info.delSetting.includes(item.name) ); if (this.info.delSetting.includes("部分广告")) { const arr2 = this.delDom.filter((item) => { if (!arr.includes(item)) return "ad" === item.type || "other" !== item.type; }); arr = arr.concat(arr2); } return 0 === arr.length ? (utils.errHandle({ errTxt: `插件设置的广告屏蔽设置中 '${GM_getValue( "setting_video_delSetting" )}' 格式书写错误`, key: info.errKeyArr[2], }), -1) : arr; } }, getAd() { const ad = [], delAdInfo = this.getAdInfo(); -1 !== delAdInfo ? (delAdInfo.forEach((item) => { let adList = []; if ("." === item.pre) if (item.isAll) (adList = document.querySelectorAll(item.pre + item.str)), (adList = [].slice.call(adList)); else { const dom = document.querySelector(item.pre + item.str); dom && adList.push(dom); } else { const ele = document.querySelector(item.pre + item.str); ele && adList.push(ele); } adList.length > 0 && adList.forEach((adDom) => { ad.push(adDom); }); }), (this.doms.ad = this.info.isDelAd ? ad.filter((item) => "none" !== item.style.display) : ad)) : (this.doms.ad = []); }, delAd() { this.doms.ad.forEach((item) => { "none" !== item.style.display && (item.style.display = "none"); }); }, showAd() { this.doms.ad.forEach((item) => { "none" === item.style.display && (item.style.display = ""); }); }, updateData() { (this.info.isDelAd = settings.video_isDelAd.value), (this.info.delSetting = settings.video_delSetting.value); }, init() { if ((this.initValue(), !this.info.isDelAd)) return; let i = 0; const timer = setInterval(() => { i++, this.getAd(), i > this.info.timeoutNum && clearInterval(timer), this.delAd(); }, this.info.interval); utils.resetErrInfo(); }, }; const baseCfg = { isEditing: !1, isShowPage: !1, param: { id: "ll_edit_wrap", box: document.body, classBase: "ll_edit_", w: "450px", h: "", contentH: "450px", bg: "rgba(0, 0, 0, 0.12)", color: "#333", fontSize: "15px", fontFamily: "PingFang SC, HarmonyOS_Regular, Helvetica Neue, Microsoft YaHei, sans-serif", zIndex: 11e3, resetTt: "重置所有设置为默认值", isShowMenu: !1, isScrollStyle: !0, isResetBtn: !0, showPage: void 0, page: [], }, }, cfg = { version: "v1.0.7", isEditing: baseCfg.isEditing, isShowPage: baseCfg.isShowPage, param: {}, allData: {}, baseData: {}, oldData: {}, controls: {}, doms: { page: [] }, editText: {}, callback: { resetBefore: null, confirmBefore: null, finished: null }, }; const css = function getCss() { const param = cfg.param, cBase = (param.page, param.classBase), baseStart = `#${param.id} .${cBase}`, fSize = param.fontSize ? param.fontSize : "14px", css = `#${ param.id } {\n position: fixed;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n z-index: ${ param.zIndex || 11e3 };\n background: ${ param.bg || "rgba(0, 0, 0, 0.12)" };\n display: none;\n}\n${baseStart}box {\n position: relative;\n width: ${ param.w || "450px" };\n ${ param.h ? "max-height:" + param.h : "" };\n margin: auto;\n color: ${ param.color || "#333" };\n background: #fff;\n font-size: ${fSize};\n line-height: normal;\n font-family: ${ param.fontFamily || "PingFang SC, HarmonyOS_Regular, Helvetica Neue, Microsoft YaHei, sans-serif" };\n border: 3px solid #dfedfe;\n border-radius: 10px;\n box-sizing: border-box;\n padding: 10px 8px 10px 15px;\n overflow: hidden;\n overflow-y: auto;\n}\n${baseStart}menu {\n font-weight: bold;\n font-size: ${ parseInt(fSize) + 1 }px;\n margin-bottom: 10px;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n${baseStart}menu-item {\n border: 1px solid #dfedfe;\n color: #9ecaff;\n background: #eef6ff;\n border-radius: 6px;\n padding: 6px 10px;\n cursor: pointer;\n}\n${baseStart}menu-item:hover {\n color: #65aaff;\n background: #dfedfe;\n border: 1px solid #dfedfe;\n}\n${baseStart}menu-item.active {\n color: #65aaff;\n background: #dfedfe;\n border: 1px solid #dfedfe;\n}\n${baseStart}page-box {\n max-height: ${ param.contentH || "" };\n padding-right: 7px;\n margin-bottom: 8px;\n overflow: hidden;\n overflow-y: auto;\n}\n${baseStart}page {\n display: none;\n}\n${baseStart}page.curPage {\n display: block;\n}\n${baseStart}comp {\n margin-bottom: 8px;\n}\n${baseStart}comp:last-child {\n margin-bottom: 2px;\n}\n${baseStart}comp-tt {\n font-weight: bold;\n line-height: 1.5;\n}\n${baseStart}comp-desc {\n line-height: 1.5;\n}\n${baseStart}title {\n font-weight: bold;\n font-size: ${ parseInt(fSize) + 5 }px;\n}\n${baseStart}rd-arr {\n line-height: 22px;\n}\n${baseStart}rd-arr label {\n margin-right: 6px;\n cursor: pointer;\n}\n${baseStart}rd-arr input {\n vertical-align: -2px;\n cursor: pointer;\n}\n${baseStart}rd-arr span {\n color: #666;\n margin-left: 2px;\n}\n#${ param.id } textarea {\n width: 100%;\n max-width: 100%;\n max-height: 300px;\n border-radius: 6px;\n line-height: normal;\n padding: 5px 7px;\n outline-color: #cee4ff;\n border: 1px solid #aaa;\n box-sizing: border-box;\n font-size: ${ parseInt(fSize) - 2 }px;\n font-family: PingFang SC, HarmonyOS_Regular, Helvetica Neue, Microsoft YaHei, sans-serif;\n /* 保留空格 */\n white-space: pre-wrap;\n /* 允许词内换行 */\n word-break: break-all;\n letter-spacing: 1px;\n overflow: hidden;\n overflow-y: auto;\n}\n#${ param.id } textarea::placeholder {\n color: #bbb;\n}\n${baseStart}ta-desc {\n margin-bottom: 3px;\n}\n${baseStart}btn-box {\n display: flex;\n justify-content: flex-end;\n}\n${baseStart}btn-box button {\n font-size: 16px;\n line-height: normal;\n color: #65aaff;\n background: #dfedfe;\n outline: none;\n border: none;\n border-radius: 6px;\n padding: 8px 16px;\n box-sizing: border-box;\n cursor: pointer;\n}\n${baseStart}btn-box .${cBase}reset-btn {\n position: absolute;\n left: 15px;\n bottom: 10px;\n color: #888;\n background: #f4f4f4;\n margin-right: 15px;\n}\n${baseStart}btn-box .${cBase}reset-btn:hover {\n color: #666;\n background: #eee;\n}\n${baseStart}btn-box .${cBase}cancel-btn {\n color: #888;\n background: #f4f4f4;\n margin-right: 15px;\n}\n${baseStart}btn-box .${cBase}cancel-btn:hover {\n color: #666;\n background: #eee;\n}\n${baseStart}btn-box .${cBase}confirm-btn {\n margin-right: 7px;\n}\n${baseStart}btn-box .${cBase}confirm-btn:hover {\n background: #cee4ff;\n}\n`; return param.isScrollStyle ? css + "\n.ll-scroll-style-1::-webkit-scrollbar,\n.ll-scroll-style-1 ::-webkit-scrollbar {\n width: 8px;\n}\n.ll-scroll-style-1-size-2::-webkit-scrollbar,\n.ll-scroll-style-1 .ll-scroll-style-1-size-2::-webkit-scrollbar {\n width: 10px;\n}\n.ll-scroll-style-1-size-3::-webkit-scrollbar,\n.ll-scroll-style-1 .ll-scroll-style-1-size-3::-webkit-scrollbar {\n width: 12px;\n}\n.ll-scroll-style-1::-webkit-scrollbar-thumb,\n.ll-scroll-style-1 ::-webkit-scrollbar-thumb {\n border-radius: 10px;\n -webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.05);\n opacity: 0.2;\n background: #daedff;\n}\n.ll-scroll-style-1::-webkit-scrollbar-track,\n.ll-scroll-style-1 ::-webkit-scrollbar-track {\n -webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.08);\n border-radius: 0;\n background: #fff;\n border-radius: 5px;\n}" : css; }; const editArea_html = function getHTML() { function getCompHTML({ info, active = "", id }) { let title, desc, ctrlTt, type = info.type; if ( ((type = { menuTitle: "mtt", title: "tt", desc: "ds", radio: "rd", checkbox: "cb", textarea: "ta", mtt: "mtt", tt: "tt", ds: "ds", rd: "rd", cb: "cb", ta: "ta", }[type]), (id = 0 === id ? "0" : id || ""), 0 === info.content ? (info.content = "0") : (info.content = info.content || ""), !type) ) return console.log("不存在的组件类型"), !1; switch ( ("tt" !== type && "ds" !== type && "mtt" !== type && ((title = info.title ? `
${info.title}
` : ""), (desc = info.desc ? `
${info.desc}
` : "")), type) ) { case "mtt": return info.content ? `
${info.content}
` : ""; case "tt": return info.content ? `
${info.content}
` : ""; case "ds": return info.content ? `
${info.content}
` : ""; case "rd": const name = info.name || new Date().getTime(); (ctrlTt = info.ctrlTt || ""), ctrlTt && (ctrlTt = `title="${ctrlTt}"`); let radio = `
`; if (void 0 === info.value && info.radioList[0]) { const obj = info.radioList[0]; info.value = void 0 === obj.value ? obj.text : obj.value; } return ( info.radioList.forEach((item) => { const value = void 0 === item.value ? item.text : item.value; let tt = item.tt || ""; tt && (tt = `title="${tt}"`); let selected = ""; info.value + "" == item.value + "" && (selected = "checked"), (radio += ``); }), (radio += "
"), `
${title}${desc}${radio}
` ); case "cb": const name2 = info.name || new Date().getTime(); if ( ((ctrlTt = info.ctrlTt || ""), ctrlTt && (ctrlTt = `title="${ctrlTt}"`), void 0 === info.value && info.radioList[0]) ) { const obj = info.radioList[0]; info.value = void 0 === obj.value ? obj.text : obj.value; } let checkbox = `
`; return ( info.radioList.forEach((item) => { const value = void 0 === item.value ? item.text : item.value; let tt = item.tt || ""; tt && (tt = `title="${tt}"`); let selected = ""; info.value + "" == item.value + "" && (selected = "checked"), (checkbox += ``); }), (checkbox += "
"), `
${title}${desc}${checkbox}
` ); case "ta": const style = `style="${ info.width ? "width:" + info.width + ";" : "" }${info.height ? "height:" + info.height + ";" : ""}${ info.fontSize ? "font-size:" + info.fontSize + ";" : "" }${info.fontFamily ? "font-family:" + info.fontFamily + ";" : ""}"`, textarea = ``; return `
${title}${desc}${textarea}
`; } } const param = cfg.param, page = param.page, cBase = param.classBase, isMenu = 1 !== page.length; let menu = `
`, pageHTML = `
`; page.forEach((curPage, index) => { let pgid = curPage.id || index; (pgid += ""), (cfg.allData[pgid] = {}), (cfg.baseData[pgid] = {}); let pageFlag = ""; if ( (cfg.isShowPage || ((void 0 === param.showPage || pgid === param.showPage + "") && ((pageFlag = "curPage"), (cfg.isShowPage = !0))), (pageHTML += `
`), curPage.components) ) { let compIndex = 0; if (isMenu || param.isShowMenu) { let curMenu = curPage.components.find( (item) => "menuTitle" === item.type ); curMenu || (curMenu = { type: "menuTitle", content: pgid }), (menu += getCompHTML({ info: curMenu, active: pageFlag ? "active" : "", })); } curPage.components.forEach((item) => { const cpid = item.id || compIndex; "menuTitle" !== item.type && (pageHTML += getCompHTML({ info: item, id: cpid })), "menuTitle" !== item.type && "title" !== item.type && "desc" !== item.type && ((item.base = void 0 === item.base ? item.value : item.base), (cfg.allData[pgid][cpid] = item.value), (cfg.baseData[pgid][cpid] = item.base), compIndex++); }); } pageHTML += "
"; }), (pageHTML += "
"), isMenu || param.isShowMenu ? (menu += "
") : (menu = ""); const resetBtn = param.isResetBtn ? `` : "", btnBox = `
\n${resetBtn}\n\n\n
`; return `
\n${menu}\n${pageHTML}\n${btnBox}\n
`; }; let param = cfg.param; const baseParam = baseCfg.param, allData = cfg.allData, controls = cfg.controls, doms = cfg.doms, cBase = baseParam.classBase; function createEditEle({ id = baseParam.id, box = baseParam.box, classBase = baseParam.classBase, w = baseParam.w, h = baseParam.h, contentH = baseParam.contentH, bg = baseParam.bg, color = baseParam.color, fontSize = baseParam.fontSize, fontFamily = baseParam.fontFamily, zIndex = baseParam.zIndex, resetTt = baseParam.resetTt, isShowMenu = baseParam.isShowMenu, isScrollStyle = baseParam.isScrollStyle, isResetBtn = baseParam.isResetBtn, showPage = baseParam.showPage, page = [], } = {}) { (cfg.isEditing = baseCfg.isEditing), (cfg.isShowPage = baseCfg.isShowPage), (cfg.param = { ...baseParam }), (param = cfg.param), (param.id = id), (param.box = box), (param.classBase = classBase), (param.w = w), (param.h = h), (param.contentH = contentH), (param.bg = bg), (param.color = color), (param.fontSize = fontSize), (param.fontFamily = fontFamily), (param.zIndex = zIndex), (param.resetTt = resetTt), (param.isShowMenu = isShowMenu), (param.isScrollStyle = isScrollStyle), (param.isResetBtn = isResetBtn), (param.showPage = showPage), (param.page = page); const html = editArea_html(); return ( (function addCss(cssText, box = document.body, id = "") { const style = document.createElement("style"); return ( id && (style.id = id), box.appendChild(style), (style.innerHTML = cssText), style ); })(css(), box), (doms.wrap = (function createEle({ className = "", id = "", title = "", css, box = document.body, type = "div", } = {}) { const ele = document.createElement(type); return ( id && (ele.id = id), className && (ele.className = className), title && (ele.title = title), css && (ele.style.cssText = css), box.appendChild(ele), ele ); })({ className: id, id })), (doms.wrap.innerHTML = html), (function getDoms() { (doms.box = doms.wrap.querySelector(`.${cBase}box`)), (doms.cancel = doms.box.querySelector(`.${cBase}cancel-btn`)), (doms.confirm = doms.box.querySelector(`.${cBase}confirm-btn`)); const isMenu = 1 !== param.page.length; (isMenu || param.isShowMenu) && ((doms.menu = doms.box.querySelector(`.${cBase}menu`)), (doms.menus = [].slice.call( doms.menu.querySelectorAll(`.${cBase}menu-item`) ))); const pages = [].slice.call(doms.box.querySelectorAll(`.${cBase}page`)); (doms.page = []), param.isResetBtn && (doms.reset = doms.box.querySelector(`.${cBase}reset-btn`)); pages.forEach((curPage, index) => { cfg.isShowPage || (curPage.classList.add("curPage"), (isMenu || param.isShowMenu) && doms.menus[0].classList.add("active"), (cfg.isShowPage = !0)); const page = {}, pgid = curPage.dataset.pgid; (page.pgid = curPage.pgid = pgid), (page.controls = [].slice.call( curPage.querySelectorAll(`.${cBase}ctrl`) )), (page.ele = curPage), doms.page.push(page), (isMenu || param.isShowMenu) && (doms.menus[index].settingsPage = curPage); const ctrls = {}; (controls[pgid] = ctrls), page.controls.forEach((item, i) => { const cpid = item.dataset.cpid, cType = item.dataset.type; let dom; (item.cpid = cpid), "rd" === cType || "cb" === cType ? ((dom = [].slice.call(item.querySelectorAll("input"))), (dom.compType = cType)) : "ta" === cType && ((dom = item.querySelector("textarea")), (dom.compType = cType), (dom.value = allData[pgid][cpid])), (ctrls[cpid] = dom); }); }); })(), (function bindEvents() { function menuHandle(e) { const dom = e.target; if (dom.classList.contains(`${cBase}menu-item`)) { const old = doms.menu.querySelector(".active"); old.classList.remove("active"), old.settingsPage.classList.remove("curPage"), dom.classList.add("active"), dom.settingsPage.classList.add("curPage"); } } function cancelEdit(e) { (e.target.className !== `${cBase}wrap` && e.target.className !== `${cBase}cancel-btn`) || (showEditArea(!1), setCompValue(cfg.oldData)); } function confirmEdit() { const callback = cfg.callback, data = getAllData(); if (callback.confirmBefore) { let result; const func = callback.confirmBefore; if ( (Array.isArray(func) ? func.curFn ? ((result = func[curFn](data)), (func.curFn = null)) : func.forEach((fn) => { result = fn(data); }) : (result = func(data)), !1 === result) ) return; } if ((showEditArea(!1), callback.finished)) { const func = callback.finished; Array.isArray(func) ? func.curFn ? (func[curFn](data), (func.curFn = null)) : func.forEach((fn) => { fn(data); }) : func(data); } } function resetEdit() { const callback = cfg.callback, data = getAllData(); if (callback.resetBefore) { let result; const func = callback.resetBefore; if ( (Array.isArray(func) ? func.curFn ? ((result = func[curFn](data)), (func.curFn = null)) : func.forEach((fn) => { result = fn(data); }) : (result = func(data)), !1 === result) ) return; } !(function resetEditData() { param.isResetBtn && setCompValue(cfg.baseData); })(); } doms.menu && doms.menu.addEventListener("click", menuHandle), doms.wrap.addEventListener("click", cancelEdit), doms.cancel.addEventListener("click", cancelEdit), doms.confirm.addEventListener("click", confirmEdit), doms.reset && doms.reset.addEventListener("click", resetEdit); })(), cfg ); } function getAllData() { function getCompItem(pgid, cpid) { if (!controls[pgid]) return; const ctrl = controls[pgid][cpid]; if (ctrl) { if (!Array.isArray(ctrl)) return ctrl.value; if ("rd" === ctrl.compType) { return ctrl.find((item) => item.checked).dataset.val; } if ("cb" === ctrl.compType) { return ctrl .filter((item) => item.checked) .map((item) => item.dataset.val); } } } const data = {}; if (0 === arguments.length) { for (const key in controls) { const page = controls[key]; data[key] = {}; for (const key2 in page) data[key][key2] = getCompItem(key, key2); } return data; } if (1 === arguments.length) { const ctrls = arguments[0]; for (const pgid in ctrls) { data[pgid] = {}; controls[pgid].forEach((cpid) => { data[pgid][cpid] = getCompItem(pgid, cpid); }); } return allData; } return getCompItem(arguments[0], arguments[1]); } function setCompValue() { function setCompItem(pgid, cpid, value) { if (!controls[pgid]) return; const ctrl = controls[pgid][cpid]; if (ctrl) if (Array.isArray(ctrl)) { if ("rd" === ctrl.compType) { const selected = ctrl.find((item) => item.checked); selected && (selected.checked = !1); const select = ctrl.find((item) => item.dataset.val === value + ""); select && (select.checked = !0); } else if ("cb" === ctrl.compType) { if ( (ctrl .filter((item) => item.checked) .forEach((item) => { item.checked = !1; }), Array.isArray(value)) ) value.forEach((val) => { const select = ctrl.find( (item) => item.dataset.val === val + "" ); select && (select.checked = !0); }); else { const select = ctrl.find( (item) => item.dataset.val === value + "" ); select && (select.checked = !0); } } } else ctrl.value = value; } if (1 === arguments.length) { const data = arguments[0]; for (const key in data) { const pageData = data[key]; for (const key2 in pageData) { setCompItem(key, key2, pageData[key2]); } } } else { setCompItem(arguments[0], arguments[1], arguments[2]); } } function showEditArea(isShow = !0, callback = null) { if ( isShow && ((cfg.oldData = getAllData()), "function" == typeof callback) ) { if (!1 === callback(cfg.oldData)) return; } (cfg.isEditing = isShow), (doms.wrap.style.display = isShow ? "block" : "none"), isShow && !doms.box.style.top && (doms.box.style.top = window.innerHeight / 2 - doms.box.clientHeight / 2 + "px"), callback && (cfg.callback = callback); } function toPageObj(settings) { const pageArr = [], menuList = []; for (let key in settings) { const item = settings[key]; menuList.includes(item.type) || menuList.push(item.type); } return ( menuList.forEach((menuTt) => { const components = [], page = { id: menuTt, components }, arr = []; for (let key in settings) { const item = settings[key]; item.type === menuTt && arr.push(item); } arr.forEach((item) => { let desc = item.txt || ""; desc && (desc = desc.replaceAll("\n", "
").trim()); const comp = { id: item.key, type: item.compType, tt: item.tt || "", title: item.title || "", desc, descTt: item.descTt || "", name: item.key, value: item.value, base: item.base, }; if ("textarea" === comp.type) (comp.ph = item.base), (comp.width = item.compW), (comp.height = item.compH), (comp.ctrlTt = "默认: " + item.base); else if ("radio" === comp.type || "checkbox" === comp.type) { let str = "默认: "; if ("checkbox" === comp.type) { let arr = item.base; Array.isArray(arr) || (arr = arr.split(/,|,/)), arr.forEach((val, i) => { 0 !== i && (str += ", "), (val = val.trim()); let valTxt = item.valueText[val]; void 0 === valTxt && (valTxt = val), (str += valTxt); }); } else { let val = item.valueText[item.base]; void 0 === val && (val = item.base), (str += val); } comp.ctrlTt = str; } if (item.valueText) { comp.radioList = []; for (let key in item.valueText) { const rd = { text: item.valueText[key], value: key }; comp.radioList.push(rd); } } components.push(comp); }), pageArr.push(page); }), pageArr ); } function getEditInfo() { const editInfo = { w: "500px", contentH: "450px", resetTT: "重置所有设置项为默认值", page: toPageObj(settings), }; return ( "首页" === info.pageName ? (editInfo.showPage = "基础设置") : "视频" === info.pageName && (editInfo.showPage = "视频页"), editInfo ); } const intervalLoopFunc = function ({ fn, breakFn, num = 10, interval = 100, isStartRun = !0, finishedFn, } = {}) { if (fn) if (isStartRun && breakFn && breakFn()) fn(), finishedFn && finishedFn(); else { let i = isStartRun ? 1 : 0; const timer = setInterval(() => { breakFn && breakFn() && (fn(), finishedFn && finishedFn(), clearInterval(timer)), i++, i >= num && clearInterval(timer); }, interval); } }, classList = info.homeClassList, delClassList = info.homeDelClassList; let vDom, nav, banner, carousel, base_videoNumRule, base_videoNumRule2, isClearAd, isTrueEnd, isAutoLayout, isLoadOne, isCarousel, videoNumRule, delClassArr; const apiUrl = info.apiUrl, imgDetails = info.imgDetails, queryNum = 0, marginTop1 = info.marginTop1, marginTop2 = info.marginTop2, zoom = info.zoom; let cssDom, cssText, oldCssText, w, isChange = !1, rowVideoNum = 3, videoNum = 0, newVideoNum = 0, firstAdIndex = 0, pageZoom = 1, loadNum = 0; window.location.pathname; function main(isLoads = !0) { if ( ((function initValue() { (isChange = !1), (rowVideoNum = 3), (videoNum = 0), (newVideoNum = 0), (firstAdIndex = 0), (pageZoom = 1); })(), isLoads && (loadNum++, loadNum > 3)) ) return; if ( (updateData(), (function home_getDoms() { if (vDom && nav && banner && carousel) return void (isCarousel || showCarousel(!1)); "string" == typeof classList.vDom ? (vDom = document.querySelector("." + classList.vDom)) : classList.vDom.forEach((item) => { !vDom && (vDom = document.querySelector("." + item)); }); if (!vDom) { const dom = document.querySelector("." + classList.video); if ((dom && (vDom = dom.parentElement), !vDom)) return; } (carousel = vDom.querySelector("." + classList.carousel)), (nav = document.querySelector("." + classList.nav)), (banner = document.querySelector("." + classList.banner)), (videoNumRule = (function home_getValue(key, defa = "") { let value = GM_getValue(key); return null == value ? defa : value; })( "setting_videoNumRule", carousel && isCarousel ? base_videoNumRule2 : base_videoNumRule )), "string" == typeof videoNumRule && (videoNumRule = getVideoNumRule(videoNumRule)); isCarousel || showCarousel(!1); })(), !vDom && isLoads) ) return void setTimeout(() => { main(); }, 500); (loadNum = 0), (w = utils.getW(isAutoLayout)), zoomPage(), setStyle(); intervalLoopFunc({ fn: function adFunc() { (videoNum = getVideoNum()), delAd(getAd(queryNum, delClassArr, newVideoNum, 1)), loadTopVideo(), utils.resetErrInfo(), (function home_bindEvents() { let timer, timer2, timer3, rollBtn = info.btnDoms.rollBtn, btnSvg = info.btnDoms.btnSvg, rollBtn2 = info.btnDoms.rollBtn2; function handleClick() { let adArr; if (!rollBtn) if ( ((rollBtn = document.querySelector( "button." + classList.btn )), (btnSvg = rollBtn && rollBtn.querySelector("svg")), (info.btnDoms.rollBtn = rollBtn), (info.btnDoms.btnSvg = btnSvg), btnSvg) ) { const fn = () => { getVideoNum(), (adArr = getAd( 3 * rowVideoNum + (carousel ? 2 : 0) + 3, delClassArr, newVideoNum, isTrueEnd ? newVideoNum : getFirstAdIndex() )), !isTrueEnd && adArr.forEach((item) => { item.forEach((adItem) => { adItem.style.display = "block"; }); }), delAd(adArr, !0), markOldVideo(); }; btnSvg.addEventListener("transitionend", () => { setTimeout(() => { intervalLoopFunc({ fn, breakFn: () => !vDom.children[1].getAttribute("oldvideo"), interval: 80, }); }, +settings.homeDelAdTime.value); }); } else rollBtn && rollBtn.addEventListener("click", () => { setTimeout(() => { getVideoNum(), (adArr = getAd( 3 * rowVideoNum + (carousel ? 2 : 0) + 3, delClassArr, newVideoNum, isTrueEnd ? newVideoNum : getFirstAdIndex() )), delAd(adArr, !0), markOldVideo(); }, 800 + settings.homeDelAdTime.value); }); rollBtn2 || ((rollBtn2 = document.querySelector("." + classList.btn2)), (info.btnDoms.rollBtn2 = rollBtn2), rollBtn2 && rollBtn2.addEventListener("click", () => { setTimeout(() => { (videoNum = getVideoNum()), (adArr = getAd( queryNum, delClassArr, 0, 1, !!isTrueEnd )), delAd(adArr, !1, !0), loadTopVideo(), markOldVideo(); }, 800); })), rollBtn && rollBtn2 && window.removeEventListener("click", handleClick); } window.addEventListener("click", handleClick), window.addEventListener("resize", () => { timer && clearTimeout(timer), (timer = setTimeout(() => { const newW = utils.getW(isAutoLayout); newW > w && delAdFn(), (w = newW), zoomPage(), setStyle(); }, 400)); }), window.addEventListener("wheel", () => { timer2 && clearTimeout(timer2), timer3 && clearTimeout(timer3), (timer2 = setTimeout(() => { delAdFn(timer3); }, 600)), (timer3 = setTimeout(() => { delAdFn(); }, 1500)); }); })(); }, breakFn: hasPreloadVideo, num: 20, finishedFn: () => { intervalLoopFunc({ fn: delAdFn, breakFn: hasSpecialVideo }); }, }); } function zoomPage() { if (document.getBoxObjectFor) return; const rootDom = document.documentElement; let rate = rootDom.scrollWidth / getMainW(); function getMainW() { let navW = nav ? nav.scrollWidth : 0; return navW > (banner ? banner.scrollWidth : 0) ? navW : rootDom.clientWidth; } !document.body.style.overflow && (document.body.style.overflow = "hidden auto"), rate > 1 ? ((pageZoom *= 1 / rate), (rootDom.style.zoom = pageZoom)) : ((pageZoom = 1), (rootDom.style.zoom = 1), (rate = rootDom.scrollWidth / getMainW()), rate > 1 && ((pageZoom *= 1 / rate), (rootDom.style.zoom = pageZoom))); } function getAd(queryNum, delClassArr, vNum, startIndex = 1, isAll = !1) { const arr = []; delClassArr.forEach(() => { arr.push([]); }); const vList = vDom.children, vLen = vList.length; let len = vNum || vLen; (len = len > vLen ? vLen : len), (queryNum = queryNum || len), (queryNum += startIndex) > len && (queryNum = len); for (let i = startIndex; i < queryNum; i++) { const vItem = vList[i]; if (!isAll && !vItem.querySelector("a")) break; for (let j = 0; j < delClassArr.length; j++) if (isChecked(vItem, delClassArr[j])) { arr[j].push(vItem); break; } } return arr; } function delAd(adArr, isDelJudge = !1, isDel = !1) { function delItem(item) { isClearAd || isDel ? (console.log("删除一个视频", item), item.remove(), newVideoNum--, videoNum--) : (console.log("后移一个视频", item), isTrueEnd ? (newVideoNum--, videoNum--, vDom.appendChild(item)) : vDom.insertBefore(item, vDom.children[newVideoNum])); } function isNeedDel() { let len = info.loadVideoNum + 1; for (let i = firstAdIndex + 1; i < len; i++) { const item = vDom.children[i]; if (!item) return !0; if (item.getAttribute("oldvideo")) return !1; } return !0; } function delInArr(arr, isDelJudge) { arr.forEach((item, i) => { if (isDelJudge && 0 === i) { intervalLoopFunc({ fn: () => { delItem(item); }, breakFn: isNeedDel, }); } else delItem(item); }); } for (let i = adArr.length - 1; i >= 0; i--) { const item = adArr[i]; isDelJudge && item.length > 0 ? (delInArr(item, !0), (isDelJudge = !1)) : delInArr(item, !1); } } function markOldVideo(len) { len = len || info.loadVideoNum; const vArr = vDom.children; for (let i = 1; i < len + 1 && vArr[i]; i++) vArr[i].setAttribute("oldvideo", "true"); } function delAdFn(timer = null) { if ((getVideoNum(), newVideoNum > videoNum)) { return ( delAd( getAd( queryNum, delClassArr, newVideoNum, isTrueEnd ? videoNum : getFirstAdIndex() ) ), (videoNum = newVideoNum), timer && clearTimeout(timer), !0 ); } } function setStyle() { if (!settings.isReorderVideo.value) return cssDom && cssDom.remove(), void (cssDom = null); if ( ((isChange = !1), videoNumRule.forEach((item) => { !(function setVideoNum(vRule) { const min = (vRule = vRule.map((i) => +i.trim()))[0] / (isAutoLayout ? zoom : 1), max = vRule[1] / (isAutoLayout ? zoom : 1), num = vRule[2]; (0 === min || min) && max && num ? (w >= min && w < max && ((cssText = carousel ? `.container {grid-template-columns: repeat(${ num + 2 },1fr) !important}\n.container>div:nth-child(n){margin-top:${marginTop2}px !important}\n.container>div:nth-child(-n+${ 3 * num + 2 + 1 }){margin-top:${marginTop1}px !important;display:block !important}\n.container>div:first-child{display:${ isCarousel ? "block" : "none" } !important}\n.container>div:nth-child(-n+${ 2 * (num + 1) - 1 }){margin-top:0px !important}` : `.container {grid-template-columns: repeat(${num},1fr) !important}\n.container>div:nth-child(n){margin-top:${marginTop2}px !important}\n.container>div:nth-child(${ 3 * num + 1 }){display:block !important}\n `), (isChange = !0), (rowVideoNum = num)), isChange || ((cssText = ""), (rowVideoNum = carousel ? 5 : 3))) : utils.errHandle({ errTxt: `插件设置的视频排列规则设置中 '${vRule.join( "" )}' 格式书写错误`, key: info.errKeyArr[1], }); })(item); }), isChange) ) { let isCssDom = !!cssDom; isCssDom || ((cssDom = document.createElement("style")), cssDom.setAttribute("type", "text/css")), oldCssText !== cssText && (cssDom.innerHTML = cssText), (oldCssText = cssText), !isCssDom && document.head.appendChild(cssDom); } else !isChange && cssDom && ((oldCssText = ""), (cssDom.innerHTML = "")); } function getVideoNum() { const vArr = vDom.children, len = vArr.length; let i; for (i = 1; i < len; i++) { if (!vArr[i].querySelector("a")) return (newVideoNum = i), i; } return (newVideoNum = i), i; } function getFirstAdIndex() { const vArr = vDom.children, len = vArr.length; firstAdIndex = 0; for (let i = 1; i < len; i++) { const vItem = vArr[i]; for (let j = 0; j < delClassArr.length; j++) if (isChecked(vItem, delClassArr[j])) return (firstAdIndex = i), i; if (!vItem.querySelector("a")) return 0; } return 0; } function hasPreloadVideo() { const vArr = vDom.children, lastDom = vArr[vArr.length - 1]; return !(!lastDom || lastDom.querySelector("a")); } function hasSpecialVideo() { const dom = vDom.querySelector(`.${info.homeClassList.specialCard}`); return !(!dom || !dom.querySelector("a")); } function isChecked(vEle, delStr) { let flag = !1; const map = classList; function custom(txt, type, selector) { const dom = vEle.querySelector(selector); if (!dom) return; const domTxt = dom.innerText, txtArr = txt.replace(type, "").split("&&"); if (!txtArr[0]) return; let f = !1; txtArr.forEach((item) => { f = f || domTxt.includes(item, ""); }), (flag = flag || f); } if ( ((delStr = delStr.trim()), (delStr = delClassList[delStr] || delStr).includes("标题=")) ) custom(delStr, "标题=", map.标题); else if (delStr.includes("作者=")) custom(delStr, "作者=", "." + map.作者); else if (delStr.includes("分类=")) custom(delStr, "分类=", "." + map.分类); else { flag = flag || vEle.classList.contains(delStr); try { flag = flag || vEle.querySelector("." + delStr); } catch (e) { utils.errHandle({ errTxt: `插件设置的屏蔽设置中 '${delStr}' 格式书写错误, 自定义格式应以 '标题=' 或 '作者=' 开头`, e, }); } } return flag; } function createVideoDom(data) { function formatNum(num) { return num > 1e8 ? (num / 1e8).toFixed(1) + "亿" : num > 1e4 ? (num / 1e4).toFixed(1) + "万" : "" + num; } function videoDom(item, reportStr) { if (item.business_info) return -1; const like = Math.floor(item.stat.like / 1e4), likeHTML = like > 1 ? `
${like}万点赞
` : "", upIconHTML = likeHTML ? "" : '\x3c!--[--\x3e\n \n \n \x3c!--]--\x3e\n', html = `
\n
\n
\n
\n
\n

\n

\n

\n
\n
\n
\n
\n
\n
\n \n \n \n \n \n
\n
\n
\n
\n
\n \n \n ${formatNum( item.stat.view )}\n \n \n \n \n \n ${formatNum( item.stat.danmaku )}
${utils.formatTime( item.duration )}\n
\n
\n
\n
\n \n
\n
`; return utils.strToDom(html); } const videoList = []; let num = 10; return ( data.forEach((item, index) => { num++; const dom = videoDom(item, `4-${index + 1}-${num}`); -1 !== dom && videoList.push(dom); }), videoList ); } async function loadTopVideo() { if (isLoadOne) try { const row = 4, newNum = settings.addVideoNum.value || (function addVideoNum() { const dis = hasSpecialVideo() ? 0 : -1; return isCarousel ? 3 * rowVideoNum + 2 - (newVideoNum - 1) + dis : 3 * rowVideoNum - (newVideoNum - 1) + dis; })(); if (newNum <= 0) return; const params = new URLSearchParams({ web_location: 1430650, y_num: 4, fresh_type: 4, feed_version: "V8", fresh_idx_1h: 1, fetch_row: row, fresh_idx: 1, brush: 1, homepage_ver: 1, ps: newNum, last_y_num: 5, screen: window.innerWidth + "-" + window.innerHeight, wts: Math.floor(new Date().getTime() / 1e3), }), data = await utils.request(`${apiUrl}?${params}`); let videoList = []; if (data.data.item) { (videoList = createVideoDom(data.data.item)), getVideoNum(); const dis = hasSpecialVideo() ? -1 : 0; for (let i = videoList.length - 1; i >= 0; i--) vDom.insertBefore(videoList[i], vDom.children[newVideoNum + dis]); } } catch (e) { console.log(e), setTimeout(() => { document.documentElement.scrollTo(0, 400), setTimeout(() => { document.documentElement.scrollTo(0, 0), setTimeout(() => { delAdFn(); }, 800); }, 20); }, 1e3); } } function getDelClassArr(value) { return (value = value .replaceAll(";", ",") .replaceAll(";", ",") .replaceAll(",", ",") .replaceAll(",\n", "\n") .replaceAll("\n", ",\n")).split(","); } function getVideoNumRule(value) { return (value = (value = value .replaceAll(";", ";") .replaceAll(";\n", ";") .replaceAll("\n", ";\n")).split(";")).map((item) => item.split(/,|,/)); } function updateData() { (isClearAd = settings.isClearAd.value), (isTrueEnd = settings.isTrueEnd.value), (isAutoLayout = settings.isAutoLayout.value), (isLoadOne = settings.isLoadOne.value), (isCarousel = settings.isCarousel.value), (videoNumRule = getVideoNumRule(settings.videoNumRule.value)), (delClassArr = getDelClassArr(settings.delClassArr.value)), (base_videoNumRule = getVideoNumRule(settings.videoNumRule.base)), (base_videoNumRule2 = getVideoNumRule(settings.videoNumRule.base2)); } function showCarousel(isShow = !0) { carousel || (carousel = vDom.querySelector("." + classList.carousel)), carousel && (carousel.style.display = isShow ? "block" : "none"), isShow || (carousel = !1); } function setValue({ value, base, key, verification = null, getValue = null, setValue = null, getVal = null, setVal = null, } = {}) { getValue && (getVal = getValue), setValue && (setVal = setValue); let newVal = value, val = getVal ? getVal(key) : localStorage.getItem(key); return ( void 0 !== base && null == val && ((val = base), "string" != typeof base && (base = JSON.stringify(base)), setVal ? setVal(key, base) : localStorage.setItem(key, base)), null !== newVal && ("function" != typeof verification || ((newVal = verification(newVal, val)), null !== newVal)) && newVal !== val && ("string" != typeof newVal && (newVal = JSON.stringify(newVal)), setVal ? setVal(key, newVal) : localStorage.setItem(key, newVal), !0) ); } function showSettings() { const oldSettings = JSON.stringify(settings); getData(); const curSettings = JSON.stringify(settings); info.settingsArea ? oldSettings !== curSettings && (info.settingsArea.doms.wrap.remove(), (info.settingsArea = createEditEle(getEditInfo()))) : (info.settingsArea = createEditEle(getEditInfo())), updateData(), videoObj.updateData(); const callback = { resetBefore: () => confirm("是否重置所有设置项为默认值?"), confirmBefore: () => {}, finished: (data) => { console.log(data); if ( !(function isValueChange() { const curData = getAllData(); return JSON.stringify(curData) !== JSON.stringify(cfg.oldData); })() ) return; const changeObj = {}; for (const key in settings) changeObj[key] = !1; for (const pageName in data) { const page = data[pageName]; for (const key in page) { const value = page[key]; let verifyFn; const flag = key.replace(info.keyBase, ""), item = settings[flag]; switch (key) { case settings.homeDelAdTime.key: verifyFn = (newVal) => (newVal = +newVal) >= 0 ? newVal : settings.homeDelAdTime.base; break; case settings.addVideoNum.key: verifyFn = (newVal) => (newVal = +newVal) >= 0 ? newVal : settings.addVideoNum.base; break; case settings.videoNumRule.key: verifyFn = (newVal) => newVal.replaceAll(" ", "").toLowerCase(); break; case settings.delClassArr.key: case settings.video_delSetting.key: verifyFn = (newVal) => newVal.replaceAll(" ", ""); } if (!item) return void console.log("设置的数据对应的对象获取失败"); changeObj[flag] = setValue({ value, base: item.base, key, verification: verifyFn, getValue: GM_getValue, setValue: GM_setValue, }); } } getData(); const changeArr = (function getTrueArr(obj) { const arr = []; for (const key in obj) obj[key] && arr.push(key); return arr; })(changeObj); if ("视频" === info.pageName) (changeArr.includes("video_delSetting") || changeArr.includes("video_isDelAd")) && (videoObj.updateData(), videoObj.getAd(), settings.video_isDelAd.value ? videoObj.delAd() : videoObj.showAd()); else if ("首页" === info.pageName) { (function hasCommonItems(arr1, arr2) { for (let i = 0; i < arr1.length; i++) if (arr2.includes(arr1[i])) return !0; return !1; })(changeArr, [ "isCarousel", "isAutoLayout", "isClearAd", "isTrueEnd", "isLoadOne", ]) ? main(!1) : (updateData(), changeArr.includes("isReorderVideo") && setStyle(), changeArr.includes("videoNumRule") && (function rearrange(rule) { (videoNumRule = getVideoNumRule(rule)), zoomPage(), setStyle(); })(settings.videoNumRule.value), changeArr.includes("delClassArr") && (function updateVideo(delClass) { (delClassArr = getDelClassArr(delClass)), delAd(getAd(queryNum, delClassArr, newVideoNum, 1)); })(settings.delClassArr.value)); } }, }; showEditArea(!0, callback); } let pageName = (function getBiliPageType() { const url = window.location.href, hostname = window.location.hostname, pathname = window.location.pathname; return "www.bilibili.com" !== hostname || ("/" !== pathname && "/index.html" !== pathname) ? url.includes("www.bilibili.com/video") ? "视频" : "search.bilibili.com" === hostname ? "搜索" : "space.bilibili.com" === hostname ? "主页" : url.includes("t.bilibili.com") || url.includes("www.bilibili.com/opus") ? "动态" : url.includes("www.bilibili.com/read") ? "专栏" : url.includes("www.bilibili.com/bangumi") ? "番剧" : "live.bilibili.com" === hostname ? "直播" : "message.bilibili.com" === hostname && "/" === pathname ? "消息" : "其他" : "首页"; })(window.location); if ( ((info.pageName = pageName), ("首页" !== pageName && "视频" !== pageName) || (getData(), GM_registerMenuCommand("设置", () => { showSettings(); })), "首页" === pageName) ) main(); else if ("视频" === pageName) { setTimeout(() => { videoObj.init(); }, videoObj.info.startTime); let url = window.location.href; const pathInterval = videoObj.info.pathInterval; setInterval(() => { url !== window.location.href && ((url = window.location.href), setTimeout(() => { videoObj.init(); }, videoObj.info.startTime)); }, pathInterval); } })();