Greasy Fork

Greasy Fork is available in English.

🔍聚合快搜

为Via设计的第三方聚合搜索栏

当前为 2024-08-04 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         🔍聚合快搜
// @namespace    https://ez118.github.io/
// @version      0.2.1
// @description  为Via设计的第三方聚合搜索栏
// @author       ZZY_WISU
// @match        *://*/*
// @license      GNU GPLv3
// @icon         data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDEyOCAxMjgiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCI+PHBhdGggZD0iTTY0IDEyOEMyOC42IDEyOCAwIDk5LjQgMCA2NFMyOC42IDAgNjQgMHM2NCAyOC42IDY0IDY0LTI4LjYgNjQtNjQgNjR6IiBzdHlsZT0iZmlsbDojZjJmN2ZmIi8+PHBhdGggZD0iTTM0LjMgNzkuNUMyMy4xIDc5LjUgMTQgNzAuNCAxNCA1OS4yIDE0IDQ4LjEgMjMuMSAzOSAzNC4zIDM5YzExLjEgMCAyMC4yIDkuMSAyMC4yIDIwLjMgMCAxMS4xLTkuMSAyMC4yLTIwLjIgMjAuMnoiIHN0eWxlPSJmaWxsOiMwMGE1ZjYiLz48cGF0aCBkPSJNNTkgMTA0Yy0xMy44IDAtMjUtMTEuMi0yNS0yNXMxMS4yLTI1IDI1LTI1IDI1IDExLjIgMjUgMjUtMTEuMiAyNS0yNSAyNXoiIHN0eWxlPSJmaWxsOiNmZjNlMDAiLz48cGF0aCBkPSJNODguMiA4MC41QzcxLjUgODAuNSA1OCA2NyA1OCA1MC4yIDU4IDMzLjUgNzEuNSAyMCA4OC4yIDIwYzE2LjggMCAzMC4zIDEzLjUgMzAuMyAzMC4yIDAgMTYuOC0xMy41IDMwLjMtMzAuMyAzMC4zeiIgc3R5bGU9ImZpbGw6I2ZmYjcwMCIvPjwvc3ZnPg==
// @run-at       document-start
// @grant        GM_registerMenuCommand
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addElement
// @grant        window.onurlchange
// @require      https://update.greasyfork.icu/scripts/499192/1402326/jquery_360.js
// ==/UserScript==

const searchEngine = [
    {
        "id":"duckduckgo",
        "name":"DuckDuckGo",
        "link":"https://duckduckgo.com/?t=h_&q=%s"
    },
    {
        "id":"bing",
        "name":"Bing",
        "link":"https://www.bing.com/search?q=%s"
    },
    {
        "id":"github",
        "name":"Github",
        "link":"https://github.com/search?q=%s&type=repositories"
    },
    {
        "id":"fdroid",
        "name":"F-Droid",
        "link":"https://search.f-droid.org/?q=%s&lang=zh_Hans"
    },
    {
        "id":"baidu",
        "name":"百度",
        "link":"https://www.baidu.com/s?wd=%s"
    }
];

var currentEngine = null; /* 存储当前正在使用的搜索引擎 */
var currentQuery = null; /* 存储当前检索词 */




function invertHex(hex) {
    hex = hex.replace("#", "");

    // 补全短的 hex 颜色代码
    if (hex.length === 3) {
        hex = hex.split('').map(c => c + c).join('');
    }

    // 确保 hex 长度为 6
    if (hex.length !== 6) {
        throw new Error("Invalid HEX color.");
    }

    // 计算反色
    let inverted = (Number(`0x${hex}`) ^ 0xFFFFFF).toString(16).toUpperCase();

    // 补全不足位数的 0
    inverted = ("000000" + inverted).slice(-6);

    return `#${inverted}`;
}

function invertRgb(rgb) {
    // 匹配 rgb(r, g, b) 格式
    const match = rgb.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
    if (!match) {
        throw new Error("Invalid RGB color.");
    }

    const r = 255 - parseInt(match[1], 10);
    const g = 255 - parseInt(match[2], 10);
    const b = 255 - parseInt(match[3], 10);

    return `rgb(${r}, ${g}, ${b})`;
}

function invertRgba(rgba) {
    // 匹配 rgba(r, g, b, a) 格式
    const match = rgba.match(/^rgba\((\d{1,3}), (\d{1,3}), (\d{1,3}), (0|0?\.\d+|1(\.0)?)\)$/);
    if (!match) {
        throw new Error("Invalid RGBA color.");
    }

    const r = 255 - parseInt(match[1], 10);
    const g = 255 - parseInt(match[2], 10);
    const b = 255 - parseInt(match[3], 10);

    return `rgba(${r}, ${g}, ${b}, 1)`;
}
function invertColor(color) {
    if (color.startsWith("#")) {
        return invertHex(color);
    } else if (color.startsWith("rgb(")) {
        return invertRgb(color);
    } else if (color.startsWith("rgba(")) {
        return invertRgba(color);
    } else {
        throw new Error("Invalid color format.");
    }
}

function findByKeyValue(array, key, value) {
    for (let i = 0; i < array.length; i++) {
        if (array[i][key] === value) {
            return i;
        }
    }
    return -1;
}

