AcWing Better!

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

Od 14.08.2023.. Pogledajte najnovija verzija.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         AcWing Better!
// @version      3.25
// @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      greatest.deepsurf.us
// @run-at       document-end
// @require      https://cdn.bootcdn.net/ajax/libs/turndown/7.1.1/turndown.min.js
// @license      MIT
// @namespace    https://greatest.deepsurf.us/users/747162
// ==/UserScript==

// 状态与初始化
const getGMValue = (key, defaultValue) => {
    const value = GM_getValue(key);
    if (value === undefined) {
        GM_setValue(key, defaultValue);
        return defaultValue;
    }
    return value;
};

const bottomBar = getGMValue("bottomBar", true);
const bingWallpaper = getGMValue("bingWallpaper", true);
const widthAdjustment = getGMValue("widthAdjustment", true);
const autoPlay = getGMValue("autoPlay", true);

// 样式
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#update_panel {
        position: fixed;
        top: 50%;
        left: 50%;
        width: 240px;
        transform: translate(-50%, -50%);
        background-color: #fdfdfd;
        border: 1px solid #00aeeccc;
        border-radius: 5px;
        box-shadow: 2px 2px 3px 1px #0000004d;
        padding: 10px 20px 20px 20px;
        color: #444242;
        background-color: #ecf0ff;
        border: 6px solid #ffffff;
        border-radius: 16px;
    }
    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;
    }
    /*设置面板*/
    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);
    }
