CSDN优化

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

目前為 2024-05-30 提交的版本,檢視 最新版本

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

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址