CSDN|简书优化

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

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

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