CSDN优化

支持PC和手机端、屏蔽广告、优化浏览体验、重定向拦截的Url、自动展开全文、自动展开代码块、全文居中、允许复制内容、去除复制内容的小尾巴、自定义屏蔽元素等

当前为 2024-07-14 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name CSDN优化
  3. // @namespace https://github.com/WhiteSevs/TamperMonkeyScript
  4. // @version 2024.7.14
  5. // @author WhiteSevs
  6. // @description 支持PC和手机端、屏蔽广告、优化浏览体验、重定向拦截的Url、自动展开全文、自动展开代码块、全文居中、允许复制内容、去除复制内容的小尾巴、自定义屏蔽元素等
  7. // @license GPL-3.0-only
  8. // @icon data:image/png;base64,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
  9. // @supportURL https://github.com/WhiteSevs/TamperMonkeyScript/issues
  10. // @match *://*.csdn.net/*
  11. // @require https://update.greasyfork.org/scripts/494167/1376186/CoverUMD.js
  12. // @require https://fastly.jsdelivr.net/npm/qmsg@1.2.1/dist/index.umd.js
  13. // @require https://fastly.jsdelivr.net/npm/@whitesev/utils@1.6.0/dist/index.umd.js
  14. // @require https://fastly.jsdelivr.net/npm/@whitesev/domutils@1.1.2/dist/index.umd.js
  15. // @require https://fastly.jsdelivr.net/npm/@whitesev/pops@1.2.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, pops) {
  30. 'use strict';
  31.  
  32. var _a;
  33. var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)();
  34. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  35. var _GM_info = /* @__PURE__ */ (() => typeof GM_info != "undefined" ? GM_info : void 0)();
  36. var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  37. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  38. var _GM_unregisterMenuCommand = /* @__PURE__ */ (() => typeof GM_unregisterMenuCommand != "undefined" ? GM_unregisterMenuCommand : void 0)();
  39. var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  40. var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  41. var _monkeyWindow = /* @__PURE__ */ (() => window)();
  42. const _SCRIPT_NAME_ = "CSDN优化";
  43. const utils = Utils.noConflict();
  44. const domutils = DOMUtils.noConflict();
  45. const __pops = pops;
  46. const log = new utils.Log(
  47. _GM_info,
  48. _unsafeWindow.console || _monkeyWindow.console
  49. );
  50. const SCRIPT_NAME = ((_a = _GM_info == null ? void 0 : _GM_info.script) == null ? void 0 : _a.name) || _SCRIPT_NAME_;
  51. const DEBUG = false;
  52. log.config({
  53. debug: DEBUG,
  54. logMaxCount: 1e3,
  55. autoClearConsole: true,
  56. tag: true
  57. });
  58. Qmsg.config(
  59. Object.defineProperties(
  60. {
  61. html: true,
  62. autoClose: true,
  63. showClose: false
  64. },
  65. {
  66. position: {
  67. get() {
  68. return PopsPanel.getValue("qmsg-config-position", "bottom");
  69. }
  70. },
  71. maxNums: {
  72. get() {
  73. return PopsPanel.getValue("qmsg-config-maxnums", 5);
  74. }
  75. },
  76. showReverse: {
  77. get() {
  78. return PopsPanel.getValue("qmsg-config-showreverse", true);
  79. }
  80. },
  81. zIndex: {
  82. get() {
  83. let maxZIndex = Utils.getMaxZIndex();
  84. let popsMaxZIndex = pops.config.InstanceUtils.getPopsMaxZIndex(maxZIndex).zIndex;
  85. return Utils.getMaxValue(maxZIndex, popsMaxZIndex) + 100;
  86. }
  87. }
  88. }
  89. )
  90. );
  91. const GM_Menu = new utils.GM_Menu({
  92. GM_getValue: _GM_getValue,
  93. GM_setValue: _GM_setValue,
  94. GM_registerMenuCommand: _GM_registerMenuCommand,
  95. GM_unregisterMenuCommand: _GM_unregisterMenuCommand
  96. });
  97. const httpx = new utils.Httpx(_GM_xmlhttpRequest);
  98. httpx.interceptors.response.use(void 0, (data) => {
  99. log.error(["拦截器-请求错误", data]);
  100. if (data.type === "onabort") {
  101. Qmsg.warning("请求取消");
  102. } else if (data.type === "onerror") {
  103. Qmsg.error("请求异常");
  104. } else if (data.type === "ontimeout") {
  105. Qmsg.error("请求超时");
  106. } else {
  107. Qmsg.error("其它错误");
  108. }
  109. return data;
  110. });
  111. httpx.config({
  112. logDetails: DEBUG
  113. });
  114. ({
  115. Object: {
  116. defineProperty: _unsafeWindow.Object.defineProperty
  117. },
  118. Function: {
  119. apply: _unsafeWindow.Function.prototype.apply,
  120. call: _unsafeWindow.Function.prototype.call
  121. },
  122. Element: {
  123. appendChild: _unsafeWindow.Element.prototype.appendChild
  124. },
  125. setTimeout: _unsafeWindow.setTimeout
  126. });
  127. const addStyle = utils.addStyle;
  128. const KEY = "GM_Panel";
  129. const ATTRIBUTE_KEY = "data-key";
  130. const ATTRIBUTE_DEFAULT_VALUE = "data-default-value";
  131. const CSDNRouter = {
  132. /**
  133. * 判断是否是华为云联盟
  134. * + huaweicloud.csdn.net
  135. */
  136. isHuaWeiCloudBlog() {
  137. return Boolean(/huaweicloud.csdn.net/i.test(window.location.origin));
  138. },
  139. /**
  140. * 判断是否是博客
  141. * + blog.csdn.net
  142. */
  143. isBlog() {
  144. return Boolean(/blog.csdn.net/i.test(window.location.origin));
  145. },
  146. /**
  147. * 判断是否是文库
  148. * + wenku.csdn.net
  149. */
  150. isWenKu() {
  151. return Boolean(/wenku.csdn.net/i.test(window.location.origin));
  152. },
  153. /**
  154. * 判断是否是链接
  155. * + link.csdn.net
  156. */
  157. isLink() {
  158. return window.location.hostname === "link.csdn.net";
  159. },
  160. /**
  161. * 判断是否是搜索
  162. * + so.csdn.net
  163. */
  164. isSo() {
  165. return window.location.hostname === "so.csdn.net";
  166. },
  167. /**
  168. * 判断是否是C知道
  169. * + so.csdn.net/know
  170. * + /chat
  171. * + /so/ai
  172. */
  173. isSoCKnow() {
  174. return this.isSo() && (window.location.pathname.startsWith("/chat") || window.location.pathname.startsWith("/so/ai"));
  175. },
  176. /**
  177. * 判断是否是资源页面
  178. * + download.csdn.net
  179. */
  180. isDownload() {
  181. return window.location.hostname === "download.csdn.net";
  182. }
  183. };
  184. const UISlider = function(text, key, defaultValue, min, max, changeCallBack, getToolTipContent, description) {
  185. let result = {
  186. text,
  187. type: "slider",
  188. description,
  189. attributes: {},
  190. getValue() {
  191. return PopsPanel.getValue(key, defaultValue);
  192. },
  193. getToolTipContent(value) {
  194. if (typeof getToolTipContent === "function") {
  195. return getToolTipContent(value);
  196. } else {
  197. return `${value}`;
  198. }
  199. },
  200. callback(event, value) {
  201. if (typeof changeCallBack === "function") {
  202. if (changeCallBack(event, value)) {
  203. return;
  204. }
  205. }
  206. PopsPanel.setValue(key, value);
  207. },
  208. min,
  209. max
  210. };
  211. if (result.attributes) {
  212. result.attributes[ATTRIBUTE_KEY] = key;
  213. result.attributes[ATTRIBUTE_DEFAULT_VALUE] = defaultValue;
  214. }
  215. return result;
  216. };
  217. const UISwitch = function(text, key, defaultValue, clickCallBack, description) {
  218. let result = {
  219. text,
  220. type: "switch",
  221. description,
  222. attributes: {},
  223. getValue() {
  224. return Boolean(PopsPanel.getValue(key, defaultValue));
  225. },
  226. callback(event, value) {
  227. log.success(`${value ? "开启" : "关闭"} ${text}`);
  228. if (typeof clickCallBack === "function") {
  229. if (clickCallBack(event, value)) {
  230. return;
  231. }
  232. }
  233. PopsPanel.setValue(key, Boolean(value));
  234. },
  235. afterAddToUListCallBack: void 0
  236. };
  237. if (result.attributes) {
  238. result.attributes[ATTRIBUTE_KEY] = key;
  239. result.attributes[ATTRIBUTE_DEFAULT_VALUE] = Boolean(defaultValue);
  240. }
  241. return result;
  242. };
  243. const SettingUIBlog = {
  244. id: "panel-blog",
  245. title: "博客",
  246. isDefault() {
  247. return CSDNRouter.isBlog();
  248. },
  249. forms: [
  250. {
  251. text: "",
  252. type: "forms",
  253. forms: [
  254. {
  255. text: "全局屏蔽",
  256. type: "deepMenu",
  257. forms: [
  258. {
  259. text: "",
  260. type: "forms",
  261. forms: [
  262. UISwitch(
  263. "【屏蔽】登录弹窗",
  264. "csdn-blog-shieldLoginDialog",
  265. true
  266. ),
  267. UISwitch(
  268. "【屏蔽】左侧博客信息",
  269. "csdn-blog-shieldLeftBlogContainerAside",
  270. false
  271. ),
  272. UISwitch(
  273. "【屏蔽】右侧目录信息",
  274. "csdn-blog-shieldRightDirectoryInformation",
  275. false
  276. ),
  277. UISwitch(
  278. "【屏蔽】顶部工具栏",
  279. "csdn-blog-shieldTopToolbar",
  280. false
  281. ),
  282. UISwitch(
  283. "【屏蔽】底部的悬浮工具栏",
  284. "csdn-blog-shieldBottomFloatingToolbar",
  285. false
  286. )
  287. ]
  288. }
  289. ]
  290. },
  291. {
  292. text: "右侧悬浮工具栏",
  293. type: "deepMenu",
  294. forms: [
  295. {
  296. text: "功能",
  297. type: "forms",
  298. forms: [
  299. UISwitch(
  300. "启用",
  301. "csdn-blog-rightToolbarEnable",
  302. true,
  303. void 0,
  304. "创作中心,隐藏/显示侧栏,新手引导,客服、举报..."
  305. ),
  306. UISwitch(
  307. "【添加按钮】前往评论",
  308. "csdn-blog-addGotoRecommandButton",
  309. true,
  310. void 0,
  311. "在悬浮工具栏最后面添加"
  312. ),
  313. UISlider(
  314. "right偏移",
  315. "csdn-blog-rightToolbarRightOffset",
  316. 90,
  317. 0,
  318. document.documentElement.clientWidth,
  319. (event, value) => {
  320. let csdnSideToolbar = document.querySelector(
  321. ".csdn-side-toolbar"
  322. );
  323. domutils.css(csdnSideToolbar, {
  324. right: value + "px"
  325. });
  326. },
  327. (value) => {
  328. return `当前:${value}px,默认:90px`;
  329. }
  330. ),
  331. UISlider(
  332. "top偏移",
  333. "csdn-blog-rightToolbarTopOffset",
  334. 140,
  335. 0,
  336. document.documentElement.clientHeight,
  337. (event, value) => {
  338. let csdnSideToolbar = document.querySelector(
  339. ".csdn-side-toolbar"
  340. );
  341. domutils.css(csdnSideToolbar, {
  342. top: value + "px"
  343. });
  344. },
  345. (value) => {
  346. return `当前:${value}px,默认:90px`;
  347. }
  348. )
  349. ]
  350. },
  351. {
  352. text: "屏蔽",
  353. type: "forms",
  354. forms: [
  355. UISwitch(
  356. "【屏蔽】创作中心",
  357. "csdn-blog-rightToolbarCreativeCenter",
  358. false
  359. ),
  360. UISwitch(
  361. "【屏蔽】显示/隐藏侧栏",
  362. "csdn-blog-rightToolbarShowOrSidebar",
  363. false
  364. ),
  365. UISwitch(
  366. "【屏蔽】新手引导",
  367. "csdn-blog-rightToolbarBeginnerGuidance",
  368. false
  369. ),
  370. UISwitch(
  371. "【屏蔽】客服",
  372. "csdn-blog-rightToolbarCustomerService",
  373. false
  374. ),
  375. UISwitch("【屏蔽】举报", "csdn-blog-rightToolbarReport", false),
  376. UISwitch(
  377. "【屏蔽】返回顶部",
  378. "csdn-blog-rightToolbarBackToTop",
  379. false
  380. )
  381. ]
  382. }
  383. ]
  384. },
  385. {
  386. text: "内容",
  387. type: "deepMenu",
  388. forms: [
  389. {
  390. text: "功能",
  391. type: "forms",
  392. forms: [
  393. UISwitch(
  394. "点击代码块自动展开",
  395. "csdn-blog-clickPreCodeAutomatically",
  396. true,
  397. void 0,
  398. "当鼠标点击代码块区域时,将自动展开内容"
  399. ),
  400. UISwitch(
  401. "自动展开代码块",
  402. "csdn-blog-autoExpandCodeContent",
  403. true,
  404. void 0,
  405. "懒人操作,免手动点击展开"
  406. ),
  407. UISwitch(
  408. "自动展开内容",
  409. "csdn-blog-autoExpandContent",
  410. true,
  411. void 0,
  412. "懒人操作,免手动点击展开"
  413. ),
  414. UISwitch(
  415. "全文居中",
  416. "csdn-blog-articleCenter",
  417. true,
  418. function(event, enable) {
  419. if (enable) {
  420. alert(
  421. "为了更好的呈现效果,请开启功能:【屏蔽】左侧博客信息、【屏蔽】右侧目录信息"
  422. );
  423. }
  424. },
  425. "自动屏蔽左侧和右侧的信息,且将文章居中"
  426. ),
  427. UISwitch(
  428. "允许选择内容",
  429. "csdn-blog-allowSelectContent",
  430. true,
  431. void 0
  432. )
  433. ]
  434. },
  435. {
  436. text: "屏蔽",
  437. type: "forms",
  438. forms: [
  439. UISwitch(
  440. "【屏蔽】底部xx技能树",
  441. "csdn-blog-shieldBottomSkillTree",
  442. false
  443. ),
  444. UISwitch(
  445. "【屏蔽】选中文字悬浮栏",
  446. "csdn-blog-shieldArticleSearchTip",
  447. false,
  448. void 0,
  449. "选中文字弹出的,例如:搜索、评论、笔记"
  450. )
  451. ]
  452. }
  453. ]
  454. },
  455. {
  456. text: "评论区",
  457. type: "deepMenu",
  458. forms: [
  459. {
  460. text: "",
  461. type: "forms",
  462. forms: [
  463. UISwitch(
  464. "启用",
  465. "csdn-blog-blockComment",
  466. true,
  467. void 0,
  468. "关闭是屏蔽评论区"
  469. ),
  470. UISwitch("优化评论区的位置", "csdn-blog-restoreComments", true)
  471. ]
  472. }
  473. ]
  474. },
  475. {
  476. text: "底部文章",
  477. type: "deepMenu",
  478. forms: [
  479. {
  480. text: "",
  481. type: "forms",
  482. forms: [
  483. UISwitch(
  484. "启用",
  485. "csdn-blog-bottomRecommendArticleEnable",
  486. true,
  487. void 0,
  488. "关闭是屏蔽底部文章"
  489. ),
  490. UISwitch(
  491. "标识CSDN下载",
  492. "csdn-blog-identityCSDNDownload",
  493. true,
  494. void 0,
  495. "使用红框标识"
  496. ),
  497. UISwitch(
  498. "移除资源下载的文章",
  499. "csdn-blog-removeResourceDownloadArticle",
  500. false,
  501. void 0,
  502. "移除download.csdn.net、www.iteye.com、edu.csdn.net的文章链接"
  503. )
  504. ]
  505. }
  506. ]
  507. },
  508. {
  509. text: "劫持/拦截",
  510. type: "deepMenu",
  511. forms: [
  512. {
  513. text: "",
  514. type: "forms",
  515. forms: [
  516. UISwitch(
  517. "拦截-复制的小尾巴",
  518. "csdn-blog-removeClipboardHijacking",
  519. true
  520. ),
  521. UISwitch(
  522. "劫持-禁止复制",
  523. "csdn-blog-unBlockCopy",
  524. true,
  525. void 0,
  526. "允许点击复制按钮进行复制"
  527. )
  528. ]
  529. }
  530. ]
  531. }
  532. ]
  533. }
  534. ]
  535. };
  536. const SettingUILink = {
  537. id: "panel-link",
  538. title: "链接",
  539. isDefault() {
  540. return CSDNRouter.isLink();
  541. },
  542. forms: [
  543. {
  544. text: "功能",
  545. type: "forms",
  546. forms: [
  547. UISwitch(
  548. "重定向链接",
  549. "csdn-link-jumpRedirect",
  550. true,
  551. void 0,
  552. "自动跳转至被拦截的Url链接"
  553. )
  554. ]
  555. }
  556. ]
  557. };
  558. const SettingUIHuaWeiCloud = {
  559. id: "panel-hua-wei-cloud",
  560. title: "华为云开发者联盟",
  561. isDefault() {
  562. return CSDNRouter.isHuaWeiCloudBlog();
  563. },
  564. forms: [
  565. {
  566. text: "功能",
  567. type: "forms",
  568. forms: [
  569. UISwitch("自动展开全文", "csdn-hua-wei-cloud-autoExpandContent", true)
  570. ]
  571. },
  572. {
  573. text: "屏蔽",
  574. type: "forms",
  575. forms: [
  576. UISwitch(
  577. "【屏蔽】云开发者任务挑战活动",
  578. "csdn-hua-wei-cloud-shieldCloudDeveloperTaskChallengeEvent",
  579. true
  580. ),
  581. UISwitch(
  582. "【屏蔽】左侧悬浮按钮",
  583. "csdn-hua-wei-cloud-shieldLeftFloatingButton",
  584. false,
  585. function(event, enable) {
  586. if (enable) {
  587. alert(
  588. "开启后将屏蔽【当前阅读量】、【点赞按钮】、【评论按钮】、【分享按钮】"
  589. );
  590. }
  591. }
  592. ),
  593. UISwitch(
  594. "【屏蔽】右侧栏",
  595. "csdn-hua-wei-cloud-blockRightColumn",
  596. false,
  597. function(event, enable) {
  598. if (enable) {
  599. alert(
  600. "开启后将屏蔽【相关产品】-【活动日历】-【运营活动】-【热门标签】"
  601. );
  602. }
  603. }
  604. ),
  605. UISwitch(
  606. "【屏蔽】底部推荐内容",
  607. "csdn-hua-wei-cloud-blockRecommendedContentAtTheBottom",
  608. false
  609. ),
  610. UISwitch(
  611. "【屏蔽】底部更多推荐",
  612. "csdn-hua-wei-cloud-shieldTheBottomForMoreRecommendations",
  613. false
  614. )
  615. ]
  616. }
  617. ]
  618. };
  619. const SettingUIWenKu = {
  620. id: "panel-wenku",
  621. title: "资源",
  622. isDefault() {
  623. return CSDNRouter.isLink();
  624. },
  625. forms: [
  626. {
  627. text: "屏蔽",
  628. type: "forms",
  629. forms: [
  630. UISwitch(
  631. "【屏蔽】资源推荐",
  632. "csdn-wenku-shieldResourceRecommend",
  633. false
  634. ),
  635. UISwitch(
  636. "【屏蔽】右侧用户信息",
  637. "csdn-wenku-shieldRightUserInfo",
  638. false
  639. ),
  640. UISwitch(
  641. "【屏蔽】右侧悬浮工具栏",
  642. "csdn-wenku-shieldRightToolBar",
  643. false
  644. )
  645. ]
  646. }
  647. ]
  648. };
  649. const SettingUISo = {
  650. id: "panel-so",
  651. title: "搜索",
  652. isDefault() {
  653. return CSDNRouter.isSo();
  654. },
  655. forms: [
  656. {
  657. text: "C知道-功能",
  658. type: "forms",
  659. forms: [UISwitch("去除水印", "csdn-so-cknow-removeMaskCover", true)]
  660. }
  661. ]
  662. };
  663. const MSettingUIBlog = {
  664. id: "m-panel-blog",
  665. title: "博客",
  666. isDefault() {
  667. return CSDNRouter.isBlog();
  668. },
  669. forms: [
  670. {
  671. text: "",
  672. type: "forms",
  673. forms: [
  674. {
  675. text: "全局屏蔽",
  676. type: "deepMenu",
  677. forms: [
  678. {
  679. text: "",
  680. type: "forms",
  681. forms: [
  682. UISwitch(
  683. "【屏蔽】广告",
  684. "m-csdn-blog-removeAds",
  685. true,
  686. void 0,
  687. "包括:登录弹窗、打开APP、ios版本提示等"
  688. ),
  689. UISwitch(
  690. "【屏蔽】顶部Toolbar",
  691. "m-csdn-blog-shieldTopToolbar",
  692. false
  693. )
  694. ]
  695. }
  696. ]
  697. },
  698. {
  699. text: "内容",
  700. type: "deepMenu",
  701. forms: [
  702. {
  703. text: "",
  704. type: "forms",
  705. forms: [
  706. UISwitch(
  707. "允许选中文字",
  708. "m-csdn-blog-allowSelectText",
  709. true,
  710. void 0,
  711. "设置user-select: text;"
  712. ),
  713. UISwitch(
  714. "自动展开",
  715. "m-csdn-blog-autoExpandContent",
  716. true,
  717. void 0,
  718. "包括内容、代码块"
  719. ),
  720. UISwitch(
  721. "不限制代码块的最大高度",
  722. "m-csdn-blog-notLimitCodePreMaxHeight",
  723. false,
  724. void 0,
  725. "让代码块的高度直接被撑开"
  726. )
  727. ]
  728. }
  729. ]
  730. },
  731. {
  732. text: "评论",
  733. type: "deepMenu",
  734. forms: [
  735. {
  736. text: "",
  737. type: "forms",
  738. forms: [
  739. UISwitch(
  740. "启用",
  741. "m-csdn-blog-comment-enable",
  742. true,
  743. void 0,
  744. "关闭是屏蔽评论区"
  745. ),
  746. UISwitch(
  747. "不限制评论区的最大高度",
  748. "m-csdn-blog-notLimitCommentMaxHeight",
  749. true,
  750. void 0,
  751. "让评论区高度直接被撑开"
  752. )
  753. ]
  754. }
  755. ]
  756. },
  757. {
  758. text: "底部文章",
  759. type: "deepMenu",
  760. forms: [
  761. {
  762. text: "",
  763. type: "forms",
  764. forms: [
  765. UISwitch(
  766. "启用",
  767. "m-csdn-blog-bottomArticleEnable",
  768. true,
  769. void 0,
  770. "关闭是屏蔽底部文章"
  771. ),
  772. UISwitch(
  773. "移除资源下载",
  774. "m-csdn-blog-removeResourceArticle",
  775. false,
  776. void 0,
  777. "移除download.csdn.net、www.iteye.com、edu.csdn.net的文章链接"
  778. ),
  779. UISwitch(
  780. "重构",
  781. "m-csdn-blog-refactoringRecommendation",
  782. true,
  783. void 0,
  784. "文章的样式统一"
  785. ),
  786. UISwitch(
  787. "新标签页打开",
  788. "m-csdn-blog-openNewTab",
  789. true,
  790. void 0,
  791. "新标签页打开文章"
  792. )
  793. ]
  794. }
  795. ]
  796. },
  797. {
  798. text: "劫持/拦截",
  799. type: "deepMenu",
  800. forms: [
  801. {
  802. text: "",
  803. type: "forms",
  804. forms: [
  805. UISwitch(
  806. "劫持-禁止复制",
  807. "m-csdn-blog-unBlockCopy",
  808. true,
  809. void 0,
  810. "允许点击复制按钮进行复制"
  811. )
  812. ]
  813. }
  814. ]
  815. }
  816. ]
  817. }
  818. ]
  819. };
  820. const MSettingUILink = {
  821. id: "m-panel-link",
  822. title: "链接",
  823. isDefault() {
  824. return CSDNRouter.isLink();
  825. },
  826. forms: [
  827. {
  828. text: "功能",
  829. type: "forms",
  830. forms: [
  831. UISwitch(
  832. "重定向链接",
  833. "m-csdn-link-jumpRedirect",
  834. true,
  835. void 0,
  836. "自动跳转至被拦截的Url链接"
  837. )
  838. ]
  839. }
  840. ]
  841. };
  842. const MSettingUISo = {
  843. id: "panel-so",
  844. title: "搜索",
  845. isDefault() {
  846. return CSDNRouter.isSo();
  847. },
  848. forms: [
  849. {
  850. text: "C知道-功能",
  851. type: "forms",
  852. forms: [UISwitch("去除水印", "m-csdn-so-cknow-removeMaskCover", true)]
  853. }
  854. ]
  855. };
  856. const MSettingUIWenKu = {
  857. id: "m-panel-wenku",
  858. title: "文库",
  859. isDefault() {
  860. return CSDNRouter.isWenKu();
  861. },
  862. forms: [
  863. {
  864. text: "屏蔽",
  865. type: "forms",
  866. forms: [
  867. UISwitch(
  868. "【屏蔽】底部工具栏",
  869. "m-csdn-wenku-shieldBottomToolbar",
  870. false
  871. )
  872. ]
  873. }
  874. ]
  875. };
  876. const MSettingUIHuaWeiCloud = {
  877. id: "m-panel-hua-wei-cloud",
  878. title: "华为云开发者联盟",
  879. isDefault() {
  880. return CSDNRouter.isHuaWeiCloudBlog();
  881. },
  882. forms: [
  883. {
  884. text: "功能",
  885. type: "forms",
  886. forms: [
  887. UISwitch(
  888. "自动展开全文",
  889. "m-csdn-hua-wei-cloud-autoExpandContent",
  890. true
  891. )
  892. ]
  893. }
  894. ]
  895. };
  896. const MSettingUIDownload = {
  897. id: "m-panel-download",
  898. title: "资源",
  899. isDefault() {
  900. return CSDNRouter.isDownload();
  901. },
  902. forms: [
  903. {
  904. text: "功能",
  905. type: "forms",
  906. forms: [
  907. UISwitch(
  908. "自动展开资源介绍",
  909. "m-csdn-download-automaticallyExpandResourceIntroduction",
  910. true,
  911. void 0,
  912. "屏蔽资源介绍【展开全部】按钮并展开资源介绍"
  913. )
  914. ]
  915. },
  916. {
  917. text: "屏蔽",
  918. type: "forms",
  919. forms: [
  920. UISwitch(
  921. "【屏蔽】广告",
  922. "m-csdn-download-removeAds",
  923. true,
  924. void 0,
  925. "包括:登录弹窗、会员降价等"
  926. )
  927. ]
  928. }
  929. ]
  930. };
  931. const UISelect = function(text, key, defaultValue, data, callback, description) {
  932. let selectData = [];
  933. if (typeof data === "function") {
  934. selectData = data();
  935. } else {
  936. selectData = data;
  937. }
  938. let result = {
  939. text,
  940. type: "select",
  941. description,
  942. attributes: {},
  943. getValue() {
  944. return PopsPanel.getValue(key, defaultValue);
  945. },
  946. callback(event, isSelectedValue, isSelectedText) {
  947. PopsPanel.setValue(key, isSelectedValue);
  948. if (typeof callback === "function") {
  949. callback(event, isSelectedValue, isSelectedText);
  950. }
  951. },
  952. data: selectData
  953. };
  954. if (result.attributes) {
  955. result.attributes[ATTRIBUTE_KEY] = key;
  956. result.attributes[ATTRIBUTE_DEFAULT_VALUE] = defaultValue;
  957. }
  958. return result;
  959. };
  960. const SettingUICommon = {
  961. id: "component-common",
  962. title: "通用",
  963. forms: [
  964. {
  965. text: "Toast配置",
  966. type: "forms",
  967. forms: [
  968. UISelect(
  969. "Toast位置",
  970. "qmsg-config-position",
  971. "bottom",
  972. [
  973. {
  974. value: "topleft",
  975. text: "左上角"
  976. },
  977. {
  978. value: "top",
  979. text: "顶部"
  980. },
  981. {
  982. value: "topright",
  983. text: "右上角"
  984. },
  985. {
  986. value: "left",
  987. text: "左边"
  988. },
  989. {
  990. value: "center",
  991. text: "中间"
  992. },
  993. {
  994. value: "right",
  995. text: "右边"
  996. },
  997. {
  998. value: "bottomleft",
  999. text: "左下角"
  1000. },
  1001. {
  1002. value: "bottom",
  1003. text: "底部"
  1004. },
  1005. {
  1006. value: "bottomright",
  1007. text: "右下角"
  1008. }
  1009. ],
  1010. (event, isSelectValue, isSelectText) => {
  1011. log.info("设置当前Qmsg弹出位置" + isSelectText);
  1012. },
  1013. "Toast显示在页面九宫格的位置"
  1014. ),
  1015. UISelect(
  1016. "最多显示的数量",
  1017. "qmsg-config-maxnums",
  1018. 3,
  1019. [
  1020. {
  1021. value: 1,
  1022. text: "1"
  1023. },
  1024. {
  1025. value: 2,
  1026. text: "2"
  1027. },
  1028. {
  1029. value: 3,
  1030. text: "3"
  1031. },
  1032. {
  1033. value: 4,
  1034. text: "4"
  1035. },
  1036. {
  1037. value: 5,
  1038. text: "5"
  1039. }
  1040. ],
  1041. void 0,
  1042. "限制Toast显示的数量"
  1043. ),
  1044. UISwitch(
  1045. "逆序弹出",
  1046. "qmsg-config-showreverse",
  1047. false,
  1048. void 0,
  1049. "修改Toast弹出的顺序"
  1050. )
  1051. ]
  1052. }
  1053. // {
  1054. // text: "Cookie配置",
  1055. // type: "forms",
  1056. // forms: [
  1057. // UISwitch(
  1058. // "启用",
  1059. // "httpx-use-cookie-enable",
  1060. // false,
  1061. // void 0,
  1062. // "启用后,将根据下面的配置进行添加cookie"
  1063. // ),
  1064. // UISwitch(
  1065. // "使用document.cookie",
  1066. // "httpx-use-document-cookie",
  1067. // false,
  1068. // void 0,
  1069. // "自动根据请求的域名来设置对应的cookie"
  1070. // ),
  1071. // UITextArea(
  1072. // "tieba.baidu.com",
  1073. // "httpx-cookie-tieba.baidu.com",
  1074. // "",
  1075. // void 0,
  1076. // void 0,
  1077. // "Cookie格式:xxx=xxxx;xxx=xxxx"
  1078. // ),
  1079. // ],
  1080. // },
  1081. ]
  1082. };
  1083. const MSettingUICommon = {
  1084. id: "component-common",
  1085. title: "通用",
  1086. forms: [
  1087. {
  1088. text: "Toast配置",
  1089. type: "forms",
  1090. forms: [
  1091. UISelect(
  1092. "Toast位置",
  1093. "qmsg-config-position",
  1094. "bottom",
  1095. [
  1096. {
  1097. value: "topleft",
  1098. text: "左上角"
  1099. },
  1100. {
  1101. value: "top",
  1102. text: "顶部"
  1103. },
  1104. {
  1105. value: "topright",
  1106. text: "右上角"
  1107. },
  1108. {
  1109. value: "left",
  1110. text: "左边"
  1111. },
  1112. {
  1113. value: "center",
  1114. text: "中间"
  1115. },
  1116. {
  1117. value: "right",
  1118. text: "右边"
  1119. },
  1120. {
  1121. value: "bottomleft",
  1122. text: "左下角"
  1123. },
  1124. {
  1125. value: "bottom",
  1126. text: "底部"
  1127. },
  1128. {
  1129. value: "bottomright",
  1130. text: "右下角"
  1131. }
  1132. ],
  1133. (event, isSelectValue, isSelectText) => {
  1134. log.info("设置当前Qmsg弹出位置" + isSelectText);
  1135. },
  1136. "Toast显示在页面九宫格的位置"
  1137. ),
  1138. UISelect(
  1139. "最多显示的数量",
  1140. "qmsg-config-maxnums",
  1141. 3,
  1142. [
  1143. {
  1144. value: 1,
  1145. text: "1"
  1146. },
  1147. {
  1148. value: 2,
  1149. text: "2"
  1150. },
  1151. {
  1152. value: 3,
  1153. text: "3"
  1154. },
  1155. {
  1156. value: 4,
  1157. text: "4"
  1158. },
  1159. {
  1160. value: 5,
  1161. text: "5"
  1162. }
  1163. ],
  1164. void 0,
  1165. "限制Toast显示的数量"
  1166. ),
  1167. UISwitch(
  1168. "逆序弹出",
  1169. "qmsg-config-showreverse",
  1170. false,
  1171. void 0,
  1172. "修改Toast弹出的顺序"
  1173. )
  1174. ]
  1175. }
  1176. // {
  1177. // text: "Cookie配置",
  1178. // type: "forms",
  1179. // forms: [
  1180. // UISwitch(
  1181. // "启用",
  1182. // "httpx-use-cookie-enable",
  1183. // false,
  1184. // void 0,
  1185. // "启用后,将根据下面的配置进行添加cookie"
  1186. // ),
  1187. // UISwitch(
  1188. // "使用document.cookie",
  1189. // "httpx-use-document-cookie",
  1190. // false,
  1191. // void 0,
  1192. // "自动根据请求的域名来设置对应的cookie"
  1193. // ),
  1194. // UITextArea(
  1195. // "tieba.baidu.com",
  1196. // "httpx-cookie-tieba.baidu.com",
  1197. // "",
  1198. // void 0,
  1199. // void 0,
  1200. // "Cookie格式:xxx=xxxx;xxx=xxxx"
  1201. // ),
  1202. // ],
  1203. // },
  1204. ]
  1205. };
  1206. const __PopsPanel__ = {
  1207. data: null,
  1208. oneSuccessExecMenu: null,
  1209. onceExec: null,
  1210. listenData: null
  1211. };
  1212. const PopsPanel = {
  1213. /** 数据 */
  1214. $data: {
  1215. /**
  1216. * 菜单项的默认值
  1217. */
  1218. get data() {
  1219. if (__PopsPanel__.data == null) {
  1220. __PopsPanel__.data = new utils.Dictionary();
  1221. }
  1222. return __PopsPanel__.data;
  1223. },
  1224. /**
  1225. * 成功只执行了一次的项
  1226. */
  1227. get oneSuccessExecMenu() {
  1228. if (__PopsPanel__.oneSuccessExecMenu == null) {
  1229. __PopsPanel__.oneSuccessExecMenu = new utils.Dictionary();
  1230. }
  1231. return __PopsPanel__.oneSuccessExecMenu;
  1232. },
  1233. /**
  1234. * 成功只执行了一次的项
  1235. */
  1236. get onceExec() {
  1237. if (__PopsPanel__.onceExec == null) {
  1238. __PopsPanel__.onceExec = new utils.Dictionary();
  1239. }
  1240. return __PopsPanel__.onceExec;
  1241. },
  1242. /** 脚本名,一般用在设置的标题上 */
  1243. get scriptName() {
  1244. return SCRIPT_NAME;
  1245. },
  1246. /** 菜单项的总值在本地数据配置的键名 */
  1247. key: KEY,
  1248. /** 菜单项在attributes上配置的菜单键 */
  1249. attributeKeyName: ATTRIBUTE_KEY,
  1250. /** 菜单项在attributes上配置的菜单默认值 */
  1251. attributeDefaultValueName: ATTRIBUTE_DEFAULT_VALUE
  1252. },
  1253. /** 监听器 */
  1254. $listener: {
  1255. /**
  1256. * 值改变的监听器
  1257. */
  1258. get listenData() {
  1259. if (__PopsPanel__.listenData == null) {
  1260. __PopsPanel__.listenData = new utils.Dictionary();
  1261. }
  1262. return __PopsPanel__.listenData;
  1263. }
  1264. },
  1265. init() {
  1266. this.initPanelDefaultValue();
  1267. this.initExtensionsMenu();
  1268. },
  1269. initExtensionsMenu() {
  1270. if (_unsafeWindow.top !== _unsafeWindow.self) {
  1271. return;
  1272. }
  1273. GM_Menu.add([
  1274. {
  1275. key: "show_pops_panel_setting",
  1276. text: "⚙ PC端设置",
  1277. autoReload: false,
  1278. isStoreValue: false,
  1279. showText(text) {
  1280. return text;
  1281. },
  1282. callback: () => {
  1283. this.showPanel();
  1284. }
  1285. },
  1286. {
  1287. key: "m_show_pops_panel_setting",
  1288. text: "⚙ 移动端端设置",
  1289. autoReload: false,
  1290. isStoreValue: false,
  1291. showText(text) {
  1292. return text;
  1293. },
  1294. callback: () => {
  1295. this.showMPanel();
  1296. }
  1297. },
  1298. {
  1299. key: "gotoCSDNCKnow",
  1300. text: "⚙ 前往C知道",
  1301. isStoreValue: false,
  1302. autoReload: false,
  1303. showText(text) {
  1304. return text;
  1305. },
  1306. callback() {
  1307. window.open("https://so.csdn.net/chat", "_blank");
  1308. }
  1309. }
  1310. ]);
  1311. },
  1312. /** 初始化本地设置默认的值 */
  1313. initPanelDefaultValue() {
  1314. let that = this;
  1315. function initDefaultValue(config) {
  1316. if (!config["attributes"]) {
  1317. return;
  1318. }
  1319. let key = config.attributes[ATTRIBUTE_KEY];
  1320. let defaultValue = config["attributes"][ATTRIBUTE_DEFAULT_VALUE];
  1321. if (key == null) {
  1322. log.warn(["请先配置键", config]);
  1323. return;
  1324. }
  1325. if (that.$data.data.has(key)) {
  1326. log.warn("请检查该key(已存在): " + key);
  1327. }
  1328. that.$data.data.set(key, defaultValue);
  1329. }
  1330. function loopInitDefaultValue(configList) {
  1331. for (let index = 0; index < configList.length; index++) {
  1332. let configItem = configList[index];
  1333. initDefaultValue(configItem);
  1334. let childForms = configItem.forms;
  1335. if (childForms && Array.isArray(childForms)) {
  1336. loopInitDefaultValue(childForms);
  1337. }
  1338. }
  1339. }
  1340. let contentConfigList = this.getPanelContentConfig().concat(
  1341. this.getMPanelContentConfig()
  1342. );
  1343. for (let index = 0; index < contentConfigList.length; index++) {
  1344. let leftContentConfigItem = contentConfigList[index];
  1345. if (!leftContentConfigItem.forms) {
  1346. continue;
  1347. }
  1348. let rightContentConfigList = leftContentConfigItem.forms;
  1349. if (rightContentConfigList && Array.isArray(rightContentConfigList)) {
  1350. loopInitDefaultValue(rightContentConfigList);
  1351. }
  1352. }
  1353. },
  1354. /**
  1355. * 设置值
  1356. * @param key 键
  1357. * @param value 值
  1358. */
  1359. setValue(key, value) {
  1360. let locaData = _GM_getValue(KEY, {});
  1361. let oldValue = locaData[key];
  1362. locaData[key] = value;
  1363. _GM_setValue(KEY, locaData);
  1364. if (this.$listener.listenData.has(key)) {
  1365. this.$listener.listenData.get(key).callback(key, oldValue, value);
  1366. }
  1367. },
  1368. /**
  1369. * 判断该键是否存在
  1370. * @param key 键
  1371. */
  1372. hasKey(key) {
  1373. let locaData = _GM_getValue(KEY, {});
  1374. return key in locaData;
  1375. },
  1376. /**
  1377. * 获取值
  1378. * @param key 键
  1379. * @param defaultValue 默认值
  1380. */
  1381. getValue(key, defaultValue) {
  1382. let locaData = _GM_getValue(KEY, {});
  1383. let localValue = locaData[key];
  1384. if (localValue == null) {
  1385. if (this.$data.data.has(key)) {
  1386. return this.$data.data.get(key);
  1387. }
  1388. return defaultValue;
  1389. }
  1390. return localValue;
  1391. },
  1392. /**
  1393. * 删除值
  1394. * @param key 键
  1395. */
  1396. deleteValue(key) {
  1397. let locaData = _GM_getValue(KEY, {});
  1398. let oldValue = locaData[key];
  1399. Reflect.deleteProperty(locaData, key);
  1400. _GM_setValue(KEY, locaData);
  1401. if (this.$listener.listenData.has(key)) {
  1402. this.$listener.listenData.get(key).callback(key, oldValue, void 0);
  1403. }
  1404. },
  1405. /**
  1406. * 监听调用setValue、deleteValue
  1407. * @param key 需要监听的键
  1408. * @param callback
  1409. */
  1410. addValueChangeListener(key, callback) {
  1411. let listenerId = Math.random();
  1412. this.$listener.listenData.set(key, {
  1413. id: listenerId,
  1414. key,
  1415. callback
  1416. });
  1417. return listenerId;
  1418. },
  1419. /**
  1420. * 移除监听
  1421. * @param listenerId 监听的id
  1422. */
  1423. removeValueChangeListener(listenerId) {
  1424. let deleteKey = null;
  1425. for (const [key, value] of this.$listener.listenData.entries()) {
  1426. if (value.id === listenerId) {
  1427. deleteKey = key;
  1428. break;
  1429. }
  1430. }
  1431. if (typeof deleteKey === "string") {
  1432. this.$listener.listenData.delete(deleteKey);
  1433. } else {
  1434. console.warn("没有找到对应的监听器");
  1435. }
  1436. },
  1437. /**
  1438. * 自动判断菜单是否启用,然后执行回调
  1439. * @param key
  1440. * @param callback 回调
  1441. */
  1442. execMenu(key, callback) {
  1443. if (typeof key !== "string") {
  1444. throw new TypeError("key 必须是字符串");
  1445. }
  1446. if (!this.$data.data.has(key)) {
  1447. log.warn(`${key} 键不存在`);
  1448. return;
  1449. }
  1450. let value = PopsPanel.getValue(key);
  1451. if (value) {
  1452. callback(value);
  1453. }
  1454. },
  1455. /**
  1456. * 自动判断菜单是否启用,然后执行回调,只会执行一次
  1457. * @param key
  1458. * @param callback 回调
  1459. */
  1460. execMenuOnce(key, callback) {
  1461. if (typeof key !== "string") {
  1462. throw new TypeError("key 必须是字符串");
  1463. }
  1464. if (!this.$data.data.has(key)) {
  1465. log.warn(`${key} 键不存在`);
  1466. return;
  1467. }
  1468. let value = PopsPanel.getValue(key);
  1469. if (value) {
  1470. if (this.$data.oneSuccessExecMenu.has(key)) {
  1471. return;
  1472. }
  1473. callback(value);
  1474. this.$data.oneSuccessExecMenu.set(key, 1);
  1475. }
  1476. },
  1477. /**
  1478. * 根据key执行一次
  1479. * @param key
  1480. */
  1481. onceExec(key, callback) {
  1482. if (typeof key !== "string") {
  1483. throw new TypeError("key 必须是字符串");
  1484. }
  1485. if (this.$data.onceExec.has(key)) {
  1486. return;
  1487. }
  1488. callback();
  1489. this.$data.onceExec.set(key, 1);
  1490. },
  1491. /**
  1492. * 显示设置面板
  1493. */
  1494. showPanel() {
  1495. __pops.panel({
  1496. title: {
  1497. text: `${SCRIPT_NAME}-PC端设置`,
  1498. position: "center",
  1499. html: false,
  1500. style: ""
  1501. },
  1502. content: this.getPanelContentConfig(),
  1503. mask: {
  1504. enable: true,
  1505. clickEvent: {
  1506. toClose: true,
  1507. toHide: false
  1508. }
  1509. },
  1510. isMobile: this.isMobile(),
  1511. width: this.getWidth(),
  1512. height: this.getHeight(),
  1513. drag: true,
  1514. only: true
  1515. });
  1516. },
  1517. /**
  1518. * 显示设置面板
  1519. */
  1520. showMPanel() {
  1521. __pops.panel({
  1522. title: {
  1523. text: `${SCRIPT_NAME}-移动端设置`,
  1524. position: "center",
  1525. html: false,
  1526. style: ""
  1527. },
  1528. content: this.getMPanelContentConfig(),
  1529. mask: {
  1530. enable: true,
  1531. clickEvent: {
  1532. toClose: true,
  1533. toHide: false
  1534. }
  1535. },
  1536. isMobile: this.isMobile(),
  1537. width: this.getWidth(),
  1538. height: this.getHeight(),
  1539. drag: true,
  1540. only: true
  1541. });
  1542. },
  1543. isMobile() {
  1544. return window.outerWidth < 550;
  1545. },
  1546. /**
  1547. * 获取设置面板的宽度
  1548. */
  1549. getWidth() {
  1550. if (window.outerWidth < 800) {
  1551. return "92dvw";
  1552. } else {
  1553. return "800px";
  1554. }
  1555. },
  1556. /**
  1557. * 获取设置面板的高度
  1558. */
  1559. getHeight() {
  1560. if (window.outerHeight > 450) {
  1561. return "80dvh";
  1562. } else {
  1563. return "450px";
  1564. }
  1565. },
  1566. /**
  1567. * 获取配置内容
  1568. */
  1569. getPanelContentConfig() {
  1570. let configList = [
  1571. SettingUICommon,
  1572. SettingUIBlog,
  1573. SettingUILink,
  1574. SettingUIHuaWeiCloud,
  1575. SettingUIWenKu,
  1576. SettingUISo
  1577. ];
  1578. return configList;
  1579. },
  1580. /**
  1581. * 获取配置内容
  1582. */
  1583. getMPanelContentConfig() {
  1584. let configList = [
  1585. MSettingUICommon,
  1586. MSettingUIBlog,
  1587. MSettingUILink,
  1588. MSettingUIHuaWeiCloud,
  1589. MSettingUIWenKu,
  1590. MSettingUISo,
  1591. MSettingUIDownload
  1592. ];
  1593. return configList;
  1594. }
  1595. };
  1596. 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";
  1597. const CSDNUtils = {
  1598. /**
  1599. * 移除元素(未出现也可以等待出现)
  1600. * @param selectorText 元素选择器
  1601. */
  1602. waitForElementToRemove(selectorText = "") {
  1603. utils.waitNodeList(selectorText).then((nodeList) => {
  1604. nodeList.forEach((item) => item.remove());
  1605. });
  1606. },
  1607. /**
  1608. * 添加屏蔽CSS
  1609. * @param args
  1610. * @example
  1611. * addBlockCSS("")
  1612. * addBlockCSS("","")
  1613. * addBlockCSS(["",""])
  1614. */
  1615. addBlockCSS(...args) {
  1616. let selectorList = [];
  1617. if (args.length === 0) {
  1618. return;
  1619. }
  1620. if (args.length === 1 && typeof args[0] === "string" && args[0].trim() === "") {
  1621. return;
  1622. }
  1623. args.forEach((selector) => {
  1624. if (Array.isArray(selector)) {
  1625. selectorList = selectorList.concat(selector);
  1626. } else {
  1627. selectorList.push(selector);
  1628. }
  1629. });
  1630. addStyle(`${selectorList.join(",\n")}{display: none !important;}`);
  1631. }
  1632. };
  1633. const CSDNHuaWeiCloud = {
  1634. init() {
  1635. addStyle(ShieldCSS$4);
  1636. PopsPanel.execMenu(
  1637. "csdn-hua-wei-cloud-shieldCloudDeveloperTaskChallengeEvent",
  1638. () => {
  1639. this.shieldCloudDeveloperTaskChallengeEvent();
  1640. }
  1641. );
  1642. PopsPanel.execMenu("csdn-hua-wei-cloud-autoExpandContent", () => {
  1643. this.autoExpandContent();
  1644. });
  1645. PopsPanel.execMenu("csdn-hua-wei-cloud-shieldLeftFloatingButton", () => {
  1646. this.shieldLeftFloatingButton();
  1647. });
  1648. PopsPanel.execMenu("csdn-hua-wei-cloud-blockRightColumn", () => {
  1649. this.blockRightColumn();
  1650. });
  1651. PopsPanel.execMenu(
  1652. "csdn-hua-wei-cloud-blockRecommendedContentAtTheBottom",
  1653. () => {
  1654. this.blockRecommendedContentAtTheBottom();
  1655. }
  1656. );
  1657. PopsPanel.execMenu(
  1658. "csdn-hua-wei-cloud-shieldTheBottomForMoreRecommendations",
  1659. () => {
  1660. this.shieldTheBottomForMoreRecommendations();
  1661. }
  1662. );
  1663. },
  1664. /**
  1665. * 自动展开内容
  1666. */
  1667. autoExpandContent() {
  1668. log.info("自动展开全文");
  1669. CSDNUtils.addBlockCSS("div.article-show-more");
  1670. addStyle(`
  1671. /* 自动展开全文 */
  1672. .main-content .user-article{
  1673. height: auto !important;
  1674. overflow: auto !important;
  1675. }
  1676. `);
  1677. },
  1678. /**
  1679. * 屏蔽云开发者任务挑战活动
  1680. */
  1681. shieldCloudDeveloperTaskChallengeEvent() {
  1682. let GM_cookie = new utils.GM_Cookie();
  1683. GM_cookie.set({ name: "show_join_group_index", value: 1 });
  1684. log.info("设置Cookie 屏蔽云开发者任务挑战活动");
  1685. },
  1686. /**
  1687. * 屏蔽左侧悬浮按钮
  1688. */
  1689. shieldLeftFloatingButton() {
  1690. log.info("屏蔽左侧悬浮按钮,包括当前阅读量、点赞按钮、评论按钮、分享按钮");
  1691. CSDNUtils.addBlockCSS("div.toolbar-wrapper.article-interact-bar");
  1692. },
  1693. /**
  1694. * 屏蔽右侧栏
  1695. */
  1696. blockRightColumn() {
  1697. log.info("屏蔽右侧栏,包括相关产品-活动日历-运营活动-热门标签");
  1698. CSDNUtils.addBlockCSS("div.page-home-right.dp-aside-right");
  1699. },
  1700. /**
  1701. * 屏蔽底部推荐内容
  1702. */
  1703. blockRecommendedContentAtTheBottom() {
  1704. log.info("屏蔽底部推荐内容");
  1705. CSDNUtils.addBlockCSS("div.recommend-card-box");
  1706. },
  1707. /**
  1708. * 屏蔽底部更多推荐
  1709. */
  1710. shieldTheBottomForMoreRecommendations() {
  1711. log.info("屏蔽底部更多推荐");
  1712. CSDNUtils.addBlockCSS("div.more-article");
  1713. }
  1714. };
  1715. 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";
  1716. const BlogCSS = "/*.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";
  1717. const BlogArticleCenterCSS = '#mainBox main {\r\n width: inherit !important;\r\n}\r\n/* 当文章向下滚动时,触发左侧信息悬浮 */\r\naside.blog_container_aside[style*="position: fixed;"] {\r\n display: none !important;\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';
  1718. const CSDNBlogRightToolBar = {
  1719. init() {
  1720. if (!PopsPanel.getValue("csdn-blog-rightToolbarEnable")) {
  1721. this.shieldRightToolbar();
  1722. }
  1723. PopsPanel.execMenuOnce("csdn-blog-rightToolbarCreativeCenter", () => {
  1724. this.shieldCreativeCenter();
  1725. });
  1726. PopsPanel.execMenuOnce("csdn-blog-rightToolbarShowOrSidebar", () => {
  1727. this.shieldShowOrSidebar();
  1728. });
  1729. PopsPanel.execMenuOnce("csdn-blog-rightToolbarBeginnerGuidance", () => {
  1730. this.shieldBeginnerGuidance();
  1731. });
  1732. PopsPanel.execMenuOnce("csdn-blog-rightToolbarCustomerService", () => {
  1733. this.shieldCustomerService();
  1734. });
  1735. PopsPanel.execMenuOnce("csdn-blog-rightToolbarReport", () => {
  1736. this.shieldReport();
  1737. });
  1738. PopsPanel.execMenuOnce("csdn-blog-rightToolbarBackToTop", () => {
  1739. this.shieldBackToTop();
  1740. });
  1741. this.initRightToolbarOffset();
  1742. domutils.ready(() => {
  1743. PopsPanel.execMenu("csdn-blog-addGotoRecommandButton", () => {
  1744. this.addGotoRecommandButton();
  1745. });
  1746. });
  1747. },
  1748. /**
  1749. * 屏蔽右侧工具栏
  1750. */
  1751. shieldRightToolbar() {
  1752. log.info("屏蔽右侧工具栏");
  1753. CSDNUtils.addBlockCSS(`div.csdn-side-toolbar`);
  1754. },
  1755. /**
  1756. * 【添加】前往评论按钮,在返回顶部的下面
  1757. */
  1758. addGotoRecommandButton() {
  1759. log.info("【添加】前往评论按钮,在返回顶部的上面");
  1760. let gotoRecommandNode = document.createElement("a");
  1761. gotoRecommandNode.className = "option-box";
  1762. gotoRecommandNode.setAttribute("data-type", "gorecommand");
  1763. gotoRecommandNode.innerHTML = `<span class="show-txt" style="display:flex;opacity:100;">前往<br>评论</span>`;
  1764. gotoRecommandNode.addEventListener("click", function() {
  1765. let toolbarBoxElement = document.querySelector(
  1766. "#toolBarBox"
  1767. );
  1768. if (!toolbarBoxElement.getClientRects().length) {
  1769. log.error("评论区处于隐藏状态");
  1770. return;
  1771. }
  1772. log.info("滚动到评论");
  1773. let toolbarBoxOffsetTop = toolbarBoxElement.getBoundingClientRect().top + window.scrollY;
  1774. let csdnToolBarElement = document.querySelector(
  1775. "#csdn-toolbar"
  1776. );
  1777. let csdnToolBarStyles = window.getComputedStyle(csdnToolBarElement);
  1778. let csdnToolBarHeight = csdnToolBarElement.clientHeight - parseFloat(csdnToolBarStyles.paddingTop) - parseFloat(csdnToolBarStyles.paddingBottom);
  1779. window.scrollTo({
  1780. top: toolbarBoxOffsetTop - csdnToolBarHeight - 8,
  1781. left: 0,
  1782. behavior: "smooth"
  1783. });
  1784. });
  1785. utils.waitNode(".csdn-side-toolbar").then(() => {
  1786. let targetElement = document.querySelector(
  1787. ".csdn-side-toolbar a:nth-last-child(2)"
  1788. );
  1789. targetElement.parentElement.insertBefore(
  1790. gotoRecommandNode,
  1791. targetElement.nextSibling
  1792. );
  1793. });
  1794. },
  1795. /**
  1796. * 初始化右侧工具栏的偏移(top、right)
  1797. */
  1798. initRightToolbarOffset() {
  1799. log.info("初始化右侧工具栏的偏移(top、right)");
  1800. addStyle(`
  1801. .csdn-side-toolbar{
  1802. left: unset !important;
  1803. }
  1804. `);
  1805. utils.waitNode(".csdn-side-toolbar").then(($sideToolbar) => {
  1806. domutils.css($sideToolbar, {
  1807. top: parseInt(PopsPanel.getValue("csdn-blog-rightToolbarTopOffset")) + "px",
  1808. right: parseInt(PopsPanel.getValue("csdn-blog-rightToolbarRightOffset")) + "px"
  1809. });
  1810. });
  1811. },
  1812. /**
  1813. * 【屏蔽】创作中心
  1814. */
  1815. shieldCreativeCenter() {
  1816. log.info("【屏蔽】创作中心");
  1817. CSDNUtils.addBlockCSS(".csdn-side-toolbar .sidetool-writeguide-box");
  1818. },
  1819. /**
  1820. * 【屏蔽】显示/隐藏侧栏
  1821. */
  1822. shieldShowOrSidebar() {
  1823. log.info("【屏蔽】显示/隐藏侧栏");
  1824. CSDNUtils.addBlockCSS(".csdn-side-toolbar a.sidecolumn");
  1825. },
  1826. /**
  1827. * 【屏蔽】新手引导
  1828. */
  1829. shieldBeginnerGuidance() {
  1830. log.info("【屏蔽】新手引导");
  1831. CSDNUtils.addBlockCSS('.csdn-side-toolbar a.option-box[data-type="guide"]');
  1832. },
  1833. /**
  1834. * 【屏蔽】客服
  1835. */
  1836. shieldCustomerService() {
  1837. log.info("【屏蔽】客服");
  1838. CSDNUtils.addBlockCSS('.csdn-side-toolbar a.option-box[data-type="cs"]');
  1839. },
  1840. /**
  1841. * 【屏蔽】举报
  1842. */
  1843. shieldReport() {
  1844. log.info("【屏蔽】举报");
  1845. CSDNUtils.addBlockCSS(
  1846. '.csdn-side-toolbar a.option-box[data-type="report"]'
  1847. );
  1848. },
  1849. /**
  1850. * 【屏蔽】返回顶部
  1851. */
  1852. shieldBackToTop() {
  1853. log.info("【屏蔽】返回顶部");
  1854. CSDNUtils.addBlockCSS('.csdn-side-toolbar a.option-box[data-type="gotop"]');
  1855. }
  1856. };
  1857. const CSDNBlog = {
  1858. init() {
  1859. this.addCSS();
  1860. CSDNBlogRightToolBar.init();
  1861. PopsPanel.execMenu("csdn-blog-articleCenter", () => {
  1862. this.articleCenter();
  1863. });
  1864. PopsPanel.execMenu("csdn-blog-shieldLoginDialog", () => {
  1865. this.shieldLoginDialog();
  1866. });
  1867. PopsPanel.execMenu("csdn-blog-autoExpandContent", () => {
  1868. this.autoExpandContent();
  1869. });
  1870. PopsPanel.execMenu("csdn-blog-autoExpandCodeContent", () => {
  1871. this.autoExpandCodeContent();
  1872. });
  1873. if (!PopsPanel.getValue("csdn-blog-comment-enable")) {
  1874. this.blockComment();
  1875. }
  1876. if (!PopsPanel.getValue("csdn-blog-bottomRecommendArticleEnable")) {
  1877. this.shieldBottomRecommendArticle();
  1878. }
  1879. PopsPanel.execMenu("csdn-blog-shieldBottomSkillTree", () => {
  1880. this.shieldBottomSkillTree();
  1881. });
  1882. PopsPanel.execMenu("csdn-blog-shieldBottomFloatingToolbar", () => {
  1883. this.shieldBottomFloatingToolbar();
  1884. });
  1885. PopsPanel.execMenu("csdn-blog-shieldLeftBlogContainerAside", () => {
  1886. this.shieldLeftBlogContainerAside();
  1887. });
  1888. PopsPanel.execMenu("csdn-blog-shieldRightDirectoryInformation", () => {
  1889. this.shieldRightDirectoryInformation();
  1890. });
  1891. PopsPanel.execMenu("csdn-blog-shieldTopToolbar", () => {
  1892. this.shieldTopToolbar();
  1893. });
  1894. PopsPanel.execMenu("csdn-blog-shieldArticleSearchTip", () => {
  1895. this.shieldArticleSearchTip();
  1896. });
  1897. PopsPanel.execMenu("csdn-blog-allowSelectContent", () => {
  1898. this.allowSelectContent();
  1899. });
  1900. domutils.ready(() => {
  1901. PopsPanel.execMenu("csdn-blog-removeClipboardHijacking", () => {
  1902. this.removeClipboardHijacking();
  1903. });
  1904. PopsPanel.execMenuOnce("csdn-blog-unBlockCopy", () => {
  1905. this.unBlockCopy();
  1906. });
  1907. PopsPanel.execMenu("csdn-blog-identityCSDNDownload", () => {
  1908. this.identityCSDNDownload();
  1909. });
  1910. PopsPanel.execMenuOnce("csdn-blog-clickPreCodeAutomatically", () => {
  1911. this.clickPreCodeAutomatically();
  1912. });
  1913. PopsPanel.execMenu("csdn-blog-restoreComments", () => {
  1914. this.restoreComments();
  1915. });
  1916. });
  1917. },
  1918. /**
  1919. * 添加屏蔽CSS和功能CSS
  1920. */
  1921. addCSS() {
  1922. log.info("添加屏蔽CSS和功能CSS");
  1923. addStyle(BlogShieldCSS);
  1924. addStyle(BlogCSS);
  1925. },
  1926. /**
  1927. * 去除剪贴板劫持
  1928. */
  1929. removeClipboardHijacking() {
  1930. var _a2;
  1931. log.info("去除剪贴板劫持");
  1932. (_a2 = document.querySelector(".article-copyright")) == null ? void 0 : _a2.remove();
  1933. if (_unsafeWindow.articleType) {
  1934. _unsafeWindow.articleType = 0;
  1935. }
  1936. if (_unsafeWindow.csdn && _unsafeWindow.csdn.copyright && _unsafeWindow.csdn.copyright.textData) {
  1937. _unsafeWindow.csdn.copyright.textData = "";
  1938. }
  1939. if (_unsafeWindow.csdn && _unsafeWindow.csdn.copyright && _unsafeWindow.csdn.copyright.htmlData) {
  1940. _unsafeWindow.csdn.copyright.htmlData = "";
  1941. }
  1942. },
  1943. /**
  1944. * 取消禁止复制
  1945. */
  1946. unBlockCopy() {
  1947. log.info("取消禁止复制");
  1948. domutils.on(
  1949. document,
  1950. "click",
  1951. function(event) {
  1952. let $click = event.target;
  1953. let $parent = $click.parentElement;
  1954. if (!$click.classList.contains("hljs-button")) {
  1955. return;
  1956. }
  1957. utils.preventEvent(event);
  1958. let copyText = ($parent.innerText || $parent.textContent || "").toString();
  1959. log.info(
  1960. "点击复制按钮复制内容:" + (copyText.length > 8 ? copyText.substring(0, 8) + "..." : copyText)
  1961. );
  1962. utils.setClip(copyText);
  1963. $click.setAttribute("data-title", "复制成功");
  1964. },
  1965. {
  1966. capture: true
  1967. }
  1968. );
  1969. let changeDataTitle = new utils.LockFunction(function(event) {
  1970. let $mouse = event.target;
  1971. if ($mouse.localName !== "pre") {
  1972. return;
  1973. }
  1974. let $hljsBtn = $mouse.querySelector(".hljs-button");
  1975. if ($hljsBtn) {
  1976. $hljsBtn.setAttribute("data-title", "复制");
  1977. }
  1978. });
  1979. domutils.on(
  1980. document,
  1981. ["mouseenter", "mouseleave"],
  1982. function(event) {
  1983. changeDataTitle.run(event);
  1984. },
  1985. {
  1986. capture: true
  1987. }
  1988. );
  1989. utils.waitNode("#content_views").then(($content_views) => {
  1990. var _a2;
  1991. if (_unsafeWindow.$) {
  1992. (_a2 = _unsafeWindow.$("#content_views")) == null ? void 0 : _a2.unbind("copy");
  1993. }
  1994. domutils.on(
  1995. $content_views,
  1996. "copy",
  1997. function(event) {
  1998. utils.preventEvent(event);
  1999. let selectText = _unsafeWindow.getSelection();
  2000. let copyText = selectText == null ? void 0 : selectText.toString();
  2001. log.info(
  2002. "Ctrl+C复制内容:" + (copyText.length > 8 ? copyText.substring(0, 8) + "..." : copyText)
  2003. );
  2004. utils.setClip(copyText);
  2005. return false;
  2006. },
  2007. {
  2008. capture: true
  2009. }
  2010. );
  2011. });
  2012. utils.waitNode(".hljs-button").then(() => {
  2013. setTimeout(() => {
  2014. document.querySelectorAll(".hljs-button").forEach((element) => {
  2015. element.removeAttribute("onclick");
  2016. element.removeAttribute("data-report-click");
  2017. element.setAttribute("data-title", "复制");
  2018. });
  2019. }, 250);
  2020. });
  2021. },
  2022. /**
  2023. * 点击代码块自动展开
  2024. */
  2025. clickPreCodeAutomatically() {
  2026. log.info("点击代码块自动展开");
  2027. document.addEventListener("click", function(event) {
  2028. var _a2;
  2029. let $click = event.target;
  2030. if ($click.localName !== "pre") {
  2031. return;
  2032. }
  2033. $click.style.setProperty("height", "auto");
  2034. (_a2 = $click.querySelector(".hide-preCode-box")) == null ? void 0 : _a2.remove();
  2035. });
  2036. },
  2037. /**
  2038. * 恢复评论到正确位置
  2039. */
  2040. restoreComments() {
  2041. log.info("恢复评论到正确位置-第一条评论");
  2042. utils.waitNode(".first-recommend-box").then(($firstRecommendBox) => {
  2043. let recommendBoxElement = document.querySelector(
  2044. ".recommend-box.insert-baidu-box.recommend-box-style"
  2045. );
  2046. recommendBoxElement.insertBefore(
  2047. $firstRecommendBox,
  2048. recommendBoxElement.firstChild
  2049. );
  2050. });
  2051. log.info("恢复评论到正确位置-第二条评论");
  2052. utils.waitNode(".second-recommend-box").then(($secondRecommendBox) => {
  2053. let recommendBoxElement = document.querySelector(
  2054. ".recommend-box.insert-baidu-box.recommend-box-style"
  2055. );
  2056. recommendBoxElement.insertBefore(
  2057. $secondRecommendBox,
  2058. recommendBoxElement.firstChild
  2059. );
  2060. });
  2061. },
  2062. /**
  2063. * 标识CSDN下载的链接
  2064. */
  2065. identityCSDNDownload() {
  2066. log.info("标识CSDN下载的链接");
  2067. document.querySelectorAll(
  2068. ".recommend-item-box[data-url*='https://download.csdn.net/']"
  2069. ).forEach((item) => {
  2070. if (PopsPanel.getValue("csdn-blog-removeResourceDownloadArticle")) {
  2071. item.remove();
  2072. } else {
  2073. item.querySelector(".content-box").style.setProperty("border", "2px solid red");
  2074. }
  2075. });
  2076. },
  2077. /**
  2078. * 全文居中
  2079. */
  2080. articleCenter() {
  2081. log.info("全文居中");
  2082. addStyle(BlogArticleCenterCSS);
  2083. },
  2084. /**
  2085. * 屏蔽登录弹窗
  2086. */
  2087. shieldLoginDialog() {
  2088. log.info("屏蔽登录弹窗");
  2089. CSDNUtils.addBlockCSS(`.passport-login-container`);
  2090. },
  2091. /**
  2092. * 自动展开代码块
  2093. */
  2094. autoExpandCodeContent() {
  2095. log.info("自动展开代码块");
  2096. CSDNUtils.addBlockCSS("pre.set-code-hide .hide-preCode-box");
  2097. addStyle(`
  2098. pre.set-code-hide{
  2099. height: auto !important;
  2100. }
  2101. /* 自动展开代码块 */
  2102. .comment-list-box,
  2103. main div.blog-content-box pre {
  2104. max-height: none !important;
  2105. }
  2106. `);
  2107. },
  2108. /**
  2109. * 自动展开全文
  2110. */
  2111. autoExpandContent() {
  2112. log.info("自动展开全文");
  2113. addStyle(`
  2114. /* 自动展开全文 */
  2115. #article_content,
  2116. .user-article.user-article-hide {
  2117. height: auto !important;
  2118. overflow: auto !important;
  2119. }
  2120. `);
  2121. },
  2122. /**
  2123. * 屏蔽评论区
  2124. */
  2125. blockComment() {
  2126. log.info("屏蔽评论区");
  2127. CSDNUtils.addBlockCSS(`#pcCommentBox`);
  2128. },
  2129. /**
  2130. * 屏蔽底部推荐文章
  2131. */
  2132. shieldBottomRecommendArticle() {
  2133. log.info("屏蔽底部推荐文章");
  2134. CSDNUtils.addBlockCSS(`main > div.recommend-box`);
  2135. },
  2136. /**
  2137. * 屏蔽底部xx技能树
  2138. */
  2139. shieldBottomSkillTree() {
  2140. log.info("屏蔽底部xx技能树");
  2141. CSDNUtils.addBlockCSS(`#treeSkill`);
  2142. },
  2143. /**
  2144. * 屏蔽底部悬浮工具栏
  2145. */
  2146. shieldBottomFloatingToolbar() {
  2147. log.info("屏蔽底部悬浮工具栏");
  2148. CSDNUtils.addBlockCSS(`#toolBarBox`);
  2149. },
  2150. /**
  2151. * 屏蔽左侧博客信息
  2152. */
  2153. shieldLeftBlogContainerAside() {
  2154. log.info("【屏蔽】左侧博客信息");
  2155. CSDNUtils.addBlockCSS(`aside.blog_container_aside`);
  2156. },
  2157. /**
  2158. * 【屏蔽】右侧目录信息
  2159. */
  2160. shieldRightDirectoryInformation() {
  2161. log.info("【屏蔽】右侧目录信息");
  2162. CSDNUtils.addBlockCSS("#rightAsideConcision", "#rightAside");
  2163. },
  2164. /**
  2165. * 屏蔽顶部Toolbar
  2166. */
  2167. shieldTopToolbar() {
  2168. log.info("屏蔽顶部Toolbar");
  2169. CSDNUtils.addBlockCSS(`#toolbarBox`);
  2170. },
  2171. /**
  2172. * 屏蔽文章内的选中搜索悬浮提示
  2173. */
  2174. shieldArticleSearchTip() {
  2175. log.info("屏蔽文章内的选中搜索悬浮提示");
  2176. CSDNUtils.addBlockCSS(`#articleSearchTip`);
  2177. },
  2178. /**
  2179. * 允许选择内容
  2180. */
  2181. allowSelectContent() {
  2182. log.info("允许选择内容");
  2183. addStyle(`
  2184. #content_views,
  2185. #content_views pre,
  2186. #content_views pre code {
  2187. user-select: text !important;
  2188. }
  2189. `);
  2190. }
  2191. };
  2192. 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";
  2193. 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}";
  2194. const CSDNWenKu = {
  2195. init() {
  2196. addStyle(WenkuCSS);
  2197. addStyle(ShieldCSS$3);
  2198. PopsPanel.execMenu("csdn-wenku-shieldResourceRecommend", () => {
  2199. this.shieldResourceRecommend();
  2200. });
  2201. PopsPanel.execMenu("csdn-wenku-shieldRightUserInfo", () => {
  2202. this.shieldRightUserInfo();
  2203. });
  2204. PopsPanel.execMenu("csdn-wenku-shieldRightToolBar", () => {
  2205. this.shieldRightToolBar();
  2206. });
  2207. },
  2208. /**
  2209. * 【屏蔽】资源推荐
  2210. */
  2211. shieldResourceRecommend() {
  2212. log.info("【屏蔽】资源推荐");
  2213. CSDNUtils.addBlockCSS("#recommend");
  2214. },
  2215. /**
  2216. * 【屏蔽】右侧用户信息
  2217. */
  2218. shieldRightUserInfo() {
  2219. log.info("【屏蔽】右侧用户信息");
  2220. CSDNUtils.addBlockCSS(".layout-right");
  2221. },
  2222. /**
  2223. * 【屏蔽】右侧悬浮工具栏
  2224. */
  2225. shieldRightToolBar() {
  2226. log.info("【屏蔽】右侧悬浮工具栏");
  2227. CSDNUtils.addBlockCSS(".csdn-side-toolbar");
  2228. }
  2229. };
  2230. const CSDNLink = {
  2231. init() {
  2232. PopsPanel.execMenu("csdn-link-jumpRedirect", () => {
  2233. this.jumpRedirect();
  2234. });
  2235. },
  2236. /**
  2237. * 去除CSDN拦截其它网址的url并自动跳转
  2238. */
  2239. jumpRedirect() {
  2240. if (window.location.hostname === "link.csdn.net" && window.location.search.startsWith("?target")) {
  2241. window.stop();
  2242. let search = window.location.search.replace(/^\?target=/gi, "");
  2243. search = decodeURIComponent(search);
  2244. let newURL = search;
  2245. log.success(`跳转链接 ${newURL}`);
  2246. window.location.href = newURL;
  2247. }
  2248. }
  2249. };
  2250. const CSDN = {
  2251. init() {
  2252. if (CSDNRouter.isLink()) {
  2253. log.info("Router: 中转链接");
  2254. CSDNLink.init();
  2255. } else if (CSDNRouter.isHuaWeiCloudBlog()) {
  2256. log.info("Router: 华为云联盟");
  2257. CSDNHuaWeiCloud.init();
  2258. } else if (CSDNRouter.isBlog()) {
  2259. log.info("Router: 博客");
  2260. CSDNBlog.init();
  2261. } else if (CSDNRouter.isWenKu()) {
  2262. log.info("Router: 文库");
  2263. CSDNWenKu.init();
  2264. } else {
  2265. log.error("暂未适配,请反馈开发者:" + globalThis.location.href);
  2266. }
  2267. }
  2268. };
  2269. const M_CSDNLink = {
  2270. init() {
  2271. PopsPanel.execMenu("m-csdn-link-jumpRedirect", () => {
  2272. CSDNLink.jumpRedirect();
  2273. });
  2274. }
  2275. };
  2276. const ShieldCSS$2 = "/* 右下角的 免费赢华为平板xxxx */\r\n.org-main-content .siderbar-box {\r\n display: none !important;\r\n}\r\n";
  2277. const M_CSDNHuaWeiCloud = {
  2278. init() {
  2279. addStyle(ShieldCSS$2);
  2280. PopsPanel.execMenu("m-csdn-hua-wei-cloud-autoExpandContent", () => {
  2281. CSDNHuaWeiCloud.autoExpandContent();
  2282. });
  2283. }
  2284. };
  2285. 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";
  2286. 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";
  2287. const M_CSDNBlog = {
  2288. init() {
  2289. this.addCSS();
  2290. PopsPanel.execMenu("m-csdn-blog-shieldTopToolbar", () => {
  2291. this.shieldTopToolbar();
  2292. });
  2293. PopsPanel.execMenu("m-csdn-blog-notLimitCodePreMaxHeight", () => {
  2294. this.notLimitCodePreMaxHeight();
  2295. });
  2296. PopsPanel.execMenu("m-csdn-blog-notLimitCommentMaxHeight", () => {
  2297. this.notLimitCommentMaxHeight();
  2298. });
  2299. PopsPanel.execMenu("m-csdn-blog-allowSelectText", () => {
  2300. this.allowSelectText();
  2301. });
  2302. PopsPanel.execMenu("m-csdn-blog-autoExpandContent", () => {
  2303. this.autoExpandContent();
  2304. });
  2305. if (!PopsPanel.getValue("m-csdn-blog-bottomArticleEnable")) {
  2306. this.blockBottomArticle();
  2307. }
  2308. if (!PopsPanel.getValue("m-csdn-blog-comment-enable")) {
  2309. this.blockComment();
  2310. }
  2311. domutils.ready(() => {
  2312. PopsPanel.execMenu("m-csdn-blog-removeAds", () => {
  2313. this.removeAds();
  2314. });
  2315. PopsPanel.execMenu("m-csdn-blog-refactoringRecommendation", () => {
  2316. this.refactoringRecommendation();
  2317. });
  2318. PopsPanel.execMenu("m-csdn-blog-unBlockCopy", () => {
  2319. CSDNBlog.unBlockCopy();
  2320. });
  2321. });
  2322. },
  2323. addCSS() {
  2324. addStyle(ShieldCSS$1);
  2325. addStyle(MBlogCSS);
  2326. },
  2327. /**
  2328. * 屏蔽顶部Toolbar
  2329. */
  2330. shieldTopToolbar() {
  2331. log.info("屏蔽顶部Toolbar");
  2332. CSDNUtils.addBlockCSS("#csdn-toolbar");
  2333. addStyle(`
  2334. /* 内容顶部要归位 */
  2335. body #main,
  2336. .margin_sides{
  2337. margin-top: unset !important;
  2338. padding-top: unset !important;
  2339. }
  2340. #article .article_title{
  2341. margin-top: .32rem !important;
  2342. padding-top: unset !important;
  2343. }
  2344. `);
  2345. },
  2346. /**
  2347. * 重构底部推荐
  2348. */
  2349. refactoringRecommendation() {
  2350. function refactoring() {
  2351. log.info("重构底部推荐");
  2352. document.querySelectorAll(
  2353. ".container-fluid"
  2354. ).forEach((item) => {
  2355. var _a2, _b;
  2356. let url = "";
  2357. let title = "";
  2358. let content = "";
  2359. let img = "";
  2360. let isCSDNDownload = false;
  2361. let isCSDNEduDownload = false;
  2362. if (item.hasAttribute("data-url")) {
  2363. url = item.getAttribute("data-url");
  2364. title = (_a2 = item.querySelector(".recommend_title div.left")) == null ? void 0 : _a2.innerHTML;
  2365. if (!item.querySelector(".text")) {
  2366. return;
  2367. }
  2368. content = (_b = item.querySelector(".text")) == null ? void 0 : _b.innerHTML;
  2369. if (item.querySelectorAll(".recommend-img").length) {
  2370. item.querySelectorAll(".recommend-img").forEach((item2) => {
  2371. img += item2.innerHTML;
  2372. });
  2373. }
  2374. } else {
  2375. log.info("节点上无data-url");
  2376. url = item.querySelector("a[data-type]").getAttribute("href");
  2377. title = item.querySelector(".recommend_title div.left").innerHTML;
  2378. content = item.querySelector(".text").innerHTML;
  2379. }
  2380. var _URL_ = new URL(url);
  2381. if (_URL_.host === "download.csdn.net" || _URL_.host === "www.iteye.com" && _URL_.pathname.match(/^\/resource/gi)) {
  2382. log.info("该链接为csdn资源下载");
  2383. isCSDNDownload = true;
  2384. title = `<div class="component-box"><a class="praise" href="javascript:;">CSDN下载</a></div>` + title;
  2385. } else if (_URL_.origin.match(/edu.csdn.net/gi)) {
  2386. isCSDNEduDownload = true;
  2387. log.info("该链接为csdn学院下载");
  2388. title = `<div class="component-box"><a class="csdn-edu-title" href="javascript:;">CSDN学院</a></div>` + title;
  2389. }
  2390. item.setAttribute("class", "GM-csdn-dl");
  2391. item.setAttribute("data-url", url);
  2392. 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>`;
  2393. item.addEventListener("click", function() {
  2394. if (PopsPanel.getValue("m-csdn-blog-openNewTab")) {
  2395. window.open(url, "_blank");
  2396. } else {
  2397. window.location.href = url;
  2398. }
  2399. });
  2400. if ((isCSDNDownload || isCSDNEduDownload) && PopsPanel.getValue("m-csdn-blog-removeResourceArticle")) {
  2401. item.remove();
  2402. }
  2403. });
  2404. }
  2405. let lockFunction = new utils.LockFunction(refactoring, 50);
  2406. utils.waitNode("#recommend").then(($recommend) => {
  2407. log.info("重构底部推荐");
  2408. lockFunction.run();
  2409. utils.mutationObserver($recommend, {
  2410. callback: () => {
  2411. lockFunction.run();
  2412. },
  2413. config: { childList: true, subtree: true, attributes: true }
  2414. });
  2415. });
  2416. },
  2417. /**
  2418. * 屏蔽底部文章
  2419. */
  2420. blockBottomArticle() {
  2421. log.info("屏蔽底部文章");
  2422. CSDNUtils.addBlockCSS("#recommend");
  2423. },
  2424. /**
  2425. * 屏蔽评论
  2426. */
  2427. blockComment() {
  2428. log.info("屏蔽评论");
  2429. CSDNUtils.addBlockCSS("#comment");
  2430. },
  2431. /**
  2432. * 去除广告
  2433. */
  2434. removeAds() {
  2435. log.info("去除广告");
  2436. CSDNUtils.waitForElementToRemove(".passport-login-container");
  2437. CSDNUtils.waitForElementToRemove(
  2438. ".btn_open_app_prompt_box.detail-open-removed"
  2439. );
  2440. CSDNUtils.waitForElementToRemove(".add-firstAd");
  2441. CSDNUtils.waitForElementToRemove("div.feed-Sign-weixin");
  2442. CSDNUtils.waitForElementToRemove("div.ios-shadowbox");
  2443. },
  2444. /**
  2445. * 不限制代码块最大高度
  2446. */
  2447. notLimitCodePreMaxHeight() {
  2448. log.info("不限制代码块最大高度");
  2449. addStyle(`
  2450. pre{
  2451. max-height: unset !important;
  2452. }
  2453. `);
  2454. },
  2455. /**
  2456. * 不限制评论区最大高度
  2457. */
  2458. notLimitCommentMaxHeight() {
  2459. log.info("不限制评论区最大高度");
  2460. addStyle(`
  2461. #comment{
  2462. max-height: none !important;
  2463. }
  2464. `);
  2465. },
  2466. /**
  2467. * 允许选择文字
  2468. */
  2469. allowSelectText() {
  2470. log.info("允许选择文字");
  2471. addStyle(`
  2472. #content_views,
  2473. #content_views pre,
  2474. #content_views pre code{
  2475. webkit-touch-callout: text !important;
  2476. -webkit-user-select: text !important;
  2477. -khtml-user-select: text !important;
  2478. -moz-user-select: text !important;
  2479. -ms-user-select: text !important;
  2480. user-select: text !important;
  2481. }
  2482. `);
  2483. },
  2484. /**
  2485. * 自动展开内容
  2486. */
  2487. autoExpandContent() {
  2488. log.info("自动展开内容");
  2489. addStyle(`
  2490. #content_views pre.set-code-hide,
  2491. .article_content{
  2492. height: 100% !important;
  2493. overflow: auto !important;
  2494. }
  2495. `);
  2496. }
  2497. };
  2498. const ShieldCSS = "/* 右下角的买一年送3个月的广告图标 */\r\n.blind_box {\r\n display: none !important;\r\n}\r\n";
  2499. const M_CSDNWenKu = {
  2500. init() {
  2501. addStyle(ShieldCSS);
  2502. PopsPanel.execMenu("m-csdn-wenku-shieldBottomToolbar", () => {
  2503. this.shieldBottomToolbar();
  2504. });
  2505. },
  2506. /**
  2507. * 【屏蔽】底部工具栏
  2508. */
  2509. shieldBottomToolbar() {
  2510. log.info("【屏蔽】底部工具栏");
  2511. CSDNUtils.addBlockCSS(`.page-container > div.btn`);
  2512. }
  2513. };
  2514. const CSDNBlockCSS = "/* 右下角悬浮图标 买1年送3个月 */\r\n.page-container .blind_box,\r\n/* 底部工具栏右边的 开会员按钮(低至xx元/次) */\r\n.page-container .btn .ml-12,\r\n/* 登录弹窗 */\r\n.passport-login-container,\r\n/* 通用广告className匹配 */\r\n.ads {\r\n display: none !important;\r\n}\r\n";
  2515. const M_CSDNDownload = {
  2516. init() {
  2517. PopsPanel.execMenu("m-csdn-download-removeAds", () => {
  2518. addStyle(CSDNBlockCSS);
  2519. });
  2520. PopsPanel.execMenuOnce(
  2521. "m-csdn-download-automaticallyExpandResourceIntroduction",
  2522. () => {
  2523. this.automaticallyExpandResourceIntroduction();
  2524. }
  2525. );
  2526. },
  2527. /**
  2528. * 自动展开资源介绍
  2529. */
  2530. automaticallyExpandResourceIntroduction() {
  2531. log.info("自动展开资源介绍");
  2532. CSDNUtils.addBlockCSS("label.unfold-font");
  2533. addStyle(`
  2534. .resource-desc{
  2535. max-height: unset !important;
  2536. overflow: unset !important;
  2537. }
  2538. `);
  2539. }
  2540. };
  2541. const M_CSDN = {
  2542. init() {
  2543. if (CSDNRouter.isLink()) {
  2544. log.info("Router: 中转链接");
  2545. M_CSDNLink.init();
  2546. } else if (CSDNRouter.isHuaWeiCloudBlog()) {
  2547. log.info("Router: 华为云联盟");
  2548. M_CSDNHuaWeiCloud.init();
  2549. } else if (CSDNRouter.isBlog()) {
  2550. log.info("Router: 博客");
  2551. M_CSDNBlog.init();
  2552. } else if (CSDNRouter.isWenKu()) {
  2553. log.info("Router: 文库");
  2554. M_CSDNWenKu.init();
  2555. } else if (CSDNRouter.isDownload()) {
  2556. log.info("Router: 资源下载");
  2557. M_CSDNDownload.init();
  2558. } else {
  2559. log.error("暂未适配,请反馈开发者:" + globalThis.location.href);
  2560. }
  2561. }
  2562. };
  2563. PopsPanel.init();
  2564. let isMobile = utils.isPhone();
  2565. let CHANGE_ENV_SET_KEY = "change_env_set";
  2566. let chooseMode = _GM_getValue(CHANGE_ENV_SET_KEY);
  2567. GM_Menu.add({
  2568. key: CHANGE_ENV_SET_KEY,
  2569. text: `⚙ 自动: ${isMobile ? "移动端" : "PC端"}`,
  2570. autoReload: false,
  2571. isStoreValue: false,
  2572. showText(text) {
  2573. if (chooseMode == null) {
  2574. return text;
  2575. }
  2576. return text + ` 手动: ${chooseMode == 1 ? "移动端" : chooseMode == 2 ? "PC端" : "未知"}`;
  2577. },
  2578. callback: () => {
  2579. let allowValue = [0, 1, 2];
  2580. let chooseText = window.prompt(
  2581. "请输入当前脚本环境判定\n\n自动判断: 0\n移动端: 1\nPC端: 2",
  2582. "0"
  2583. );
  2584. if (!chooseText) {
  2585. return;
  2586. }
  2587. let chooseMode2 = parseInt(chooseText);
  2588. if (isNaN(chooseMode2)) {
  2589. Qmsg.error("输入的不是规范的数字");
  2590. return;
  2591. }
  2592. if (!allowValue.includes(chooseMode2)) {
  2593. Qmsg.error("输入的值必须是0或1或2");
  2594. return;
  2595. }
  2596. if (chooseMode2 == 0) {
  2597. _GM_deleteValue(CHANGE_ENV_SET_KEY);
  2598. } else {
  2599. _GM_setValue(CHANGE_ENV_SET_KEY, chooseMode2);
  2600. }
  2601. }
  2602. });
  2603. if (chooseMode != null) {
  2604. log.info(`手动判定为${chooseMode === 1 ? "移动端" : "PC端"}`);
  2605. if (chooseMode == 1) {
  2606. M_CSDN.init();
  2607. } else if (chooseMode == 2) {
  2608. CSDN.init();
  2609. } else {
  2610. Qmsg.error("意外,手动判定的值不在范围内");
  2611. _GM_deleteValue(CHANGE_ENV_SET_KEY);
  2612. }
  2613. } else {
  2614. if (isMobile) {
  2615. log.info("自动判定为移动端");
  2616. M_CSDN.init();
  2617. } else {
  2618. log.info("自动判定为PC端");
  2619. CSDN.init();
  2620. }
  2621. }
  2622.  
  2623. })(Qmsg, DOMUtils, Utils, pops);