// ==UserScript== // @name AcWing Better! // @version 3.29.0 // @description AcWing界面美化,功能增强,视频时间点标记跳转,代码markdown一键复制 // @author 北极小狐 // @match https://www.acwing.com/* // @icon https://aowuucdn.oss-cn-beijing.aliyuncs.com/acwing.png // @grant GM_xmlhttpRequest // @grant GM_info // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_setClipboard // @connect greasyfork.org // @run-at document-end // @connect sustech.edu.cn // @require https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/turndown/7.2.0/turndown.min.js#sha512-sJzEecN5Nk8cq81zKtGq6/z9Z/r3q38zV9enY75IVxiG7ybtlNUt864sL4L1Kf36bYIwxTMVKQOtU4VhD7hGrw== // @license MIT // @namespace https://greasyfork.org/users/747162 // @downloadURL https://update.greasyfork.icu/scripts/464981/AcWing%20Better%21.user.js // @updateURL https://update.greasyfork.icu/scripts/464981/AcWing%20Better%21.meta.js // ==/UserScript== // 状态与初始化 const getGMValue = (key, defaultValue) => { const value = GM_getValue(key); if (value === undefined) { GM_setValue(key, defaultValue); return defaultValue; } return value; }; const { hostname, href } = window.location; const bottomBar = getGMValue("bottomBar", true); const bingWallpaper = getGMValue("bingWallpaper", true); const widthAdjustment = getGMValue("widthAdjustment", true); const autoPlay = getGMValue("autoPlay", true); const acTimer = getGMValue("acTimer", true); const hideNavbar = getGMValue("hideNavbar", false); // 常量 const helpCircleHTML = '
'; const darkenPageStyle = `body::before { content: ""; display: block; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.4); z-index: 9999; }`; // 样式 if (bottomBar) { GM_addStyle(` .fs-gui-taskbar { height: 3.5vh !important; background-color: #dde1e5 !important; } .fs-gui-taskbar-widgets-apps-item > img { height: 2.2vh !important; width: 2.2vh !important; margin: 0.5vh 0.5vh 0.5vh 0.5vh !important; } .fs-gui-taskbar-widgets-clock{ width: 0px !important; height: 0px !important; overflow: hidden !important; } .fs-gui-taskbar-widgets-apps-item { margin-right: 2vh !important; } #fs-gui-taskbar-search-field { font-size: 13px !important; } .fs-gui-taskbar-search-icon { font-size: 16px !important; top: 0.95vh !important; left: 4.3vh !important; } .fs-gui-taskbar-begin { height: 3vh !important; width: 3vh !important; margin: 0.2vh !important; border-radius: 60%; background-color: #fffefe80 !important; } button.fs-gui-taskbar-begin.pull-left.btn.btn-default img { width: 83% !important; } #fs-gui-taskbar-search-field { height: 90% !important; margin: 0.15vh; border-radius: 100px; border-width: 0.2vh; border-style: solid; border-color: #c7d2dd; } #fs-gui-taskbar-search-field:focus-visible { border-width: 0.2vh; border-style: solid; border-color: #8bb2d9; outline: -webkit-focus-ring-color auto 0px; } `); } if (bingWallpaper) { GM_addStyle(` #acwing_body { background: white url(https://bingw.jasonzeng.dev) fixed !important; } `); } if (widthAdjustment) { GM_addStyle(` .container { width: auto !important; margin: 0px 3px; } `); $(document).ready(function () { $('.base_body .container .row').children().removeClass(' col-sm-offset-2 col-sm-8 col-md-offset-2 col-md-9'); $('.col-md-8').removeClass('col-md-8').addClass('col-md-12'); }) } GM_addStyle(` span.mdViewContent { white-space: pre-wrap; } .file-explorer-main-field-item.file-explorer-main-field-item-desktop { width: 0px; height: 0px; overflow: hidden; } .comment-conent { overflow-x: auto; } /* 页脚 */ footer#acwing_footer .copyright { color: #fff; } footer#acwing_footer .copyright a, .links a, footer#acwing_footer .container { color: #fff; } /* 复制按钮 */ pre.hljs { display: flex; justify-content: space-between; } span.copy-button { cursor: pointer; background-color: #e6e6e6; color: #727378; height: 20px; font-size: 13px; border-radius: 0.3rem; padding: 1px 5px; margin: 5px; box-shadow: 0 0 1px #0000004d; } span.copy-button.copied { background-color: #07e65196; color: #104f2b; } /* html2md */ .html2md-panel { display: flex; justify-content: flex-end; } button.html2mdButton { height: 30px; width: 30px; } button.html2mdButton { display: flex; align-items: center; cursor: pointer; background-color: #ffffff; color: #606266; height: 22px; width: auto; font-size: 13px; border-radius: 0.3rem; padding: 1px 5px; margin: 5px; border: 1px solid #dcdfe6; } button.html2mdButton:hover { color: #409eff; border-color: #409eff; background-color: #f1f8ff; } button.html2mdButton.copied { background-color: #f0f9eb; color: #67c23e; border: 1px solid #b3e19d; } button.html2mdButton.html2md-view.mdViewed { background-color: #ff980057; color: #5a3a0c; } /* 打卡框 */ .ui.bottom.attached.tab.segment.active { padding: 0px; } /* 视频bar */ .embed-responsive { height: max-content; padding-bottom: 0px; } .player_bar { margin: 2px; display: flex; justify-content: space-between; } .player_bar_go { cursor: pointer; width: 50px; color: #999; height: auto; font-size: 13px; border-radius: 0.3rem; padding: 1px 5px; margin: 5px; border: none; background: linear-gradient(-225deg,#d5dbe4,#f8f8f8); box-shadow: inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4); display: flex; justify-content: center; align-items: center; } button#player_bar_list_add_new_item_btn { height: 30px; width: 50px; background-color: #00aeec; color: #ffffff; font-size: 13px; border-radius: 0rem 0.5rem 0.5rem 0rem; padding: 1px 5px; margin: 5px 5px 5px 0px; border: none; box-shadow: 0 0 1px #0000004d; } div#player_bar_list { display: grid; width: 100%; border-radius: 0.3rem 0rem 0rem 0.3rem; margin: 5px 0px 5px 0px; border: 1px solid #00aeeccc; } div#player_bar_list input[type="radio"] { appearance: none; width: 0; height: 0; overflow: hidden; } div#player_bar_list input[type=radio]:focus { outline: 0px; } label.player_bar_ul_li_text { max-width: 100%; height: 90px; overflow-x: auto; font-weight: 400; margin: 0px 4px; border: 1px dashed #0000004d; padding: 3px; } ul#player_bar_ul li button { background-color: #e6e6e6; color: #727378; height: 23px; font-size: 14px; border-radius: 0.3rem; padding: 1px 5px; margin: 5px; border: none; box-shadow: 0 0 1px #0000004d; } ul#player_bar_ul { list-style-type: none; padding-inline-start: 0px; display: flex; overflow-x: auto; max-width: 100%; margin: 0px; } ul#player_bar_ul li { height: 100px; width: 80px; display: grid; overflow: hidden; margin: 4px 4px; min-width: 100px; } label.player_bar_ul_li_text:hover { background-color: #eae4dc24; } input[type="radio"]:checked + .player_bar_ul_li_text { background: #41e49930; border: 1px solid green; color: green; } ul#player_bar_ul::-webkit-scrollbar { width: 5px; height: 8px; } ul#player_bar_ul::-webkit-scrollbar-thumb { border-radius: 2px; border: 1px solid rgba(56,56,56,.3411764706); background-clip: padding-box; background-color: #a29bb84a; 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); } ul#player_bar_ul::-webkit-scrollbar-track { background-color: #f1f1f1; border-radius: 5px; } label.player_bar_ul_li_text::-webkit-scrollbar { width: 5px; height: 7px; background-color: #aaa; } label.player_bar_ul_li_text::-webkit-scrollbar-thumb { border: 1px solid rgba(56,56,56,.3411764706); background-clip: padding-box; background-color: #a29bb84a; } label.player_bar_ul_li_text::-webkit-scrollbar-track { background-color: #f1f1f1; } .player_bar_list_add_div { display: flex; height: 40px; margin: 4px 2px; } input#player_bar_list_add_input { width: 100%; height: 30px; background-color: #ffffff; color: #727378; font-size: 13px; border-radius: 0.3rem 0rem 0rem 0.3rem; padding: 1px 5px; margin: 5px 0px 5px 0px; border: 1px solid #00aeeccc; border-right: none; box-shadow: 0 0 1px #0000004d; } input#player_bar_list_add_input:focus-visible { border-width: 2px; border-style: solid; border-color: #8bb2d9; outline: -webkit-focus-ring-color auto 0px; } button#player_bar_list_add_new_item_btn.added { background-color: #07e65196; color: #104f2b; } div#player_bar_go.gone { color: #3f5a14; font-weight: 600; background: linear-gradient(-225deg,#9CCC65,#E6EE9C); box-shadow: inset 0 -2px 0 0 #cde3e6, inset 0 0 1px 1px #c6fd7d, 0 1px 2px 1px rgb(30 90 44 / 40%); } /* bar修改菜单 */ div#player_bar_menu { position: absolute; border-width: 1px; border-style: solid; border-color: #8bb2d9; box-shadow: 1px 1px 4px 0px #0000004d; } div#player_bar_menu_edit { cursor: pointer; background-color: #ffffff; color: black; box-shadow: inset 0px 0px 0px 0px #8bb2d9; padding: 2px 6px; } div#player_bar_menu_delete { cursor: pointer; background-color: #ffff; box-shadow: inset 0px 1px 0px 0px #8bb2d9; color: black; padding: 2px 6px; } div#player_bar_menu_edit:hover { background-color: #00aeec; color: white; } div#player_bar_menu_delete:hover { background-color: #FF5722; color: white; } /*设置面板*/ div#topNavBar { width: 80%; } nav.navbar.navbar-inverse.navbar-fixed-top.navbar-expand-lg .container { display: flex; align-items: center; justify-content: space-between; } button.html2mdButton.ACBetter_setting { background-color: #56aa56; color: white; white-space: nowrap; float: right; height: 30px; margin: 10px; border: 0px; } #ACwingBetter_setting_menu { z-index: 9999; border-radius: 0.5rem; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); display: grid; position: fixed; top: 50%; left: 50%; width: 270px; transform: translate(-50%, -50%); border-radius: 16px; background-color: #ecf0ff; border: 6px solid #ffffff; color: #697e91; padding: 10px 20px 20px 20px; } #ACwingBetter_setting_menu .tool-box { position: absolute; display: flex; align-items: center; justify-content: center; width: 2.5rem; height: 2.5rem; top: 3px; right: 3px; } #ACwingBetter_setting_menu .btn-close { display: flex; align-items: center; justify-content: center; text-align: center; padding: 10px; width: 2rem; height: 2rem; color: transparent; font-size: 0; cursor: pointer; background-color: #ff000080; border: none; border-radius: 10px; transition: .2s ease all; } #ACwingBetter_setting_menu .btn-close:hover { width: 2rem; height: 2rem; font-size: 1rem; color: #ffffff; background-color: #ff0000cc; box-shadow: 0 5px 5px 0 #00000026; } #ACwingBetter_setting_menu .btn-close:active { width: .9rem; height: .9rem; font-size: .9rem; color: #ffffffde; --shadow-btn-close: 0 3px 3px 0 #00000026; box-shadow: var(--shadow-btn-close); } .checkbox-con { margin: 10px; display: flex; align-items: center; color: white; } #ACwingBetter_setting_menu input[type=checkbox]:focus { outline: 0px; } .checkbox-con input[type="checkbox"] { margin: 0px; appearance: none; width: 48px; height: 24px; border: 2px solid #6b8092; border-radius: 20px; background: #f1e1e1; position: relative; box-sizing: border-box; } .checkbox-con input[type="checkbox"]::before { content: ""; width: 16px; height: 16px; background: #6b80927a; border: 2px solid #6b8092; border-radius: 50%; position: absolute; top: 0; left: 0; transform: translate(16%, 12%); transition: all 0.3s ease-in-out; } .checkbox-con input[type="checkbox"]::after { 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"); position: absolute; top: 0; left: 24px; } .checkbox-con input[type="checkbox"]:checked { border: 2px solid #02c202; background: #e2f1e1; } .checkbox-con input[type="checkbox"]:checked::before { background: rgba(2, 194, 2, 0.5); border: 2px solid #02c202; transform: translate(160%, 13%); transition: all 0.3s ease-in-out; } .checkbox-con input[type="checkbox"]:checked::after { 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"); position: absolute; top: 3px; left: 4px; } .checkbox-con label { margin: 0px 0px 0px 10px; cursor: pointer; user-select: none; } .ACBetter_setting_list { display: flex; align-items: center; margin-top: 18px; } .checkbox-con button { cursor: pointer; display: inline-flex; padding: 0.5rem 1rem; background-color: #1aa06d; color: #ffffff; font-size: 1rem; line-height: 1.5rem; font-weight: 500; justify-content: center; width: 100%; border-radius: 0.375rem; border: none; box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } /*设置面板-tip*/ .help_tip { margin-right: auto; } span.input_label { font-size: 14px; } .help_tip .tip_text { display: none; position: absolute; color: #697e91; font-weight: 400; font-size: 14px; letter-spacing: 0px; background-color: #ffffff; padding: 10px; margin: 5px 0px; border-radius: 4px; border: 1px solid #e4e7ed; box-shadow: 0px 0px 12px rgba(0, 0, 0, .12); z-index: 999; } .help_tip .tip_text p { margin-bottom: 5px; } .help_tip .tip_text:before { content: ""; position: absolute; top: -20px; right: -10px; bottom: -10px; left: -10px; z-index: -1; } .help-icon { display: flex; cursor: help; width: 15px; color: #b4b9d4; margin-left: 5px; } .AtBetter_setting_menu .AtBetter_setting_menu_label_text .help_tip .help-icon { color: #7fbeb2; } .help_tip .help-icon:hover + .tip_text, .help_tip .tip_text:hover { display: block; cursor: help; width: 250px; } /*更新检查*/ div#update_panel { z-index: 9999; position: fixed; top: 50%; left: 50%; width: 240px; transform: translate(-50%, -50%); box-shadow: 0px 0px 4px 0px #0000004d; padding: 10px 20px 20px 20px; color: #444242; background-color: #f5f5f5; border: 1px solid #848484; border-radius: 8px; } div#update_panel #updating { cursor: pointer; display: inline-flex; padding: 0px; background-color: #1aa06d; color: #ffffff; font-size: 1rem; line-height: 1.5rem; font-weight: 500; justify-content: center; width: 100%; border-radius: 0.375rem; border: none; box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); } div#update_panel #updating a { text-decoration: none; color: white; display: flex; position: inherit; top: 0; left: 0; width: 100%; height: 22px; font-size: 14px; justify-content: center; align-items: center; } #skip_menu { display: flex; margin-top: 10px; justify-content: flex-end; align-items: center; } #skip_menu .help_tip { margin-right: 5px; margin-left: -5px; } #skip_menu .help-icon { color: #f44336; } `); // 隐藏顶栏 if (hideNavbar & href.includes("/problem/content/")) { GM_addStyle(` nav.navbar { display: none; } .base_body { padding-top: 10px !important; } `); }; // 获取cookie function getCookie(name) { const cookies = document.cookie.split(";"); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); const [cookieName, cookieValue] = cookie.split("="); if (cookieName === name) { return decodeURIComponent(cookieValue); } } return ""; } // 防抖函数 function debounce(callback) { let timer; let immediateExecuted = false; const delay = 500; return function () { clearTimeout(timer); if (!immediateExecuted) { callback.call(this); immediateExecuted = true; } timer = setTimeout(() => { immediateExecuted = false; }, delay); }; } // 为元素添加鼠标拖动 function addDraggable(element) { let isDragging = false; let initialX, initialY; // 元素的初始位置 let startX, startY, offsetX, offsetY; // 鼠标起始位置,移动偏移量 let isSpecialMouseDown = false; // 选取某些元素时不拖动 element.on('mousedown', function (e) { var elem = $(this); var elemOffset = elem.offset(); var centerX = elemOffset.left + elem.outerWidth() / 2; var centerY = elemOffset.top + elem.outerHeight() / 2; initialX = centerX - window.pageXOffset; initialY = centerY - window.pageYOffset; isDragging = true; startX = e.clientX; startY = e.clientY; isSpecialMouseDown = $(e.target).is('label, p, input, textarea, span'); $('body').css('cursor', 'all-scroll'); }); $(document).on('mousemove', function (e) { if (!isDragging) return; // 不执行拖动操作 if ($(e.target).is('label, p, input, textarea, span') || isSpecialMouseDown && !$(e.target).is('input, textarea')) return; e.preventDefault(); offsetX = e.clientX - startX; offsetY = e.clientY - startY; element.css({ top: initialY + offsetY + 'px', left: initialX + offsetX + 'px' }); }); $(document).on('mouseup', function () { isDragging = false; isSpecialMouseDown = false; $('body').css('cursor', 'default'); }); } // 更新检查 (function checkScriptVersion() { function compareVersions(version1 = "0", version2 = "0") { const v1Array = String(version1).split("."); const v2Array = String(version2).split("."); const minLength = Math.min(v1Array.length, v2Array.length); let result = 0; for (let i = 0; i < minLength; i++) { const curV1 = Number(v1Array[i]); const curV2 = Number(v2Array[i]); if (curV1 > curV2) { result = 1; break; } else if (curV1 < curV2) { result = -1; break; } } if (result === 0 && v1Array.length !== v2Array.length) { const v1IsBigger = v1Array.length > v2Array.length; const maxLenArray = v1IsBigger ? v1Array : v2Array; for (let i = minLength; i < maxLenArray.length; i++) { const curVersion = Number(maxLenArray[i]); if (curVersion > 0) { v1IsBigger ? result = 1 : result = -1; break; } } } return result; } GM_xmlhttpRequest({ method: "GET", url: "https://greasyfork.org/zh-CN/scripts/464981.json", timeout: 10 * 1e3, onload: function (response) { const scriptData = JSON.parse(response.responseText); const skipUpdate = getCookie("skipUpdate"); if ( scriptData.name === GM_info.script.name && compareVersions(scriptData.version, GM_info.script.version) === 1 && skipUpdate !== "true" ) { const styleElement = GM_addStyle(darkenPageStyle); $("body").append(`

