CSDN优化

支持手机端和PC端,屏蔽广告,优化浏览体验,自动跳转拦截的URL

当前为 2024-05-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name CSDN优化
  3. // @namespace https://github.com/WhiteSevs/TamperMonkeyScript
  4. // @version 2024.5.23
  5. // @author WhiteSevs
  6. // @description 支持手机端和PC端,屏蔽广告,优化浏览体验,自动跳转拦截的URL
  7. // @license GPL-3.0-only
  8. // @icon https://www.csdn.net/favicon.ico
  9. // @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
  10. // @match *://*.csdn.net/*
  11. // @require https://update.greasyfork.org/scripts/494167/1376186/CoverUMD.js
  12. // @require https://update.greasyfork.org/scripts/465772/1360574/DOMUtils.js
  13. // @require https://update.greasyfork.org/scripts/455186/1377415/WhiteSevsUtils.js
  14. // @require https://update.greasyfork.org/scripts/456485/1371568/pops.js
  15. // @require https://cdn.jsdelivr.net/npm/qmsg@1.0.5/dist/index.umd.js
  16. // @grant GM_addStyle
  17. // @grant GM_cookie
  18. // @grant GM_deleteValue
  19. // @grant GM_getValue
  20. // @grant GM_info
  21. // @grant GM_registerMenuCommand
  22. // @grant GM_setValue
  23. // @grant GM_unregisterMenuCommand
  24. // @grant GM_xmlhttpRequest
  25. // @grant unsafeWindow
  26. // @run-at document-start
  27. // ==/UserScript==
  28.  
  29. (function (Qmsg) {
  30. 'use strict';
  31.  
  32. var _a, _b, _c;
  33. var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
  34. var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
  35. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  36. var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
  37. var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  38. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  39. var _GM_unregisterMenuCommand = /* @__PURE__ */ (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)();
  40. var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  41. var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  42. var _monkeyWindow = /* @__PURE__ */ (() => window)();
  43. const SCRIPT_NAME$1 = "CSDN优化";
  44. const utils = (_a = _monkeyWindow.Utils || _unsafeWindow.Utils) == null ? void 0 : _a.noConflict();
  45. const DOMUtils = (_b = _monkeyWindow.DOMUtils || _unsafeWindow.DOMUtils) == null ? void 0 : _b.noConflict();
  46. const pops = _monkeyWindow.pops || _unsafeWindow.pops;
  47. const log = new utils.Log(
  48. _GM_info,
  49. _unsafeWindow.console || _monkeyWindow.console
  50. );
  51. const SCRIPT_NAME = ((_c = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _c.name) || SCRIPT_NAME$1;
  52. const DEBUG = false;
  53. log.config({
  54. debug: DEBUG,
  55. logMaxCount: 2e4,
  56. autoClearConsole: true,
  57. tag: true
  58. });
  59. Qmsg.config({
  60. position: "bottom",
  61. html: true,
  62. maxNums: 5,
  63. autoClose: true,
  64. showClose: false,
  65. showReverse: true
  66. });
  67. const GM_Menu = new utils.GM_Menu({
  68. GM_getValue: _GM_getValue,
  69. GM_setValue: _GM_setValue,
  70. GM_registerMenuCommand: _GM_registerMenuCommand,
  71. GM_unregisterMenuCommand: _GM_unregisterMenuCommand
  72. });
  73. const httpx = new utils.Httpx(_GM_xmlhttpRequest);
  74. httpx.config({
  75. logDetails: DEBUG,
  76. onabort() {
  77. Qmsg.warning("请求取消");
  78. },
  79. ontimeout() {
  80. Qmsg.error("请求超时");
  81. },
  82. onerror(response) {
  83. Qmsg.error("请求异常");
  84. log.error(["httpx-onerror 请求异常", response]);
  85. }
  86. });
  87. ({
  88. Object: {
  89. defineProperty: _unsafeWindow.Object.defineProperty
  90. },
  91. Function: {
  92. apply: _unsafeWindow.Function.prototype.apply,
  93. call: _unsafeWindow.Function.prototype.call
  94. },
  95. Element: {
  96. appendChild: _unsafeWindow.Element.prototype.appendChild
  97. },
  98. setTimeout: _unsafeWindow.setTimeout
  99. });
  100. const KEY = "GM_Panel";
  101. const ATTRIBUTE_KEY = "data-key";
  102. const ATTRIBUTE_DEFAULT_VALUE = "data-default-value";
  103. const CSDNRouter = {
  104. /**
  105. * 判断是否是华为云联盟
  106. * + huaweicloud.csdn.net
  107. */
  108. isHuaWeiCloudBlog() {
  109. return Boolean(/huaweicloud.csdn.net/i.test(window.location.origin));
  110. },
  111. /**
  112. * 判断是否是博客
  113. * + blog.csdn.net
  114. */
  115. isBlog() {
  116. return Boolean(/blog.csdn.net/i.test(window.location.origin));
  117. },
  118. /**
  119. * 判断是否是文库
  120. * + wenku.csdn.net
  121. */
  122. isWenKu() {
  123. return Boolean(/wenku.csdn.net/i.test(window.location.origin));
  124. },
  125. /**
  126. * 判断是否是链接
  127. * + link.csdn.net
  128. */
  129. isLink() {
  130. return window.location.hostname === "link.csdn.net";
  131. },
  132. /**
  133. * 判断是否是搜索
  134. * + so.csdn.net
  135. */
  136. isSo() {
  137. return window.location.hostname === "so.csdn.net";
  138. },
  139. /**
  140. * 判断是否是C知道
  141. * + so.csdn.net/know
  142. * + /chat
  143. * + /so/ai
  144. */
  145. isSoCKnow() {
  146. return this.isSo() && (window.location.pathname.startsWith("/chat") || window.location.pathname.startsWith("/so/ai"));
  147. }
  148. };
  149. const UISlider = function(text, key, defaultValue, min, max, changeCallBack, getToolTipContent, description) {
  150. let result = {
  151. text,
  152. type: "slider",
  153. description,
  154. attributes: {},
  155. getValue() {
  156. return PopsPanel.getValue(key, defaultValue);
  157. },
  158. getToolTipContent(value) {
  159. if (typeof getToolTipContent === "function") {
  160. return getToolTipContent(value);
  161. } else {
  162. return `${value}`;
  163. }
  164. },
  165. callback(event, value) {
  166. if (typeof changeCallBack === "function") {
  167. if (changeCallBack(event, value)) {
  168. return;
  169. }
  170. }
  171. PopsPanel.setValue(key, value);
  172. },
  173. min,
  174. max
  175. };
  176. if (result.attributes) {
  177. result.attributes[ATTRIBUTE_KEY] = key;
  178. result.attributes[ATTRIBUTE_DEFAULT_VALUE] = defaultValue;
  179. }
  180. return result;
  181. };
  182. const UISwitch = function(text, key, defaultValue, clickCallBack, description) {
  183. let result = {
  184. text,
  185. type: "switch",
  186. description,
  187. attributes: {},
  188. getValue() {
  189. return Boolean(PopsPanel.getValue(key, defaultValue));
  190. },
  191. callback(event, value) {
  192. log.success(`${value ? "开启" : "关闭"} ${text}`);
  193. if (typeof clickCallBack === "function") {
  194. if (clickCallBack(event, value)) {
  195. return;
  196. }
  197. }
  198. PopsPanel.setValue(key, Boolean(value));
  199. },
  200. afterAddToUListCallBack: void 0
  201. };
  202. if (result.attributes) {
  203. result.attributes[ATTRIBUTE_KEY] = key;
  204. result.attributes[ATTRIBUTE_DEFAULT_VALUE] = Boolean(defaultValue);
  205. }
  206. return result;
  207. };
  208. const SettingUIBlog = {
  209. id: "panel-blog",
  210. title: "博客",
  211. isDefault() {
  212. return CSDNRouter.isBlog();
  213. },
  214. forms: [
  215. {
  216. text: "屏蔽",
  217. type: "forms",
  218. forms: [
  219. UISwitch(
  220. "【屏蔽】登录弹窗",
  221. "csdn-blog-shieldLoginDialog",
  222. true
  223. ),
  224. UISwitch(
  225. "【屏蔽】底部xx技能树",
  226. "csdn-blog-shieldBottomSkillTree",
  227. false
  228. ),
  229. UISwitch(
  230. "【屏蔽】左侧博客信息",
  231. "csdn-blog-shieldLeftBlogContainerAside",
  232. false
  233. ),
  234. UISwitch(
  235. "【屏蔽】右侧目录信息",
  236. "csdn-blog-shieldRightDirectoryInformation",
  237. false
  238. ),
  239. UISwitch(
  240. "【屏蔽】右侧工具栏",
  241. "csdn-blog-shieldfloatingButton",
  242. false
  243. ),
  244. UISwitch(
  245. "【屏蔽】顶部工具栏",
  246. "csdn-blog-shieldTopToolbar",
  247. false
  248. ),
  249. UISwitch(
  250. "【屏蔽】搜索悬浮工具栏",
  251. "csdn-blog-shieldArticleSearchTip",
  252. false,
  253. void 0,
  254. "选中文字弹出的,例如:搜索、评论、笔记"
  255. ),
  256. UISwitch(
  257. "【屏蔽】底部的悬浮工具栏",
  258. "csdn-blog-shieldBottomFloatingToolbar",
  259. false
  260. )
  261. ]
  262. },
  263. {
  264. text: "功能",
  265. type: "forms",
  266. forms: [
  267. UISlider(
  268. "右侧工具栏的right偏移",
  269. "csdn-blog-rightToolbarRightOffset",
  270. 90,
  271. 0,
  272. document.documentElement.clientWidth,
  273. (event, value) => {
  274. let csdnSideToolbar = document.querySelector(".csdn-side-toolbar");
  275. DOMUtils.css(csdnSideToolbar, {
  276. right: value + "px"
  277. });
  278. },
  279. (value) => {
  280. return `当前:${value}px,默认:90px`;
  281. }
  282. ),
  283. UISlider(
  284. "右侧工具栏的top偏移",
  285. "csdn-blog-rightToolbarTopOffset",
  286. 140,
  287. 0,
  288. document.documentElement.clientHeight,
  289. (event, value) => {
  290. let csdnSideToolbar = document.querySelector(".csdn-side-toolbar");
  291. DOMUtils.css(csdnSideToolbar, {
  292. top: value + "px"
  293. });
  294. },
  295. (value) => {
  296. return `当前:${value}px,默认:90px`;
  297. }
  298. )
  299. ]
  300. },
  301. {
  302. text: "内容",
  303. type: "forms",
  304. forms: [
  305. UISwitch(
  306. "自动展开内容块",
  307. "csdn-blog-autoExpandContent",
  308. false
  309. ),
  310. UISwitch(
  311. "全文居中",
  312. "csdn-blog-articleCenter",
  313. true,
  314. function(event, enable) {
  315. if (enable) {
  316. alert(
  317. "为了更好的呈现效果,请开启功能:【屏蔽】左侧博客信息、【屏蔽】右侧目录信息"
  318. );
  319. }
  320. }
  321. )
  322. ]
  323. },
  324. {
  325. text: "评论",
  326. type: "forms",
  327. forms: [
  328. UISwitch(
  329. "屏蔽",
  330. "csdn-blog-blockComment",
  331. false,
  332. void 0,
  333. "屏蔽评论"
  334. ),
  335. UISwitch(
  336. "优化评论的位置",
  337. "csdn-blog-restoreComments",
  338. true
  339. ),
  340. UISwitch(
  341. "添加前往评论的按钮",
  342. "csdn-blog-addGotoRecommandButton",
  343. true
  344. )
  345. ]
  346. },
  347. {
  348. text: "底部文章",
  349. type: "forms",
  350. forms: [
  351. UISwitch(
  352. "屏蔽",
  353. "csdn-blog-shieldBottomRecommendArticle",
  354. false,
  355. void 0,
  356. "屏蔽底部文章"
  357. ),
  358. UISwitch(
  359. "标识CSDN下载",
  360. "csdn-blog-identityCSDNDownload",
  361. true,
  362. void 0,
  363. "使用红框标识"
  364. ),
  365. UISwitch(
  366. "移除资源下载的文章",
  367. "csdn-blog-removeResourceDownloadArticle",
  368. false,
  369. void 0,
  370. "移除download.csdn.net、www.iteye.com、edu.csdn.net的文章链接"
  371. )
  372. ]
  373. },
  374. {
  375. text: "劫持/拦截",
  376. type: "forms",
  377. forms: [
  378. UISwitch(
  379. "拦截-复制的小尾巴",
  380. "csdn-blog-removeClipboardHijacking",
  381. true
  382. ),
  383. UISwitch(
  384. "劫持-禁止复制",
  385. "csdn-blog-unBlockCopy",
  386. true,
  387. void 0,
  388. "允许点击复制按钮进行复制"
  389. )
  390. ]
  391. }
  392. ]
  393. };
  394. const SettingUILink = {
  395. id: "panel-link",
  396. title: "链接",
  397. isDefault() {
  398. return CSDNRouter.isLink();
  399. },
  400. forms: [
  401. {
  402. text: "功能",
  403. type: "forms",
  404. forms: [
  405. UISwitch(
  406. "重定向链接",
  407. "csdn-link-jumpRedirect",
  408. true,
  409. void 0,
  410. "自动跳转至被拦截的Url链接"
  411. )
  412. ]
  413. }
  414. ]
  415. };
  416. const SettingUIHuaWeiCloud = {
  417. id: "panel-hua-wei-cloud",
  418. title: "华为云开发者联盟",
  419. isDefault() {
  420. return CSDNRouter.isHuaWeiCloudBlog();
  421. },
  422. forms: [
  423. {
  424. text: "功能",
  425. type: "forms",
  426. forms: [
  427. UISwitch(
  428. "自动展开全文",
  429. "csdn-hua-wei-cloud-autoExpandContent",
  430. true
  431. )
  432. ]
  433. },
  434. {
  435. text: "屏蔽",
  436. type: "forms",
  437. forms: [
  438. UISwitch(
  439. "【屏蔽】云开发者任务挑战活动",
  440. "csdn-hua-wei-cloud-shieldCloudDeveloperTaskChallengeEvent",
  441. true
  442. ),
  443. UISwitch(
  444. "【屏蔽】左侧悬浮按钮",
  445. "csdn-hua-wei-cloud-shieldLeftFloatingButton",
  446. false,
  447. function(event, enable) {
  448. if (enable) {
  449. alert(
  450. "开启后将屏蔽【当前阅读量】、【点赞按钮】、【评论按钮】、【分享按钮】"
  451. );
  452. }
  453. }
  454. ),
  455. UISwitch(
  456. "【屏蔽】右侧栏",
  457. "csdn-hua-wei-cloud-blockRightColumn",
  458. false,
  459. function(event, enable) {
  460. if (enable) {
  461. alert(
  462. "开启后将屏蔽【相关产品】-【活动日历】-【运营活动】-【热门标签】"
  463. );
  464. }
  465. }
  466. ),
  467. UISwitch(
  468. "【屏蔽】底部推荐内容",
  469. "csdn-hua-wei-cloud-blockRecommendedContentAtTheBottom",
  470. false
  471. ),
  472. UISwitch(
  473. "【屏蔽】底部更多推荐",
  474. "csdn-hua-wei-cloud-shieldTheBottomForMoreRecommendations",
  475. false
  476. )
  477. ]
  478. }
  479. ]
  480. };
  481. const SettingUIWenKu = {
  482. id: "panel-wenku",
  483. title: "资源",
  484. isDefault() {
  485. return CSDNRouter.isLink();
  486. },
  487. forms: [
  488. {
  489. text: "屏蔽",
  490. type: "forms",
  491. forms: [
  492. UISwitch(
  493. "【屏蔽】资源推荐",
  494. "csdn-wenku-shieldResourceRecommend",
  495. false
  496. ),
  497. UISwitch(
  498. "【屏蔽】右侧用户信息",
  499. "csdn-wenku-shieldRightUserInfo",
  500. false
  501. ),
  502. UISwitch(
  503. "【屏蔽】右侧悬浮工具栏",
  504. "csdn-wenku-shieldRightToolBar",
  505. false
  506. )
  507. ]
  508. }
  509. ]
  510. };
  511. const SettingUISo = {
  512. id: "panel-so",
  513. title: "搜索",
  514. isDefault() {
  515. return CSDNRouter.isSo();
  516. },
  517. forms: [
  518. {
  519. text: "C知道-功能",
  520. type: "forms",
  521. forms: [
  522. UISwitch(
  523. "去除水印",
  524. "csdn-so-cknow-removeMaskCover",
  525. true
  526. )
  527. ]
  528. }
  529. ]
  530. };
  531. const MSettingUIBlog = {
  532. id: "m-panel-blog",
  533. title: "博客",
  534. isDefault() {
  535. return CSDNRouter.isBlog();
  536. },
  537. forms: [
  538. {
  539. text: "屏蔽",
  540. type: "forms",
  541. forms: [
  542. UISwitch(
  543. "【屏蔽】广告",
  544. "m-csdn-blog-removeAds",
  545. true,
  546. void 0,
  547. "包括:登录弹窗、打开APP、ios版本提示等"
  548. ),
  549. UISwitch(
  550. "【屏蔽】顶部Toolbar",
  551. "m-csdn-blog-shieldTopToolbar",
  552. false
  553. )
  554. ]
  555. },
  556. {
  557. text: "内容",
  558. type: "forms",
  559. forms: [
  560. UISwitch(
  561. "允许选中文字",
  562. "m-csdn-blog-allowSelectText",
  563. true,
  564. void 0,
  565. "设置user-select: text;"
  566. ),
  567. UISwitch(
  568. "自动展开",
  569. "m-csdn-blog-autoExpandContent",
  570. true,
  571. void 0,
  572. "包括内容、代码块"
  573. ),
  574. UISwitch(
  575. "不限制代码块的最大高度",
  576. "m-csdn-blog-notLimitCodePreMaxHeight",
  577. false,
  578. void 0,
  579. "让代码块的高度直接被撑开"
  580. )
  581. ]
  582. },
  583. {
  584. text: "评论",
  585. type: "forms",
  586. forms: [
  587. UISwitch(
  588. "屏蔽",
  589. "m-csdn-blog-blockComment",
  590. false,
  591. void 0,
  592. "屏蔽评论区"
  593. ),
  594. UISwitch(
  595. "不限制评论区的最大高度",
  596. "m-csdn-blog-notLimitCommentMaxHeight",
  597. true,
  598. void 0,
  599. "让评论区高度直接被撑开"
  600. )
  601. ]
  602. },
  603. {
  604. text: "底部文章",
  605. type: "forms",
  606. forms: [
  607. UISwitch(
  608. "屏蔽",
  609. "m-csdn-blog-blockBottomArticle",
  610. false,
  611. void 0,
  612. "屏蔽底部文章"
  613. ),
  614. UISwitch(
  615. "移除资源下载的文章",
  616. "m-csdn-blog-removeResourceArticle",
  617. false,
  618. void 0,
  619. "移除download.csdn.net、www.iteye.com、edu.csdn.net的文章链接"
  620. ),
  621. UISwitch(
  622. "重构",
  623. "m-csdn-blog-refactoringRecommendation",
  624. true,
  625. void 0,
  626. "样式统一化"
  627. ),
  628. UISwitch(
  629. "新标签页打开",
  630. "m-csdn-blog-openNewTab",
  631. true,
  632. void 0,
  633. "点击文章,新标签页打开"
  634. )
  635. ]
  636. },
  637. {
  638. text: "劫持/拦截",
  639. type: "forms",
  640. forms: [
  641. UISwitch(
  642. "劫持-禁止复制",
  643. "m-csdn-blog-unBlockCopy",
  644. true,
  645. void 0,
  646. "允许点击复制按钮进行复制"
  647. )
  648. ]
  649. }
  650. ]
  651. };
  652. const MSettingUILink = {
  653. id: "m-panel-link",
  654. title: "链接",
  655. isDefault() {
  656. return CSDNRouter.isLink();
  657. },
  658. forms: [
  659. {
  660. text: "功能",
  661. type: "forms",
  662. forms: [
  663. UISwitch(
  664. "重定向链接",
  665. "m-csdn-link-jumpRedirect",
  666. true,
  667. void 0,
  668. "自动跳转至被拦截的Url链接"
  669. )
  670. ]
  671. }
  672. ]
  673. };
  674. const MSettingUISo = {
  675. id: "panel-so",
  676. title: "搜索",
  677. isDefault() {
  678. return CSDNRouter.isSo();
  679. },
  680. forms: [
  681. {
  682. text: "C知道-功能",
  683. type: "forms",
  684. forms: [
  685. UISwitch(
  686. "去除水印",
  687. "m-csdn-so-cknow-removeMaskCover",
  688. true
  689. )
  690. ]
  691. }
  692. ]
  693. };
  694. const MSettingUIWenKu = {
  695. id: "m-panel-wenku",
  696. title: "资源",
  697. isDefault() {
  698. return CSDNRouter.isWenKu();
  699. },
  700. forms: [
  701. {
  702. text: "屏蔽",
  703. type: "forms",
  704. forms: [
  705. UISwitch(
  706. "【屏蔽】底部工具栏",
  707. "m-csdn-wenku-shieldBottomToolbar",
  708. false
  709. )
  710. ]
  711. }
  712. ]
  713. };
  714. const MSettingUIHuaWeiCloud = {
  715. id: "m-panel-hua-wei-cloud",
  716. title: "华为云开发者联盟",
  717. isDefault() {
  718. return CSDNRouter.isHuaWeiCloudBlog();
  719. },
  720. forms: [
  721. {
  722. text: "功能",
  723. type: "forms",
  724. forms: [
  725. UISwitch(
  726. "自动展开全文",
  727. "m-csdn-hua-wei-cloud-autoExpandContent",
  728. true
  729. )
  730. ]
  731. }
  732. ]
  733. };
  734. const PopsPanel = {
  735. /** 数据 */
  736. $data: {
  737. /**
  738. * 菜单项的默认值
  739. */
  740. data: new utils.Dictionary(),
  741. /**
  742. * 成功只执行了一次的项
  743. */
  744. oneSuccessExecMenu: new utils.Dictionary(),
  745. /**
  746. * 成功只执行了一次的项
  747. */
  748. onceExec: new utils.Dictionary(),
  749. /** 脚本名,一般用在设置的标题上 */
  750. scriptName: SCRIPT_NAME,
  751. /** 菜单项的总值在本地数据配置的键名 */
  752. key: KEY,
  753. /** 菜单项在attributes上配置的菜单键 */
  754. attributeKeyName: ATTRIBUTE_KEY,
  755. /** 菜单项在attributes上配置的菜单默认值 */
  756. attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE
  757. },
  758. /** 监听器 */
  759. $listener: {
  760. /**
  761. * 值改变的监听器
  762. */
  763. listenData: new utils.Dictionary()
  764. },
  765. init() {
  766. this.initPanelDefaultValue();
  767. this.initExtensionsMenu();
  768. },
  769. initExtensionsMenu() {
  770. if (_unsafeWindow.top !== _unsafeWindow.self) {
  771. return;
  772. }
  773. GM_Menu.add([
  774. {
  775. key: "show_pops_panel_setting",
  776. text: "⚙ PC端设置",
  777. autoReload: false,
  778. isStoreValue: false,
  779. showText(text) {
  780. return text;
  781. },
  782. callback: () => {
  783. this.showPanel();
  784. }
  785. },
  786. {
  787. key: "m_show_pops_panel_setting",
  788. text: "⚙ 移动端端设置",
  789. autoReload: false,
  790. isStoreValue: false,
  791. showText(text) {
  792. return text;
  793. },
  794. callback: () => {
  795. this.showMPanel();
  796. }
  797. },
  798. {
  799. key: "gotoCSDNCKnow",
  800. text: "⚙ 前往C知道",
  801. isStoreValue: false,
  802. autoReload: false,
  803. showText(text) {
  804. return text;
  805. },
  806. callback() {
  807. window.open("https://so.csdn.net/chat", "_blank");
  808. }
  809. }
  810. ]);
  811. },
  812. /** 初始化本地设置默认的值 */
  813. initPanelDefaultValue() {
  814. let that = this;
  815. function initDefaultValue(config) {
  816. if (!config["attributes"]) {
  817. return;
  818. }
  819. let key = config.attributes[ATTRIBUTE_KEY];
  820. let defaultValue = config["attributes"][ATTRIBUTE_DEFAULT_VALUE];
  821. if (key == null) {
  822. log.warn(["请先配置键", config]);
  823. return;
  824. }
  825. if (that.$data.data.has(key)) {
  826. log.warn("请检查该key(已存在): " + key);
  827. }
  828. that.$data.data.set(key, defaultValue);
  829. }
  830. let contentConfigList = this.getPanelContentConfig().concat(this.getMPanelContentConfig());
  831. for (let index = 0; index < contentConfigList.length; index++) {
  832. let leftContentConfigItem = contentConfigList[index];
  833. if (!leftContentConfigItem.forms) {
  834. continue;
  835. }
  836. let rightContentConfigList = leftContentConfigItem.forms;
  837. for (let formItemIndex = 0; formItemIndex < rightContentConfigList.length; formItemIndex++) {
  838. let rightContentConfigItem = rightContentConfigList[formItemIndex];
  839. if (rightContentConfigItem.forms) {
  840. let childFormConfigList = rightContentConfigItem.forms;
  841. for (let formChildConfigIndex = 0; formChildConfigIndex < childFormConfigList.length; formChildConfigIndex++) {
  842. initDefaultValue(childFormConfigList[formChildConfigIndex]);
  843. }
  844. } else {
  845. initDefaultValue(rightContentConfigItem);
  846. }
  847. }
  848. }
  849. },
  850. /**
  851. * 设置值
  852. * @param key 键
  853. * @param value 值
  854. */
  855. setValue(key, value) {
  856. let locaData = _GM_getValue(KEY, {});
  857. let oldValue = locaData[key];
  858. locaData[key] = value;
  859. _GM_setValue(KEY, locaData);
  860. if (this.$listener.listenData.has(key)) {
  861. this.$listener.listenData.get(key).callback(key, oldValue, value);
  862. }
  863. },
  864. /**
  865. * 获取值
  866. * @param key 键
  867. * @param defaultValue 默认值
  868. */
  869. getValue(key, defaultValue) {
  870. let locaData = _GM_getValue(KEY, {});
  871. let localValue = locaData[key];
  872. if (localValue == null) {
  873. if (this.$data.data.has(key)) {
  874. return this.$data.data.get(key);
  875. }
  876. return defaultValue;
  877. }
  878. return localValue;
  879. },
  880. /**
  881. * 删除值
  882. * @param key 键
  883. */
  884. deleteValue(key) {
  885. let locaData = _GM_getValue(KEY, {});
  886. let oldValue = locaData[key];
  887. Reflect.deleteProperty(locaData, key);
  888. _GM_setValue(KEY, locaData);
  889. if (this.$listener.listenData.has(key)) {
  890. this.$listener.listenData.get(key).callback(key, oldValue, void 0);
  891. }
  892. },
  893. /**
  894. * 监听调用setValue、deleteValue
  895. * @param key 需要监听的键
  896. * @param callback
  897. */
  898. addValueChangeListener(key, callback) {
  899. let listenerId = Math.random();
  900. this.$listener.listenData.set(key, {
  901. id: listenerId,
  902. key,
  903. callback
  904. });
  905. return listenerId;
  906. },
  907. /**
  908. * 移除监听
  909. * @param listenerId 监听的id
  910. */
  911. removeValueChangeListener(listenerId) {
  912. let deleteKey = null;
  913. for (const [key, value] of this.$listener.listenData.entries()) {
  914. if (value.id === listenerId) {
  915. deleteKey = key;
  916. break;
  917. }
  918. }
  919. if (typeof deleteKey === "string") {
  920. this.$listener.listenData.delete(deleteKey);
  921. } else {
  922. console.warn("没有找到对应的监听器");
  923. }
  924. },
  925. /**
  926. * 自动判断菜单是否启用,然后执行回调
  927. * @param key
  928. * @param callback 回调
  929. */
  930. execMenu(key, callback) {
  931. if (typeof key !== "string") {
  932. throw new TypeError("key 必须是字符串");
  933. }
  934. let value = PopsPanel.getValue(key);
  935. if (value) {
  936. callback(value);
  937. }
  938. },
  939. /**
  940. * 自动判断菜单是否启用,然后执行回调,只会执行一次
  941. * @param key
  942. * @param callback 回调
  943. */
  944. execMenuOnce(key, callback) {
  945. if (typeof key !== "string") {
  946. throw new TypeError("key 必须是字符串");
  947. }
  948. let value = PopsPanel.getValue(key);
  949. if (value) {
  950. if (this.$data.oneSuccessExecMenu.has(key)) {
  951. return;
  952. }
  953. callback(value);
  954. this.$data.oneSuccessExecMenu.set(key, 1);
  955. }
  956. },
  957. /**
  958. * 根据key执行一次
  959. * @param key
  960. */
  961. onceExec(key, callback) {
  962. if (typeof key !== "string") {
  963. throw new TypeError("key 必须是字符串");
  964. }
  965. if (this.$data.onceExec.has(key)) {
  966. return;
  967. }
  968. callback();
  969. this.$data.onceExec.set(key, 1);
  970. },
  971. /**
  972. * 显示设置面板
  973. */
  974. showPanel() {
  975. pops.panel({
  976. title: {
  977. text: `${SCRIPT_NAME}-PC端设置`,
  978. position: "center",
  979. html: false,
  980. style: ""
  981. },
  982. content: this.getPanelContentConfig(),
  983. mask: {
  984. enable: true,
  985. clickEvent: {
  986. toClose: true,
  987. toHide: false
  988. }
  989. },
  990. isMobile: this.isMobile(),
  991. width: this.getWidth(),
  992. height: this.getHeight(),
  993. drag: true,
  994. only: true
  995. });
  996. },
  997. /**
  998. * 显示设置面板
  999. */
  1000. showMPanel() {
  1001. pops.panel({
  1002. title: {
  1003. text: `${SCRIPT_NAME}-移动端设置`,
  1004. position: "center",
  1005. html: false,
  1006. style: ""
  1007. },
  1008. content: this.getMPanelContentConfig(),
  1009. mask: {
  1010. enable: true,
  1011. clickEvent: {
  1012. toClose: true,
  1013. toHide: false
  1014. }
  1015. },
  1016. isMobile: this.isMobile(),
  1017. width: this.getWidth(),
  1018. height: this.getHeight(),
  1019. drag: true,
  1020. only: true
  1021. });
  1022. },
  1023. isMobile() {
  1024. return window.outerWidth < 550;
  1025. },
  1026. /**
  1027. * 获取设置面板的宽度
  1028. */
  1029. getWidth() {
  1030. if (window.outerWidth < 800) {
  1031. return "92dvw";
  1032. } else {
  1033. return "800px";
  1034. }
  1035. },
  1036. /**
  1037. * 获取设置面板的高度
  1038. */
  1039. getHeight() {
  1040. if (window.outerHeight > 450) {
  1041. return "80dvh";
  1042. } else {
  1043. return "450px";
  1044. }
  1045. },
  1046. /**
  1047. * 获取配置内容
  1048. */
  1049. getPanelContentConfig() {
  1050. let configList = [
  1051. SettingUIBlog,
  1052. SettingUILink,
  1053. SettingUIHuaWeiCloud,
  1054. SettingUIWenKu,
  1055. SettingUISo
  1056. ];
  1057. return configList;
  1058. },
  1059. /**
  1060. * 获取配置内容
  1061. */
  1062. getMPanelContentConfig() {
  1063. let configList = [
  1064. MSettingUIBlog,
  1065. MSettingUILink,
  1066. MSettingUIHuaWeiCloud,
  1067. MSettingUIWenKu,
  1068. MSettingUISo
  1069. ];
  1070. return configList;
  1071. }
  1072. };
  1073. const ShieldCSS$4 = "/* 底部免费抽xxx奖品广告 */\r\ndiv.siderbar-box,\r\n/* 华为开发者联盟加入社区 */\r\ndiv.user-desc.user-desc-fix {\r\n display: none !important;\r\n}\r\n";
  1074. const CSDNHuaWeiCloud = {
  1075. init() {
  1076. _GM_addStyle(ShieldCSS$4);
  1077. PopsPanel.execMenu("csdn-hua-wei-cloud-shieldCloudDeveloperTaskChallengeEvent", () => {
  1078. this.shieldCloudDeveloperTaskChallengeEvent();
  1079. });
  1080. PopsPanel.execMenu("csdn-hua-wei-cloud-autoExpandContent", () => {
  1081. this.autoExpandContent();
  1082. });
  1083. PopsPanel.execMenu("csdn-hua-wei-cloud-shieldLeftFloatingButton", () => {
  1084. this.shieldLeftFloatingButton();
  1085. });
  1086. PopsPanel.execMenu("csdn-hua-wei-cloud-blockRightColumn", () => {
  1087. this.blockRightColumn();
  1088. });
  1089. PopsPanel.execMenu("csdn-hua-wei-cloud-blockRecommendedContentAtTheBottom", () => {
  1090. this.blockRecommendedContentAtTheBottom();
  1091. });
  1092. PopsPanel.execMenu("csdn-hua-wei-cloud-shieldTheBottomForMoreRecommendations", () => {
  1093. this.shieldTheBottomForMoreRecommendations();
  1094. });
  1095. },
  1096. /**
  1097. * 自动展开内容
  1098. */
  1099. autoExpandContent() {
  1100. log.success("自动展开全文");
  1101. _GM_addStyle(`
  1102. /* 自动展开全文 */
  1103. .main-content .user-article{
  1104. height: auto !important;
  1105. overflow: auto !important;
  1106. }
  1107. /* 点击阅读全文 */
  1108. div.article-show-more {
  1109. display: none !important;
  1110. }
  1111. `);
  1112. },
  1113. /**
  1114. * 屏蔽云开发者任务挑战活动
  1115. */
  1116. shieldCloudDeveloperTaskChallengeEvent() {
  1117. let GM_cookie = new utils.GM_Cookie();
  1118. GM_cookie.set({ name: "show_join_group_index", value: 1 });
  1119. log.success("屏蔽云开发者任务挑战活动");
  1120. },
  1121. /**
  1122. * 屏蔽左侧悬浮按钮
  1123. */
  1124. shieldLeftFloatingButton() {
  1125. log.success(
  1126. "屏蔽左侧悬浮按钮,包括当前阅读量、点赞按钮、评论按钮、分享按钮"
  1127. );
  1128. _GM_addStyle(`
  1129. div.toolbar-wrapper.article-interact-bar{
  1130. display: none !important;
  1131. }`);
  1132. },
  1133. /**
  1134. * 屏蔽右侧栏
  1135. */
  1136. blockRightColumn() {
  1137. log.success("屏蔽右侧栏,包括相关产品-活动日历-运营活动-热门标签");
  1138. _GM_addStyle(`
  1139. div.page-home-right.dp-aside-right{
  1140. display: none !important;
  1141. }
  1142. `);
  1143. },
  1144. /**
  1145. * 屏蔽底部推荐内容
  1146. */
  1147. blockRecommendedContentAtTheBottom() {
  1148. log.success("屏蔽底部推荐内容");
  1149. _GM_addStyle(`
  1150. div.recommend-card-box{
  1151. display: none !important;
  1152. }`);
  1153. },
  1154. /**
  1155. * 屏蔽底部更多推荐
  1156. */
  1157. shieldTheBottomForMoreRecommendations() {
  1158. log.success("屏蔽底部更多推荐");
  1159. _GM_addStyle(`
  1160. div.more-article{
  1161. display: none !important;
  1162. }`);
  1163. }
  1164. };
  1165. const BlogShieldCSS = ".ecommend-item-box.recommend-recommend-box,\r\n.login-mark,\r\n.opt-box.text-center,\r\n.leftPop,\r\n#csdn-shop-window,\r\n.toolbar-advert,\r\n.hide-article-box,\r\n.user-desc.user-desc-fix,\r\n.recommend-card-box,\r\n.more-article,\r\n.article-show-more,\r\n#csdn-toolbar-profile-nologin,\r\n.guide-rr-first,\r\n#recommend-item-box-tow,\r\n/* 发文章得原力分图片提示 */\r\ndiv.csdn-toolbar-creative-mp,\r\n/* 阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。 */\r\n#toolBarBox div.write-guide-buttom-box,\r\n/* 觉得还不错? 一键收藏 */\r\nul.toolbox-list div.tool-active-list,\r\n/* 右边按钮组的最上面的创作话题 */\r\ndiv.csdn-side-toolbar .activity-swiper-box,\r\n.sidetool-writeguide-box .tip-box,\r\n/* 右下角的登录提示 */\r\n.passport-login-tip-container {\r\n display: none !important;\r\n}\r\n\r\n\r\n";
  1166. const BlogExpandContentCSS = "/* 自动展开代码块 */\r\n.comment-list-box,\r\nmain div.blog-content-box pre {\r\n max-height: none !important;\r\n}\r\n/* 自动展开全文 */\r\n#article_content,\r\n.user-article.user-article-hide {\r\n height: auto !important;\r\n overflow: auto !important;\r\n}\r\n.blog_container_aside,\r\n#nav {\r\n margin-left: -45px;\r\n}\r\n.recommend-right.align-items-stretch.clearfix,\r\n.dl_right_fixed {\r\n margin-left: 45px;\r\n}\r\n#content_views,\r\n#content_views pre,\r\n#content_views pre code {\r\n user-select: text !important;\r\n}\r\n\r\n/* 屏蔽向下滚动时左边的容器 */\r\naside.blog_container_aside {\r\n display: none !important;\r\n}\r\n";
  1167. const BlogArticleCenterCSS = "#mainBox main {\r\n width: inherit !important;\r\n}\r\n\r\n\r\n@media (min-width: 1320px) and (max-width: 1380px) {\r\n .nodata .container {\r\n width: 900px !important;\r\n }\r\n\r\n .nodata .container main {\r\n width: 900px;\r\n }\r\n\r\n .nodata .container main #pcCommentBox pre > ol.hljs-ln {\r\n width: 490px !important;\r\n }\r\n\r\n .nodata .container main .articleConDownSource {\r\n width: 500px;\r\n }\r\n}\r\n\r\n@media screen and (max-width: 1320px) {\r\n .nodata .container {\r\n width: 760px !important;\r\n }\r\n\r\n .nodata .container main {\r\n width: 760px;\r\n }\r\n\r\n .nodata .container main #pcCommentBox pre > ol.hljs-ln {\r\n width: 490px !important;\r\n }\r\n\r\n .nodata .container main .toolbox-list .tool-reward {\r\n display: none;\r\n }\r\n\r\n .nodata\r\n .container\r\n main\r\n .more-toolbox-new\r\n .toolbox-left\r\n .profile-box\r\n .profile-name {\r\n max-width: 128px;\r\n }\r\n\r\n .nodata .container main .articleConDownSource {\r\n width: 420px;\r\n }\r\n}\r\n\r\n@media screen and (min-width: 1380px) {\r\n .nodata .container {\r\n width: 1010px !important;\r\n }\r\n\r\n .nodata .container main {\r\n width: 1010px;\r\n }\r\n\r\n .nodata .container main #pcCommentBox pre > ol.hljs-ln {\r\n width: 490px !important;\r\n }\r\n\r\n .nodata .container main .articleConDownSource {\r\n width: 560px;\r\n }\r\n}\r\n\r\n@media (min-width: 1550px) and (max-width: 1700px) {\r\n .nodata .container {\r\n width: 820px !important;\r\n }\r\n\r\n .nodata .container main {\r\n width: 820px;\r\n }\r\n\r\n .nodata .container main #pcCommentBox pre > ol.hljs-ln {\r\n width: 690px !important;\r\n }\r\n\r\n .nodata .container main .articleConDownSource {\r\n width: 500px;\r\n }\r\n}\r\n\r\n@media screen and (min-width: 1700px) {\r\n .nodata .container {\r\n width: 1010px !important;\r\n }\r\n\r\n .nodata .container main {\r\n width: 1010px;\r\n }\r\n\r\n .nodata .container main #pcCommentBox pre > ol.hljs-ln {\r\n width: 690px !important;\r\n }\r\n\r\n .nodata .container main .articleConDownSource {\r\n width: 560px;\r\n }\r\n}\r\n";
  1168. const CSDNBlog = {
  1169. init() {
  1170. this.addCSS();
  1171. PopsPanel.execMenu("csdn-blog-articleCenter", () => {
  1172. this.articleCenter();
  1173. });
  1174. PopsPanel.execMenu("csdn-blog-shieldLoginDialog", () => {
  1175. this.shieldLoginDialog();
  1176. });
  1177. PopsPanel.execMenu("m-csdn-blog-autoExpandContent", () => {
  1178. this.autoExpandContent();
  1179. this.clickPreCodeAutomatically();
  1180. });
  1181. PopsPanel.execMenu("csdn-blog-blockComment", () => {
  1182. this.blockComment();
  1183. });
  1184. PopsPanel.execMenu("csdn-blog-shieldfloatingButton", () => {
  1185. this.shieldRightToolbar();
  1186. });
  1187. PopsPanel.execMenu("csdn-blog-shieldBottomRecommendArticle", () => {
  1188. this.shieldBottomRecommendArticle();
  1189. });
  1190. PopsPanel.execMenu("csdn-blog-shieldBottomSkillTree", () => {
  1191. this.shieldBottomSkillTree();
  1192. });
  1193. PopsPanel.execMenu("csdn-blog-shieldBottomFloatingToolbar", () => {
  1194. this.shieldBottomFloatingToolbar();
  1195. });
  1196. PopsPanel.execMenu("csdn-blog-shieldLeftBlogContainerAside", () => {
  1197. this.shieldLeftBlogContainerAside();
  1198. });
  1199. PopsPanel.execMenu("csdn-blog-shieldRightDirectoryInformation", () => {
  1200. this.shieldRightDirectoryInformation();
  1201. });
  1202. PopsPanel.execMenu("csdn-blog-shieldTopToolbar", () => {
  1203. this.shieldTopToolbar();
  1204. });
  1205. PopsPanel.execMenu("csdn-blog-shieldArticleSearchTip", () => {
  1206. this.shieldArticleSearchTip();
  1207. });
  1208. this.initRightToolbarOffset();
  1209. DOMUtils.ready(() => {
  1210. PopsPanel.execMenu("ccsdn-blog-removeClipboardHijacking", () => {
  1211. this.removeClipboardHijacking();
  1212. });
  1213. PopsPanel.execMenu("csdn-blog-unBlockCopy", () => {
  1214. this.unBlockCopy();
  1215. });
  1216. PopsPanel.execMenu("csdn-blog-identityCSDNDownload", () => {
  1217. this.identityCSDNDownload();
  1218. });
  1219. PopsPanel.execMenu("csdn_pc_clickPreCodeAutomatically", () => {
  1220. this.clickPreCodeAutomatically();
  1221. });
  1222. PopsPanel.execMenu("csdn-blog-restoreComments", () => {
  1223. this.restoreComments();
  1224. });
  1225. PopsPanel.execMenu("csdn-blog-addGotoRecommandButton", () => {
  1226. this.addGotoRecommandButton();
  1227. });
  1228. });
  1229. },
  1230. /**
  1231. * 添加屏蔽CSS和功能CSS
  1232. */
  1233. addCSS() {
  1234. _GM_addStyle(BlogShieldCSS);
  1235. _GM_addStyle(BlogExpandContentCSS);
  1236. },
  1237. /**
  1238. * 去除剪贴板劫持
  1239. */
  1240. removeClipboardHijacking() {
  1241. var _a2;
  1242. log.info("去除剪贴板劫持");
  1243. (_a2 = document.querySelector(".article-copyright")) == null ? void 0 : _a2.remove();
  1244. if (_unsafeWindow.articleType) {
  1245. _unsafeWindow.articleType = 0;
  1246. }
  1247. if (_unsafeWindow.csdn && _unsafeWindow.csdn.copyright && _unsafeWindow.csdn.copyright.textData) {
  1248. _unsafeWindow.csdn.copyright.textData = "";
  1249. }
  1250. if (_unsafeWindow.csdn && _unsafeWindow.csdn.copyright && _unsafeWindow.csdn.copyright.htmlData) {
  1251. _unsafeWindow.csdn.copyright.htmlData = "";
  1252. }
  1253. },
  1254. /**
  1255. * 取消禁止复制
  1256. */
  1257. unBlockCopy() {
  1258. log.info("取消禁止复制");
  1259. document.addEventListener(
  1260. "click",
  1261. function(event) {
  1262. let $click = event.target;
  1263. let $parent = $click.parentElement;
  1264. if (!$click.classList.contains("hljs-button")) {
  1265. return;
  1266. }
  1267. utils.preventEvent(event);
  1268. let copyText = $parent.innerText || $parent.textContent;
  1269. utils.setClip(copyText);
  1270. $click.setAttribute("data-title", "复制成功");
  1271. },
  1272. {
  1273. capture: true
  1274. }
  1275. );
  1276. let changeDataTitle = new utils.LockFunction(function(event) {
  1277. var _a2;
  1278. let $mouse = event.target;
  1279. if ($mouse.localName !== "pre") {
  1280. return;
  1281. }
  1282. (_a2 = $mouse.querySelector(".hljs-button")) == null ? void 0 : _a2.setAttribute("data-title", "复制");
  1283. });
  1284. document.addEventListener("mouseenter", changeDataTitle.run, {
  1285. capture: true
  1286. });
  1287. document.addEventListener("mouseleave", changeDataTitle.run, {
  1288. capture: true
  1289. });
  1290. utils.waitNode("#content_views").then((element) => {
  1291. var _a2;
  1292. (_a2 = _unsafeWindow.$("#content_views")) == null ? void 0 : _a2.unbind("copy");
  1293. element.addEventListener("copy", function(event) {
  1294. var _a3;
  1295. utils.preventEvent(event);
  1296. let selectText = (_a3 = _unsafeWindow.getSelection()) == null ? void 0 : _a3.toString();
  1297. utils.setClip(selectText);
  1298. return false;
  1299. });
  1300. });
  1301. utils.waitNode(".hljs-button").then(() => {
  1302. setTimeout(() => {
  1303. document.querySelectorAll(".hljs-button").forEach((element) => {
  1304. element.removeAttribute("onclick");
  1305. element.removeAttribute("data-report-click");
  1306. element.setAttribute("data-title", "复制");
  1307. });
  1308. }, 250);
  1309. });
  1310. },
  1311. /**
  1312. * 点击代码块自动展开
  1313. */
  1314. clickPreCodeAutomatically() {
  1315. log.info("点击代码块自动展开");
  1316. document.addEventListener("click", function(event) {
  1317. var _a2;
  1318. let $click = event.target;
  1319. if ($click.localName !== "pre") {
  1320. return;
  1321. }
  1322. $click.style.setProperty("height", "auto");
  1323. (_a2 = $click.querySelector(".hide-preCode-box")) == null ? void 0 : _a2.remove();
  1324. });
  1325. },
  1326. /**
  1327. * 恢复评论到正确位置
  1328. */
  1329. restoreComments() {
  1330. log.info("恢复评论到正确位置-第一条评论");
  1331. utils.waitNode(".first-recommend-box").then((element) => {
  1332. let recommendBoxElement = document.querySelector(
  1333. ".recommend-box.insert-baidu-box.recommend-box-style"
  1334. );
  1335. recommendBoxElement.insertBefore(
  1336. element,
  1337. recommendBoxElement.firstChild
  1338. );
  1339. });
  1340. log.info("恢复评论到正确位置-第二条评论");
  1341. utils.waitNode(".second-recommend-box").then((element) => {
  1342. let recommendBoxElement = document.querySelector(
  1343. ".recommend-box.insert-baidu-box.recommend-box-style"
  1344. );
  1345. recommendBoxElement.insertBefore(
  1346. element,
  1347. recommendBoxElement.firstChild
  1348. );
  1349. });
  1350. },
  1351. /**
  1352. * 标识CSDN下载的链接
  1353. */
  1354. identityCSDNDownload() {
  1355. log.info("标识CSDN下载的链接");
  1356. document.querySelectorAll(
  1357. ".recommend-item-box[data-url*='https://download.csdn.net/']"
  1358. ).forEach((item) => {
  1359. if (PopsPanel.getValue("csdn-blog-removeResourceDownloadArticle")) {
  1360. item.remove();
  1361. } else {
  1362. item.querySelector(".content-box").style.setProperty("border", "2px solid red");
  1363. }
  1364. });
  1365. },
  1366. /**
  1367. * 全文居中
  1368. */
  1369. articleCenter() {
  1370. log.info("全文居中");
  1371. _GM_addStyle(BlogArticleCenterCSS);
  1372. },
  1373. /**
  1374. * 添加前往评论的按钮,在返回顶部的下面
  1375. */
  1376. addGotoRecommandButton() {
  1377. log.info("添加前往评论的按钮,在返回顶部的上面");
  1378. let gotoRecommandNode = document.createElement("a");
  1379. gotoRecommandNode.className = "option-box";
  1380. gotoRecommandNode.setAttribute("data-type", "gorecommand");
  1381. gotoRecommandNode.innerHTML = `<span class="show-txt" style="display:flex;opacity:100;">前往<br>评论</span>`;
  1382. gotoRecommandNode.addEventListener("click", function() {
  1383. let toolbarBoxElement = document.querySelector("#toolBarBox");
  1384. if (!toolbarBoxElement.getClientRects().length) {
  1385. log.error("评论区处于隐藏状态");
  1386. return;
  1387. }
  1388. log.info("滚动到评论");
  1389. let toolbarBoxOffsetTop = toolbarBoxElement.getBoundingClientRect().top + window.scrollY;
  1390. let csdnToolBarElement = document.querySelector("#csdn-toolbar");
  1391. let csdnToolBarStyles = window.getComputedStyle(csdnToolBarElement);
  1392. let csdnToolBarHeight = csdnToolBarElement.clientHeight - parseFloat(csdnToolBarStyles.paddingTop) - parseFloat(csdnToolBarStyles.paddingBottom);
  1393. window.scrollTo({
  1394. top: toolbarBoxOffsetTop - csdnToolBarHeight - 8,
  1395. left: 0,
  1396. behavior: "smooth"
  1397. });
  1398. });
  1399. utils.waitNode(".csdn-side-toolbar").then(() => {
  1400. let targetElement = document.querySelector(
  1401. ".csdn-side-toolbar a:nth-last-child(2)"
  1402. );
  1403. targetElement.parentElement.insertBefore(
  1404. gotoRecommandNode,
  1405. targetElement.nextSibling
  1406. );
  1407. });
  1408. },
  1409. /**
  1410. * 屏蔽登录弹窗
  1411. */
  1412. shieldLoginDialog() {
  1413. log.info("屏蔽登录弹窗");
  1414. _GM_addStyle(`.passport-login-container{display: none !important;}`);
  1415. },
  1416. /**
  1417. * 自动展开内容块
  1418. */
  1419. autoExpandContent() {
  1420. log.info("自动展开内容块");
  1421. _GM_addStyle(`
  1422. pre.set-code-hide{height: auto !important;}
  1423. pre.set-code-hide .hide-preCode-box{display: none !important;}
  1424. `);
  1425. },
  1426. /**
  1427. * 屏蔽右侧工具栏
  1428. */
  1429. shieldRightToolbar() {
  1430. log.info("屏蔽右侧工具栏");
  1431. _GM_addStyle(`div.csdn-side-toolbar{display: none !important;}`);
  1432. },
  1433. /**
  1434. * 屏蔽评论区
  1435. */
  1436. blockComment() {
  1437. log.info("屏蔽评论区");
  1438. _GM_addStyle(`#pcCommentBox{display: none !important;}`);
  1439. },
  1440. /**
  1441. * 屏蔽底部推荐文章
  1442. */
  1443. shieldBottomRecommendArticle() {
  1444. log.info("屏蔽底部推荐文章");
  1445. _GM_addStyle(`main > div.recommend-box {display: none !important;}`);
  1446. },
  1447. /**
  1448. * 屏蔽底部xx技能树
  1449. */
  1450. shieldBottomSkillTree() {
  1451. _GM_addStyle(`#treeSkill{display: none !important;}`);
  1452. },
  1453. /**
  1454. * 屏蔽底部悬浮工具栏
  1455. */
  1456. shieldBottomFloatingToolbar() {
  1457. log.info("屏蔽底部悬浮工具栏");
  1458. _GM_addStyle(`#toolBarBox{display: none !important;}`);
  1459. },
  1460. /**
  1461. * 屏蔽左侧博客信息
  1462. */
  1463. shieldLeftBlogContainerAside() {
  1464. log.success("【屏蔽】左侧博客信息");
  1465. _GM_addStyle(`aside.blog_container_aside{display: none !important;}`);
  1466. },
  1467. /**
  1468. * 【屏蔽】右侧目录信息
  1469. */
  1470. shieldRightDirectoryInformation() {
  1471. log.success("【屏蔽】右侧目录信息");
  1472. _GM_addStyle(`
  1473. #rightAsideConcision,
  1474. #rightAside{
  1475. display: none !important;
  1476. }
  1477. `);
  1478. },
  1479. /**
  1480. * 屏蔽顶部Toolbar
  1481. */
  1482. shieldTopToolbar() {
  1483. _GM_addStyle(`#toolbarBox{display: none !important;}`);
  1484. },
  1485. /**
  1486. * 屏蔽文章内的选中搜索悬浮提示
  1487. */
  1488. shieldArticleSearchTip() {
  1489. _GM_addStyle(`#articleSearchTip{display: none !important;}`);
  1490. },
  1491. /**
  1492. * 初始化右侧工具栏的偏移(top、right)
  1493. */
  1494. initRightToolbarOffset() {
  1495. _GM_addStyle(`
  1496. .csdn-side-toolbar{
  1497. left: unset !important;
  1498. }
  1499. `);
  1500. utils.waitNode(".csdn-side-toolbar").then((element) => {
  1501. DOMUtils.css(element, {
  1502. top: parseInt(PopsPanel.getValue("csdn-blog-rightToolbarTopOffset")) + "px",
  1503. right: parseInt(
  1504. PopsPanel.getValue("csdn-blog-rightToolbarRightOffset")
  1505. ) + "px"
  1506. });
  1507. });
  1508. }
  1509. };
  1510. const WenkuCSS = "#chatgpt-article-detail\r\n > div.layout-center\r\n > div.main\r\n > div.article-box\r\n > div.cont.first-show.forbid {\r\n max-height: unset !important;\r\n height: auto !important;\r\n overflow: auto !important;\r\n}\r\n\r\n.forbid {\r\n user-select: text !important;\r\n}\r\n";
  1511. const ShieldCSS$3 = "/* wenku顶部横幅 */\r\n#app > div > div.main.pb-32 > div > div.top-bar,\r\n/* 底部展开全文 */\r\n#chatgpt-article-detail > div.layout-center > div.main > div.article-box > div.cont.first-show.forbid > div.open {\r\n display: none !important;\r\n}";
  1512. const CSDNWenKu = {
  1513. init() {
  1514. _GM_addStyle(WenkuCSS);
  1515. _GM_addStyle(ShieldCSS$3);
  1516. PopsPanel.execMenu("csdn-wenku-shieldResourceRecommend", () => {
  1517. this.shieldResourceRecommend();
  1518. });
  1519. PopsPanel.execMenu("csdn-wenku-shieldRightUserInfo", () => {
  1520. this.shieldRightUserInfo();
  1521. });
  1522. PopsPanel.execMenu("csdn-wenku-shieldRightToolBar", () => {
  1523. this.shieldRightToolBar();
  1524. });
  1525. },
  1526. /**
  1527. * 【屏蔽】资源推荐
  1528. */
  1529. shieldResourceRecommend() {
  1530. _GM_addStyle(`#recommend{display:none !important;}`);
  1531. },
  1532. /**
  1533. * 【屏蔽】右侧用户信息
  1534. */
  1535. shieldRightUserInfo() {
  1536. _GM_addStyle(`.layout-right{display:none !important;}`);
  1537. },
  1538. /**
  1539. * 【屏蔽】右侧悬浮工具栏
  1540. */
  1541. shieldRightToolBar() {
  1542. _GM_addStyle(`.csdn-side-toolbar {display:none !important;}`);
  1543. }
  1544. };
  1545. const CSDNLink = {
  1546. init() {
  1547. PopsPanel.execMenu("csdn-link-jumpRedirect", () => {
  1548. this.jumpRedirect();
  1549. });
  1550. },
  1551. /**
  1552. * 去除CSDN拦截其它网址的url并自动跳转
  1553. */
  1554. jumpRedirect() {
  1555. if (window.location.hostname === "link.csdn.net" && window.location.search.startsWith("?target")) {
  1556. window.stop();
  1557. let search = window.location.search.replace(/^\?target=/gi, "");
  1558. search = decodeURIComponent(search);
  1559. let newURL = search;
  1560. log.success(`跳转链接 ${newURL}`);
  1561. window.location.href = newURL;
  1562. }
  1563. }
  1564. };
  1565. const CSDN = {
  1566. init() {
  1567. if (CSDNRouter.isLink()) {
  1568. log.info("Router: 中转链接");
  1569. CSDNLink.init();
  1570. } else if (CSDNRouter.isHuaWeiCloudBlog()) {
  1571. log.info("Router: 华为云联盟");
  1572. CSDNHuaWeiCloud.init();
  1573. } else if (CSDNRouter.isBlog()) {
  1574. log.info("Router: 博客");
  1575. CSDNBlog.init();
  1576. } else if (CSDNRouter.isWenKu()) {
  1577. log.info("Router: 文库");
  1578. CSDNWenKu.init();
  1579. } else {
  1580. log.error("暂未适配,请反馈开发者:" + globalThis.location.href);
  1581. }
  1582. }
  1583. };
  1584. const M_CSDNLink = {
  1585. init() {
  1586. PopsPanel.execMenu("m-csdn-link-jumpRedirect", () => {
  1587. CSDNLink.jumpRedirect();
  1588. });
  1589. }
  1590. };
  1591. const ShieldCSS$2 = "/* 右下角的 免费赢华为平板xxxx */\r\n.org-main-content .siderbar-box {\r\n display: none !important;\r\n}\r\n";
  1592. const M_CSDNHuaWeiCloud = {
  1593. init() {
  1594. _GM_addStyle(ShieldCSS$2);
  1595. PopsPanel.execMenu("m-csdn-hua-wei-cloud-autoExpandContent", () => {
  1596. CSDNHuaWeiCloud.autoExpandContent();
  1597. });
  1598. }
  1599. };
  1600. const ShieldCSS$1 = "#operate,.feed-Sign-span,\r\n.view_comment_box,\r\n.weixin-shadowbox.wap-shadowbox,\r\n.feed-Sign-span,\r\n.user-desc.user-desc-fix,\r\n.comment_read_more_box,\r\n#content_views pre.set-code-hide .hide-preCode-box,\r\n/* 登录弹窗 */\r\n.passport-login-container,\r\n.hljs-button[data-title='登录后复制'],\r\n.article-show-more,\r\n#treeSkill,\r\ndiv.btn_open_app_prompt_div,\r\ndiv.readall_box,\r\ndiv.aside-header-fixed,\r\ndiv.feed-Sign-weixin,\r\ndiv.ios-shadowbox {\r\n display: none !important;\r\n}\r\n";
  1601. const MBlogCSS = "#mainBox {\r\n width: auto;\r\n}\r\n.user-desc.user-desc-fix {\r\n height: auto !important;\r\n overflow: auto !important;\r\n}\r\n.component-box .praise {\r\n background: #ff5722;\r\n border-radius: 5px;\r\n padding: 0px 8px;\r\n height: auto;\r\n}\r\n.component-box .praise,\r\n.component-box .share {\r\n color: #fff;\r\n}\r\n.component-box a {\r\n display: inline-block;\r\n font-size: xx-small;\r\n}\r\n.component-box {\r\n display: inline;\r\n margin: 0;\r\n position: relative;\r\n white-space: nowrap;\r\n}\r\n.csdn-edu-title {\r\n background: #4d6de1;\r\n border-radius: 5px;\r\n padding: 0px 8px;\r\n height: auto;\r\n color: #fff !important;\r\n}\r\n\r\n.GM-csdn-dl {\r\n padding: 0.24rem 0.32rem;\r\n width: 100%;\r\n justify-content: space-between;\r\n -webkit-box-pack: justify;\r\n border-bottom: 1px solid #f5f6f7 !important;\r\n}\r\n.GM-csdn-title {\r\n font-size: 0.3rem;\r\n color: #222226;\r\n letter-spacing: 0;\r\n line-height: 0.44rem;\r\n font-weight: 600;\r\n /*max-height: .88rem;*/\r\n word-break: break-all;\r\n overflow: hidden;\r\n display: -webkit-box;\r\n -webkit-box-orient: vertical;\r\n -webkit-line-clamp: 2;\r\n}\r\n.GM-csdn-title a {\r\n word-break: break-all;\r\n color: #222226;\r\n font-weight: 600;\r\n}\r\n.GM-csdn-title em,\r\n.GM-csdn-content em {\r\n font-style: normal;\r\n color: #fc5531;\r\n}\r\n.GM-csdn-content {\r\n /*max-width: 5.58rem;*/\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 1;\r\n -webkit-box-orient: vertical;\r\n color: #555666;\r\n font-size: 0.24rem;\r\n line-height: 0.34rem;\r\n max-height: 0.34rem;\r\n word-break: break-all;\r\n -webkit-box-flex: 1;\r\n -ms-flex: 1;\r\n flex: 1;\r\n margin-top: 0.16rem;\r\n}\r\n.GM-csdn-img img {\r\n width: 2.18rem;\r\n height: 1.58rem;\r\n /*margin-left: .16rem*/\r\n}\r\n";
  1602. function waitForElementToRemove(selectorText = "") {
  1603. utils.waitNodeList(selectorText).then(() => {
  1604. document.querySelectorAll(selectorText).forEach((item) => {
  1605. item.remove();
  1606. });
  1607. });
  1608. }
  1609. const M_CSDNBlog = {
  1610. init() {
  1611. this.addCSS();
  1612. PopsPanel.execMenu("m-csdn-blog-shieldTopToolbar", () => {
  1613. this.shieldTopToolbar();
  1614. });
  1615. PopsPanel.execMenu("m-csdn-blog-notLimitCodePreMaxHeight", () => {
  1616. this.notLimitCodePreMaxHeight();
  1617. });
  1618. PopsPanel.execMenu("m-csdn-blog-notLimitCommentMaxHeight", () => {
  1619. this.notLimitCommentMaxHeight();
  1620. });
  1621. PopsPanel.execMenu("m-csdn-blog-allowSelectText", () => {
  1622. this.allowSelectText();
  1623. });
  1624. PopsPanel.execMenu("m-csdn-blog-autoExpandContent", () => {
  1625. this.autoExpandContent();
  1626. });
  1627. PopsPanel.execMenu("m-csdn-blog-blockBottomArticle", () => {
  1628. this.blockBottomArticle();
  1629. });
  1630. PopsPanel.execMenu("m-csdn-blog-blockComment", () => {
  1631. this.blockComment();
  1632. });
  1633. DOMUtils.ready(() => {
  1634. PopsPanel.execMenu("m-csdn-blog-removeAds", () => {
  1635. this.removeAds();
  1636. });
  1637. PopsPanel.execMenu("m-csdn-blog-refactoringRecommendation", () => {
  1638. this.refactoringRecommendation();
  1639. });
  1640. PopsPanel.execMenu("m-csdn-blog-unBlockCopy", () => {
  1641. CSDNBlog.unBlockCopy();
  1642. });
  1643. });
  1644. },
  1645. addCSS() {
  1646. _GM_addStyle(ShieldCSS$1);
  1647. _GM_addStyle(MBlogCSS);
  1648. },
  1649. /**
  1650. * 屏蔽顶部Toolbar
  1651. */
  1652. shieldTopToolbar() {
  1653. log.success("屏蔽顶部Toolbar");
  1654. _GM_addStyle(`
  1655. #csdn-toolbar{
  1656. display: none !important;
  1657. }
  1658. /* 内容顶部要归位 */
  1659. body #main,
  1660. .margin_sides{
  1661. margin-top: unset !important;
  1662. padding-top: unset !important;
  1663. }
  1664. #article .article_title{
  1665. margin-top: .32rem !important;
  1666. padding-top: unset !important;
  1667. }
  1668. `);
  1669. },
  1670. /**
  1671. * 重构底部推荐
  1672. */
  1673. refactoringRecommendation() {
  1674. function refactoring() {
  1675. log.success("重构底部推荐");
  1676. document.querySelectorAll(".container-fluid").forEach((item) => {
  1677. var _a2, _b2;
  1678. let url = "";
  1679. let title = "";
  1680. let content = "";
  1681. let img = "";
  1682. let isCSDNDownload = false;
  1683. let isCSDNEduDownload = false;
  1684. if (item.hasAttribute("data-url")) {
  1685. url = item.getAttribute("data-url");
  1686. title = (_a2 = item.querySelector(".recommend_title div.left")) == null ? void 0 : _a2.innerHTML;
  1687. if (!item.querySelector(".text")) {
  1688. return;
  1689. }
  1690. content = (_b2 = item.querySelector(".text")) == null ? void 0 : _b2.innerHTML;
  1691. if (item.querySelectorAll(".recommend-img").length) {
  1692. item.querySelectorAll(".recommend-img").forEach((item2) => {
  1693. img += item2.innerHTML;
  1694. });
  1695. }
  1696. } else {
  1697. log.info("节点上无data-url");
  1698. url = item.querySelector("a[data-type]").getAttribute("href");
  1699. title = item.querySelector(".recommend_title div.left").innerHTML;
  1700. content = item.querySelector(".text").innerHTML;
  1701. }
  1702. var _URL_ = new URL(url);
  1703. if (_URL_.host === "download.csdn.net" || _URL_.host === "www.iteye.com" && _URL_.pathname.match(/^\/resource/gi)) {
  1704. log.info("该链接为csdn资源下载");
  1705. isCSDNDownload = true;
  1706. title = `<div class="component-box"><a class="praise" href="javascript:;">CSDN下载</a></div>` + title;
  1707. } else if (_URL_.origin.match(/edu.csdn.net/gi)) {
  1708. isCSDNEduDownload = true;
  1709. log.info("该链接为csdn学院下载");
  1710. title = `<div class="component-box"><a class="csdn-edu-title" href="javascript:;">CSDN学院</a></div>` + title;
  1711. }
  1712. item.setAttribute("class", "GM-csdn-dl");
  1713. item.setAttribute("data-url", url);
  1714. item.innerHTML = `<div class="GM-csdn-title"><div class="left">${title}</div></div><div class="GM-csdn-content">${content}</div><div class="GM-csdn-img">${img}</div>`;
  1715. item.addEventListener("click", function() {
  1716. if (PopsPanel.getValue("m-csdn-blog-openNewTab")) {
  1717. window.open(url, "_blank");
  1718. } else {
  1719. window.location.href = url;
  1720. }
  1721. });
  1722. if ((isCSDNDownload || isCSDNEduDownload) && PopsPanel.getValue("m-csdn-blog-removeResourceArticle")) {
  1723. item.remove();
  1724. }
  1725. });
  1726. }
  1727. let lockFunction = new utils.LockFunction(refactoring, this, 50);
  1728. utils.waitNode("#recommend").then((element) => {
  1729. log.success("重构底部推荐");
  1730. lockFunction.run();
  1731. utils.mutationObserver(element, {
  1732. callback: lockFunction.run,
  1733. config: { childList: true, subtree: true, attributes: true }
  1734. });
  1735. });
  1736. },
  1737. /**
  1738. * 屏蔽底部文章
  1739. */
  1740. blockBottomArticle() {
  1741. log.success("屏蔽底部文章");
  1742. _GM_addStyle("#recommend{display:none !important;}");
  1743. },
  1744. /**
  1745. * 屏蔽评论
  1746. */
  1747. blockComment() {
  1748. log.success("屏蔽评论");
  1749. _GM_addStyle("#comment{display:none !important;}");
  1750. },
  1751. /**
  1752. * 去除广告
  1753. */
  1754. removeAds() {
  1755. log.info("去除广告");
  1756. waitForElementToRemove(".passport-login-container");
  1757. waitForElementToRemove(".btn_open_app_prompt_box.detail-open-removed");
  1758. waitForElementToRemove(".add-firstAd");
  1759. waitForElementToRemove("div.feed-Sign-weixin");
  1760. waitForElementToRemove("div.ios-shadowbox");
  1761. },
  1762. /**
  1763. * 不限制代码块最大高度
  1764. */
  1765. notLimitCodePreMaxHeight() {
  1766. log.success("不限制代码块最大高度");
  1767. _GM_addStyle(`
  1768. pre{
  1769. max-height: unset !important;
  1770. }
  1771. `);
  1772. },
  1773. /**
  1774. * 不限制评论区最大高度
  1775. */
  1776. notLimitCommentMaxHeight() {
  1777. log.success("不限制评论区最大高度");
  1778. _GM_addStyle(`
  1779. #comment{
  1780. max-height: none !important;
  1781. }
  1782. `);
  1783. },
  1784. /**
  1785. * 允许选择文字
  1786. */
  1787. allowSelectText() {
  1788. log.success("允许选择文字");
  1789. _GM_addStyle(`
  1790. #content_views,
  1791. #content_views pre,
  1792. #content_views pre code{
  1793. webkit-touch-callout: text !important;
  1794. -webkit-user-select: text !important;
  1795. -khtml-user-select: text !important;
  1796. -moz-user-select: text !important;
  1797. -ms-user-select: text !important;
  1798. user-select: text !important;
  1799. }
  1800. `);
  1801. },
  1802. /**
  1803. * 自动展开内容
  1804. */
  1805. autoExpandContent() {
  1806. log.success("自动展开内容");
  1807. _GM_addStyle(`
  1808. #content_views pre.set-code-hide,
  1809. .article_content{
  1810. height: 100% !important;
  1811. overflow: auto !important;
  1812. }
  1813. `);
  1814. }
  1815. };
  1816. const ShieldCSS = "/* 右下角的买一年送3个月的广告图标 */\r\n.blind_box {\r\n display: none !important;\r\n}\r\n";
  1817. const M_CSDNWenKu = {
  1818. init() {
  1819. _GM_addStyle(ShieldCSS);
  1820. PopsPanel.execMenu("m-csdn-wenku-shieldBottomToolbar", () => {
  1821. this.shieldBottomToolbar();
  1822. });
  1823. },
  1824. /**
  1825. * 【屏蔽】底部工具栏
  1826. */
  1827. shieldBottomToolbar() {
  1828. _GM_addStyle(`
  1829. .page-container > div.btn{
  1830. display: none !important;
  1831. }
  1832. `);
  1833. }
  1834. };
  1835. const M_CSDN = {
  1836. init() {
  1837. if (CSDNRouter.isLink()) {
  1838. log.info("Router: 中转链接");
  1839. M_CSDNLink.init();
  1840. } else if (CSDNRouter.isHuaWeiCloudBlog()) {
  1841. log.info("Router: 华为云联盟");
  1842. M_CSDNHuaWeiCloud.init();
  1843. } else if (CSDNRouter.isBlog()) {
  1844. log.info("Router: 博客");
  1845. M_CSDNBlog.init();
  1846. } else if (CSDNRouter.isWenKu()) {
  1847. log.info("Router: 文库");
  1848. M_CSDNWenKu.init();
  1849. } else {
  1850. log.error("暂未适配,请反馈开发者:" + globalThis.location.href);
  1851. }
  1852. }
  1853. };
  1854. PopsPanel.init();
  1855. let isMobile = utils.isPhone();
  1856. let CHANGE_ENV_SET_KEY = "change_env_set";
  1857. let chooseMode = _GM_getValue(CHANGE_ENV_SET_KEY);
  1858. GM_Menu.add(
  1859. {
  1860. key: CHANGE_ENV_SET_KEY,
  1861. text: `⚙ 自动: ${isMobile ? "移动端" : "PC端"}`,
  1862. autoReload: false,
  1863. isStoreValue: false,
  1864. showText(text) {
  1865. if (chooseMode == null) {
  1866. return text;
  1867. }
  1868. return text + ` 手动: ${chooseMode == 1 ? "移动端" : chooseMode == 2 ? "PC端" : "未知"}`;
  1869. },
  1870. callback: () => {
  1871. let allowValue = [0, 1, 2];
  1872. let chooseText = window.prompt("请输入当前脚本环境判定\n1. 自动判断: 0\n2. 移动端: 1\n3. PC端: 2", "0");
  1873. if (!chooseText) {
  1874. return;
  1875. }
  1876. let chooseMode2 = parseInt(chooseText);
  1877. if (isNaN(chooseMode2)) {
  1878. Qmsg.error("输入的不是规范的数字");
  1879. return;
  1880. }
  1881. if (!allowValue.includes(chooseMode2)) {
  1882. Qmsg.error("输入的值必须是0或1或2");
  1883. return;
  1884. }
  1885. if (chooseMode2 == 0) {
  1886. _GM_deleteValue(CHANGE_ENV_SET_KEY);
  1887. } else {
  1888. _GM_setValue(CHANGE_ENV_SET_KEY, chooseMode2);
  1889. }
  1890. }
  1891. }
  1892. );
  1893. if (chooseMode != null) {
  1894. log.info(`手动判定为${chooseMode === 1 ? "移动端" : "PC端"}`);
  1895. if (chooseMode == 1) {
  1896. M_CSDN.init();
  1897. } else if (chooseMode == 2) {
  1898. CSDN.init();
  1899. } else {
  1900. Qmsg.error("意外,手动判定的值不在范围内");
  1901. _GM_deleteValue(CHANGE_ENV_SET_KEY);
  1902. }
  1903. } else {
  1904. if (isMobile) {
  1905. log.info("自动判定为移动端");
  1906. M_CSDN.init();
  1907. } else {
  1908. log.info("自动判定为PC端");
  1909. CSDN.init();
  1910. }
  1911. }
  1912.  
  1913. })(Qmsg);