CSDN助手

CSDN未登录复制、复制代码不带原文链接、禁用登录弹窗、未登录查看所有评论、评论完全展开

  1. // ==UserScript==
  2. // @name CSDN助手
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.41
  5. // @description CSDN未登录复制、复制代码不带原文链接、禁用登录弹窗、未登录查看所有评论、评论完全展开
  6. // @author Gandalf_jiajun
  7. // @include https://blog.csdn.net/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant none
  10. // @note 2022.01.28 更新禁用提示登录弹窗。
  11. // @note 2022.01.29 更新评论区子项显示及自动展开。
  12. // @note 2022.01.30 V0.21 更新评论区表情包显示异常。
  13. // @note 2022.01.31 V0.22 修复评论区样式显示异常问题。
  14. // @note 2022.02.15 V0.31 破解阅读文章必须关注作者功能。
  15. // @note 2022.03.01 v0.40 随机cookie欺骗。伪造登录屏蔽弹窗。
  16. // @note 2022.03.06 v0.41 删除随机cookie欺骗。优化伪造hide_login cookie登录屏蔽弹窗。修复bug。
  17. //觉得本脚本还可以的可以给个好评,觉得有问题的可以留言,谢谢各位!
  18. // ==/UserScript==
  19.  
  20. (function() {
  21. 'use strict';
  22.  
  23. const appendStyle = (tagArr) => {
  24. tagArr.forEach(element => {
  25. element.style.userSelect = 'text';
  26. element.style.webkitUserSelect = 'text';
  27. });
  28. };
  29. const translateParams = (params) => {
  30. let str = '?';
  31. for(let i in params) {
  32. str += i + '=' + params[i] + '&';
  33. }
  34. return str.substring(0, str.length - 1);
  35. };
  36. const request = (method, url, params) => {
  37. return new Promise((resolve, reject) => {
  38. let newUrl = params ? url + translateParams(params) : url;
  39. const xml = new XMLHttpRequest;
  40. xml.open(method, newUrl, true);
  41. xml.send();
  42. xml.onreadystatechange = () => {
  43. if(xml.readyState == 4 && xml.status == 200) {
  44. resolve(JSON.parse(xml.responseText));
  45. }
  46. };
  47. })
  48. };
  49. let tag_a = document.querySelectorAll('#content_views pre');
  50. let tag_b = document.querySelectorAll('#content_views pre code');
  51. let domMask = document.querySelector('.hide-article-box') || null;
  52. // console.log(tag_a, tag_b);
  53. appendStyle(tag_a);
  54. appendStyle(tag_b);
  55. const getCompleteDom = () => {
  56. if (domMask) {
  57. let completeDom = document.querySelectorAll('#article_content')[0];
  58. completeDom.style.height = "inherit";
  59. completeDom.style.overflow = "auto";
  60. domMask.innerHTML = "";
  61. domMask.style.display = "none";
  62. }
  63. };
  64. // 替换表情包
  65. const replaceDoge = (str) => { // [face]emoji:062.png[/face]
  66. return str.replace(/\[face\]([^\]]+):([^\[]+)\[\/face\]/g, `<img src="//g.csdnimg.cn/static/face/$1/$2" alt="表情包"/>`)
  67. };
  68. const replaceComment = (str) => {
  69. let newCom;
  70. newCom = replaceDoge(str);
  71. return newCom;
  72. };
  73. // 生成子项dom
  74. const createSubDom = (arr) => {
  75. let dom = `<li class="replay-box" style="display:block;padding-left: 32px;"><ul class="comment-list" style="margin: 0;padding: 0;margin: 0;border: 0;">`;
  76. arr.forEach((v) => {
  77. let contentDom = `<li style="display: block;margin: 0;" class="comment-line-box comment-line-box-hide" data-commentid="${v.commentId}" data-replyname="qq_23611043">
  78. <div class="comment-list-item" style="
  79. display: -webkit-box;
  80. display: -ms-flexbox;
  81. display: flex;
  82. width: 100%;
  83. ">
  84. <a class="comment-list-href" target="_blank" href="https://blog.csdn.net/${v.userName}" style="
  85. padding-top: 0;
  86. height: 24px;
  87. ">
  88. <img src="${v.avatar}" username="${v.userName}" alt="${v.userName}" class="avatar">
  89. </a>
  90. <div class="right-box " style="
  91. padding-bottom: 14px;
  92. width: 100%;
  93. margin-left: 8px;
  94. ">
  95. <div class="new-info-box clearfix">
  96. <div class="comment-top" style="
  97. display: -webkit-box;
  98. display: -ms-flexbox;
  99. display: flex;
  100. -webkit-box-pack: end;
  101. -ms-flex-pack: end;
  102. justify-content: flex-end;
  103. margin-bottom: 4px;
  104. line-height: 20px;
  105. font-size: 14px;
  106. ">
  107. <div class="user-box" style="
  108. flex: 1;
  109. ">
  110. <a class="name-href" target="_blank" href="https://blog.csdn.net/${v.userName}">
  111. <span class="name mr-8">${v.userName}</span>
  112. </a>
  113. <span class="text">回复</span>
  114. <span class="nick-name"> ${v.parentUserName}</span>
  115. <span class="date" title="${v.postTime}">${v.dateFormat}</span>
  116. </div>
  117. <div class="opt-comment" style="
  118. display: none;
  119. ">
  120. <a class="btn-bt btn-report">
  121. <img class="btn-report-img" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLookMore.png" title="">
  122. <div class="hide-box">
  123. <span data-type="report" class="hide-item hide-report"> 举报</span>
  124. </div>
  125. </a>
  126. <img class="comment_img_replay" src="https://csdnimg.cn/release/blogv2/dist/pc/img/newCommentReplyWhite.png">
  127. <a class="btn-bt btn-reply" data-type="reply" data-flag="true">回复</a>
  128. </div>
  129. <div class="comment-like " data-commentid="${v.commentId}">
  130. <img class="comment-like-img unclickImg" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLikeWhite.png" title="点赞">
  131. <img class="comment-like-img comment-like-img-hover" style="display:none" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLikeHover.png" title="点赞">
  132. <img class="comment-like-img clickedImg" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLikeActive.png" title="取消点赞">
  133. <span></span>
  134. </div>
  135. </div>
  136. <div class="comment-center">
  137. <div class="new-comment">
  138. <div class="new-comment">${v.content ? replaceComment(v.content) : ``}</div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </div>
  144. </li>`;
  145. dom += contentDom;
  146. });
  147. dom += `</li></ul>`;
  148. return dom;
  149. };
  150. // 生成dom
  151. const createDom = (arr) => {
  152. let dom = `<div class="comment-list-box">`; // </div>
  153. arr.forEach((v, i) => {
  154. let commentDom = `<ul class="comment-list" style="
  155. border: 0;
  156. margin: 0;
  157. ">
  158. <li class="comment-line-box " style="margin: 0;" data-commentid="${v.info.commentId}" data-replyname="${v.info.parentUserName}">
  159. <div class="comment-list-item" style="display: flex;width: 100%;">
  160. <a class="comment-list-href" style="display: block;padding-top: 15px;height: 48px;" target="_blank" href="https://blog.csdn.net/${v.info.userName}">
  161. <img src=${v.info.avatar} username=${v.info.userName} alt=${v.info.userName} class="avatar" style="
  162. display: block;
  163. width: 32px;
  164. height: 32px;
  165. border-radius: 50%;
  166. border: 1px solid #e8e8ed;
  167. ">
  168. </a>
  169. <div class="right-box" style="
  170. border-top: 1px solid #e8e8ed;
  171. padding-top: 14px;
  172. padding-bottom: 14px;
  173. width: 100%;
  174. margin-left: 8px;
  175. ">
  176. <div class="new-info-box clearfix">
  177. <div class="comment-top" style="
  178. display: -webkit-box;
  179. display: -ms-flexbox;
  180. display: flex;
  181. -webkit-box-pack: end;
  182. -ms-flex-pack: end;
  183. justify-content: flex-end;
  184. margin-bottom: 4px;
  185. line-height: 20px;
  186. font-size: 14px;
  187. ">
  188. <div class="user-box" style="
  189. -webkit-box-flex: 1;
  190. -ms-flex: 1;
  191. flex: 1;
  192. display: -webkit-box;
  193. display: -ms-flexbox;
  194. display: flex;
  195. -webkit-box-align: center;
  196. -ms-flex-align: center;
  197. align-items: center;
  198. ">
  199. <a class="name-href" target="_blank" href="https://blog.csdn.net/${v.info.userName}">
  200. <span class="name ">${v.info.nickName}</span>
  201. </a>
  202. <span class="date" title="${v.info.postTime}">${v.info.dateFormat}</span>
  203. </div>
  204. <div class="opt-comment" style="
  205. line-height: 20px;
  206. height: 20px;
  207. display: none;
  208. ">
  209. <a class="btn-bt btn-report">
  210. <img class="btn-report-img" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLookMore.png" title="">
  211. <div class="hide-box">
  212. <span data-type="report" class="hide-item hide-report"> 举报</span>
  213. </div>
  214. </a>
  215. <img class="comment_img_replay" src="https://csdnimg.cn/release/blogv2/dist/pc/img/newCommentReplyWhite.png">
  216. <a class="btn-bt btn-reply" data-type="reply" data-flag="true">回复</a>
  217. </div>
  218. <div class="comment-like " data-commentid="${v.info.commentId}">
  219. <img class="comment-like-img unclickImg" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLikeWhite.png" title="点赞">
  220. <img class="comment-like-img comment-like-img-hover" style="display:none" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLikeHover.png" title="点赞">
  221. <img class="comment-like-img clickedImg" src="https://csdnimg.cn/release/blogv2/dist/pc/img/commentLikeActive.png" title="取消点赞">
  222. <span></span>
  223. </div>
  224. </div>
  225. <div class="comment-center">
  226. <div class="new-comment">${v.info.content ? replaceComment(v.info.content): ``}</div>
  227. </div>
  228. </div>
  229. </div>
  230. </div>
  231. </li>
  232. ${v.sub.length>0 ? createSubDom(v.sub) : ``}
  233. </ul>`;
  234. dom += commentDom;
  235. })
  236. dom += `</div>`;
  237. return dom;
  238. };
  239. // 获取评论
  240. const getComment = async () => {
  241. try {
  242. let articalId = window.location.href.split('/article/details/')[1].split('?')[0];
  243. let commentUrl = '/phoenix/web/v1/comment/list/' + articalId;
  244. let params = {
  245. page: 1,
  246. size: 999,
  247. fold: 'unfold',
  248. commentId: ''
  249. };
  250. const res = await request('post', commentUrl, params);
  251. let dom = createDom(res.data.list);
  252. let parentNode = document.getElementsByClassName('comment-list-container')[0];
  253. let parentNode_chrome = document.getElementsByClassName('unlogin-comment-box-new')[0];
  254. if (parentNode_chrome && window.navigator.userAgent.indexOf('Chrome')) { // 判断是否为谷歌浏览器
  255. parentNode_chrome.innerHTML = `<div class="comment-title">评论<span>${res.data.count}</span></div>` + dom;
  256. } else {
  257. parentNode.innerHTML = dom;
  258. }
  259. } catch(err) {
  260. console.log(err);
  261. }
  262. };
  263. const setCookie = (key, value, path, domain) => {
  264. const time = 4 * 30 * 24 * 60 * 60 * 1000;
  265. const date = new Date(+new Date + time).toUTCString();
  266. document.cookie = `${key}=${value};path=${path};domain=${domain};expires=${date}`
  267. }
  268. const setHideLogin = () => {
  269. const cookieArr = document.cookie.split('; ');
  270. if (cookieArr.includes("hide_login=2")) {
  271. return
  272. } else {
  273. setCookie('hide_login', 2, '/', '.csdn.net')
  274. location.href = location.href
  275. }
  276. }
  277.  
  278. setTimeout(() => {
  279. getCompleteDom();
  280. getComment();
  281. window.csdn ? window.csdn.copyright.init('', '') : '';
  282. window.csdn.loginBox.show = function() {};
  283. setHideLogin();
  284. }, 0);
  285. })();