// ==UserScript==
// @name           增强百度搜索
// @namespace      http://hi.baidu.com/chrisyue/
// @include        http://www.baidu.com/s?* 
// @include        http://www.baidu.com/baidu?*
// @description    Enhancing Baidu search result 增强百度搜索结果页
// ==/UserScript==

// @author chrisyue http://hi.baidu.com/chrisyue/blog/item/0e6655df55ff401b48540341.html
// @email  blizzchris@gmail.com
//
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html




try {





// CONST
// just a simple version number, easy to check ver.
var VERSION = 0.11;
// END OF CONST





// FUNCITONS
// XPath
function getXPathResult(xpath, parentNode, type)
{
    parentNode = parentNode || document;
    type       = type       || XPathResult.ORDERED_NODE_SNAPSHOT_TYPE;
    return document.evaluate(xpath, parentNode, null, type, null);
}

// Self remove
function removeSelf(node)
{
    node.parentNode.removeChild(node);
}

// END OF FUNCTIONS




// ********************* START CHANGING *********************

// ****Version check****
// implement version check function
var script2 = document.createElement("script");
script2.setAttribute("type", "text/javascript");
script2.innerHTML = 'function bpp_checkVersion(latest){ var current='
                  + VERSION 
                  + ';if(latest>current){var container=document.evaluate("//td[@align=\'right\']",document,null,XPathResult.ANY_TYPE,null).iterateNext();var link=document.createElement("a");link.setAttribute("href", "http://userscripts.org/scripts/show/47560");link.appendChild(document.createTextNode("[baidu++ v"+latest+"]"));link.style.color="red";container.insertBefore(link, container.firstChild) } }';                 
document.getElementsByTagName("head").item(0).appendChild(script2);
// load version
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://baiduplusplus.googlecode.com/files/baiduplusplus-checkver.js");
document.body.appendChild(script);



// ****Add "Add Baidu" to search bar****
// create <link />
var search = document.createElement("link");
search.setAttribute("rel", "search");
search.setAttribute("type", "application/opensearchdescription+xml");
search.setAttribute("href", "http://baiduplusplus.googlecode.com/files/baidu.xml");
search.setAttribute("title", "Baidu");
// append to <head />
document.getElementsByTagName("head").item(0).appendChild(search);



// ****Clear Ad****
// get Ad container parentNode "<td align='left' ... />"
var xpath = "//td[@align='left'][@style]/div";
var sideBar = getXPathResult(xpath).snapshotItem(0);
sideBar.style.border = 0;
sideBar.style.padding = 0;
var sideBarTd = sideBar.parentNode;
sideBarTd.style.padding = "8px";
var sideBarTable = sideBarTd.parentNode.parentNode.parentNode;
sideBarTable.removeAttribute("width");
with ( sideBarTable.style ) {
    border = "1px solid #dde";
    backgroundColor = "rgb(239, 242, 250)";
    MozBorderRadius = "8px";
    margin = "8px 8px 0 0";
    cssFloat = "right";
}
sideBarTable.previousSibling.previousSibling.style.margin = 0;

// clear content
while ( !GM_getValue("bpp-remove-ad-disabled") && sideBar.hasChildNodes() ) {
    sideBar.removeChild(sideBar.firstChild);
}


if ( !GM_getValue("bpp-remove-promotion-disabled") ) {
    // ****Remove promotion****
    // find promotion
    var xpath = "//a[text()='推广']";
    var promotions = getXPathResult(xpath);
    // if have promotion
    var cnt = promotions.snapshotLength;
    if ( cnt > 0 ) {
        // show message
        var message = document.createElement("p");
        message.style.textAlign = "center";
        message.appendChild(document.createTextNode("**** " + cnt + "个推广被屏蔽 ****"));
        // append message before first promotion
        var firstPromotionTable = promotions.snapshotItem(0)
                                            .parentNode
                                            .parentNode
                                            .parentNode
                                            .parentNode
                                            .parentNode;
        firstPromotionTable.parentNode.insertBefore(message, firstPromotionTable);
        // remove promotions
        for ( i = 0; i < cnt; i++ ) {
            currentPromotionTable = promotions.snapshotItem(i)
                                              .parentNode
                                              .parentNode
                                              .parentNode
                                              .parentNode
                                              .parentNode
            if ( currentPromotionTable.previousSibling.tagName == "BR" ) { 
                // remove "<br />"
                removeSelf(currentPromotionTable.previousSibling);
            }
            removeSelf(currentPromotionTable);
        }
    }
}


if ( !GM_getValue("bpp-auto-to-page2-disabled") ) {
    // if the result are all promotions and have been removed ...
    var xpath = "//td[@class='f']";
    var results = getXPathResult(xpath);
    if ( results.snapshotLength == 0 ) {
        var message2 = document.createElement("p");
        message2.style.textAlign = "center";
        message2.appendChild(document.createTextNode("囧rz第一页全是推广，自动跳转到第二页……"));
        message.parentNode.insertBefore(message2, message.nextSibling);
        // then link to [2]
        var xpath = "//a[text()='[2]']";
        window.location.href = "http://" + document.domain + "/"
                             + getXPathResult(xpath).snapshotItem(0).getAttribute("href");
    }
}


if ( !GM_getValue("bpp-remove-sponsors-disabled") ) {
    // ****Remove Sponsor Links****
    var xpath = "//table[@bgcolor='#f5f5f5']";
    var sponsors = getXPathResult(xpath);
    // if have sponsor links
    var cnt = sponsors.snapshotLength;
    if ( cnt > 0 ) {
        // show message
        var message = document.createElement("p");
        message.style.textAlign = "center";
        message.appendChild(document.createTextNode("**** " + cnt + "个赞助商链接被屏蔽 ****"));
        // append message to first sponsor
        var firstSponsor = sponsors.snapshotItem(0)
        firstSponsor.parentNode.insertBefore(message, firstSponsor);
        // remove sponsors
        for ( i = 0; i < cnt; i++ ) {
            removeSelf(sponsors.snapshotItem(i));
        }
    }
}


if ( !GM_getValue("bpp-add-alt-search-disabled") ) {
    // ****Add alternate search list****
    // like Google, Yahoo ..
    var ul  = document.createElement("ul");
    ul.style.padding = 0;
    ul.style.margin = "0 0 8px";
    ul.style.listStyle = "none";
    // append it to sidebar
    sideBar.appendChild(ul);
    var lis = new Array();

    // ****Add "Search in Google zh-CN"****
    // create <a />
    var link = document.createElement("a");
    // get keyword // sometimes id='kw' sometimes name="wd"
    var input = document.getElementById("kw") || document.getElementsByName("wd").item(0);
    var keyword = input.getAttribute("value");
    // append to sideBar
    link.appendChild(document.createTextNode("使用谷歌搜索\"" + keyword + "\""));
    link.setAttribute("href", "http://www.google.cn/search?hl=zh-CN&q=" + encodeURIComponent(keyword));
    link.setAttribute("target", "_blank");
    var li = document.createElement("li");
    li.appendChild(link);
    lis.push(li);


    // ****Add "Search in Google"****
    // create <a />
    var link = document.createElement("a");
    // append to sideBar
    link.appendChild(document.createTextNode("使用Google搜索\"" + keyword + "\"(英文)"));
    link.setAttribute("href", "http://www.google.com/search?hl=en&q=" + encodeURIComponent(keyword));
    link.setAttribute("target", "_blank");
    var li = document.createElement("li");
    li.appendChild(link);
    lis.push(li);


    // ****Add "Search in Yahoo zh-CN"****
    // create <a />
    var link = document.createElement("a");
    // get keyword (already got)
    //var keyword = document.getElementById("kw").getAttribute("value");
    // append to sideBar
    link.appendChild(document.createTextNode("使用雅虎搜索\"" + keyword + "\""));
    link.setAttribute("href", "http://one.cn.yahoo.com/s?p=" + encodeURIComponent(keyword)) + "&v=web";
    link.setAttribute("target", "_blank");
    var li = document.createElement("li");
    li.appendChild(link);
    lis.push(li);


    // ****Add "Search in Yahoo"****
    // create <a />
    var link = document.createElement("a");
    // get keyword (already got)
    //var keyword = document.getElementById("kw").getAttribute("value");
    // append to sideBar
    link.appendChild(document.createTextNode("使用Yahoo搜索\"" + keyword + "\"(英文)"));
    link.setAttribute("href", "http://search.yahoo.com/search?p=" + encodeURIComponent(keyword));
    link.setAttribute("target", "_blank");
    var li = document.createElement("li");
    li.appendChild(link);
    lis.push(li);


    // add all LIs to UL
    for ( i in lis ) {
        ul.appendChild(lis[i]);
    }
}


if ( !GM_getValue("bpp-flickr-disabled") ) {
    // ****Add Flickr****
    // create container <div id="flickr" />
    var flickr = document.createElement("div");
    flickr.setAttribute("id", "bpp-flickr");
    flickr.style.border = "1px solid #aaf";
    flickr.style.width = "300px";
    // create title
    var title = document.createElement("h3");
    title.style.backgroundColor = "#ccf";
    title.style.margin = "0";
    title.style.padding = "2px";
    title.appendChild(document.createTextNode("相关图片 - Flickr"));
    // append title to container
    flickr.appendChild(title);

    // flickr api params
    // @see http://www.flickr.com/services/api/flickr.photos.search.html
    var param = new Array();
    param.push("method=flickr.photos.search");
    param.push("api_key=2d828cb62dd8467013a32cd0efed6ab1");
    param.push("text=" + encodeURIComponent(keyword));
    param.push("sort=relevance");
    param.push("per_page=16");
    param.push("format=json");
    // implementation of jsonFlickrApi()
    var script2 = document.createElement("script");
    script2.setAttribute("type", "text/javascript");
    script2.innerHTML = 'function jsonFlickrApi(data){if ( data.photos.total == 0 ) {document.getElementById("bpp-flickr").appendChild(document.createTextNode("无相关图片"));return 0;} var images = data.photos.photo; for ( i in images ) {src = "http://farm" + images[i].farm + ".static.flickr.com/" + images[i].server + "/" + images[i].id + "_" + images[i].secret + "_s.jpg"; url = "http://www.flickr.com/photos/" + images[i].owner + "/" + images[i].id; img = document.createElement("img"); img.setAttribute("src", src); img.setAttribute("alt", "载入中..."); img.style.borderWidth = 0; link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("target", "_blank"); link.appendChild(img); document.getElementById("bpp-flickr").appendChild(link)}}';
    // and append it to <head />
    document.getElementsByTagName("head").item(0).appendChild(script2);
    // get data from api.flickr.com (as "jsonFlickrApi(json_data)")
    var script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.setAttribute("src", "http://api.flickr.com/services/rest?" + param.join("&"));
    document.body.appendChild(script);

    // append flickr panel to sideBar
    sideBar.appendChild(flickr)
}


if ( !GM_getValue("bpp-clone-related-to-top-disabled") ) {
    // ****Show related keyword on top because of Autopagerize****
    // copy related keyword to top
    var xpath = "//div[@style='background-color: rgb(239, 242, 250); height: 60px; width: 100%; clear: both;']";
    var relatedKeyword = getXPathResult(xpath).snapshotItem(0);
    if ( relatedKeyword ) {
        // clone it
        var clone = relatedKeyword.cloneNode(true);
        // and append it before 3th <table />;
        var table = document.getElementsByTagName("table").item(2);
        table.parentNode.insertBefore(clone, table);
    }
}



// ****Multi-Columns****
function multiColumn() 
{
    var tds = getXPathResult("//table[@id]/tbody/tr/td[@class='f']");
    if ( tds.snapshotLength > 0 ) { // if unhandled result exists
        // create frame
        var frameTable = document.createElement("table");
        frameTable.setAttribute("cellpadding", 0);
        frameTable.setAttribute("cellspacing", 8);
        frameTable.setAttribute("border", 0);
        // give a class for later use
        frameTable.className = "bpp-frame";
        var frameTBody = document.createElement("tbody");
        
        var column_cnt = GM_getValue("bpp-column-number") || 1; // default 1 column
        var trs_cnt = Math.ceil(tds.snapshotLength / column_cnt);
        for ( i = 0; i < trs_cnt; i++ ) {
            for ( j = 0; j < column_cnt; j++ ) {
                var index = i * column_cnt + j;
                if ( index >= tds.snapshotLength ) break;
                var td    = tds.snapshotItem(index);
                var table = td.parentNode.parentNode.parentNode;
                if ( table.nextSibling && table.nextSibling.tagName == "BR" ) {
                    table.nextSibling.style.display = "none";
                }
                var frameTd = td;
                frameTd.style.width = (100 / column_cnt) + "%";
                frameTd.style.verticalAlign = "top";
                frameTd.style.padding = "8px";
                if ( 0 == j ) {
                    var frameTr = document.createElement("tr");
                    frameTBody.appendChild(frameTr);
                }
                frameTr.appendChild(frameTd);
                removeSelf(table);
            }
        }
        frameTable.appendChild(frameTBody);
        if ( document.getElementsByClassName('bpp-frame').length > 0 ) {
            var hrs = document.getElementsByTagName('hr');
            document.body.insertBefore(frameTable, hrs.item(hrs.length - 1).nextSibling.nextSibling);
        } else {
            document.body.insertBefore(frameTable, sideBarTable.nextSibling);
        }
    }
}

multiColumn();


// ****colorful results****
function colorfulTables() 
{
    if ( !GM_getValue("bpp-colorful-background-disabled") ) {
        var tds = getXPathResult("//td[@class='f']");
        for ( i = 0; i < tds.snapshotLength; i++ ) {
            var td = tds.snapshotItem(i);
            if ( td.style.backgroundColor ) continue;
            var r = parseInt(Math.random() * 48) + 220;
            var g = parseInt(Math.random() * 48) + 220;
            var b = parseInt(Math.random() * 48) + 220;
            with ( td.style ) {
                backgroundColor = 'rgb(' + r + ',' + g + ',' + b + ')';
                MozBorderRadius = "8px";
                border = "1px solid rgb(" + (r - 16) + ',' + (g - 16) + ',' + (b - 16) + ')';
            }
        }
    }
}
    
colorfulTables();


// ****Add favicon****
function addFavicon() 
{
    if ( !GM_getValue("bpp-show-favicon-disabled") ) {
        var results = getXPathResult("//td[@class='f']");
        for ( i = 0; i < results.snapshotLength; i++ ) {
            var a = results.snapshotItem(i).firstChild;
            if ( a.tagName == 'DIV' ) continue; // already have icon
            var container = document.createElement("div");
            container.style.width = container.style.height = "16px";
            container.style.backgroundImage = "url(chrome://global/skin/icons/folder-item.png)";
            container.style.cssFloat = "left";
            container.style.marginRight = "5px";
            
            var ico = document.createElement("img");
            ico.setAttribute("alt", "");
            ico.setAttribute("src", "http://" + a.hostname + "/favicon.ico");
            ico.setAttribute("width", 16);
            ico.style.backgroundColor = a.parentNode.style.backgroundColor;
            
            container.appendChild(ico);
            results.snapshotItem(i).insertBefore(container, a);
        }
    }    
}
    
addFavicon();



if ( document.getElementById("autopagerize_icon") ) {   // if have autopagerize
    // copy from favicon with google3
    var scrollHeight = document.documentElement.scrollHeight;
    document.addEventListener("scroll", function(){
            if( scrollHeight != document.documentElement.scrollHeight ) {
                scrollHeight = document.documentElement.scrollHeight;
                multiColumn();
                colorfulTables();
                addFavicon();
            }
    }, false);
}



// ****Config Pannel****
var button = document.createElement("a");
button.appendChild(document.createTextNode("[设置Baidu++]"));
button.setAttribute("href", "javascript:void(0)");
button.style.background = "yellow";
var a = getXPathResult("//a[text()='把百度设为主页']").snapshotItem(0);
a.parentNode.appendChild(document.createTextNode(" | "));
a.parentNode.appendChild(button);
// define click event
button.addEventListener("click", function() {
    var cover = document.createElement("div");
    cover.addEventListener("click", function() {
        removeSelf(cover.nextSibling);
        removeSelf(cover);
    }, false);
    with ( cover.style ) {
        width       = screen.availWidth + "px";
        height      = screen.availHeight + "px";
        background  = "#000";
        opacity     = 0.5;
        position    = "fixed";
        zIndex      = 1000;
        top         = 0;
        left        = 0;
    }
    document.body.appendChild(cover);
    // panel
    var panel = document.createElement("div");
    // table
    var table   = document.createElement("table");
    // table title
    var caption = document.createElement("caption");
    caption.style.fontWeight = "bold";
    caption.style.marginBottom = "8px";
    caption.appendChild(document.createTextNode("Baidu++[v" + VERSION + "]选项"));
    table.appendChild(caption);
    // table footer, contain a close button
    var tfoot  = document.createElement("tfoot");
    var tr     = document.createElement("tr");
    var td     = document.createElement("td");
    td.setAttribute("colspan", 2);
    td.style.textAlign = "center";
    var clsbtn = document.createElement("button"); // button
    clsbtn.appendChild(document.createTextNode("关闭"));
    // close button onclick event
    clsbtn.addEventListener("click", function() {
        removeSelf(cover);
        removeSelf(panel);
    }, false);
    td.appendChild(clsbtn);
    tr.appendChild(td);
    tfoot.appendChild(tr);
    table.appendChild(tfoot);
    
    // settings:
    var chk_removeAd        = document.createElement("input");
    var chk_cloneRelated2Top = document.createElement("input");
    var chk_addAltSearch    = document.createElement("input");
    var chk_flickr          = document.createElement("input");
    var chk_removePromotion = document.createElement("input");
    var chk_autoToPage2     = document.createElement("input");
    var chk_favicon         = document.createElement("input");
    var chk_colorfulBg      = document.createElement("input");
    
    if ( GM_getValue("bpp-remove-promotion-disabled") ) {
        GM_setValue("bpp-auto-to-page2-disabled", true);
        chk_autoToPage2.setAttribute("disabled", "disabled");
    }
    var chk_removeSponsors  = document.createElement("input");
    
    var settings = [
        { "id" : "bpp-remove-ad", "node" : chk_removeAd, "text" : "移除右侧广告" },
        { "id" : "bpp-clone-related-to-top", "node" : chk_cloneRelated2Top, "text" : "复制相关搜索到顶部" },
        { "id" : "bpp-add-alt-search", "node" : chk_addAltSearch, "text" : "增加其他搜索引擎链接" },
        { "id" : "bpp-flickr", "node" : chk_flickr, "text" : "增加flickr相关图片" },
        { "id" : "bpp-remove-promotion", "node" : chk_removePromotion, "text" : "搜索结果中移除百度推广" },
        { "id" : "bpp-auto-to-page2", "node" : chk_autoToPage2, "text" : "如果搜索结果全是推广自动跳转到第二页" },
        { "id" : "bpp-remove-sponsors", "node" : chk_removeSponsors, "text" : "搜索结果中移除赞助商链接" },
        { "id" : "bpp-show-favicon", "node" : chk_favicon, "text" : "搜索结果链接前加网站图标" },
        { "id" : "bpp-colorful-background", "node" : chk_colorfulBg, "text" : "搜索结果随机背景色(可改善autopagerize结果条目间距)" }
    ];
    
    var tbody = document.createElement("tbody");
    for ( i in settings ) { // insert checkbox
        var tr = document.createElement("tr");
        var td1 = document.createElement("td");
        with ( settings[i] ) {
            node.setAttribute("id", settings[i].id);
            node.setAttribute("type", "checkbox");
            if ( !GM_getValue(id + "-disabled") ) {
                node.setAttribute("checked", "checked");
            }
            node.addEventListener("change", function() {
                GM_setValue(id + "-disabled", !node.checked);
            }, false);
        }
        td1.appendChild(settings[i].node);
        var td2 = document.createElement("td");
        var label = document.createElement("label");
        label.setAttribute("for", settings[i].id);
        label.appendChild(document.createTextNode(settings[i].text));
        td2.appendChild(label);
        tr.appendChild(td1);
        tr.appendChild(td2);
        tbody.appendChild(tr);
    }
    
    chk_removePromotion.addEventListener("change", function() {
        if ( !chk_removePromotion.checked ) {
            chk_autoToPage2.checked = false;
            chk_autoToPage2.removeAttribute("checked");
            chk_autoToPage2.setAttribute("disabled", "disabled");
            GM_setValue("bpp-auto-to-page2-disabled", false);
        } else {
            chk_autoToPage2.removeAttribute("disabled");
        }
    }, false);
    // end settings;
    
    // multiColumn setting
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    td.appendChild(document.createTextNode('结果显示列数：'));
    td.setAttribute("colspan", 2);
    var select = document.createElement("select");
    for ( i = 1; i <= 4; i++ ) {
        var option = document.createElement("option");
        option.setAttribute("value", i);
        if ( i == GM_getValue("bpp-column-number") ) {
            option.setAttribute("selected", "selected");
        }
        option.appendChild(document.createTextNode(i));
        select.appendChild(option);
    }
    td.appendChild(select);
    tr.appendChild(td);
    tbody.appendChild(tr);
    select.addEventListener("change", function () {
        GM_setValue("bpp-column-number", select.options[select.selectedIndex].value);
    }, false);
    
    // tips - change after refresh
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    td.setAttribute("colspan", 2);
    var em = document.createElement("em");
    em.appendChild(document.createTextNode("修改后刷新页面生效"));
    em.style.fontSize = "8pt";
    td.appendChild(em);
    tr.appendChild(td);
    tbody.appendChild(tr);
    table.appendChild(tbody);
    panel.appendChild(table);
    var a = document.createElement("a");
    a.appendChild(document.createTextNode("Baidu++发布页"));
    a.setAttribute("href", "http://hi.baidu.com/chrisyue/blog/item/0e6655df55ff401b48540341.html");
    a.setAttribute("target", "_blank");
    a.style.fontSize = "9pt";
    panel.appendChild(a);
    document.body.appendChild(panel);
    with ( panel.style ) {
        padding     = "20px";
        background  = "#fff";
        border      = "1px solid #ccf";
        position    = "fixed";
        zIndex      = 2000;
        top         = document.body.clientHeight / 2 - panel.clientHeight / 2 + "px";
        left        = document.body.clientWidth  / 2 - panel.clientWidth  / 2 + "px";
        MozBorderRadius = "8px";
    }
    clsbtn.focus();
}, false);




} catch (e) {
    //for ( property in e ) {
    //    alert(property + ":" + e[property]);
    //}
    //alert(e.message)
}