CSDN优化

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

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

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