Greasy Fork

Greasy Fork is available in English.

Google:多引擎同屏

在Google搜索页面同时显示多个搜索引擎的结果

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Google:多引擎同屏
// @namespace   http://userscripts.org/users/86496
// @version      2.0.1
// @description  在Google搜索页面同时显示多个搜索引擎的结果
// @author       hzhbest
// @match        https://www.google.com/*
// @icon         https://www.google.com/favicon.ico
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// @connect      www.baidu.com
// @connect      www.so.com
// @connect      www.sogou.com
// @connect      cn.bing.com
// @connect      s.weibo.com
// @connect      www.izito.com
// @connect      duckduckgo.com
// @license      MIT
// ==/UserScript==


(function () {

    if (window.top.document.location.href != window.self.document.location.href) return; // 在iframe中则不运行

    setTimeout(init, 500);                          //首次运行

    //判断并推进主进程,重新观察
    function init() {
        var thisurl = document.location.href;
        var kw = getUriParam(thisurl, 'q');
        // log('kw: ', kw);
        if (!kw) return;
        // https://www.google.com/search?q=AAAA&tbs=cdr%3A1%2Ccd_min%3A4%2F11%2F2012%2Ccd_max%3A4%2F11%2F2013
        let tbs = getUriParam(thisurl, 'tbs');
        var arri, dateset;
        if (!!tbs) arri = tbs.match(/\d{1,2}\%2F\d{1,2}\%2F\d{4}/g);  // 提取网址中的时间数组
        if (!!arri) {
            dateset = arri.map(ds => ggdateTOdate(ds)); // 有时间范围则引入到多引擎加载中
            console.log('dateset: ', dateset);
            go(kw, dateset);
        } else {
            go(kw);
        }
    }

    //主进程
    function go(kw, dateset) {

        //  ===设置开始=========================================================================

        // > 是否只在第一页显示(true / false)
        var onlyPageOne = true;

        //  **以下一行并非设置项,请勿修改! //如果只在第一页显示则在非第一页的页面直接退出
        if (onlyPageOne && getUriParam(document.location.href, 'start') > 0) return;

        // > 直接展示的搜索结果数量(个);一般小于等于10,因为一般搜索结果一页就10项
        var resultNumber = 3;

        // > 搜索结果的显示高度(像素);小于此高度的将按实际高度显示,大于此高度的在鼠标移上时展开;
        //     要想不收缩显示,将该值设得较大(例如1000)即可
        var disHeight = 120;

        // > 与主搜索结果的水平间距(像素)
        var lgap = 50;

        // > 获取搜索结果最长尝试(超时)时间(秒)。
        var resultTimeout = 30;

        var xEngs = [

            // > 外部搜索引擎(提取结果信息线索)
            // 说明: xEngs[x].name - 搜索引擎的名字(用作标识)
            //		  xEngs[x].enable - 启用开关,1-启用,0-禁用
            //		  xEngs[x].boxname - 同屏结果框元素的 ID
            //		  xEngs[x].url - 搜索引擎的搜索 Url,其中“--keyword--”用于替换实际搜索关键词
            //		  xEngs[x].resultcss - 指向每条搜索结果的 css selector
            //		  xEngs[x].em - 搜索引擎对关键词强调的 css selector
            //        xEngs[x].timepara - 搜索引擎自由指定始末时间的URL参数模版
            //        xEngs[x].timeformat - 用于将时间对象转换为始末时间格式的函数
            //		  x - 显示顺序。放在前面的搜索引擎靠上显示结果

            {
                name: 'Baidu',
                enable: 1,
                boxname: "bdResult",
                url: 'https://www.baidu.com/s?wd=--keyword--',
                resultcss: '#content_left>div[class*="result"][id]:not([tpl="recommend_list"])',
                em: 'em',
                timepara: '&gpc=stf%3D--sdate--%2C--edate--%7Cstftype%3D2',
                timeformat: function (dateobj) {
                    return dateobj / 1000;
                }
            },
            {
                name: '360',
                enable: 1,
                boxname: "360Result",
                url: 'http://www.so.com/s?ie=utf-8&q=--keyword--',
                resultcss: '#main li.res-list',
                em: 'em'
            },
            {
                name: 'Bing',
                enable: 1,
                boxname: "bingResult",
                url: 'http://cn.bing.com/search?q=--keyword--',
                resultcss: 'li.b_algo',
                em: 'strong',
                timepara: '&filters=ex1%3a%22ez5_--sdate--_--edate--%22',
                timeformat: function (dateobj) {
                    const d0 = Date.parse('1970-1-1');
                    const msxd = 24 * 60 * 60 * 1000;
                    return (dateobj - d0) / msxd;
                }
            },
            {
                name: 'Sogou',
                enable: 1,
                boxname: "sogouResult",
                url: 'http://www.sogou.com/web?query=--keyword--',
                resultcss: 'div.results>div>div.struct201102',
                em: 'em'
            },
            {
                name: 'GoogleCN',
                enable: 0,
                boxname: "gcnResult",
                url: 'http://www.google.com.hk/search?q=--keyword--',
                resultcss: 'div#rso div.g',
                em: 'em',
                timepara: '&tbs=cdr%3A1%2Ccd_min%3A--sdate--%2Ccd_max%3A--edate--',
                timeformat: function (dateobj) {
                    let d = dateobj.getDate();
                    let m = dateobj.getMonth();
                    let y = dateobj.getFullYear();
                    return d + '%2F' + m + '%2F' + y;
                }
            },
            {
                name: 'Weibo',
                enable: 0,
                boxname: "weiboResult",
                url: 'https://s.weibo.com/weibo?q=--keyword--',
                resultcss: 'div#pl_feedlist_index>div>div.card-wrap'
            },
            {
                name: 'izito',
                enable: 0,
                boxname: "izitoResult",
                url: 'https://www.izito.com/search?q=--keyword--',
                resultcss: 'li.organic-results__item.organic-results-item',
                em: 'strong'
            }
        ]
        //  ===Config END | 设置结束=========================================================================


        var _ID = 'resultPlus';     //同屏结果主框架ID
        var _xID = '#' + _ID;

        var b;  //同屏结果主框架

        // 页面框架提取
        var bctn = qElem('div#rcnt');          //主搜索结果容器;该容器未载入时继续等待
        if (!bctn) { setTimeout(go, 300); return; }
        var lcol = qElem('div#center_col');       //搜索结果条目容器;以此容器位置确定插入同屏结果位置
        var lmar = (!!lcol) ? (getX(lcol) + lcol.offsetWidth + lgap) : (window.innerWidth * 0.56);    //插入同屏结果的左边缘
        var b_width = Math.min(504, window.innerWidth - lmar - 30); //同屏结果的宽度
        var wcol = lcol.offsetWidth;

        // 样式表
        //同屏结果主框架位置大小和底色
        var bxstyle = _xID + '{position:absolute; top:100px; left:' + lmar + 'px; background:white; z-index:10; width:' + b_width + 'px;'
            + ' line-height: 130%; border-bottom:1px solid #AACCFF;}';
        //分引擎框架样式
        var xestyle = _xID + ' .xe{border-top:1px solid #7799cc; padding: 1px 3px 3px 4px; '
            + 'background:linear-gradient(5deg, rgba(170, 204, 255,0.1) 0%, rgba(255, 255, 255,0.7) 100%),linear-gradient(0deg, rgba(255,255,255,0.65) 0%, rgba(127, 127, 203,0.3) 10%, rgb(170, 204, 255) 100%);}';
        //分引擎名称样式
        var exstyle = _xID + ' ._external {color: #6868b0 !important;}'
            + _xID + ' ._external:after {content:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAFVBMVEVmmcwzmcyZzP8AZswAZv////////9E6giVAAAAB3RSTlP///////8AGksDRgAAADhJREFUGFcly0ESAEAEA0Ei6/9P3sEcVB8kmrwFyni0bOeyyDpy9JTLEaOhQq7Ongf5FeMhHS/4AVnsAZubxDVmAAAAAElFTkSuQmCC");}';
        //关闭按钮样式
        var clstyle = _xID + ' .close{position: absolute; top: 0; right: 0; padding: 0 10px;}'
            + _xID + ' .close:hover{outline: 1px solid #731616; outline-offset: -1px; background-color: #F28E8E!important; color: #731616!important;}';
        //刷新链接样式
        var rfstyle = _xID + ' ._refresh{display: none; margin: 0 10px;}'
            + _xID + ' .xe:hover ._refresh{display: inline-block;}'
        //同屏搜索结果通用样式
        var glo_style = 'body{overflow: auto !important; min-height: 1200px;}'  /*不加这个在百度自己搜索结果太少时会使同屏结果显示不全 */
            + _xID + ' p, ' + _xID + ' ul {margin: 0; padding:0;}'
            + _xID + ' li{list-style: none outside none;}'
            + _xID + ' a{color: #2626A8;}'
            + _xID + ' a div>div{display: inline;}' /*链接中的图片之类*/
            + _xID + ' svg{height: 14px !important; width: 14px !important;}' /*svg图片限制大小;通常是图标*/
            + _xID + '>div>*{height: auto!important;}' /*收缩搜索结果自带高度*/
            /*同屏结果框架样式*/
            + _xID + ' div._result{max-height:' + disHeight + 'px; margin-bottom:5px; background:white; overflow:hidden; transition: height, max-height 2.5s ease-out 1s;}'
            + _xID + ' div._result:hover{max-height: 100000px; margin-bottom:0px; padding-bottom:5px; background: #F0F7F9; transition: height, max-height 0.2s ease-out; outline: 1px solid #82BDCE;}'
            + _xID + ' div._result h3, ' + _xID + ' div._result h2{font-size:13pt!important; font-weight: 800; border-bottom: 1px solid white; margin-bottom:2px;}'
            + _xID + ' div._result:hover h3, ' + _xID + ' div._result:hover h2{border-bottom: 1px solid #a7cDd6;}'
            /*更多结果框架样式*/
            + _xID + ' ._resultMore{max-height: none!important;}'
            + _xID + ' ._re_hide>div,' + _xID + ' ._no_result{display:none;}'
            + _xID + ' ._re_more{display: block; height: 20px; width: 100%; text-align: center; background: #ddd; cursor: pointer;}'
            + _xID + ' ._re_more:hover{background: #F0F7F9!important;}'
            + _xID + ' ._re_hide ._re_more{background: white;}'
            + _xID + ' div._result+div._result,' + _xID + ' ._resultMore{border-top: 1px solid #aaccff;}';
        //应付搜索结果特殊元素变样的样式
        var tablestyle = _xID + ' td{padding: 5px 0 5px 13px !important; color: #000!important; width: fit-content !important;}'
            + _xID + ' tr+tr>td{padding: 0px 0 8px 13px !important;}' + _xID + ' td>h3{margin-left: -8px; line-height: 1.3em;}';
        var li_style = _xID + ' div._result>li {padding: 5px 0 8px 13px !important; background-image: none;}'
            + _xID + ' li h3>a:first-child,' + _xID + ' li h3>em {font-size: 13pt !important; margin-left: -8px;}'
            + _xID + ' li>div, ' + _xID + ' li>p {font-size: small;}';
        //特殊结果:与主搜索结果相同
        var mat_style = _xID + ' div._match {background: #eee; background:linear-gradient(to bottom, #eee, white); max-height:1.1em;}' + _xID + ' div._match:hover{max-height: 1000px;}'
            + '._hilire{background: #ffd!important; background: linear-gradient(to bottom, #ffd, white)!important;}'
        //同屏搜索结果-引擎专属样式
        var _w;
        var gg_style = /*Google style*/`
            .xhjkHe{max-width: ${wcol}px !important;}
            #rhs {position: fixed; left: 10px; bottom: 10px; transform-origin: bottom left; transform: scale(0.45); background: white; transition: all 0.2s 1s; max-height: 60vh; overflow-y:auto;}
            #rhs:hover {transition: transform 0.3s; transform: scale(1); box-shadow: 0 0 6px -1px #333; padding: 5px; z-index: 9999999;}
            `;
        _w = 'div[id^="bingResult_"] ';
        var bg_style = /*Bing style*/ _w + '.crch,' + _w + '.sb_tsuf{display:none!important;}'
            + _w + 'h2{margin:5px 0;}' + _w + '.inner,' + _w + '.HeroTab{display: none;}'
            + _w + 'div.tptt{background: #e9e9ffed; width: fit-content; outline: 1px solid #bac4e0; border-radius: 1em; padding: 1px 0.5em;}';
        _w = 'div[id^="sogouResult_"] ';
        var sg_style = /*Sogou style*/ _w + '>div {padding: 7px 0 8px 13px !important;background-image:none;} '
            + _w + '>div>h3 {margin-left:-8px;} '
            + _w + '.img-height{float: right;} '
            + _w + '.tit-ico {background-position: left 1px;background-repeat: no-repeat;padding-left: 20px;}'
            + _w + '.item-list{display: grid; grid-template-columns: auto auto auto auto auto auto auto auto auto;}'
            + _w + '.citeurl{position: sticky; bottom: 3px; background: #e9e9ffed; width: fit-content; outline: 1px solid #bac4e0; border-radius: 1em; padding: 1px 0.5em;}';
        _w = 'div[id^="360Result_"] ';
        var sz_style = /*360 style*/ _w + 'h3>a>img {width:16px !important; height:16px !important; float: none !important;}'
            + _w + 'img {float: right;}'
            + _w + 'li:hover div>a>img {float: none;}'
            + _w + '.g-linkinfo{position: sticky; bottom: 3px; background: #e9e9ffed; width: fit-content; outline: 1px solid #bac4e0; border-radius: 1em; padding: 1px 6px !important;}';
        _w = 'div[id^="weiboResult_"] ';
        var wb_style = /*Weibo style*/ _w + 'div.menu,' + _w + '.WB_video_h5 {display: none;} '
            + _w + 'div.media{max-height: 200px; overflow: hidden;}' + _w + 'div.media:hover{overflow: auto; scrollbar-width: thin;} '
            + _w + 'div.avator{width: fit-content; float: left;} '
            + _w + 'div.avator img{float: left; margin: 3px; height:32px; width:32px;} '
            + _w + 'img.face{height:18px !important; width:18px !important;} '
            + _w + '.card-act{position: sticky; bottom: 3px; left: 300px; background: #e9e9ffed; width: fit-content; border-top: 1px solid #bac4e0;}'
            + _w + '.woo-font--retweet{margin-left: 1em; display: inline-block; height: 16px !important; content:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGlkPSJMYXllcl8xIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA2NCA2NDsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDY0IDY0IiB4bWw6c3BhY2U9InByZXNlcnZlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiMxMzQ1NjM7fQo8L3N0eWxlPjxnPjxnIGlkPSJJY29uLUV4dGVybmFsLUxpbmsiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM4Mi4wMDAwMDAsIDM4MC4wMDAwMDApIj48cG9seWxpbmUgY2xhc3M9InN0MCIgaWQ9IkZpbGwtMTE4IiBwb2ludHM9Ii0zNTIuMywtMzQzLjQgLTM1NC42LC0zNDUuNyAtMzI4LjgsLTM3MS40IC0zMjYuNiwtMzY5LjIgLTM1Mi4zLC0zNDMuNCAgICAiLz48cG9seWxpbmUgY2xhc3M9InN0MCIgaWQ9IkZpbGwtMTE5IiBwb2ludHM9Ii0zMjYsLTM1NC45IC0zMjkuNCwtMzU0LjkgLTMyOS40LC0zNjguNiAtMzQzLjEsLTM2OC42IC0zNDMuMSwtMzcyIC0zMjYsLTM3MiAgICAgIC0zMjYsLTM1NC45ICAgICIvPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0tMzM0LjYtMzI0aC0zNC4zYy0yLjgsMC01LjEtMi4zLTUuMS01LjF2LTM0LjNjMC0yLjgsMi4zLTUuMSw1LjEtNS4xaDE4Ljl2My40aC0xOC45ICAgICBjLTAuOSwwLTEuNywwLjgtMS43LDEuN3YzNC4zYzAsMC45LDAuOCwxLjcsMS43LDEuN2gzNC4zYzAuOSwwLDEuNy0wLjgsMS43LTEuN1YtMzQ4aDMuNHYxOC45Qy0zMjkuNC0zMjYuMy0zMzEuNy0zMjQtMzM0LjYtMzI0ICAgICAiIGlkPSJGaWxsLTEyMCIvPjwvZz48L2c+PC9zdmc+");} '
            + _w + '.woo-font--comment{margin-left: 1em; display: inline-block; height: 16px !important; content:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHdpZHRoPSIxMDBweCIgaGVpZ2h0PSIxMDBweCIgdmlld0JveD0iLTI0NyAzNzAuOSAxMDAgMTAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IC0yNDcgMzcwLjkgMTAwIDEwMDsiDQoJIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPHBhdGggZD0iTS0xNDcuNywzOTAuNGMtMC4zLTUuNS00LjctOS44LTEwLTkuOGgtNzguOGMtNS42LDAtMTAuMSw0LjYtMTAuMSwxMC4ydjQyLjNjMCw1LjUsNC42LDEwLjIsMTAuMSwxMC4yaDIuM3YxNC4xDQoJCWMwLDEuNSwwLjgsMi44LDIuMiwzLjRjMC42LDAuMywxLjEsMC40LDEuNywwLjRjMSwwLDEuOS0wLjQsMi42LTEuMWwxNy4zLTE2LjloNTIuOGM1LjQsMCwxMC00LjcsMTAtMTAuMnYtNDIuNkwtMTQ3LjcsMzkwLjR6DQoJCSBNLTE1Mi43LDQzMy4xYzAsMi44LTIuMyw1LjItNSw1LjJoLTU0LjhsLTE2LjcsMTYuM3YtMTYuM2gtNy4zYy0yLjcsMC01LjEtMi40LTUuMS01LjJ2LTQyLjNjMC0yLjgsMi4zLTUuMiw1LjEtNS4yaDc4LjgNCgkJYzIuNywwLDQuOCwyLjIsNSw1VjQzMy4xeiIvPg0KCTxwYXRoIGQ9Ik0tMjIyLjcsMzk5LjJoNTAuNWMxLjQsMCwyLjUtMS4xLDIuNS0yLjVsMCwwYzAtMS40LTEuMS0yLjUtMi41LTIuNWgtNTAuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41bDAsMA0KCQlDLTIyNS4yLDM5OC4xLTIyNC4xLDM5OS4yLTIyMi43LDM5OS4yeiIvPg0KCTxwYXRoIGQ9Ik0tMjIyLjcsNDA4LjdoNTAuNWMxLjQsMCwyLjUtMS4xLDIuNS0yLjVsMCwwYzAtMS40LTEuMS0yLjUtMi41LTIuNWgtNTAuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41bDAsMA0KCQlDLTIyNS4yLDQwNy42LTIyNC4xLDQwOC43LTIyMi43LDQwOC43eiIvPg0KCTxwYXRoIGQ9Ik0tMjIyLjcsNDE4LjJoNTAuNWMxLjQsMCwyLjUtMS4xLDIuNS0yLjVsMCwwYzAtMS40LTEuMS0yLjUtMi41LTIuNWgtNTAuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41bDAsMA0KCQlDLTIyNS4yLDQxNy4xLTIyNC4xLDQxOC4yLTIyMi43LDQxOC4yeiIvPg0KCTxwYXRoIGQ9Ik0tMjIyLjcsNDI3LjdoMjkuNmMxLjQsMCwyLjUtMS4xLDIuNS0yLjVsMCwwYzAtMS40LTEuMS0yLjUtMi41LTIuNWgtMjkuNmMtMS40LDAtMi41LDEuMS0yLjUsMi41bDAsMA0KCQlDLTIyNS4yLDQyNi42LTIyNC4xLDQyNy43LTIyMi43LDQyNy43eiIvPg0KPC9nPg0KPC9zdmc+DQo=");} '
            + _w + 'button{border: 0; background: transparent; margin-left: 1em;}'
            + _w + '.card-top{float: right; margin-right: 6px;}' + _w + '.card-top h4{margin: 0;}'
            + _w + 'ul{display: grid; grid-template-columns: auto auto auto auto auto auto auto auto auto;}' + _w + 'ul>li{display: inline;} ' + _w + 'ul>li img{top:0 !important;}'
            + _w + '.thumbnail{min-height:0 !important;} ' + _w + '.card-wrap{padding: 10px;} ' + _w + '.info{float: left;}' + _w + '.info span{vertical-align: middle;}'
            + _w + '.from{width: 150px; float: right; height: 1.3em; overflow: hidden;}' + _w + '.from:hover{overflow: visible; background: #e3f5f1;}'
            + _w + '.txt{clear: both;}';


        var hl_styles = new Array();    //高亮样式数组
        var xEng_boxes = new Array();   //同屏搜索结果分引擎框架

        for (const i in xEngs) {
            if (xEngs[i].enable == 1) {
                xEngs[i].url = xEngs[i].url.replace('--keyword--', kw);        //替换搜索关键词到引擎网址
                console.log('xEngs[i].url: ', xEngs[i].url);
                if (!!xEngs[i].timepara && !!dateset) {                        // 若多引擎支持时间范围且主引擎使用了时间范围
                    let sdate = xEngs[i].timeformat(dateset[0]);
                    let edate = xEngs[i].timeformat(dateset[1]);
                    let timepara = xEngs[i].timepara.replace('--sdate--', sdate).replace('--edate--', edate);
                    xEngs[i].url += timepara;
                    xEngs[i].dateset = "[ " + dateTOymd(dateset[0]) + " - " + dateTOymd(dateset[1]) + " ] ";
                }
            }
            if (!!xEngs[i].em) {
                hl_styles[i] = _xID + ' div[id^="' + xEngs[i].resultcss + '_"] ' + xEngs[i].em;
            }   //形成高亮样式
        }
        var hili_style = hl_styles.join(',') + '{color: #CC0033 !important; background: #fffcec;}';


        // 插入 CSS
        var headID = document.getElementsByTagName("head")[0];
        var cssNode = creaElemIn('style', headID);
        cssNode.type = 'text/css';
        cssNode.id = '__xEngs';
        cssNode.innerHTML = hili_style + bxstyle + xestyle + clstyle + rfstyle + glo_style + exstyle + tablestyle + li_style + mat_style + gg_style + bg_style + sg_style + sz_style + wb_style;

        // 提取Google搜索结果
        var resls = qaElem('div#rso>div>div>div');        //Google各条搜索结果
        var ggRes = [], ggResUrls = [], ggResNo = 0;
        // var speIDs = /imagebox_bigimages|imagebox|newsbox|videobox|blogbox/;
        for (let h = 0; h < resls.length; h++) {
            // if (speIDs.test(resls[h]).id) continue;
            var gglnk = qElem('span>a', resls[h]);
            if (!gglnk) continue;
            ggResUrls.push(gglnk.href.toLowerCase());               //提取主链接网址推入结果网址数组
            ggResNo++;
            resls[h].title = '第 ' + ggResNo + ' 结果';
            ggRes.push(resls[h]);                                   //推入结果数组
        }

        // 准备同屏搜索结果主框架
        b = creaElemIn('div', document.body);
        b.id = _ID;
        // 构建关闭按钮
        var close = creaElemIn('a', b);
        close.href = '#';
        close.className = 'close';
        close.addEventListener('click', () => {
            headID.removeChild(cssNode);
            document.body.removeChild(b);
        }, false);
        close.innerHTML = 'X';
        close.title = '关闭';

        // 按启用的多引擎构建结果框并获取搜索结果填入
        for (const i in xEngs) {
            if (xEngs[i].enable == 1) {
                xEng_boxes[i] = new Array();
                resultbox(b, xEng_boxes[i], xEngs[i], resultNumber);    //构建同屏各搜索引擎结果框架
                addresult(xEng_boxes[i], xEngs[i], resultNumber);       //插入搜索结果节点
            }
        }


        // FUNCTIONS

        // 构建一个搜索引擎结果框架
        function resultbox(root, box, engObj, rescnt) { //root:供插入引擎结果的主框架,box:供写入引擎结果的盒框架,engArr:供写入引擎标志的信息数组,rescnt:先显的结果数
            var c, d, e, f, r;
            //引擎名称框
            c = creaElemIn('div', root);
            c.className = 'xe';
            c.id = engObj.boxname;
            //引擎跳转链
            d = creaElemIn('a', c);
            addtext(d, engObj.name + ' ' + (engObj?.dateset || ''));
            d.href = engObj.url;
            d.target = '_blank';
            d.className = '_external';
            // 引擎刷新链
            r = creaElemIn('a', c);
            r.className = '_refresh';
            addtext(r, "刷新结果");
            r.addEventListener('click', () => {
                addresult(box, engObj, rescnt);
            }, false);
            //先显结果框
            for (let k = 0; k < rescnt; k++) {
                box[k] = creaElemIn('div', root);
                box[k].id = engObj.boxname + '_' + (k + 1);
                box[k].innerHTML = (k == 0) ? '正在获取结果...' : '...';
            }
            //后显结果框
            if (rescnt == 10) return;
            e = creaElemIn('div', root);
            e.className = '_resultMore _re_hide';
            e.id = engObj.boxname + 'More';
            for (let k = rescnt; k < 10; k++) {
                box[k] = creaElemIn('div', e);
                box[k].id = engObj.boxname + '_' + (k + 1);
            }
            //后显结果展开按钮
            f = creaElemIn('a', e);
            f.className = '_re_more';
            f.innerHTML = '↓展开↓';
            f.title = '展开更多结果';
            f.href = '#' + engObj.boxname;
            f.addEventListener('click', function (ev) {
                ev.preventDefault();
                var s = (this.parentNode.className == '_resultMore _re_hide');
                this.parentNode.className = (s) ? '_resultMore ' : '_resultMore _re_hide';
                this.innerHTML = (s) ? '↑收起↑' : '↓展开↓';
                this.title = (s) ? '收起更多结果' : '展开更多结果';
            }, false);
        }

        // 发送请求并转递返回数据
        function addresult(box, engObj, rescnt) { //box:供写入引擎结果的盒框架,engArr:供写入引擎标志的信息数组,rescnt:先显的结果数
            var timeout = function () {
                for (const i in box) {
                    set(box[i], (i == 0) ? '* 获取结果超时 *' : '');
                }
            };
            var errortimer = setTimeout(timeout, resultTimeout * 1000);

            var option = {
                method: "GET",
                url: engObj.url,
                onload: function (_h) {
                    clearTimeout(errortimer);
                    var _Node = document.createElement('div');
                    _Node.innerHTML = _h.responseText;              //包含整个页面的div
                    initresult(_Node, box, engObj.name, engObj.resultcss, rescnt);
                }
            }
            GM_xmlhttpRequest(option);
        }

        // Initialize results
        function initresult(_Node, box, engName, resSelector, rescnt) { //_Node:需处理的搜索结果,box:供写入引擎结果的盒框架,engName:引擎名称,resSelector:从搜索结果中提取单条搜索结果的选择器,rescnt:先显的结果数
            var _result = [], _resultLinkHref;
            var no_result_con = "* 无返回结果,请尝试直接访问 *";
            for (let i = 0; i < 10; i++) {
                _result[i] = (i == 0) ? no_result_con : '';      //初始化搜索结果临时容器
            }
            var _ns = qaElem(resSelector, _Node);               //按选择器提取的搜索结果数组
            for (let i = 0, j = 0; i < 12; i++) {                   //遍历搜索结果数组,排除特殊内容,放入临时容器,以j为索引
                var _n = _ns[i];
                //log(engName+" i "+i);
                if (_n == null) { //log(engName+" j "+j);
                    if (j <= rescnt && rescnt != 10) box[rescnt].parentNode.className = '_no_result';   //若无结果需要放入后显结果框,则包含展开按钮的后显结果鵟直接不显示
                    break;
                } else {  //log(engName+" j "+j);

                    //GCN url fix
                    if (engName == 'GoogleCN') fixgcn(_n);

                    //Google url fix
                    if (engName == 'Google') fixgl(_n);

                    //360 img flx
                    if (engName == '360') fixso(_n);

                    //Bing img url fix
                    if (engName == 'Bing') {
                        fixbmg(_n);
                        if (!_n.firstChild || (!_n.firstChild.firstChild && !_n.firstChild.nextSibling) || (_n.firstChild.localName == 'script' && !_n.firstChild.nextSibling)) continue;
                    }

                    //链接都在新标签页打开
                    var _resultLinks = _n.getElementsByTagName('a');
                    for (const o in _resultLinks) {
                        if (!!_resultLinks[o].href && /\:\/\//.test(_resultLinks[o].href)) {
                            _resultLinks[o].target = '_blank';
                        }
                    }

                    //处理图片框架
                    var _imgs = _n.getElementsByTagName('img');
                    for (const o in _imgs) {
                        if (!!_imgs[o].src && _imgs[o].src.indexOf('data:') == 0) {
                            _imgs[o].parentNode.style = 'width: fit-content; height: fit-content;';
                        }
                    }

                    //将处理后的结果放入临时容器
                    _result[j] = getoutterHTML(_n);

                    //检查同屏引擎搜索结果的主链接和主引擎搜索结果,找出同归结果
                    if (!_resultLinks[0]) continue;     //跳过无链接的结果
                    if (!!_resultLinks[0].href) {
                        _resultLinkHref = _resultLinks[0].href.toLowerCase();
                        for (const p in ggResUrls) {
                            if (_resultLinkHref == ggResUrls[p] || _resultLinkHref + '/' == ggResUrls[p]) {  //deal with bing's result url
                                box[j].className = '_match';
                                _result[j] = '同 Google 第 <b>' + (Number(p) + 1) + '</b> 结果' + _result[j];
                                if (ggRes[p].className.indexOf('_hilire') == -1) {
                                    ggRes[p].className += ' _hilire';
                                    ggRes[p].title += ';同时为 ' + engName + ' 第 ' + (j + 1) + ' 结果';
                                } else {
                                    ggRes[p].title += '及 ' + engName + ' 第 ' + (j + 1) + ' 结果';
                                }
                            }
                        }
                    }
                    j++;
                    if (j == 10) break;
                }
            }
            for (let i = 0; i < 10; i++) {      //将临时结果转入结果框
                set(box[i], _result[i]);
                if (_result[i]) box[i].className += ' _result';
            }
        }


        // 修复360懒图片
        function fixso(_resultcontent) {
            var imgs = qaElem('.so-lazyimg', _resultcontent);
            if (!imgs.length) return;
            for (const i in imgs) {
                if (!!imgs[i].dataset && !!imgs[i].dataset.isrc) imgs[i].src = imgs[i].dataset.isrc;
            }
        }

        // "修复"GoogleCN链接
        function fixgcn(_resultcontent) {
            var Links = qaElem('a', _resultcontent);
            for (const i in Links) {
                if (Links[i].href && Links[i].href.match(/^http:\/\/www\.google\..*\/url\?q=/i)) {
                    Links[i].href = Links[i].href.replace(/^http:\/\/www\.google\..*\/url\?q=(.*?)&.*/i, "$1");
                }
            }
        }

        // "修复"Google链接
        function fixgl(_resultcontent) {
            var Links = qaElem('a', _resultcontent);
            for (const i in Links) {
                if (Links[i].href && Links[i].href.indexOf('/') == 0) {
                    Links[i].href = 'https://www.google.com/' + Links[i].href.slice(1);
                }
            }
        }

        // 修复Bing图片地址
        function fixbmg(_resultcontent) {
            var Imgs = qaElem('img', _resultcontent);
            for (const i in Imgs) {
                if (Imgs[i].src && Imgs[i].src.indexOf('http://') != 0 && Imgs[i].src.indexOf('data:') != 0) {
                    Imgs[i].src = 'http://www.bing.com' + Imgs[i].src;
                }
            }
        }
    }


    //
    /** 从url中提取名为【param】的参数的值;提取不到返回空字符
     * @param {string} surl 网址
     * @param {string} param 参数名称
     * @returns {string} 参数值
     */
    function getUriParam(surl, param) {
        var result = surl.match(new RegExp("(\\?|&)" + param + "(\\[\\])?=([^&]*)"));
        return result ? result[3] : '';
    }

    function ggdateTOdate(string) { // 4%2F11%2F2012
        return new Date(string.replaceAll("%2F", '/'));
    }

    // 将日期对象转成“YYYY-MM-DD”格式
    function dateTOymd(odate) {
        return odate.getFullYear() + "-" + twodg(odate.getMonth() + 1) + "-" + twodg(odate.getDate());
    }

    // 补足两位数字
    function twodg(s) {
        if (s.length == 1) {
            s = "0" + s;
        }
        return s;
    }

    function log() {	//debug
        var args = Array.prototype.slice.call(arguments);
        console.log.apply(console, args);
    }


    // Create and insert an element
    function creaElemIn(tagname, destin) {
        var theElem = destin.appendChild(document.createElement(tagname));
        return theElem;
    }

    // scroll node into view
    function scrTo(node) {
        if (!node) return;
        if (node.getBoundingClientRect) {
            var pos = node.getBoundingClientRect();
            /*var pos_h = node.offsetHeight;*/
            document.documentElement.scrollTop = document.body.scrollTop = pos.top + window.pageYOffset - window.innerHeight / 10;
        } else {
            node.scrollIntoView();
        }
    }

    // Set content
    function set(elem, str) {
        elem.innerHTML = str;
    }

    // Get full HTML nodes in string
    function getoutterHTML(elem) {
        var a = elem.attributes, str = "<" + elem.tagName, i = 0; for (; i < a.length; i++)
            if (a[i].specified) str += " " + a[i].name + '="' + a[i].value + '"';
        if (!canHaveChildren(elem)) return str + " />";
        return str + ">" + elem.innerHTML + "</" + elem.tagName + ">";
    }
    function canHaveChildren(elem) {
        return !/^(area|base|basefont|col|frame|hr|img|br|input|isindex|link|meta|param)$/.test(elem.tagName.toLowerCase());
    }

    // Add text node
    function addtext(obj, text) {
        var content = document.createTextNode(text);
        obj.appendChild(content);
    }

    function qElem(cssSelector, root) {
        let _r = root || document;
        return _r.querySelector(cssSelector);
    }

    // get all elements by css selector
    function qaElem(cssSelector, root) {
        let _r = root || document;
        return _r.querySelectorAll(cssSelector);
    }

    // get the accumulative offsetleft of target element
    function getX(oElement) {
        var iReturnValue = 0;
        while (oElement != null) {
            iReturnValue += oElement.offsetLeft;
            oElement = oElement.offsetParent;
        }
        return iReturnValue;
    }


})();