AlwaysBing

Always search with Bing

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name               AlwaysBing
// @namespace          AlwaysBing
// @version            1.0.0
// @description        Always search with Bing
// @description:en     Always search with Bing
// @description:zh-CN  永远使用 Bing 搜索
// @description:zh-TW  永遠使用 Bing 搜索
// @icon               https://cn.bing.com/favicon.ico
// @author             lingbopro
// @homepage           https://github.com/lingbopro/AlwaysBing
// @license            MIT
// @match              *://*.bing.com/*
// @match              *://*.baidu.com/*
// @grant              GM_setValue
// @grant              GM_getValue
// @grant              GM_registerMenuCommand
// @grant              GM_addStyle
// @grant              GM_log
// @grant              window.location
// @noframes
// ==/UserScript==

(function () {
    'use strict';

    /*
     * AlwaysBing
     * 这是一个开源的用户脚本
     * 遵循 MIT 协议
     * GitHub 存储库: https://github.com/lingbopro/AlwaysBing
     * GreasyFork: https://greasyfork.org/zh-CN/scripts/496648
     * 贡献代码前,先用 Prettier 格式化啊~
     */

    //SECTION - 配置 / CONFIG
    /*
     * --------------------
     * 这里是配置内容。
     * 如果你要修改配置,请在这里修改。
     * PS: 不要删JSDoc啊
     * --------------------
     */

    /**
     * 规则列表
     * @type {array}
     */
    let rules = [
        // TODO: 完善规则
        {
            name: '百度', // 名称
            matches: [
                // 子规则
                {
                    type: 'search', // 类型(用来匹配下方的Bing URL)
                    url: 'baidu.com/s', // URL匹配
                    query: 'wd', // 包含搜索内容的参数名称
                },
                {
                    type: 'image',
                    url: 'image.baidu.com/search',
                    query: 'word',
                },
                {
                    type: 'video',
                    url: 'baidu.com/sf/vsearch',
                    query: 'wd',
                },
            ],
        },
    ];
    /**
     * 必应的 URL
     * @type {object}
     */
    let bing = {
        search: 'https://bing.com/search?q=',
        image: 'https://bing.com/images/search?q=',
        video: 'https://bing.com/videos/search?q=',
    };
    /**
     * 读取的配置
     * @type {object}
     */
    let config = {
        rules: [
            // 每项分别对应规则的对应项
            {
                action: 'redirect',
            },
        ],
    };
    //!SECTION

    //SECTION - 逻辑 / LOGIC
    /*
     * --------------------
     * 这里是核心逻辑。
     * 如果你要修改配置,就别动这。
     * 注释不太多,将就看吧:D
     * :)
     * --------------------
     */

    let modal_open = false; // 防止叠弹窗
    /**
     * 读取配置
     */
    let readConfig = function () {
        GM_log(`AlwaysBing: read config`);
        config = GM_getValue('config', config); // 读取配置
        config.rules.forEach((value, index) => {
            // 将配置写到规则表中
            rules[index].action = value.action;
        });
        GM_log(`AlwaysBing: config:\n${JSON.stringify(config)}`);
    };
    /**
     * 写入配置
     */
    let writeConfig = function () {
        GM_log(`AlwaysBing: write config`);
        rules.forEach((value, index) => {
            // 将配置从规则表再写回到配置表
            config.rules[index].action = value.action;
        });
        GM_setValue('config', config); // 写入配置
    };
    /**
     * 上下文菜单回调
     * @param {number} index
     */
    let menuCallback = function (index) {
        GM_log(`AlwaysBing: menu callback: ${index}`);
        let rule = rules[index];
        switch (rule.action) {
            case 'redirect':
                rule.action = 'modal';
                break;
            case 'modal':
                rule.action = 'modal_closeable';
                break;
            case 'modal_closeable':
                rule.action = 'nothing';
                break;
            case 'nothing':
                rule.action = 'redirect';
                break;
            default:
                break;
        }
        rules[index] = rule;
        writeConfig();
        refreshMenu();
    };
    /**
     * 刷新上下文菜单
     */
    let refreshMenu = function () {
        GM_log(`AlwaysBing: refresh menu`);
        rules.forEach((value, index) => {
            let text = '';
            switch (value.action) {
                case 'redirect':
                    text = '🔗重定向';
                    break;
                case 'modal':
                    text = '💬提示';
                    break;
                case 'modal_closeable':
                    text = '💬提示(可关闭)';
                    break;
                case 'nothing':
                    text = '❌什么也不做';
                    break;
                default:
                    break;
            }
            GM_registerMenuCommand(
                `🔍${value.name}: ${text}`,
                function () {
                    menuCallback(index);
                },
                {
                    id: 'menu-' + index,
                    autoClose: false,
                    title: `🔍规则: ${value.name}\n▶动作: ${text}`,
                }
            );
        });
    };
    /**
     * 处理和匹配规则
     */
    let process = function () {
        GM_log(`AlwaysBing: process`);
        rules.forEach((value, index) => {
            // 遍历规则
            let currentRule = value;
            GM_log(`AlwaysBing: process rule ${value.name}`);
            value.matches.forEach((value, index) => {
                // 遍历子规则
                if (window.location.href.includes(value.url)) {
                    // URL匹配
                    GM_log(`AlwaysBing: URL matches rule ${currentRule.name}`);
                    let searchParams = new URLSearchParams(
                        window.location.search
                    );
                    let query = searchParams.get(value.query); // 获取参数
                    let url = bing[value.type] + query; // 对应的必应URL
                    switch (currentRule.action) {
                        case 'redirect':
                            window.location.href = url;
                            break;
                        case 'modal':
                            showModal(url, false);
                            break;
                        case 'modal_closeable':
                            showModal(url, true);
                            break;
                        case 'nothing':
                            break;
                        default:
                            break;
                    }
                }
            });
        });
    };
    /**
     * 显示提示窗
     * @param {string} url 跳转的URL
     * @param {boolean} closeable 是否可关闭
     */
    let showModal = function (url, closeable) {
        if (modal_open) {
            return;
        }
        modal_open = true;
        GM_log(
            `AlwaysBing: show modal\n(url: ${url}\n closeable: ${closeable})`
        );
        let modalEl = document.createElement('div');
        modalEl.id = 'alwaysbing-modal-wrapper';
        // 样式
        GM_addStyle(`
#alwaysbing-modal-wrapper {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #00000060;
    -webkit-user-select: none;
    user-select: none;
    z-index: 1145; /* 故意不小心的 */
}
#alwaysbing-modal {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    padding: 10px 8px;
    width: -moz-fit-content;
    height: -moz-fit-content;
    width: fit-content;
    height: fit-content;
    max-width: 30%;
    max-height: 50%;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #ffffff;
    text-align: center;
}

/* Bing 暗色主题 */
/* 好像没啥用... */
.b_dark .alwaysbing-modal {
    background-color: #1b1a19;
    color: #ffffff;
}
.b_dark .alwaysbing-modal * {
    color: #ffffff;
}

#alwaysbing-modal>* {
    padding: 10px;
    margin: 15px;
}
#alwaysbing-modal>.close-btn {
    text-align: right;
    align-self: flex-end;
    width: 20px;
    height: 20px;
    cursor: pointer;
}
#alwaysbing-modal>.img-wrapper {
    margin: 10px;
    padding: 10px;
}
#alwaysbing-modal>.img-wrapper>.img {
    display: block;
    width: 60px;
    height: 60px;
    text-align: center;
}
#alwaysbing-modal>.tit {
    font-size: large;
    font-weight: bold;
}
#alwaysbing-modal>.btn {
    padding: 18px;
    background-color: #35adfd;
    color: #ffffff;
    border-radius: 10px;
    cursor: pointer;
}
#alwaysbing-modal>.btn:hover {
    background-color: #7ec9fc;
}
`);
        // HTML
        modalEl.innerHTML = `
<div id="alwaysbing-modal">
    <div class="close-btn" align="right"  
        onclick="document.getElementById('alwaysbing-modal-wrapper').hidden = true;" 
        ${closeable ? '' : 'hidden'}>
        <!-- 关闭按钮 -->
        <!-- https://icons.bootcss.com/icons/x-lg/ -->
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-lg" viewBox="0 0 16 16">
            <path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z"/>
        </svg>
    </div>
    <div align="center" class="img-wrapper">
        <!-- Bing图标 -->
        <img class="img" src="https://cn.bing.com/favicon.ico" />
    </div>
    <div class="tit">
        <!-- 标题 -->
        建议使用 Bing 搜索
    </div>
    <div class="content">
        Microsoft Bing 拥有更好的搜索能力,更少的广告,更精准的结果
    </div>
    <div class="btn" onclick="window.open('${url}','_self')">使用 Bing</div>
</div>
`;
        document.body.appendChild(modalEl);
    };

    /**
     * 初始化
     */
    let init = function () {
        GM_log(`AlwaysBing: init`);
        readConfig();
        refreshMenu();
        process();
    };
    init();
    //!SECTION
})();