U2实时预览BBCODE

实时预览BBCODE

目前为 2022-04-30 提交的版本。查看 最新版本

// ==UserScript==
// @name         U2实时预览BBCODE
// @namespace    https://u2.dmhy.org/
// @version      0.4.1
// @description  实时预览BBCODE
// @author       kysdm
// @grant        none
// @match        *://u2.dmhy.org/*
// @exclude      *://u2.dmhy.org/attachment.php*
// @exclude      *://u2.dmhy.org/shoutbox.php*
// @icon         https://u2.dmhy.org/favicon.ico
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js
// @license      Apache-2.0
// ==/UserScript==

/*
本脚本基于 Bamboo Green 界面风格进行修改
/*

/*
GreasyFork 地址
    https://greasyfork.org/zh-CN/scripts/426268-u2%E5%AE%9E%E6%97%B6%E9%A2%84%E8%A7%88bbcode
*/

/*
更新日志
    https://github.com/kysdm/u2_share/commits/main/u2share_bbcode.user.js
*/

/*
无法显示的 Tag
    由U2自带上传工具上传的文件
    Flash 有关的 Tag <u2好像本来就不支持>
    我不知道的特殊操作
*/

/*
与U2娘显示不同的标签 (非标准操作)
    U2允许未封闭标签,此脚本不接受此操作。
*/

'use strict';

// 声明全局变量
var lang = new lang_init($('#locale_selection').val());;
// CSS
$('body').append(`<style type="text/css">td.smile-icon { padding: 3px !important; }</style>`);

// 现存BBCODE元素
(async () => {
    if ($('.bbcode').length === 0) return;  // 判断页面是否存在 bbcode 输入框
    new init();
    const url = location.href.match(/u2\.dmhy\.org\/(upload|forums|comment|contactstaff|sendmessage)\.php/i) || ['', ''];
    await syncScroll('#bbcodejs_tbody', url[1], '.bbcode', '#bbcode2')
    if (url[1] === 'upload') { await autoSaveUpload(); } else { await autoSaveMessage('#bbcodejs_tbody', '.bbcode', '#qr', url[1], '#compose'); }

    $('.bbcode').parents("tr:eq(1)").after('<tr><td class="rowhead nowrap" valign="top" style="padding: 3px" align="right">' + lang['preview']
        + '</td><td class="rowfollow"><table width="100%" cellspacing="0" cellpadding="5" border="0" ><tbody><tr><td  align="left" colspan="2">'
        + '<div id="bbcode2" style="min-height: 25px; max-height: ' + ($('.bbcode').height() + 30) + 'px; overflow-x: auto ; overflow-y: auto; white-space: pre-wrap;">'
        + '<div class="child">' + bbcode2html($('.bbcode').val()) + '</div></div></td></tr></tbody></table></td>');

    // https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
    let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
    let element = document.querySelector('.bbcode');
    var height_now, height_last;
    var observer = new MutationObserver((mutations) => {
        mutations.forEach(function (mutation) {
            if (mutation.type == "attributes") {
                height_now = Number(mutation.target.style.height.replace('px', '')) + 30;
                if (height_last === height_now) { return } else { height_last = height_now; };
                $("#bbcode2").css("max-height", height_now + "px");
            };
        })
    });
    observer.observe(element, {
        attributes: true,
        attributeFilter: ['style']
    });

    $('.bbcode').bind('input propertychange', async function updateValue() {
        let html = bbcode2html($(this).val());
        $('#bbcode2').children('.child').html(html);
    });

    $('.codebuttons').click(async function updateValue() {
        let html = bbcode2html($('.bbcode').val());
        $('#bbcode2').children('.child').html(html);
    });

    $("td.embedded.smile-icon a").click(async function updateValue() {
        await sleep(0);
        let html = bbcode2html($('.bbcode').val());
        $('#bbcode2').children('.child').html(html);
    });

    if (/u2\.dmhy\.org\/upload\.php/i.test(location.href)) {

        // 添加中括号
        function add_brackets(txt) { if (txt === '') { return ''; } else { return '[' + txt + ']'; } };

        // 检查重叠的中括号
        function check_title(txt) {
            if (/\[{2,}|\]{2,}/g.test(txt)) { return '<font color="red">' + txt + '</font>'; } else { return txt; }
        };

        var main_title = '<font color="red"><b>' + lang['select_type'] + '</b></font>';

        function add_main_title() {
            var type_id = $('#browsecat').val();
            if (type_id === '0') {
                // console.log('请选择分类...');
                main_title = '<font color="red"><b>' + lang['select_type'] + '</b></font>';
            } else if (['9', '411', '413', '12', '13', '14', '15', '16', '17', '410', '412'].indexOf(type_id) !== -1) {
                // console.log('分类ID是: ' + type_id + ' anime');
                main_title = '<b>'
                    + add_brackets($('#anime_chinese-input').val())
                    + add_brackets($('#anime_english-input').val())
                    + add_brackets($('#anime_original-input').val())
                    + add_brackets($('#anime_source-input').val())
                    + add_brackets($('#anime_resolution-input').val())
                    + add_brackets($('#anime_episode-input').val())
                    + add_brackets($('#anime_container-input').val())
                    + add_brackets($('#anime_extra-input').val())
                    + '</b>';
            } else if (['21', '22', '23'].indexOf(type_id) !== -1) {
                // console.log('分类ID是: ' + type_id + ' manga');
                main_title = '<b>'
                    + add_brackets($('#manga_title-input').val())
                    + add_brackets($('#manga_author-input').val())
                    + add_brackets($('#manga_volume-input').val())
                    + add_brackets($('#manga_ended').find("select").val())
                    + add_brackets($('#manga_publisher-input').val())
                    + add_brackets($('#manga_remark-input').val())
                    + '</b>';
            } else if (type_id === '30') {
                // console.log('分类ID是: ' + type_id + ' music');
                var prefix_1 = $('#music_prefix').find("select").val();
                var prefix_2 = $('#music_collection').find("select").val();
                if (['EAC', 'XLD'].indexOf(prefix_1) !== -1) { var music_quality = false; }
                else if (['Hi-Res', 'Web'].indexOf(prefix_1) !== -1) { var music_quality = true; };
                switch (prefix_2) {
                    case "0": // 单张
                        main_title = '<b>'
                            + add_brackets(prefix_1)
                            + add_brackets($('#music_date-input').val())
                            + add_brackets($('#music_category-input').val())
                            + add_brackets($('#music_artist-input').val())
                            + add_brackets($('#music_title-input').val())
                            + add_brackets($('#music_serial_number-input').val())
                            + add_brackets((() => { if (music_quality) { return $('#music_quality-input').val(); } else { return ''; } })())
                            + add_brackets($('#music_format-input').val())
                            + '</b>';
                        break;
                    case "1": // 合集
                        main_title = '<b>'
                            + add_brackets(prefix_1)
                            + add_brackets('合集')
                            + add_brackets($('#music_category-input').val())
                            + add_brackets($('#music_title-input').val())
                            + add_brackets($('#music_quantity-input').val())
                            + add_brackets((() => { if (music_quality) { return $('#music_quality-input').val(); } else { return ''; } })())
                            + '</b>';
                        break;
                }
            } else if (type_id === '40') {
                // console.log('分类ID是: ' + type_id + ' other');
                main_title = '<b>' + $('#other_title-input').val() + '</b>';
            } else {
                // console.log('分类ID是: ' + type_id);
            }
            $('#checktitle').html(check_title(main_title));
        }

        $("#browsecat").change(() => { new add_main_title; })
        $(".torrent-info-input").bind('input propertychange', () => { new add_main_title; });
        $('#other_title').after('<tr><td class="rowhead nowrap" valign="top" align="right">' + lang['main_title'] + '</td>'
            + '<td id="checktitle" class="rowfollow" valign="top" align="left" valign="middle">' + main_title + '</td></tr>'
        );
    };


    function init() {
        var h1 = $('.codebuttons').eq(6).parent().html();
        var h2 = $('.codebuttons').eq(7).parent().html();
        var h3 = $('.codebuttons').eq(8).parent().html();
        $('.codebuttons').eq(8).parent().remove();
        $('.codebuttons').eq(7).parent().remove();
        $('.codebuttons').eq(6).parent().remove();

        $('.codebuttons').eq(2).parent().after('<td class="embedded"><input class="codebuttons" style="text-decoration: line-through;'
            + 'font-size:11px;margin-right:3px" type="button" value="S" onclick="onEditorActionS(\'descr\', \'EDITOR_S\')">');

        $('.codebuttons').eq(5).parent()
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="CODE" onclick="onEditorActionS(\'descr\', \'EDITOR_CODE\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="PRE" onclick="onEditorActionS(\'descr\', \'EDITOR_PRE\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="LIST" onclick="onEditorActionS(\'descr\', \'EDITOR_LIST\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="RT*" onclick="onEditorActionS(\'descr\', \'EDITOR_RT\')">');

        // $('.codebuttons').eq(10).attr("onclick", "onEditorActionS('descr','EDITOR_QUOTE')");

        $('.codebuttons').eq(10).parent()
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="SPOILER*" onclick="onEditorActionS(\'descr\', \'EDITOR_SPOILER+\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="SPOILER" onclick="onEditorActionS(\'descr\', \'EDITOR_SPOILER\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="MEDIAINFO" onclick="onEditorActionS(\'descr\', \'EDITOR_MEDIAINFO\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="INFO" onclick="onEditorActionS(\'descr\', \'EDITOR_INFO\')">')
            .after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="QUOTE*" onclick="onEditorActionS(\'descr\', \'EDITOR_QUOTE+\')">');

        $('.codebuttons').eq(4)
            .attr("onclick", "onEditorActionS('descr','EDITOR_URL')")
            .parent().after('<td class="embedded"><input class="codebuttons" style="'
                + 'font-size:11px;margin-right:3px" type="button" value="URL*" onclick="onEditorActionS(\'descr\', \'EDITOR_URL+\')">'
            );

        $('.codebuttons').parents('table').eq(0).after('<div id="bbcodejs_tbody" style="position:relative; margin-top: 4px"></div>');

        $('#bbcodejs_tbody').append('<div id="bbcodejs_select" style="position: absolute; margin-top:2px; margin-bottom:2px; float: left;">' + h1 + h2 + h3 + '</div>');

        const margin = $('.codebuttons').parents('tbody').eq(0).width() - $("#bbcodejs_select").width() - 2.6;
        $("#bbcodejs_select").css("margin-left", margin + "px");

        $('body').append(
            '<script type="text/javascript">\n\
    function onEditorActionS(textAreaId, action, param) {\n\
        var textArea = document.querySelector(".bbcode");\n\
        var selStart = textArea.selectionStart;\n\
        var selEnd = textArea.selectionEnd;\n\
        var selectionText, url;\n\
        if (selStart === null || selEnd === null) {\n\
            selStart = selEnd = textArea.value.length;\n\
        }\n\
        switch (action) {\n\
            case "EDITOR_S": {\n\
                addTag(textArea, "s", null, "", true);\n\
                break;\n\
            }\n\
            case "EDITOR_INFO": {\n\
                addTag(textArea, "info", null, "", true);\n\
                break;\n\
            }\n\
            case "EDITOR_MEDIAINFO": {\n\
                addTag(textArea, "mediainfo", null, "", true);\n\
                break;\n\
            }\n\
            case "EDITOR_PRE": {\n\
                addTag(textArea, "pre", null, "", true);\n\
                break;\n\
            }\n\
            case "EDITOR_CODE": {\n\
                addTag(textArea, "code", null, "", true);\n\
                break;\n\
            }\n\
            case "EDITOR_RT": {\n\
                if (selStart !== selEnd) {\n\
                    var title = window.prompt("'+ lang['rt_text'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        break;\n\
                    }\n\
                    selectionText = textArea.value.substring(selStart, selEnd);\n\
                    console.log(selectionText);\n\
                    addTag(textArea, "rt", title, selectionText, false);\n\
                    // break;\n\
                } else {\n\
                    text = window.prompt("'+ lang['main_body'] + '");\n\
                    if (text === null || text.length === 0) {\n\
                        break;\n\
                    }\n\
                    var title = window.prompt("'+ lang['rt_text'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        break;\n\
                    }\n\
                    addTag(textArea, "rt", title, text, false);\n\
                }\n\
                break;\n\
            }\n\
            case "EDITOR_QUOTE+": {\n\
                if (selStart !== selEnd) {\n\
                    var title = window.prompt("' + lang['main_body_prefix'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        title = "";\n\
                    }\n\
                    selectionText = textArea.value.substring(selStart, selEnd);\n\
                    // addTag(textArea, "quote", null, "", true);\n\
                    addTag(textArea, "quote", title, selectionText, false);\n\
                } else {\n\
                    text = window.prompt("' + lang['main_body'] + '");\n\
                    if (text === null || text.length === 0) {\n\
                        break;\n\
                    }\n\
                    var title = window.prompt("' + lang['main_body_prefix'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        title = "";\n\
                    }\n\
                    addTag(textArea, "quote", title, text, false);\n\
                }\n\
                break;\n\
            }\n\
            case "EDITOR_URL+": {\n\
                if (selStart !== selEnd) {\n\
                    selectionText = textArea.value.substring(selStart, selEnd); // 选中的文字\n\
                    if (/^(?:https?|ftp|gopher|news|telnet|mms|rtsp):\\/\\/((?!&lt;|&gt;|\\s|"|>|\'|<|\\(|\\)|\\[|\\]).)+/gi.test(selectionText)) {\n\
                        // 选中的是URL时\n\
                        var title = window.prompt("' + lang['url_name'] + '");\n\
                        if (title === null || title.length === 0) {\n\
                            // selectionText = textArea.value.substring(selStart, selEnd);\n\
                            // addTag(textArea, "url", null, "", true);\n\
                            break;\n\
                        } else {\n\
                            addTag(textArea, "url", selectionText, title, false);\n\
                        }\n\
                    } else {\n\
                        // 选中的是文字时\n\
                        var url_link = window.prompt("' + lang['url_link'] + '");\n\
                        if (url_link === null || url_link.length === 0) {\n\
                            // selectionText = textArea.value.substring(selStart, selEnd);\n\
                            // addTag(textArea, "url", null, "", true);\n\
                            break;\n\
                        } else {\n\
                            addTag(textArea, "url", url_link, selectionText, false);\n\
                        }\n\
                    }\n\
                } else {\n\
                    text = window.prompt("' + lang['url_link'] + '");\n\
                    if (text === null || text.length === 0) {\n\
                        break;\n\
                    }\n\
                    var title = window.prompt("' + lang['url_name'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        title = "";\n\
                        addTag(textArea, "url", null, text, false);\n\
                        break;\n\
                    }\n\
                    addTag(textArea, "url", text, title, false);\n\
                }\n\
                break;\n\
            }\n\
            case "EDITOR_SPOILER+": {\n\
                if (selStart !== selEnd) {\n\
                    var title = window.prompt("' + lang['main_body_prefix'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        addTag(textArea, "spoiler", null, "", true);\n\
                        break;\n\
                    }\n\
                    selectionText = textArea.value.substring(selStart, selEnd);\n\
                    // addTag(textArea, "spoiler", null, "", true);\n\
                    addTag(textArea, "spoiler", title, selectionText, false);\n\
                } else {\n\
                    text = window.prompt("' + lang['main_body'] + '");\n\
                    if (text === null || text.length === 0) {\n\
                        break;\n\
                    }\n\
                    var title = window.prompt("' + lang['main_body_prefix'] + '");\n\
                    if (title === null || title.length === 0) {\n\
                        title = "";\n\
                        addTag(textArea, "spoiler", null, text, false);\n\
                        break;\n\
                    }\n\
                    addTag(textArea, "spoiler", title, text, false);\n\
                }\n\
                break;\n\
            }\n\
            case "EDITOR_SPOILER": {\n\
                addTag(textArea, "spoiler", null, "", true);\n\
                break;\n\
            }\n\
            case "EDITOR_QUOTE": {\n\
                if (selStart !== selEnd) {\n\
                    addTag(textArea, "quote", null, "", true);\n\
                } else {\n\
                    text = window.prompt("' + lang['main_body'] + '");\n\
                    if (text === null || text.length === 0) {\n\
                        break;\n\
                    }\n\
                    // var title = window.prompt("' + lang['main_body_prefix'] + '");\n\
                    // if (title === null || title.length === 0) {\n\
                    //     title = "";\n\
                    // }\n\
                    addTag(textArea, "quote", null, text, false);\n\
                }\n\
                break;\n\
            }\n\
            case "EDITOR_URL": {\n\
                if (selStart !== selEnd) {\n\
                    addTag(textArea, "url", null, "", true);\n\
                } else {\n\
                    text = window.prompt("' + lang['url_link'] + '");\n\
                    if (text === null || text.length === 0) {\n\
                        break;\n\
                    }\n\
                    addTag(textArea, "url", null, text, false);\n\
                }\n\
                break;\n\
            }\n\
            case "EDITOR_LIST": {\n\
                if (selStart !== selEnd) {\n\
                    break;\n\
                }\n\
                addTag(textArea, "*", null, null, true);\n\
                break;\n\
            }\n\
        }\n\
        textArea.focus();\n\
    }</script>'
        );
    }
})();


