CSDN优化

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

当前为 2024-04-15 提交的版本,查看 最新版本

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