ModernMonkeyConfig Edition

Easy configuration dialog builder for user scripts - Modern Edition

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/548021/1652803/ModernMonkeyConfig%20Edition.js

// ==UserScript==
// @name           ModernMonkeyConfig Edition
// @namespace      http://odyniec.net/
// @description    Easy configuration dialog builder for user scripts - Modern Edition
// @version        0.1.4
// @include        *
// ==/UserScript==

/*
 * ModernMonkeyConfig Edition
 * version 0.1.4
 * 
 * Based on MonkeyConfig by Michal Wojciechowski (odyniec.net)
 * Modernized with responsive design, modern icons, fixed header/footer
 */

function ModernMonkeyConfig() {
    var cfg = this,
        /* Data object passed to the constructor */
        data,
        /* Configuration parameters (data.parameters or data.params) */
        params,
        /* Current values of configuration parameters */
        values = {},
        /* Identifier used to store/retrieve configuration */
        storageKey,
        /* Is the configuration dialog displayed? */
        displayed,
        /* Currently displayed window/layer */
        openWin, openLayer,
        /* DOM element wrapping the configuration form */
        container,
        /* Darkened overlay used in the layer display mode */
        overlay;
    
    /**
     * Initialize configuration 
     * 
     * @param newData New data object
     */
    function init(newData) {
        data = newData;

        if (data) {
            params = data.parameters || data.params;
            
            if (data.buttons === undefined)
                /* Set default buttons */
                data.buttons = [ 'save', 'defaults', 'cancel' ];
            
            if (data.title === undefined)
                /*
                 * If GM_getMetadata is available, get the name of the script
                 * and use it in the dialog title
                 */
                if (typeof GM_getMetadata == 'function') {
                    var scriptName = GM_getMetadata('name');
                    data.title = scriptName + ' Configuration'; 
                }
                else
                    data.title = 'Configuration';
        }
        
        /* Make a safe version of title to be used as stored value identifier */ 
        var safeTitle = data && data.title ?
                data.title.replace(/[^a-zA-Z0-9]/g, '_') : '';

        storageKey = '_ModernMonkeyConfig_' + safeTitle + '_cfg';
        
        var storedValues;
        
        /* Load stored values (if present) */
        if (GM_getValue(storageKey))
            storedValues = JSON.parse(GM_getValue(storageKey));

        for (var name in params) {
            /* If there's a value defined in the passed data object, use it */
            if (params[name]['value'] !== undefined)
                set(name, params[name].value);
            /* Check if there's a stored value for this parameter */
            else if (storedValues && storedValues[name] !== undefined)
                set(name, storedValues[name]);            
            /* Otherwise, set the default value (if defined) */
            else if (params[name]['default'] !== undefined)
                set(name, params[name]['default']);
            else
                set(name, '');
        }

        if (data.menuCommand) {
            /* Add an item to the User Script Commands menu */
            var caption = data.menuCommand !== true ? data.menuCommand :
                data.title;
            
            GM_registerMenuCommand(caption, function () { cfg.open(); });
        }

        /* Expose public methods */
        cfg.open = open;
        cfg.close = close;
        cfg.get = get;
        cfg.set = function (name, value) {
            set(name, value);
            update();
        };
    }
    
    /**
     * Get the value of a configuration parameter
     * 
     * @param name Name of the configuration parameter
     * @returns Value of the configuration parameter
     */
    function get(name) {
        return values[name];
    }
    
    /**
     * Set the value of a configuration parameter
     * 
     * @param name Name of the configuration parameter
     * @param value New value of the configuration parameter
     */
    function set(name, value) {
        values[name] = value;
    }
    
    /**
     * Reset configuration parameters to default values
     */ 
    function setDefaults() {
        for (var name in params) {
            if (typeof params[name]['default'] !== 'undefined') {
                set(name, params[name]['default']);
            }
        }
    }
    
    /**
     * Render the configuration dialog
     */
    function render() {
        var html = '<div class="__ModernMonkeyConfig_layer">' +
            '<div class="__ModernMonkeyConfig_header">' +
            '<h5>' + data.title + '</h5>' +
            '<button type="button" class="__ModernMonkeyConfig_close_btn" id="__ModernMonkeyConfig_button_close">' +
            ModernMonkeyConfig.res.icons.x + 
            '</button>' +
            '</div>' +
            '<div class="__ModernMonkeyConfig_container">' +
            '<div class="__ModernMonkeyConfig_content">' +
            '<div class="__ModernMonkeyConfig_form">';

        for (var name in params) {
            html += ModernMonkeyConfig.formatters['field'](name, params[name]);
        }

        html += '</div>' +
                '</div>' +
                '</div>' +
                '<div class="__ModernMonkeyConfig_footer">' +
                '<div class="__ModernMonkeyConfig_buttons">';

        /* Render buttons */
        for (var button in data.buttons) {
            switch (data.buttons[button]) {
            case 'cancel':
                html += '<button type="button" class="__ModernMonkeyConfig_btn __ModernMonkeyConfig_btn_secondary" ' +
                    'id="__ModernMonkeyConfig_button_cancel">' +
                    ModernMonkeyConfig.res.icons.x + ' Cancel</button>';
                break;
            case 'defaults':
                html += '<button type="button" class="__ModernMonkeyConfig_btn __ModernMonkeyConfig_btn_secondary" ' +
                    'id="__ModernMonkeyConfig_button_defaults">' +
                    ModernMonkeyConfig.res.icons.rotateCounterClockwise + ' Reset</button>';
                break;
            case 'save':
                html += '<button type="button" class="__ModernMonkeyConfig_btn __ModernMonkeyConfig_btn_primary" ' +
                    'id="__ModernMonkeyConfig_button_save">' +
                    ModernMonkeyConfig.res.icons.check + ' Save</button>';
                break;
            }
        }
        
        html += '</div></div></div>';

        return html;
    }
    
    /**
     * Update the fields in the dialog to reflect current values 
     */
    function update() {
        /* Do nothing if the dialog is not currently displayed */
        if (!displayed)
            return;
        
        for (var name in params) {
            var value = values[name];
            
            switch (params[name].type) {
            case 'checkbox':
                var elem = container.querySelector('[name="' + name + '"]');
                elem.checked = !!value;
                break;
            case 'custom':
                params[name].set(value, container
                        .querySelector('#__ModernMonkeyConfig_parent_' + name));
                break;
            case 'number':
            case 'text':
            case 'color':
                var elem = container.querySelector('[name="' + name + '"]');
                elem.value = value;
                break;
            case 'select':
                var elem = container.querySelector('[name="' + name + '"]');
                
                if (elem.tagName.toLowerCase() == 'input') {
                    if (elem.type && elem.type == 'radio') {
                        /* Single selection with radio buttons */
                        elem = container.querySelector(
                            '[name="' + name + '"][value="' + value + '"]');
                        elem.checked = true;
                    }
                    else if (elem.type && elem.type == 'checkbox') {
                        /* Multiple selection with checkboxes */
                        var checkboxes = container.querySelectorAll(
                            'input[name="' + name + '"]');

                        for (var i = 0; i < checkboxes.length; i++)
                            checkboxes[i].checked = 
                                (value.indexOf(checkboxes[i].value) > -1);
                    }
                }
                else if (elem.tagName.toLowerCase() == 'select')
                    if (elem.multiple) {
                        /* Multiple selection element */
                        var options = container.querySelectorAll(
                            'select[name="' + name + '"] option');
                            
                        for (var i = 0; i < options.length; i++)
                            options[i].selected =
                                (value.indexOf(options[i].value) > -1);
                    }
                    else
                        /* Single selection element */
                        elem.value = value;
                break;
            }
        }
    }
    
    /**
     * Save button click event handler
     */
    function saveClick() {
        for (var name in params) {
            switch (params[name].type) {
            case 'checkbox':
                var elem = container.querySelector('[name="' + name + '"]');
                values[name] = elem.checked;
                break;
            case 'custom':
                values[name] = params[name].get(container
                        .querySelector('#__ModernMonkeyConfig_parent_' + name));
                break;
            case 'number':
            case 'text':
            case 'color':
                var elem = container.querySelector('[name="' + name + '"]');
                values[name] = elem.value;
                break;
            case 'select':
                var elem = container.querySelector('[name="' + name + '"]');

                if (elem.tagName.toLowerCase() == 'input') {
                    if (elem.type && elem.type == 'radio')
                        /* Single selection with radio buttons */
                        values[name] = container.querySelector(
                            '[name="' + name + '"]:checked').value;
                    else if (elem.type && elem.type == 'checkbox') {
                        /* Multiple selection with checkboxes */
                        values[name] = [];
                        var inputs = container.querySelectorAll(
                            'input[name="' + name + '"]');

                        for (var i = 0; i < inputs.length; i++)
                            if (inputs[i].checked)
                                values[name].push(inputs[i].value);
                    }
                }
                else if (elem.tagName.toLowerCase() == 'select' && elem.multiple) {
                    /* Multiple selection element */
                    values[name] = [];
                    var options = container.querySelectorAll(
                        'select[name="' + name + '"] option');

                    for (var i = 0; i < options.length; i++)
                        if (options[i].selected)
                            values[name].push(options[i].value);
                }
                else
                    values[name] = elem.value;
                break;
            }
        }
        
        GM_setValue(storageKey, JSON.stringify(values));
        
        close();
        
        if (data.onSave)
            data.onSave(values);
    }
    
    /**
     * Cancel button click event handler 
     */
    function cancelClick() {
        close();
    }
    
    /**
     * Set Defaults button click event handler
     */
    function defaultsClick() {
        setDefaults();
        update();
    }

    /**
     * Close button click event handler
     */
    function closeClick() {
        close();
    }

    /**
     * Open configuration dialog
     * 
     * @param mode
     *            Display mode ("iframe", "layer", or "window", defaults to
     *            "layer")
     * @param options
     *            Display mode options
     */
    function open(mode, options) {
        mode = mode || 'layer';
        
        function openDone() {
            /* Attach button event handlers */
            var button;
            
            if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_save'))
                button.addEventListener('click', saveClick, true);
            if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_cancel'))
                button.addEventListener('click', cancelClick, true);
            if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_defaults'))
                button.addEventListener('click', defaultsClick, true);
            if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_close'))
                button.addEventListener('click', closeClick, true);
            
            displayed = true;
            update();
        }
        
        switch (mode) {
        case 'window':        
            var windowFeatures = {
                location: 'no',
                status: 'no',
                left: window.screenX,
                top: window.screenY,
                width: 100,
                height: 100
            };
            
            /* Additional features may be specified as an option */
            if (options && options.windowFeatures)
                for (var name in options.windowFeatures)
                    windowFeatures[name] = options.windowFeatures[name];

            var featuresArray = [];
            
            for (var name in windowFeatures)
                featuresArray.push(name + '=' + windowFeatures[name]);

            var win = window.open('', data.title, featuresArray.join(','));
            
            /* Find head and body */
            var head = win.document.getElementsByTagName('head')[0],
                body = win.document.getElementsByTagName('body')[0];

            head.innerHTML = '<title>' + data.title + '</title>' + 
                '<style type="text/css">' +
                ModernMonkeyConfig.res.stylesheets.main + '</style>';
            
            body.className = '__ModernMonkeyConfig_window';
            /* Place the rendered configuration dialog inside the window body */
            body.innerHTML = render();

            /* Find the container */
            container = win.document.querySelector('.__ModernMonkeyConfig_container');
            
            /* Resize window to the dimensions of the container div */
            win.innerWidth = container.clientWidth;
            win.resizeBy(0, -win.innerHeight + container.clientHeight);
            
            /* Place the window centered relative to the parent */
            win.moveBy(Math.round((window.outerWidth - win.outerWidth) / 2),
                Math.round((window.outerHeight - win.outerHeight) / 2));
            
            openWin = win;
            
            openDone();
            
            break;
        case 'layer':
        default:
            if (!ModernMonkeyConfig.styleAdded) {
                GM_addStyle(ModernMonkeyConfig.res.stylesheets.main);
                ModernMonkeyConfig.styleAdded = true;
            }
            
            var body = document.querySelector('body');
            
            /* Create the overlay */
            overlay = document.createElement('div');
            overlay.className = '__ModernMonkeyConfig_overlay';
            overlay.addEventListener('click', function(e) {
                if (e.target === overlay) {
                    close();
                }
            }, true);
            
            body.appendChild(overlay);
            
            /* 
             * Place the rendered configuration dialog inside the overlay
             */
            overlay.innerHTML = render();
            
            /* Find the layer element */
            openLayer = overlay.querySelector('.__ModernMonkeyConfig_layer');
            container = overlay.querySelector('.__ModernMonkeyConfig_container');
            
            openDone();
            
            break;
        }
    }
    
    /**
     * Close configuration dialog 
     */
    function close() {
        if (openWin) {
            openWin.close();
            openWin = undefined;
        }
        else if (overlay) {
            overlay.parentNode.removeChild(overlay);
            overlay = undefined;
            openLayer = undefined;
        }
        
        displayed = false;
    }

    init(arguments[0]);
}