function isSearchEngine() {
    const currentUrl = new URL(window.location.href);
    return searchEngine.some(engine => {
        const prefix = engine.link.split('%s')[0];
        const engineUrl = new URL(prefix);
        return currentUrl.hostname === engineUrl.hostname && currentUrl.pathname.startsWith(engineUrl.pathname);
    });
}

function initEle() {
    // 创建搜索栏元素并添加到页面
    var $quickSearchBar = $('<div>', {
        class: 'userscript-quickSearchBar',
        id: 'userscript-quickSearchBar'
    }).appendTo('body');

    let html = '';
const currentURL = window.location.href;

$.each(searchEngine, (index, item) => {
    const link = item.link;
    const splitLink = link.split('%s');
    let prefix = null;
    let suffix = null;

    if (splitLink.length === 2) {
        prefix = splitLink[0];
        suffix = splitLink[1];
    } else if (splitLink.length > 2) {
        prefix = splitLink[0];
        suffix = splitLink.slice(1).join('%s');
    }

    console.log(`Checking ${item.name}`);
    console.log(`Prefix: ${prefix}`);
    console.log(`Suffix: ${suffix}`);
    console.log(`Current URL: ${currentURL}`);

    if (currentURL.startsWith(prefix) && currentURL.endsWith(suffix)) {
        currentEngine = item;
        currentQuery = currentURL.slice(prefix.length, currentURL.length - suffix.length);
        html += `<div class="item active" seid="${item.id}">${item.name}</div>`;
    } else {
        html += `<div class="item" seid="${item.id}">${item.name}</div>`;
    }

    console.log(`Current Query: ${currentQuery}`);
});

console.log(`Final HTML: ${html}`);

    // 清理 HTML 内容并插入到搜索栏
    $quickSearchBar.append(html + `
        <div id="userscript-quickSearchBar-optBtn">⚙️</div>
        <div class="blank"></div>
    `);

    // 添加点击事件监听器
    $("#userscript-quickSearchBar>.item").click((e) => {
        var seid = $(e.target).attr("seid");
        var seIndex = findByKeyValue(searchEngine, "id", seid);
        location.href = searchEngine[seIndex].link.replace("%s", currentQuery);
    });
}


(function () {
    'use strict';

    var websiteThemeColor = $('body').css('background-color') || "#FFF";
    var websiteFontColor = invertColor(websiteThemeColor);

    /* 适配黑暗模式 */
    if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
        /* 黑暗模式下的样式 */
        GM_addStyle(`
            .userscript-quickSearchBar{ user-select:none; background-color:` + websiteThemeColor + `; color:` + websiteFontColor + `; padding:6px 10px; font-size:12px; line-height:20px; width:100vw; height:30px; border-top:1px solid #AAA; position:fixed; bottom:-1px; left:0; right:0; display:flex; flex-direction:row; overflow-x:auto; overflow-y:hidden; box-sizing: initial; z-index:100000; }
            .userscript-quickSearchBar>.item{ margin:0px 5px; border-radius:20px; border:1px solid #ddd; padding:5px 9px; width:fit-content; flex-basis:fit-content; flex-shrink:0; cursor:pointer; background-color:transparent; }
            .userscript-quickSearchBar>.active{ border:1px solid #6d7fb4; color:#6d7fb4; }
            .userscript-quickSearchBar>.blank{ flex-basis:25px; flex-shrink:0; width:25px; }
            #userscript-quickSearchBar-optBtn{ flex-shrink:0; flex-basis:fit-content; width:fit-content; border-radius:20px; border:1px solid #ddd; padding:4px 6px; cursor:pointer; }
        `);
    } else {
        /* 日间模式下的样式 */
        GM_addStyle(`
            .userscript-quickSearchBar{ user-select:none; background-color:` + websiteThemeColor + `; color:` + websiteFontColor + `; padding:6px 10px; font-size:12px; line-height:20px; width:100vw; height:30px; border-top:1px solid #AAA; position:fixed; bottom:-1px; left:0; right:0; display:flex; flex-direction:row; overflow-x:auto; overflow-y:hidden; box-sizing: initial; z-index:100000; }
            .userscript-quickSearchBar>.item{ margin:0px 5px; border-radius:20px; border:1px solid #ddd; padding:5px 9px; width:fit-content; flex-basis:fit-content; flex-shrink:0; cursor:pointer; background-color:transparent; }
            .userscript-quickSearchBar>.active{ border:1px solid #6d7fb4; color:#6d7fb4; }
            .userscript-quickSearchBar>.blank{ flex-basis:25px; flex-shrink:0; width:25px; }
            #userscript-quickSearchBar-optBtn{ flex-shrink:0; flex-basis:fit-content; width:fit-content; border-radius:20px; border:1px solid #ddd; padding:4px 6px; cursor:pointer; }
        `);
    }

    if(isSearchEngine()){
        console.log("【提示】已保存的搜素引擎")
        initEle();

        setTimeout(()=>{
            if($("#userscript-quickSearchBar").length == 0){
                initEle();
            }
        }, 500)
    }
})();