CSDN|简书优化

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

当前为 2023-12-19 提交的版本,查看 最新版本

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