/**
 * Replace double quotes with entities so that the string can be safely used
 * in a HTML attribute
 * 
 * @param string A string
 * @returns String with double quotes replaced with entities
 */
ModernMonkeyConfig.esc = function (string) {
    return string.replace(/"/g, '&quot;');
};

ModernMonkeyConfig.HTML = {
    '_field': function (name, options, data) {
        var html;
        
        if (options.type && ModernMonkeyConfig.HTML[options.type])
            html = ModernMonkeyConfig.HTML[options.type](name, options, data);
        else
            return;
        
        if (/\[FIELD\]/.test(options.html)) {
            html = options.html.replace(/\[FIELD\]/, html);
        }
        
        return html;
    },
    '_label': function (name, options, data) {
        var label = options['label'] ||
            name.substring(0, 1).toUpperCase() + name.substring(1)
                .replace(/_/g, ' ');

        return '<label for="__ModernMonkeyConfig_field_' + name + '">' + label + '</label>';
    },
    'checkbox': function (name, options, data) {
        return '<div class="__ModernMonkeyConfig_checkbox_wrapper">' +
               '<input id="__ModernMonkeyConfig_field_' + name + 
               '" type="checkbox" name="' + name + '" class="__ModernMonkeyConfig_checkbox" />' +
               '<span class="__ModernMonkeyConfig_checkmark"></span>' +
               '</div>'; 
    },
    'custom': function (name, options, data) {
        return options.html;
    },
    'number': function (name, options, data) {
        return '<input id="__ModernMonkeyConfig_field_' + name + '" ' +
            'type="number" class="__ModernMonkeyConfig_input" ' +
            'name="' + name + '" />';
    },
    'select': function (name, options, data) {
        var choices = {}, html = '';
        
        if (options.choices.constructor == Array) {
            /* options.choices is an array -- build key/value pairs */
            for (var i = 0; i < options.choices.length; i++)
                choices[options.choices[i]] = options.choices[i];
        }
        else
            /* options.choices is an object -- use it as it is */
            choices = options.choices;

        if (!options.multiple) {
            /* Single selection */
            if (!/^radio/.test(options.variant)) {
                /* Select element */
                html += '<select id="__ModernMonkeyConfig_field_' + name + '" ' +
                    'class="__ModernMonkeyConfig_select" ' +
                    'name="' + name + '">';
            
                for (var value in choices)
                    html += '<option value="' + ModernMonkeyConfig.esc(value) + '">' +
                        choices[value] + '</option>';
                
                html += '</select>';
            }
            else {
                /* Radio buttons */
                html += '<div class="__ModernMonkeyConfig_radio_group">';
                for (var value in choices) {
                    html += '<label class="__ModernMonkeyConfig_radio_label">' +
                        '<input type="radio" name="' + name + '" ' +
                        'value="' + ModernMonkeyConfig.esc(value) + '" class="__ModernMonkeyConfig_radio" />' +
                        '<span class="__ModernMonkeyConfig_radio_mark"></span>' +
                        choices[value] + '</label>';
                }
                html += '</div>';
            }
        }
        else {
            /* Multiple selection */
            if (!/^checkbox/.test(options.variant)) {
                /* Select element */
                html += '<select id="__ModernMonkeyConfig_field_' + name + '" ' +
                    'class="__ModernMonkeyConfig_select" ' +
                    'multiple="multiple" ' +
                    'name="' + name + '">';
                
                for (var value in choices)
                    html += '<option value="' + ModernMonkeyConfig.esc(value) + '">' +
                        choices[value] + '</option>';
                
                html += '</select>';
            }
            else {
                /* Checkboxes */
                html += '<div class="__ModernMonkeyConfig_checkbox_group">';
                for (var value in choices) {
                    html += '<label class="__ModernMonkeyConfig_checkbox_label">' +
                        '<input type="checkbox" ' +
                        'name="' + name + '" ' +
                        'value="' + ModernMonkeyConfig.esc(value) + '" class="__ModernMonkeyConfig_checkbox" />' +
                        '<span class="__ModernMonkeyConfig_checkmark"></span>' +
                        choices[value] + '</label>';
                }
                html += '</div>';
            }
        }
        
        return html;
    },
    'text': function (name, options, data) {
        if (options.long)
            return '<textarea id="__ModernMonkeyConfig_field_' + name + '" ' +
                'class="__ModernMonkeyConfig_textarea" ' +
                (!isNaN(options.long) ? 'rows="' + options.long + '" ' : '') +
                'name="' + name + '"></textarea>';
        else
            return '<input id="__ModernMonkeyConfig_field_' + name + '" ' +
                'type="text" class="__ModernMonkeyConfig_input" ' +
                'name="' + name + '" />';
    },
    'color': function(name, options, data) {
        return '<input id="__ModernMonkeyConfig_field_' + name + '" ' +
            'type="color" class="__ModernMonkeyConfig_color" ' +
            'name="' + name + '" />';
    }
};

ModernMonkeyConfig.formatters = {
    'field': function (name, options, data) {
        var html = '<div class="__ModernMonkeyConfig_field_group">';

        switch (options.type) {
        case 'checkbox':
            /* Checkboxes get special treatment */
            html += '<div id="__ModernMonkeyConfig_parent_' + name + '" class="__ModernMonkeyConfig_checkbox_field">';
            html += ModernMonkeyConfig.HTML['_field'](name, options, data);
            html += ModernMonkeyConfig.HTML['_label'](name, options, data);
            html += '</div>';
            break;
        default:
            html += '<div class="__ModernMonkeyConfig_label_wrapper">';
            html += ModernMonkeyConfig.HTML['_label'](name, options, data);
            html += '</div>';
            html += '<div id="__ModernMonkeyConfig_parent_' + name + '" class="__ModernMonkeyConfig_input_wrapper">';
            html += ModernMonkeyConfig.HTML['_field'](name, options, data);
            html += '</div>';
            break;
        }
        
        html += '</div>';

        return html;
    }
};

/* Has the stylesheet been added? */
ModernMonkeyConfig.styleAdded = false;

/* Resources */
ModernMonkeyConfig.res = {};

/* Modern SVG Icons (Lucide style) */
ModernMonkeyConfig.res.icons = {
    'check': '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20,6 9,17 4,12"></polyline></svg>',
    'x': '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>',
    'rotateCounterClockwise': '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 4v6h6"></path><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>'
};

/* Modern Responsive Stylesheets with Fixed Header/Footer */
ModernMonkeyConfig.res.stylesheets = {
    'main': `
/* Reset and base styles */
.__ModernMonkeyConfig_overlay * {
    box-sizing: border-box;
}

/* Overlay */
.__ModernMonkeyConfig_overlay {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    background: rgba(0, 0, 0, 0.5) !important;
    backdrop-filter: blur(4px) !important;
    z-index: 999999 !important;
    animation: __ModernMonkeyConfig_fadeIn 0.2s ease-out !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Layer container - Fixed size */
.__ModernMonkeyConfig_layer {
    width: 280px !important;
    max-width: 90vw !important;
    max-height: 90vh !important;
    background: #ffffff !important;
    border-radius: 12px !important;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !important;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !important;
    font-size: 12px !important;
    line-height: 1.5 !important;
    color: #1f2937 !important;
    border: 1px solid #e5e7eb !important;
    display: flex !important;
    flex-direction: column !important;
    animation: __ModernMonkeyConfig_slideIn 0.3s ease-out !important;
    overflow: hidden !important;
    user-select: none !important;
}

/* Fixed Header */
.__ModernMonkeyConfig_header {
    position: relative !important;
    padding: 10px 14px !important;
    border-bottom: 1px solid #f3f4f6 !important;
    background: #ffffff !important;
    border-radius: 12px 12px 0 0 !important;
    flex-shrink: 0 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
}

.__ModernMonkeyConfig_header h5 {
    margin: 0 !important;
    padding: 0 !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    color: #111827 !important;
    line-height: 1.25 !important;
    flex: 1 !important;
}

/* Close button */
.__ModernMonkeyConfig_close_btn {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 18px !important;
    height: 18px !important;
    border: none !important;
    background: transparent !important;
    border-radius: 6px !important;
    cursor: pointer !important;
    transition: all 0.2s ease !important;
    color: #6b7280 !important;
    padding: 0 !important;
    margin: 0 !important;
}

.__ModernMonkeyConfig_close_btn:hover {
    background: #f3f4f6 !important;
    color: #374151 !important;
}

.__ModernMonkeyConfig_close_btn svg {
    width: 18px !important;
    height: 18px !important;
}

/* Scrollable Container */
.__ModernMonkeyConfig_container {
    flex: 1 !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    padding: 0 !important;
    margin: 0 !important;
}

/* Content area */
.__ModernMonkeyConfig_content {
    padding: 14px !important;
}

/* Form */
.__ModernMonkeyConfig_form {
    display: flex !important;
    flex-direction: column !important;
    gap: 20px !important;
}

/* Field groups */
.__ModernMonkeyConfig_field_group {
    display: flex !important;
    flex-direction: column !important;
    gap: 8px !important;
}

.__ModernMonkeyConfig_label_wrapper {
    display: flex !important;
    align-items: center !important;
}

.__ModernMonkeyConfig_label_wrapper label {
    font-weight: 500 !important;
    color: #374151 !important;
    font-size: 12px !important;
    margin: 0 !important;
    padding: 0 !important;
    line-height: 1.5 !important;
}

.__ModernMonkeyConfig_input_wrapper {
    display: flex !important;
    flex-direction: column !important;
}

/* Input styles */
.__ModernMonkeyConfig_input,
.__ModernMonkeyConfig_select,
.__ModernMonkeyConfig_textarea {
    width: 100% !important;
    padding: 4px 6px !important;
    border: 1px solid #d1d5db !important;
    border-radius: 6px !important;
    font-size: 12px !important;
    font-family: inherit !important;
    color: #1f2937 !important;
    background: #ffffff !important;
    transition: all 0.2s ease !important;
    margin: 0 !important;
    outline: none !important;
}

.__ModernMonkeyConfig_input:focus,
.__ModernMonkeyConfig_select:focus,
.__ModernMonkeyConfig_textarea:focus {
    border-color: #3b82f6 !important;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

.__ModernMonkeyConfig_textarea {
    resize: vertical !important;
    min-height: 80px !important;
}

.__ModernMonkeyConfig_color {
    width: 60px !important;
    height: 40px !important;
    padding: 4px !important;
    border: 1px solid #d1d5db !important;
    border-radius: 6px !important;
    background: #ffffff !important;
    cursor: pointer !important;
}

/* Checkbox styles */
.__ModernMonkeyConfig_checkbox_field {
    display: flex !important;
    align-items: center !important;
    gap: 12px !important;
    flex-direction: row-reverse !important;
    justify-content: flex-end !important;
}

.__ModernMonkeyConfig_checkbox_wrapper {
    position: relative !important;
    display: inline-block !important;
}

.__ModernMonkeyConfig_checkbox {
    opacity: 0 !important;
    position: absolute !important;
    width: 0 !important;
    height: 0 !important;
}

.__ModernMonkeyConfig_checkmark {
    display: inline-block !important;
    width: 20px !important;
    height: 20px !important;
    border: 2px solid #d1d5db !important;
    border-radius: 4px !important;
    background: #ffffff !important;
    cursor: pointer !important;
    transition: all 0.2s ease !important;
    position: relative !important;
}

.__ModernMonkeyConfig_checkbox:checked + .__ModernMonkeyConfig_checkmark {
    background: #3b82f6 !important;
    border-color: #3b82f6 !important;
}

.__ModernMonkeyConfig_checkbox:checked + .__ModernMonkeyConfig_checkmark::after {
    content: '' !important;
    position: absolute !important;
    left: 6px !important;
    top: 1px !important;
    width: 5px !important;
    height: 10px !important;
    border: solid #ffffff !important;
    border-width: 0 2px 2px 0 !important;
    transform: rotate(45deg) !important;
}

/* Radio button styles */
.__ModernMonkeyConfig_radio_group {
    display: flex !important;
    flex-direction: column !important;
    gap: 8px !important;
}

.__ModernMonkeyConfig_radio_label {
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
    cursor: pointer !important;
    font-size: 12px !important;
    color: #374151 !important;
}

.__ModernMonkeyConfig_radio {
    opacity: 0 !important;
    position: absolute !important;
    width: 0 !important;
    height: 0 !important;
}

.__ModernMonkeyConfig_radio_mark {
    display: inline-block !important;
    width: 18px !important;
    height: 18px !important;
    border: 2px solid #d1d5db !important;
    border-radius: 50% !important;
    background: #ffffff !important;
    transition: all 0.2s ease !important;
    position: relative !important;
}

.__ModernMonkeyConfig_radio:checked + .__ModernMonkeyConfig_radio_mark {
    border-color: #3b82f6 !important;
}

.__ModernMonkeyConfig_radio:checked + .__ModernMonkeyConfig_radio_mark::after {
    content: '' !important;
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    width: 8px !important;
    height: 8px !important;
    border-radius: 50% !important;
    background: #3b82f6 !important;
    transform: translate(-50%, -50%) !important;
}

/* Checkbox group styles */
.__ModernMonkeyConfig_checkbox_group {
    display: flex !important;
    flex-direction: column !important;
    gap: 8px !important;
}

.__ModernMonkeyConfig_checkbox_label {
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
    cursor: pointer !important;
    font-size: 12px !important;
    color: #374151 !important;
}

/* Fixed Footer */
.__ModernMonkeyConfig_footer {
    position: relative !important;
    padding: 10px 14px !important;
    border-top: 1px solid #f3f4f6 !important;
    background: #ffffff !important;
    border-radius: 0 0 12px 12px !important;
    flex-shrink: 0 !important;
}

/* Button styles */
.__ModernMonkeyConfig_buttons {
    display: flex !important;
    gap: 12px !important;
    justify-content: center !important;
}

.__ModernMonkeyConfig_btn {
    display: inline-flex !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 5px 8px !important;
    border-radius: 6px !important;
    font-size: 12px !important;
    font-weight: 500 !important;
    font-family: inherit !important;
    cursor: pointer !important;
    transition: all 0.2s ease !important;
    border: 1px solid transparent !important;
    text-decoration: none !important;
    outline: none !important;
    margin: 0 !important;
}

.__ModernMonkeyConfig_btn_primary {
    background: #3b82f6 !important;
    color: #ffffff !important;
    border-color: #3b82f6 !important;
}

.__ModernMonkeyConfig_btn_primary:hover {
    background: #2563eb !important;
    border-color: #2563eb !important;
    box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3) !important;
}

.__ModernMonkeyConfig_btn_secondary {
    background: #ffffff !important;
    color: #374151 !important;
    border-color: #d1d5db !important;
}

.__ModernMonkeyConfig_btn_secondary:hover {
    background: #f9fafb !important;
    border-color: #9ca3af !important;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
}

.__ModernMonkeyConfig_btn svg {
    flex-shrink: 0 !important;
}

/* Custom scrollbar */
.__ModernMonkeyConfig_container::-webkit-scrollbar {
    width: 6px !important;
}

.__ModernMonkeyConfig_container::-webkit-scrollbar-track {
    background: #f1f5f9 !important;
}

.__ModernMonkeyConfig_container::-webkit-scrollbar-thumb {
    background: #cbd5e1 !important;
    border-radius: 3px !important;
}

.__ModernMonkeyConfig_container::-webkit-scrollbar-thumb:hover {
    background: #94a3b8 !important;
}

/* Window mode styles */
body.__ModernMonkeyConfig_window {
    margin: 0 !important;
    padding: 0 !important;
    background: #f9fafb !important;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !important;
}

body.__ModernMonkeyConfig_window .__ModernMonkeyConfig_layer {
    width: 100% !important;
    height: 100vh !important;
    max-width: none !important;
    max-height: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    border: none !important;
}

/* Animations */
@keyframes __ModernMonkeyConfig_fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes __ModernMonkeyConfig_slideIn {
    from { 
        opacity: 0;
        transform: scale(0.95);
    }
    to { 
        opacity: 1;
        transform: scale(1);
    }
}

/* Responsive design */
@media (max-width: 640px) {
    .__ModernMonkeyConfig_layer {
        width: 90vw !important;
        max-height: 60vh !important;
        border-radius: 8px !important;
    }
    
    .__ModernMonkeyConfig_header,
    .__ModernMonkeyConfig_content,
    .__ModernMonkeyConfig_footer {
        padding-left: 16px !important;
        padding-right: 16px !important;
    }
    
    .__ModernMonkeyConfig_buttons {
        flex-direction: column-reverse !important;
        gap: 8px !important;
    }
    
    .__ModernMonkeyConfig_btn {
        width: 100% !important;
        justify-content: center !important;
    }
}

/* High contrast mode */
@media (prefers-contrast: high) {
    .__ModernMonkeyConfig_layer {
        border-width: 2px !important;
    }
    
    .__ModernMonkeyConfig_input,
    .__ModernMonkeyConfig_select,
    .__ModernMonkeyConfig_textarea {
        border-width: 2px !important;
    }
    
    .__ModernMonkeyConfig_btn {
        border-width: 2px !important;
    }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .__ModernMonkeyConfig_overlay,
    .__ModernMonkeyConfig_layer,
    .__ModernMonkeyConfig_input,
    .__ModernMonkeyConfig_select,
    .__ModernMonkeyConfig_textarea,
    .__ModernMonkeyConfig_btn,
    .__ModernMonkeyConfig_checkmark,
    .__ModernMonkeyConfig_radio_mark,
    .__ModernMonkeyConfig_close_btn {
        animation: none !important;
        transition: none !important;
    }
}
`
};

QingJ © 2025

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