// ==UserScript==
// @name 🔍聚合快搜
// @namespace https://ez118.github.io/
// @version 0.2
// @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.gf.qytechs.cn/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);
const a = 1;//parseFloat(match[4]);
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
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; // 如果没有找到匹配的item,返回-1
}
function isSearchEngine() {
const currentUrl = window.location.href;
return searchEngine.filter(engine => {
const prefix = engine.link.split('%s')[0];
return currentUrl.includes(prefix);
});
}
function initEle() {
// 创建搜索栏元素并添加到页面
var $quickSearchBar = $('<div>', {
class: 'userscript-quickSearchBar',
id: 'userscript-quickSearchBar'
}).appendTo('body');
var html = "";
const currentURL = window.location.href;
// 生成搜索引擎按钮的 HTML 内容
$.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');
}
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>`;
}
});
// 清理 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();
}
})();