CSDN|简书优化

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

目前為 2023-09-02 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name CSDN|简书优化
  3. // @icon https://www.csdn.net/favicon.ico
  4. // @namespace https://greasyfork.org/zh-CN/scripts/406136-csdn-简书优化
  5. // @supportURL https://greasyfork.org/zh-CN/scripts/406136-csdn-简书优化/feedback
  6. // @version 0.7.3
  7. // @description 支持手机端和PC端,屏蔽广告,优化浏览体验,自动跳转简书拦截URL
  8. // @author WhiteSevs
  9. // @match http*://*.csdn.net/*
  10. // @match http*://*.jianshu.com/*
  11. // @match http*://*.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://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.4.1/jquery.min.js
  22. // @require https://greasyfork.org/scripts/449471-viewer/code/Viewer.js?version=1170654
  23. // @require https://greasyfork.org/scripts/455186-whitesevsutils/code/WhiteSevsUtils.js?version=1244325
  24. // ==/UserScript==
  25.  
  26. (function () {
  27. const utils = Utils.noConflict();
  28. const jQuery = $.noConflict(true);
  29. const log = new utils.Log(GM_info);
  30. log.config({
  31. logMaxCount: 20,
  32. autoClearConsole: true,
  33. });
  34. /**
  35. * 因为在有些页面上,比如:简书,当插入style元素到head中,该页面清除该元素
  36. */
  37. const GM_addStyle = utils.GM_addStyle;
  38. let GM_Menu = null;
  39. /**
  40. * 移除元素(未出现也可以等待出现)
  41. * @param {string} selectorText 元素选择器
  42. */
  43. const waitForElementToRemove = function (selectorText = "") {
  44. utils.waitNode(selectorText).then((dom) => {
  45. dom.forEach((item) => {
  46. item.remove();
  47. });
  48. });
  49. };
  50.  
  51. const Optimization = {
  52. jianshu: {
  53. /**
  54. * 判断是否是简书
  55. */
  56. locationMatch() {
  57. return Boolean(/jianshu.(com|io)/i.test(window.location.origin));
  58. },
  59. PC: {
  60. /**
  61. * 添加屏蔽CSS
  62. */
  63. addCSS() {
  64. GM_addStyle(`
  65. .download-app-guidance,
  66. .call-app-btn,
  67. .collapse-tips,
  68. .note-graceful-button,
  69. .app-open,
  70. .header-wrap,
  71. .recommend-wrap.recommend-ad,
  72. .call-app-Ad-bottom,
  73. #recommended-notes p.top-title span.more,
  74. #homepage .modal,
  75. button.index_call-app-btn,
  76. span.note__flow__download,
  77. .download-guide,
  78. #footer,
  79. .comment-open-app-btn-wrap,
  80. .nav.navbar-nav + div,
  81. .self-flow-ad,
  82. #free-reward-panel,
  83. div[id*='AdFive'],
  84. #index-aside-download-qrbox{
  85. display:none !important;
  86. }
  87. body.reader-day-mode.normal-size {
  88. overflow: auto !important;
  89. }
  90. .collapse-free-content{
  91. height:auto !important;
  92. }
  93. .copyright{
  94. color:#000 !important;
  95. }
  96. #note-show .content .show-content-free .collapse-free-content:after{
  97. background-image:none !important;
  98. }
  99. footer > div > div{
  100. justify-content: center;
  101. }`);
  102. },
  103. /**
  104. * 全文居中
  105. */
  106. articleCenter() {
  107. GM_addStyle(`
  108. div[role=main] aside,
  109. div._3Pnjry{
  110. display: none !important;
  111. }
  112. div._gp-ck{
  113. width: 100% !important;
  114. }`);
  115. waitForElementToRemove("div[role=main] aside");
  116. waitForElementToRemove("div._3Pnjry");
  117. utils.waitNode("div._gp-ck").then((dom) => {
  118. dom.forEach((item) => {
  119. item.style["width"] = "100%";
  120. });
  121. });
  122. },
  123. /**
  124. * 去除剪贴板劫持
  125. */
  126. removeClipboardHijacking() {
  127. const stopNativePropagation = (event) => {
  128. event.stopPropagation();
  129. };
  130. window.addEventListener("copy", stopNativePropagation, true);
  131. document.addEventListener("copy", stopNativePropagation, true);
  132. },
  133. /**
  134. * 自动展开全文
  135. */
  136. autoExpandFullText() {
  137. utils
  138. .waitNode(`div#homepage div[class*="dialog-"]`)
  139. .then((nodeList) => {
  140. nodeList[0].style["visibility"] = "hidden";
  141. utils.mutationObserver(nodeList[0], {
  142. callback: (mutations) => {
  143. if (mutations.length == 0) {
  144. return;
  145. }
  146. if (mutations[0].target.style["display"] != "none") {
  147. document
  148. .querySelector(
  149. 'div#homepage div[class*="dialog-"] .cancel'
  150. )
  151. ?.click();
  152. }
  153. },
  154. config: {
  155. /* 子节点的变动(新增、删除或者更改) */
  156. childList: false,
  157. /* 属性的变动 */
  158. attributes: true,
  159. /* 节点内容或节点文本的变动 */
  160. characterData: true,
  161. /* 是否将观察器应用于该节点的所有后代节点 */
  162. subtree: true,
  163. },
  164. });
  165. });
  166. },
  167. /**
  168. * 去除简书拦截其它网址的url并自动跳转
  169. */
  170. jumpRedirect() {
  171. if (window.location.pathname === "/go-wild") {
  172. /* 禁止简书拦截跳转 */
  173. window.stop();
  174. let search = window.location.href.replace(
  175. window.location.origin + "/",
  176. ""
  177. );
  178. search = decodeURIComponent(search);
  179. let newURL = search
  180. .replace(/^go-wild\?ac=2&url=/gi, "")
  181. .replace(/^https:\/\/link.zhihu.com\/\?target\=/gi, "");
  182. window.location.href = newURL;
  183. }
  184. },
  185. run() {
  186. this.addCSS();
  187. this.removeClipboardHijacking();
  188. this.autoExpandFullText();
  189. if (GM_Menu.get("JianShuArticleCenter")) {
  190. this.articleCenter();
  191. }
  192. },
  193. },
  194. Mobile: {
  195. addCSS() {
  196. Optimization.jianshu.PC.addCSS();
  197. },
  198. /**
  199. * 手机-移除底部推荐阅读
  200. */
  201. removeFooterRecommendRead() {
  202. GM_addStyle(`
  203. #recommended-notes{
  204. display: none !important;
  205. }`);
  206. },
  207. /**
  208. * 处理原型
  209. */
  210. handlePrototype() {
  211. let originalAppendChild = Node.prototype.appendChild;
  212. Node.prototype.appendChild = function (element) {
  213. /* 允许添加的元素localName */
  214. let allowElementLocalNameList = ["img"];
  215. /* 不允许script标签加载包括jianshu.io的js资源,会让简书跳到广告页面 */
  216. if (
  217. element.src &&
  218. !element.src.includes("jianshu.io") &&
  219. !allowElementLocalNameList.includes(element.localName)
  220. ) {
  221. console.log("禁止添加的元素", element);
  222. return null;
  223. } else {
  224. return originalAppendChild.call(this, element);
  225. }
  226. };
  227. },
  228. run() {
  229. Optimization.jianshu.Mobile.handlePrototype();
  230. this.addCSS();
  231. Optimization.jianshu.PC.removeClipboardHijacking();
  232. Optimization.jianshu.PC.autoExpandFullText();
  233. if (GM_Menu.get("JianShuremoveFooterRecommendRead")) {
  234. this.removeFooterRecommendRead();
  235. }
  236. },
  237. },
  238. /**
  239. * 函数入口
  240. */
  241. run() {
  242. this.PC.jumpRedirect();
  243. if (utils.isPhone()) {
  244. log.success("简书-移动端");
  245. this.Mobile.run();
  246. } else {
  247. log.success("简书-桌面端");
  248. this.PC.run();
  249. }
  250. },
  251. },
  252. csdn: {
  253. /**
  254. * 判断是否是CSDN
  255. */
  256. locationMatch() {
  257. return Boolean(/csdn.net/i.test(window.location.origin));
  258. },
  259. PC: {
  260. addCSS() {
  261. GM_addStyle(`
  262. .ecommend-item-box.recommend-recommend-box,
  263. .login-mark,
  264. .opt-box.text-center,
  265. .leftPop,
  266. #csdn-shop-window,
  267. .toolbar-advert,
  268. .hide-article-box,
  269. .user-desc.user-desc-fix,
  270. .recommend-card-box,
  271. .more-article,
  272. .article-show-more,
  273. #csdn-toolbar-profile-nologin,
  274. .guide-rr-first,
  275. #recommend-item-box-tow,
  276. /* 发文章得原力分图片提示 */
  277. div.csdn-toolbar-creative-mp,
  278. /* 阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。 */
  279. #toolBarBox div.write-guide-buttom-box,
  280. /* 觉得还不错? 一键收藏 */
  281. ul.toolbox-list div.tool-active-list{
  282. display: none !important;
  283. }
  284. .comment-list-box{
  285. max-height: none !important;
  286. }
  287. .blog_container_aside,
  288. #nav{
  289. margin-left: -45px;
  290. }
  291. .recommend-right.align-items-stretch.clearfix,.dl_right_fixed{
  292. margin-left: 45px;
  293. }
  294. #content_views pre,
  295. #content_views pre code{
  296. user-select: text !important;
  297. }
  298. #article_content,
  299. .user-article.user-article-hide{
  300. height: auto !important;
  301. overflow: auto !important;
  302. }
  303. `);
  304. },
  305. /**
  306. * 去除剪贴板劫持
  307. */
  308. removeClipboardHijacking() {
  309. log.info("去除剪贴板劫持");
  310. jQuery(".article-copyright")?.remove();
  311. if (unsafeWindow.articleType) {
  312. unsafeWindow.articleType = 0;
  313. }
  314. if (
  315. unsafeWindow.csdn &&
  316. unsafeWindow.csdn.copyright &&
  317. unsafeWindow.csdn.copyright.textData
  318. ) {
  319. unsafeWindow.csdn.copyright.textData = "";
  320. }
  321. if (
  322. unsafeWindow.csdn &&
  323. unsafeWindow.csdn.copyright &&
  324. unsafeWindow.csdn.copyright.htmlData
  325. ) {
  326. unsafeWindow.csdn.copyright.htmlData = "";
  327. }
  328. },
  329. /**
  330. * 取消禁止复制
  331. */
  332. unBlockCopy() {
  333. log.info("取消禁止复制");
  334. jQuery(document).on("click", ".hljs-button", function (event) {
  335. utils.preventEvent(event);
  336. /* 复制按钮 */
  337. let btnNode = jQuery(this);
  338. /* 需要复制的文本 */
  339. let copyText = btnNode.parent().text();
  340. utils.setClip(copyText);
  341. btnNode.attr("data-title", "复制成功");
  342. });
  343. jQuery(document).on("mouseenter mouseleave", "pre", function () {
  344. this.querySelector(".hljs-button")?.setAttribute(
  345. "data-title",
  346. "复制"
  347. );
  348. });
  349. /* 取消Ctrl+C的禁止 */
  350. utils.waitNode("#content_views").then(() => {
  351. unsafeWindow.$("#content_views").unbind("copy");
  352. jQuery("#content_views")
  353. .off("copy")
  354. .on("copy", function (event) {
  355. utils.preventEvent(event);
  356. utils.setClip(unsafeWindow.getSelection().toString());
  357. return false;
  358. });
  359. });
  360. /* 删除所有复制按钮的原有的复制事件 */
  361. jQuery(".hljs-button").each((_, item) => {
  362. item.removeAttribute("onclick");
  363. });
  364. },
  365. /**
  366. * 点击代码块自动展开
  367. */
  368. clickPreCodeAutomatically() {
  369. if (!GM_Menu.get("autoExpandContent")) {
  370. return;
  371. }
  372. log.info("点击代码块自动展开");
  373. jQuery(document).on("click", "pre", function () {
  374. let clickNode = jQuery(this);
  375. clickNode.css("height", "auto");
  376. clickNode.find(".hide-preCode-box")?.remove();
  377. });
  378. },
  379. /**
  380. * 恢复评论到正确位置
  381. */
  382. restoreComments() {
  383. /* 第一条评论 */
  384. log.info("恢复评论到正确位置-第一条评论");
  385. utils.waitNode(".first-recommend-box").then((dom) => {
  386. jQuery(
  387. ".recommend-box.insert-baidu-box.recommend-box-style"
  388. ).prepend(jQuery(dom));
  389. });
  390. log.info("恢复评论到正确位置-第二条评论");
  391. /* 第二条评论 */
  392. utils.waitNode(".second-recommend-box").then((dom) => {
  393. jQuery(
  394. ".recommend-box.insert-baidu-box.recommend-box-style"
  395. ).prepend(jQuery(dom));
  396. });
  397. },
  398. /**
  399. * 标识CSDN下载的链接
  400. */
  401. identityCSDNDownload() {
  402. log.info("标识CSDN下载的链接");
  403. jQuery(
  404. ".recommend-item-box[data-url*='https://download.csdn.net/']"
  405. ).each((index, item) => {
  406. if (GM_Menu.get("removeCSDNDownloadPC")) {
  407. item.remove();
  408. } else {
  409. jQuery(item).find(".content-box").css("border", "2px solid red");
  410. }
  411. });
  412. },
  413. /**
  414. * 全文居中
  415. */
  416. articleCenter() {
  417. if (!GM_Menu.get("articleCenter")) {
  418. return;
  419. }
  420. log.info("全文居中");
  421. GM_addStyle(`
  422. aside.blog_container_aside{
  423. display:none !important;
  424. }
  425. #mainBox main{
  426. width: inherit !important;
  427. }
  428. `);
  429. GM_addStyle(`
  430. @media (min-width: 1320px) and (max-width:1380px) {
  431. .nodata .container {
  432. width:900px !important
  433. }
  434.  
  435. .nodata .container main {
  436. width: 900px
  437. }
  438. .nodata .container main #pcCommentBox pre >ol.hljs-ln {
  439. width: 490px !important
  440. }
  441. .nodata .container main .articleConDownSource {
  442. width: 500px
  443. }
  444. }
  445. @media screen and (max-width: 1320px) {
  446. .nodata .container {
  447. width:760px !important
  448. }
  449. .nodata .container main {
  450. width: 760px
  451. }
  452. .nodata .container main #pcCommentBox pre >ol.hljs-ln {
  453. width: 490px !important
  454. }
  455. .nodata .container main .toolbox-list .tool-reward {
  456. display: none
  457. }
  458. .nodata .container main .more-toolbox-new .toolbox-left .profile-box .profile-name {
  459. max-width: 128px
  460. }
  461. .nodata .container main .articleConDownSource {
  462. width: 420px
  463. }
  464. }
  465. @media screen and (min-width: 1380px) {
  466. .nodata .container {
  467. width:1010px !important
  468. }
  469. .nodata .container main {
  470. width: 1010px
  471. }
  472. .nodata .container main #pcCommentBox pre >ol.hljs-ln {
  473. width: 490px !important
  474. }
  475. .nodata .container main .articleConDownSource {
  476. width: 560px
  477. }
  478. }
  479. @media (min-width: 1550px) and (max-width:1700px) {
  480. .nodata .container {
  481. width:820px !important
  482. }
  483. .nodata .container main {
  484. width: 820px
  485. }
  486. .nodata .container main #pcCommentBox pre >ol.hljs-ln {
  487. width: 690px !important
  488. }
  489. .nodata .container main .articleConDownSource {
  490. width: 500px
  491. }
  492. }
  493. @media screen and (min-width: 1700px) {
  494. .nodata .container {
  495. width:1010px !important
  496. }
  497. .nodata .container main {
  498. width: 1010px
  499. }
  500. .nodata .container main #pcCommentBox pre >ol.hljs-ln {
  501. width: 690px !important
  502. }
  503. .nodata .container main .articleConDownSource {
  504. width: 560px
  505. }
  506. }
  507. `);
  508. },
  509. /**
  510. * 添加前往评论的按钮,在返回顶部的下面
  511. */
  512. addGotoRecommandButton() {
  513. log.info("添加前往评论的按钮,在返回顶部的上面");
  514. let gotoRecommandNode = jQuery(`
  515. <a class="option-box" data-type="gorecommand">
  516. <span class="show-txt" style="display:flex;opacity:100;">前往<br>评论</span>
  517. </a>
  518. `);
  519. jQuery(gotoRecommandNode).on("click", function () {
  520. log.info("滚动到评论");
  521. jQuery("html, body").animate(
  522. {
  523. scrollTop:
  524. jQuery("#toolBarBox").offset().top -
  525. jQuery("#csdn-toolbar").height() -
  526. 8,
  527. },
  528. 1000
  529. );
  530. });
  531. utils.waitNode(".csdn-side-toolbar").then(() => {
  532. jQuery(".csdn-side-toolbar a").eq("-2").after(gotoRecommandNode);
  533. });
  534. },
  535. /**
  536. * 屏蔽登录弹窗
  537. */
  538. shieldLoginDialog() {
  539. if (GM_Menu.get("shieldLoginDialog")) {
  540. log.info("屏蔽登录弹窗");
  541. window.GM_CSS_GM_shieldLoginDialog = [
  542. GM_addStyle(
  543. `.passport-login-container{display: none !important;}`
  544. ),
  545. ];
  546. }
  547. },
  548. /**
  549. * 自动展开内容块
  550. */
  551. autoExpandContent() {
  552. if (!GM_Menu.get("autoExpandContent")) {
  553. return;
  554. }
  555. log.info("自动展开内容块");
  556. GM_addStyle(`
  557. pre.set-code-hide{
  558. height: auto !important;
  559. }
  560. pre.set-code-hide .hide-preCode-box{
  561. display: none !important;
  562. }
  563. `);
  564. },
  565. /**
  566. * 屏蔽右侧悬浮按钮
  567. */
  568. csdnShieldfloatingButton() {
  569. if (!GM_Menu.get("csdnShieldfloatingButton")) {
  570. return;
  571. }
  572. log.info("屏蔽右侧悬浮按钮");
  573. GM_addStyle(`
  574. div.csdn-side-toolbar{
  575. display: none !important;
  576. }
  577. `);
  578. },
  579. /**
  580. * 屏蔽底部推荐文章
  581. */
  582. csdnShieldBottomRecommendArticle() {
  583. if (!GM_Menu.get("csdnShieldBottomRecommendArticle")) {
  584. return;
  585. }
  586. log.info("屏蔽底部推荐文章");
  587. GM_addStyle(`
  588. main > div.recommend-box {
  589. display: none !important;
  590. }
  591. `);
  592. },
  593. /**
  594. * 屏蔽底部悬浮工具栏
  595. */
  596. csdnShieldBottomFloatingToolbar() {
  597. if (!GM_Menu.get("csdnShieldBottomFloatingToolbar")) {
  598. return;
  599. }
  600. log.info("屏蔽底部悬浮工具栏");
  601. GM_addStyle(`
  602. #toolBarBox {
  603. display: none !important;
  604. }
  605. `);
  606. },
  607. /**
  608. * 显示/隐藏目录
  609. */
  610. showOrHideDirectory() {
  611. if (GM_Menu.get("showOrHideDirectory")) {
  612. log.info("显示目录");
  613. GM_addStyle(`
  614. aside.blog_container_aside{
  615. display: none !important;
  616. }
  617. `);
  618. } else {
  619. log.info("隐藏目录");
  620. GM_addStyle(`
  621. aside.blog_container_aside{
  622. display: block !important;
  623. }
  624. `);
  625. }
  626. },
  627. /**
  628. * 显示/隐藏侧边栏
  629. */
  630. showOrHideSidebar() {
  631. if (GM_Menu.get("showOrHideSidebar")) {
  632. log.info("显示侧边栏");
  633. GM_addStyle(`
  634. #rightAsideConcision{
  635. display: none !important;
  636. }
  637. `);
  638. } else {
  639. log.info("隐藏侧边栏");
  640. GM_addStyle(`
  641. #rightAsideConcision{
  642. display: block !important;
  643. }
  644. `);
  645. }
  646. },
  647. /**
  648. * 去除CSDN拦截其它网址的url并自动跳转
  649. */
  650. jumpRedirect() {
  651. /* https://link.csdn.net/?target=https%3A%2F%2Fjaist.dl.sourceforge.net%2Fproject%2Fportecle%2Fv1.11%2Fportecle-1.11.zip */
  652. if (
  653. window.location.hostname === "link.csdn.net" &&
  654. window.location.search.startsWith("?target")
  655. ) {
  656. /* 禁止CSDN拦截跳转 */
  657. window.stop();
  658. let search = window.location.search.replace(/^\?target=/gi, "");
  659. search = decodeURIComponent(search);
  660. let newURL = search;
  661. log.success(`跳转链接 ${newURL}`);
  662. window.location.href = newURL;
  663. }
  664. },
  665. run() {
  666. this.addCSS();
  667. this.articleCenter();
  668. this.shieldLoginDialog();
  669. this.autoExpandContent();
  670. this.csdnShieldfloatingButton();
  671. this.csdnShieldBottomRecommendArticle();
  672. this.csdnShieldBottomFloatingToolbar();
  673. this.showOrHideDirectory();
  674. this.showOrHideSidebar();
  675. let that = this;
  676. jQuery(document).ready(function () {
  677. that.removeClipboardHijacking();
  678. that.unBlockCopy();
  679. that.identityCSDNDownload();
  680. that.clickPreCodeAutomatically();
  681. that.restoreComments();
  682. that.addGotoRecommandButton();
  683. });
  684. },
  685. },
  686. Mobile: {
  687. addCSS() {
  688. GM_addStyle(`
  689. #mainBox{
  690. width: auto;
  691. }
  692. .user-desc.user-desc-fix{
  693. height: auto !important;
  694. overflow: auto !important;
  695. }
  696. #operate,.feed-Sign-span,
  697. .view_comment_box,
  698. .weixin-shadowbox.wap-shadowbox,
  699. .feed-Sign-span,
  700. .user-desc.user-desc-fix,
  701. .comment_read_more_box,
  702. #content_views pre.set-code-hide .hide-preCode-box,
  703. .passport-login-container,
  704. .hljs-button[data-title='登录后复制'],
  705. .article-show-more,
  706. #treeSkill,
  707. div.btn_open_app_prompt_div,
  708. div.readall_box,
  709. div.aside-header-fixed,
  710. div.feed-Sign-weixin,
  711. div.ios-shadowbox{
  712. display:none !important;
  713. }
  714. .component-box .praise {
  715. background: #ff5722;
  716. border-radius: 5px;
  717. padding: 0px 8px;
  718. height: auto;
  719. }
  720. .component-box .praise,.component-box .share {
  721. color: #fff;
  722. }
  723. .component-box a {
  724. display: inline-block;
  725. font-size:xx-small;
  726. }
  727. .component-box {
  728. display: inline;
  729. margin: 0;
  730. position: relative;
  731. white-space:nowrap;
  732. }
  733. .csdn-edu-title{
  734. background: #4d6de1;
  735. border-radius: 5px;
  736. padding: 0px 8px;
  737. height: auto;
  738. color: #fff !important;
  739. }
  740. #comment{
  741. max-height: none !important;
  742. }
  743. #content_views pre,
  744. #content_views pre code{
  745. webkit-touch-callout: text !important;
  746. -webkit-user-select: text !important;
  747. -khtml-user-select: text !important;
  748. -moz-user-select: text !important;
  749. -ms-user-select: text !important;
  750. user-select: text !important;
  751. }
  752. #content_views pre.set-code-hide,
  753. .article_content{
  754. height: 100% !important;
  755. overflow: auto !important;
  756. }`);
  757. GM_addStyle(`
  758. .GM-csdn-dl{
  759. padding: .24rem .32rem;
  760. width: 100%;
  761. justify-content: space-between;
  762. -webkit-box-pack: justify;
  763. border-bottom: 1px solid #F5F6F7!important;
  764. }
  765. .GM-csdn-title{
  766. font-size: .3rem;
  767. color: #222226;
  768. letter-spacing: 0;
  769. line-height: .44rem;
  770. font-weight: 600;
  771. //max-height: .88rem;
  772. word-break: break-all;
  773. overflow: hidden;
  774. display: -webkit-box;
  775. -webkit-box-orient: vertical;
  776. -webkit-line-clamp: 2
  777. }
  778. .GM-csdn-title a{
  779. word-break: break-all;
  780. color: #222226;
  781. font-weight: 600;
  782. }
  783. .GM-csdn-title em,.GM-csdn-content em{
  784. font-style: normal;
  785. color: #fc5531
  786. }
  787. .GM-csdn-content{
  788. //max-width: 5.58rem;
  789. overflow: hidden;
  790. text-overflow: ellipsis;
  791. display: -webkit-box;
  792. -webkit-line-clamp: 1;
  793. -webkit-box-orient: vertical;
  794. color: #555666;
  795. font-size: .24rem;
  796. line-height: .34rem;
  797. max-height: .34rem;
  798. word-break: break-all;
  799. -webkit-box-flex: 1;
  800. -ms-flex: 1;
  801. flex: 1;
  802. margin-top: .16rem;
  803. }
  804. .GM-csdn-img img{
  805. width: 2.18rem;
  806. height: 1.58rem;
  807. //margin-left: .16rem
  808. }
  809. .GM-csdn-Redirect{
  810. color: #fff;
  811. background-color: #f90707;
  812. font-family: sans-serif;
  813. margin: auto 2px;
  814. border: 1px solid #ccc;
  815. border-radius: 4px;
  816. padding: 0px 3px;
  817. font-size: xx-small;
  818. display: inline;
  819. white-space: nowrap;
  820. }`);
  821. },
  822. /**
  823. * 重构底部推荐
  824. */
  825. refactoringRecommendation() {
  826. log.info("重构底部推荐");
  827. function refactoring() {
  828. /* 反复执行的重构函数 */
  829. jQuery(".container-fluid").each((index, item) => {
  830. item = jQuery(item);
  831. var url = ""; /* 链接 */
  832. var title = ""; /* 标题 */
  833. var content = ""; /* 内容 */
  834. var img = ""; /* 图片 */
  835. var isCSDNDownload = false; /* 判断是否是CSDN资源下载 */
  836. var isCSDNEduDownload = false; /* 判断是否是CSDN-学院资源下载 */
  837. if (item.attr("data-url")) {
  838. /* 存在真正的URL */
  839. url = item.attr("data-url");
  840. title = item.find(".recommend_title div.left").html();
  841. content = item.find(".text").html();
  842. if (item.find(".recommend-img").length) {
  843. /* 如果有图片就加进去 */
  844. item.find(".recommend-img").each((_index_, _item_) => {
  845. img += jQuery(_item_).html();
  846. });
  847. }
  848. } else {
  849. log.info("节点上无data-url");
  850. url = item.find("a[data-type]").attr("href");
  851. title = item.find(".recommend_title div.left").html();
  852. content = item.find(".text").html();
  853. }
  854. if (GM_Menu.get("showDirect")) {
  855. /* 开启就添加 */
  856. title += `<div class="GM-csdn-Redirect">Redirect</div>`;
  857. }
  858. var _URL_ = new URL(url);
  859. if (
  860. _URL_.host === "download.csdn.net" ||
  861. (_URL_.host === "www.iteye.com" &&
  862. _URL_.pathname.match(/^\/resource/gi))
  863. ) {
  864. /* 该链接为csdn资源下载 */
  865. log.info("该链接为csdn资源下载");
  866. isCSDNDownload = true;
  867. title += `<div class="component-box"><a class="praise" href="javascript:;">CSDN下载</a></div>`;
  868. } else if (_URL_.origin.match(/edu.csdn.net/gi)) {
  869. /* 该链接为csdn学院下载 */
  870. isCSDNEduDownload = true;
  871. log.info("该链接为csdn学院下载");
  872. title += `<div class="component-box"><a class="csdn-edu-title" href="javascript:;">CSDN学院</a></div>`;
  873. }
  874. item.attr("class", "GM-csdn-dl");
  875. item.attr("data-url", url);
  876. item.html(
  877. `<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>`
  878. );
  879. if (
  880. (isCSDNDownload || isCSDNEduDownload) &&
  881. GM_Menu.get("removeCSDNDownloadMobile")
  882. ) {
  883. item.remove();
  884. }
  885. /* jQuery("#recommend")
  886. .find(".recommend_list")
  887. .before(jQuery("#first_recommend_list").find("dl").parent().html()); */
  888. });
  889. }
  890. utils.waitNode("#recommend").then((nodeList) => {
  891. utils.mutationObserver(nodeList[0], {
  892. callback: () => {
  893. setTimeout(() => {
  894. refactoring();
  895. }, 300);
  896. },
  897. config: { childList: true, subtree: true, attributes: true },
  898. });
  899. });
  900.  
  901. this.recommendClickEvent();
  902. },
  903. /**
  904. * 设置底部推荐点击跳转事件
  905. */
  906. recommendClickEvent() {
  907. log.info("设置底部推荐点击跳转事件");
  908. jQuery(document).on("click", ".GM-csdn-dl", function () {
  909. let url = jQuery(this).attr("data-url");
  910. if (GM_Menu.get("openNewTab")) {
  911. window.open(url, "_blank");
  912. } else {
  913. window.location.href = url;
  914. }
  915. });
  916. },
  917. /**
  918. * 去除广告
  919. */
  920. removeAds() {
  921. log.info("去除广告");
  922. /* 登录窗口 */
  923. waitForElementToRemove(".passport-login-container");
  924. /* 打开APP */
  925. waitForElementToRemove(
  926. ".btn_open_app_prompt_box.detail-open-removed"
  927. );
  928. /* 广告 */
  929. waitForElementToRemove(".add-firstAd");
  930. /* 打开CSDN APP 小程序看全文 */
  931. waitForElementToRemove("div.feed-Sign-weixin");
  932. /* ios版本提示 */
  933. waitForElementToRemove("div.ios-shadowbox");
  934. },
  935. run() {
  936. this.addCSS();
  937. let that = this;
  938. jQuery(document).ready(function () {
  939. that.removeAds();
  940. that.refactoringRecommendation();
  941. });
  942. },
  943. },
  944. /**
  945. * 函数入口
  946. */
  947. run() {
  948. Optimization.csdn.PC.jumpRedirect();
  949. if (utils.isPhone()) {
  950. log.success("移动端模式");
  951. this.Mobile.run();
  952. } else {
  953. log.success("桌面端模式");
  954. this.PC.run();
  955. }
  956. },
  957. },
  958. huaWeiCSDN: {
  959. /**
  960. * 判断是否是CSDN
  961. */
  962. locationMatch() {
  963. return Boolean(/huaweicloud.csdn.net/i.test(window.location.origin));
  964. },
  965. PC: {
  966. addCSS() {
  967. GM_addStyle(`
  968. /* 底部免费抽xxx奖品广告 */
  969. div.siderbar-box,
  970. /* 华为开发者联盟加入社区 */
  971. div.user-desc.user-desc-fix,
  972. /* 点击阅读全文 */
  973. div.article-show-more{
  974. display: none !important;
  975. }
  976.  
  977. /* 自动展开全文 */
  978. .main-content .user-article{
  979. height: auto !important;
  980. overflow: auto !important;
  981. }
  982. `);
  983. },
  984. run() {
  985. this.addCSS();
  986. this.huaweiCSDNShieldCloudDeveloperTaskChallengeEvent();
  987. this.huaweiCSDNShieldLeftFloatingButton();
  988. this.huaweiCSDNBlockRightColumn();
  989. this.huaweiCSDNBlockRecommendedContentAtTheBottom();
  990. this.huaweiCSDNShieldTheBottomForMoreRecommendations();
  991. },
  992. /**
  993. * 屏蔽云开发者任务挑战活动
  994. */
  995. huaweiCSDNShieldCloudDeveloperTaskChallengeEvent() {
  996. let GM_cookie = new utils.GM_Cookie();
  997. GM_cookie.set({ name: "show_join_group_index", value: 1 });
  998. log.success("屏蔽云开发者任务挑战活动");
  999. },
  1000. /**
  1001. * 屏蔽左侧悬浮按钮
  1002. */
  1003. huaweiCSDNShieldLeftFloatingButton() {
  1004. if (!GM_Menu.get("huaweiCSDNShieldLeftFloatingButton")) {
  1005. return;
  1006. }
  1007. log.success(
  1008. "屏蔽左侧悬浮按钮,包括当前阅读量、点赞按钮、评论按钮、分享按钮"
  1009. );
  1010. GM_addStyle(`
  1011. div.toolbar-wrapper.article-interact-bar{
  1012. display: none !important;
  1013. }`);
  1014. },
  1015. /**
  1016. * 屏蔽右侧栏
  1017. */
  1018. huaweiCSDNBlockRightColumn() {
  1019. if (!GM_Menu.get("huaweiCSDNBlockRightColumn")) {
  1020. return;
  1021. }
  1022. log.success("屏蔽右侧栏,包括相关产品-活动日历-运营活动-热门标签");
  1023. GM_addStyle(`
  1024. div.page-home-right.dp-aside-right{
  1025. display: none !important;
  1026. }
  1027. `);
  1028. },
  1029. /**
  1030. * 屏蔽底部推荐内容
  1031. */
  1032. huaweiCSDNBlockRecommendedContentAtTheBottom() {
  1033. if (!GM_Menu.get("huaweiCSDNBlockRecommendedContentAtTheBottom")) {
  1034. return;
  1035. }
  1036. log.success("屏蔽底部推荐内容");
  1037. GM_addStyle(`
  1038. div.recommend-card-box{
  1039. display: none !important;
  1040. }`);
  1041. },
  1042. /**
  1043. * 屏蔽底部更多推荐
  1044. */
  1045. huaweiCSDNShieldTheBottomForMoreRecommendations() {
  1046. if (!GM_Menu.get("huaweiCSDNShieldTheBottomForMoreRecommendations")) {
  1047. return;
  1048. }
  1049. log.success("屏蔽底部更多推荐");
  1050. GM_addStyle(`
  1051. div.more-article{
  1052. display: none !important;
  1053. }`);
  1054. },
  1055. },
  1056. },
  1057. };
  1058. if (Optimization.huaWeiCSDN.locationMatch()) {
  1059. GM_Menu = new utils.GM_Menu(
  1060. {
  1061. huaweiCSDNShieldCloudDeveloperTaskChallengeEvent: {
  1062. text: "电脑-屏蔽云开发者任务挑战活动",
  1063. enable: true,
  1064. showText: (_text_, _enable_) => {
  1065. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1066. },
  1067. callback: () => {
  1068. window.location.reload();
  1069. },
  1070. },
  1071. huaweiCSDNShieldLeftFloatingButton: {
  1072. text: "电脑-屏蔽左侧悬浮按钮",
  1073. enable: false,
  1074. title: "包括当前阅读量、点赞按钮、评论按钮、分享按钮",
  1075. showText: (_text_, _enable_) => {
  1076. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1077. },
  1078. callback: () => {
  1079. window.location.reload();
  1080. },
  1081. },
  1082. huaweiCSDNBlockRightColumn: {
  1083. text: "电脑-屏蔽右侧",
  1084. enable: false,
  1085. title: "包括相关产品-活动日历-运营活动-热门标签",
  1086. showText: (_text_, _enable_) => {
  1087. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1088. },
  1089. callback: () => {
  1090. window.location.reload();
  1091. },
  1092. },
  1093. huaweiCSDNBlockRecommendedContentAtTheBottom: {
  1094. text: "电脑-屏蔽底部推荐内容",
  1095. enable: false,
  1096. showText: (_text_, _enable_) => {
  1097. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1098. },
  1099. callback: () => {
  1100. window.location.reload();
  1101. },
  1102. },
  1103. huaweiCSDNShieldTheBottomForMoreRecommendations: {
  1104. text: "电脑-屏蔽底部更多推荐",
  1105. enable: false,
  1106. showText: (_text_, _enable_) => {
  1107. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1108. },
  1109. callback: () => {
  1110. window.location.reload();
  1111. },
  1112. },
  1113. },
  1114. false,
  1115. GM_getValue,
  1116. GM_setValue,
  1117. GM_registerMenuCommand,
  1118. GM_unregisterMenuCommand
  1119. );
  1120. Optimization.huaWeiCSDN.PC.run();
  1121. } else if (Optimization.csdn.locationMatch()) {
  1122. if (utils.isPhone()) {
  1123. GM_Menu = new utils.GM_Menu(
  1124. {
  1125. showDirect: {
  1126. text: "手机-标识处理过的底部推荐文章",
  1127. enable: true,
  1128. showText: (_text_, _enable_) => {
  1129. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1130. },
  1131. callback: () => {
  1132. window.location.reload();
  1133. },
  1134. },
  1135. openNewTab: {
  1136. text: "手机-底部推荐文章新标签页打开",
  1137. enable: true,
  1138. showText: (_text_, _enable_) => {
  1139. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1140. },
  1141. callback: () => {
  1142. window.location.reload();
  1143. },
  1144. },
  1145. removeCSDNDownloadMobile: {
  1146. text: "手机-移除文章底部的CSDN下载",
  1147. enable: false,
  1148. showText: (_text_, _enable_) => {
  1149. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1150. },
  1151. callback: () => {
  1152. window.location.reload();
  1153. },
  1154. },
  1155. },
  1156. false,
  1157. GM_getValue,
  1158. GM_setValue,
  1159. GM_registerMenuCommand,
  1160. GM_unregisterMenuCommand
  1161. );
  1162. } else {
  1163. GM_Menu = new utils.GM_Menu(
  1164. {
  1165. removeCSDNDownloadPC: {
  1166. text: "电脑-屏蔽底部推荐文章的CSDN下载",
  1167. enable: false,
  1168. showText: (_text_, _enable_) => {
  1169. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1170. },
  1171. callback: () => {
  1172. window.location.reload();
  1173. },
  1174. },
  1175. shieldLoginDialog: {
  1176. text: "电脑-屏蔽登录弹窗",
  1177. enable: true,
  1178. showText: (_text_, _enable_) => {
  1179. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1180. },
  1181. callback: (_key_, _enable_) => {
  1182. if (!_enable_) {
  1183. window.GM_CSS_GM_shieldLoginDialog?.forEach((item) => {
  1184. item.remove();
  1185. });
  1186. } else {
  1187. if (typeof window.GM_CSS_GM_shieldLoginDialog !== "undefined") {
  1188. window.GM_CSS_GM_shieldLoginDialog = [
  1189. ...window.GM_CSS_GM_shieldLoginDialog,
  1190. GM_addStyle(
  1191. `.passport-login-container{display: none !important;}`
  1192. ),
  1193. ];
  1194. } else {
  1195. window.GM_CSS_GM_shieldLoginDialog = [
  1196. GM_addStyle(
  1197. `.passport-login-container{display: none !important;}`
  1198. ),
  1199. ];
  1200. }
  1201. }
  1202. },
  1203. },
  1204. csdnShieldfloatingButton: {
  1205. text: "电脑-屏蔽右侧悬浮按钮",
  1206. enable: false,
  1207. showText: (_text_, _enable_) => {
  1208. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1209. },
  1210. callback: () => {
  1211. window.location.reload();
  1212. },
  1213. },
  1214. csdnShieldBottomRecommendArticle: {
  1215. text: "电脑-屏蔽底部推荐文章",
  1216. enable: false,
  1217. showText: (_text_, _enable_) => {
  1218. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1219. },
  1220. callback: () => {
  1221. window.location.reload();
  1222. },
  1223. },
  1224. csdnShieldBottomFloatingToolbar: {
  1225. text: "电脑-屏蔽底部悬浮工具栏",
  1226. enable: false,
  1227. showText: (_text_, _enable_) => {
  1228. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1229. },
  1230. callback: () => {
  1231. window.location.reload();
  1232. },
  1233. },
  1234. articleCenter: {
  1235. text: "电脑-全文居中",
  1236. enable: true,
  1237. showText: (_text_, _enable_) => {
  1238. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1239. },
  1240. callback: () => {
  1241. window.location.reload();
  1242. },
  1243. },
  1244. autoExpandContent: {
  1245. text: "电脑-自动展开内容块",
  1246. enable: false,
  1247. showText: (_text_, _enable_) => {
  1248. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1249. },
  1250. callback: () => {
  1251. window.location.reload();
  1252. },
  1253. },
  1254. showOrHideDirectory: {
  1255. text: "电脑-显示目录",
  1256. enable: false,
  1257. showText: (_text_, _enable_) => {
  1258. return _enable_ ? `⚙ 电脑-隐藏目录` : `⚙ ${_text_}`;
  1259. },
  1260. callback: (_key_, _enable_) => {
  1261. window.location.reload();
  1262. },
  1263. },
  1264. showOrHideSidebar: {
  1265. text: "电脑-显示侧边栏",
  1266. enable: false,
  1267. showText: (_text_, _enable_) => {
  1268. return _enable_ ? `⚙ 电脑-隐藏侧边栏` : `⚙ ${_text_}`;
  1269. },
  1270. callback: (_key_, _enable_) => {
  1271. window.location.reload();
  1272. },
  1273. },
  1274. },
  1275. false,
  1276. GM_getValue,
  1277. GM_setValue,
  1278. GM_registerMenuCommand,
  1279. GM_unregisterMenuCommand
  1280. );
  1281. }
  1282. GM_Menu.add({
  1283. gotoCSDNCKnow: {
  1284. text: "⚙ 前往C知道",
  1285. callback() {
  1286. window.open("https://so.csdn.net/so/ai?", "_blank");
  1287. },
  1288. },
  1289. });
  1290. Optimization.csdn.run();
  1291. } else if (Optimization.jianshu.locationMatch()) {
  1292. if (utils.isPhone()) {
  1293. GM_Menu = new utils.GM_Menu(
  1294. {
  1295. JianShuremoveFooterRecommendRead: {
  1296. text: "手机-移除底部推荐阅读",
  1297. enable: false,
  1298. showText: (_text_, _enable_) => {
  1299. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1300. },
  1301. callback: () => {
  1302. window.location.reload();
  1303. },
  1304. },
  1305. },
  1306. false,
  1307. GM_getValue,
  1308. GM_setValue,
  1309. GM_registerMenuCommand,
  1310. GM_unregisterMenuCommand
  1311. );
  1312. } else {
  1313. GM_Menu = new utils.GM_Menu(
  1314. {
  1315. JianShuArticleCenter: {
  1316. text: "电脑-全文居中",
  1317. enable: true,
  1318. showText: (_text_, _enable_) => {
  1319. return (_enable_ ? "✅" : "❌") + " " + _text_;
  1320. },
  1321. callback: () => {
  1322. window.location.reload();
  1323. },
  1324. },
  1325. },
  1326. false,
  1327. GM_getValue,
  1328. GM_setValue,
  1329. GM_registerMenuCommand,
  1330. GM_unregisterMenuCommand
  1331. );
  1332. }
  1333.  
  1334. Optimization.jianshu.run();
  1335. }
  1336. })();