`);

// 更新检查
(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://greatest.deepsurf.us/zh-CN/scripts/464981.json",
        timeout: 10 * 1e3,
        onload: function (response) {
            const scriptData = JSON.parse(response.responseText);
            if (scriptData.name === GM_info.script.name && compareVersions(scriptData.version, GM_info.script.version) === 1) {
                $("body").append(`
					<div id='update_panel'>
						<h3>${GM_info.script.name}有新版本!</h3>
						<hr>
						<div class='update_panel_menu'>
                            <span class ='tip'>版本信息:${GM_info.script.version} → ${scriptData.version}</span>
						</div>
						<br>
						<button id='updating'><a target="_blank" href="${scriptData.url}">更新</a></button>
					</div>
				`);
            }
        }
    });
})();

// 防抖函数
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 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(
        "<button class='html2mdButton ACBetter_setting'>AcWingBetter设置</button>"
    );
});

$(document).ready(function () {
    $(".ACBetter_setting").click(function () {
        $(".ACBetter_setting").attr("disabled", true);
        $(".ACBetter_setting").css("background-color", "#e6e6e6");
        $(".ACBetter_setting").css("color", "#727378");
        $(".ACBetter_setting").css("cursor", "not-allowed");
        $("body").append(`
            <div class='checkbox-con' id='ACwingBetter_setting_menu'>
                <div class="tool-box">
                    <button class="btn-close">×</button>
                </div>
                <h3>AcWingBetter设置</h3>
                <hr>
                <div class='ACBetter_setting_list'>
                    <input type="checkbox" id="bottomBar" name="bottomBar" checked>
                    <label for="bottomBar">美化底栏</label>
                </div>
                <div class='ACBetter_setting_list'>
                    <input type="checkbox" id="bingWallpaper" name="bingWallpaper" checked>
                    <label for="bingWallpaper">Bing每日壁纸</label>
                </div>
                <div class='ACBetter_setting_list'>
                    <input type="checkbox" id="widthAdjustment" name="widthAdjustment" checked>
                    <label for="widthAdjustment">页面宽屏</label>
                </div>
                <div class='ACBetter_setting_list'>
                    <input type="checkbox" id="autoPlay" name="autoPlay" checked>
                    <label for="autoPlay">不自动播放视频</label>
                </div>
                <br>
                <button id='save'>保存</button>
            </div>
        `);
        $("#save").click(function () {
            GM_setValue("bottomBar", $("#bottomBar").prop("checked"));
            GM_setValue("bingWallpaper", $("#bingWallpaper").prop("checked"));
            GM_setValue("widthAdjustment", $("#widthAdjustment").prop("checked"));
            GM_setValue("autoPlay", $("#autoPlay").prop("checked"));
            location.reload();
        });
        $("#bottomBar").prop("checked", GM_getValue("bottomBar"));
        $("#bingWallpaper").prop("checked", GM_getValue("bingWallpaper"));
        $("#widthAdjustment").prop("checked", GM_getValue("widthAdjustment"));
        $("#autoPlay").prop("checked", GM_getValue("autoPlay"));
        // 关闭
        $("#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");
        })
    });
});

// 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 = `<div class='html2md-panel'>
    <button class='html2mdButton html2md-view${suffix}'>MarkDown视图</button>
    <button class='html2mdButton html2md-cb${suffix}'>Copy</button>
  </div>`;
    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(`<span class="mdViewContent" oninput="$(this).parent().get(0).markdown=this.value;" style="width:auto; height:auto;">${target.markdown}</span>`);
        }
        // 恢复删除的元素
        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 = $('<button>').text("Copy").addClass(`html2mdButton copy-button${id}`);
        let wrapperDiv = $('<div>').addClass('copy-div');
        $(wrapperDiv).append(beforeButton);
        $(wrapperDiv).css({
            display: "flex",
            justifyContent: "flex-end"
        });
        codeBlock.parent().before(wrapperDiv);

        $(document).on("click", `.copy-button${id}`, debounce(function () {
            GM_setClipboard(codeBlock.text().replace(/\n+$/, ''));
            // 更新复制按钮文本
            var self = this;
            $(self).addClass('copied');
            $(self).text("Copied");
            var self = this;
            setTimeout(function () {
                $(self).removeClass('copied');
                $(self).text("Copy");
            }, 2000);
        }));
    });
}

function addConversionButton() {
    // 添加按钮到content部分
    $('div[data-field-name="content"]').each(function () {
        let id = "_question-oi-bd_" + getRandomNumber(8);
        addButtonPanel(this, id, "this_level");
        addButtonWithHTML2MD(this, id, "this_level");
        addButtonWithCopy(this, id, "this_level");
    });

    // 为代码块添加复制按钮
    codeCopy();
};

// 播放器添加节点标签功能
function addPlayerBar(player_bar_video) {
    const player = $(".prism-player");
    const player_bar = $("<div class='player_bar'></div>").insertAfter(player);

    const player_bar_list = $("<div class='player_bar_list' id='player_bar_list'></div>").appendTo(player_bar);
    const player_bar_ul = $("<ul class='player_bar_ul' id='player_bar_ul'></ul>").appendTo(player_bar_list);

    const player_bar_go = $("<div class='player_bar_go' id='player_bar_go'>Go!</div>").appendTo(player_bar);

    const player_bar_list_add_div = $("<div class='player_bar_list_add_div'></div>").insertAfter(player_bar);
    const player_bar_list_add_input = $("<input class='player_bar_list_add_input' type='text' id='player_bar_list_add_input' placeholder='在这里输入备注内容,点击Add添加一个时间点标记;选中一个标记,点击Go跳转;右键标记,修改或删除'></input>").appendTo(player_bar_list_add_div);
    const player_bar_list_add_button = $("<button class='player_bar_list_add_button' id='player_bar_list_add_new_item_btn'>Add</button>").appendTo(player_bar_list_add_div);

    // 页面路径标识
    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 = $("<li></li>");
        const radio = $("<input type='radio' name='player_bar_ul'></input>").appendTo(li);
        radio.attr("id", counter++);
        const label = $("<label class='player_bar_ul_li_text'></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 = $("<div id='player_bar_menu' style='display: none;'></div>");
    menu.html(`
        <div id='player_bar_menu_edit'>修改</div>
        <div id='player_bar_menu_delete'>删除</div>
    `);
    $("body").append(menu);
}

$(document).ready(function () {
    // 让某些链接在新窗口打开
    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);
});