AcWing Better!

AcWing界面美化,功能增强,视频时间点标记跳转,代码markdown一键复制

当前为 2023-06-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name AcWing Better!
  3. // @version 3.22
  4. // @description AcWing界面美化,功能增强,视频时间点标记跳转,代码markdown一键复制
  5. // @author 北极小狐
  6. // @match https://www.acwing.com/*
  7. // @icon https://aowuucdn.oss-cn-beijing.aliyuncs.com/acwing.png
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_info
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @connect gf.qytechs.cn
  13. // @run-at document-start
  14. // @require https://cdn.bootcdn.net/ajax/libs/turndown/7.1.1/turndown.min.js
  15. // @license MIT
  16. // @namespace https://gf.qytechs.cn/users/747162
  17. // ==/UserScript==
  18.  
  19. // 初始化
  20. if(GM_getValue("bottomBar")===undefined) GM_setValue("bottomBar", true);
  21. if(GM_getValue("bingWallpaper")===undefined) GM_setValue("bingWallpaper", true);
  22. if(GM_getValue("widthAdjustment")===undefined) GM_setValue("widthAdjustment", true);
  23. if(GM_getValue("autoPlay")===undefined) GM_setValue("autoPlay", true);
  24.  
  25. // 样式
  26. function loadCssCode(code){
  27. var style = document.createElement('style');
  28. style.type = 'text/css';
  29. style.rel = 'stylesheet';
  30. style.appendChild(document.createTextNode(code));
  31. var head = document.getElementsByTagName('head')[0];
  32. head.appendChild(style);
  33. }
  34. if(GM_getValue("bottomBar")===true){
  35. loadCssCode(`
  36. .fs-gui-taskbar {
  37. height: 3.5vh !important;
  38. background-color: #dde1e5 !important;
  39. }
  40. .fs-gui-taskbar-widgets-apps-item > img {
  41. height: 2.2vh !important;
  42. width: 2.2vh !important;
  43. margin: 0.5vh 0.5vh 0.5vh 0.5vh !important;
  44. }
  45. .fs-gui-taskbar-widgets-clock{
  46. width: 0px !important;
  47. height: 0px !important;
  48. overflow: hidden !important;
  49. }
  50. .fs-gui-taskbar-widgets-apps-item {
  51. margin-right: 2vh !important;
  52. }
  53. #fs-gui-taskbar-search-field {
  54. font-size: 13px !important;
  55. }
  56. .fs-gui-taskbar-search-icon {
  57. font-size: 16px !important;
  58. top: 0.95vh !important;
  59. left: 4.3vh !important;
  60. }
  61. .fs-gui-taskbar-begin {
  62. height: 3vh !important;
  63. width: 3vh !important;
  64. margin: 0.2vh !important;
  65. border-radius: 60%;
  66. background-color: #fffefe80 !important;
  67. }
  68. button.fs-gui-taskbar-begin.pull-left.btn.btn-default img {
  69. width: 83% !important;
  70. }
  71. #fs-gui-taskbar-search-field {
  72. height: 90% !important;
  73. margin: 0.15vh;
  74. border-radius: 100px;
  75. border-width: 0.2vh;
  76. border-style: solid;
  77. border-color: #c7d2dd;
  78. }
  79. #fs-gui-taskbar-search-field:focus-visible {
  80. border-width: 0.2vh;
  81. border-style: solid;
  82. border-color: #8bb2d9;
  83. outline: -webkit-focus-ring-color auto 0px;
  84. }
  85. `);
  86. }
  87. if(GM_getValue("bingWallpaper")===true){
  88. loadCssCode(`
  89. #acwing_body {
  90. background: white url(https://bingw.jasonzeng.dev) fixed !important;
  91. }
  92. `);
  93. }
  94. if(GM_getValue("widthAdjustment")===true){
  95. loadCssCode(`
  96. .container {
  97. width: auto !important;
  98. margin: 0px 3px;
  99. }
  100. `);
  101. document.addEventListener('DOMContentLoaded', function() {
  102. $('.base_body .container .row').children().removeClass(' col-sm-offset-2 col-sm-8 col-md-offset-2 col-md-9');
  103. });
  104. }
  105. loadCssCode(`
  106. /* 去除没用的图标 */
  107. .file-explorer-main-field-item.file-explorer-main-field-item-desktop {
  108. width: 0px;
  109. height: 0px;
  110. overflow: hidden;
  111. }
  112. /* 背景bing壁纸 */
  113.  
  114. /* 修复评论区某些同学发超长单词会导致整个页面显示x-scrollbar的**行为 */
  115. .comment-conent {
  116. overflow-x: auto;
  117. }
  118. /* 页脚 */
  119. footer#acwing_footer .copyright {
  120. color: #fff;
  121. }
  122. footer#acwing_footer .copyright a, .links a, footer#acwing_footer .container {
  123. color: #fff;
  124. }
  125.  
  126. /* 复制按钮 */
  127. pre.hljs {
  128. display: flex;
  129. justify-content: space-between;
  130. }
  131. span.copy-button {
  132. cursor: pointer;
  133. background-color: #e6e6e6;
  134. color: #727378;
  135. height: 20px;
  136. font-size: 13px;
  137. border-radius: 0.3rem;
  138. padding: 1px 5px;
  139. margin: 5px;
  140. box-shadow: 0 0 1px #0000004d;
  141. }
  142. span.copy-button.copied {
  143. background-color: #07e65196;
  144. color: #104f2b;
  145. }
  146. /* html2md */
  147. .html2md-panel {
  148. display: flex;
  149. justify-content: flex-end;
  150. }
  151. button.html2mdButton {
  152. height: 30px;
  153. width: 30px;
  154. }
  155. button.html2mdButton {
  156. cursor: pointer;
  157. background-color: #e6e6e6;
  158. color: #727378;
  159. height: 30px;
  160. width: auto;
  161. font-size: 13px;
  162. border-radius: 0.3rem;
  163. border: none;
  164. padding: 1px 5px;
  165. margin: 5px;
  166. box-shadow: 0 0 1px #0000004d;
  167. }
  168. button.html2mdButton.copied {
  169. background-color: #07e65196;
  170. color: #104f2b;
  171. }
  172. button.html2mdButton.html2md-view.mdViewed {
  173. background-color: #ff980057;
  174. color: #5a3a0c;
  175. }
  176. /* 打卡框 */
  177. .ui.bottom.attached.tab.segment.active {
  178. padding: 0px;
  179. }
  180. /* 视频bar */
  181. .embed-responsive {
  182. height: max-content;
  183. padding-bottom: 0px;
  184. }
  185. .player_bar {
  186. margin: 2px;
  187. display: flex;
  188. justify-content: space-between;
  189. }
  190. .player_bar_go {
  191. cursor: pointer;
  192. width: 50px;
  193. color: #999;
  194. height: auto;
  195. font-size: 13px;
  196. border-radius: 0.3rem;
  197. padding: 1px 5px;
  198. margin: 5px;
  199. border: none;
  200. background: linear-gradient(-225deg,#d5dbe4,#f8f8f8);
  201. box-shadow: inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);
  202. display: flex;
  203. justify-content: center;
  204. align-items: center;
  205. }
  206. button#player_bar_list_add_new_item_btn {
  207. height: 30px;
  208. width: 50px;
  209. background-color: #00aeec;
  210. color: #ffffff;
  211. font-size: 13px;
  212. border-radius: 0rem 0.5rem 0.5rem 0rem;
  213. padding: 1px 5px;
  214. margin: 5px 5px 5px 0px;
  215. border: none;
  216. box-shadow: 0 0 1px #0000004d;
  217. }
  218. div#player_bar_list {
  219. display: grid;
  220. width: 100%;
  221. border-radius: 0.3rem 0rem 0rem 0.3rem;
  222. margin: 5px 0px 5px 0px;
  223. border: 1px solid #00aeeccc;
  224. }
  225. div#player_bar_list input[type="radio"] {
  226. appearance: none;
  227. width: 0;
  228. height: 0;
  229. overflow: hidden;
  230. }
  231. div#player_bar_list input[type=radio]:focus {
  232. outline: 0px;
  233. }
  234. label.player_bar_ul_li_text {
  235. max-width: 100%;
  236. height: 90px;
  237. overflow-x: auto;
  238. font-weight: 400;
  239. margin: 0px 4px;
  240. border: 1px dashed #0000004d;
  241. padding: 3px;
  242. }
  243. ul#player_bar_ul li button {
  244. background-color: #e6e6e6;
  245. color: #727378;
  246. height: 23px;
  247. font-size: 14px;
  248. border-radius: 0.3rem;
  249. padding: 1px 5px;
  250. margin: 5px;
  251. border: none;
  252. box-shadow: 0 0 1px #0000004d;
  253. }
  254. ul#player_bar_ul {
  255. list-style-type: none;
  256. padding-inline-start: 0px;
  257. display: flex;
  258. overflow-x: auto;
  259. max-width: 100%;
  260. margin: 0px;
  261. }
  262. ul#player_bar_ul li {
  263. height: 100px;
  264. width: 80px;
  265. display: grid;
  266. overflow: hidden;
  267. margin: 4px 4px;
  268. min-width: 100px;
  269. }
  270. label.player_bar_ul_li_text:hover {
  271. background-color: #eae4dc24;
  272. }
  273. input[type="radio"]:checked + .player_bar_ul_li_text {
  274. background: #41e49930;
  275. border: 1px solid green;
  276. color: green;
  277. }
  278.  
  279. ul#player_bar_ul::-webkit-scrollbar {
  280. width: 5px;
  281. height: 8px;
  282. }
  283. ul#player_bar_ul::-webkit-scrollbar-thumb {
  284. border-radius: 2px;
  285. border: 1px solid rgba(56,56,56,.3411764706);
  286. background-clip: padding-box;
  287. background-color: #a29bb84a;
  288. background-image: -webkit-linear-gradient(45deg,hsla(0deg,0%,100%,.4) 25%,transparent 0,transparent 50%,hsla(0deg,0%,100%,.4) 0,hsla(0deg,0%,100%,.4) 75%,transparent 0,transparent);
  289. }
  290. ul#player_bar_ul::-webkit-scrollbar-track {
  291. background-color: #f1f1f1;
  292. border-radius: 5px;
  293. }
  294.  
  295. label.player_bar_ul_li_text::-webkit-scrollbar {
  296. width: 5px;
  297. height: 7px;
  298. background-color: #aaa;
  299. }
  300. label.player_bar_ul_li_text::-webkit-scrollbar-thumb {
  301. border: 1px solid rgba(56,56,56,.3411764706);
  302. background-clip: padding-box;
  303. background-color: #a29bb84a;
  304. }
  305. label.player_bar_ul_li_text::-webkit-scrollbar-track {
  306. background-color: #f1f1f1;
  307. }
  308. .player_bar_list_add_div {
  309. display: flex;
  310. height: 40px;
  311. margin: 4px 2px;
  312. }
  313. input#player_bar_list_add_input {
  314. width: 100%;
  315. height: 30px;
  316. background-color: #ffffff;
  317. color: #727378;
  318. font-size: 13px;
  319. border-radius: 0.3rem 0rem 0rem 0.3rem;
  320. padding: 1px 5px;
  321. margin: 5px 0px 5px 0px;
  322. border: 1px solid #00aeeccc;
  323. border-right: none;
  324. box-shadow: 0 0 1px #0000004d;
  325. }
  326. input#player_bar_list_add_input:focus-visible {
  327. border-width: 2px;
  328. border-style: solid;
  329. border-color: #8bb2d9;
  330. outline: -webkit-focus-ring-color auto 0px;
  331. }
  332. button#player_bar_list_add_new_item_btn.added {
  333. background-color: #07e65196;
  334. color: #104f2b;
  335. }
  336. div#player_bar_go.gone {
  337. color: #3f5a14;
  338. font-weight: 600;
  339. background: linear-gradient(-225deg,#9CCC65,#E6EE9C);
  340. box-shadow: inset 0 -2px 0 0 #cde3e6, inset 0 0 1px 1px #c6fd7d, 0 1px 2px 1px rgb(30 90 44 / 40%);
  341. }
  342. /* bar修改菜单 */
  343. div#player_bar_menu {
  344. position: absolute;
  345. border-width: 1px;
  346. border-style: solid;
  347. border-color: #8bb2d9;
  348. box-shadow: 1px 1px 4px 0px #0000004d;
  349. }
  350. div#player_bar_menu_edit {
  351. cursor: pointer;
  352. background-color: #ffffff;
  353. color: black;
  354. box-shadow: inset 0px 0px 0px 0px #8bb2d9;
  355. padding: 2px 6px;
  356. }
  357. div#player_bar_menu_delete {
  358. cursor: pointer;
  359. background-color: #ffff;
  360. box-shadow: inset 0px 1px 0px 0px #8bb2d9;
  361. color: black;
  362. padding: 2px 6px;
  363. }
  364. div#player_bar_menu_edit:hover {
  365. background-color: #00aeec;
  366. color: white;
  367. }
  368. div#player_bar_menu_delete:hover {
  369. background-color: #FF5722;
  370. color: white;
  371. }
  372. /*更新检查*/
  373. div#update_panel {
  374. position: fixed;
  375. top: 50%;
  376. left: 50%;
  377. width: 240px;
  378. transform: translate(-50%, -50%);
  379. background-color: #fdfdfd;
  380. border: 1px solid #00aeeccc;
  381. border-radius: 5px;
  382. box-shadow: 2px 2px 3px 1px #0000004d;
  383. padding: 10px 20px 20px 20px;
  384. color: #444242;
  385. background-color: #ecf0ff;
  386. border: 6px solid #ffffff;
  387. border-radius: 16px;
  388. }
  389. div#update_panel #updating {
  390. cursor: pointer;
  391. display: inline-flex;
  392. padding: 0px;
  393. background-color: #1aa06d;
  394. color: #ffffff;
  395. font-size: 1rem;
  396. line-height: 1.5rem;
  397. font-weight: 500;
  398. justify-content: center;
  399. width: 100%;
  400. border-radius: 0.375rem;
  401. border: none;
  402. box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  403. }
  404. div#update_panel #updating a {
  405. text-decoration: none;
  406. color: white;
  407. display: flex;
  408. position: inherit;
  409. top: 0;
  410. left: 0;
  411. width: 100%;
  412. height: 22px;
  413. font-size: 14px;
  414. justify-content: center;
  415. align-items: center;
  416. }
  417. /*设置面板*/
  418. div#topNavBar {
  419. width: 80%;
  420. }
  421. nav.navbar.navbar-inverse.navbar-fixed-top.navbar-expand-lg .container {
  422. display: flex;
  423. align-items: center;
  424. justify-content: space-between;
  425. }
  426. button.html2mdButton.ACBetter_setting {
  427. background-color: #56aa56;
  428. color: white;
  429. white-space: nowrap;
  430. }
  431. #ACwingBetter_setting_menu {
  432. z-index: 9999;
  433. border-radius: 0.5rem;
  434. box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  435. display: grid;
  436. position: fixed;
  437. top: 50%;
  438. left: 50%;
  439. width: 270px;
  440. transform: translate(-50%, -50%);
  441. border-radius: 16px;
  442. background-color: #ecf0ff;
  443. border: 6px solid #ffffff;
  444. color: #697e91;
  445. padding: 10px 20px 20px 20px;
  446. }
  447.  
  448. #ACwingBetter_setting_menu .tool-box {
  449. position: absolute;
  450. display: flex;
  451. align-items: center;
  452. justify-content: center;
  453. width: 2.5rem;
  454. height: 2.5rem;
  455. top: 3px;
  456. right: 3px;
  457. }
  458.  
  459. #ACwingBetter_setting_menu .btn-close {
  460. display: flex;
  461. align-items: center;
  462. justify-content: center;
  463. text-align: center;
  464. padding: 10px;
  465. width: 2rem;
  466. height: 2rem;
  467. color: transparent;
  468. font-size: 0;
  469. cursor: pointer;
  470. background-color: #ff000080;
  471. border: none;
  472. border-radius: 10px;
  473. transition: .2s ease all;
  474. }
  475.  
  476. #ACwingBetter_setting_menu .btn-close:hover {
  477. width: 2rem;
  478. height: 2rem;
  479. font-size: 1rem;
  480. color: #ffffff;
  481. background-color: #ff0000cc;
  482. box-shadow: 0 5px 5px 0 #00000026;
  483. }
  484.  
  485. #ACwingBetter_setting_menu .btn-close:active {
  486. width: .9rem;
  487. height: .9rem;
  488. font-size: .9rem;
  489. color: #ffffffde;
  490. --shadow-btn-close: 0 3px 3px 0 #00000026;
  491. box-shadow: var(--shadow-btn-close);
  492. }
  493.  
  494. .checkbox-con {
  495. margin: 10px;
  496. display: flex;
  497. align-items: center;
  498. color: white;
  499. }
  500.  
  501. #ACwingBetter_setting_menu input[type=checkbox]:focus {
  502. outline: 0px;
  503. }
  504.  
  505. .checkbox-con input[type="checkbox"] {
  506. margin: 0px;
  507. appearance: none;
  508. width: 48px;
  509. height: 24px;
  510. border: 2px solid #6b8092;
  511. border-radius: 20px;
  512. background: #f1e1e1;
  513. position: relative;
  514. box-sizing: border-box;
  515. }
  516.  
  517. .checkbox-con input[type="checkbox"]::before {
  518. content: "";
  519. width: 16px;
  520. height: 16px;
  521. background: #6b80927a;
  522. border: 2px solid #6b8092;
  523. border-radius: 50%;
  524. position: absolute;
  525. top: 0;
  526. left: 0;
  527. transform: translate(16%, 12%);
  528. transition: all 0.3s ease-in-out;
  529. }
  530.  
  531. .checkbox-con input[type="checkbox"]::after {
  532. content: url("data:image/svg+xml,%3Csvg xmlns='://www.w3.org/2000/svg' width='23' height='23' viewBox='0 0 23 23' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M6.55021 5.84315L17.1568 16.4498L16.4497 17.1569L5.84311 6.55026L6.55021 5.84315Z' fill='%23EA0707' fill-opacity='0.89'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M17.1567 6.55021L6.55012 17.1568L5.84302 16.4497L16.4496 5.84311L17.1567 6.55021Z' fill='%23EA0707' fill-opacity='0.89'/%3E%3C/svg%3E");
  533. position: absolute;
  534. top: 0;
  535. left: 24px;
  536. }
  537.  
  538. .checkbox-con input[type="checkbox"]:checked {
  539. border: 2px solid #02c202;
  540. background: #e2f1e1;
  541. }
  542.  
  543. .checkbox-con input[type="checkbox"]:checked::before {
  544. background: rgba(2, 194, 2, 0.5);
  545. border: 2px solid #02c202;
  546. transform: translate(160%, 13%);
  547. transition: all 0.3s ease-in-out;
  548. }
  549.  
  550. .checkbox-con input[type="checkbox"]:checked::after {
  551. content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='13' viewBox='0 0 15 13' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M14.8185 0.114533C15.0314 0.290403 15.0614 0.605559 14.8855 0.818454L5.00187 12.5L0.113036 6.81663C-0.0618274 6.60291 -0.0303263 6.2879 0.183396 6.11304C0.397119 5.93817 0.71213 5.96967 0.886994 6.18339L5.00187 11L14.1145 0.181573C14.2904 -0.0313222 14.6056 -0.0613371 14.8185 0.114533Z' fill='%2302C202' fill-opacity='0.9'/%3E%3C/svg%3E");
  552. position: absolute;
  553. top: 3px;
  554. left: 4px;
  555. }
  556.  
  557. .checkbox-con label {
  558. margin: 0px 0px 0px 10px;
  559. cursor: pointer;
  560. user-select: none;
  561. }
  562.  
  563. .ACBetter_setting_list {
  564. display: flex;
  565. align-items: center;
  566. margin-top: 18px;
  567. }
  568.  
  569. .checkbox-con button {
  570. cursor: pointer;
  571. display: inline-flex;
  572. padding: 0.5rem 1rem;
  573. background-color: #1aa06d;
  574. color: #ffffff;
  575. font-size: 1rem;
  576. line-height: 1.5rem;
  577. font-weight: 500;
  578. justify-content: center;
  579. width: 100%;
  580. border-radius: 0.375rem;
  581. border: none;
  582. box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  583. }
  584. `);
  585.  
  586. // 更新检查
  587. (function checkScriptVersion() {
  588. function compareVersions(version1 = "0", version2 = "0") {
  589. const v1Array = String(version1).split(".");
  590. const v2Array = String(version2).split(".");
  591. const minLength = Math.min(v1Array.length, v2Array.length);
  592. let result = 0;
  593. for (let i = 0; i < minLength; i++) {
  594. const curV1 = Number(v1Array[i]);
  595. const curV2 = Number(v2Array[i]);
  596. if (curV1 > curV2) {
  597. result = 1;
  598. break;
  599. } else if (curV1 < curV2) {
  600. result = -1;
  601. break;
  602. }
  603. }
  604. if (result === 0 && v1Array.length !== v2Array.length) {
  605. const v1IsBigger = v1Array.length > v2Array.length;
  606. const maxLenArray = v1IsBigger ? v1Array : v2Array;
  607. for (let i = minLength; i < maxLenArray.length; i++) {
  608. const curVersion = Number(maxLenArray[i]);
  609. if (curVersion > 0) {
  610. v1IsBigger ? result = 1 : result = -1;
  611. break;
  612. }
  613. }
  614. }
  615. return result;
  616. }
  617.  
  618. GM_xmlhttpRequest({
  619. method: "GET",
  620. url: "https://gf.qytechs.cn/zh-CN/scripts/464981.json",
  621. timeout: 10 * 1e3,
  622. onload: function(response) {
  623. const scriptData = JSON.parse(response.responseText);
  624. if (scriptData.name === GM_info.script.name && compareVersions(scriptData.version, GM_info.script.version) === 1) {
  625. $("body").append(`
  626. <div id='update_panel'>
  627. <h3>${GM_info.script.name}有新版本!</h3>
  628. <hr>
  629. <div class='update_panel_menu'>
  630. <span class ='tip'>版本信息:${GM_info.script.version} ${scriptData.version}</span>
  631. </div>
  632. <br>
  633. <button id='updating'><a target="_blank" href="${scriptData.url}">更新</a></button>
  634. </div>
  635. `);
  636. }
  637. }
  638. });
  639. })();
  640.  
  641. // 设置面板
  642. document.addEventListener('DOMContentLoaded', function() {
  643. $("#topNavBar").after(
  644. "<button class='html2mdButton ACBetter_setting'>ACwingBetter设置</button>"
  645. );
  646. });
  647. document.addEventListener('DOMContentLoaded', function() {
  648. $(".ACBetter_setting").click(function () {
  649. $(".ACBetter_setting").attr("disabled", true);
  650. $(".ACBetter_setting").css("background-color", "#e6e6e6");
  651. $(".ACBetter_setting").css("color", "#727378");
  652. $(".ACBetter_setting").css("cursor", "not-allowed");
  653. $("body").append(`
  654. <div class='checkbox-con' id='ACwingBetter_setting_menu'>
  655. <div class="tool-box">
  656. <button class="btn-close">×</button>
  657. </div>
  658. <h3>ACwingBetter设置</h3>
  659. <hr>
  660. <div class='ACBetter_setting_list'>
  661. <input type="checkbox" id="bottomBar" name="bottomBar" checked>
  662. <label for="bottomBar">美化底栏</label>
  663. </div>
  664. <div class='ACBetter_setting_list'>
  665. <input type="checkbox" id="bingWallpaper" name="bingWallpaper" checked>
  666. <label for="bingWallpaper">Bing每日壁纸</label>
  667. </div>
  668. <div class='ACBetter_setting_list'>
  669. <input type="checkbox" id="widthAdjustment" name="widthAdjustment" checked>
  670. <label for="widthAdjustment">页面宽屏</label>
  671. </div>
  672. <div class='ACBetter_setting_list'>
  673. <input type="checkbox" id="autoPlay" name="autoPlay" checked>
  674. <label for="autoPlay">不自动播放视频</label>
  675. </div>
  676. <br>
  677. <button id='save'>保存</button>
  678. </div>
  679. `);
  680. $("#save").click(function () {
  681. GM_setValue("bottomBar", $("#bottomBar").prop("checked"));
  682. GM_setValue("bingWallpaper", $("#bingWallpaper").prop("checked"));
  683. GM_setValue("widthAdjustment", $("#widthAdjustment").prop("checked"));
  684. GM_setValue("autoPlay", $("#autoPlay").prop("checked"));
  685. location.reload();
  686. });
  687. $("#bottomBar").prop("checked", GM_getValue("bottomBar"));
  688. $("#bingWallpaper").prop("checked", GM_getValue("bingWallpaper"));
  689. $("#widthAdjustment").prop("checked", GM_getValue("widthAdjustment"));
  690. $("#autoPlay").prop("checked", GM_getValue("autoPlay"));
  691. // 关闭
  692. $("#ACwingBetter_setting_menu .btn-close").click(function () {
  693. $("#ACwingBetter_setting_menu").remove();
  694. $(".ACBetter_setting").attr("disabled", false);
  695. $(".ACBetter_setting").css("background-color", "#56aa56");
  696. $(".ACBetter_setting").css("color", "white");
  697. $(".ACBetter_setting").css("cursor", "pointer");
  698. })
  699. });
  700. });
  701.  
  702. // 添加复制按钮
  703. function addCopy(){
  704. // 获取所有 .hljs 中的代码块
  705. const codeBlocks = document.querySelectorAll('.hljs code');
  706.  
  707. // 循环遍历每个代码块
  708. codeBlocks.forEach(codeBlock => {
  709. // 创建一个 span 元素,并设置样式
  710. const beforeButton = document.createElement('span');
  711. beforeButton.textContent = "Copy";
  712. beforeButton.className = 'copy-button';
  713. // 在代码块前面插入按钮
  714. codeBlock.parentNode.insertBefore(beforeButton, codeBlock.nextSibling);
  715. // 为按钮添加点击事件
  716. beforeButton.addEventListener('click', event => {
  717. // 创建临时文本域
  718. const textarea = document.createElement('textarea');
  719. textarea.value = codeBlock.textContent.replace(/\n+$/, '');
  720. document.body.appendChild(textarea);
  721. textarea.select();
  722. document.execCommand('copy');
  723. document.body.removeChild(textarea);
  724.  
  725.  
  726. // 更新复制按钮文本
  727. beforeButton.classList.add('copied');
  728. beforeButton.textContent = "Copied";
  729. setTimeout(() => {
  730. beforeButton.classList.remove('copied');
  731. beforeButton.textContent = "Copy";
  732. }, 2000);
  733. }, false);
  734. });
  735. }
  736.  
  737. // 移除复制按钮
  738. function removeCopy(){
  739. var elements = document.querySelectorAll('.hljs .copy-button');
  740. for (var i = 0; i < elements.length; i++) {
  741. elements[i].parentNode.removeChild(elements[i]);
  742. }
  743.  
  744. }
  745.  
  746. document.addEventListener('DOMContentLoaded', function() {
  747. // 让某些链接在新窗口打开
  748. var regExps = [
  749. /常用代码模板/,
  750. /example/,
  751. /test/
  752. ];
  753. var aTags = document.getElementsByTagName('a');
  754. for (var i = 0; i < aTags.length; i++) {
  755. for (var j = 0; j < regExps.length; j++) {
  756. if (regExps[j].test(aTags[i].textContent)) {
  757. aTags[i].setAttribute('target', '_blank');
  758. break;
  759. }
  760. }
  761. }
  762. // 自动恢复进度条
  763. setTimeout(function() {
  764. try {
  765. document.querySelector('.play-jump').click();
  766. if(GM_getValue("autoPlay")===true){
  767. let player_bar_video = document.querySelector('video');
  768. if(!player_bar_video.paused)player_bar_video.pause();
  769. }
  770. } catch (error) {
  771. // do nothing
  772. }
  773. }, 3000);
  774. // 复制按钮
  775. addCopy();
  776. // 移除广告元素
  777. let ADidADList = ["1024-activity","test"];
  778. ADtraverseDom(document.body);
  779. function ADtraverseDom(node) {
  780. if (node.nodeType === Node.ELEMENT_NODE && ADidADList.includes(node.id)) {
  781. node.parentNode.removeChild(node);
  782. } else {
  783. for (let i = 0; i < node.childNodes.length; i++) {
  784. ADtraverseDom(node.childNodes[i]);
  785. }
  786. }
  787. }
  788. // 修改打卡页代码框默认高度
  789. var element = document.getElementById("martor-content");
  790. if(element){
  791. var style = window.getComputedStyle(element);
  792. element.style.height = "55vh";
  793. }
  794. });
  795.  
  796. // MarkDown
  797.  
  798. document.addEventListener('DOMContentLoaded', function() {
  799. let debug = false; // whether to enable on editor
  800.  
  801. let turndownService = new TurndownService();
  802.  
  803. turndownService.keep(['del']);
  804.  
  805. // code block
  806. turndownService.addRule('pre', {
  807. filter: 'pre',
  808. replacement: function (content, node) {
  809. let t = $(node).attr("class").split(/\s+/).slice(-1);
  810. if (t == "hljs") t = "";
  811. return "```" + t + "\n" + content.trim() + "\n```";
  812. }
  813. });
  814.  
  815. // remove <script> math
  816. turndownService.addRule('remove-script', {
  817. filter: function (node, options) {
  818. return node.tagName.toLowerCase() == "script" && node.type.startsWith("math/tex");
  819. },
  820. replacement: function (content, node) {
  821. return "";
  822. }
  823. });
  824.  
  825. // inline math
  826. turndownService.addRule('inline-math', {
  827. filter: function (node, options) {
  828. return node.tagName.toLowerCase() == "span" && node.className == "MathJax";
  829. },
  830. replacement: function (content, node) {
  831. return "$" + $(node).next().text() + "$";
  832. }
  833. });
  834.  
  835. // block math
  836. turndownService.addRule('block-math', {
  837. filter: function (node, options) {
  838. return node.tagName.toLowerCase() == "div" && node.className == "MathJax_Display";
  839. },
  840. replacement: function (content, node) {
  841. return "\n$$\n" + $(node).next().text() + "\n$$\n";
  842. }
  843. });
  844.  
  845. // add buttons
  846. $("div[data-tab='preview-tab-content']").each(function() {
  847. if (debug || $(this).prev().attr('data-tab') != "editor-tab-content")
  848. $(this).before(
  849. "<div class='html2md-panel'> <button class='html2mdButton html2md-view'>MarkDown视图</button> <button class='html2mdButton html2md-cb'>Copy</button> </div>"
  850. );
  851. });
  852.  
  853. $(".html2md-cb").click(function() {
  854. let target = $(this).parent().next().get(0);
  855. if (!target.markdown){
  856. removeCopy();
  857. target.markdown = turndownService.turndown($(target).html());
  858. addCopy();
  859. }
  860. const textarea = document.createElement('textarea');
  861. textarea.value = target.markdown;
  862. document.body.appendChild(textarea);
  863. textarea.select();
  864. document.execCommand('copy');
  865. document.body.removeChild(textarea);
  866. // console.log(markdown);
  867. $(this).addClass("copied");
  868. $(this).text("Copied");
  869. // 更新复制按钮文本
  870. setTimeout(() => {
  871. $(this).removeClass("copied");
  872. $(this).text("Copy");
  873. }, 2000);
  874. });
  875.  
  876. $(".html2md-view").click(function() {
  877. let target = $(this).parent().next().get(0);
  878. if (target.viewmd) {
  879. target.viewmd = false;
  880. $(this).text("MarkDown视图");
  881. $(this).removeClass("mdViewed");
  882. $(target).html(target.original_html);
  883. addCopy();
  884. } else {
  885. target.viewmd = true;
  886. removeCopy();
  887. if (!target.original_html)
  888. target.original_html = $(target).html();
  889. if (!target.markdown)
  890. target.markdown = turndownService.turndown($(target).html());
  891. $(this).text("原始内容");
  892. $(this).addClass("mdViewed");
  893. $(target).html(`<span oninput="$(this).parent().get(0).markdown=this.value;" style="width:auto; height:auto; white-space: pre;">${target.markdown}</span>`);
  894. }
  895. });
  896. });
  897.  
  898.  
  899. // 播放器添加节点标签功能
  900. function addPlayerBar(player_bar_video){
  901. // 创建元素
  902. var player = document.querySelector('.prism-player');
  903. var player_bar = document.createElement('div');
  904. player_bar.classList.add('player_bar');
  905. player.parentNode.insertBefore(player_bar, player.nextSibling);
  906.  
  907. var player_bar_list = document.createElement('div');
  908. player_bar_list.classList.add('player_bar_list');
  909. player_bar_list.setAttribute("id","player_bar_list");
  910. player_bar.appendChild(player_bar_list);
  911.  
  912. var player_bar_ul = document.createElement('ul');
  913. player_bar_ul.classList.add('player_bar_ul');
  914. player_bar_ul.setAttribute("id","player_bar_ul");
  915. player_bar_list.appendChild(player_bar_ul);
  916.  
  917. var player_bar_go = document.createElement('div');
  918. player_bar_go.classList.add('player_bar_go');
  919. player_bar_go.setAttribute("id","player_bar_go");
  920. var player_bar_goText = document.createTextNode("Go!");
  921. player_bar_go.appendChild(player_bar_goText);
  922. player_bar.appendChild(player_bar_go);
  923.  
  924. var player_bar_list_add_div = document.createElement('div');
  925. player_bar_list_add_div.classList.add('player_bar_list_add_div');
  926. player_bar.parentNode.insertBefore(player_bar_list_add_div, player_bar.nextSibling);
  927.  
  928. var player_bar_list_add_input = document.createElement('input');
  929. player_bar_list_add_input.classList.add('player_bar_list_add_input');
  930. player_bar_list_add_input.setAttribute("type","text");
  931. player_bar_list_add_input.setAttribute("id","player_bar_list_add_input");
  932. player_bar_list_add_input.setAttribute("placeholder","在这里输入备注内容,点击Add添加一个时间点标记;选中一个标记,点击Go跳转;右键标记,修改或删除");
  933. player_bar_list_add_div.appendChild(player_bar_list_add_input);
  934.  
  935. var player_bar_list_add_button = document.createElement('button');
  936. player_bar_list_add_button.classList.add('player_bar_list_add_button');
  937. player_bar_list_add_button.setAttribute("id","player_bar_list_add_new_item_btn");
  938. var player_bar_list_add_buttonText = document.createTextNode("Add");
  939. player_bar_list_add_button.appendChild(player_bar_list_add_buttonText);
  940. player_bar_list_add_div.appendChild(player_bar_list_add_button);
  941.  
  942. //存储cookie的名称和标识符
  943. const COOKIE_NAME = "listItems";
  944. const PAGE_IDENTIFIER = window.location.href;
  945. //计数器
  946. let counter = 0;
  947.  
  948. //获取GM值中的数据
  949. function getListData() {
  950. let data = GM_getValue("cookieData");
  951. if (!data) {
  952. data = {};
  953. } else {
  954. data = JSON.parse(data);
  955. }
  956. if (!data[PAGE_IDENTIFIER]) {
  957. data[PAGE_IDENTIFIER] = [];
  958. }
  959. return data[PAGE_IDENTIFIER];
  960. }
  961.  
  962. //将数据保存到GM值中
  963. function saveListData(data) {
  964. let cookieData = GM_getValue("cookieData");
  965. if (cookieData) {
  966. cookieData = JSON.parse(cookieData);
  967. } else {
  968. cookieData = {};
  969. }
  970. cookieData[PAGE_IDENTIFIER] = data;
  971. GM_setValue("cookieData", JSON.stringify(cookieData));
  972. }
  973.  
  974. //创建新的li元素
  975. function createListItemElement(text) {
  976. const li = document.createElement("li");
  977. const radio = document.createElement("input");
  978. radio.type = "radio";
  979. radio.name = "player_bar_ul";
  980. radio.id = counter++;
  981. li.appendChild(radio);
  982. const label = document.createElement("label");
  983. label.textContent = text;
  984. label.classList.add("player_bar_ul_li_text");
  985. label.setAttribute("for", radio.id);
  986. li.appendChild(label);
  987. li.addEventListener("contextmenu", (event) => {
  988. //阻止默认右键菜单
  989. event.preventDefault();
  990. //显示菜单
  991. menu.style.display = "block";
  992. menu.style.left = event.pageX + "px";
  993. menu.style.top = event.pageY + "px";
  994.  
  995. const deleteItem = document.getElementById("player_bar_menu_delete");
  996. const editItem = document.getElementById("player_bar_menu_edit");
  997.  
  998. function onDelete() {
  999. deleteItem.removeEventListener("click", onDelete);
  1000. const list = document.getElementById("player_bar_ul");
  1001. const index = Array.from(list.children).indexOf(li);
  1002. const data = getListData();
  1003. data.splice(index, 1);
  1004. saveListData(data);
  1005. li.remove();
  1006. menu.style.display = "none";
  1007. }
  1008.  
  1009. function onEdit() {
  1010. editItem.removeEventListener("click", onEdit);
  1011. const list = document.getElementById("player_bar_ul");
  1012. const index = Array.from(list.children).indexOf(li);
  1013. const data = getListData();
  1014. label.textContent = data[index].text;
  1015. const text = prompt("请输入修改后的内容", label.textContent);
  1016. if (text !== undefined && text!==null) {
  1017. data[index].text = text.trim();
  1018. saveListData(data);
  1019. }
  1020. renderList();//重新渲染
  1021. menu.style.display = "none";
  1022. }
  1023.  
  1024. deleteItem.addEventListener("click", onDelete);
  1025. editItem.addEventListener("click", onEdit);
  1026.  
  1027. document.addEventListener("click", (event) => {
  1028. //点击菜单外部,隐藏菜单并移除事件监听器
  1029. if (!menu.contains(event.target)) {
  1030. menu.style.display = "none";
  1031. // 移除所有事件监听器
  1032. deleteItem.removeEventListener("click", onDelete);
  1033. editItem.removeEventListener("click", onEdit);
  1034. }
  1035. });
  1036. });
  1037. return li;
  1038. }
  1039.  
  1040. //渲染列表
  1041. function renderList() {
  1042. const listContainer = document.getElementById("player_bar_list");
  1043. const list = document.getElementById("player_bar_ul");
  1044. list.innerHTML = "";
  1045. const data = getListData();
  1046. data.forEach((item) => {
  1047. list.appendChild(createListItemElement(item.text));
  1048. });
  1049. }
  1050.  
  1051. //新增列表项
  1052. function addNewItem() {
  1053. const input = document.getElementById("player_bar_list_add_input");
  1054. const text = input.value.trim();
  1055. if (text === "") {
  1056. alert("请输入内容");
  1057. return;
  1058. }
  1059. const data = getListData();
  1060. data.push({text: text, time: player_bar_video.currentTime});
  1061. saveListData(data);
  1062. const list = document.getElementById("player_bar_ul");
  1063. list.appendChild(createListItemElement(text));
  1064. input.value = "";
  1065. }
  1066.  
  1067. //为添加按钮添加事件处理程序
  1068. var player_bar_add_button = document.getElementById("player_bar_list_add_new_item_btn")
  1069. player_bar_add_button.addEventListener("click", ()=>{
  1070. addNewItem();
  1071. player_bar_add_button.classList.add('added');
  1072. player_bar_add_button.textContent = "Added";
  1073. setTimeout(() => {
  1074. player_bar_add_button.classList.remove('added');
  1075. player_bar_add_button.textContent = "Add";
  1076. }, 2000);
  1077. });
  1078.  
  1079. //在页面加载时渲染列表
  1080. renderList();
  1081.  
  1082. //为跳转按钮添加事件处理程序
  1083. var click_player_bar_go = document.getElementById("player_bar_go");
  1084. click_player_bar_go.addEventListener("click", () => {
  1085. const selected = document.querySelector('input[name="player_bar_ul"]:checked');
  1086. if (selected) {
  1087. const data = getListData();
  1088. const index = Array.from(selected.parentNode.parentNode.children).indexOf(selected.parentNode);
  1089. player_bar_video.currentTime = data[index].time;
  1090. click_player_bar_go.classList.add('gone');
  1091. click_player_bar_go.textContent = "Gone";
  1092. setTimeout(() => {
  1093. click_player_bar_go.classList.remove('gone');
  1094. click_player_bar_go.textContent = "Go!";
  1095. }, 2000);
  1096. } else {
  1097. alert("请选择一项");
  1098. }
  1099. });
  1100.  
  1101. //创建自定义菜单
  1102. const menu = document.createElement("div");
  1103. menu.id = "player_bar_menu";
  1104. menu.style.display = "none";
  1105. menu.innerHTML = `
  1106. <div id="player_bar_menu_edit">修改</div>
  1107. <div id="player_bar_menu_delete">删除</div>
  1108. `;
  1109. document.body.appendChild(menu);
  1110. }
  1111.  
  1112. window.addEventListener('load', function() {
  1113. var player_bar_video = document.querySelector('video');
  1114. if(player_bar_video!=null)addPlayerBar(player_bar_video);
  1115. });

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址