CSDN|简书优化

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

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

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