CSDN优化

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

当前为 2024-03-16 提交的版本,查看 最新版本

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