Block_Obj

BLOCK_OBJ

La data de 21-09-2020. Vezi ultima versiune.

Acest script nu ar trebui instalat direct. Aceasta este o bibliotecă pentru alte scripturi care este inclusă prin directiva meta a // @require https://update.greasyfork.org/scripts/407543/850077/Block_Obj.js

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 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         Block_Obj
// @namespace    https://greasyfork.org/zh-CN/users/193133-pana
// @homepage     https://www.sailboatweb.com
// @version      2.9.0
// @description  BLOCK_OBJ
// @author       pana
// @license      GNU General Public License v3.0 or later
// ==/UserScript==

const BLOCK_STYLE = `
    .block_obj_wrap_div {
        background-color: #222222;
        border-radius: 3px;
        border: 1px solid #282A36;
        bottom: 6vh;
        box-shadow: 0 0 5px #282A36;
        color: #D3D3D3;
        font-size: 13px;
        margin: 0px;
        padding: 0px;
        position: fixed;
        text-align: left;
        transition: 0.8s;
        width: 520px;
        z-index: 99999;
    }
    .block_obj_show_wrap {
        display: block;
        right: 0;
    }
    .block_obj_hidden_wrap {
        right: -530px;
    }
    .block_obj_main_fieldset {
        border-radius: 3px;
        border: 3px groove #00A1D6;
        height: auto;
        margin: 8px;
        min-width: 300px;
        padding: 4px 9px 6px 9px;
        width: auto;
    }
    .block_obj_ul_node {
        list-style: none;
        padding-left: 0;
        margin: 0;
    }
    .block_obj_checkbox_li {
        display: inline-block;
        margin-top: 5px;
    }
    .block_obj_checkbox_input {
        clip: rect(0, 0, 0, 0);
        position: absolute;
    }
    .block_obj_checkbox_label {
        cursor: pointer;
        vertical-align: middle;
    }
    .block_obj_checkbox_input + label::before {
        background-color: silver;
        border-radius: 0.1em;
        color: #FFF;
        content: "\\a0";
        display: inline-block;
        height: 1em;
        line-height: 85%;
        margin-right: 0.5em;
        text-align: center;
        vertical-align: 0.2em;
        width: 1em;
    }
    .block_obj_checkbox_input:checked + label::before {
        background-color: #00A1D6;
        content: "\\2713";
    }
    .block_obj_separator_text {
        color: #FFB86C;
        margin-top: 5px;
    }
    .block_obj_separator_symbol {
        background-color: #303030;
        height: 2px;
        margin-bottom: 5px;
        margin-top: 5px;
        min-width: 400px;
    }
    .block_obj_input_div {
        margin-top: 5px;
    }
    .block_obj_input {
        background-color: #C0C0C0;
        border: 1px solid #C0C0C0;
        color: #000;
        font-size: 13px;
        min-height: 15px;
        margin-left: 5px;
        margin-right: 5px;
        padding-left: 4px;
    }
    .block_obj_keyword_input {
        width: 150px;
    }
    .block_obj_input_btn {
        background-color: #3da9cc;
        border-radius: 3px;
        border: 1px solid #73C9E5;
        box-shadow: 0 0 4px #73C9E5;
        color: #FFF;
        cursor: pointer;
        display: inline-block;
        min-height: 15px;
        margin-left: 5px;
        text-align: center;
        vertical-align: bottom;
        white-space: nowrap;
        width: 30px;
    }
    .block_obj_list_div {
        margin-top: 5px;
    }
    .block_obj_list_textarea_div {
        border: 1px dotted #00A1D6;
        margin-top: 3px;
        max-height: 60px;
        min-height: 3px;
        overflow: auto;
    }
    .block_obj_list_textarea_div::-webkit-scrollbar {
        background-color: #979797;
        border-radius: 5px;
        width: 10px;
    }
    .block_obj_list_textarea_div::-webkit-scrollbar-thumb {
        background-color: #404040;
        border-radius: 5px;
    }
    .block_obj_button_clicked {
        color: #000;
    }
    .block_obj_child_span {
        background-color: #3D3D3D;
        border-radius: 5px;
        border: 1px solid #3D3D3D;
        display: inline-block;
        margin: 3px;
        padding: 2px;
        min-height: 18px;
    }
    .block_obj_child_text {
        border-right: 1px solid #A9181C;
        margin-right: 4px;
        padding-right: 4px;
    }
    .block_obj_child_del {
        color: #A9181C;
        cursor: pointer;
    }
    .block_obj_list_textarea_expand {
        max-height: 720px;
    }
    .block_obj_li_hide {
        display: none;
    }
    .block_obj_reg_input {
        width: 100px;
    }
    .block_obj_modifier_input {
        width: 50px;
    }
    .block_obj_button {
        background-color: #FB7299;
        border-radius: 4px;
        border: 1px solid #FB7299;
        color: #FFF;
        cursor: pointer;
        margin-top: 5px;
        padding: 2px 4px;
        position: relative;
        min-height: 17px;
    }
    .block_obj_save_button {
        float: right;
        margin-right: 5px;
    }
    .block_obj_cancel_button {
        float: left;
        margin-left: 5px;
    }
    .block_obj_expand_box {
        bottom: 0px;
        height: 6vh;
        position: fixed;
        right: -6vw;
        transition: 0.5s;
        width: 12vw;
        z-index: 99999;
    }
    .block_obj_show_expand_box {
        right: 0;
        width: 6vw;
    }
    .block_obj_expand_span {
        background-color: #00A1D6;
        border-radius: 19px;
        border: 1px solid #00A1D6;
        bottom: 1vh;
        color: #FFF;
        cursor: pointer;
        display: block;
        font-size: 13px;
        height: 38px;
        line-height: 38px;
        position: absolute;
        right: 1vw;
        text-align: center;
        width: 38px;
        z-index: 99999;
        user-select: none;
    }
    .block_obj_expand_span:hover {
        box-shadow: 0 0 5px 1px green;
    }
    .block_obj_move_right {
        margin-left: 15px;
    }
    .block_obj_none {
        display: none !important;
    }
    .block_obj_hidden {
        visibility: hidden !important;
    }
    .block_obj_presentation_div {
        display: flex;
        position: fixed;
        background-color: rgba(0, 0, 0, .5);
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 100000;
        align-items: center;
        justify-content: center;
    }
    .block_obj_dialog_div {
        position: relative;
        width: 400px;
        background-color: #4e5654;
        border: 0 solid #000;
        border-radius: 12px;
        display: flex;
        flex-direction: column;
    }
    .block_obj_big_bang_top_part {
        margin-top: 5px;
        margin-bottom: 5px;
    }
    .block_obj_big_bang_h3 {
        font-size: 20px;
        color: #fff;
        margin-left: 5px;
        background-color: #4e5654;
        border-color: #4e5654;
    }
    .block_obj_big_bang_deselect_btn {
        float: right;
        margin-top: 5px;
        margin-right: 5px;
        color: #2a2a92;
        cursor: pointer;
    }
    .block_obj_big_bang_middle_part {
        margin-top: 5px;
        margin-bottom: 5px;
        max-height: 500px;
        overflow-y: auto;
    }
    .block_obj_big_bang_text {
        background-color: #3e3939;
        color: #fff;
        padding: 5px;
        margin: 4px;
        font-size: 16px;
        display: inline-block;
        border-radius: 99px;
        cursor: pointer;
        user-select: none;
    }
    .block_obj_big_bang_text_selected {
        background-color: #3636b1 !important;
    }
    .block_obj_big_bang_bottom_part {
        margin-top: 5px;
        margin-bottom: 5px;
        text-align: center;
    }
    .block_obj_big_bang_add_btn, .block_obj_big_bang_copy_btn {
        display: inline-block;
        padding: 10px;
        color: #fff;
        background-color: #325561;
        cursor: pointer;
        border-radius: 99px;
        margin-left: 20px;
        margin-right: 20px;
    }
    .block_obj_big_bang_add_btn:hover, .block_obj_big_bang_copy_btn:hover {
        color: #2a2a92;
    }
`;
class Block_Obj {
    constructor(config_key, reg_key_array = []) {
        this.wrapDiv = null;
        this.mainFieldset = null;
        this.ulNode = null;
        this.style = null;
        this.saveField = [];
        this.onSave = null;
        this.onChange = null;
        this.field = [];
        this.configKey = config_key;
        this.regKeyArray = reg_key_array;
        this.config = {};
    }
    async init(initialization) {
        if (! this.id) {
            this.id = initialization.id ? 'blockObj_' + initialization.id : 'blockObj_' + Block_Obj.count;
            ! initialization.id && Block_Obj.count ++;
        }
        this.config = await this.readConfig();
        this.regKeyArray.forEach(key => {
            if (this.config[key] === undefined) {
                this.config[key] = [];
            }
        });
        this.display = initialization.display ? true : false;
        if (initialization.events) {
            if (typeof(initialization.events['save']) === 'function') {
                this.onSave = initialization.events['save'];
            }
            if (typeof(initialization.events['change']) === 'function') {
                this.onChange = initialization.events['change'];
            }
        }
        this.style = document.createElement('style');
        this.style.innerHTML = BLOCK_STYLE;
        document.body.appendChild(this.style);
        if (initialization.style && typeof(initialization.style) === 'string') {
            let external_style = document.createElement('style');
            external_style.type = 'text/css';
            external_style.innerHTML = initialization.style;
            document.body.appendChild(external_style);
        }
        ! this.wrapDiv && this.createSettingsPanel();
        this.field = initialization.field;
        this.settingsPanel();
        Block_Obj.GM.registerMenuCommand(initialization.menu, () => this.expandWrap());
        Block_Obj.GM.addValueChangeListener(this.configKey, (_name, _old_value, new_value, remote) => {
            if (remote) {
                this.destroyAndRebuild(new_value);
                typeof(this.onChange) === 'function' && this.onChange(this.getConfig());
            }
        });
        let expand_box = document.createElement('div');
        expand_box.className = 'block_obj_expand_box';
        expand_box.onmouseenter = function() {
            this.classList.add('block_obj_show_expand_box');
        };
        expand_box.onmouseleave = function() {
            this.classList.remove('block_obj_show_expand_box');
        };
        let hover_button = {};
        if (initialization.hover_button) {
            Object.assign(hover_button, initialization.hover_button);
        }
        let expand_span = document.createElement('span');
        expand_span.id = this.id + '_expandSpan';
        expand_span.className = 'block_obj_expand_span';
        expand_span.textContent = hover_button.label == null ? '屏蔽' : hover_button.label;
        expand_span.title = hover_button.title == null ? '显示/隐藏屏蔽设置' : hover_button.title;
        expand_span.addEventListener('click', () => {
            this.expandWrap();
            if (hover_button.click && typeof(hover_button.click) === 'function') {
                hover_button.click(expand_span);
            }
        });
        expand_box.appendChild(expand_span);
        document.body.appendChild(expand_box);
    }
    settingsPanel() {
        if (Array.isArray(this.field)) {
            this.field.forEach(ele => {
                if (! this.wrapDiv.querySelector('#' + this.id + '_' + (ele.id ? ele.id : ''))) {
                    switch (ele.type.toLowerCase()) {
                        case 'separator':
                        case 's':
                            this.insertSeparator(ele.id, ele.label, ele.title, ele.classname);
                            break;
                        case 'br':
                        case 'b':
                            this.insertBr(ele.classname);
                            break;
                        case 'input':
                        case 'i':
                            this.insertInput(ele.list_id, ele.id, false, ele.label, ele.title, ele.placeholder, ele.classname, ele.campare);
                            break;
                        case 'reg_input':
                        case 'ri':
                            this.insertInput(ele.list_id, ele.id, true, ele.label, ele.title, ele.placeholder, ele.classname, ele.campare, ele.modifier_label, ele.modifier_placeholder);
                            break;
                        case 'list':
                        case 'l':
                            this.insertList(ele.id, (this.config[ele.id] == null ? ele.default : this.config[ele.id]), ele.label, ele.title, ele.classname);
                            break;
                        case 'checkbox':
                        case 'c':
                        default:
                            this.insertCheckbox(ele.id, ele.label, ele.title, (this.config[ele.id] == null ? ele.default : this.config[ele.id]), ele.classname, ele.move_right);
                            break;
                    }
                }
            });
        }
        let save_button = this.createSpanBtn('block_obj_button block_obj_save_button', '保存并关闭', '保存设置并关闭设置窗口', e => {
            this.expandWrap();
            this.saveConfig();
        });
        let only_save_button = this.createSpanBtn('block_obj_button block_obj_save_button', '仅保存', '仅保存设置', e => {
            only_save_button.textContent = '已保存';
            save_timer && window.clearTimeout(save_timer);
            var save_timer = window.setTimeout(() => {
                only_save_button.textContent = '仅保存';
            }, 1000);
            this.saveConfig();
        });
        let cancel_button = this.createSpanBtn('block_obj_button block_obj_cancel_button', '取消', '关闭设置窗口', e => {
            this.expandWrap();
            cancel_timer && window.clearTimeout(cancel_timer);
            var cancel_timer = window.setTimeout(() => {
                this.display = false;
                this.destroyAndRebuild();
            }, 800);
            e.stopPropagation();
        });
        this.ulNode.appendChild(save_button);
        this.ulNode.appendChild(only_save_button);
        this.ulNode.appendChild(cancel_button);
        document.body.appendChild(this.wrapDiv);
    }
    getConfig() {
        let real_config = {};
        Object.assign(real_config, this.config);
        this.regKeyArray.forEach(key => {
            real_config[key] = this.convertArray(real_config[key]);
        });
        return real_config;
    }
    async readConfig() {
        let config = {};
        if (this.configKey) {
            config = await Block_Obj.GM.getValue(this.configKey, {});
        }
        return config;
    }
    saveConfig() {
        this.saveField.forEach(item => {
            if (item.type == 'checkbox') {
                this.config[item.key] = document.getElementById(this.id + '_' + item.key).checked;
            } else if (item.type == 'list') {
                this.config[item.key] = this.extractList(this.id + '_' + item.key);
            }
        });
        Block_Obj.GM.setValue(this.configKey, this.config);
        typeof(this.onSave) === 'function' && this.onSave(this.getConfig());
    }
    createSettingsPanel() {
        this.wrapDiv = document.createElement('div');
        this.wrapDiv.id = this.id + '_wrapDiv';
        this.wrapDiv.className = 'block_obj_wrap_div ' + (this.display ? 'block_obj_show_wrap' : 'block_obj_hidden_wrap');
        this.mainFieldset = document.createElement('fieldset');
        this.mainFieldset.id = this.id + '_mainFieldset';
        this.mainFieldset.className = 'block_obj_main_fieldset';
        this.wrapDiv.appendChild(this.mainFieldset);
        this.ulNode = document.createElement('ul');
        this.ulNode.id = this.id + '_ulNode';
        this.ulNode.className = 'block_obj_ul_node';
        this.mainFieldset.appendChild(this.ulNode);
        document.body.appendChild(this.wrapDiv);
    }
    destroyAndRebuild(new_config = null) {
        this.config = new_config || this.config;
        document.body.removeChild(this.wrapDiv);
        this.createSettingsPanel();
        this.settingsPanel();
    }
    expandWrap() {
        let panel = document.getElementById(this.id + '_wrapDiv');
        if (panel) {
            if (panel.classList.contains('block_obj_show_wrap')) {
                this.display = false;
                panel.classList.remove('block_obj_show_wrap');
                panel.classList.add('block_obj_hidden_wrap');
            } else {
                this.display = true;
                panel.classList.remove('block_obj_hidden_wrap');
                panel.classList.add('block_obj_show_wrap');
            }
        }
    }
    insertCheckbox(id, label = '', title = '', checked = false, classname = null, move_right = false) {
        let checkbox_li = document.createElement('li');
        checkbox_li.className = 'block_obj_checkbox_li';
        classname && checkbox_li.classList.add(classname);
        move_right && checkbox_li.classList.add('block_obj_move_right');
        let checkbox_input = document.createElement('input');
        checkbox_input.type = 'checkbox';
        checkbox_input.className = 'block_obj_checkbox_input';
        checkbox_input.id = this.id + '_' + id;
        checkbox_input.checked = checked ? true : false;
        let checkbox_label = document.createElement('label');
        checkbox_label.className = 'block_obj_checkbox_label';
        checkbox_label.setAttribute('for', this.id + '_' + id);
        checkbox_label.textContent = label;
        checkbox_label.title = title;
        checkbox_li.appendChild(checkbox_input);
        checkbox_li.appendChild(checkbox_label);
        this.ulNode.appendChild(checkbox_li);
        this.saveField.push({
            'key': id,
            'type': 'checkbox'
        });
    }
    insertSeparator(id = null, label = null, title = null, li_classname = null) {
        let separator_li = document.createElement('li');
        separator_li.className = 'block_obj_separator_li';
        li_classname && separator_li.classList.add('block_obj_' + li_classname);
        let separator_div = document.createElement('div');
        if (id) {
            separator_div.id = this.id + '_' + id;
        }
        if (label) {
            separator_div.className = 'block_obj_separator_text';
            separator_div.textContent = label;
        } else {
            separator_div.className = 'block_obj_separator_symbol';
        }
        separator_div.title = title ? title : '';
        separator_li.appendChild(separator_div);
        this.ulNode.appendChild(separator_li);
    }
    insertBr(classname = null) {
        let br = document.createElement('br');
        br.className = classname ? classname : '';
        this.ulNode.appendChild(br);
    }
    insertInput(list_id, id = null, is_reg = false, label = '', title = '', placeholder = '', li_classname = null, campare = null, modifier_label = '', modifier_placeholder = '') {
        let input_li = document.createElement('li');
        input_li.className = li_classname ? 'block_obj_' + li_classname : '';
        let input_div = document.createElement('div');
        input_div.className = 'block_obj_input_div';
        let input_span = document.createElement('span');
        input_span.className = 'block_obj_input_span';
        input_span.textContent = label;
        input_div.appendChild(input_span);
        let input = document.createElement('input');
        if (id) {
            input.id = this.id + '_' + id;
        }
        input.title = title;
        input.placeholder = placeholder;
        input.type = 'text';
        input.className = is_reg ? 'block_obj_input block_obj_reg_input' : 'block_obj_input block_obj_keyword_input';
        input_span.appendChild(input);
        let modifier_span = document.createElement('span');
        modifier_span.textContent = modifier_label;
        is_reg && input_div.appendChild(modifier_span);
        let modifier_input = document.createElement('input');
        if (id) {
            modifier_input.id = this.id + '_modifier_' + id;
        }
        modifier_input.placeholder = modifier_placeholder;
        modifier_input.type = 'text';
        modifier_input.className = 'block_obj_input block_obj_modifier_input';
        modifier_span.appendChild(modifier_input);
        let the_list_id = this.id + '_' + list_id;
        input.addEventListener('keyup', e => {
            if (e.keyCode === 13) {
                is_reg ? this.addRegListItem(input, modifier_input, the_list_id) : this.addListItem(input, the_list_id, campare);
            }
        });
        modifier_input.addEventListener('keyup', e => {
            e.keyCode === 13 && this.addRegListItem(input, modifier_input, the_list_id);
        });
        let add_btn = this.createSpanBtn('block_obj_input_btn', '添加', '添加内容到列表中', e => {
            if (is_reg ? this.addRegListItem(input, modifier_input, the_list_id) : this.addListItem(input, the_list_id, campare)) {
                this.buttonClicked(add_btn, '添加成功', 'block_obj_button_clicked');
            }
        });
        let delete_btn = this.createSpanBtn('block_obj_input_btn', '删除', '从列表中删除符合的项目', e => {
            if (is_reg ? this.delRegListItem(input, modifier_input, the_list_id) : this.delListItem(input, the_list_id)) {
                this.buttonClicked(delete_btn, '删除成功', 'block_obj_button_clicked');
            }
        });
        let clear_btn = this.createSpanBtn('block_obj_input_btn', '清空', '清空列表', _e => {
            document.getElementById(the_list_id).innerHTML = '';
            this.buttonClicked(clear_btn, '清除成功', 'block_obj_button_clicked');
        });
        let copy_btn = this.createSpanBtn('block_obj_input_btn', '复制', '复制列表', _e => {
            Block_Obj.GM.setClipboard(this.extractList(the_list_id).toString());
            this.buttonClicked(copy_btn, '复制成功', 'block_obj_button_clicked');
        });
        let expand_btn = this.createSpanBtn('block_obj_input_btn', '展开', '展开列表', _e => {
            li_classname && this.toggleList('block_obj_' + li_classname);
            if (expand_btn.textContent == '展开') {
                expand_btn.textContent = '恢复';
                expand_btn.title = '收缩列表';
            } else {
                expand_btn.textContent = '展开';
                expand_btn.title = '展开列表';
            }
        });
        input_div.appendChild(add_btn);
        input_div.appendChild(delete_btn);
        input_div.appendChild(clear_btn);
        input_div.appendChild(copy_btn);
        input_div.appendChild(expand_btn);
        input_li.appendChild(input_div);
        this.ulNode.appendChild(input_li);
    }
    insertList(id, save_array = [], label = '', title = '', li_classname = '') {
        let list_li = document.createElement('li');
        list_li.className = li_classname ? 'block_obj_' + li_classname : '';
        let list_div = document.createElement('div');
        list_div.className = 'block_obj_list_div';
        list_div.textContent = label;
        list_div.title = title;
        let list_textarea_div = document.createElement('div');
        list_textarea_div.id = this.id + '_' + id;
        list_textarea_div.className = 'block_obj_list_textarea_div';
        for (let item of save_array) {
            item && list_textarea_div.insertAdjacentElement('afterbegin', this.createListItem(item));
        }
        list_div.appendChild(list_textarea_div);
        list_li.appendChild(list_div);
        this.ulNode.appendChild(list_li);
        this.saveField.push({
            'key': id,
            'type': 'list'
        });
    }
    addListItem(input, list_id, campare = null) {
        let text_value = input.value;
        if (text_value) {
            let text_arr = this.stringToArray(text_value);
            let save_arr = this.extractList(list_id);
            text_arr.forEach(item => {
                let status = true;
                if (typeof(campare) === 'function') {
                    let temp_status = campare(item);
                    if (typeof(temp_status) === 'boolean') {
                        status = temp_status;
                    }
                }
                if (status) {
                    ! save_arr.includes(item) && document.getElementById(list_id).insertAdjacentElement('afterbegin', this.createListItem(item));
                }
            });
            input.value = '';
            return true;
        }
        return false;
    }
    delListItem(input, list_id) {
        let text_value = input.value;
        if (text_value) {
            let del_status = false;
            let text_arr = this.stringToArray(text_value);
            let save_arr = this.extractList(list_id);
            text_arr.forEach(item => {
                if (save_arr.includes(item)) {
                    let total_child = document.getElementById(list_id).getElementsByClassName('block_obj_child_span');
                    try {
                        document.getElementById(list_id).removeChild(total_child[total_child.length - 1 - save_arr.indexOf(item)]);
                        del_status = true;
                    } catch(e) {
                        del_status = false;
                        console.error('Block_Obj: Error deleting element.');
                        console.error(e);
                    }
                }
            });
            if (del_status) {
                input.value = '';
                return true;
            }
        }
        return false;
    }
    addRegListItem(reg_input, modifier_input, list_id) {
        let reg_value = reg_input.value;
        let modifier_value = modifier_input.value;
        if (reg_value) {
            try {
                let reg_obj = new RegExp(reg_value, modifier_value);
                let save_arr = this.extractList(list_id);
                ! save_arr.includes(reg_obj.toString()) && document.getElementById(list_id).insertAdjacentElement('afterbegin', this.createListItem(reg_obj.toString()));
                reg_input.value = '';
                modifier_input.value = '';
                return true;
            } catch(e) {
                console.error('Block_Obj: Invalid regular expression.');
                console.error(e);
            }
        }
        return false;
    }
    delRegListItem(reg_input, modifier_input, list_id) {
        let reg_value = reg_input.value;
        let modifier_value = modifier_input.value;
        if (reg_value) {
            let del_status = false;
            try {
                let reg_obj = new RegExp(reg_value, modifier_value);
                let save_arr = this.extractList(list_id);
                if (save_arr.includes(reg_obj.toString())) {
                    let total_child = document.getElementById(list_id).getElementsByClassName('block_obj_child_span');
                    document.getElementById(list_id).removeChild(total_child[total_child.length - 1 - save_arr.indexOf(reg_obj.toString())]);
                    del_status = true;
                }
            } catch(e) {
                del_status = false;
                console.error('Block_Obj: Invalid regular expression or error deleting element.');
                console.error(e);
            }
            if (del_status) {
                reg_input.value = '';
                modifier_input.value = '';
                return true;
            }
            return false;
        }
    }
    createSpanBtn(classname, label, title, callback) {
        let btn_span = this.createBasicBtn('span', label, title, classname);
        btn_span.addEventListener('click', e => typeof(callback) === 'function' && callback(e));
        return btn_span;
    }
    createListItem(text_value) {
        let child_span = document.createElement('span');
        child_span.className = 'block_obj_child_span';
        let text_span = document.createElement('span');
        text_span.className = 'block_obj_child_text';
        text_span.textContent = text_value.length > 9 ? text_value.slice(0, 3) + '...' + text_value.slice(-3) : text_value;
        if (text_value.length > 9) {
            text_span.title = text_value;
        }
        let del_span = document.createElement('span');
        del_span.textContent = 'X';
        del_span.title = '移除';
        del_span.className = 'block_obj_child_del';
        del_span.addEventListener('click', e => child_span.remove());
        child_span.appendChild(text_span);
        child_span.appendChild(del_span);
        return child_span;
    }
    createBasicBtn(type, text, title, classname) {
        let btn_type = 'span';
        if (typeof(type) === 'string') {
            switch (type.toLowerCase()) {
                case 'div':
                case 'd':
                    btn_type = 'div';
                    break;
                case 'a':
                    btn_type = 'a';
                    break;
                case 'button':
                    btn_type = 'button';
                    break;
                case 'input':
                    btn_type = 'input';
                    break;
                case 'i':
                    btn_type = 'i';
                    break;
                case 'b':
                    btn_type = 'b';
                    break;
                case 'span':
                case 's':
                default:
                    btn_type = 'span';
                    break;
            }
        }
        let btn = document.createElement(btn_type);
        btn.textContent = text ? text : '';
        btn.title = title ? title : '';
        btn.className = classname ? classname : '';
        return btn;
    }
    createBlockBtn(value, list_id, classname, type = 'span', text = '', title = '', campare = null) {
        let block_btn = this.createBasicBtn(type, text, title, classname);
        block_btn.addEventListener('click', e => {
            e.stopPropagation();
            if (value && list_id) {
                let status = true;
                if (typeof(campare) === 'function') {
                    let temp_status = campare(value);
                    if (typeof(temp_status) === 'boolean') {
                        status = temp_status;
                    }
                }
                if (status) {
                    let the_list_id = this.id + '_' + list_id;
                    let save_arr = this.extractList(the_list_id);
                    ! save_arr.includes(value) && document.getElementById(the_list_id) && document.getElementById(the_list_id).insertAdjacentElement('afterbegin', this.createListItem(value));
                }
            }
            this.saveConfig();
        });
        return block_btn;
    }
    createBigBangBtn(value, list_id, classname, type = 'span', text = '', title = '', campare = null) {
        let big_bang_btn = this.createBasicBtn(type, text, title, classname);
        big_bang_btn.addEventListener('click', e => {
            e.stopPropagation();
            if (value && list_id) {
                let the_list_id = this.id + '_' + list_id;
                this.injectionBigBangPanel(value, the_list_id, campare);
            }
        });
        return big_bang_btn;
    }
    injectionBigBangPanel(value, list_id, campare = null) {
        let presentation_div = document.createElement('div');
        presentation_div.id = this.id + '_presentationDiv';
        presentation_div.className = 'block_obj_presentation_div';
        presentation_div.addEventListener('click', function(event) {
            if (event.target === this) {
                if (presentation_div) {
                    presentation_div.remove();
                }
            }
        });
        let dialog_div = document.createElement('div');
        dialog_div.className = 'block_obj_dialog_div';
        presentation_div.appendChild(dialog_div);
        let top_part = document.createElement('div');
        top_part.className = 'block_obj_big_bang_top_part';
        let h3 = document.createElement('h3');
        h3.className = 'block_obj_big_bang_h3';
        h3.textContent = '大爆炸';
        top_part.appendChild(h3);
        let deselect_btn = this.createSpanBtn('block_obj_big_bang_deselect_btn', '取消选择', '取消全部已选择的内容', e => {
            e.stopPropagation();
            let select_arr = document.querySelectorAll('.block_obj_big_bang_text_selected');
            for (let s of select_arr) {
                s.classList.remove('block_obj_big_bang_text_selected');
            }
        });
        top_part.appendChild(deselect_btn);
        let value_array = value.replace(/\s| /gi, '').split('');
        let middle_part = document.createElement('div');
        middle_part.className = 'block_obj_big_bang_middle_part';
        let node_array = value_array.map((ele, index) => {
            let ele_node = this.createBasicBtn('span', ele, '', 'block_obj_big_bang_text');
            ele_node.setAttribute('data-index', index);
            ele_node.addEventListener('click', e => {
                e.stopPropagation();
                ele_node.classList.contains('block_obj_big_bang_text_selected') ? ele_node.classList.remove('block_obj_big_bang_text_selected') : ele_node.classList.add('block_obj_big_bang_text_selected');
            });
            return ele_node;
        });
        node_array.forEach(item => {
            middle_part.appendChild(item);
        });
        let bottom_part = document.createElement('div');
        bottom_part.className = 'block_obj_big_bang_bottom_part';
        let add_btn = this.createSpanBtn('block_obj_big_bang_add_btn', '添加', '添加选择的内容到列表中', e => {
            e.stopPropagation();
            let text_value = this.getSelectedText('block_obj_big_bang_text_selected');
            if (text_value && list_id) {
                let text_arr = this.stringToArray(text_value);
                let save_arr = this.extractList(list_id);
                text_arr.forEach(item => {
                    let status = true;
                    if (typeof(campare) === 'function') {
                        let temp_status = campare(item);
                        if (typeof(temp_status) === 'boolean') {
                            status = temp_status;
                        }
                    }
                    if (status) {
                        ! save_arr.includes(item) && document.getElementById(list_id).insertAdjacentElement('afterbegin', this.createListItem(item));
                    }
                });
                this.saveConfig();
                presentation_div.remove();
            } 
        });
        bottom_part.appendChild(add_btn);
        let copy_btn = this.createSpanBtn('block_obj_big_bang_copy_btn', '复制', '复制选择的内容到剪贴板中', e => {
            e.stopPropagation();
            let text_value = this.getSelectedText('block_obj_big_bang_text_selected');
            if (text_value) {
                Block_Obj.GM.setClipboard(text_value);
                presentation_div.remove();
            }
        });
        bottom_part.appendChild(copy_btn);
        dialog_div.appendChild(top_part);
        dialog_div.appendChild(middle_part);
        dialog_div.appendChild(bottom_part);
        document.body.appendChild(presentation_div);
    }
    getSelectedText(classname) {
        let selected_array = document.getElementsByClassName(classname);
        let last_index = -1;
        let text_value = '';
        for (let selected of selected_array) {
            let index = selected.getAttribute('data-index') || -1;
            if (Number(index) == last_index + 1) {
                text_value += selected.textContent;
            } else {
                text_value = text_value ? text_value + ',' + selected.textContent : selected.textContent;
            }
            last_index = Number(index);
        }
        return text_value;
    }
    buttonClicked(button, click_title, click_class) {
        let original_title = button.title;
        button.title = click_title;
        click_class && button.classList.add(click_class);
        timer && window.clearTimeout(timer);
        var timer = window.setTimeout(() => {
            button.title = original_title;
            button.classList.remove(click_class);
        }, 1000);
    }
    extractList(list_id) {
        let re_arr = [];
        let list_dom = document.getElementById(list_id);
        let list_arr = list_dom.getElementsByClassName('block_obj_child_text');
        for (let i = list_arr.length - 1; i >= 0; i --) {
            list_arr[i].title ? re_arr.push(list_arr[i].title) : re_arr.push(list_arr[i].textContent);
        }
        return re_arr;
    }
    stringToArray(text_string) {
        let temp_array = text_string.split(',');
        let return_array = [];
        for (let i = 0, l = temp_array.length; i < l; i ++) {
            for (let j = i + 1; j < l; j ++) {
                if (temp_array[i] === temp_array[j]) {
                    ++ i;
                    j = i;
                }
            }
            return_array.push(temp_array[i]);
        }
        return return_array;
    }
    toggleList(li_classname) {
        for (let li of this.ulNode.querySelectorAll('li')) {
            if (li.classList.contains(li_classname)) {
                let list_textarea_div = li.querySelector('.block_obj_list_textarea_div');
                if (list_textarea_div) {
                    list_textarea_div.classList.contains('block_obj_list_textarea_expand') ? list_textarea_div.classList.remove('block_obj_list_textarea_expand') : list_textarea_div.classList.add('block_obj_list_textarea_expand');
                }
            } else {
                li.classList.contains('block_obj_li_hide') ? li.classList.remove('block_obj_li_hide') : li.classList.add('block_obj_li_hide');
            }
        }
        for (let br of this.ulNode.querySelectorAll('br')) {
            br.classList.contains('block_obj_li_hide') ? br.classList.remove('block_obj_li_hide') : br.classList.add('block_obj_li_hide');
        }
    }
    convertArray(string_array) {
        let re_arr = [];
        if (Array.isArray(string_array)) {
            for (let i = 0; i < string_array.length; i ++) {
                try {
                    let new_reg = new RegExp(string_array[i].replace(/^\/|\/[a-z]*$/gi, ''), string_array[i].replace(/^\/.*\/[^a-z]*/i, ''));
                    re_arr.push(new_reg);
                } catch(e) {
                    console.error('Block_Obj: The transformation contains invalid regular expressions.');
                    console.error(e);
                }
            }
        }
        return re_arr;
    }
}
Block_Obj.count = 0;
Block_Obj.GM = {
    'isError': false,
    'menuCount': 0,
    'error': message => {
        if (! Block_Obj.GM.isError) {
            Block_Obj.GM.isError = true;
            alert('The required ' + message + ' method is incomplete!!!');            
        }
    },
    'warn': message => {
        console.warn('The required ' + message + ' method is incomplete!!!');
    },
    'tips': message => {
        console.info('Tips: ' + message);
    },
    'info': () => {
        if (typeof(GM_info) === 'object') {
            return GM_info;
        } else if (typeof(GM.info) === 'object') {
            return GM.info;
        } else {
            Block_Obj.GM.warn('GM_info or GM.info');
            return {
                'script': {
                    'version': 0
                },
                'scriptHandler': 'Unknown',
                'version': 0
            };
        }
    },
    'getValue': (name, defaultValue) => {
        if (typeof(GM_getValue) === 'function') {
            return GM_getValue(name, defaultValue);
        } else if (typeof(GM.getValue) === 'function') {
            return GM.getValue(name, defaultValue);
        } else {
            Block_Obj.GM.error('GM_getValue or GM.getValue');
            return null;
        }
    },
    'setValue': (name, value) => {
        if (typeof(GM_setValue) === 'function') {
            GM_setValue(name, value);
        } else if (typeof(GM.setValue) === 'function') {
            GM.setValue(name, value);
        } else {
            Block_Obj.GM.error('GM_setValue or GM.setValue');
        }
    },
    'deleteValue': async(name) => {
        if (typeof(GM_deleteValue) === 'function') {
            await GM_deleteValue(name);
        } else if (typeof(GM.deleteValue) === 'function') {
            await GM.deleteValue(name);
        } else {
            Block_Obj.GM.error('GM_deleteValue or GM.deleteValue');
        }
    },
    'listValues': () => {
        if (typeof(GM_listValues) === 'function') {
            return GM_listValues();
        } else if (typeof(GM.listValues) === 'function') {
            return GM.listValues();
        } else {
            Block_Obj.GM.error('GM_listValues or GM.listValues');
        }
    },
    'openInTab': (url, options) => {
        if (typeof(GM_openInTab) === 'function') {
            GM_openInTab(url, options);
        } else if (typeof(GM.openItTab) === 'function') {
            GM.openInTab(url, options.active);
        } else {
            Block_Obj.GM.error('GM_openInTab or GM.openInTab');
        }
    },
    'hasOpenIntTabMethods': () => {
        return typeof(GM_openInTab) === 'function' || typeof(GM.openItTab) === 'function';
    },
    'hasRegisterMenuCommandMethods': () => {
        return typeof(GM_registerMenuCommand) === 'function';
    },
    'hasAddValueChangeListenerMethods': () => {
        return typeof(GM_addValueChangeListener) === 'function';
    },
    'registerMenuCommand': (name, fn) => {
        let menuId = null;
        if (typeof(GM_registerMenuCommand) === 'function') {
            if (Block_Obj.GM.info().scriptHandler === 'Violentmonkey') {
                Block_Obj.GM.menuCount ++;
                GM_registerMenuCommand(Block_Obj.GM.menuCount + '.' + name, fn);
                menuId = Block_Obj.GM.menuCount + '.' + name;
            } else if (Block_Obj.GM.info().scriptHandler === 'Tampermonkey') {
                menuId = GM_registerMenuCommand(name, fn);
            }
        } else {
            Block_Obj.GM.warn('GM_registerMenuCommand');
        }
        return menuId;
    },
    'unregisterMenuCommand': menuId => {
        if (typeof(GM_unregisterMenuCommand) === 'function') {
            GM_unregisterMenuCommand(menuId);
            if (Block_Obj.GM.info().scriptHandler === 'Violentmonkey') {
                Block_Obj.GM.menuCount --;
                if (Block_Obj.fn.compare('2.12.5', Block_Obj.GM.info().version)) {
                    Block_Obj.GM.tips('Maybe you should update Violentmonkey to 2.12.5 or higher.');
                }
            }
        } else {
            Block_Obj.GM.warn('GM_unregisterMenuCommand');
        }
    },
    'addValueChangeListener': (name, callback) => {
        if (typeof(GM_addValueChangeListener) === 'function') {
            return GM_addValueChangeListener(name, callback);
        } else {
            Block_Obj.GM.warn('GM_addValueChangeListener');
            return null;
        }
    },
    'removeValueChangeListener': listenerId => {
        if (typeof(GM_removeValueChangeListener) === 'function') {
            GM_removeValueChangeListener(listenerId);
        } else {
            Block_Obj.GM.warn('GM_removeValueChangeListener');
        }
    },
    'setClipboard': text => {
        if (typeof(GM_setClipboard) === 'function') {
            GM_setClipboard(text);
        } else if (typeof(GM.setClipboard) === 'function') {
            GM.setClipboard(text);
        } else {
            Block_Obj.GM.error('GM_setClipboard or GM.setClipboard');
        }
    }
};
Block_Obj.fn = {
    'hideOperation': (node, hide_status, method = 0) => {
        if (node && node instanceof HTMLElement) {
            if (hide_status) {
                if (method === 0) {
                    node.classList.add('block_obj_none');
                } else if (method === 1) {
                    node.classList.add('block_obj_hidden');
                } else if (method === 2) {
                    node.style.display = 'none';
                } else if (method === 3) {
                    node.style.visibility = 'hidden';
                }
            } else {
                if (method === 0) {
                    node.classList.remove('block_obj_none');
                } else if (method === 1) {
                    node.classList.remove('block_obj_hidden');
                } else if (method === 2) {
                    node.style.display = '';
                } else if (method === 3) {
                    node.style.visibility = '';
                }
            }
        }
    },
    compare(str1, str2, symbol = '.', equal = false) {
        let arr1 = str1.split(symbol);
        let arr2 = str2.split(symbol);
        let compare_status = false;
        let len = arr1.length < arr2.length ? arr1.length : arr2.length;
        for (let i = len - 1; i >= 0; i --) {
            if (Number(arr1[i]) > Number(arr2[i])) {
                compare_status = true;
            } else if (equal && Number(arr1[i]) == Number(arr2[i])) {
                compare_status = true;
            } else {
                compare_status = false;
            }
        }
        return compare_status;
    },
    'getVersion': () => '2.9.0'
};