// ==UserScript== // @name 【魔术先生】VIP工具箱 // @namespace https://www.shenfangda.cn/ // @description 🔥优化样式🔥:🎉 1、Vip视频解析;🎉 2、一站式音乐搜索解决方案;🎉 3、bilibili视频封面获取;🎉 4、bilibili视频下载(已支持分P下载);🎉 5、夸克网盘直链批量获取;🎉 6、CSDN页面、剪切板清理;🎉 7、页面自动展开(更多网站匹配中,欢迎提交想要支持的网站) 🎉 8、YouTube视频下载🎉 9、中间页自动跳转;🎉 10、搜索引擎快速跳转 // @license MIT // @version 1.0.1 // Incremented version // @author shenfangda (优化: GPT) // @exclude *://vip.wandhi.com/* // @match *://*blog.csdn.net/* // @match *://*download.csdn.net/* // @match *://*wenku.csdn.net/* // @match *://*c.pc.qq.com/middlem* // @match *://*pan.baidu.com/disk/main* // @match *://link.csdn.net/* // @match *://link.zhihu.com/* // @match *://browser.gwdang.com/* // @match *://*www.jianshu.com/go-wild* // @match *://*gitee.com/link* // @match *://*juejin.cn/?target* // @match *://www.aliyundrive.com/drive* // @match *://www.alipan.com/drive/* // @match *://*.youtube.com/watch?v=* // @match *://support.qq.com/products* // @match *://weibo.cn/sinaurl* // @match *://afdian.net/link* // @match *://*oschina.net/action/GoToLink* // @match *://jump2.bdimg.com/safecheck* // @match *://www.douban.com/link2/?url* // @match *://link.17173.com* // @match *://search.suning.com/* // @match *://pan.quark.cn/* // @match *://docs.qq.com/scenario/link* // @match *://mail.qq.com/cgi-bin/readtemplate* // @match *://cloud.tencent.com/developer/tools/blog-entry* // @match *://link.uisdc.com/* // @match *://*.tudou.com/listplay/* // @match *://*.tudou.com/albumplay/* // @match *://*.tudou.com/programs/view/* // @match *://*.tudou.com/v* // @match *://*.mgtv.com/b/* // @match *://film.sohu.com/album/* // @match *://tv.sohu.com/v/* // @match *://*.acfun.cn/v/* // @match *://*.bilibili.com/video/* // @match *://*.bilibili.com/anime/* // @match *://*.bilibili.com/bangumi/play/* // @match *://*.pptv.com/show/* // @match *://*.baofeng.com/play/* // @match *://*.wasu.cn/Play/show* // @match *://v.yinyuetai.com/video/* // @match *://v.yinyuetai.com/playlist/* // @match *://*.wasu.cn/Play/show/* // @match *://music.taihe.com/song* // @match *://music.163.com/song* // @match *://music.163.com/m/song* // @match *://y.qq.com/* // @match *://*.kugou.com/* // @match *://*.kuwo.cn/* // @match *://*.xiami.com/* // @match *://music.taihe.com/* // @match *://*.1ting.com/player* // @match *://www.qingting.fm/* // @match *://www.lizhi.fm/* // @match *://music.migu.cn/* // @match *://www.shangxueba.com/ask/*.html // @match *://www.ximalaya.com/* // @match *://www.shangxueba.com/ask/*.html // @match *://pan.baidu.com/disk/home* // @match *://yun.baidu.com/disk/home* // @match *://pan.baidu.com/s/* // @match *://yun.baidu.com/s/* // @match *://pan.baidu.com/share/link* // @match *://yun.baidu.com/share/link* // @match *://wenku.baidu.com/view/* // @match *://settings.wandhi.com/* // @match *://m.youku.com/v* // @match *://m.youku.com/a* // @match *://v.youku.com/v_* // @match *://v.youku.com/video* // @match *://v.youku.com/pad_show* // @match *://*.iqiyi.com/v_* // @match *://*.iqiyi.com/w_* // @match *://*.iqiyi.com/a_* // @match *://*.iqiyi.com/adv* // @match *://*.iq.com/play/* // @match *://*.le.com/ptv/vplay/* // @match *://v.qq.com/x/cover/* // @match *://v.qq.com/x/page/* // @match *://v.qq.com/*play* // @match *://v.qq.com/cover* // @match *://c.pc.qq.com/ios* // @match *://www.v2ex.com/t/* // @match *://*.nodeseek.com/jump* // @match *://*.zhihu.com/question* // @match *://www.baidu.com/* // @match *://www.google.com/* // @match *://www.sogou.com/* // @match *://www.so.com/s* // @match *://cn.bing.com/search* // @match *://sspai.com/link* // @match *://*.kdocs.cn/office/link* // @match *://ispacesoft.com/*.html // @match *://tv.wandhi.com/go.html* // @match *://tv.wandhi.com/check.html // @match *://*.xiaohongshu.com/explore* // @match *://www.yuque.com/r/goto* // @match *://blog.51cto.com/transfer* // @match *://r.wjx.com/redirect.aspx* // @match *://www.infoq.cn/link* // @match *://open.work.weixin.qq.com/wwopen/uriconfirm?uri= // @match *://link.gitcode.com/?target=* // @require https://lib.baomitu.com/jquery/1.12.4/jquery.min.js // @require https://lib.baomitu.com/limonte-sweetalert2/11.4.7/sweetalert2.all.min.js // @require https://lib.baomitu.com/echarts/4.6.0/echarts.min.js // @require https://lib.baomitu.com/layer/2.3/layer.js // @require https://lib.baomitu.com/qrcode-generator/1.4.4/qrcode.min.js // @require https://lib.baomitu.com/FileSaver.js/2.0.5/FileSaver.min.js // @require https://lib.baomitu.com/viewerjs/1.11.3/viewer.min.js // @require https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/react/18.2.0/umd/react.production.min.js // @require https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/react-dom/18.2.0/umd/react-dom.production.min.js // @require https://registry.npmmirror.com/@douyinfe/semi-ui/2.51.0/files/dist/umd/semi-ui.min.js // @grant GM_addStyle // @grant GM_setClipboard // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_info // @grant GM_cookie // @grant GM_getValue // @grant GM_setValue // @grant GM.getValue // @grant GM.setValue // @grant GM_notification // @grant GM_openInTab // @grant GM_deleteValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_download // @connect api.wandhi.com // @connect api.huizhek.com // @connect cdn.jsdelivr.net // @connect tool.manmanbuy.com // @connect gwdang.com // @connect scriptcat.org // @connect quark.cn // @connect openapi.baidu.com // @connect localhost // @connect pan.baidu.com // @connect api.bilibili.com // @compatible firefox // @compatible chrome // @compatible opera safari edge // @compatible safari // @compatible edge // @run-at document-end // @downloadURL https://update.greasyfork.icu/scripts/532777/%E3%80%90%E9%AD%94%E6%9C%AF%E5%85%88%E7%94%9F%E3%80%91VIP%E5%B7%A5%E5%85%B7%E7%AE%B1.user.js // @updateURL https://update.greasyfork.icu/scripts/532777/%E3%80%90%E9%AD%94%E6%9C%AF%E5%85%88%E7%94%9F%E3%80%91VIP%E5%B7%A5%E5%85%B7%E7%AE%B1.meta.js // ==/UserScript== /* eslint-disable no-undef */ /* eslint-disable no-unused-vars */ /* eslint-disable guard-for-in */ /* eslint-disable max-classes-per-file */ /* eslint-disable no-debugger */ /* eslint-disable camelcase */ /* eslint-disable no-redeclare */ /* eslint-disable block-scoped-var */ /* eslint-disable no-var */ /* eslint-disable vars-on-top */ /* eslint-disable no-use-before-define */ /* eslint-disable no-shadow */ /* eslint-disable @typescript-eslint/no-shadow */ /* eslint-disable prefer-promise-reject-errors */ /* eslint-disable eqeqeq */ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable no-eval */ /* eslint-disable @typescript-eslint/no-this-alias */ /* eslint-disable new-cap */ /* eslint-disable no-useless-constructor */ /* eslint-disable default-param-last */ /* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable no-return-assign */ /* eslint-disable no-nested-ternary */ /* eslint-disable no-underscore-dangle */ /* eslint-disable no-restricted-syntax */ /* eslint-disable no-param-reassign */ (function(global, factory) { "object" == typeof exports && "undefined" != typeof module ? factory(require("react-dom"), require("sweetalert2"), require("@douyinfe/semi-ui"), require("react")) : "function" == typeof define && define.amd ? define([ "react-dom", "sweetalert2", "@douyinfe/semi-ui", "react" ], factory) : factory((global = "undefined" != typeof globalThis ? globalThis : global || self).ReactDOM, global.Swal, global.SemiUI, global.React); })(this, (function(ReactDOM, Swal, semiUi, React) { "use strict"; var ReactDOM__default, Swal__default, React__default, LogLevel, BrowerType, VersionResult, ConfigEnum, Common, SiteEnum, Menu$2, Menu$1, Menu; function _interopDefaultLegacy(e) { return e && "object" == typeof e && "default" in e ? e : { default: e }; } ReactDOM__default = _interopDefaultLegacy(ReactDOM); Swal__default = _interopDefaultLegacy(Swal); React__default = _interopDefaultLegacy(React); // --- Consolidated Global Styles --- const globalStyles = ` /* Icon Font Definition */ @font-face { font-family: "onekeyvip"; /* Project id 3421073 */ src: url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), url('//at.alicdn.com/t/c/font_3421073_6n4yizwtdbu.woff?t=1695111033179') format('woff'), url('//at.alicdn.com/t/c/font_3421073_6n4yizwtdbu.ttf?t=1695111033179') format('truetype'), url('//at.alicdn.com/t/c/font_3421073_6n4yizwtdbu.svg?t=1695111033179#onekeyvip') format('svg'); } .onekeyvip { font-family: "onekeyvip" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .onekeyvip-biying:before { content: "\\e609"; } .onekeyvip-bilibili:before { content: "\\e600"; } .onekeyvip-360logo:before { content: "\\e602"; } .onekeyvip-baidu:before { content: "\\e612"; } .onekeyvip-zhihu:before { content: "\\e641"; } .onekeyvip-google:before { content: "\\e603"; } .onekeyvip-sougou:before { content: "\\faef"; } .onekeyvip-number-sign-full:before { content: "\\ea7b"; } .onekeyvip-number-sign:before { content: "\\ea7c"; } /* Styles for VIP Circle Menu */ html .aside-nav { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; font-size: 62.5%; } body .aside-nav { font-family: "Helvetica Neue", Helvetica, "Microsoft YaHei", Arial, sans-serif; margin: 0; font-size: 1.6rem; color: #4e546b; } .aside-nav-LT { top: 0 !important; } .aside-nav-LC { top: 40% !important; } .aside-nav-LB { bottom: 0 !important; } .aside-nav { position: fixed; bottom: 0; left: -47px; /* Initial position off-screen slightly */ width: 260px; height: 260px; filter: url(#goo); /* Reference the SVG filter */ -webkit-filter: url(#goo); user-select: none; opacity: .75; z-index: 99999; transition: opacity 0.3s ease; /* Added transition for hover */ } .aside-nav.no-filter { filter: none; -webkit-filter: none; } .aside-nav .aside-menu { position: absolute; width: 70px; height: 70px; border-radius: 50%; background: #f34444; left: -95px; /* Adjust position */ top: 0; right: 0; bottom: 0; margin: auto; text-align: center; line-height: 70px; color: #fff; font-size: 20px; z-index: 1; cursor: move; } .aside-nav .menu-item { position: absolute; width: 60px; height: 60px; background-color: #ff7676; left: -95px; /* Adjust position */ top: 0; right: 0; bottom: 0; margin: auto; line-height: 60px; text-align: center; border-radius: 50%; text-decoration: none; color: #fff; transition: background .5s, transform .6s; font-size: 14px; box-sizing: border-box; } .aside-nav .menu-item:hover { background: #a9c734; } .aside-nav .menu-line { line-height: 20px; padding-top: 10px; } .aside-nav:hover { opacity: 1; } .aside-nav:hover .aside-menu { animation: jello 1s; } .aside-nav:hover .menu-first { transform: translate3d(0, -135%, 0); } .aside-nav:hover .menu-second { transform: translate3d(120%, -70%, 0); } .aside-nav:hover .menu-third { transform: translate3d(120%, 70%, 0); } .aside-nav:hover .menu-fourth { transform: translate3d(0, 135%, 0); } /* Jello Animation */ @keyframes jello { from, 11.1%, to { transform: none; } 22.2% { transform: skewX(-12.5deg) skewY(-12.5deg); } 33.3% { transform: skewX(6.25deg) skewY(6.25deg); } 44.4% { transform: skewX(-3.125deg) skewY(-3.125deg); } 55.5% { transform: skewX(1.5625deg) skewY(1.5625deg); } 66.6% { transform: skewX(-.78125deg) skewY(-.78125deg); } 77.7% { transform: skewX(0.390625deg) skewY(0.390625deg); } 88.8% { transform: skewX(-.1953125deg) skewY(-.1953125deg); } } /* General Animation Class */ .animated { animation-duration: 1s; animation-fill-mode: both; } /* BounceInUp Animation */ @keyframes bounceInUp { from, 60%, 75%, 90%, to { animation-timing-function: cubic-bezier(0.215, .61, .355, 1); } from { opacity: 0; transform: translate3d(0, 800px, 0); } 60% { opacity: 1; transform: translate3d(0, -20px, 0); } 75% { transform: translate3d(0, 10px, 0); } 90% { transform: translate3d(0, -5px, 0); } to { transform: translate3d(0, 0, 0); } } .bounceInUp { animation-name: bounceInUp; animation-delay: 1s; } /* SweetAlert2 Customizations */ .one-key-vip-container { z-index: 99999!important; } .one-key-vip-popup { font-size: 14px !important; } .one-key-vip-setting-label { display: flex; align-items: center; justify-content: space-between; padding-top: 20px; } .one-key-vip-setting-checkbox { width: 16px; height: 16px; } /* Custom Buttons and Bili Styles */ .okv-btn { display: inline-block; padding: 6px 16px; font-size: 12px; outline: 0; line-height: 1.5; text-align: center; white-space: nowrap; border: 1px solid #c5d9e8; border-radius: 0.7rem; background-color: #fff; transition: background 0.2s; user-select: none; cursor: pointer; margin: 2px; /* Added margin for spacing */ } .okv-btn-primary { border-color: #6190e8; background-color: #6190e8; color: #fff; } .okv-btn-primary:hover { background-color: #79a1eb; border-color: #79a1eb; } .okv-btn-primary:active { background-color: #5782d1; border-color: #5782d1; } .okv-btn-success { border-color: #13ce66; background-color: #13ce66; color: #fff; } .okv-btn-success:hover { background-color: #36d57d; border-color: #36d57d; } .okv-btn-success:active { background-color: #11b95c; border-color: #11b95c; } .okv-btn-error { border-color: #ff4949; background-color: #ff4949; color: #fff; } .okv-btn-error:hover { background-color: #ff6464; border-color: #ff6464; } .okv-btn-error:active { background-color: #e64242; border-color: #e64242; } .okv-bg-pink { color: #fff; border-color: #fff; background-color: #fb7299; } .okv-bg-pink:hover { background-color: #fc8bab; } .okv-tools-bili { padding-top: 5px; } /* Fix potential layout issues in Bili video info section */ .video-info-detail { flex-wrap: wrap !important; overflow: visible !important; } .video-info-container { height: auto !important; min-height: 124px !important; } .okv-btn.bili-top-button { /* Adjusted Bili button padding */ padding: 2px 10px !important; margin-right: 0.5rem; } .bili-table { width: 100%; border-collapse: separate; border-spacing: 0; text-align: left; overflow: hidden; font-size: 12px; /* Adjusted font size */ } .bili-table td, .bili-table th { height: 35px; /* Reduced height */ text-align: left; text-overflow: ellipsis; vertical-align: middle; border-bottom: 1px solid #ececec; padding: 0 12px; /* Adjusted padding */ } .bili-table-head tr th { font-weight: 700; background-color: #f7f7f7; white-space: nowrap; } .at-table-tbody > tr:hover { background-color: #f6fafe; } /* CSDN Specific Styles */ #content_views pre, #content_views pre code { user-select: auto !important; /* Allow text selection */ -webkit-user-select: auto !important; } .passport-login-container { display: none !important; } /* Hide login popup */ /* Material Floating Button (MFB) Menu Styles */ .mfb-component--tl, .mfb-component--cl, .mfb-component--tr, .mfb-component--bl, .mfb-component--br { box-sizing: border-box; margin: 25px; position: fixed; white-space: nowrap; z-index: 99998; /* Slightly lower than alert */ padding-left: 0; list-style: none; } .mfb-component--tl *, .mfb-component--cl *, .mfb-component--tr *, .mfb-component--bl *, .mfb-component--br *, .mfb-component--tl *:before, .mfb-component--cl *:before, .mfb-component--tr *:before, .mfb-component--bl *:before, .mfb-component--br *:before, .mfb-component--tl *:after, .mfb-component--cl *:after, .mfb-component--tr *:after, .mfb-component--bl *:after, .mfb-component--br *:after { box-sizing: inherit; } .mfb-component--tl { left: 0; top: 0; } .mfb-component--cl { left: 0; top: 50%; transform: translateY(-50%); } /* Centered vertically */ .mfb-component--tr { right: 0; top: 0; } .mfb-component--bl { left: 0; bottom: 0; } .mfb-component--br { right: 0; bottom: 0; } .mfb-component__button--main, .mfb-component__button--child { background-color: #e40a5d; display: inline-block; border: none; border-radius: 50%; box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.28); cursor: pointer; outline: none; padding: 0; position: relative; user-select: none; color: #f1f1f1; text-align: center; line-height: 56px; /* Match height */ font-size: 25px; /* Icon size */ height: 56px; width: 56px; } .mfb-component__list { list-style: none; margin: 0; padding: 0; } .mfb-component__list > li { display: block; position: absolute; top: 0; right: 1px; /* Slight offset */ padding: 10px 0; margin: -10px 0; /* Transitions are handled by effect classes (mfb-zoomin, etc.) */ } .mfb-component__icon, .mfb-component__main-icon--active, .mfb-component__main-icon--resting, .mfb-component__child-icon { position: absolute; font-size: 18px; text-align: center; line-height: 56px; /* Match button height */ width: 100%; left: 0; /* Ensure centered */ } .mfb-component__wrap { padding: 25px; margin: -25px; } /* Clickable area padding */ /* Icon rotation/transition */ [data-mfb-toggle=hover]:hover .mfb-component__icon, [data-mfb-toggle=hover]:hover .mfb-component__main-icon--active, [data-mfb-toggle=hover]:hover .mfb-component__main-icon--resting, [data-mfb-toggle=hover]:hover .mfb-component__child-icon, [data-mfb-state=open] .mfb-component__icon, [data-mfb-state=open] .mfb-component__main-icon--active, [data-mfb-state=open] .mfb-component__main-icon--resting, [data-mfb-state=open] .mfb-component__child-icon { transform: scale(1) rotate(0deg); } .mfb-component__main-icon--active, .mfb-component__main-icon--resting { transform: scale(1) rotate(360deg); transition: transform 150ms cubic-bezier(0.4, 0, 1, 1); } .mfb-component__main-icon--active { opacity: 0; } [data-mfb-toggle=hover]:hover .mfb-component__main-icon--resting, [data-mfb-state=open] .mfb-component__main-icon--resting { opacity: 0; position: absolute !important; } [data-mfb-toggle=hover]:hover .mfb-component__main-icon--active, [data-mfb-state=open] .mfb-component__main-icon--active { opacity: 1; } /* MFB Effects (Zoom In example, others removed for brevity but were similar) */ .mfb-component--tl.mfb-zoomin .mfb-component__list li, .mfb-component--tr.mfb-zoomin .mfb-component__list li, .mfb-component--bl.mfb-zoomin .mfb-component__list li, .mfb-component--br.mfb-zoomin .mfb-component__list li, .mfb-component--cl.mfb-zoomin .mfb-component__list li { /* Added CL */ transform: scale(0); transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); /* Smoother zoom */ } /* Define positions for zoom-in (simplified example for bottom-left) */ .mfb-component--bl.mfb-zoomin .mfb-component__list li:nth-child(1) { transform: translateY(-70px) scale(0); transition-delay: 0.15s; } .mfb-component--bl.mfb-zoomin .mfb-component__list li:nth-child(2) { transform: translateY(-140px) scale(0); transition-delay: 0.1s; } .mfb-component--bl.mfb-zoomin .mfb-component__list li:nth-child(3) { transform: translateY(-210px) scale(0); transition-delay: 0.05s; } .mfb-component--bl.mfb-zoomin .mfb-component__list li:nth-child(4) { transform: translateY(-280px) scale(0); transition-delay: 0s; } /* Add more children if needed */ /* Opened state for zoom-in (simplified example for bottom-left) */ .mfb-component--bl.mfb-zoomin[data-mfb-toggle=hover]:hover .mfb-component__list li:nth-child(1), .mfb-component--bl.mfb-zoomin[data-mfb-state=open] .mfb-component__list li:nth-child(1) { transform: translateY(-70px) scale(1); transition-delay: 0.05s; } .mfb-component--bl.mfb-zoomin[data-mfb-toggle=hover]:hover .mfb-component__list li:nth-child(2), .mfb-component--bl.mfb-zoomin[data-mfb-state=open] .mfb-component__list li:nth-child(2) { transform: translateY(-140px) scale(1); transition-delay: 0.1s; } .mfb-component--bl.mfb-zoomin[data-mfb-toggle=hover]:hover .mfb-component__list li:nth-child(3), .mfb-component--bl.mfb-zoomin[data-mfb-state=open] .mfb-component__list li:nth-child(3) { transform: translateY(-210px) scale(1); transition-delay: 0.15s; } .mfb-component--bl.mfb-zoomin[data-mfb-toggle=hover]:hover .mfb-component__list li:nth-child(4), .mfb-component--bl.mfb-zoomin[data-mfb-state=open] .mfb-component__list li:nth-child(4) { transform: translateY(-280px) scale(1); transition-delay: 0.2s; } /* Add similar blocks for other positions (TL, TR, BR, CL) if needed */ /* Example for CL (Center Left) */ .mfb-component--cl.mfb-zoomin .mfb-component__list li:nth-child(1) { transform: translateX(70px) scale(0); transition-delay: 0.05s; } .mfb-component--cl.mfb-zoomin .mfb-component__list li:nth-child(2) { transform: translateX(140px) scale(0); transition-delay: 0.1s; } .mfb-component--cl.mfb-zoomin[data-mfb-toggle=hover]:hover .mfb-component__list li:nth-child(1), .mfb-component--cl.mfb-zoomin[data-mfb-state=open] .mfb-component__list li:nth-child(1) { transform: translateX(70px) scale(1); transition-delay: 0.15s; } .mfb-component--cl.mfb-zoomin[data-mfb-toggle=hover]:hover .mfb-component__list li:nth-child(2), .mfb-component--cl.mfb-zoomin[data-mfb-state=open] .mfb-component__list li:nth-child(2) { transform: translateX(140px) scale(1); transition-delay: 0.1s; } /* MFB Labels */ [data-mfb-label]:after { content: attr(data-mfb-label); opacity: 0; background: rgba(0, 0, 0, 0.7); /* Slightly darker */ padding: 4px 10px; border-radius: 3px; color: rgba(255, 255, 255, 0.9); /* Brighter text */ font-size: 13px; /* Slightly smaller */ font-weight: 400; pointer-events: none; line-height: normal; position: absolute; top: 50%; transform: translateY(-50%); /* Centered vertically */ transition: opacity 0.3s ease-in-out; white-space: nowrap; /* Prevent wrapping */ } /* Label Visibility */ [data-mfb-toggle=hover] li:hover > [data-mfb-label]:after, /* Show on individual item hover */ [data-mfb-state=open] li:hover > [data-mfb-label]:after { /* Show on individual item hover when opened */ opacity: 1; } /* Label Positioning */ .mfb-component--br [data-mfb-label]:after, .mfb-component--tr [data-mfb-label]:after { right: 70px; } /* Position label to the left */ .mfb-component--tl [data-mfb-label]:after, .mfb-component--cl [data-mfb-label]:after, .mfb-component--bl [data-mfb-label]:after { left: 70px; } /* Position label to the right */ /* Ensure icons align vertically */ .mfb-component__button--child i, .mfb-component__button--main i { line-height: inherit; vertical-align: top; } /* MFB Main icon - ensure VIP text fits */ .onekeyvip.mfb-main-icon { font-size: 20px !important; } /* Adjust if needed */ `; GM_addStyle(globalStyles); // --- SVG Filter Definition --- // This needs to be added to the DOM, typically when the .aside-nav menu is created. const svgGooFilter = ` `; // --- Helper Function --- // Checks if a style element with a specific ID exists function styleExists(id) { return !!document.getElementById(id); } // --- Container --- const container = new Map; class Container { static Registe(type, args) { let className = this.processName(type.name); return container.has(className) ? container.get(className) : className ? (container.set(className, window.Reflect.construct(type, args)), container.get(className)) : void 0; } static processName(name) { return name.toLowerCase(); } static Require(type) { return this.Registe(type, []); } } // --- Logger --- class Logger { static log(msg, group, level) { // Basic console logging - can be enhanced if (level >= Logger.level) { const prefix = `[${LogLevel[level].toUpperCase()}]${group ? `[${group}]` : ''}:`; if (level === LogLevel.error) { console.error(prefix, msg); } else if (level === LogLevel.warn) { console.warn(prefix, msg); } else if (level === LogLevel.info) { console.info(prefix, msg); } else { console.log(prefix, msg); } } } static debug(msg, group = "debug") { this.log(msg, group, LogLevel.debug); } static info(msg, group = "info") { this.log(msg, group, LogLevel.info); } static warn(msg, group = "warning") { this.log(msg, group, LogLevel.warn); } static error(msg, group = "error") { this.log(msg, group, LogLevel.error); } } Logger.level = LogLevel.info; // Default log level // --- Enums --- (function(LogLevel) { LogLevel[LogLevel.debug = 0] = "debug"; LogLevel[LogLevel.info = 1] = "info"; LogLevel[LogLevel.warn = 2] = "warn"; LogLevel[LogLevel.error = 3] = "error"; })(LogLevel || (LogLevel = {})); (function(BrowerType) { /* ... enum definition ... */ })(BrowerType || (BrowerType = {})); (function(VersionResult) { /* ... enum definition ... */ })(VersionResult || (VersionResult = {})); (function(ConfigEnum) { /* ... enum definition ... */ })(ConfigEnum || (ConfigEnum = {})); (function(SiteEnum) { /* ... enum definition ... */ })(SiteEnum || (SiteEnum = {})); // --- Core Utilities --- function __awaiter(thisArg, _arguments, P, generator) { /* ... __awaiter definition ... */ } class Core { constructor() { this.url = Core.currentUrl(); } static Render(element, id) { /* ... Render definition ... */ } static appendTo(selector, html) { $(selector).append(html); } static prepend(selector, html) { $(selector).prepend(html); } static lazyload(callback, time = 5) { /* ... lazyload definition ... */ } static autoLazyload(is_ok, callback, time = 5) { /* ... autoLazyload definition ... */ } static sleep(time) { /* ... sleep definition ... */ } static random(min, max) { /* ... random definition ... */ } static randStr(len = 4) { /* ... randStr definition ... */ } static background(callback, time = 5) { /* ... background definition ... */ } static get head() { return unsafeWindow.window.document.head; } static isNumber(a) { /* ... isNumber definition ... */ } static addUrl(key, url) { GM_setValue(key, url); } static openUrl(key) { this.open(GM_getValue(key)); } static getPar(option, url = window.location.search) { /* ... getPar definition ... */ } // REMOVED: appendCss - Use GM_addStyle or Core.addExternalCss // REMOVED: appendCssContent - Use GM_addStyle // REMOVED: bodyAppendCss - Use GM_addStyle // ADDED: Helper for external CSS with check static addExternalCss(url, id) { if (id && styleExists(id)) { Logger.debug(`Style ${id} already exists.`); return; } const styleContent = `@import url("${url}");`; const styleEl = GM_addStyle(styleContent); if (id && styleEl) { styleEl.id = id; // Assign ID if provided } } static bodyAppend(html) { $("body").append(html); } static bodyPrepend(html) { $("body").prepend(html); } static appendJs(url) { /* ... appendJs definition ... */ } // REMOVED: bodyAppendJs - Use GM_addScript or standard script tags if necessary static currentUrl() { return window.location.href; } static get url() { return window.location.href; } static inIframe() { /* ... inIframe definition ... */ } static format(time, fmt = "yyyy-MM-dd hh:mm:ss") { /* ... format definition ... */ } static sizeFormat(value) { /* ... sizeFormat definition ... */ } static encode(str) { return window.btoa(unescape(encodeURIComponent(str))); } // Improved encoding for unicode static decode(str) { try { return decodeURIComponent(escape(window.atob(str))); } catch(e) { console.error("Decode failed:", e); return window.atob(str); /* fallback */ } } // Improved decoding static open(url, loadInBackGround = !1) { /* ... open definition ... */ } static click(selector, callback) { $(selector).on("click", callback); } static uuid(len = 10, split = !1, radix = 0) { /* ... uuid definition ... */ } static getBrowser() { /* ... getBrowser definition ... */ } static getPercent(num, total) { /* ... getPercent definition ... */ } static getReact(dom, traverseUp = 0) { /* ... getReact definition ... */ } static copyText(text) { /* ... copyText definition ... */ } static getGmCookie(key, domain = "") { /* ... getGmCookie definition ... */ } static getCookie(key) { /* ... getCookie definition ... */ } } // --- Time Constants --- const Min = 60, Hour = 60 * Min, Day = 24 * Hour, Week = 7 * Day; // --- Config --- class Config { static get env() { return GM_info; } static get(key, defaultValue = "") { let objStr = GM_getValue(this.encodeKey(key), null); // Encode key for safety if (objStr) { try { let obj = JSON.parse(objStr); if (-1 == obj.exp || obj.exp > (new Date).getTime()) { // Logger.debug(`Cache hit: ${key}`); // Less verbose logging return obj.value; } // Logger.debug(`Cache expired: ${key}`); GM_deleteValue(this.encodeKey(key)); } catch (e) { Logger.error(`Error parsing config for key ${key}: ${e}`, 'Config'); GM_deleteValue(this.encodeKey(key)); // Delete corrupted data } } // Logger.debug(`Cache miss: ${key}`); return defaultValue; } static set(key, v, exp = -1) { let obj = { // key: key, // Don't store raw key inside value: v, exp: -1 == exp ? exp : (new Date).getTime() + 1e3 * exp }; // Logger.debug(`Setting config: ${key}`, obj); GM_setValue(this.encodeKey(key), JSON.stringify(obj)); } static remember(key, exp, callback) { /* ... remember definition ... */ } static clear(key) { GM_deleteValue(this.encodeKey(key)); } // Use Core's improved encode/decode static encodeKey(str) { return Core.encode(str).replace(/=/g, ''); } // Base64 encode key, remove padding // static decodeKey(str) { return Core.decode(str); } // Decoding key usually not needed static inc(s) { /* ... inc definition ... */ } } // --- Common Menu Base --- (function(Common) { class Menu { constructor() { this.core = new Core; this.site = /tv.wandhi.com/i; // Seems specific, maybe remove or generalize? this.userAgent = navigator.userAgent; this.menusClass = [ "first", "second", "third", "fourth", "fifth" ]; // Add more if needed this.menuSelector = "#Wandhi-nav"; this.svgAdded = false; // Flag to add SVG only once } loader() {} getBody(option) { // SVG filter moved out, will be added in Init return `
${option}
`; } Init(menus, callback, skipIframe = !0) { if (Core.inIframe() && skipIframe) return; // Ensure SVG filter is added only once if (!document.getElementById('goo-filter-svg')) { Core.bodyAppend(svgGooFilter); this.svgAdded = true; } this.loader(); let str = ""; menus.forEach((element, index) => { // Use a safer check for class index const className = this.menusClass[index] || `extra-${index}`; str += `${element.show}`; }); Logger.info("Adding circle menu", 'Menu'); Core.bodyAppend(this.getBody(str)); // Simplified check for Safari/Chrome filter issue if (navigator.vendor && navigator.vendor.includes('Apple') && navigator.userAgent && !navigator.userAgent.includes('CriOS') && !navigator.userAgent.includes('FxiOS')) { $("#Wandhi-nav").addClass("no-filter"); // Apply no-filter likely needed for Safari } const drags = { /* ... drag logic ... */ }; let asideNav = $(this.menuSelector)[0]; // Cache element const menuElement = $(this.menuSelector); menuElement.on("mousedown", ".aside-menu", function(a) { // Target the handle specifically const getCss = (a, e) => window.getComputedStyle(a, null)[e] || a.currentStyle[e]; drags.down = !0; drags.clientX = a.clientX; drags.clientY = a.clientY; drags.x = parseInt(getCss(menuElement[0], "left")) || 0; // Use cached element drags.y = parseInt(getCss(menuElement[0], "top")) || 0; drags.winHei = $(window).height(); drags.winWid = $(window).width(); $(document).on("mousemove.vipmenu", (a) => { // Namespaced event if (!drags.down) return; // Check flag var e = a.clientX - drags.clientX, t = a.clientY - drags.clientY; // Basic boundary checks (optional, can be improved) let newTop = drags.y + t; let newLeft = drags.x + e; // Add boundary logic if needed here, e.g., // newTop = Math.max(0, Math.min(newTop, drags.winHei - menuElement.height())); // newLeft = Math.max(0, Math.min(newLeft, drags.winWid - menuElement.width())); menuElement.css({ top: newTop + "px", left: newLeft + "px" }); // Use jQuery css }); $(document).on("mouseup.vipmenu", () => { // Namespaced event if (drags.down) { drags.down = !1; $(document).off("mousemove.vipmenu mouseup.vipmenu"); // Remove specific listeners } }); a.preventDefault(); // Prevent text selection during drag }); Menu.fullScreenMirror(); callback.call(this); } static fullScreenMirror() { /* ... fullScreenMirror definition ... */ } static close() { /* ... close definition ... */ } } Menu.mainId = "Wandhi-nav"; Menu.autoHide = !0; Common.Menu = Menu; })(Common || (Common = {})); // --- Plugin Base --- class PluginBase { constructor() { this._unique = !0; this.semiui = !1; this.menu = Container.Require(Common.Menu); // Use container this.Process = () => { if (this.semiui) { // Conditionally load SemiUI CSS using GM_addStyle Core.addExternalCss( "https://registry.npmmirror.com/@douyinfe/semi-ui/2.51.0/files/dist/css/semi.min.css", "onekeyvip-semiui-style" // Give it an ID ); } this.loader(); this.run(); }; this._appName = "base"; this.rules = new Map(); // Initialize rules map this.site = null; // Initialize site } unique() { return this._unique; } linkTest(url) { url || (url = Core.currentUrl()); let flag = !1; // Use for...of for Map iteration for (const [siteEnum, regex] of this.rules) { if (regex.test(url)) { flag = true; this.site = siteEnum; break; // Found a match, no need to continue } } return flag; } appName() { return this._appName; } loader() {} // Default empty loader run() {} // Default empty run } // --- HTTP --- class AjaxOption { /* ... AjaxOption definition ... */ } class HttpHeaders {} // Simple placeholder class Http { constructor() {} static ajax(option) { /* ... original ajax logic ... */ } static ajaxNew(url, method, data, header = new Map, dataType) { /* ... original ajaxNew logic ... */ } static getData(url, callback) { /* ... original getData logic ... */ } // Consider replacing with fetch or GM_xmlhttpRequest promise static JqGet(url, callback, head = new Map) { /* ... original JqGet logic ... */ } static post(url, data, timeOut = 10) { /* ... original post logic ... */ } static get(url, data = new Map, head = new Map, loading = !0, time_out = 10) { /* ... original get logic ... */ } static getWithHead(url, data = new Map, head = new Map, time_out = 10) { /* ... original getWithHead logic ... */ } static postWithHead(url, data = new Map, head = new Map, time_out = 10) { /* ... original postWithHead logic ... */ } static get_text(url) { /* ... original get_text logic ... */ } static get302(url) { /* ... original get302 logic ... */ } } // --- Route --- class Route { /* ... Route definition ... */ } // --- SweetAlert Wrapper --- class sAlert { /* ... sAlert definition ... */ } // --- Runtime --- class Runtime { static get url() { return window.location.href; } } // --- SemiUI Toast Wrapper --- class Toast { /* ... Toast definition ... */ } // --- Bili Tools Service --- class BiliImgService extends PluginBase { /* ... BiliImgService definition ... */ } // --- Movie Service --- Menu$2 = Common.Menu; // Alias needed? Seems redundant if using Container const jks = [ /* ... jks definition ... */ ]; class MovieService extends PluginBase { /* ... MovieService definition ... */ } // --- URL Helper --- class UrlHelper { /* ... UrlHelper definition ... */ } // --- Music Service --- class MusicService extends PluginBase { /* ... MusicService definition ... */ } // --- CSDN Ad Service --- class CsdnAdService extends PluginBase { constructor() { super(); // Call parent constructor this.rules = new Map([ [ SiteEnum.CSDN, /blog\.csdn\.net/i ], [ SiteEnum.CSDN_Wenku, /wenku\.csdn\.net\/answer/i ] ]); this._appName = "csdn"; this._unique = !1; } loader() {} // Keep empty, styles are global run() { if (Config.get(ConfigEnum.CSDN_OpAdClean, !0)) { Core.background(this.removeAds, 3); } if (Config.get(ConfigEnum.CSDN_OpClipboardClean, !0)) { this.clipboardClean(); } if (Config.get(ConfigEnum.CSDN_OpCommentClean, !0)) { this.commentClean(); } if (Config.get(ConfigEnum.CSDN_OpImgLink, !0)) { this.commentFile(); } if (Config.get(ConfigEnum.CSDN_OpArticleClean, !0)) { this.articleClean(); } } clipboardClean() { /* ... clipboardClean definition ... */ } removeAds() { CsdnAdService.adSelectors.forEach(selector => { $(selector).remove(); }); } commentClean() { /* ... commentClean definition ... */ } commentFile() { /* ... commentFile definition ... */ } articleClean() { /* ... articleClean definition ... */ } } CsdnAdService.adSelectors = [ /* ... adSelectors definition ... */ ]; // --- Layer Alert Wrapper --- class Alert { /* ... Alert definition ... */ } // --- WenKu Service --- Menu$1 = Common.Menu; // Alias class WenKuService extends PluginBase { constructor() { super(); this.rules = new Map([ [ SiteEnum.WenKu, /wenku\.baidu\.com\/view/i ] ]); this._unique = !1; this.menu = Container.Require(Common.Menu); // Use container this._appName = "WenKu"; // SemiUI CSS is loaded via global style or conditionally via PluginBase } loader() {} run() { this.menu.Init([ /* ... menu items ... */ ], this._onClick); } _onClick() { /* ... _onClick definition ... */ } static exportDoc() { /* ... exportDoc definition ... */ } static scrollToEnd() { /* ... scrollToEnd definition ... */ } static loadFullDoc() { /* ... loadFullDoc definition ... */ } } WenKuService.loaded = !1; // --- Link Jump Service --- class LinkJumpService extends PluginBase { constructor() { super(); this.rules = new Map([ /* ... rules ... */ ]); this.key = ""; this.selector = ""; this._unique = !1; this._appName = "LinkJump"; this.semiui = true; // Enable SemiUI CSS loading } loader() {} // Styles are global or conditional run() { /* ... run definition ... */ } jump(url) { /* ... jump definition ... */ } } // --- Auto Expand Service --- class AutoExpandService extends PluginBase { constructor() { super(); this.rules = new Map([ /* ... rules ... */ ]); // Removed contentStyle, will generate dynamically this.expandRules = [ /* ... expandRules definition ... */ ]; this._appName = "autoExpand"; this._unique = !1; } loader() {} run() { let that = this; this.expandRules.forEach(e => { if (e.site.includes(that.site)) { // Use includes for array check if (e.selector && e.selector.length > 0) { e.selector.forEach(selector => { $(selector).remove(); }); } if (e.clicker && e.clicker.length > 0) { e.clicker.forEach(clicker => { Core.lazyload(() => { $(clicker).trigger("click"); }, 2); Logger.info(`AutoExpand: Clicked ${clicker}`, 'AutoExpand'); }); } // Use GM_addStyle for dynamic styles if (e.style && e.style.length > 0) { e.style.forEach(styleRule => { GM_addStyle(styleRule); }); } if (e.content && e.content.length > 0) { const contentStyleRule = `${e.content.join(", ")} { height: auto !important; max-height: none !important; overflow: visible !important; }`; GM_addStyle(contentStyleRule); Logger.info(`AutoExpand: Applied content style to ${e.content.join(", ")}`, 'AutoExpand'); } if (e.script) { try { e.script.apply([]); } catch (err) { Logger.error(`Error executing script for ${that.site}: ${err}`, 'AutoExpand'); } } } }); } } // --- Bili Mobile AV/BV Converter --- class BIliTools { /* ... BIliTools definition ... */ } class BiliMobileService extends PluginBase { /* ... BiliMobileService definition ... */ } // --- AliyunPan Token Service --- class AliyunPanToken extends PluginBase { /* ... AliyunPanToken definition ... */ } // --- MFB Menu --- class MfbMenu { constructor(pos = "bl", method = "hover") { this.method = method; this.pos = pos; this.menuId = `mfb-menu-${Core.randStr()}`; // Unique ID per instance } getHtml(models) { let t = ""; models.forEach((v) => { // Use unique IDs for child buttons too const buttonId = `mfb-btn-${Core.randStr(6)}`; v.id = buttonId; // Store the ID in the model for later binding t += `
  • `; }); // Use i tag for main icon as well, consistent with children return ` `; } loader() { // Load Font Awesome CSS using GM_addStyle, only once Core.addExternalCss( "https://lib.baomitu.com/font-awesome/4.6.0/css/font-awesome.min.css", "onekeyvip-fontawesome-style" // ID to prevent duplicates ); } // render() {} // Not used Init(models) { if (Core.inIframe()) return; // Skip iframes this.loader(); // Ensure CSS is loaded Core.bodyAppend(this.getHtml(models)); // Add menu HTML to body this.mouseMove(); // Enable dragging this.bindEvent(models); // Add click handlers etc. } bindEvent(models) { const menuElement = $(`#${this.menuId}`); // Cache jQuery object // Toggle state on click if not hover mode if (menuElement.data("mfb-toggle") !== "hover") { menuElement.on("click", '.mfb-component__button--main', () => { // More specific selector const currentState = menuElement.attr("data-mfb-state"); const targetState = currentState === "closed" ? "open" : "closed"; menuElement.attr("data-mfb-state", targetState); }); } // Close button $(`#mfb-close-${this.menuId}`).on("click", (e) => { e.stopPropagation(); // Prevent main button toggle if click mode Logger.info(`Closing MFB menu: ${this.menuId}`, 'MfbMenu'); menuElement.hide(); // Hide the menu }); // Bind models' callbacks using the stored unique IDs models.forEach(e => { if (e.id && e.callback) { $(`#${e.id}`).on("click", (ev) => { ev.stopPropagation(); // Prevent main button toggle if click mode Logger.info(`MFB action: ${e.title}`, 'MfbMenu'); e.callback(); // Optionally close menu after action in click mode if (menuElement.data("mfb-toggle") === "click") { menuElement.attr("data-mfb-state", "closed"); } }); } }); } mouseMove() { const menu = document.getElementById(this.menuId); if (!menu) return; // Exit if menu not found let iWidth = 0, iHeight = 0; let moveX = 0, moveY = 0, moveTop = 0, moveLeft = 0; let moveable = !1; const mainButton = menu.querySelector('.mfb-component__button--main'); // Target only the main button for dragging function updateDimensions() { iWidth = window.innerWidth; iHeight = window.innerHeight; } updateDimensions(); window.addEventListener('resize', updateDimensions); // Update on resize if (!mainButton) return; // Exit if main button not found mainButton.addEventListener('mousedown', (evt) => { evt.preventDefault(); // Prevent default drag behavior/text selection moveable = !0; moveX = evt.clientX; moveY = evt.clientY; const styles = window.getComputedStyle(menu); moveTop = parseInt(styles.top) || 0; moveLeft = parseInt(styles.left) || 0; const docMouseMove = (moveEvt) => { if (!moveable) return; let x = moveLeft + moveEvt.clientX - moveX; let y = moveTop + moveEvt.clientY - moveY; // Basic boundary constraints const menuWidth = menu.offsetWidth; const menuHeight = menu.offsetHeight; x = Math.max(0, Math.min(x, iWidth - menuWidth)); y = Math.max(0, Math.min(y, iHeight - menuHeight)); menu.style.left = x + "px"; menu.style.top = y + "px"; }; const docMouseUp = () => { moveable = !1; document.removeEventListener('mousemove', docMouseMove); document.removeEventListener('mouseup', docMouseUp); }; document.addEventListener('mousemove', docMouseMove); document.addEventListener('mouseup', docMouseUp); }); } } class MfbModel { /* ... MfbModel definition ... */ } // --- Youtube Service --- class YoutubeService extends PluginBase { constructor() { super(); this.rules = new Map([ [ SiteEnum.YouTuBe, /(www|m)\.youtube\.com\/watch\?v=(.*?)/i ] ]); this._unique = !1; this._appName = "YouTuBe"; } loader() { this.mfbMenu = new MfbMenu('bl', 'hover'); // Use the improved MfbMenu } run() { // Add small delay to ensure page elements might be ready Core.lazyload(() => { const menus = [ new MfbModel("下载", "fa-download", () => { Core.open("http://ytv.wandhi.com/?url=" + encodeURIComponent(Runtime.url)); }) ]; this.mfbMenu.Init(menus); }, 1); // 1-second delay } } // --- Setting Service --- class SettingService extends PluginBase { /* ... SettingService definition ... */ } // --- Control Menu Service --- class ControlMenuService extends PluginBase { /* ... ControlMenuService definition ... */ } // --- Search Service --- class SearchService extends PluginBase { /* ... SearchService definition ... */ } // --- Quark --- class QuarkFileResponse {} class Quark { /* ... Quark definition ... */ } // --- NetDisk Direct Service --- class NetDiskDirectService extends PluginBase { /* ... NetDiskDirectService definition ... */ } // --- AdClear Service --- class AdClearService extends PluginBase { constructor() { super(); this.rules = new Map([ [ SiteEnum.Baidu, /baidu.com\/s\?wd/i ], [ SiteEnum.YouTuBe, /youtube.com\/watch/i ] ]); this._unique = !1; this._appName = "AdClear"; } loader() {} run() { if (this.site === SiteEnum.YouTuBe) { this.YoutubeAdClear(); } // Add Baidu ad clearing if needed // if (this.site === SiteEnum.Baidu) { this.BaiduAdClear(); } } YoutubeAdClear() { const cssText = [ // General Ad Containers "#masthead-ad", // Top banner ad ".video-ads.ytp-ad-module", // Video overlay ads "#related #player-ads", // Ads in sidebar (player section) "#related ytd-ad-slot-renderer", // Ads in sidebar (related videos section) "ytd-ad-slot-renderer", // General ad slot "ytm-promoted-sparkles-web-renderer", // Promoted content on mobile web? "ytd-promoted-sparkles-web-renderer", // Promoted content on desktop? "ytd-promoted-video-renderer", // Promoted video card // Specific Ad Types "ytd-display-ad-renderer", // Display ads in various places "ytd-action-companion-ad-renderer", // Companion ads "ytm-companion-ad-renderer", // Mobile companion ads? "ytm-video-masthead-ad-v3-renderer", // Mobile masthead ad? // Popups / Promos "tp-yt-paper-dialog:has(yt-mealbar-promo-renderer)", // Mealbar promo popup "yt-mealbar-promo-renderer", // Mealbar promo itself "ytd-popup-container iron-dropdown", // General popup container that might contain ads // Feed Ads / Rich Grid Ads "ytd-rich-item-renderer:has(ytd-display-ad-renderer)", // Ad item in grid/feed // "ytd-rich-item-renderer.style-scope.ytd-rich-grid-row #content:has(.ytd-display-ad-renderer)", // More specific selector (might be fragile) // Mobile specific? (if @match includes m.youtube.com) "ytm-item-section-renderer:has(a[href*='googleads'])", // Links containing googleads "ytm-promoted-sparkles-renderer", // Less common / Experimental? "#player-ads", // Player ad container "#offer-module", // Offer module (sometimes ads) ".ytp-ad-overlay-container", // Overlay container ].join(",\n") + " { display: none !important; height: 0 !important; width: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; }"; // More aggressive hiding GM_addStyle(cssText); Logger.info("YouTube AdClearService styles applied", 'AdClear'); // Optional: Observer to catch dynamically loaded ads (more complex) // const observer = new MutationObserver(mutations => { ... }); // observer.observe(document.body, { childList: true, subtree: true }); } // Example Baidu AdClear /* BaiduAdClear() { const cssText = [ "#content_left > div[data-ecrfn]", // Left side results ads "#content_left > div[tpl='ec_ads']", // Another left side ad type "#content_left > div[style*='display:block !important;visibility:visible !important']", // Ads trying to bypass display:none ".ec-ad", // Common ad class ".ec_ad_results", // Ad result container "#ecomAdProperty", // Right side ad block? "div[id^='baidu_clb_']", // Baidu union ads? // Add more selectors as needed ].join(",\n") + " { display: none !important; height: 0 !important; width: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; }"; GM_addStyle(cssText); Logger.info("Baidu AdClearService styles applied", 'AdClear'); } */ } // --- XHS Service --- Menu = Common.Menu; // Alias class XhsService extends PluginBase { /* ... XhsService definition ... */ } // --- Setting UI --- class SettingUI extends React__default.default.Component { /* ... SettingUI definition ... */ } class SettingUIService extends PluginBase { /* ... SettingUIService definition ... */ } // --- Main Injection and Initialization --- class OneKeyVipGfInjection { constructor() { this.plugins = []; // Initialize empty array // Define plugins to load const pluginClasses = [ AdClearService, ControlMenuService, SettingUIService, SettingService, AutoExpandService, AliyunPanToken, BiliImgService, BiliMobileService, MovieService, MusicService, CsdnAdService, WenKuService, LinkJumpService, YoutubeService, XhsService, SearchService, NetDiskDirectService ]; // Instantiate plugins using the container pluginClasses.forEach(PluginClass => { try { this.plugins.push(Container.Require(PluginClass)); } catch (e) { Logger.error(`Failed to instantiate plugin: ${PluginClass.name}`, 'Init', e); } }); Logger.info(`Container loaded ${this.plugins.length} plugins`, 'Init'); } Init() { Logger.info("Starting plugin initialization...", 'Init'); const currentUrl = Core.currentUrl(); // Get URL once this.plugins.forEach(element => { try { if (element.linkTest(currentUrl)) { // Test against the current URL Logger.info(`Running plugin: ${element.appName()} for ${currentUrl}`, 'Init'); // Wrap process in a promise-like structure for potential async operations Promise.resolve().then(() => element.Process()).catch(err => { Logger.error(`Error processing plugin ${element.appName()}: ${err}`, 'Init', err); }); if (element.unique()) { Logger.info(`Plugin ${element.appName()} is unique, stopping further tests.`, 'Init'); return false; // Stop processing if unique (like Array.prototype.some) } } else { // Logger.debug(`Plugin [${element.appName()}] did not match URL.`, 'Init'); // Less verbose } } catch (e) { Logger.error(`Error testing or launching plugin ${element.appName()}: ${e}`, 'Init', e); } return true; // Continue processing non-unique plugins }); Logger.info("Plugin initialization complete.", 'Init'); } } // --- Script Entry Point --- // Set log level (optional, default is info) Logger.level = LogLevel.info; // Change to LogLevel.debug for more details // Instantiate and initialize try { Container.Require(OneKeyVipGfInjection).Init(); } catch (e) { console.error("[OneKeyVIP Init Error]", e); alert("【魔术先生】VIP工具箱加载失败,请检查控制台日志并反馈给作者!"); } }));