Quick Search

Quick search for Google,google image, google scholar, duckduckgo, twitter, GitHub.... You don't need to enter the whole links, you just need to use `g keyword` to google search, `yt keyword`to youtube.com search. and don't worry about like 'yt ' , you just will go to youtube.com. nothing will change.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Quick Search
// @namespace    quick-search
// @homepage     https://github.com/WhyWhatHow/powertoys4browser
// @supportURL   https://github.com/WhyWhatHow/powertoys4browser/issues
// @author       whywhathow
// @version      1.9
// @icon         https://raw.githubusercontent.com/WhyWhatHow/powertoys4browser/master/icons/quick-search.ico
// @description  Quick search for Google,google image, google scholar, duckduckgo, twitter,  GitHub.... You don't need to enter the whole links, you just need to use `g keyword`  to google search, `yt keyword`to youtube.com search. and don't worry about like 'yt ' , you just will go to youtube.com. nothing will change. 
// @match        *://*/*
// @grant        GM_notification
// @license      MIT

// ==/UserScript==


const DEFAULT_SEARCH_ENGINE = "https://www.google.com/search?q=";
const searchEngines = {};

/**
 *  初始化 搜索引擎 配置信息
 */
function initSearchEngines() {

    const jsonData = {
        "phind": {
            "shortcut": "ph",
            "url": "https://phind.com/search?q="
        },

        "google": {
            "shortcut": "g",
            "url": "https://www.google.com/search?q="
        },
        "googleimages": {
            "shortcut": "gi",
            "url": "https://www.google.com/search?tbm=isch&q="
        },
        "bing": {
            "shortcut": "b",
            "url": "https://www.bing.com/search?q="
        },
        "bingimages": {
            "shortcut": "bi",
            "url": "https://www.bing.com/images/search?q="
        },
        "duckduckgo": {
            "shortcut": "d",
            "url": "https://duckduckgo.com/?q="
        },
        "wikipedia": {
            "shortcut": "w",
            "url": "https://wikipedia.org/w/index.php?search="
        },
        "youtube": {
            "shortcut": "yt",
            "url": "https://www.youtube.com/results?search_query="
        },
        "amazon": {
            "shortcut": "a",
            "url": "https://www.amazon.com/s?k="
        },
        "twitter": {
            "shortcut": "tw",
            "url": "https://twitter.com/search?q="
        },
        "googlescholar": {
            "shortcut": "s",
            "url": "https://scholar.google.com/scholar?q="
        },
        "arxiv": {
            "shortcut": "x",
            "url": "https://arxiv.org/search/?query="
        },
        "ebay": {
            "shortcut": "e",
            "url": "https://www.ebay.com/sch/i.html?_nkw="
        },
        "stackoverflow": {
            "shortcut": "so",
            "url": "https://stackoverflow.com/search?q="
        },
        "github": {
            "shortcut": "gh",
            "url": "https://github.com/search?q="
        },
        "linkedin": {
            "shortcut": "li",
            "url": "https://www.linkedin.com/search/results/all/?keywords="
        },
        "reddit": {
            "shortcut": "r",
            "url": "https://www.reddit.com/search/?q="
        },
        "wolframalpha": {
            "shortcut": "wa",
            "url": "https://www.wolframalpha.com/input/?i="
        },
        "steam": {
            "shortcut": "st",
            "url": "https://store.steampowered.com/search/?term="
        }
    };

    for (const [key, value] of Object.entries(jsonData)) {
        searchEngines[value.shortcut] = value.url;
    }
}

/***
 * 消息通知
 */
function showNotification(title, options) {
    // 检查浏览器是否支持通知
    if (!('Notification' in window)) {
        console.log('浏览器不支持通知');
        return;
    }
    // 检查通知权限
    if (Notification.permission === 'granted') {
        // 显示通知
        const notification = new Notification(title, options);

        // 点击通知时执行回调函数
        if (options && options.onClick) {
            notification.addEventListener('click', options.onClick);
        }
    } else if (Notification.permission !== 'denied') {
        // 请求通知权限
        Notification.requestPermission((permission) => {
            if (permission === 'granted') {
                // 显示通知
                const notification = new Notification(title, options);

                // 点击通知时执行回调函数
                if (options && options.onClick) {
                    notification.addEventListener('click', options.onClick);
                }
            }
        });
    }
}

/**
 * 判断是否是readwise 的插件版本
 * 是readwise 插件部分 返回true ,不是返回false
 * @returns {boolean}
 */
function isReadwise() {
    var tagName = document.activeElement.tagName;
    if ("READWISE-TOOLTIP-CONTAINER" === tagName) {
        console.log("-----------------------true---------------------")
        return true;
    }
    return false;
}

/**
 * 判断是否是 需要忽略的部分, 比如说 input textarea, 以及部分browser 插件 example: readwise
 */
function isIgnored() {
    if (!isInput() && !isReadwise()) {
        return true;
    }
    return false;
}

/***
 * 光标判断 是否是在输入框 input ,textarea
 */
function isInput() {
    var tagName = document.activeElement.tagName;
    console.log(tagName + "---------------------+");
    if (document.activeElement.tagName.toLowerCase() == "input" || document.activeElement.tagName.toLowerCase() == "textarea") {
        return true;
    } else if (document.activeElement.tagName.toLowerCase() == "div" && document.activeElement.contentEditable == "true") {
        return true;
    } else {
        return false;
    }
}

/**
 * 获取url的hostname, 即 homepage
 * @param {string} url
 */
function gengerateHomepage(url) {
    const homepageUrl = url.split("/").slice(0, 3).join("/");
    return homepageUrl;
}

/**
 *  // todo user determine open new window, or just default window
 *  页面跳转
 * @param url
 */
function redirect(url) {
    console.log("-----------------------------------search url --------------------------");
    console.log(url);
    // todo user determine open new window, or just default window
    window.location.href = url;
    // window.open(url, '_blank');
    // window.open(url);
}

/**
 * 输入窗口判断
 */
function running() {
    console.log("runing........................")
    // 弹出输入窗口
    var search = prompt(" Quick search:   ^-_-^ ");
    // 如果用户输入了内容,则进行搜索
    if (search !== null) {
        var parts = search.trim().split(" ");
        var engine = parts.shift().toLowerCase();
        var keyword = parts.join(" ");
        // 处理keyword 为空, 直接进行go to home page 
        var url = searchEngines[engine];
        if (!url) {
            // default search
            url = DEFAULT_SEARCH_ENGINE;
            keyword = engine;
        }
        console.log(url);
        if (!keyword) {
            url = gengerateHomepage(searchEngines[engine]);
        } else {
            url = searchEngines[engine] + keyword;
        }
        showNotification("now searching, please wait.....")
        redirect(url);
    }
}

/**
 * 1. init search engine
 * 2. check is in input
 */
(function () {
    'use strict';
    console.log('------------------------------------------------------')

    console.log("---------------------quick search start -------------------")
    document.addEventListener('keydown', function (event) {
        if (event.ctrlKey && event.key === 'g') {
            return;
        }
        if (event.altKey && event.shiftKey && event.key === 'g') {
            return;
        }
        if (event.key === 'g' && isIgnored()) {
            initSearchEngines();
            running();
        }
    }, true);
})();

// hints : js 匿名hanshu 执行 是 (function(){})();(function(){}) 只是定义了一个匿名函数. fuck!