必应首页自定义背景图片

在首页添加配置按钮, 配置首页样式

// ==UserScript==
// @name         必应首页自定义背景图片
// @namespace    http://tampermonkey.net/
// @version      1.0.9
// @description  在首页添加配置按钮, 配置首页样式
// @author       Ctory-Nily
// @match        https://www.bing.com/*
// @match        https://cn.bing.com/*
// @match        https://www.bing.com/
// @match        https://cn.bing.com/
// @exclude      https://www.bing.com/search*
// @exclude      https://cn.bing.com/search*
// @exclude      https://www.bing.com/account*
// @exclude      https://cn.bing.com/account*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=bing.com
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    // 等待页面加载完成
    function waitForPageLoad() {
        return new Promise(resolve => {
            if (document.readyState === 'complete') {
                resolve();
            } else {
                window.addEventListener('load', resolve);
            }
        });
    }

    // 配置存储
    const CONFIG_KEY = 'bingBackgroundConfig';
    const POSITION_KEY = 'bingButtonPosition';
    const BG_IMAGE_KEY = 'bingCustomBackground'; // localStorage中的背景图片key

    // 默认配置
    const defaultConfig = {
        removehpTriviaOuter: true,
        removemusCard: true,
        removeVsDefault: true,
        removeFooter: true,
        theme: 'system'
    };

    // 默认按钮位置
    const defaultPosition = {
        left: '10px',
        top: 'auto',
        bottom: '10px',
        right: 'auto'
    };

    // 获取当前配置
    function getConfig() {
        const saved = GM_getValue(CONFIG_KEY, JSON.stringify(defaultConfig));
        return JSON.parse(saved);
    }

    // 获取按钮位置
    function getButtonPosition() {
        const saved = GM_getValue(POSITION_KEY, JSON.stringify(defaultPosition));
        return JSON.parse(saved);
    }

    // 保存配置
    function saveConfig(config) {
        GM_setValue(CONFIG_KEY, JSON.stringify(config));
        applyConfig(config);
    }

    // 保存按钮位置
    function saveButtonPosition(position) {
        GM_setValue(POSITION_KEY, JSON.stringify(position));
    }

    // 获取背景图片
    function getBackgroundImage() {
        return localStorage.getItem(BG_IMAGE_KEY) || '';
    }

    // 保存背景图片
    function saveBackgroundImage(imageUrl) {
        if (imageUrl) {
            localStorage.setItem(BG_IMAGE_KEY, imageUrl);
        } else {
            localStorage.removeItem(BG_IMAGE_KEY);
        }
    }

    // 应用配置
    function applyConfig(config) {
        applyTheme(config.theme);

        const bgImage = getBackgroundImage();
        const imgCont = document.querySelector('.img_cont');
        const hpTopCover = document.querySelector('.hp_top_cover');

        if (bgImage) {
            if (imgCont) imgCont.style.backgroundImage = `url("${bgImage}")`;
            if (hpTopCover) hpTopCover.style.backgroundImage = `url("${bgImage}")`;
        }

        if (config.removehpTriviaOuter) {
            const musCard = document.querySelector('.musCard');
            if (musCard) musCard.remove();
        }

        if (config.removemusCard) {
            const hpTriviaOuter = document.querySelector('.hp_trivia_outer');
            if (hpTriviaOuter) hpTriviaOuter.remove();
        }

        if (config.removeVsDefault) {
            const vsDefault = document.getElementById('vs_default');
            if (vsDefault) vsDefault.remove();
        }

        if (config.removeFooter) {
            const footer = document.getElementById('footer');
            if (footer) footer.remove();
        }

        updateScrollContStyle(config.removemusCard);
    }

    // 应用主题
    function applyTheme(theme) {
        const root = document.documentElement;
        root.classList.remove('bing-theme-light', 'bing-theme-dark');

        let effectiveTheme = theme;
        if (theme === 'system') {
            effectiveTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
        }

        if (effectiveTheme === 'dark') {
            root.classList.add('bing-theme-dark');
        } else {
            root.classList.add('bing-theme-light');
        }
    }

    // 更新scroll_cont样式
    function updateScrollContStyle(removemusCard) {
        const scrollCont = document.getElementById('scroll_cont');
        if (scrollCont) {
            scrollCont.style.marginTop = removemusCard ? '47px' : '';
        }
    }

    // 添加CSS样式
    GM_addStyle(`
        :root.bing-theme-light {
            --bing-primary-color: #0078d4;
            --bing-bg-color: #ffffff;
            --bing-text-color: #000000;
            --bing-panel-bg: rgba(255, 255, 255, 0.95);
            --bing-panel-text: #333333;
            --bing-btn-hover: rgba(0, 0, 0, 0.1);
        }

        :root.bing-theme-dark {
            --bing-primary-color: #0078d4;
            --bing-bg-color: #1e1e1e;
            --bing-text-color: #ffffff;
            --bing-panel-bg: rgba(30, 30, 30, 0.95);
            --bing-panel-text: #ffffff;
            --bing-btn-hover: rgba(255, 255, 255, 0.1);
        }

        .bing-settings-btn {
            position: fixed;
            z-index: 99999;
            width: 40px;
            height: 40px;
            background: var(--bing-primary-color);
            border: none;
            border-radius: 50%;
            cursor: move;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
            touch-action: none;
            user-select: none;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        }

        .bing-settings-btn:hover {
            background: #565656;
            transform: scale(1.1);
        }

        .bing-settings-btn.dragging {
            opacity: 0.8;
            transform: scale(1.1);
            cursor: grabbing;
        }

        .bing-settings-btn.panel-open {
            cursor: default;
        }

        .bing-settings-icon {
            width: 24px;
            height: 24px;
            color: white;
            pointer-events: none;
        }

        .bing-settings-panel {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 100001;
            width: 80%;
            max-width: 400px;
            max-height: 90vh;
            overflow-y: auto;
            background: var(--bing-panel-bg);
            border-radius: 8px;
            padding: 15px;
            font-size: 14px;
            color: var(--bing-panel-text);
            font-family: 'Segoe UI', sans-serif;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
            display: none;
            backdrop-filter: blur(10px);
        }

        .bing-settings-panel h3 {
            margin: 0 0 20px 0;
            font-size: 18px;
            text-align: center;
            border-bottom: 1px solid rgba(0, 0, 0, 0.1);
            padding-bottom: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .bing-settings-section {
            margin-bottom: 20px;
        }

        .bing-settings-section h4 {
            margin: 0 0 10px 0;
            font-size: 15px;
        }

        .bing-settings-option {
            display: flex;
            align-items: center;
            margin-bottom: 12px;
        }

        .bing-settings-option label {
            cursor: pointer;
        }

        .bing-settings-option input[type="checkbox"],
        .bing-settings-option select {
            margin-right: 10px;
        }
        .bing-settings-option button {
            padding: 5px;
        }

        .bing-settings-btn-group {
            display: flex;
            gap: 10px;
            margin-top: 20px;
        }

        .bing-settings-btn-group button {
            flex: 1;
            padding: 10px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background 0.2s;
        }

        .bing-settings-btn-primary {
            background: var(--bing-primary-color);
            color: white;
        }

        .bing-settings-btn-primary:hover {
            background: #106ebe;
        }

        .bing-settings-btn-secondary {
            background: var(--bing-btn-hover);
            color: var(--bing-panel-text);
        }

        .bing-settings-btn-secondary:hover {
            background: rgba(0, 0, 0, 0.2);
        }

        #bingBgFileInput {
            display: none;
        }

        .bing-theme-selector {
            padding: 8px 12px;
            border-radius: 4px;
            border: 1px solid rgba(0, 0, 0, 0.1);
            background: var(--bing-panel-bg);
            color: var(--bing-panel-text);
            font-size: 14px;
            width: 100%;
        }

        .bing-modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 100000;
            display: none;
        }

        /* 添加这些样式到你的GM_addStyle部分 */
        .bing-settings-row {
            display: flex;
            align-items: center;
            gap: 15px;
            margin-bottom: 15px;
        }

        .bing-settings-row h4 {
            margin: 0;
            min-width: 80px; /* 给标题固定宽度保持对齐 */
        }

        .bing-theme-selector {
            flex: 1;
        }

        .bing-button-group {
            display: flex;
            gap: 10px;
            flex: 1;
        }

        .bing-settings-btn-secondary {
            flex: 1;
            white-space: nowrap;
        }

        .bing-switch {
            position: relative;
            display: inline-block;
            width: 50px;
            height: 24px;
            margin-right: 10px;
            vertical-align: middle;
        }

        .bing-switch input {
            display: none;
        }

        .bing-slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 24px;
        }

        .bing-slider:before {
            position: absolute;
            content: "";
            height: 20px;
            width: 20px;
            left: 2px;
            bottom: 2px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }

        input:checked + .bing-slider {
            background-color: #0078d4 !important;
        }

        input:checked + .bing-slider:before {
            transform: translateX(26px);
        }

        /* 暗色主题适配 */
        :root.bing-theme-dark .bing-slider {
            background-color: #555;
        }

        /* 调整选项布局 */
        .bing-settings-option {
            display: flex;
            align-items: center;
            margin-bottom: 12px;
        }

        /* 主题切换按钮样式 */
        .bing-theme-toggle {
            background: none;
            border: none;
            cursor: pointer;
            padding: 5px;
            margin-right: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: var(--bing-panel-text);
        }

        .bing-theme-toggle svg {
            width: 20px;
            height: 20px;
            fill: currentColor;
        }

        .bing-theme-toggle:hover {
            opacity: 0.8;
        }

        .bing-title-container {
            display: flex;
            align-items: center;
            justify-content: center;
        }

        /* 响应式调整 */
        @media (max-width: 600px) {
            .bing-settings-row {
                flex-direction: column;
                align-items: flex-start;
                gap: 8px;
            }

            .bing-setting-mobile-row {
                flex-direction: row !important;
                align-items: center;
            }

            .bing-settings-row h4 {
                min-width: auto;
            }

            .bing-button-group {
                width: 100%;
                flex-direction: column;
            }

            .bing-theme-selector,
            .bing-settings-btn-secondary {
                width: 100%;
                line-height: 30px;
            }
        }

        /* 添加媒体查询 */
        @media (max-width: 480px) {
            .bing-settings-panel {
                width: 80%;
                max-height: 80vh;
                padding: 10px;
            }

            .bing-settings-btn-group {
                flex-direction: column;
            }

            .bing-settings-btn-group button {
                width: 100%;
            }

            .bing-settings-section h4 {
                font-size: 14px;
            }

            .bing-settings-btn {
                width: 35px;
                height: 35px;
                inset: 350px auto auto 30px;
            }

            .bing-settings-icon {
                width: 30px;
                height: 30px;
            }
        }
    `);

    // 提示窗口
    function showSaveSuccess(message = "保存成功", duration = 1000) {
        const div = document.createElement("div");
        div.innerHTML = `✔ ${message}`;
        div.style.position = "fixed";
        div.style.top = "20%"; // 改为从顶部20%开始
        div.style.left = "50%";
        div.style.transform = "translate(-50%, -50%)";
        div.style.zIndex = "9999";
        div.style.backgroundColor = "#4caf50";
        div.style.color = "white";
        div.style.padding = "12px 24px"; // 减小内边距
        div.style.borderRadius = "6px";
        div.style.boxShadow = "0 2px 8px rgba(0, 0, 0, 0.3)";
        div.style.fontSize = "16px"; // 减小字体大小
        div.style.fontWeight = "bold";
        div.style.opacity = "1";
        div.style.transition = "opacity 0.5s ease-out";
        div.style.maxWidth = "80%"; // 限制最大宽度
        div.style.textAlign = "center";
        div.style.wordBreak = "break-word"; // 允许换行

        document.body.appendChild(div);

        setTimeout(() => {
            div.style.opacity = "0";
            setTimeout(() => div.remove(), 500);
        }, duration);
    }

    // 创建设置按钮
    function createSettingsButton() {
        const settingsBtn = document.createElement('button');
        settingsBtn.className = 'bing-settings-btn';
        settingsBtn.title = 'Bing 背景配置';
        settingsBtn.innerHTML = `
            <svg class="bing-settings-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
                <path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/>
                <circle cx="12" cy="12" r="3"/>
            </svg>
        `;

        const position = getButtonPosition();
        Object.keys(position).forEach(key => {
            if (position[key] !== 'auto') {
                settingsBtn.style[key] = position[key];
            }
        });

        document.body.appendChild(settingsBtn);
        return settingsBtn;
    }

    // 设置拖动功能
    function setupDrag(element) {
        let isDragging = false;
        let offsetX, offsetY;
        let startX, startY;
        let lastX = 0, lastY = 0;
        let velocityX = 0, velocityY = 0;
        let animationFrame;
        let allowDrag = true;

        // 添加事件监听
        element.addEventListener('mousedown', startDrag);
        element.addEventListener('touchstart', startDrag, { passive: false });

        function startDrag(e) {
            // 如果是触摸事件且有多点触控,则不处理
            if (e.touches && e.touches.length > 1) return;

            if (!allowDrag) return;

            // 记录点击位置
            const rect = element.getBoundingClientRect();
            const clientX = e.type === 'mousedown' ? e.clientX : e.touches[0].clientX;
            const clientY = e.type === 'mousedown' ? e.clientY : e.touches[0].clientY;

            offsetX = clientX - rect.left;
            offsetY = clientY - rect.top;
            startX = clientX;
            startY = clientY;
            lastX = clientX;
            lastY = clientY;

            // 停止任何现有的惯性动画
            cancelAnimationFrame(animationFrame);
            velocityX = 0;
            velocityY = 0;

            // 开始拖动
            isDragging = true;
            element.classList.add('dragging');
            element.style.transition = 'none'; // 禁用过渡效果
            document.body.style.userSelect = 'none'; // 防止选中文本

            // 添加事件监听
            document.addEventListener('mousemove', drag);
            document.addEventListener('touchmove', drag, { passive: false });
            document.addEventListener('mouseup', stopDrag);
            document.addEventListener('touchend', stopDrag);
        }

        function drag(e) {
            // 如果是触摸事件且有多点触控,则不处理
            if (e.touches && e.touches.length > 1) return;

            if (!isDragging) return;
            e.preventDefault();

            // 获取当前位置
            const clientX = e.type === 'mousemove' ? e.clientX : e.touches[0].clientX;
            const clientY = e.type === 'mousemove' ? e.clientY : e.touches[0].clientY;

            // 计算速度(用于惯性效果)
            velocityX = clientX - lastX;
            velocityY = clientY - lastY;
            lastX = clientX;
            lastY = clientY;

            // 计算新位置
            let x = clientX - offsetX;
            let y = clientY - offsetY;

            // 边界约束
            const maxX = window.innerWidth - element.offsetWidth;
            const maxY = window.innerHeight - element.offsetHeight;
            x = Math.max(0, Math.min(x, maxX));
            y = Math.max(0, Math.min(y, maxY));

            // 应用新位置
            element.style.left = `${x}px`;
            element.style.top = `${y}px`;
            element.style.bottom = 'auto';
            element.style.right = 'auto';
        }

        function stopDrag(e) {
            if (!isDragging) return;

            // 清除拖动状态
            isDragging = false;
            element.classList.remove('dragging');
            document.body.style.userSelect = '';

            // 移除事件监听
            document.removeEventListener('mousemove', drag);
            document.removeEventListener('touchmove', drag);
            document.removeEventListener('mouseup', stopDrag);
            document.removeEventListener('touchend', stopDrag);

            // 检查是否是点击而非拖动
            const clientX = e.type === 'mouseup' ? e.clientX : e.changedTouches[0].clientX;
            const clientY = e.type === 'mouseup' ? e.clientY : e.changedTouches[0].clientY;

            const movedX = Math.abs(clientX - startX);
            const movedY = Math.abs(clientY - startY);

            if (movedX < 5 && movedY < 5) {
                element.dispatchEvent(new MouseEvent('click'));
                return;
            }

            // 保存新位置
            const newPosition = {
                left: element.style.left,
                top: element.style.top,
                bottom: element.style.bottom,
                right: element.style.right
            };
            saveButtonPosition(newPosition);

            // 惯性效果
            const animate = () => {
                if (Math.abs(velocityX) < 0.1 && Math.abs(velocityY) < 0.1) {
                    element.style.transition = ''; // 恢复过渡效果
                    return;
                }

                let x = parseFloat(element.style.left) + velocityX;
                let y = parseFloat(element.style.top) + velocityY;

                // 边界约束
                const maxX = window.innerWidth - element.offsetWidth;
                const maxY = window.innerHeight - element.offsetHeight;
                x = Math.max(0, Math.min(x, maxX));
                y = Math.max(0, Math.min(y, maxY));

                // 检查是否到达边界
                if (x <= 0 || x >= maxX) velocityX = 0;
                if (y <= 0 || y >= maxY) velocityY = 0;

                element.style.left = `${x}px`;
                element.style.top = `${y}px`;
                element.style.bottom = 'auto';
                element.style.right = 'auto';

                velocityX *= 0.95; // 摩擦力
                velocityY *= 0.95;

                animationFrame = requestAnimationFrame(animate);
            };

            animationFrame = requestAnimationFrame(animate);
        }

        // 公开方法以控制拖动
        return {
            setAllowDrag: (value) => {
                allowDrag = value;
                if (!value) {
                    element.classList.remove('dragging');
                    isDragging = false;
                }
            }
        };
    }

    // 创建设置面板
    function createSettingsPanel() {
        // 创建遮罩层
        const overlay = document.createElement('div');
        overlay.className = 'bing-modal-overlay';

        // 创建面板
        const settingsPanel = document.createElement('div');
        settingsPanel.className = 'bing-settings-panel';
        settingsPanel.innerHTML = `
            <h3>
                <button class="bing-theme-toggle" id="bingThemeToggle" title="切换主题">
                    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-moon-icon lucide-moon"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>
                </button>
                <span>Bing 背景配置</span>
            </h3>

            <div class="bing-settings-section">
                <div class="bing-settings-row">
                    <h4>背景配置</h4>
                    <div class="bing-button-group">
                        <button id="bingUploadBgBtn" class="bing-settings-btn-secondary">上传背景</button>
                        <button id="bingResetBgBtn" class="bing-settings-btn-secondary">重置背景</button>
                    </div>
                </div>
            </div>

            <div class="bing-settings-section">
                <h4>元素配置</h4>
                <div class="bing-settings-option">
                    <label class="bing-switch">
                        <input type="checkbox" id="bingremovehpTriviaOuter">
                        <span class="bing-slider"></span>
                    </label>
                    <label for="bingremovehpTriviaOuter">移除问答卡片</label>
                </div>
                <div class="bing-settings-option">
                    <label class="bing-switch">
                        <input type="checkbox" id="bingremovemusCard">
                        <span class="bing-slider"></span>
                    </label>
                    <label for="bingremovemusCard">移除切换图片按钮</label>
                </div>
                <div class="bing-settings-option">
                    <label class="bing-switch">
                        <input type="checkbox" id="bingremoveVsDefault">
                        <span class="bing-slider"></span>
                    </label>
                    <label for="bingremoveVsDefault">移除设为主页按钮部分</label>
                </div>
                <div class="bing-settings-option">
                    <label class="bing-switch">
                        <input type="checkbox" id="bingremoveFooter">
                        <span class="bing-slider"></span>
                    </label>
                    <label for="bingremoveFooter">移除页脚</label>
                </div>
            </div>

            <div class="bing-settings-btn-group">
                <button id="bingSaveConfigBtn" class="bing-settings-btn-primary">保存配置</button>
                <button id="bingExportConfigBtn" class="bing-settings-btn-secondary">导出配置</button>
                <button id="bingImportConfigBtn" class="bing-settings-btn-secondary">导入配置</button>
                <button id="bingResetConfigBtn" class="bing-settings-btn-secondary">重置配置</button>
            </div>
        `;

        // 将面板添加到遮罩层
        overlay.appendChild(settingsPanel);
        document.body.appendChild(overlay);

        return {
            panel: settingsPanel,
            overlay: overlay
        };
    }

    // 初始化脚本
    async function init() {

        // 添加视口meta标签
        let meta = document.querySelector('meta[name="viewport"]');
        if (!meta) {
            meta = document.createElement('meta');
            meta.name = "viewport";
            meta.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no";
            document.head.appendChild(meta);
        }

        // 等待页面加载完成
        await waitForPageLoad();

        // 创建UI元素
        const settingsBtn = createSettingsButton();
        const { panel: settingsPanel, overlay: modalOverlay } = createSettingsPanel();
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.id = 'bingBgFileInput';
        fileInput.accept = 'image/*';
        document.body.appendChild(fileInput);

        // 设置拖动功能
        const dragController = setupDrag(settingsBtn);

        // 加载配置
        const currentConfig = getConfig();

        // 初始化UI状态
        document.getElementById('bingremovehpTriviaOuter').checked = currentConfig.removehpTriviaOuter;
        document.getElementById('bingremovemusCard').checked = currentConfig.removemusCard;
        document.getElementById('bingremoveVsDefault').checked = currentConfig.removeVsDefault;
        document.getElementById('bingremoveFooter').checked = currentConfig.removeFooter;

        // 应用配置
        applyConfig(currentConfig);

        // 事件监听
        settingsBtn.addEventListener('click', function() {
            modalOverlay.style.display = 'block';
            settingsPanel.style.display = 'block';
            settingsBtn.classList.add('panel-open');
            dragController.setAllowDrag(false);
        });

        // ESC键关闭面板
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' && modalOverlay.style.display === 'block') {
                closePanel();
            }
        });

        function closePanel() {
            modalOverlay.style.display = 'none';
            settingsPanel.style.display = 'none';
            settingsBtn.classList.remove('panel-open');
            dragController.setAllowDrag(true);
        }

        modalOverlay.addEventListener('click', function(e) {
            if (e.target === modalOverlay) {
                closePanel();
            }
        });

        // 主题切换按钮功能
        const themeToggle = document.getElementById('bingThemeToggle');
        themeToggle.addEventListener('click', function() {
            const currentTheme = getConfig().theme;
            let newTheme;

            if (currentTheme === 'system') {
                newTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'light' : 'dark';
            } else {
                newTheme = currentTheme === 'dark' ? 'light' : 'dark';
            }

            // 更新配置
            const config = getConfig();
            config.theme = newTheme;
            saveConfig(config);

            // 更新图标
            updateThemeToggleIcon(newTheme);
            applyTheme(newTheme);
        });

        // 更新主题切换图标
        function updateThemeToggleIcon(theme) {
            const isDark = theme === 'dark' || (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
            themeToggle.innerHTML = isDark ?
                `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sun-icon lucide-sun"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></svg>` :
                `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-moon-icon lucide-moon"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>`;
        }

        // 初始化主题切换图标
        updateThemeToggleIcon(currentConfig.theme);

        document.getElementById('bingUploadBgBtn').addEventListener('click', function(e) {
            e.stopPropagation();

            // 在手机上,使用accept属性限制文件类型
            fileInput.accept = 'image/jpeg,image/png,image/webp';
            fileInput.capture = 'environment'; // 允许直接拍照上传

            fileInput.click();
        });

        fileInput.addEventListener('change', function(e) {
            if (this.files && this.files[0]) {
                const file = this.files[0];

                // 可以保留一个初步的文件大小检查
                if (file.size > 5 * 1024 * 1024) { // 比如原始文件不超过5MB
                    alert('图片文件过大,请选择5MB以下的图片。脚本将尝试压缩。');
                    return;
                }

                const reader = new FileReader();
                reader.onload = function(event) {
                    const img = new Image();
                    img.onload = function() {
                        const canvas = document.createElement('canvas');
                        const MAX_WIDTH = 2560; // 最大宽度
                        const MAX_HEIGHT = 1440; // 最大高度
                        let width = img.width;
                        let height = img.height;

                        if (width > height) {
                            if (width > MAX_WIDTH) {
                                height *= MAX_WIDTH / width;
                                width = MAX_WIDTH;
                            }
                        } else {
                            if (height > MAX_HEIGHT) {
                                width *= MAX_HEIGHT / height;
                                height = MAX_HEIGHT;
                            }
                        }
                        canvas.width = width;
                        canvas.height = height;
                        const ctx = canvas.getContext('2d');
                        ctx.drawImage(img, 0, 0, width, height);

                        // 尝试使用 image/jpeg 或 image/webp 进行压缩
                        let compressedDataUrl = canvas.toDataURL('image/jpeg', 0.95); // 0.75 是压缩质量
                        console.log('Original size (approx Base64):', event.target.result.length);
                        console.log('Compressed size:', compressedDataUrl.length);

                        // 检查压缩后的大小是否仍然太大 (可选,但推荐)
                        // data:URL 长度大约是字节数的 4/3
                        if (compressedDataUrl.length > 3.5 * 1024 * 1024 * 4/3) { // 估算压缩后localStorage占用约3.5MB
                            alert('图片压缩后仍然过大,请尝试更小的图片或更高压缩率。');
                            // 可以尝试更低的质量或提示用户
                            // compressedDataUrl = canvas.toDataURL('image/jpeg', 0.6);
                            // if (compressedDataUrl.length > ...) return;
                            return;
                        }


                        try {

                            document.cookie = 'SRCHD=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';
                            document.cookie = 'SRCHUID=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';
                            document.cookie = 'SRCHUSR=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';

                            saveBackgroundImage(compressedDataUrl); // 保存压缩后的图片
                            applyConfig(getConfig());
                            showSaveSuccess('上传成功');
                        } catch (quotaError) {
                            if (quotaError.name === 'QuotaExceededError') {
                                alert('存储空间不足!即使压缩后图片仍然过大,请尝试更小的图片,或清理浏览器缓存后重试。');
                                // 考虑在这里提供清理旧背景的选项
                                // localStorage.removeItem(BG_IMAGE_KEY);
                            } else {
                                alert('发生未知错误: ' + quotaError.message);
                            }
                        } finally {
                            closePanel(); // 确保面板关闭
                        }
                    }
                    img.onerror = function() {
                        alert('无法加载图片文件。');
                        closePanel();
                    }
                    img.src = event.target.result; // 先将原始 FileReader 結果给 Image 对象
                }
                reader.onerror = function() {
                    alert('读取文件失败。');
                    closePanel();
                }
                reader.readAsDataURL(file); // 读取原始文件为 data URL
                this.value = ''; // 清空 file input
            }
        });

        document.getElementById('bingResetBgBtn').addEventListener('click', function() {
            if (confirm('确定要重置背景图片吗?')) {
                saveBackgroundImage('');
                applyConfig(getConfig());

                document.cookie = 'SRCHD=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';
                document.cookie = 'SRCHUID=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';
                document.cookie = 'SRCHUSR=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';

                location.reload();
            }
        });

        document.getElementById('bingSaveConfigBtn').addEventListener('click', function() {
            const config = getConfig();
            config.removehpTriviaOuter = document.getElementById('bingremovehpTriviaOuter').checked;
            config.removemusCard = document.getElementById('bingremovemusCard').checked;
            config.removeVsDefault = document.getElementById('bingremoveVsDefault').checked;
            config.removeFooter = document.getElementById('bingremoveFooter').checked;
            saveConfig(config);
            closePanel();

            location.reload();
        });

        document.getElementById('bingExportConfigBtn').addEventListener('click', function() {
            const config = getConfig();
            const configStr = JSON.stringify(config);
            const blob = new Blob([configStr], { type: 'application/json' });
            const url = URL.createObjectURL(blob);

            const a = document.createElement('a');
            a.href = url;
            a.download = 'bing_background_config.json';
            a.click();

            URL.revokeObjectURL(url);
        });

        document.getElementById('bingImportConfigBtn').addEventListener('click', function() {
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = '.json';

            input.onchange = e => {
                const file = e.target.files[0];
                const reader = new FileReader();

                reader.onload = event => {
                    try {
                        const config = JSON.parse(event.target.result);
                        saveConfig(config);

                        location.reload();
                    } catch (err) {
                        alert('配置文件无效');
                    }
                };

                reader.readAsText(file);
            };

            input.click();
        });

        document.getElementById('bingResetConfigBtn').addEventListener('click', function() {
            if (confirm('确定要重置所有设置为默认值吗?')) {
                saveConfig(defaultConfig);
                saveBackgroundImage('');

                document.cookie = 'SRCHD=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';
                document.cookie = 'SRCHUID=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';
                document.cookie = 'SRCHUSR=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.bing.com';

                location.reload();
            }
        });

        // 永久监听并移除不需要的元素
        const observer = new MutationObserver(function() {
            const config = getConfig();
            // 监听并移除切换按钮
            if (config.removemusCard) {
                const musCard = document.querySelector('.musCard');
                if (musCard) musCard.remove();
            }

            // 监听并移除问答卡片
            if (config.removehpTriviaOuter) {
                const hpTriviaOuter = document.querySelector('.hp_trivia_inner_new');
                if (hpTriviaOuter) hpTriviaOuter.remove();
            }

            // 监听并移除搜索框下方按钮
            if (config.removeVsDefault) {
                const vsDefault = document.getElementById('vs_default');
                if (vsDefault) vsDefault.remove();
            }

            // 监听并移除页脚
            if (config.removeFooter) {
                const footer = document.getElementById('footer');
                if (footer) footer.remove();
            }

            // 重载配置
            applyConfig(currentConfig);
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // 启动脚本
    init();
})();