${GM_info.script.name}有新版本!


版本信息:${GM_info.script.version} → ${scriptData.version}

`+ helpCircleHTML + `

更新遇到了问题?

由于 Greasyfork 平台的原因,当新版本刚发布时,点击 Greasyfork 上的更新按钮可能会出现实际更新/安装的却是上一个版本的情况

通常你只需要稍等几分钟,然后再次前往更新/安装即可

你也可以点击下方按钮,在本次浏览器会话期间将不再提示更新

`); $("#skip_update").click(function () { document.cookie = "skipUpdate=true; expires=session; path=/"; styleElement.remove(); $("#update_panel").remove(); }); } } }); })(); // 随机数生成 function getRandomNumber(numDigits) { let min = Math.pow(10, numDigits - 1); let max = Math.pow(10, numDigits) - 1; return Math.floor(Math.random() * (max - min + 1)) + min; } // 设置面板 $(document).ready(function () { $("#topNavBar").after( "" ); }); const ACwingBetterSettingMenuHTML = `

AcWingBetter设置


`; $(document).ready(function () { $(".ACBetter_setting").click(function () { const styleElement = GM_addStyle(darkenPageStyle); $(".ACBetter_setting").attr("disabled", true); $(".ACBetter_setting").css("background-color", "#e6e6e6"); $(".ACBetter_setting").css("color", "#727378"); $(".ACBetter_setting").css("cursor", "not-allowed"); $("body").append(ACwingBetterSettingMenuHTML); addDraggable($('#ACwingBetter_setting_menu')); $("#bottomBar").prop("checked", GM_getValue("bottomBar")); $("#hideNavbar").prop("checked", GM_getValue("hideNavbar")); $("#bingWallpaper").prop("checked", GM_getValue("bingWallpaper")); $("#widthAdjustment").prop("checked", GM_getValue("widthAdjustment")); $("#autoPlay").prop("checked", GM_getValue("autoPlay")); $("#acTimer").prop("checked", GM_getValue("acTimer")); $("#save").click(function () { GM_setValue("bottomBar", $("#bottomBar").prop("checked")); GM_setValue("hideNavbar", $("#hideNavbar").prop("checked")); GM_setValue("bingWallpaper", $("#bingWallpaper").prop("checked")); GM_setValue("widthAdjustment", $("#widthAdjustment").prop("checked")); GM_setValue("autoPlay", $("#autoPlay").prop("checked")); GM_setValue("acTimer", $("#acTimer").prop("checked")); $(styleElement).remove(); location.reload(); }); // 关闭 $("#ACwingBetter_setting_menu .btn-close").click(function () { $("#ACwingBetter_setting_menu").remove(); $(".ACBetter_setting").attr("disabled", false); $(".ACBetter_setting").css("background-color", "#56aa56"); $(".ACBetter_setting").css("color", "white"); $(".ACBetter_setting").css("cursor", "pointer"); $(styleElement).remove(); }) }); }); // html2md转换/处理规则 let turndownService = new TurndownService(); turndownService.keep(['del']); // 丢弃 turndownService.addRule('remove-by-class', { filter: function (node) { return node.classList.contains('html2md-panel') || node.classList.contains('html2mdButton'); }, replacement: function (content, node) { return ""; } }); turndownService.addRule('remove-script', { filter: function (node, options) { return node.tagName.toLowerCase() == "script" && node.type.startsWith("math/tex"); }, replacement: function (content, node) { return ""; } }); // code block turndownService.addRule('pre', { filter: 'pre', replacement: function (content, node) { let t = $(node).attr("class").split(/\s+/).slice(-1); if (t == "hljs") t = ""; return "```" + t + "\n" + content.trim() + "\n```"; } }); // inline math turndownService.addRule('inline-math', { filter: function (node, options) { return node.tagName.toLowerCase() == "span" && node.className == "MathJax"; }, replacement: function (content, node) { return "$" + $(node).next().text() + "$"; } }); // block math turndownService.addRule('block-math', { filter: function (node, options) { return node.tagName.toLowerCase() == "div" && node.className == "MathJax_Display"; }, replacement: function (content, node) { return "\n$$\n" + $(node).next().text() + "\n$$\n"; } }); // 按钮面板 function addButtonPanel(parent, suffix, type) { let htmlString = `
`; if (type === "this_level") { $(parent).before(htmlString); } else if (type === "child_level") { $(parent).prepend(htmlString); } } function addButtonWithHTML2MD(parent, suffix, type) { $(document).on("click", ".html2md-view" + suffix, function () { var target, removedChildren = $(); if (type === "this_level") { target = $(".html2md-view" + suffix).parent().next().get(0); } else if (type === "child_level") { target = $(".html2md-view" + suffix).parent().parent().get(0); removedChildren = $(".html2md-view" + suffix).parent().parent().children(':first').detach(); } if (target.viewmd) { target.viewmd = false; $(this).text("MarkDown视图"); $(this).removeClass("mdViewed"); $(target).html(target.original_html); } else { target.viewmd = true; if (!target.original_html) { target.original_html = $(target).html(); } if (!target.markdown) { target.markdown = turndownService.turndown($(target).html()); } $(this).text("原始内容"); $(this).addClass("mdViewed"); $(target).html(`${target.markdown}`); } // 恢复删除的元素 if (removedChildren) $(target).prepend(removedChildren); }); } function addButtonWithCopy(parent, suffix, type) { $(document).on("click", ".html2md-cb" + suffix, function () { let target, removedChildren, text; if (type === "this_level") { target = $(".html2md-cb" + suffix).parent().next().eq(0).clone(); } else if (type === "child_level") { target = $(".html2md-cb" + suffix).parent().parent().eq(0).clone(); $(target).children(':first').remove(); } if ($(target).find('.mdViewContent').length <= 0) { text = turndownService.turndown($(target).html()); } else { text = $(target).find('.mdViewContent').text(); } GM_setClipboard(text); $(this).addClass("copied"); $(this).text("Copied"); // 更新复制按钮文本 setTimeout(() => { $(this).removeClass("copied"); $(this).text("Copy"); }, 2000); $(target).remove(); }); } // 代码块复制按钮 function codeCopy() { $('.hljs code').each(function () { let codeBlock = $(this); let id = "_" + getRandomNumber(8); let beforeButton = $(' `); // 页面路径标识 const PAGE_IDENTIFIER = window.location.href; // 计数器 let counter = 0; // 获取数据 function getListData() { let data = GM_getValue("cookieData"); if (!data) { data = {}; } else { data = JSON.parse(data); } if (!data[PAGE_IDENTIFIER]) { data[PAGE_IDENTIFIER] = []; } return data[PAGE_IDENTIFIER]; } // 保存数据 function saveListData(data) { let cookieData = GM_getValue("cookieData"); if (cookieData) { cookieData = JSON.parse(cookieData); } else { cookieData = {}; } cookieData[PAGE_IDENTIFIER] = data; GM_setValue("cookieData", JSON.stringify(cookieData)); } // 创建新的li元素 function createListItemElement(text) { const li = $("
  • "); const radio = $("").appendTo(li); radio.attr("id", counter++); const label = $("").text(text).attr("for", radio.attr("id")).appendTo(li); li.on("contextmenu", (event) => { event.preventDefault(); const menu = $("#player_bar_menu"); menu.css({ display: "block", left: event.pageX, top: event.pageY }); const deleteItem = $("#player_bar_menu_delete"); const editItem = $("#player_bar_menu_edit"); function onDelete() { deleteItem.off("click", onDelete); const list = $("#player_bar_ul"); const index = Array.from(list.children()).indexOf(li.get(0)); const data = getListData(); data.splice(index, 1); saveListData(data); li.remove(); menu.css({ display: "none" }); } function onEdit() { editItem.off("click", onEdit); const list = $("#player_bar_ul"); const index = Array.from(list.children()).indexOf(li.get(0)); const data = getListData(); label.text(data[index].text); const text = prompt("请输入修改后的内容", label.text()); if (text !== undefined && text !== null) { data[index].text = text.trim(); saveListData(data); } renderList(); menu.css({ display: "none" }); } deleteItem.on("click", onDelete); editItem.on("click", onEdit); $(document).on("click", (event) => { if (!menu.get(0).contains(event.target)) { menu.css({ display: "none" }); deleteItem.off("click", onDelete); editItem.off("click", onEdit); } }); }); return li; } // 渲染列表 function renderList() { const listContainer = $("#player_bar_list"); const list = $("#player_bar_ul"); list.empty(); const data = getListData(); data.forEach((item) => { list.append(createListItemElement(item.text)); }); } // 新增列表项 function addNewItem() { const input = $("#player_bar_list_add_input"); const text = input.val().trim(); if (text === "") { alert("请输入内容"); return; } const data = getListData(); data.push({ text: text, time: player_bar_video.currentTime }); saveListData(data); const list = $("#player_bar_ul"); list.append(createListItemElement(text)); input.val(""); } // 为添加按钮添加事件处理程序 const player_bar_add_button = $("#player_bar_list_add_new_item_btn"); player_bar_add_button.on("click", () => { addNewItem(); player_bar_add_button.addClass('added'); player_bar_add_button.text("Added"); setTimeout(() => { player_bar_add_button.removeClass('added'); player_bar_add_button.text("Add"); }, 2000); }); // 渲染列表 renderList(); // 跳转按钮 const click_player_bar_go = $("#player_bar_go"); click_player_bar_go.on("click", () => { const selected = $('input[name="player_bar_ul"]:checked'); if (selected.length) { const data = getListData(); const index = selected.parent().index(); player_bar_video.currentTime = data[index].time; click_player_bar_go.addClass('gone'); click_player_bar_go.text("Gone"); setTimeout(() => { click_player_bar_go.removeClass('gone'); click_player_bar_go.text("Go!"); }, 2000); } else { alert("请选择一项"); } }); // 创建自定义菜单 const menu = $(""); menu.html(`
    修改
    删除
    `); $("body").append(menu); } function formatTime(time) { var seconds = Math.floor((time / 1000) % 60); var minutes = Math.floor((time / (1000 * 60)) % 60); var hours = Math.floor((time / (1000 * 60 * 60)) % 24); var days = Math.floor(time / (1000 * 60 * 60 * 24)); var timeString = ''; if (days > 0) { timeString += days + '天'; } if (hours > 0) { timeString += hours + '小时'; } if (minutes > 0) { timeString += minutes + '分钟'; } if (seconds > 0) { timeString += seconds + '秒'; } return timeString; } // AC计时器 function acTiming() { var startTime = new Date(); var timer = setInterval(function () { var status = $('#submit-code-status-value-id').text().trim(); if (status === 'Accepted') { clearInterval(timer); var endTime = new Date(); var totalTime = endTime - startTime; var timeString = formatTime(totalTime); $('#submit-code-status-value-id').after('
    耗时:' + timeString + ' 要重新开始计时请刷新页面
    '); } }, 500); } $(document).ready(function () { if (acTimer && window.location.href.includes("/problem/content/")) acTiming(); // 让某些链接在新窗口打开 var regExps = [ /常用代码模板/, /example/, /test/ ]; var aTags = document.getElementsByTagName('a'); for (var i = 0; i < aTags.length; i++) { for (var j = 0; j < regExps.length; j++) { if (regExps[j].test(aTags[i].textContent)) { aTags[i].setAttribute('target', '_blank'); break; } } } // 自动恢复进度条 (function checkAndPlay() { if ($('.play-jump').length > 0) { $('.play-jump').click(); if (GM_getValue("autoPlay") === true) { let player_bar_video = document.querySelector('video'); if (!player_bar_video.paused) player_bar_video.pause(); } } else { setTimeout(checkAndPlay, 500); } })(); // 调整视频高度 $('.prism-player').height($('.prism-player').width() / 1.7); // 添加按钮 addConversionButton(); // 移除广告元素 let ADidADList = ["1024-activity", "test"]; ADtraverseDom(document.body); function ADtraverseDom(node) { if (node.nodeType === Node.ELEMENT_NODE && ADidADList.includes(node.id)) { node.parentNode.removeChild(node); } else { for (let i = 0; i < node.childNodes.length; i++) { ADtraverseDom(node.childNodes[i]); } } } // 修改打卡页代码框默认高度 var element = document.getElementById("martor-content"); if (element) { var style = window.getComputedStyle(element); element.style.height = "55vh"; } var player_bar_video = document.querySelector('video'); if (player_bar_video != null) addPlayerBar(player_bar_video); });