csdn_optimizer

make csdn better

安装此脚本?
作者推荐脚本

您可能也喜欢sogou_optimizer

安装此脚本
  1. // ==UserScript==
  2. // @name csdn_optimizer
  3. // @namespace https://github.com/Kyouichirou
  4. // @version 1.4.1
  5. // @description make csdn better
  6. // @author HLA
  7. // @include /https:\/\/(\w+\.)?\w+\.csdn\.net.*/
  8. // @grant unsafeWindow
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @grant GM_addStyle
  12. // @grant GM_registerMenuCommand
  13. // @grant GM_unregisterMenuCommand
  14. // @grant GM_setClipboard
  15. // @grant GM_notification
  16. // @grant GM_openInTab
  17. // @run-at document-start
  18. // @license MIT
  19. // @compatiable chrome; just test on chrome 80+
  20. // @noframes
  21. // @icon https://blog.csdn.net/favicon.ico
  22. // ==/UserScript==
  23.  
  24. (() => {
  25. "use strict";
  26. const Notification = (
  27. content = "",
  28. title = "",
  29. duration = 2500,
  30. cfunc,
  31. ofunc
  32. ) => {
  33. GM_notification({
  34. text: content,
  35. title: title,
  36. timeout: duration,
  37. onclick: cfunc,
  38. ondone: ofunc,
  39. });
  40. };
  41. const escapeHTML_Blank = (html) => html.replace(/\s/g, " ");
  42. const CSDN = {
  43. input: {
  44. get article() {
  45. const bgp = `data:image/webp;base64,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`;
  46. return `
  47. div#article_content{
  48. height: auto !important;
  49. }
  50. .article-header-box {background-color: transparent !important;}
  51. .blog-content-box {background-image: url(${bgp}) !important;}
  52. .comment-box .comment-list-container .comment-list-box {
  53. overflow: auto !important;
  54. max-height: none !important;
  55. }
  56. #content_views pre code,
  57. #content_views pre{user-select: unset !important;}
  58. #content_views span {background-color: transparent !important;}
  59. .toolbar-advert,
  60. div.hide-article-box,
  61. #csdn-redpack,
  62. div#recommendAdBox,
  63. .hljs-button.signin,
  64. #blogColumnPayAdvert,
  65. .opt-box.text-center,
  66. img.comment-sofa-flag,
  67. .recommend-item-box.recommend-download-box.clearfix,
  68. .recommend-item-box.type_download.clearfix,
  69. .recommend-item-box.type_course.clearfix,
  70. .recommend-item-box.recommend-other-item-box.type_download,
  71. .recommend-item-box.recommend-other-item-box.type_discussion_topic,
  72. .recommend-item-box.recommend-other-item-box.type_course,
  73. .recommend-item-box.type_download.clearfix,
  74. .recommend-item-box.baiduSearch,`;
  75. },
  76. placeholder(mode) {
  77. GM_addStyle(`
  78. input::-webkit-input-placeholder {
  79. font-size: 0px;
  80. text-align: right;
  81. }
  82. ${mode ? this.article : ""}
  83. .login-box,
  84. .login-mark,
  85. .passport-login-container,
  86. .csdn-side-toolbar,
  87. .toolbar-search-hot {
  88. display: none !important;
  89. }
  90. `);
  91. },
  92. dropmenu() {
  93. let input = document.getElementsByClassName(
  94. "toolbar-search onlySearch"
  95. );
  96. if (input.length > 0) {
  97. const m = new MutationObserver((records) => {
  98. for (const e of records) {
  99. if (e.addedNodes.length > 0) {
  100. for (const a of e.addedNodes) {
  101. if (
  102. a.className ===
  103. "toolbar-search-drop-menu "
  104. ) {
  105. a.remove();
  106. break;
  107. }
  108. }
  109. break;
  110. }
  111. }
  112. });
  113. m.observe(input[0], { childList: true });
  114. unsafeWindow.addEventListener(
  115. "visibilitychange",
  116. (e) => {
  117. e.preventDefault();
  118. e.stopPropagation();
  119. },
  120. true
  121. );
  122. let boxs = input[0].getElementsByTagName("input");
  123. let buttons = input[0].getElementsByTagName("button");
  124. if (boxs.length > 0 && buttons.length > 0) {
  125. const box = boxs[0];
  126. buttons[0].addEventListener(
  127. "click",
  128. (e) => {
  129. if (!box.value) {
  130. e.preventDefault();
  131. e.stopImmediatePropagation();
  132. }
  133. },
  134. true
  135. );
  136. box.addEventListener(
  137. "keydown",
  138. (e) => {
  139. if (!box.value) {
  140. e.preventDefault();
  141. e.stopImmediatePropagation();
  142. }
  143. },
  144. true
  145. );
  146. buttons = null;
  147. boxs = null;
  148. }
  149. input = null;
  150. }
  151. },
  152. },
  153. antiRedirect() {
  154. const links = Object.getOwnPropertyDescriptors(
  155. HTMLAnchorElement.prototype
  156. ).href;
  157. const trackids = ["?utm_", "utm_source", "?ops_request"];
  158. Object.defineProperty(HTMLAnchorElement.prototype, "href", {
  159. ...links,
  160. get() {
  161. const href = decodeURIComponent(links.get.call(this));
  162. for (const id of trackids) {
  163. const tmp = href.split(id);
  164. if (tmp.length > 1) {
  165. this.href = tmp[1];
  166. return tmp[1];
  167. }
  168. }
  169. return href;
  170. },
  171. });
  172. },
  173. antiLeech() {
  174. // if those pictures are not from csdn
  175. const content = document.getElementById("content_views");
  176. if (!content) return;
  177. const imgs = content.getElementsByTagName("img");
  178. const hosts = ["csdnimg.cn", "csdn.net"];
  179. for (const img of imgs) {
  180. const src = img.src;
  181. if (src && !hosts.some((e) => src.includes(e))) {
  182. img.setAttribute("referrerPolicy", "no-referrer");
  183. img.src = img.src + "?";
  184. }
  185. }
  186. },
  187. comment: {
  188. // covert the link of text to href
  189. textTolink(text) {
  190. const reg =
  191. /((http|https):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g;
  192. return reg.test(text)
  193. ? text.replace(
  194. reg,
  195. "<a href='$1' target='_blank' style='color: #00a0e9;width: 360px;display: inline;'>$1</a>"
  196. )
  197. : null;
  198. },
  199. text_convertor() {
  200. const snc = document.getElementsByClassName("new-comment");
  201. for (const e of snc) {
  202. if (!e.innerHTML.includes("href")) {
  203. const s = this.textTolink(e.textContent);
  204. s && (e.innerHTML = s);
  205. }
  206. }
  207. },
  208. },
  209. menus: {
  210. s_id: null,
  211. r_id: null,
  212. n_id: null,
  213. reader_style: null,
  214. simple_style: null,
  215. create_simple_style(m = true) {
  216. if (this.simple_style) return;
  217. this.reset_reader();
  218. let i = 7;
  219. let t = "";
  220. const none_display = `
  221. div#asideCustom,
  222. div#asideNewComments,
  223. div#asideNewNps{display: none !important;}`;
  224. const sider_bar = `
  225. aside.blog_container_aside,
  226. div#rightAside{opacity: 0.1;}
  227. aside.blog_container_aside:hover{
  228. opacity: 1;
  229. transition: opacity 3s;
  230. }
  231. div#rightAside:hover{
  232. opacity: 1;
  233. transition: opacity 3s;
  234. }`;
  235. for (i; i > 1; i--)
  236. t += `.csdn-toolbar-fl.toolbar-menus > li:nth-of-type(${i}),`;
  237. this.simple_style = GM_addStyle(
  238. t +
  239. ".toolbar-btn.toolbar-btn-vip.csdn-toolbar-fl {visibility: hidden !important;}" +
  240. none_display +
  241. (m ? sider_bar : "")
  242. );
  243. },
  244. create_reader_style() {
  245. if (this.reader_style) return;
  246. this.reset_simple();
  247. const sty = `
  248. #csdn-toolbar,
  249. aside.blog_container_aside,
  250. .aside-box.kind_person.d-flex.flex-column,
  251. .comment-box,
  252. .first-recommend-box,
  253. .second-recommend-box,
  254. .recommend-box.insert-baidu-box,
  255. .recommend-tit-mod {display: none ! important;}
  256. `;
  257. this.reader_style = GM_addStyle(sty);
  258. },
  259. simple_action() {
  260. if (this.s_id) {
  261. GM_unregisterMenuCommand(this.s_id);
  262. this.s_id = null;
  263. }
  264. GM_setValue("mode", "s");
  265. this.create_simple_style();
  266. this.reader();
  267. this.normal();
  268. },
  269. reader_action() {
  270. if (this.r_id) {
  271. GM_unregisterMenuCommand(this.r_id);
  272. this.r_id = null;
  273. }
  274. GM_setValue("mode", "r");
  275. this.create_reader_style();
  276. this.simple();
  277. this.normal();
  278. },
  279. reset_simple() {
  280. if (this.simple_style) {
  281. this.simple_style.remove();
  282. this.simple_style = null;
  283. }
  284. },
  285. reset_reader() {
  286. if (this.reader_style) {
  287. this.reader_style.remove();
  288. this.reader_style = null;
  289. }
  290. },
  291. normal_action() {
  292. if (this.n_id) {
  293. GM_unregisterMenuCommand(this.n_id);
  294. this.n_id = null;
  295. }
  296. GM_setValue("mode", "");
  297. this.reset_reader();
  298. this.reset_simple();
  299. this.simple();
  300. this.reader();
  301. },
  302. simple() {
  303. !this.s_id &&
  304. (this.s_id = GM_registerMenuCommand(
  305. "Simple Mode",
  306. this.simple_action.bind(this)
  307. ));
  308. },
  309. reader() {
  310. !this.r_id &&
  311. (this.r_id = GM_registerMenuCommand(
  312. "Reader Mode",
  313. this.reader_action.bind(this)
  314. ));
  315. },
  316. normal() {
  317. !this.n_id &&
  318. (this.n_id = GM_registerMenuCommand(
  319. "Normal Mode",
  320. this.normal_action.bind(this)
  321. ));
  322. },
  323. create(m) {
  324. const mode = GM_getValue("mode");
  325. if (!m && mode) {
  326. this.create_simple_style(m);
  327. return;
  328. }
  329. if (mode) {
  330. if (mode === "r") {
  331. this.simple();
  332. this.create_reader_style();
  333. } else {
  334. this.reader();
  335. this.create_simple_style();
  336. }
  337. this.normal();
  338. } else {
  339. this.simple();
  340. this.reader();
  341. }
  342. },
  343. },
  344. code: {
  345. // ctrl + right mouse => copy the code directly
  346. clipboard(text) {
  347. if (!text) {
  348. Notification("failed to get the content of code");
  349. return;
  350. }
  351. try {
  352. try {
  353. navigator.clipboard.writeText(text);
  354. } catch (err) {
  355. console.log(err);
  356. GM_setClipboard(text, "text");
  357. }
  358. Notification("the code has been copied to clipboard");
  359. } catch (err) {
  360. console.log(err);
  361. Notification("some error on copy the code");
  362. }
  363. },
  364. get_code(node) {
  365. const num = node.getElementsByClassName("pre-numbering");
  366. if (num.length > 0) {
  367. let text = "";
  368. for (const e of node.childNodes) {
  369. if (e.className === "pre-numbering") continue;
  370. text += e.innerText;
  371. }
  372. return text;
  373. }
  374. return node.innerText;
  375. },
  376. event() {
  377. const pres = document.getElementsByTagName("pre");
  378. for (const pre of pres)
  379. pre.title = "Ctrl + Right mouse button to copy this code";
  380. pres.length > 0 &&
  381. document.addEventListener("contextmenu", (e) => {
  382. if (e.ctrlKey) {
  383. for (const p of e.path) {
  384. if (p.localName === "pre") {
  385. e.preventDefault();
  386. e.stopImmediatePropagation();
  387. const text = this.get_code(p);
  388. this.clipboard(text);
  389. break;
  390. }
  391. }
  392. }
  393. });
  394. },
  395. },
  396. anti_prevent_copy() {
  397. // disable initialization of csdn copy event(this feature will add copyrigth content to the data of copy)
  398. unsafeWindow.csdn = {};
  399. Object.defineProperty(unsafeWindow.csdn, "copyright", {
  400. value: null,
  401. });
  402. },
  403. anti_click_redirect() {
  404. // anti track what you click
  405. document.addEventListener(
  406. "click",
  407. (e) => {
  408. let ic = 0;
  409. for (const a of e.path) {
  410. if (a.localName === "a") {
  411. e.preventDefault();
  412. e.stopImmediatePropagation();
  413. const href = a.href;
  414. if (href) {
  415. const trackids = [
  416. "?utm_",
  417. "utm_source",
  418. "?ops_request",
  419. ];
  420. const index = trackids.findIndex((e) =>
  421. href.includes(e)
  422. );
  423. GM_openInTab(
  424. index < 0 ? href : href.slice(0, index),
  425. {
  426. insert: true,
  427. active: true,
  428. }
  429. );
  430. }
  431. break;
  432. } else if (ic > 2) break;
  433. ic++;
  434. }
  435. },
  436. true
  437. );
  438. },
  439. clear_bottom() {
  440. // clear the bottom zone that displays some relative articles
  441. const b = document.getElementsByClassName(
  442. "recommend-box insert-baidu-box"
  443. );
  444. const rubbish = [
  445. "\u534e\u4e3a",
  446. "CSDN\u8d44\u8baf",
  447. "CSDNnew",
  448. "\u5927\u5b66\u751f",
  449. "\u5e94\u5c4a\u751f",
  450. "\u6bd5\u4e1a\u751f",
  451. "\u79c1\u6d3b",
  452. "\u6708\u85aa",
  453. "\u5e74\u85aa",
  454. "\u8df3\u69fd",
  455. "\u5de5\u8d44",
  456. "\u4e8b\u4e1a",
  457. "\u5de5\u7a0b\u5e08",
  458. "\u85aa\u8d44",
  459. "\u517c\u804c",
  460. "\u7c89\u4e1d",
  461. "\u627e\u5de5\u4f5c",
  462. "\u7b80\u5386",
  463. "\u9762\u8bd5",
  464. "\u540c\u4e8b",
  465. "\u4f17\u5305",
  466. "HR",
  467. "\u85aa\u6c34",
  468. "\u5916\u5305",
  469. "\u79bb\u804c",
  470. "\u8fbe\u5185",
  471. ];
  472. if (b.length > 0) {
  473. const items = b[0].getElementsByClassName(
  474. "recommend-item-box type_blog clearfix"
  475. );
  476. let i = items.length;
  477. const trackids = ["?utm_", "utm_source", "?ops_request"];
  478. for (i; i--; ) {
  479. const text = items[i].innerText;
  480. if (text && rubbish.some((e) => text.includes(e))) {
  481. items[i].remove();
  482. continue;
  483. }
  484. const links = items[i].getElementsByTagName("a");
  485. let fr = false;
  486. for (const a of links) {
  487. let href = a.href;
  488. if (href && href.startsWith("http")) {
  489. const index = trackids.findIndex((e) =>
  490. href.includes(e)
  491. );
  492. index > 0 && (href = href.slice(0, index));
  493. if (href.includes("/article/") || !this.blackLists)
  494. continue;
  495. const i = href.lastIndexOf("/");
  496. if (i > 0) {
  497. const id = href.slice(i + 1);
  498. if (this.blackLists.includes(id)) {
  499. fr = true;
  500. break;
  501. }
  502. }
  503. index > 0 && (a.href = href);
  504. }
  505. }
  506. fr && items[i].remove();
  507. }
  508. }
  509. this.blackLists = null;
  510. },
  511. user_manage: {
  512. // block some rubbish author
  513. create_button(mode) {
  514. const postion = document.getElementsByClassName(
  515. "user-profile-operate-btn"
  516. );
  517. const [color, name, title] = mode
  518. ? ["black", "unBlock", "unblock this author"]
  519. : ["red", "Block", "block this author"];
  520. if (postion.length === 0) {
  521. const button = `
  522. <button
  523. style="
  524. margin-left: 158px;
  525. width: 65px;
  526. opacity: 0.95;
  527. font-size: 14px;
  528. line-height: 20px;
  529. text-align: center;
  530. cursor: pointer;
  531. color: ${color};
  532. background: none;
  533. border: 1px solid;
  534. border-radius: 3px;
  535. "
  536. title=${escapeHTML_Blank(title)}
  537. >
  538. ${name}
  539. </button>`;
  540. const user = document.getElementsByClassName(
  541. "user-info d-flex flex-column profile-intro-name-box"
  542. );
  543. if (user.length === 0)
  544. console.log("failed to get the postion of button");
  545. else {
  546. user[0].insertAdjacentHTML("beforeend", button);
  547. setTimeout(
  548. () =>
  549. (user[0].lastElementChild.onclick = (e) =>
  550. this.click_event(e.target)),
  551. 250
  552. );
  553. }
  554. } else {
  555. const button = `
  556. <button class="block" style="
  557. width: 92px;
  558. height: 32px;
  559. color: ${color};
  560. font-size: 15px;
  561. cursor: pointer;
  562. border-radius: 20px;
  563. opacity: 0.95;
  564. border: 1px solid #999aaa;
  565. " title=${escapeHTML_Blank(title)}>${name}</button>`;
  566. postion[0].insertAdjacentHTML("afterbegin", button);
  567. setTimeout(
  568. () =>
  569. (postion[0].firstElementChild.onclick = (e) =>
  570. this.click_event(e.target)),
  571. 350
  572. );
  573. }
  574. },
  575. click_event(target) {
  576. debugger;
  577. let blackLists = GM_getValue("block");
  578. if (target.innerText === "Block") {
  579. if (blackLists) {
  580. if (!blackLists.includes(this.id)) {
  581. blackLists.push(this.id);
  582. GM_setValue("block", blackLists);
  583. }
  584. } else {
  585. blackLists = [];
  586. blackLists.push(this.id);
  587. GM_setValue("block", blackLists);
  588. }
  589. target.innerText = "unBlock";
  590. target.title = "unblock this author";
  591. target.style.color = "black";
  592. } else {
  593. if (blackLists) {
  594. const index = blackLists.indexOf(this.id);
  595. if (index > -1) {
  596. blackLists.splice(index, 1);
  597. GM_setValue("block", blackLists);
  598. }
  599. }
  600. target.innerText = "Block";
  601. target.title = "block this author";
  602. target.style.color = "red";
  603. }
  604. },
  605. id: null,
  606. main(mode, id) {
  607. this.create_button(mode);
  608. this.id = id;
  609. },
  610. },
  611. blackLists: null,
  612. get_block() {
  613. this.blackLists = GM_getValue("block");
  614. },
  615. start() {
  616. const href = location.href;
  617. const f = href.includes("/article/");
  618. this.antiRedirect();
  619. this.input.placeholder(f);
  620. this.anti_prevent_copy();
  621. //unsafewindow, some page can not capture the event.
  622. window.onload = () => {
  623. if (f) {
  624. this.get_block();
  625. this.antiLeech();
  626. this.code.event();
  627. this.anti_click_redirect();
  628. this.comment.text_convertor();
  629. setTimeout(() => this.clear_bottom(), 330);
  630. } else {
  631. const regs = [
  632. /https:\/\/blog\.csdn\.net\/(\w+)($|\/|\/category\w+\.html|\?type=[a-z]+)/,
  633. /https:\/\/(\w+)\.blog\.csdn\.net(\/|$)/,
  634. ];
  635. let id = null;
  636. for (const reg of regs) {
  637. const ms = href.match(reg);
  638. if (ms && ms.length > 1) {
  639. id = ms[1];
  640. break;
  641. }
  642. }
  643. if (id) {
  644. this.get_block();
  645. const mode =
  646. this.blackLists && this.blackLists.includes(id);
  647. this.user_manage.main(mode, id);
  648. this.blackLists = null;
  649. this.anti_click_redirect();
  650. } else if (href.endsWith(".net/"))
  651. this.anti_click_redirect();
  652. }
  653. this.input.dropmenu();
  654. };
  655. this.menus.create(f);
  656. },
  657. };
  658. CSDN.start();
  659. })();