async function sleep(interval) {
    return new Promise(resolve => {
        setTimeout(resolve, interval);
    })
};

function bbcode2html(bbcodestr) {
    const f_reg = new RegExp("^\"?\"?$|^(?:&quot;)?(?:&quot;)?$");

    var tempCode = new Array();
    var tempCodeCount = 0;

    function addTempCode(value) {
        tempCode[tempCodeCount] = value;
        let returnstr = "<tempCode_" + tempCodeCount + ">";
        tempCodeCount++;
        return returnstr;
    }

    const escape_reg = new RegExp("[&\"\'<>]", "g");
    bbcodestr = bbcodestr.replace(escape_reg, function (s, x) {
        switch (s) {
            case '&':
                return '&amp;';
            case '"':
                return '&quot;';
            case "'":
                return '&#039;';
            case '<':
                return '&lt;';
            case '>':
                return '&gt;';
            default:
                return s;
        }
    });

    bbcodestr = bbcodestr.replace(/\r\n/g, () => { return '<br>' });
    bbcodestr = bbcodestr.replace(/\n/g, () => { return '<br>' });
    bbcodestr = bbcodestr.replace(/\r/g, () => { return '<br>' });

    // info/code 标签
    const info_reg = new RegExp("\\[(mediainfo|info|code)\\](.+?)\\[\\/(\\1)\\]", "gis");
    bbcodestr = bbcodestr.replace(info_reg, function (s, x, y) {
        switch (x) {
            case 'info':
                return addTempCode('<fieldset class="codemain" style="background-color: transparent; word-break: break-all"><legend><b><span style="color: blue">'
                    + lang['info'] + '</span></b></legend>' + y + '</fieldset>');
            case 'mediainfo':
                return addTempCode('<fieldset class="codemain" style="background-color: transparent; word-break: break-all"><legend><b><span style="color: red">'
                    + lang['mediainfo'] + '</span></b></legend>' + y + '</fieldset>');
            case 'code':
                return addTempCode(`<br><div class="codetop">${lang['code']}</div><div class="codemain">${y}</div><br />`);
            default:
                return s;
        }
    });

    // 超链接 (绝对)
    bbcodestr = bbcodestr.replace(/\[url=((?:https?|ftp|gopher|news|telnet|mms|rtsp):\/\/((?!&lt;|&gt;|\s|"|>|'|<|\(|\)|\[|\]).)+)\](.+?)\[\/url\]/gis, function (s, x, y, z) {
        return addTempCode('<a class="faqlink" rel="nofollow noopener noreferer" href="' + x + '">' + z + '</a>');
    });

    bbcodestr = bbcodestr.replace(/\[url\]((?:https?|ftp|gopher|news|telnet|mms|rtsp):\/\/((?!&lt;|&gt;|\s|"|>|'|<|\(|\)|\[|\]).)+)\[\/url\]/gis, function (s, x) {
        return addTempCode('<a class="faqlink" rel="nofollow noopener noreferer" href="' + x + '">' + x + '</a>')
    });

    // 超链接 (相对)
    bbcodestr = bbcodestr.replace(/\[url=(((?!&lt;|&gt;|\s|"|>|'|<|\(|\)|\[|\]).)+)\](.+?)\[\/url\]/gis, function (s, x, y, z) {
        return addTempCode('<a class="faqlink" rel="nofollow noopener noreferer" href="' + x + '">' + z + '</a>');
    });

    bbcodestr = bbcodestr.replace(/\[url\](((?!&lt;|&gt;|\s|"|>|'|<|\(|\)|\[|\]).)+)\[\/url\]/gis, function (s, x) {
        return addTempCode('<a class="faqlink" rel="nofollow noopener noreferer" href="' + x + '">' + x + '</a>')
    });

    // 单个标签 不带参
    const o_reg = new RegExp("\\[(\\*|siteurl|site)\\]", "gi");
    bbcodestr = bbcodestr.replace(o_reg, function (s, x, y) {
        switch (x) {
            case '*':
                return '<img class="listicon listitem" src="pic/trans.gif" alt="list">';
            case 'site':
                return 'U2分享園@動漫花園';
            case 'siteurl':
                return 'https://u2.dmhy.org';
            default:
                return s;
        }
    });

    // 成对标签 带参
    const d_reg = new RegExp("\\[(rt|font)=([^\\]]+)\\](.*?)\\[(/\\1)\\]", "gis");
    while (d_reg.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(d_reg, function (s, w, x, y, z) {
            switch (w) {
                case 'rt':
                    if (f_reg.test(x)) {
                        return '[' + addTempCode('p3F#oW2@cEn_JHstp-&37DgD' + w) + '=' + x + ']'
                            + y + '[' + addTempCode('p3F#oW2@cEn_JHstp-&37DgD' + z) + ']'
                    }
                    else {
                        return addTempCode('<ruby>' + y + '<rp>(</rp><rt>' + x.replace(/^(?:&quot;)?(.*?)(?:&quot;)?$/, "$1") + '</rt><rp>)</rp></ruby>');
                    }
                case 'font':
                    if (f_reg.test(x)) {
                        return '[' + addTempCode('p3F#oW2@cEn_JHstp-&37DgD' + w) + '=' + x + ']'
                            + y + '[' + addTempCode('p3F#oW2@cEn_JHstp-&37DgD' + z) + ']';
                    }
                    else {
                        return '<span style="font-family: ' + x.replace(/^(?:&quot;)?(.*?)(?:&quot;)?$/, "$1") + '">' + y + '</span>';
                    }
                default:
                    return s;
            }
        })
    };

    // 成对标签 不带参
    const a_reg = new RegExp("\\[(pre|b|i|u|s)\\](.*?)\\[/(\\1)\\]", "gs");
    while (a_reg.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(a_reg, function (s, x, y, z) {
            switch (x) {
                case 'b':
                    return '<b>' + y + '</b>';
                case 'i':
                    return '<em>' + y + '</em>';
                case 'u':
                    return '<u>' + y + '</u>';
                case 's':
                    return '<s>' + y + '</s>';
                case 'pre':
                    return '<pre>' + y + '</pre>';
                default:
                    return s;
            }
        })
    };

    // 颜色
    const color_reg = new RegExp("\\[color=(?:&quot;)?([#0-9a-z]{1,15}|[a-z]+?)(?:&quot;)?\\](.*?)\\[/color\\]", "gis");
    while (color_reg.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(color_reg, function (s, x, y) {
            return '<span style="color: ' + x + '">' + y + '</span>';
        })
    };

    // 文字大小
    const size_reg = new RegExp("\\[size=(?:&quot;)?([1-7])(?:&quot;)?\\](.*?)\\[/size\\]", "gis");
    while (size_reg.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(size_reg, function (s, x, y) {
            return '<font size="' + x + '">' + y + '</font>';
        })
    };

    // 图片
    bbcodestr = bbcodestr.replace(/\[(img|imglnk)\]([^\]]+)\[\/(?:\1)\]/gi, function (s, x, y) {
        if (/^https?:\/\/((?!&lt;|&gt;|"|>|'|<|;|\(|\)|\[|\]).)+$/i.test(y)) {
            switch (x) {
                case 'img':
                    return addTempCode('<img alt="image" src="' + y + '" style="height: auto; width: auto; max-width: 100%;">');
                case 'imglnk':
                    return addTempCode('<a class="faqlink" rel="nofollow noopener noreferer" href="' + y + '"><img alt="image" src="'
                        + y + '" style="height: auto; width: auto; max-width: 100%;"></a>');
            }
        } else {
            return addTempCode(s);
        }
    });

    bbcodestr = bbcodestr.replace(/\[img=([^\]]+)\]/gi, function (s, x) {
        if (/^https?:\/\/((?!&lt;|&gt;|"|>|'|<|;|\(|\)|\[|\]).)+$/i.test(x)) {
            return addTempCode('<img alt="image" src="' + x + '" style="height: auto; width: auto; max-width: 100%;">');
        } else {
            return addTempCode(s);
        }
    });

    // 没有bbcode包裹的超链接
    bbcodestr = bbcodestr.replace(/((?:https?|ftp|gopher|news|telnet|mms|rtsp):\/\/((?!&lt;|&gt;|\s|"|>|'|<|\(|\)|\[|\]).)+)/gi, function (s, x) {
        return '<a class="faqlink" rel="nofollow noopener noreferer" href="' + s + '">' + s + '</a>';
    });

    // 引用
    const quote_reg1 = new RegExp("\\[quote\\](.*?)\\[/quote\\]", "gsi");
    while (quote_reg1.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(quote_reg1, function (s, x) {
            return '<fieldset><legend>' + lang['quote'] + '</legend>' + x + '</fieldset>';
        });
    };
    const quote_reg2 = new RegExp("\\[quote=([^\\[\\]]*)\\](.*?)\\[/quote\\]", "gsi");
    while (quote_reg2.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(quote_reg2, function (s, x, y) {
            if (f_reg.test(x)) {
                return '<fieldset><legend>' + lang['quote'] + '</legend>' + y + '</fieldset>';
            }
            else {
                return '<fieldset><legend>' + lang['quote'] + ': ' + x.replace(/^(?:&quot;)?(.*?)(?:&quot;)?$/, "$1") + '</legend>' + y + '</fieldset>';
            }
        });
    };

    // spoiler
    const spoiler_reg1 = new RegExp("\\[spoiler\\](.*?)\\[/spoiler\\]", "gsi");
    const spoiler_reg2 = new RegExp("\\[spoiler=([^\\]]+)\\](.*?)\\[/spoiler\\]", "gsi");
    while (spoiler_reg1.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(spoiler_reg1, function (s, x) {
            return '<table class="spoiler" width="100%"><tbody><tr><td class="colhead">'
                + lang['spoiler'] + '&nbsp;&nbsp;'
                + '<button class="spoiler-button-show" style="display: none;">' + lang['spoiler_button_1'] + '</button>'
                + '<button class="spoiler-button-hide">' + lang['spoiler_button_2'] + '</button>'
                + '</td></tr><tr><td><span class="spoiler-content" style="display: inline;">'
                + x + '</span></td></tr></tbody></table>';
        });
    };
    while (spoiler_reg2.test(bbcodestr)) {
        bbcodestr = bbcodestr.replace(spoiler_reg2, function (s, x, y) {
            if (f_reg.test(x)) {
                return '<table class="spoiler" width="100%"><tbody><tr><td class="colhead">'
                    + lang['spoiler'] + '&nbsp;&nbsp;'
                    + '<button class="spoiler-button-show" style="display: none;">' + lang['spoiler_button_1'] + '</button>'
                    + '<button class="spoiler-button-hide">' + lang['spoiler_button_2'] + '</button>'
                    + '</td></tr><tr><td><span class="spoiler-content" style="display: inline;">'
                    + y + '</span></td></tr></tbody></table>';
            }
            else {
                return '<table class="spoiler" width="100%"><tbody><tr><td class="colhead">'
                    + x.replace(/^(?:&quot;)?(.*?)(?:&quot;)?$/, "$1") + '&nbsp;&nbsp;'
                    + '<button class="spoiler-button-show" style="display: none;">' + lang['spoiler_button_1'] + '</button>'
                    + '<button class="spoiler-button-hide">' + lang['spoiler_button_2'] + '</button>'
                    + '</td></tr><tr><td><span class="spoiler-content" style="display: inline;">'
                    + y + '</span></td></tr></tbody></table>';
            }
        });
    };

    // 表情
    const em_reg = new RegExp("\\[(em[1-9][0-9]*)\\]", "gi");
    bbcodestr = bbcodestr.replace(em_reg, function (s, x) {
        switch (x) {
            case (x.match(/^em[1-9][0-9]*/i) || {}).input:
                return '<img src="pic/smilies/' + x.replace("em", "") + '.gif" alt="[' + x + ']">';
            default:
                return s;
        }
    })

    for (let i = 0, len = tempCode.length; i < len; i++) {
        // console.log(i + " : " + tempCode[i]);
        bbcodestr = bbcodestr.replace("<tempCode_" + i + ">", tempCode[i]);
    }

    bbcodestr = bbcodestr.replace(/p3F#oW2@cEn_JHstp-&37DgD/g, "");

    if (/(<br>)$/.test(bbcodestr)) { bbcodestr = bbcodestr + '<br>' };

    var htmlobj = $.parseHTML('<div>' + bbcodestr + '</div>');

    $(htmlobj).children('fieldset').children('fieldset').children('fieldset').children('fieldset').each(function () {
        $(this).html($(this).html().replace(/(^<legend>[^<]*?<\/legend>)(.*)/i, function (s, x, y) {
            return x + '<table class="spoiler" width="100%"><tbody>'
                + '<tr><td class="colhead">' + lang['auto_fold'] + '&nbsp;&nbsp;'
                + '<button class="spoiler-button-show" style="display: none;">' + lang['spoiler_button_1'] + '</button>'
                + '<button class="spoiler-button-hide" style="">' + lang['spoiler_button_2'] + '</button>'
                + '</td></tr><tr><td><span class="spoiler-content" style="display: inline;">'
                + y + '</span></td></tr></tbody></table>';
        }))
    });

    return $(htmlobj).html();
};


function lang_init(lang) {
    var lang_json = {
        "zh_CN": {
            "quote": "引用",
            "info": "发布信息",
            "mediainfo": "媒体信息",
            "code": "代码",
            "spoiler": "警告!下列文字很可能泄露剧情,请谨慎选择是否观看。",
            "spoiler_button_1": "我就是手贱",
            "spoiler_button_2": "我真是手贱",
            "main_title": "主标题",
            "rt_text": "请输入上标",
            "main_body": "请输入正文",
            "main_body_prefix": "请输入标题",
            "url_name": "请输入网址名称",
            "url_link": "请输入网址链接",
            "select_type": "请选择分类...",
            "preview": "预览",
            "auto_fold": "过深引用自动折叠"
        },
        "zh_TW": {
            "quote": "引用",
            "info": "發佈訊息",
            "mediainfo": "媒體訊息",
            "code": "代碼",
            "spoiler": "警告!下列文字很可能洩露劇情,請謹慎選擇是否觀看。",
            "spoiler_button_1": "我就是手賤",
            "spoiler_button_2": "我真是手賤",
            "main_title": "主標題",
            "rt_text": "請輸入上標",
            "main_body": "請輸入正文",
            "main_body_prefix": "請輸入標題",
            "url_name": "請輸入網址名稱",
            "url_link": "請輸入網址連結",
            "select_type": "請選擇分類...",
            "preview": "預覽",
            "auto_fold": "過深引用自動摺疊"
        },
        "zh_HK": {
            "quote": "引用",
            "info": "發佈訊息",
            "mediainfo": "媒體訊息",
            "code": "代碼",
            "spoiler": "警告!下列文字很可能洩露劇情,請謹慎選擇是否觀看。",
            "spoiler_button_1": "我就是手賤",
            "spoiler_button_2": "我真是手賤",
            "main_title": "主標題",
            "rt_text": "請輸入上標",
            "main_body": "請輸入正文",
            "main_body_prefix": "請輸入標題",
            "url_name": "請輸入網址名稱",
            "url_link": "請輸入網址鏈接",
            "select_type": "請選擇分類...",
            "preview": "預覽",
            "auto_fold": "過深引用自動摺疊"
        },
        "en_US": {
            "quote": "Quote",
            "info": "Infobox",
            "mediainfo": "Media Info",
            "code": "CODE",
            "spoiler": "Warning! This section contains spoiler!",
            "spoiler_button_1": "I agree to view this.",
            "spoiler_button_2": "Hide this.",
            "main_title": "Main Title",
            "rt_text": "Please enter superscript",
            "main_body": "Please enter the text",
            "main_body_prefix": "Please enter a title",
            "url_name": "Please enter the URL name",
            "url_link": "Please enter the URL link",
            "select_type": "Please select a type.",
            "preview": "Preview",
            "auto_fold": "Over quote auto fold"
        },
        "ru_RU": {
            "quote": "Цитата",
            "info": "Отправленные",
            "mediainfo": "Данные о Медиа",
            "code": "CODE",
            "spoiler": "Предупреждение! Данный раздел содержит СПОЙЛЕРЫ!",
            "spoiler_button_1": "I agree to view this.",
            "spoiler_button_2": "Hide this.",
            "main_title": "Основное название",
            "rt_text": "Пожалуйста, введите надстрочный индекс",
            "main_body": "Пожалуйста, введите текст",
            "main_body_prefix": "Пожалуйста, введите название",
            "url_name": "Пожалуйста, введите имя URL",
            "url_link": "Пожалуйста, введите URL-ссылку",
            "select_type": "выберите тип ...",
            "preview": "Предварительный просмотр",
            "auto_fold": "Автоматическое складывание для более глубоких ссылок"
        }
    };
    return lang_json[lang];
};


async function autoSaveUpload() {
    let db = localforage.createInstance({ name: "bbcodejs" });
    let num_global = 10;
    let num = 10; // 设置自动保存时间间隔
    let type = 'upload';

    $('#bbcodejs_tbody').append(`<span id="${type}_auto_save_on" style="margin-top:4px; display: none;">`
        + `<input id="${type}_switch" class="codebuttons" style="font-size:11px;margin-right:3px;" type="button" value="自动保存已开启">`
        + `<input id="${type}_clean" class="codebuttons" style="font-size:11px;margin-right:3px;" type="button" value="清空数据">`
        + `<span id="${type}_auto_save_text" style="display: none;">&nbsp;&nbsp;正在保存...</span></span>`
        + `<span id="${type}_auto_save_off" style="margin-top:4px; display: none;">`
        + `<input class="codebuttons" style="font-size:11px;margin-right:3px;" type="button" value="自动保存已关闭"></span>`
    );

    // 为自动保存按钮绑定事件
    $(`#${type}_auto_save_on`).click(async function (ev) {
        let button_id = $(ev.target).attr('id');
        switch (button_id) {
            case `${type}_switch`:
                $(this).hide(); // 隐藏按钮
                $(`#${type}_auto_save_off`).fadeIn(200); // 渐入按钮
                clearInterval($(`#${type}_auto_save_text`).attr('title')); // 清除setInterval函数
                await db.setItem(`${type}_autoSaveMessageSwitch`, false)
                console.log(`${type}-自动保存已关闭`);
                break;
            case `${type}_clean`:
                if (window.confirm("确定清空所有数据?")) {
                    await clean();
                    window.location.reload();
                };
                break;
        };
    });

    $(`#${type}_auto_save_off`).click(async function () {
        $(this).hide();
        $(`#${type}_auto_save_on`).fadeIn(200);
        $(`#${type}_auto_save_text`).attr("title", setInterval(autoSave, 1000));  // 设置setInterval函数
        await db.setItem(`${type}_autoSaveMessageSwitch`, true)
        console.log(`${type}-自动保存已开启`);
    });

    // 提交候选后 删除所有保存的记录 (如果要还原记录,直接返回上一页即可。)
    $("#qr").click(async function () {
        await clean();
        console.log(`${type}-提交上传请求`);
    });

    async function clean() {
        clearInterval($(`#${type}_auto_save_text`).attr('title')); // 清除setInterval函数
        await db.removeItem(`${type}_autoSaveMessageTime`);
        await db.removeItem(`${type}_autoSaveMessageBbcode`);
        await db.removeItem(`${type}_autoSaveMessageSmallDescr`);
        await db.removeItem(`${type}_autoSaveMessagePoster`);
        await db.removeItem(`${type}_autoSaveMessageAnidbUrl`);
        await db.removeItem(`${type}_autoSaveMessageInfo`);
        console.log(`${type}-已清空保存的记录`);
    }

    // 检测上次自动保存开关设定
    db.getItem(`${type}_autoSaveMessageSwitch`).then(async (value) => {
        if (value) {
            // 启用自动保存
            $(`#${type}_auto_save_on`).show();
            $(`#${type}_auto_save_off`).hide();
            $(`#${type}_auto_save_text`).attr("title", setInterval(autoSave, 1000)); // 设置setInterval函数
            console.log(`${type}-自动保存已开启`);
            // 检查输入框内是否已经存在字符串
            let _input_bool = true
            $("#compose input[id$='-input']").add('#browsecat').add('.bbcode').each(function () {
                let _input = $(this).val()
                if (_input !== "" && _input !== "0") { _input_bool = false; return; } // 把input和select一起做判断了 总没人在标题里单独打个0吧
            });
            // 当输入框是空白时 还原上次备份内容
            if (_input_bool) {
                await db.getItem(`${type}_autoSaveMessageSmallDescr`).then((value) => { $('[name="small_descr"]').val(value); })
                await db.getItem(`${type}_autoSaveMessagePoster`).then((value) => { $('[name="poster"]').val(value); });
                await db.getItem(`${type}_autoSaveMessageAnidbUrl`).then((value) => { $('[name="anidburl"]').val(value); });
                await db.getItem(`${type}_autoSaveMessageInfo`).then((value) => {
                    if (value === null) return;
                    $('#browsecat').val(value['category']);
                    $('#browsecat').change(); // 手动触发列表更改事件
                    $('#autocheck_placeholder').children().eq(0).prop("checked", value['auto_pass']);
                    $('#autocheck_placeholder').children().eq(1).prop("checked", !value['auto_pass']);
                    for (var key in value) { if (/^(anime|manga|music|other)/.test(key)) { $('#' + key + '-input').val(value[key]); }; };
                });
                await db.getItem(`${type}_autoSaveMessageBbcode`).then((value) => { $('.bbcode').val(value); }) // 还原bbcode输入框内容
                $('[class^="torrent-info-input"]').trigger("input"); // 手动触发标题更改
                $('.bbcode').trigger("input"); // 手动触发bbcode更改
                console.log(`${type}-已还原备份`);
            };
        } else {
            // 关闭自动保存
            $(`#${type}_auto_save_on`).hide();
            $(`#${type}_auto_save_off`).show();
            await db.setItem(`${type}_autoSaveMessageSwitch`, false)
            console.log(`${type}-自动保存已关闭`);
        }
    }).catch(async function (err) {
        // 第一次运行时 <第一次运行时 数据库里什么都没有>
        // 这段其实也没什么用 数据库中如果没有这个键值 会返回 undefined
        $(`#${type}_auto_save_on`).hide();
        $(`#${type}_auto_save_off`).show();
        await db.setItem(`${type}_autoSaveMessageSwitch`, false)
        console.log(`${type}-第一次运行`);
        console.log(`${type}-${err}`);
    });

    async function autoSave() {
        // 由于安全问题 不允许为 input file 赋值
        num--
        // console.log(num);
        if (num <= 0) {
            $(`#${type}_auto_save_text`).fadeIn(2000);
            await db.setItem(`${type}_autoSaveMessageTime`, getDateString()) // 记录保存数据的时间 string
            await db.setItem(`${type}_autoSaveMessageBbcode`, $('.bbcode').val()) // 保存 bbcode 输入框内容
            // 倒是可以跑循环 直接拿到数据 就不用写这么大一堆了 (
            let upload_info = {
                "category": $('#browsecat').val(),
                "auto_pass": $('#autocheck_placeholder').children().eq(0).is(':checked'),
                "anime_chinese": $('#anime_chinese-input').val(),
                "anime_english": $('#anime_english-input').val(),
                "anime_original": $('#anime_original-input').val(),
                "anime_source": $('#anime_source-input').val(),
                "anime_resolution": $('#anime_resolution-input').val(),
                "anime_episode": $('#anime_episode-input').val(),
                "anime_container": $('#anime_container-input').val(),
                "anime_extra": $('#anime_extra-input').val(),
                "manga_title": $('#manga_title-input').val(),
                "manga_author": $('#manga_author-input').val(),
                "manga_volume": $('#manga_volume-input').val(),
                "manga_ended": $('#manga_ended-input').val(),
                "manga_publisher": $('#manga_publisher-input').val(),
                "manga_remark": $('#manga_remark-input').val(),
                "music_prefix": $('#music_prefix-input').val(),
                "music_collection": $('#music_collection-input').val(),
                "music_date": $('#music_date-input').val(),
                "music_category": $('#music_category-input').val(),
                "music_artist": $('#music_artist-input').val(),
                "music_title": $('#music_title-input').val(),
                "music_serial_number": $('#music_serial_number-input').val(),
                "music_quantity": $('#music_quantity-input').val(),
                "music_quality": $('#music_quality-input').val(),
                "music_format": $('#music_format-input').val(),
                "other_title": $('#other_title-input').val()
            };
            await db.setItem(`${type}_autoSaveMessageInfo`, upload_info);
            await db.setItem(`${type}_autoSaveMessageSmallDescr`, $('[name="small_descr"]').val());
            await db.setItem(`${type}_autoSaveMessagePoster`, $('[name="poster"]').val());
            await db.setItem(`${type}_autoSaveMessageAnidbUrl`, $('[name="anidburl"]').val());
            num = num_global + 4; // 重置倒计时
            $(`#${type}_auto_save_text`).fadeOut(2000);
        };
    }
};


// 当前时间 字符串格式
function getDateString() {
    const time = new Date();
    return time.getFullYear().toString() + zero(time.getMonth() + 1).toString() + zero(time.getDate()).toString()
        + zero(time.getHours()) + zero(time.getMinutes()) + zero(time.getSeconds())
};

function zero(obj) {
    return obj < 10 ? '0' + obj : obj
};


// 有时间整合两个相同作用的函数 auto_save_message - autoSaveMessage
// elementButton 插入按钮的位置
// elementBbcode BBCODE输入框
// elementPost 提交按钮
// type 识别符
// parent 父级元素
async function autoSaveMessage(elementButton, elementBbcode, elementPost, type, parent) {
    let db = localforage.createInstance({ name: "bbcodejs" });
    let num_global = 10; // 设置自动保存时间间隔
    let num = 10; // 设置自动保存时间间隔

    $(elementButton).append(`<span id="${type}_auto_save_on" style="margin-top:4px; display: none;">`
        + `<input id="${type}_switch" class="codebuttons" style="font-size:11px;margin-right:3px;" type="button" value="自动保存已开启">`
        + `<input id="${type}_clean" class="codebuttons" style="font-size:11px;margin-right:3px;" type="button" value="清空数据">`
        + `<span id="${type}_auto_save_text" style="display: none;">&nbsp;&nbsp;正在保存...</span></span>`
        + `<span id="${type}_auto_save_off" style="margin-top:4px; display: none;">`
        + `<input class="codebuttons" style="font-size:11px;margin-right:3px;" type="button" value="自动保存已关闭"></span>`
    );

    // 为自动保存按钮绑定事件
    $(`#${type}_auto_save_on`).click(async function (ev) {  // 关闭自动保存
        let button_id = $(ev.target).attr('id');
        switch (button_id) {
            case `${type}_switch`:
                $(this).hide(); // 隐藏按钮
                $(`#${type}_auto_save_off`).fadeIn(200); // 渐入按钮
                clearInterval($(`#${type}_auto_save_text`).attr('title')); // 清除setInterval函数
                await db.setItem(`${type}_autoSaveMessageSwitch`, false)
                console.log(`${type}-自动保存已关闭`);
                break;
            case `${type}_clean`:
                if (window.confirm("确定清空所有数据?")) {
                    await clean();
                    window.location.reload();
                };
                break;
        };
    });

    $(`#${type}_auto_save_off`).click(async function () {  // 开启自动保存
        $(this).hide(); // 隐藏按钮
        $(`#${type}_auto_save_on`).fadeIn(200);
        $(`#${type}_auto_save_text`).attr("title", setInterval(autoSave, 1000));  // 设置setInterval函数
        await db.setItem(`${type}_autoSaveMessageSwitch`, true)
        console.log(`${type}-自动保存已开启`);
    });

    // 提交候选后 删除所有保存的记录 (如果要还原记录,直接返回上一页即可。)
    $(elementPost).click(async function () {
        await clean()
        console.log(`${type}-提交上传请求`);
    });

    async function clean() {
        clearInterval($(`#${type}_auto_save_text`).attr('title')); // 清除setInterval函数
        await db.removeItem(`${type}_autoSaveMessageTime`);
        await db.removeItem(`${type}_autoSaveMessageBbcode`);
        await db.removeItem(`${type}_autoSaveMessageSubject`);
        console.log(`${type}-已清空保存的记录`);
    };

    // 检测上次自动保存开关设定
    await db.getItem(`${type}_autoSaveMessageSwitch`).then(async (value) => {
        if (value) {
            // 启用自动保存
            $(`#${type}_auto_save_on`).show();
            $(`#${type}_auto_save_off`).hide();
            $(`#${type}_auto_save_text`).attr("title", setInterval(autoSave, 1000)); // 设置setInterval函数
            console.log(`${type}-自动保存已开启`);
            // 检查输入框内是否已经存在字符串
            let _input_bool = true
            $(`${parent} input[name='subject']`).add(elementBbcode).each(function () {
                let _input = $(this).val()
                if (_input !== "") { _input_bool = false; return; }
            });
            // 当输入框是空白时 还原上次备份内容
            if (_input_bool) {
                await db.getItem(`${type}_autoSaveMessageSubject`).then((value) => { $(`${parent} input[name='subject']`).val(value); });
                await await db.getItem(`${type}_autoSaveMessageBbcode`).then((value) => { $(elementBbcode).val(value); }) // 还原bbcode输入框内容
                $(elementBbcode).trigger("input"); // 手动触发bbcode更改
                console.log(`${type}-已还原备份`);
            };
        } else {
            // 关闭自动保存
            $(`#${type}_auto_save_on`).hide();
            $(`#${type}_auto_save_off`).show();
            await db.setItem(`${type}_autoSaveMessageSwitch`, false);
        };
    }).catch(async function (err) {
        // 第一次运行时 <第一次运行时 数据库里什么都没有>
        // 这段其实也没什么用 数据库中如果没有这个键值 会返回 undefined
        $(`#${type}_auto_save_on`).hide();
        $(`#${type}_auto_save_off`).show();
        await db.setItem(`${type}_autoSaveMessageSwitch`, false);
        console.log(`${type}-第一次运行`);
        console.log(`${type}-${err}`);
    });

    async function autoSave() {
        num--;
        // console.log(num);
        if (num <= 0) {
            $(`#${type}_auto_save_text`).fadeIn(2000);
            await db.setItem(`${type}_autoSaveMessageTime`, getDateString()) // 记录保存数据的时间 string
            await db.setItem(`${type}_autoSaveMessageBbcode`, $(elementBbcode).val()) // 保存 bbcode 输入框内容
            await db.setItem(`${type}_autoSaveMessageSubject`, $(`${parent} input[name='subject']`).val());
            num = num_global + 4; // 重置倒计时
            $(`#${type}_auto_save_text`).fadeOut(2000);
        };
    };
};


// 输入框与预览框同步滚动
// element 按钮插入位置
// type 标识符
// bbcode 输入框位置
// preview 预览位置
async function syncScroll(element, type, bbcode, preview) {
    let db = localforage.createInstance({ name: "bbcodejs" });  // 为以后统一数据库做准备
    console.log('启用bbcodejs数据库');
    $(element).append(`<input id="${type}_sync_scroll_on" class="codebuttons" style="font-size:11px; margin-right:3px;; display: none;" type="button" value="同步滚动已开启"></input>`
        + `<input id="${type}_sync_scroll_off" class="codebuttons" style="font-size: 11px; margin-right:3px; display: none;" type="button" value="同步滚动已关闭"></input>`
    );

    await db.getItem(`${type}_syncScrollSwitch`).then(async (value) => {
        if (value) {
            $(`#${type}_sync_scroll_on`).show();
            new onScroll();
            console.log(`${type}-同步滚动已打开`);
        } else {
            $(`#${type}_sync_scroll_off`).show();
            console.log(`${type}-同步滚动已关闭`);
        };
    });

    // 为按钮绑定事件
    $(`#${type}_sync_scroll_off`).click(async function () {
        $(this).hide();
        $(`#${type}_sync_scroll_on`).fadeIn(200); // 渐入按钮
        await db.setItem(`${type}_syncScrollSwitch`, true);
        new onScroll();
        console.log(`${type}-同步滚动已打开`);
    });

    $(`#${type}_sync_scroll_on`).click(async function () {
        $(this).hide();
        $(`#${type}_sync_scroll_off`).fadeIn(200); // 渐入按钮
        await db.setItem(`${type}_syncScrollSwitch`, false);
        new offScroll();
        console.log(`${type}-同步滚动已关闭`);
    });

    // 绑定鼠标事件
    function onScroll() {
        let currentTab = 0;
        $(bbcode).mouseover(() => { currentTab = 1; });
        $(preview).mouseover(() => { currentTab = 2; });

        $(bbcode).scroll(() => {
            if (currentTab !== 1) return;
            let scale = ($(preview).children('.child').get(0).offsetHeight - $(preview).get(0).offsetHeight) / ($(bbcode).get(0).scrollHeight - $(bbcode).get(0).offsetHeight);
            $(preview).scrollTop($(bbcode).scrollTop() * scale);
        });

        $(preview).scroll(() => {
            if (currentTab !== 2) return;
            let scale = ($(preview).children('.child').get(0).offsetHeight - $(preview).get(0).offsetHeight) / ($(bbcode).get(0).scrollHeight - $(bbcode).get(0).offsetHeight);
            $(bbcode).scrollTop($(preview).scrollTop() / scale);
        });
    };

    // 解除鼠标事件
    function offScroll() {
        $(bbcode).off("scroll").off("mouseover");
        $(preview).off("scroll").off("mouseover");
    };
};

// 为bbcode加上[]
function createTagBox(name, attribute, content) {
    var components = [];
    components.push('[');
    components.push(name);
    if (attribute !== null) {
        components.push('=');
        components.push(attribute);
    }
    components.push(']');
    if (content !== null) {
        components.push(content);
        components.push('[/');
        components.push(name);
        components.push(']');
    }
    return components.join('');
};

function replaceTextBox(str, start, end, replacement) {
    return str.substring(0, start) + replacement + str.substring(end);
};

function addTagBox(textArea, name, attribute, content, surround) {
    var selStart = textArea.selectionStart;
    var selEnd = textArea.selectionEnd;
    if (selStart === null || selEnd === null) {
        selStart = selEnd = textArea.value.length;
    }
    var selTarget = selStart + name.length + 2 + (attribute ? attribute.length + 1 : 0);
    if (selStart === selEnd) {
        textArea.value = replaceTextBox(textArea.value, selStart, selEnd, createTagBox(name, attribute, content));
    } else {
        var replacement = null;
        if (surround) {
            replacement = createTagBox(name, attribute, textArea.value.substring(selStart, selEnd));
        } else {
            replacement = createTagBox(name, attribute, content);
        }
        textArea.value = replaceTextBox(textArea.value, selStart, selEnd, replacement);
    }
    textArea.setSelectionRange(selTarget, selTarget);
};

function onEditorActionBox(action, element, param) {
    var textArea = document.querySelector(element);
    var selStart = textArea.selectionStart;
    var selEnd = textArea.selectionEnd;
    var selectionText, url;
    if (selStart === null || selEnd === null) {
        selStart = selEnd = textArea.value.length;
    };
    switch (action) {
        case 'B': {
            addTagBox(textArea, 'b', null, '', true);
            break;
        }
        case 'I': {
            addTagBox(textArea, 'i', null, '', true);
            break;
        }
        case 'U': {
            addTagBox(textArea, 'u', null, '', true);
            break;
        }
        case 'URL': {
            if (selStart !== selEnd) {
                selectionText = textArea.value.substring(selStart, selEnd);
                addTagBox(textArea, 'url', selectionText, selectionText, false);
            } else {
                url = window.prompt("请输入链接URL:");
                if (url === null || url.length === 0) {
                    break;
                }
                var title = window.prompt("请输入链接标题(可选):");
                if (title === null || title.length === 0) {
                    title = url;
                }
                addTagBox(textArea, 'url', url, title, false);
            }
            break;
        }
        case 'IMG': {
            if (selStart !== selEnd) {
                selectionText = textArea.value.substring(selStart, selEnd);
                addTagBox(textArea, 'img', null, selectionText, false);
            } else {
                url = window.prompt("请输入图片的完整路径:");
                // url = window.prompt(EDITOR_LANG.image);
                if (url === null) {
                    break;
                }
                var urlLower = url.toLowerCase();
                if (!urlLower.startsWith('http://') && !urlLower.startsWith('https://')) {
                    // window.alert(EDITOR_LANG['invalid_image']);
                    window.alert("图片URL必须以http://或https://开头。");
                    break;
                }
                addTagBox(textArea, 'img', null, url, false);
            }
            break;
        }
        case 'QUOTE': {
            addTagBox(textArea, 'quote', null, '', true);
            break;
        }
        case 'COLOR': {
            if (param !== "") {
                addTagBox(textArea, 'color', param, '', true);
            }
            break;
        }
        case 'FONT': {
            if (param !== "") {
                addTagBox(textArea, 'font', param, '', true);
            }
            break;
        }
        case 'SIZE': {
            if (param !== "") {
                addTagBox(textArea, 'size', param, '', true);
            }
            break;
        }
        // 自定义
        case "S": {
            addTagBox(textArea, "s", null, "", true);
            break;
        }
        case "INFO": {
            addTagBox(textArea, "info", null, "", true);
            break;
        }
        case "MEDIAINFO": {
            addTagBox(textArea, "mediainfo", null, "", true);
            break;
        }
        case "PRE": {
            addTagBox(textArea, "pre", null, "", true);
            break;
        }
        case "CODE": {
            addTagBox(textArea, "code", null, "", true);
            break;
        }
        case "RT*": {
            if (selStart !== selEnd) {
                var title = window.prompt(lang['rt_text']);
                if (title === null || title.length === 0) {
                    break;
                }
                selectionText = textArea.value.substring(selStart, selEnd);
                addTagBox(textArea, "rt", title, selectionText, false);
                // break;
            } else {
                let text = window.prompt(lang['main_body']);
                if (text === null || text.length === 0) {
                    break;
                }
                var title = window.prompt(lang['rt_text']);
                if (title === null || title.length === 0) {
                    break;
                }
                addTagBox(textArea, "rt", title, text, false);
            }
            break;
        }
        case "QUOTE*": {
            if (selStart !== selEnd) {
                var title = window.prompt(lang['main_body_prefix']);
                if (title === null || title.length === 0) {
                    title = "";
                }
                selectionText = textArea.value.substring(selStart, selEnd);
                // addTag(textArea, "quote", null, "", true);
                addTagBox(textArea, "quote", title, selectionText, false);
            } else {
                let text = window.prompt(lang['main_body']);
                if (text === null || text.length === 0) {
                    break;
                }
                var title = window.prompt(lang['main_body_prefix']);
                if (title === null || title.length === 0) {
                    title = "";
                }
                addTagBox(textArea, "quote", title, text, false);
            }
            break;
        }
        case "URL*": {
            if (selStart !== selEnd) {
                selectionText = textArea.value.substring(selStart, selEnd); // 选中的文字
                if (/^(?:https?|ftp|gopher|news|telnet|mms|rtsp):\/\/((?!&lt;|&gt;|\s|"|>|'|<|\(|\)|\[|\]).)+/gi.test(selectionText)) {
                    // 选中的是URL时
                    var title = window.prompt(lang['url_name']);
                    if (title === null || title.length === 0) {
                        // selectionText = textArea.value.substring(selStart, selEnd);
                        // addTag(textArea, "url", null, "", true);
                        break;
                    } else {
                        addTagBox(textArea, "url", selectionText, title, false);
                    };
                } else {
                    // 选中的是文字时
                    var url_link = window.prompt(lang['url_link']);
                    if (url_link === null || url_link.length === 0) {
                        // selectionText = textArea.value.substring(selStart, selEnd);
                        // addTag(textArea, "url", null, "", true);
                        break;
                    } else {
                        addTagBox(textArea, "url", url_link, selectionText, false);
                    };
                };
            } else {
                let text = window.prompt(lang['url_link']);
                if (text === null || text.length === 0) {
                    break;
                }
                var title = window.prompt(lang['url_name']);
                if (title === null || title.length === 0) {
                    title = "";
                    addTagBox(textArea, "url", null, text, false);
                    break;
                }
                addTagBox(textArea, "url", text, title, false);
            }
            break;
        }
        case "SPOILER*": {
            if (selStart !== selEnd) {
                var title = window.prompt(lang['main_body_prefix']);
                if (title === null || title.length === 0) {
                    addTagBox(textArea, "spoiler", null, "", true);
                    break;
                }
                selectionText = textArea.value.substring(selStart, selEnd);
                // addTag(textArea, "spoiler", null, "", true);
                addTagBox(textArea, "spoiler", title, selectionText, false);
            } else {
                let text = window.prompt(lang['main_body']);
                if (text === null || text.length === 0) {
                    break;
                }
                var title = window.prompt(lang['main_body_prefix']);
                if (title === null || title.length === 0) {
                    title = "";
                    addTagBox(textArea, "spoiler", null, text, false);
                    break;
                }
                addTagBox(textArea, "spoiler", title, text, false);
            }
            break;
        }
        case "SPOILER": {
            addTagBox(textArea, "spoiler", null, "", true);
            break;
        }
        case "QUOTE": {
            if (selStart !== selEnd) {
                addTagBox(textArea, "quote", null, "", true);
            } else {
                let text = window.prompt(lang['main_body']);
                if (text === null || text.length === 0) {
                    break;
                };
                addTagBox(textArea, "quote", null, text, false);
            }
            break;
        };
        case "URL": {
            if (selStart !== selEnd) {
                addTagBox(textArea, "url", null, "", true);
            } else {
                let text = window.prompt(lang['url_link']);
                if (text === null || text.length === 0) {
                    break;
                };
                addTagBox(textArea, "url", null, text, false);
            }
            break;
        };
        case "LIST": {
            if (selStart !== selEnd) {
                break;
            };
            addTagBox(textArea, "*", null, null, true);
            break;
        };
        case (action.match(/^#\[.+\]$/i) || {}).input: {
            addTagBox(textArea, action.slice(2, -1), null, null, true);
            break;
        };
    }
    textArea.focus();
};


/**
* 悬浮窗口拖动
*/
// function mouseDrag(ev) {
//     // 拖动悬浮窗口   ps.是真的卡
//     let mx = 0;  // 鼠标x轴
//     let my = 0;  // 鼠标y轴
//     let dx = 0;  // 元素x轴
//     let dy = 0;  // 元素y轴
//     let isDraging = false;  // 是否允许拖动

//     //鼠标按下
//     ev.mousedown(function (e) {
//         e = e || window.event;
//         if (e.target.nodeName === 'TD' || e.target.nodeName === 'DIV' || e.target.nodeName === 'H2') {
//             mx = e.pageX;  // 鼠标X坐标
//             my = e.pageY;  // 鼠标Y坐标
//             dx = ev.offset().left;  // 元素x轴
//             dy = ev.offset().top;  // 元素y轴
//             isDraging = true;  //标记对话框可拖动
//         };
//     });

//     // 鼠标松开
//     ev.mouseup(function () {
//         isDraging = false;
//     });

//     // 鼠标离开
//     ev.mouseleave(function () {
//         isDraging = false;
//     });

//     //鼠标移动
//     $(document).mousemove(function (e) {
//         e = e || window.event;
//         let x = e.pageX;  // 鼠标X坐标
//         let y = e.pageY;  // 鼠标Y坐标
//         if (isDraging) { // 判断能否允许拖动
//             let moveX = dx + x - mx;  // 元素新的left值
//             let moveY = dy + y - my; // 元素新的top值
//             // 范围
//             // var pageW = $(window).width();
//             // var pageH = $(window).height();
//             // var dialogW = ev.width();
//             // var dialogH = ev.height();
//             // var maxX = pageW - dialogW;       //X轴可拖动最大值
//             // var maxY = pageH - dialogH;       //Y轴可拖动最大值
//             // moveX = Math.min(Math.max(0, moveX), maxX);     //X轴可拖动范围
//             // moveY = Math.min(Math.max(0, moveY), maxY);     //Y轴可拖动范围
//             // 设置元素的left,top
//             ev.css({ "left": moveX + 'px', "top": moveY + 'px' });
//         };
//     });
// };

async function basicFrame(title, type) {
    let basic_html = `
<tr>
    <td id="${type}_outer" align="center" class="outer" style="padding-top: 20px; padding-bottom: 20px; display: none;">
        <table class="main" width="940" border="0" cellspacing="0" cellpadding="0">
            <tbody>
                <tr>
                    <td class="embedded">
                        <form id="${type}_compose_custom" method="post" name="${type}_compose_custom">
                            <h2 class="${type}_h2_move" id="${type}_move_part" align="left">${title}</h2>
                            <table width="100%" border="1" cellspacing="0" cellpadding="10">
                                <tbody>
                                    <tr>
                                    <td class="text" align="center">
                                        <table class="main" width="100%" border="1" cellspacing="0" cellpadding="5">
                                        <tbody>
                                            <tr>
                                            <td class="rowhead" valign="top">正文</td>
                                            <td class="rowfollow" align="left">
                                                <div id="${type}_editorouterbox" style="display: block;">
                                                <table width="100%" cellspacing="0" cellpadding="5" border="0">
                                                    <tbody>
                                                    <tr>
                                                        <td align="left" colspan="2">
                                                        <table id="${type}_bbcode_button" cellspacing="1" cellpadding="2" border="0">
                                                            <tbody>
                                                            <tr>
                                                            </tr>
                                                            </tbody>
                                                        </table>
                                                        <div id="${type}_bbcodejs_tbody_box" style="position:relative; margin-top: 4px">
                                                            <div id="${type}_bbcodejs_select_box" style="position: absolute; margin-top: 2px; margin-bottom: 2px; float: left;">
                                                            <select class="med codebuttons" name="${type}_bbcode_color" style="margin-right: 3px; visibility: visible;">
                                                                <option value="">--- 颜色 ---</option>
                                                            </select>
                                                            <select class="med codebuttons" name="${type}_bbcode_font" style="visibility: visible;">
                                                                <option value="">--- 字体 ---</option>
                                                            </select>
                                                            <select class="med codebuttons" name="${type}_bbcode_size" style="visibility: visible;">
                                                                <option value="">--- 字号 ---</option>
                                                            </select>
                                                            </div>
                                                        </div>
                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td colspan="2" valign="middle">
                                                        <iframe src="attachment.php?text_area_id=${type}_box_bbcode" width="100%" height="24" frameborder="0" scrolling="no" marginheight="0" marginwidth="0">
                                                        </iframe>
                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td align="left">
                                                        <textarea class="${type}_box_bbcode" cols="100" style="width: 99%" id="${type}_box_bbcode" rows="20"></textarea>
                                                        </td>
                                                        <td align="center" width="150">
                                                        <table id="${type}_smile-icon" cellspacing="1" cellpadding="3">
                                                            <tbody>
                                                            </tbody>
                                                        </table>
                                                        <br>
                                                        <a onclick="ShowSmileWindow(&quot;${type}_compose_custom&quot;, &quot;${type}_box_bbcode&quot;)">更多表情</a>
                                                        </td>
                                                    </tr>
                                                    </tbody>
                                                </table>
                                                </div>
                                            </td>
                                            </tr>
                                            <tr>
                                            <td colspan="2" align="center">
                                                <table>
                                                <tbody>
                                                    <tr>
                                                    <td class="embedded">
                                                        <input id="${type}_post_box" type="button" class="btn" value="发送">
                                                    </td>
                                                    <td class="embedded">
                                                        <input id="${type}_close_box" type="button" class="btn" value="关闭">
                                                    </td>
                                                    </tr>
                                                </tbody>
                                                </table>
                                            </td>
                                            </tr>
                                        </tbody>
                                        </table>
                                    </td>
                                    </tr>
                                </tbody>
                            </table>
                        </form>
                    </td>
                </tr>
            </tbody>
        </table>
    </td>
</tr>`
    parse_html = $.parseHTML('<table>' + basic_html + '</table>');  // 转为对象
    const bbcode_button = [
        { "style": "font-weight: bold;font-size:11px; margin-right:3px", "value": "B" },
        { "style": "font-style: italic;font-size:11px;margin-right:3px", "value": "I" },
        { "style": "text-decoration: underline;font-size:11px;margin-right:3px", "value": "U" },
        { "style": "text-decoration: line-through;font-size:11px;margin-right:3px", "value": "S" },
        { "style": "font-size:11px;margin-right:3px", "value": "URL" },
        { "style": "font-size:11px;margin-right:3px", "value": "URL*" },
        { "style": "font-size:11px;margin-right:3px", "value": "IMG" },
        { "style": "font-size:11px;margin-right:3px", "value": "RT*" },
        { "style": "font-size:11px;margin-right:3px", "value": "LIST" },
        { "style": "font-size:11px;margin-right:3px", "value": "PRE" },
        { "style": "font-size:11px;margin-right:3px", "value": "CODE" },
        { "style": "font-size:11px;margin-right:3px", "value": "QUOTE" },
        { "style": "font-size:11px;margin-right:3px", "value": "QUOTE*" },
        { "style": "font-size:11px;margin-right:3px", "value": "INFO" },
        { "style": "font-size:11px;margin-right:3px", "value": "MEDIAINFO" },
        { "style": "font-size:11px;margin-right:3px", "value": "SPOILER" },
        { "style": "font-size:11px;margin-right:3px", "value": "SPOILER*" }
    ];
    const smile_list = [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 16, 17, 19, 20, 21, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 39, 40, 41, 42, 192, 198];
    const font_list = ['Arial', 'Arial Black', 'Arial Narrow', 'Book Antiqua', 'Century Gothic', 'Comic Sans MS', 'Courier New',
        'Fixedsys', 'Garamond', 'Georgia', 'Impact', 'Lucida Console', 'Lucida Sans Unicode', 'Microsoft Sans Serif',
        'Palatino Linotype', 'System', 'Tahoma', 'Times New Roman', 'Trebuchet MS', 'Verdana'];
    const color_list = ["Black", "Sienna", "Dark Olive Green", "Dark Green", "Dark Slate Blue", "Navy", "Indigo",
        "Dark Slate Gray", "Dark Red", "Dark Orange", "Olive", "Green", "Teal", "Blue", "Slate Gray", "Dim Gray",
        "Red", "Sandy Brown", "Yellow Green", "Sea Green", "Medium Turquoise", "Royal Blue", "Purple", "Gray",
        "Magenta", "Orange", "Yellow", "Lime", "Cyan", "Deep Sky Blue", "Dark Orchid", "Silver", "Pink",
        "Wheat", "Lemon Chiffon", "Pale Green", "Pale Turquoise", "Light Blue", "Plum", "White"];
    // 插入表情
    smile_list.forEach(function (item, index) {
        if (Number.isInteger((index + 4) / 4)) $(parse_html).find(`#${type}_smile-icon`).children('tbody').append(`<tr></tr>`);
        $(parse_html).find(`#${type}_smile-icon`).find('tr:last').append(`<td class="embedded smile-icon"><a href="#[em${item}]" name="${type}_bbcode_smile"><img style="max-width: 25px;" src="pic/smilies/${item}.gif" alt=""></a></td>`);
    });
    // 插入字体大小菜单
    [1, 2, 3, 4, 5, 6, 7].forEach(function (item) { $(parse_html).find(`[name="${type}_bbcode_size"]`).append(`<option value="${item}">${item}</option>`); })
    // 插入字体菜单
    font_list.forEach(function (item) { $(parse_html).find(`[name="${type}_bbcode_font"]`).append(`<option value="${item}">${item}</option>`); });
    // 插入颜色菜单
    color_list.forEach(function (item) { $(parse_html).find(`[name="${type}_bbcode_color"]`).append(`<option style="background-color: ${item.replace(/\s/g, '').toLowerCase()}" value="${item.replace(/\s/g, '')}">${item}</option>`); });
    // 插入按钮
    bbcode_button.forEach(function (item) {
        $(parse_html).find(`#${type}_bbcode_button`).find('tr:last').append(`<td class="embedded"><input class="codebuttons" style="${item.style}" type="button" value="${item.value}" name="${type}_bbcode_button"></td>`);
    });
    // 插入预览框
    $(parse_html).find(`#${type}_box_bbcode`).parents("tr:eq(1)").after(`<tr><td class="rowhead nowrap" valign="top" style="padding: 3px" align="right">${lang['preview']}</td><td class="rowfollow"><table width="100%" cellspacing="0" cellpadding="5" border="0" ><tbody><tr><td  align="left" colspan="2"><div id="${type}_bbcode2_box" style="min-height: 25px; max-height: 1px; overflow-x: auto ; overflow-y: auto; white-space: pre-wrap;"><div class="child"></div></div></td></tr></tbody></table></td>`);
    return $(parse_html).html().replace(/^<tbody>([\s\S]*)<\/tbody>$/gm, '$1');
};


/**
* 同步窗口大小变化
*/
function syncWindowChange(input, preview) {
    let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
    let element = document.querySelector(input);
    var height_now, height_last;
    var observer = new MutationObserver((mutations) => {
        mutations.forEach(function (mutation) {
            if (mutation.type == "attributes") {
                height_now = Number(mutation.target.style.height.replace('px', '')) + 30;
                if (height_last === height_now) { return } else { height_last = height_now; };
                $(preview).css("max-height", height_now + "px");
            };
        })
    });
    observer.observe(element, {
        attributes: true,
        attributeFilter: ['style']
    });
};


/**
* 悬浮窗居中
*/
// class center {
//     constructor() {
//         // 鼠标滚动时保持悬浮窗居中
//         const bbcodeWindowScroll = (ev) => {
//             ev.data.css({ 'top': ($(window).height() - ev.data.outerHeight()) / 2 + $(document).scrollTop() });
//         };
//         // 浏览器窗口大小变化后保持悬浮窗居中
//         // 不知道为什么用 setTimeout 后,页面上有两个悬浮窗时,总有一个悬浮窗无法居中
//         const bbcodeWindowResize = (ev) => {
//             ev.data.css({
//                 'left': ($(window).width() - ev.data.outerWidth()) / 2,
//                 'top': ($(window).height() - ev.data.outerHeight()) / 2 + $(document).scrollTop()
//             });
//         };
//         //自动居中对话框
//         this.on = (ev) => {
//             // 点开窗口时让悬浮窗居中
//             ev.css({
//                 'left': ($(window).width() - ev.outerWidth()) / 2,
//                 'top': ($(window).height() - ev.outerHeight()) / 2 + $(document).scrollTop()
//             });
//             // 浏览器窗口大小变化后保持悬浮窗居中
//             $(window).on("resize", null, ev, bbcodeWindowResize);
//             // 鼠标滚动时保持悬浮窗居中
//             $(window).on("scroll", null, ev, bbcodeWindowScroll);
//         };
//         // 关闭居中 <移除监听>
//         this.off = () => {
//             $(window).off("resize", null, bbcodeWindowResize, null);
//             $(window).off("scroll", null, bbcodeWindowScroll, null);
//         };
//     };
// };


/**
* 监听用户动作
* @param {string} type - BBCODE窗口类型
*/
function btnListener(type) {
    // 下拉菜单监听
    $(`[name="${type}_bbcode_color"]`).change(function () { onEditorActionBox('COLOR', `#${type}_box_bbcode`, this.options[this.selectedIndex].value); this.selectedIndex = 0; });
    $(`[name="${type}_bbcode_font"]`).change(function () { onEditorActionBox('FONT', `#${type}_box_bbcode`, this.options[this.selectedIndex].value); this.selectedIndex = 0; });
    $(`[name="${type}_bbcode_size"]`).change(function () { onEditorActionBox('SIZE', `#${type}_box_bbcode`, this.options[this.selectedIndex].value); this.selectedIndex = 0; });
    // 按钮监听
    $(`[name="${type}_bbcode_button"]`).click(function () { onEditorActionBox(this.value, `#${type}_box_bbcode`); });
    // 输入框右边表情,鼠标悬浮图标变大
    $(`[name="${type}_bbcode_smile"]`).mouseenter(function () { $(this).children('img').css({ "transform": "scale(1.35)", "transition": "all 0.3s" }); });
    // 输入框右边表情,鼠标离开图标恢复原状
    $(`[name="${type}_bbcode_smile"]`).mouseleave(function () { $(this).children('img').css({ "transform": "" }); });
    // 输入框右边表情,点击图标输入表情
    $(`[name="${type}_bbcode_smile"]`).click(function () { onEditorActionBox($(this).attr('href'), `#${type}_box_bbcode`); });
    // 监听各种按钮的点击事件
    $(`[name="${type}_bbcode_color"],[name="${type}_bbcode_font"],[name="${type}_bbcode_size"],[name="${type}_bbcode_button"],[name="${type}_bbcode_smile"],td.embedded.${type}_smile-icon a`).click(async function () { $(`#${type}_bbcode2_box`).children('.child').html(bbcode2html($(`#${type}_box_bbcode`).val())); });
    // 监听bbcode写入事件
    $(`#${type}_box_bbcode`).bind('input propertychange', async function () { $(`#${type}_bbcode2_box`).children('.child').html(bbcode2html($(this).val())); });

};


// 从弹窗添加表情实时预览结果 [https://u2.dmhy.org/moresmilies.php?form=upload&text=descr]
// 考虑更换成内部悬浮窗
// 外部窗口填入,不记录光标位置
(async () => {
    if (location.pathname !== '/moresmilies.php') return;

    $('td[align="center"] a').each(function () {
        let scriptAction = $(this).attr('href');
        $(this).attr('href', scriptAction.replace('SmileIT', 'SmileIT2'));
    });

    $('body').append(`<script type="text/javascript">
function SmileIT2(smile, form, text) {
    window.opener.document.forms[form].elements[text].value = window.opener.document.forms[form].elements[text].value + " " + smile + " ";
    window.opener.document.forms[form].elements[text].focus();
    window.opener.document.forms[form].elements[text].dispatchEvent(new Event('input'));
    window.close();
};
</script>`)

})();


// 举报
(async () => {
    let type = 'report';
    // 查找举报提交页面
    const $report_form = $('form[action="report.php"]');
    if ($report_form.length === 0) return;
    $report_form.find('[type="submit"]').after(`<input id="${type}_bbcode" type="button" value="高级">`);
    // 插入框架
    $('#outer').parent().after(await basicFrame('举报', type));
    // 插入同步窗口滚动按钮
    await syncScroll(`#${type}_bbcodejs_tbody_box`, type, `#${type}_box_bbcode`, `#${type}_bbcode2_box`);
    // 插入自动保存按钮
    await autoSaveMessage(`#${type}_bbcodejs_tbody_box`, `#${type}_box_bbcode`, `#${type}_post_box`, type, `${type}_compose_custom`);
    const $outer = $(`#${type}_outer`);
    // 监听按钮
    btnListener(type);
    // 同步窗口大小变化
    syncWindowChange(`#${type}_box_bbcode`, `#${type}_bbcode2_box`);

    // 关闭窗口
    $(`#${type}_close_box`).click(function () {
        $('#outer').show();
        $outer.hide();
    });
    // 发送
    $(`#${type}_post_box`).click(function () {
        $('[name="reason"]').val($(`#${type}_box_bbcode`).val());
        $outer.hide();
        $('#outer').show();
        $report_form.find('[type="submit"]').trigger("submit");
    });
    //显示窗口
    $(`#${type}_bbcode`).click(async function () {
        // 获取输入框的值,如引用之类的数据
        let text = $report_form.find('textarea').val();
        // 如果外部输入框不为空,则引入外部输入框的值
        if (text !== '') $(`#${type}_box_bbcode`).val(text);
        // 显示窗口
        $outer.show();
        // 隐藏窗口
        $('#outer').hide();
        // 设置悬浮窗口中预览窗口的最大高度
        $(`#${type}_bbcode2_box`).css("max-height", ($(`#${type}_box_bbcode`).height() + 30) + "px");
        const margin = $(`#${type}_compose_custom .codebuttons`).parents('tbody').eq(0).width() - $(`#${type}_bbcodejs_select_box`).width() - 2.6;
        $(`#${type}_bbcodejs_select_box`).css("margin-left", margin + "px");
        // 手动触发bbcode内容更改
        $(`#${type}_box_bbcode`).trigger("input");
    });
})();


// 聊天
(async () => {
    let type = 'shbox';
    const $shbox_button = $('#hbsubmit');  // 查找聊天版清除按钮
    if ($shbox_button.length === 0) return;  // 聊天版自动刷新时,会再次触发当前函数 || 未开启聊天版
    $shbox_button.after(`<input id="${type}_bbcode" type="button" class="codebuttons" value="高级">`)
    // 插入框架
    $('#nav_block').parent().after(await basicFrame('群聊区', type));
    // 插入同步窗口滚动按钮
    await syncScroll(`#${type}_bbcodejs_tbody_box`, type, `#${type}_box_bbcode`, `#${type}_bbcode2_box`);
    // 插入自动保存按钮
    await autoSaveMessage(`#${type}_bbcodejs_tbody_box`, `#${type}_box_bbcode`, `#${type}_post_box`, type, `${type}_compose_custom`);
    const $outer = $(`#${type}_outer`);
    // 监听按钮
    btnListener(type);
    // 同步窗口大小变化
    syncWindowChange(`#${type}_box_bbcode`, `#${type}_bbcode2_box`);

    // 点击关闭窗口按钮
    $(`#${type}_close_box`).click(function () { $outer.hide(); });
    // 发送
    $(`#${type}_post_box`).click(function () {
        $('#shbox_text').val($(`#${type}_box_bbcode`).val());
        $('[name="shbox"]').trigger("submit");
        $outer.hide();
    });
    //点击按钮
    $(`#${type}_bbcode`).click(async function () {
        // 获取输入框的值,如引用之类的数据
        let text = $('#shbox_text').val();
        // 如果外部输入框不为空,则引入外部输入框的值
        if (text !== '') $(`#${type}_box_bbcode`).val(text);
        // 显示窗口
        $outer.is(':hidden') ? $outer.show() : $outer.hide();
        // 设置窗口中预览窗口的最大高度
        $(`#${type}_bbcode2_box`).css("max-height", ($(`#${type}_box_bbcode`).height() + 30) + "px");
        const margin = $(`#${type}_compose_custom .codebuttons`).parents('tbody').eq(0).width() - $(`#${type}_bbcodejs_select_box`).width() - 2.6;
        $(`#${type}_bbcodejs_select_box`).css("margin-left", margin + "px");
        // 手动触发bbcode内容更改
        $(`#${type}_box_bbcode`).trigger("input");
    });
})();


// 请求续种
(async () => {
    if (location.pathname !== '/request.php') return;
    let type = 'request';
    // 查找按钮
    const $request_button = $('#qr');
    if ($request_button.length === 0) return;
    $request_button.after(`<input id="${type}_bbcode" type="button" class="codebuttons" value="高级">`)
    // 插入框架
    $('#outer').find('tbody:first').append(await basicFrame('回应/评论', type));
    // 插入同步窗口滚动按钮
    await syncScroll(`#${type}_bbcodejs_tbody_box`, type, `#${type}_box_bbcode`, `#${type}_bbcode2_box`);
    // 插入自动保存按钮
    await autoSaveMessage(`#${type}_bbcodejs_tbody_box`, `#${type}_box_bbcode`, `#${type}_post_box`, type, `${type}_compose_custom`);
    const $outer = $(`#${type}_outer`);

    // 监听按钮
    btnListener(type);
    // 同步窗口大小变化
    syncWindowChange(`#${type}_box_bbcode`, `#${type}_bbcode2_box`);

    // 关闭窗口
    $(`#${type}_close_box`).click(function () {
        $('#compose').parentsUntil('.embedded').eq(-1).show();
        $outer.hide();
    });
    // 发送
    $(`#${type}_post_box`).click(function () {
        $('#compose textarea').val($(`#${type}_box_bbcode`).val());
        $outer.hide();
        $('#compose').parentsUntil('.embedded').eq(-1).show();
        $('#compose').trigger("submit");
    });
    //点击弹出窗口
    $(`#${type}_bbcode`).click(async function () {
        // 获取输入框的值,如引用之类的数据
        let text = $('#compose textarea').val();
        // 如果外部输入框不为空,则引入外部输入框的值
        if (text !== '') $(`#${type}_box_bbcode`).val(text);
        // 显示窗口
        $outer.show();
        // 隐藏窗口
        $('#compose').parentsUntil('.embedded').eq(-1).hide();
        // 设置悬浮窗口中预览窗口的最大高度
        $(`#${type}_bbcode2_box`).css("max-height", ($(`#${type}_box_bbcode`).height() + 30) + "px");
        const margin = $(`#${type}_compose_custom .codebuttons`).parents('tbody').eq(0).width() - $(`#${type}_bbcodejs_select_box`).width() - 2.6;
        $(`#${type}_bbcodejs_select_box`).css("margin-left", margin + "px");
        // 手动触发bbcode内容更改
        $(`#${type}_box_bbcode`).trigger("input");
    });
})();


// 控制面板
(async () => {
    if (location.pathname !== '/usercp.php') return;
    let action;
    let type = 'usercp';
    const $signature_window = $('[name="signature"]');  // 查找BBCODE窗口
    const $info_window = $('[name="info"]');  // 查找BBCODE窗口
    if ($signature_window.length !== 0) { type = `${type}_signature`; action = 'signature'; }
    else if ($info_window.length !== 0) { type = `${type}_info`; action = 'info'; }
    else return;

    $(`[name="${action}"]`).parent().find('a').attr({ 'href': 'javascript:void(0);false;', 'target': '', 'id': `${action}_bbcode_a` });
    // await basicFrame(action === 'signature' ? '论坛签名档' : '个人说明', type);  
    // 插入框架
    $('#outer').find('tbody:first').append(await basicFrame(action === 'signature' ? '论坛签名档' : '个人说明', type));
    // 插入同步窗口滚动按钮
    await syncScroll(`#${type}_bbcodejs_tbody_box`, type, `#${type}_box_bbcode`, `#${type}_bbcode2_box`);
    // 插入自动保存按钮
    await autoSaveMessage(`#${type}_bbcodejs_tbody_box`, `#${type}_box_bbcode`, `#${type}_post_box`, type, `${type}_compose_custom`);
    const $outer = $(`#${type}_outer`);

    btnListener(type);  // 监听按钮
    syncWindowChange(`#${type}_box_bbcode`, `#${type}_bbcode2_box`);  // 同步窗口大小变化

    // 关闭窗口
    $(`#${type}_close_box`).click(function () {
        $('#outer').children('table:last').show();
        $outer.hide();
    });
    // 发送
    $(`#${type}_post_box`).click(function () {
        $(`[name="${action}"]`).val($(`#${type}_box_bbcode`).val());
        $('#outer').children('table:last').show();
        $outer.hide();
    });
    // 点击弹出窗口
    $(`#${action}_bbcode_a`).click(async function () {
        // 获取输入框的值,如引用之类的数据
        let text = $(`[name="${action}"]`).val();
        // 如果外部输入框不为空,则引入外部输入框的值
        if (text !== '') $(`#${type}_box_bbcode`).val(text);
        // 显示悬浮窗口
        $outer.show();
        // 隐藏窗口
        $('#outer').children('table:last').hide();
        // 设置悬浮窗口中预览窗口的最大高度
        $(`#${type}_bbcode2_box`).css("max-height", ($(`#${type}_box_bbcode`).height() + 30) + "px");
        const margin = $(`#${type}_compose_custom .codebuttons`).parents('tbody').eq(0).width() - $(`#${type}_bbcodejs_select_box`).width() - 2.6;
        $(`#${type}_bbcodejs_select_box`).css("margin-left", margin + "px");
        // 手动触发bbcode内容更改
        $(`#${type}_box_bbcode`).trigger("input");
        $(`#${type}_post_box`).attr("value", '填写');
    });
})();