aermude / AermTab

// ==UserScript==
// @name          AermTab
// @namespace     http://tampermonkey.net/
// @version       1.0
// @license        MIT
// @description   错误新页标签--当打开的页面无法链接时打开搜索页
// @author        YourName
// @match         *://*/*
// @grant         GM_addStyle
// @grant         GM_getValue
// @grant         GM_setValue
// @grant         GM_registerMenuCommand
// ==/UserScript==

(function() {
    'use strict';

    // ======================
    // 样式模块
    // ======================
    const injectStyles = () => {
        GM_addStyle(`
            :root {
                --primary-color: #4a90e2;
                --hover-color: #357abd;
                --danger-color: #ff4444;
            }

            body {
                font-family: 'Segoe UI', sans-serif;
                margin: 0;
                padding: 20px;
                background: #f0f2f5;
            }

            .container {
                max-width: 800px;
                margin: 0 auto;
            }

            header h1 {
                color: var(--primary-color);
                text-align: center;
                margin-bottom: 30px;
            }

            .search-box {
                display: flex;
                gap: 10px;
                margin-bottom: 20px;
            }

            #searchInput {
                flex: 1;
                padding: 12px 20px;
                border: 2px solid var(--primary-color);
                border-radius: 24px;
                font-size: 16px;
                transition: box-shadow 0.3s;
            }

            #searchInput:focus {
                outline: none;
                box-shadow: 0 0 8px rgba(74,144,226,0.3);
            }

            button {
                padding: 12px 24px;
                background: var(--primary-color);
                border: none;
                border-radius: 24px;
                color: white;
                cursor: pointer;
                transition: background 0.3s;
            }

            button:hover {
                background: var(--hover-color);
            }

            .links-grid {
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
                gap: 15px;
                margin-top: 30px;
            }

            .link-card {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 12px;
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                transition: transform 0.2s;
            }

            .link-card:hover {
                transform: translateY(-2px);
            }

            .link-card a {
                color: var(--primary-color);
                text-decoration: none;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }

            .delete-btn {
                color: var(--danger-color);
                cursor: pointer;
                padding: 4px;
                margin-left: 8px;
            }

            .history-panel {
                background: white;
                border-radius: 8px;
                padding: 15px;
                margin: 20px 0;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }

            .history-item {
                display: inline-block;
                margin: 5px;
                padding: 6px 12px;
                background: #e3f2fd;
                border-radius: 15px;
                cursor: pointer;
                transition: background 0.3s;
            }

            .history-item:hover {
                background: #bbdefb;
            }
        `);
    };

    // ======================
    // 模板模块
    // ======================
    const pageTemplate = () => `
        <div class="container">
            <header>
                <h1>AermTab</h1>
            </header>
            
            <div class="search-box">
                <input type="text" 
                       id="searchInput" 
                       placeholder="输入搜索内容..."
                       autocomplete="off">
                <button id="searchBtn">全网搜索</button>
            </div>

            <div class="history-panel">
                <div id="searchHistory"></div>
            </div>

            <div class="links-grid" id="linkList"></div>
        </div>
    `;

    // ======================
    // 核心功能模块
    // ======================
    class AermTab {
        constructor() {
            this.links = GM_getValue('aermtab-links', this.defaultLinks());
            this.history = GM_getValue('aermtab-history', []);
            this.init();
        }

        defaultLinks() {
            return [
                { name: '百度', url: 'https://www.baidu.com' },
                { name: 'GitHub', url: 'https://github.com' },
                { name: 'MDN', url: 'https://developer.mozilla.org' },
                { name: 'Vue', url: 'https://vuejs.org' }
            ];
        }

        init() {
            if (!this.checkEnvironment()) return;
            
            this.renderUI();
            injectStyles();
            this.bindEvents();
            this.registerMenu();
        }

        checkEnvironment() {
            const validHosts = [
                'localhost',
                '127.0.0.1',
                'chromewebdata',
                'newtab'
            ];
            return validHosts.includes(window.location.hostname.toLowerCase());
        }

        renderUI() {
            document.documentElement.innerHTML = pageTemplate();
            this.renderLinks();
            this.renderHistory();
        }

        renderLinks() {
            const container = document.getElementById('linkList');
            container.innerHTML = this.links
                .map((link, index) => `
                    <div class="link-card">
                        <a href="${link.url}" target="_blank">${link.name}</a>
                        <span class="delete-btn" data-index="${index}">×</span>
                    </div>
                `)
                .join('');
        }

        renderHistory() {
            const container = document.getElementById('searchHistory');
            container.innerHTML = this.history
                .slice(0, 15)
                .map(term => `
                    <div class="history-item" data-term="${term}">
                        ${term}
                    </div>
                `)
                .join('');
        }

        bindEvents() {
            // 搜索功能
            document.getElementById('searchBtn').addEventListener('click', () => this.performSearch());
            document.getElementById('searchInput').addEventListener('keypress', e => {
                if (e.key === 'Enter') this.performSearch();
            });

            // 事件委托
            document.body.addEventListener('click', e => {
                // 删除书签
                if (e.target.classList.contains('delete-btn')) {
                    this.deleteLink(parseInt(e.target.dataset.index));
                }
                // 点击历史记录
                if (e.target.classList.contains('history-item')) {
                    this.searchTerm(e.target.dataset.term);
                }
            });
        }

        performSearch() {
            const input = document.getElementById('searchInput');
            const term = input.value.trim();
            if (!term) return;

            // 更新搜索历史
            this.history = [
                term,
                ...this.history.filter(t => t !== term)
            ].slice(0, 30);
            
            GM_setValue('aermtab-history', this.history);
            window.location.href = `https://www.baidu.com/s?wd=${encodeURIComponent(term)}`;
        }

        searchTerm(term) {
            document.getElementById('searchInput').value = term;
            this.performSearch();
        }

        deleteLink(index) {
            this.links.splice(index, 1);
            GM_setValue('aermtab-links', this.links);
            this.renderLinks();
        }

        registerMenu() {
            GM_registerMenuCommand('添加快捷方式', () => {
                const name = prompt('输入网站名称:');
                const url = prompt('输入网站地址:');
                if (name && url) {
                    this.links.push({ name, url });
                    GM_setValue('aermtab-links', this.links);
                    this.renderLinks();
                }
            });

            GM_registerMenuCommand('清除搜索历史', () => {
                this.history = [];
                GM_setValue('aermtab-history', []);
                this.renderHistory();
            });
        }
    }

    // ======================
    // 初始化
    // ======================
    if (window.location.protocol === 'chrome-extension:') return;
    new AermTab();
})();