// ==UserScript==
// @name 特别好用的搜索引擎跳转脚本
// @namespace http://tampermonkey.net/
// @license MIT
// @version 1.5.0
// @description 搜索引擎相互跳转,对页面入侵性最小,置顶显示;并且还有复制后可以选择多种搜索引擎进行搜索的功能。(已完美修复 Cloudflare 盾卡死问题 & 增加高级选词弹窗配置)
// @author Gemini
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @run-at document-start
// @downloadURL https://update.greasyfork.icu/scripts/569195/%E7%89%B9%E5%88%AB%E5%A5%BD%E7%94%A8%E7%9A%84%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E8%B7%B3%E8%BD%AC%E8%84%9A%E6%9C%AC.user.js
// @updateURL https://update.greasyfork.icu/scripts/569195/%E7%89%B9%E5%88%AB%E5%A5%BD%E7%94%A8%E7%9A%84%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E8%B7%B3%E8%BD%AC%E8%84%9A%E6%9C%AC.meta.js
// ==/UserScript==
(function() {
'use strict';
// =====================================================================
// 0. 安全防御突破:构建 Trusted Types Policy (免疫 YouTube 拦截)
// =====================================================================
const gmPolicy = (function() {
if (typeof window.trustedTypes !== 'undefined' && window.trustedTypes.createPolicy) {
try { return window.trustedTypes.createPolicy('gm_search_policy', { createHTML: (s) => s }); }
catch (e) { return { createHTML: (s) => s }; }
}
return { createHTML: (s) => s };
})();
// =====================================================================
// 1. 核心配置与引擎数据库 (Base64 源码修改区)
// =====================================================================
const PLACEHOLDER_BASE64 = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzllOWU5ZSI+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bS0xIDE3LjkzYy0zLjk1LS40OS03LTMuODUtNy03LjkzIDAtLjYyLjA4LTEuMjEuMjMtMS43OUw5IDE1djFjMCAxLjEgLjkgMiAyIDJ2MS45M3ptNi45LTEuNTRjLS41NC0xLjE3LTEuNjQtMi0yLjktMnYtMmMwLS41NS0uNDUtMS0xLTFoLTJ2LTIuNWMwLS4yOC4yMi0uNS41LS41aDRjLjU1IDAgMS0uNDUgMS0xVjhjMC0uNTUtLjQ1LTEtMS0xaC00Yy0uNTUgMC0xIC40NS0xIDF2My41aC0xdi0xLjVjMC0uNTUtLjQ1LTEtMS0xaC0xYy0uNTUgMC0xLS40NS0xLTFWNmgyYy41NSAwIDEtLjQ1IDEtMXYtLjQ2YzEuMDUtLjM0IDIuMTgtLjU0IDMuNC0uNTQgNS41MSAwIDEwIDQuNDkgMTAgMTB6Ii8+PC9zdmc+";
const DEFAULT_ENGINES = [
{ id: 'baidu', name: '百度', domain: 'baidu.com', url: 'https://www.baidu.com/s?wd=%s', icon: '', enabled: true },
{ id: 'google', name: 'Google', domain: 'google.com', url: 'https://www.google.com/search?q=%s', icon: '', enabled: true },
{ id: 'bing', name: '必应', domain: 'bing.com', url: 'https://www.bing.com/search?q=%s', icon: '', enabled: true },
{ id: 'bilibili', name: 'B站', domain: 'bilibili.com', url: 'https://search.bilibili.com/all?keyword=%s', icon: '', enabled: true },
{ id: 'youtube', name: 'YouTube', domain: 'youtube.com', url: 'https://www.youtube.com/results?search_query=%s', icon: '', enabled: true },
{ id: 'xiaohongshu', name: '小红书', domain: 'xiaohongshu.com', url: 'https://www.xiaohongshu.com/search_result?keyword=%s', icon: "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB0PSIxNzczMjQwMjk4MDQ1IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjM4OTEiIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4Ij48cGF0aCBkPSJNMCAwbTI1NiAwbDUxMiAwcTI1NiAwIDI1NiAyNTZsMCA1MTJxMCAyNTYtMjU2IDI1NmwtNTEyIDBxLTI1NiAwLTI1Ni0yNTZsMC01MTJxMC0yNTYgMjU2LTI1NloiIGZpbGw9IiNGQTJDMTkiIHAtaWQ9IjM4OTIiPjwvcGF0aD48cGF0aCBkPSJNNDQ1LjgyNCA3NjYuMjkzMzMzYzQuMTgxMzMzLTkuMTMwNjY3IDcuNjgtMTcuMDY2NjY3IDExLjQ3NzMzMy0yNC43ODkzMzNhNTEyIDUxMiAwIDAgMCAyMy4yNTMzMzQtNDkuMjM3MzMzIDI5LjE0MTMzMyAyOS4xNDEzMzMgMCAwIDEgMzQuNzczMzMzLTIxLjcxNzMzNGMyMS45NzMzMzMgMS41Nzg2NjcgNDQuMDMyIDAuNDI2NjY3IDY2Ljk4NjY2NyAwLjQyNjY2N1YzODQuODUzMzMzYy0xNS40NDUzMzMgMC0zMC42NzczMzMtMC41NTQ2NjctNDUuNzgxMzM0IDAtMTAuNTM4NjY3IDAuNTU0NjY3LTE0LjI1MDY2Ny0yLjkwMTMzMy0xMy45MDkzMzMtMTQuMTY1MzMzIDAuNzI1MzMzLTI3LjA5MzMzMyAwLTU0LjI3MiAwLTgyLjYwMjY2N2gyMTQuMjI5MzMzdjY1LjcwNjY2N2MwIDMwLjg5MDY2NyAwIDMwLjg5MDY2Ny0yOS45NTIgMzAuODkwNjY3aC0zMC4xMjI2NjZ2Mjg1Ljk1Mmg2NS4wMjRjMjYuMTk3MzMzIDAgMjYuMTk3MzMzIDAgMjYuMTk3MzMzIDI3LjUydjU3LjY0MjY2NmMwIDcuOTc4NjY3LTEuOTYyNjY3IDEyLjAzMi0xMC42MjQgMTIuMDMyLTEwMS42NzQ2NjctMC4xNzA2NjctMjAzLjM5Mi0wLjI5ODY2Ny0zMDUuMDY2NjY3LTAuMjEzMzMzYTM3LjcxNzMzMyAzNy43MTczMzMgMCAwIDEtNi40ODUzMzMtMS4zNjUzMzMiIGZpbGw9IiNGRkZGRkYiIHAtaWQ9IjM4OTMiPjwvcGF0aD48cGF0aCBkPSJNNDg2LjM1NzMzMyA1NTkuMTQ2NjY3Yy0xMy4zOTczMzMgMjcuNjA1MzMzLTI1LjE3MzMzMyA1Mi4yNjY2NjctMzcuNTQ2NjY2IDc2LjUwMTMzM2ExMS42MDUzMzMgMTEuNjA1MzMzIDAgMCAxLTguOTYgNC41MjI2NjdjLTI5Ljc4MTMzMyAwLTU5LjczMzMzMyAxLjE1Mi04OS40MjkzMzQtMS4wNjY2NjctMjkuNzM4NjY3LTIuMjE4NjY3LTQxLjY0MjY2Ny0yMS4zMzMzMzMtMjkuNzgxMzMzLTUwLjUxNzMzMyAxMy40ODI2NjctMzMuNjY0IDI5LjczODY2Ny00NC44LTk5LjJsMy40MTMzMzMtOC44MzJjLTEyLjAzMiAwLTIyLjU3MDY2NyAwLjI5ODY2Ny0zMy4xMDkzMzMgMC04LjU3NiAwLjEyOC0xNy4xNTItMC42ODI2NjctMjUuNTE0NjY3LTIuMzQ2NjY3YTMwLjAzNzczMzMgMzAuMDM3MzMzIDAgMCAxLTI1LjcyOC0zMy41MzYgMzAuNzIgMzAuNzIgMCAwIDEgMi45MDEzMzQtMTAuMTEyYzE4LjA0OC00My4zNDkzMzMgMzguMjcyLTg1Ljg0NTMzMyA1Ny43NzA2NjYtMTI4LjU1NDY2NyA2LjM1NzMzMy0xMy45OTQ2NjcgMTMuMDEzMzMzLTI3Ljc3NiAyMC4xODEzMzQtNDEuMzg2NjY2IDEuODM0NjY3LTMuNTQxMzMzIDYuMTAxMzMzLTguMDY0IDkuMzg2NjY2LTguMTkyIDI3Ljg2MTMzMy0wLjY4MjY2NyA1NS44MDgtMC4zNDEzMzMgODYuMTg2NjY3LTAuMzQxMzM0LTIuNjQ1MzMzIDYuNzg0LTQuMTM4NjY3IDExLjM5Mi02LjE0NCAxNS43MDEzMzQtMTcuMDY2NjY3IDM1LjcxMi0zNC4xNzYgNzEuMzgxMzMzLTUxLjM3MDY2NyAxMDYuOTY1MzMzLTMuNDU2IDcuMjEwNjY3LTcuNjggMTQuNzIgNS4yOTA2NjcgMjAuMjI0IDMuNDEzMzMzLTE4LjU2IDE3LjQwOC0xNS4xODkzMzMgMjkuNjEwNjY3LTE1LjE4OTMzM2g3MC40Yy0yLjk0NCA3LjA0LTQuODY0IDExLjk0NjY2Ny02Ljk5NzMzNCAxNi41OTczMzMtMjEuNzYgNDUuNDQtNDMuODYxMzMzIDkwLjUzODY2Ny02NS4yOCAxMzUuOTM2LTguNzg5MzMzIDE4LjQ3NDY2Ny01Ljg0NTMzMyAyMi45OTczMzMgMTQuNjM0NjY3IDIzLjE2OCAxMC41Mzg2NjctMC4yOTg2NjcgMjEuMjA1MzMzLTAuMzQxMzMzIDM1LjI4NTMzMy0wLjM0MTMzM20tMzguMzE0NjY2IDExMS44NzJjLTE2LjUxMiAzMy4xMDkzMzMtMzEuMjc0NjY3IDYyLjg5MDY2Ny00Ni4zNzg2NjcgOTIuNTAxMzMzYTEwLjI0IDEwLjI0IDAgMCAxLTcuNjggNC4yNjY2NjdjLTQwLjQ5MDY2Ny0wLjQyNjY2Ny04MS4wNjY2NjctMS4xOTQ2NjctMTIxLjY4NTMzMy0yLjI2MTMzNGE3OS4zMTczMzMgNzkuMzE3MzMzIDAgMCAxLTE2LjI5ODY2Ny00LjI2NjY2NmwyMi42OTg2NjctNDUuOTA5MzM0YzcuMzgxMzMzLTE1LjE4OTMzMyAxNC41OTItMzAuMjkzMzMzIDIyLjU3MDY2Ni00NC43MTQ2NjZhMTMuNjUzMzMzIDEzLjY1MzMzMyAwIDAgMSA5LjcyOC02LjRjMzcuMjA1MzMzIDEuODM0NjY3IDc0LjQxMDY2NyA0LjQzNzMzMyAxMTEuNjU4NjY3IDYuNjk4NjY2IDcuNDI0IDAuMzg0IDE0LjUwNjY2NyAwLjA4NTMzMyAyNS4zODY2NjcgMC4wODUzMzQiIGZpbGw9IiNGRkZGRkYiIHAtaWQ9IjM4OTQiPjwvcGF0aD48L3N2Zz4=", enabled: true },
{ id: 'douyin', name: '抖音', domain: 'douyin.com', url: 'https://www.douyin.com/search/%s', icon: '', enabled: true },
{ id: 'weibo', name: '微博', domain: 'weibo.com', url: 'https://s.weibo.com/weibo?q=%s', icon: '', enabled: true }
];
const DEFAULT_CONFIG = {
height: 56, fontSize: 15, gap: 20, theme: 'auto', alwaysPin: false,
showSelectionPreview: true, popupTrigger: 'auto',
engines: DEFAULT_ENGINES
};
let userConfig = GM_getValue('gm_search_config', DEFAULT_CONFIG);
if (!userConfig.engines || userConfig.engines.length === 0) userConfig.engines = DEFAULT_ENGINES;
userConfig.engines.forEach(eng => {
const defEng = DEFAULT_ENGINES.find(d => d.id === eng.id);
if (defEng) eng.icon = defEng.icon;
});
userConfig = { ...DEFAULT_CONFIG, ...userConfig };
// =====================================================================
// 2. 纯净 DOM 构建函数
// =====================================================================
function el(tag, props, children) {
const e = document.createElement(tag);
if (props) {
for (let k in props) {
if (k === 'className') e.className = props[k];
else if (k === 'dataset') { for (let d in props[k]) e.dataset[d] = props[k][d]; }
else if (k === 'style') { for (let s in props[k]) e.style[s] = props[k][s]; }
else e[k] = props[k];
}
}
if (children) {
for (let i = 0; i < children.length; i++) {
const c = children[i];
if (typeof c === 'string' || typeof c === 'number') e.appendChild(document.createTextNode(String(c)));
else if (c instanceof Node) e.appendChild(c);
}
}
return e;
}
// =====================================================================
// 3. 动态场景嗅探 & 关键词提取
// =====================================================================
function checkIsSearchPage() {
const host = window.location.hostname, path = window.location.pathname;
if (host.includes('baidu.com') && path.includes('/s')) return true;
if (host.includes('google.com') && path.includes('/search')) return true;
if (host.includes('bing.com') && path.includes('/search')) return true;
if (host.includes('search.bilibili.com')) return true;
if (host.includes('youtube.com') && path.includes('/results')) return true;
if (host.includes('xiaohongshu.com') && path.includes('/search_result')) return true;
if (host.includes('douyin.com') && path.includes('/search')) return true;
if (host.includes('weibo.com') && path.includes('/weibo')) return true;
for (let eng of userConfig.engines) {
if (eng.enabled && host.includes(eng.domain) && window.location.search) {
try {
const queryParams = new URLSearchParams(new URL(eng.url).search);
for (let [key, val] of queryParams.entries()) {
if (val.includes('%s') && new URLSearchParams(window.location.search).has(key)) return true;
}
} catch(e) {}
}
}
return false;
}
let isEngineSearchPage = checkIsSearchPage();
function getOriginalKeyword() {
const url = new URL(window.location.href), host = url.hostname;
let kw = '';
for (let eng of userConfig.engines) {
if (host.includes(eng.domain)) {
try {
const queryParams = new URLSearchParams(new URL(eng.url).search);
for (let [key, val] of queryParams.entries()) {
if (val.includes('%s')) { kw = url.searchParams.get(key); if (kw) break; }
}
} catch(e) {}
}
if (kw) break;
}
if (!kw && host.includes('douyin.com')) {
const pathParts = url.pathname.split('/');
if (pathParts[1] === 'search' && pathParts[2]) kw = decodeURIComponent(pathParts[2]);
}
if (!kw) {
const inputs = document.querySelectorAll('input[type="text"], input[type="search"]');
for (let input of inputs) { if (input.value && input.value.trim() !== '') { kw = input.value.trim(); break; } }
}
return kw ? kw.trim() : '';
}
// =====================================================================
// 4. 智能主题感知系统
// =====================================================================
function getPageLuminance() {
const getBg = (elem) => {
let bg = window.getComputedStyle(elem).backgroundColor;
return (bg === 'rgba(0, 0, 0, 0)' || bg === 'transparent') ? null : bg;
};
let bg = getBg(document.body) || getBg(document.documentElement);
if (!bg) return 'light';
let match = bg.match(/\d+/g);
if (match && match.length >= 3) {
let r = parseInt(match[0]), g = parseInt(match[1]), b = parseInt(match[2]);
return ((r * 299 + g * 587 + b * 114) / 1000) < 128 ? 'dark' : 'light';
}
return 'light';
}
function applySmartTheme() {
let theme = userConfig.theme;
if (theme === 'auto') theme = getPageLuminance();
document.documentElement.setAttribute('data-gm-theme', theme);
}
// =====================================================================
// 5. CSS 隔离与各大站基础适配
// =====================================================================
const SITE_RULES = {
'baidu.com': `#head, #s_tab { top: var(--gm-offset) !important; transition: top 0.3s ease !important; }`,
'google.com': `html.gm-search-page.gm-scrolled #searchform, html.gm-search-page.gm-scrolled .sfbg, html.gm-search-page.gm-scrolled #hdtb { margin-top: var(--gm-offset) !important; transition: margin-top 0.3s ease !important; }`,
'bing.com': `#b_header { position: sticky !important; top: var(--gm-offset) !important; z-index: 10000 !important; transition: top 0.3s ease, padding 0.3s ease !important; background-color: var(--gm-bg) !important; } html.gm-scrolled #b_header nav, html.gm-scrolled #b_header .b_scopebar, html.gm-scrolled #b_header #b_header_nav { display: none !important; } html.gm-scrolled #b_header { padding-top: 12px !important; padding-bottom: 12px !important; height: auto !important; min-height: 0 !important; }`,
'weibo.com': `
html.gm-search-page #searchapps, html.gm-search-page [class*="Nav_wrap_"], html.gm-search-page [class*="Nav_panel_"], html.gm-search-page #weibo_top_public { top: var(--gm-offset) !important; transition: top 0.3s ease !important; }
html.gm-search-page #searchapps { position: sticky !important; z-index: 9999 !important; }
`,
'xiaohongshu.com': `
html.gm-search-page #global > .header-container { top: var(--gm-offset) !important; transition: top 0.3s ease !important; z-index: 9999 !important; }
html.gm-search-page .side-bar { top: calc(var(--gm-offset) + 72px) !important; transition: top 0.3s ease !important; }
html.gm-search-page .main-container { padding-top: var(--gm-offset) !important; transition: padding-top 0.3s ease !important; }
html.gm-search-page .reds-sticky-box, html.gm-search-page .tag-search-page-sticky, html.gm-search-page .search-layout__middle { display: none !important; }
`,
'youtube.com': `
html.gm-search-page #masthead-container { top: var(--gm-offset) !important; transform: none !important; transition: top 0.3s ease !important; }
html.gm-search-page ytd-page-manager, html.gm-search-page #page-manager { margin-top: calc(56px + var(--gm-offset)) !important; transform: none !important; transition: margin-top 0.3s ease !important; }
html.gm-search-page tp-yt-app-drawer { top: calc(56px + var(--gm-offset)) !important; transition: top 0.3s ease !important; }
html.gm-search-page #chips-wrapper, html.gm-search-page ytd-feed-filter-chip-bar-renderer { top: calc(56px + var(--gm-offset)) !important; transition: top 0.3s ease !important; }
`,
'douyin.com': `
html.gm-search-page #douyin-header { top: var(--gm-offset) !important; transition: top 0.3s ease !important; z-index: 9999 !important; }
html.gm-search-page a[href="//www.douyin.com/"] { transform: translateY(var(--gm-offset)) !important; transition: transform 0.3s ease !important; z-index: 10000 !important; display: inline-block; }
html.gm-search-page #search-toolbar-container { position: sticky !important; top: calc(56px + var(--gm-offset)) !important; transition: top 0.3s ease !important; z-index: 9998 !important; }
html.gm-search-page .YDoaql1z { display: none !important; }
html.gm-search-page .hDLEI3Iz { margin-top: 0 !important; padding-top: 0 !important; }
`,
'bilibili.com': `.bili-header__bar, #biliMainHeader { position: fixed !important; top: var(--gm-offset) !important; left: 0 !important; width: 100% !important; z-index: 10000 !important; background-color: var(--gm-bg) !important; box-shadow: 0 2px 4px rgba(0,0,0,0.08) !important; transition: top 0.3s ease !important; transform: none !important; animation: none !important; } .bili-header { min-height: 64px !important; } .search-sticky-header, [class*="sticky-header"] { display: none !important; } .bili-header__bar .center-search-container, #biliMainHeader .center-search-container { display: flex !important; opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; flex: 1 1 auto !important; width: 100% !important; max-width: 500px !important; margin: 0 auto !important; } .bili-header__bar .center-search__bar, #biliMainHeader .center-search__bar { width: 100% !important; max-width: 500px !important; margin: 0 auto !important; } .center-search-container form, .center-search-container #nav-searchform { display: flex !important; flex: 1 !important; width: 100% !important; } .bili-header__bar .right-entry-text, #biliMainHeader .right-entry-text { display: inline-block !important; } .bili-header__bar .left-entry ~ div:not(.center-search-container):not(.right-entry), #biliMainHeader .left-entry ~ div:not(.center-search-container):not(.right-entry) { display: none !important; } .center-search-container .nav-search-keyword { display: none !important; } .center-search-container input::-webkit-input-placeholder, .center-search-container input::-moz-placeholder, .center-search-container input:-ms-input-placeholder, .center-search-container input::placeholder { color: transparent !important; text-shadow: none !important; } .center-search-container input { color: var(--gm-text) !important; opacity: 1 !important; -webkit-text-fill-color: var(--gm-text) !important; } .search-header .search-input { display: none !important; } .search-header { background: transparent !important; min-height: 0 !important; height: auto !important; padding-top: 20px !important; padding-bottom: 5px !important; } .bili-header__banner, .download-entry, .download-client-trigger, .bili-header .left-entry .v-popover-wrap:has(.download-client-trigger), .bili-header a[href*="//app.bilibili.com"] { display: none !important; }`
};
let isBlockVisible = isEngineSearchPage;
let isSelectionMode = false;
let lastScrollTop = 0;
const currentDomain = window.location.hostname;
let styleEl = null;
let cssText = `
:root {
--gm-config-height: ${userConfig.height}px;
--gm-config-fontsize: ${userConfig.fontSize}px;
--gm-config-gap: ${userConfig.gap}px;
--gm-offset: 0px;
--gm-bg: #ffffff; --gm-text: #222222; --gm-hover: #f5f5f5; --gm-active: #e8e8e8; --gm-border: #f0f0f0; --gm-shadow: 0 1px 3px rgba(0,0,0,0.04);
--gm-pill-bg: #e6f4ff; --gm-pill-text: #1677ff; --gm-pill-border: #91caff;
}
html[data-gm-theme="dark"], @media (prefers-color-scheme: dark) { html[data-gm-theme="auto"] {
--gm-bg: #1e1e20; --gm-text: #e0e0e0; --gm-hover: #2b2b2d; --gm-active: #3a3a3c; --gm-border: #2c2c2e; --gm-shadow: 0 1px 3px rgba(0,0,0,0.5);
--gm-pill-bg: rgba(22, 119, 255, 0.15); --gm-pill-text: #4096ff; --gm-pill-border: rgba(22, 119, 255, 0.3);
}}
html.gm-search-page { margin-top: var(--gm-offset) !important; box-sizing: border-box !important; transition: margin-top 0.3s ease !important; }
#custom-fixed-top-block {
position: fixed; top: -100px; left: 0; width: 100%; height: var(--gm-config-height);
background-color: var(--gm-bg); border-bottom: 1px solid var(--gm-border);
display: flex; align-items: center; justify-content: space-between; padding: 0 20px;
z-index: 2147483647 !important; pointer-events: auto;
transition: top 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), background-color 0.3s, box-shadow 0.3s, border 0.3s;
box-shadow: var(--gm-shadow); box-sizing: border-box; user-select: none;
}
.gm-left-zone, .gm-right-zone { flex: 1; display: flex; align-items: center; min-width: 0; }
.gm-left-zone { justify-content: flex-start; }
.gm-engines-wrapper { flex: 0 0 auto; display: flex; align-items: center; gap: var(--gm-config-gap); }
#gm-selection-preview {
display: flex; align-items: center; background: transparent; color: rgb(22, 119, 255); border: none;
padding: 0; font-size: 13px; max-width: 100%; box-sizing: border-box;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; transform: translateX(-10px); pointer-events: none; transition: opacity 0.3s ease, transform 0.3s ease;
}
#custom-fixed-top-block.gm-selection-mode #gm-selection-preview { opacity: 1; transform: translateX(0); }
.gm-engine-btn {
display: flex; align-items: center; gap: 6px; padding: calc(var(--gm-config-height) * 0.1) 14px; border-radius: 6px;
color: var(--gm-text); font-size: var(--gm-config-fontsize); font-weight: 500; cursor: pointer; transition: background 0.2s, transform 0.1s;
}
.gm-engine-btn:hover { background: var(--gm-hover); }
#custom-fixed-top-block:not(.gm-selection-mode) .gm-engine-btn.gm-active { font-weight: bold; }
.gm-engine-btn img { width: 1.1em !important; height: 1.1em !important; border-radius: 4px !important; object-fit: contain !important; display: inline-block !important; background-color: transparent !important; pointer-events: none; }
/* GUI 绝对防污染隔离 */
#gm-settings-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 340px; background: var(--gm-bg); border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); z-index: 2147483648; display: none; flex-direction: column; border: 1px solid var(--gm-border); color: var(--gm-text); overflow: hidden; text-align: left !important; }
#gm-settings-panel, #gm-settings-panel * { box-sizing: border-box !important; font-family: system-ui, -apple-system, sans-serif !important; letter-spacing: normal !important; word-spacing: normal !important; line-height: 1.5 !important; text-transform: none !important; text-shadow: none !important; white-space: normal !important; word-break: normal !important; }
#gm-settings-panel .gm-settings-header { padding: 14px 18px; border-bottom: 1px solid var(--gm-border); display: flex; justify-content: space-between; align-items: center; cursor: grab; background: var(--gm-hover); }
#gm-settings-panel .gm-settings-header:active { cursor: grabbing; }
#gm-settings-panel .gm-settings-header span:first-child { font-size: 16px !important; font-weight: bold !important; color: var(--gm-text) !important; }
#gm-settings-panel .gm-settings-close { cursor: pointer; font-size: 20px !important; font-weight: normal !important; color: #999 !important; }
#gm-settings-panel .gm-settings-close:hover { color: #ff4d4f !important; }
#gm-settings-panel .gm-tabs { display: flex; border-bottom: 1px solid var(--gm-border); }
#gm-settings-panel .gm-tab { flex: 1; text-align: center !important; padding: 12px 0; cursor: pointer; font-size: 14px !important; color: var(--gm-text); opacity: 0.6; transition: 0.2s; font-weight: normal !important; }
#gm-settings-panel .gm-tab.active { opacity: 1; font-weight: bold !important; color: #1677ff !important; border-bottom: 2px solid #1677ff !important; }
#gm-settings-panel .gm-tab-content { display: none; flex-direction: column; gap: 16px; padding: 18px; max-height: 400px; overflow-y: auto; }
#gm-settings-panel .gm-tab-content.active { display: flex; }
#gm-settings-panel .gm-setting-item { display: flex; flex-direction: column; gap: 8px; }
#gm-settings-panel .gm-setting-item-row { display: flex; flex-direction: row; justify-content: space-between; align-items: center; }
#gm-settings-panel .gm-setting-label { display: flex; justify-content: space-between; align-items: center; width: 100%; }
#gm-settings-panel .gm-setting-label span { font-size: 14px !important; color: var(--gm-text) !important; font-weight: normal !important;}
#gm-settings-panel .gm-setting-value { color: #1677ff !important; font-weight: bold !important; font-size: 14px !important; }
#gm-settings-panel input[type=range] { -webkit-appearance: none; width: 100%; height: 6px !important; background: #e5e5e5 !important; border-radius: 3px !important; outline: none; margin: 0 !important; }
#gm-settings-panel input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px !important; height: 16px !important; border-radius: 50% !important; background: #1677ff !important; cursor: pointer; border: 2px solid #fff !important; box-shadow: 0 1px 3px rgba(0,0,0,0.3) !important; }
#gm-settings-panel select, #gm-settings-panel input[type=text], #gm-settings-panel textarea { width: 100%; padding: 8px !important; border-radius: 6px !important; border: 1px solid var(--gm-border) !important; background: var(--gm-bg) !important; color: var(--gm-text) !important; font-size: 13px !important; outline: none; box-sizing: border-box; }
#gm-settings-panel input[type=text]:focus, #gm-settings-panel textarea:focus { border-color: #1677ff !important; }
#gm-settings-panel textarea { resize: vertical; min-height: 60px; }
#gm-settings-panel .gm-switch { position: relative; display: inline-block; width: 40px !important; height: 22px !important; flex-shrink: 0; }
#gm-settings-panel .gm-switch input { opacity: 0; width: 0; height: 0; margin: 0; }
#gm-settings-panel .gm-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .3s; border-radius: 22px !important; }
#gm-settings-panel .gm-slider:before { position: absolute; content: ""; height: 18px !important; width: 18px !important; left: 2px !important; bottom: 2px !important; background-color: white; transition: .3s; border-radius: 50% !important; box-shadow: 0 1px 2px rgba(0,0,0,0.2) !important; }
#gm-settings-panel input:checked + .gm-slider { background-color: #1677ff !important; }
#gm-settings-panel input:checked + .gm-slider:before { transform: translateX(18px) !important; }
#gm-settings-panel .gm-engine-list-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px; background: var(--gm-hover); border-radius: 8px; margin-bottom: 8px; }
#gm-settings-panel .gm-engine-list-item.disabled { opacity: 0.5; filter: grayscale(100%); }
#gm-settings-panel .gm-engine-info { display: flex; align-items: center; gap: 8px; flex: 1; overflow: hidden; }
#gm-settings-panel .gm-engine-info img { width: 18px !important; height: 18px !important; border-radius: 4px !important; flex-shrink: 0; }
#gm-settings-panel .gm-engine-info span { font-size: 14px !important; font-weight: 500 !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
#gm-settings-panel .gm-engine-actions { display: flex; gap: 4px; }
#gm-settings-panel .gm-action-btn { padding: 4px; cursor: pointer; font-size: 14px !important; opacity: 0.7; transition: 0.2s; border-radius: 4px; user-select: none; }
#gm-settings-panel .gm-action-btn:hover { opacity: 1; background: rgba(0,0,0,0.05); }
#gm-settings-panel .gm-primary-btn { padding: 10px; background: #1677ff; color: #fff !important; border: none; border-radius: 8px; cursor: pointer; font-weight: bold !important; font-size: 14px !important; text-align: center; }
#gm-settings-panel .gm-primary-btn:hover { background: #4096ff; }
#gm-settings-panel .gm-secondary-btn { padding: 10px; background: var(--gm-hover); color: var(--gm-text) !important; border: none; border-radius: 8px; cursor: pointer; font-size: 14px !important; text-align: center; }
`;
function injectDynamicCSS() {
let dynamicRules = '';
if (isEngineSearchPage) {
document.documentElement.classList.add('gm-search-page');
document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
for (const [domain, ruleCSS] of Object.entries(SITE_RULES)) {
if (currentDomain.includes(domain)) { dynamicRules += `\n${ruleCSS}`; break; }
}
} else {
document.documentElement.classList.remove('gm-search-page');
document.documentElement.style.setProperty('--gm-offset', '0px');
}
if(styleEl) styleEl.textContent = cssText + dynamicRules;
}
// =====================================================================
// 🚀 安全路由系统:精准特征cloudflare识别 (融合底层网络指纹,绝对防卡死)
// =====================================================================
let __gm_is_shield_locked = false;
function isShieldPage() {
// 1. 白名单免疫
if (isEngineSearchPage) return false;
if (__gm_is_shield_locked) return true;
// 2. 高危标题嗅探
const t = document.title || '';
if (/^(Just a moment|Checking your browser|Attention Required|请稍候|安全验证)/i.test(t.trim())) {
__gm_is_shield_locked = true;
return true;
}
// 🌟 3. 最致命的网络特征底层嗅探 (核心修复)
// 真正的 CF 拦截页必定会加载 challenge-platform 脚本。
// 用这个路径判断,既能 100% 抓出伪装的 CF 盾,又绝对不会误杀带验证码的普通网页!
if (document.querySelector('script[src*="/cdn-cgi/challenge-platform/"]')) {
__gm_is_shield_locked = true;
return true;
}
// 4. 专属防御容器 DOM 特征
const shieldSelectors = '#challenge-running, #cf-wrapper, .cf-browser-verification, #challenge-stage';
if (document.querySelector(shieldSelectors)) {
__gm_is_shield_locked = true;
return true;
}
// 5. 极简 DOM + 底部水印兜底
if (document.body && document.querySelectorAll('*').length < 150) {
const text = document.body.innerText || '';
if (text.includes('Ray ID:') && text.includes('Cloudflare')) {
__gm_is_shield_locked = true;
return true;
}
}
return false;
}
function bootScript() {
if (!styleEl && (document.head || document.documentElement)) {
styleEl = document.createElement('style');
styleEl.id = 'gm-search-style';
(document.head || document.documentElement).appendChild(styleEl);
injectDynamicCSS();
}
}
if (isEngineSearchPage) {
bootScript();
} else {
document.addEventListener('DOMContentLoaded', () => {
if (isShieldPage()) return;
bootScript();
});
}
function updateBarVisibility() {
const topBlock = document.getElementById('custom-fixed-top-block');
if (!topBlock) return;
if (isSelectionMode) {
topBlock.style.top = '0px';
topBlock.classList.add('gm-selection-mode');
if (isEngineSearchPage) document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
return;
} else {
topBlock.style.top = `-${userConfig.height + 20}px`;
topBlock.classList.remove('gm-selection-mode');
}
if (!isEngineSearchPage) return;
if (userConfig.alwaysPin) {
isBlockVisible = true;
topBlock.style.top = '0px';
document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
return;
}
if (isBlockVisible) {
topBlock.style.top = '0px';
document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
} else {
topBlock.style.top = `-${userConfig.height + 20}px`;
document.documentElement.style.setProperty('--gm-offset', '0px');
}
}
function renderTopBarEngines() {
const wrapper = document.querySelector('.gm-engines-wrapper');
if (!wrapper) return;
wrapper.textContent = '';
const activeEngines = userConfig.engines.filter(e => e.enabled !== false);
activeEngines.forEach(engine => {
let finalIcon = engine.icon ? engine.icon.trim() : '';
if (finalIcon.startsWith('