// ==UserScript==
// @name Metasearch
// @namespace https://github.com/Jkker/metasearch-v3
// @version 1.1.0
// @description Aggregated Searcher
// @author Jkker
// @license MIT
// @match *://google.com/search*
// @match *://*.google.com/search*
// @match *://baidu.com/s*
// @match *://*.baidu.com/s*
// @match *://zhihu.com/search*
// @match *://*.zhihu.com/search*
// @match *://bilibili.com/all*
// @match *://*.bilibili.com/all*
// @match *://duckduckgo.com/*
// @match *://*.duckduckgo.com/*
// @match *://youtube.com/results*
// @match *://*.youtube.com/results*
// @match *://github.com/search*
// @match *://*.github.com/search*
// @match *://twitter.com/search*
// @match *://*.twitter.com/search*
// @match *://wolframalpha.com/input*
// @match *://*.wolframalpha.com/input*
// @match *://weibo.com/weibo*
// @match *://*.weibo.com/weibo*
// @match *://bing.com/dict/search*
// @match *://*.bing.com/dict/search*
// @match *://youdao.com/result*
// @match *://*.youdao.com/result*
// @match *://amazon.com/s*
// @match *://*.amazon.com/s*
// @match *://ebay.com/sch/i.html*
// @match *://*.ebay.com/sch/i.html*
// @match *://jd.com/bases/m/searchKeyword.htm*
// @match *://*.jd.com/bases/m/searchKeyword.htm*
// @match *://taobao.com/search*
// @match *://*.taobao.com/search*
// @match *://mozilla.org/en-US/search*
// @match *://*.mozilla.org/en-US/search*
// @icon https://raw.githubusercontent.com/Jkker/metasearch-v3/master/src/favicon.ico
// @grant none
// @supportURL https://github.com/Jkker/metasearch-v3/issues
// @downloadURL none
// ==/UserScript==
(function() {
"use strict";
const styles = "";
const allEngines = [
{
name: "Google",
key: "google",
disabled: false,
url: "https://www.google.com/search?igu=1&pws=0&gl=us&gws_rd=cr&source=hp&newwindow=1&q=%s&oq=%s&safe=off",
matchSite: /^https?:\/\/www\.google(?:\.[A-z]{2,3}){1,2}\/[^?]+\?(?!tbm=)(?:&?q=|(?:[^#](?!&tbm=))+?&q=)(?:.(?!&tbm=))*$|(^https?:\/\/xn--flw351e\.ml\/search\?q=)/,
preload: false,
embeddable: true,
weight: 10,
url_scheme: "",
lightness: 0.607843137254902,
color: "#4285F4",
icon: ''
},
{
name: "\u767E\u5EA6",
key: "baidu",
disabled: false,
url: "https://www.baidu.com/s?ie=utf-8&word=%s",
matchSite: /^https?:\/\/www\.baidu\.com\/(?:s|baidu)/,
preload: false,
embeddable: true,
weight: 9,
lightness: 0.5078431372549019,
color: "#556dea",
icon: '',
q: "wd"
},
{
name: "\u77E5\u4E4E",
key: "zhihu",
preload: false,
disabled: false,
url: "https://www.zhihu.com/search?type=content&q=%s",
matchSite: /^https?:\/\/www\.zhihu\.com\/search\?/i,
embeddable: false,
weight: 8,
url_scheme: "zhihu://search?q=%s",
lightness: 0.5,
color: "#0084FF",
icon: ''
},
{
name: "bilibili",
key: "bilibili",
preload: false,
disabled: false,
url: "https://search.bilibili.com/all?keyword=%s",
matchSite: /^https?:\/\/search\.bilibili\.com\/all/,
q: "keyword",
embeddable: true,
weight: 7,
url_scheme: "bilibili://search?keyword=%s",
lightness: 0.6431372549019607,
color: "#DF698C",
icon: ''
},
{
name: "DDG",
key: "duckduckgo",
url: "https://duckduckgo.com/?q=%s&kaj=m&k1=-1&kn=1&kp=-2",
matchSite: /^https?:\/\/duckduckgo\.com\/*/i,
preload: false,
embeddable: true,
weight: 6,
disabled: false,
lightness: 0.6039215686274509,
color: "#E37151",
icon: ''
},
{
name: "Reddit",
key: "reddit",
disabled: false,
url: "https://www.google.com/search?q=%s+site%3Areddit.com",
matchSite: (url2, query) => {
var _a, _b, _c;
return url2.includes("google.com") && ((_c = (_b = decodeURIComponent((_a = query.get("q")) != null ? _a : "")) == null ? void 0 : _b.includes) == null ? void 0 : _c.call(_b, "site:reddit.com"));
},
q: (url2, query) => {
var _a, _b, _c;
return (_c = (_b = decodeURIComponent((_a = query.get("q")) != null ? _a : "")).replace) == null ? void 0 : _c.call(_b, "site:reddit.com", "");
},
preload: false,
embeddable: true,
weight: 6,
url_scheme: "",
lightness: 0.5372549019607843,
color: "#eb5527",
icon: ''
},
{
name: "YouTube",
key: "youtube",
preload: false,
disabled: false,
url: "https://www.youtube.com/results?search_query=%s",
matchSite: /^https?:\/\/www\.youtube\.com\/results/,
q: "search_query",
embeddable: true,
weight: 6,
url_scheme: "youtube://YouTube.com/results?search_query=%s",
lightness: 0.5254901960784314,
color: "#ea3322",
icon: ''
},
{
name: "Github",
key: "github",
preload: false,
disabled: false,
url: "https://github.com/search?q=%s",
matchSite: /^https?:\/\/github\.com\/search/,
embeddable: true,
weight: 5,
lightness: 0.09215686274509804,
color: "#181717",
icon: ''
},
{
name: "Twitter",
key: "twitter",
preload: false,
disabled: false,
url: "https://twitter.com/search?q=%s",
matchSite: /^https?:\/\/twitter\.com\/search/,
embeddable: true,
weight: 2,
lightness: 0.5254901960784314,
color: "#1da1f2",
icon: ''
},
{
name: "Wolfram",
key: "wolfram",
preload: false,
disabled: false,
url: "https://www.wolframalpha.com/input?i=%s",
matchSite: /^https?:\/\/www\.wolframalpha\.com\/input/,
embeddable: true,
weight: 4,
lightness: 0.5254901960784314,
color: "#e87242",
icon: '',
q: "i"
},
{
name: "\u4ECA\u65E5\u5934\u6761",
key: "toutiao",
preload: false,
disabled: true,
url: "https://so.toutiao.com/search?keyword=%s",
q: "keyword",
embeddable: true,
weight: 4,
lightness: 0.5764705882352941,
color: "#dd5049",
icon: ''
},
{
name: "\u5FAE\u535A",
key: "weibo",
preload: false,
disabled: false,
url: "https://s.weibo.com/weibo?q=%s",
matchSite: /^https?:\/\/s\.weibo\.com\/weibo\//i,
embeddable: true,
weight: 3.5,
url_scheme: "sinaweibo://searchall?q=%s",
lightness: 0.5156862745098039,
color: "#d33436",
icon: ''
},
{
name: "Quora",
key: "quora",
url: "https://www.google.com/search?q=%s+site%3Aquora.com",
matchSite: (url2, query) => {
var _a, _b, _c;
return url2.includes("google.com") && ((_c = (_b = decodeURIComponent((_a = query.get("q")) != null ? _a : "")) == null ? void 0 : _b.includes) == null ? void 0 : _c.call(_b, "site:quora.com"));
},
q: (url2, query) => {
var _a, _b, _c;
return (_c = (_b = decodeURIComponent((_a = query.get("q")) != null ? _a : "")).replace) == null ? void 0 : _c.call(_b, "site:quora.com", "");
},
url_scheme: "",
preload: false,
embeddable: true,
weight: 3,
disabled: false,
lightness: 0.42549019607843136,
color: "#aa382f",
icon: ''
},
{
name: "Bing \u8BCD\u5178",
key: "bingdict",
url: "https://cn.bing.com/dict/search?q=%s",
matchSite: "https://cn.bing.com/dict/search",
embeddable: false,
preload: false,
weight: 3,
disabled: false,
url_scheme: "",
lightness: 0.6,
color: "#09ABA0",
icon: ''
},
{
name: "\u6709\u9053",
key: "youdao",
preload: false,
disabled: false,
url: "https://dict.youdao.com/result?word=%s&lang=en",
matchSite: /^https?:\/\/dict\.youdao\.com\/(m\/)?result/i,
q: "word",
embeddable: true,
weight: 3,
lightness: 0.484313725490196,
color: "#E31436",
icon: ''
},
{
name: "Amazon",
key: "amazon",
preload: false,
disabled: false,
url: "https://www.amazon.com/s?k=%s",
matchSite: "amazon.com/s",
q: "k",
embeddable: true,
weight: 2,
lightness: 0.5,
color: "#FF9900",
icon: ''
},
{
name: "eBay",
key: "ebay",
url: "https://www.ebay.com/sch/i.html?_nkw=%s",
matchSite: "ebay.com/sch",
q: "_nkw",
preload: false,
embeddable: true,
weight: 2,
disabled: false,
lightness: 0.4862745098039215,
color: "#4164ea",
icon: ''
},
{
name: "\u4EAC\u4E1C",
key: "jing-dong",
preload: false,
disabled: false,
url: "https://sou.m.jd.com/bases/m/searchKeyword.htm?keyword=%s",
matchSite: "sou.m.jd.com/bases/m/searchKeyword.htm",
q: "keyword",
embeddable: true,
weight: 1,
url_scheme: 'openapp.jdmobile://virtual?params={"des":"productList","keyWord":"%s","from":"search","category":"jump"}',
lightness: 0.4941176470588235,
color: "#E1251B",
icon: ''
},
{
name: "\u6DD8\u5B9D",
key: "taobao",
preload: false,
disabled: false,
url: "https://s.taobao.com/search?q=%s",
matchSite: "s.taobao.com/search",
embeddable: true,
weight: 1,
url_scheme: "taobao://s.taobao.com?q=%s",
lightness: 0.5196078431372548,
color: "#E94F20",
icon: ''
},
{
name: "MDN",
key: "mdnwebdocs",
preload: false,
disabled: false,
url: "https://developer.mozilla.org/en-US/search?q=%s",
matchSite: "developer.mozilla.org/en-US/search",
embeddable: true,
weight: -1,
lightness: 0,
color: "#000000",
icon: ''
},
{
name: "\u5FAE\u4FE1",
key: "wechat",
preload: false,
disabled: true,
url: "https://weixin.sogou.com/weixin?p=01030402&query=%s&type=2&ie=utf8",
q: "query",
embeddable: true,
weight: -2,
lightness: 0.39215686274509803,
color: "#07C160",
icon: ''
}
];
const engines = allEngines.filter((e) => !e.disabled).sort((a, b) => b.weight - a.weight);
function Button({ icon, color, name, display, lightness, href }) {
const a = document.createElement("a");
if (color)
a.style.color = color;
a.href = href;
if (!display) {
a.style.display = "none";
}
a.title = name;
a.classList.add("icon-button");
a.innerHTML = icon;
const text = document.createElement("span");
text.innerText = name;
if (lightness < 0.5) {
a.classList.add("dark-invert");
}
a.append(text);
return a;
}
const matchSite = (url2, searchParams2) => {
for (let i = engines.length - 1; i >= 0; i--) {
const e = engines[i];
if (e.matchSite instanceof RegExp) {
if (e.matchSite.test(url2)) {
return i;
}
} else if (typeof e.matchSite === "function") {
if (e.matchSite(url2, searchParams2)) {
return i;
}
} else if (typeof e.matchSite === "string") {
if (url2.includes(e.matchSite)) {
return i;
}
}
}
return -1;
};
const getQuery = (engine, url2, searchParams2) => {
if (typeof engine.q === "string") {
return searchParams2.get(engine.q);
}
if (engine.q instanceof RegExp) {
const match = engine.q.exec(window.location.href);
if (match)
return match[1];
}
if (typeof engine.q === "function") {
return engine.q(url2, searchParams2);
}
if (Array.isArray(engine.q)) {
for (let i = 0; i < engine.q.length; i++) {
const q = searchParams2.get(engine.q[i]);
if (q)
return q;
}
}
return searchParams2.get("q") || searchParams2.get("query") || null;
};
const searchParams = new URLSearchParams(window.location.search);
const url = window.location.href;
const engineIndex = matchSite(url, searchParams);
if (engineIndex !== -1) {
console.log(`\u{1F680} `, engines[engineIndex]);
const q = encodeURIComponent(
getQuery(engines[engineIndex], url, searchParams).trim()
);
const body = document.querySelector("body");
const root = document.createElement("div");
const linkContainer = document.createElement("div");
linkContainer.id = "metasearch-link-container";
root.id = "metasearch-root";
let prevScrollPosition = window.pageYOffset;
window.onscroll = function() {
const currentScrollPos = window.pageYOffset;
root.style.bottom = prevScrollPosition > currentScrollPos ? "0" : "-48px";
prevScrollPosition = currentScrollPos;
};
for (let i = 0; i < engines.length; i++) {
if (i === engineIndex)
continue;
const engine = engines[i];
const button = Button({
icon: engine.icon,
color: engine.color,
name: engine.name,
display: true,
lightness: engine.lightness,
href: engine.url.replaceAll("%s", q)
});
linkContainer.appendChild(button);
}
root.appendChild(linkContainer);
const close = document.createElement("button");
close.innerHTML = ``;
close.classList.add("icon-button");
close.id = "metasearch-close";
close.addEventListener("click", () => {
root.style.bottom = "-40px";
});
function styleInject(css,ref){if(ref===void 0){ref={}}var insertAt=ref.insertAt;if(!css||typeof document==="undefined"){return}var head=document.head||document.getElementsByTagName("head")[0];var style=document.createElement("style");style.type="text/css";if(insertAt==="top"){if(head.firstChild){head.insertBefore(style,head.firstChild)}else{head.appendChild(style)}}else{head.appendChild(style)}if(style.styleSheet){style.styleSheet.cssText=css}else{style.appendChild(document.createTextNode(css))}};styleInject(`#metasearch-root {
box-sizing: border-box;
width: 100vw;
display: flex;
position: fixed;
bottom: 0;
left: 0;
transition: all 0.1s ease-in-out;
height: 32px;
background-color: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
z-index: 999999999;
box-shadow: 0px 0px 9px rgba(0, 0, 0, 0.07);
overflow-y: hidden;
}
#metasearch-root .icon-button {
all: unset;
box-sizing: border-box;
text-decoration: none;
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
background-color: transparent;
border: 0;
outline: transparent;
cursor: pointer;
transition: all 0.15s ease-in-out;
white-space: nowrap;
-webkit-tap-highlight-color: transparent;
color: rgba(0, 0, 0, 0.8);
flex: 1 0 auto;
padding: 2px 5px;
min-width: 32px;
height: 100%;
}
#metasearch-root .icon-button > svg {
width: 20px;
height: 20px;
color: currentColor;
fill: currentColor;
stroke: currentColor;
}
@media screen and (max-width: 768px) {
#metasearch-root .icon-button > svg {
height: 24px;
width: 24px;
}
}
@media screen and (prefers-color-scheme: dark) {
#metasearch-root .icon-button {
color: white;
}
}
#metasearch-root .icon-button:hover {
filter: brightness(0.85);
background-color: rgba(0, 0, 0, 0.08);
}
@media screen and (prefers-color-scheme: dark) {
#metasearch-root .icon-button:hover.dark-invert {
filter: invert(1) hue-rotate(180deg) brightness(0.85);
}
}
#metasearch-root .icon-button:active {
-webkit-tap-highlight-color: transparent;
filter: brightness(0.7);
background-color: rgba(0, 0, 0, 0.12);
}
@media screen and (prefers-color-scheme: dark) {
#metasearch-root .icon-button:active.dark-invert {
filter: invert(1) hue-rotate(180deg) brightness(0.7);
}
}
@media screen and (max-width: 768px) {
#metasearch-root .icon-button {
padding: 0;
min-width: 40px;
}
#metasearch-root .icon-button > span {
display: none;
}
}
@media screen and (max-width: 768px) {
#metasearch-root {
height: 40px;
}
}
@media screen and (prefers-color-scheme: dark) {
#metasearch-root {
background-color: rgba(25, 25, 25, 0.7);
color: rgba(255, 255, 255, 0.8);
}
#metasearch-root .dark-invert {
filter: invert(1) hue-rotate(180deg);
}
}
#metasearch-root #metasearch-close {
box-shadow: -1px 2px 9px rgba(0, 0, 0, 0.1);
}
#metasearch-root #metasearch-link-container {
scrollbar-width: none;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
display: flex;
box-sizing: border-box;
}
#metasearch-root #metasearch-link-container::-webkit-scrollbar {
display: none;
}
body {
position: relative !important;
}`);
root.appendChild(close);
body.appendChild(root);
}
})();