quick-view-douban

see douban book movie music in every webpage by selecting text

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name           quick-view-douban
// @namespace      http://vivyli.com
// @modified       ywzhaiqi
// @include        *
// @version        2.1
// @description    see douban book movie music in every webpage by selecting text
// @description    修正电影搜索,增加图片显示
// @grant          GM_xmlhttpRequest
// ==/UserScript==

var apikey = '0c088077ba8a630f241981672f9f292d';

var imgDouban;
var txtSelection;
var isBookClicked = false;
var isMovieClicked = false;
var isMusicClicked = false;
var q = null;
var userAgent = 'known';
initialize();

document.addEventListener('mousedown', clean, false);
document.addEventListener('mouseup', showIcon, false);

function clean(event) {
    var divInfo = getId('divInfo');
    var divSearch = getId('divSearch');

    if (divInfo) {
        if (!clickedInsideID(event.target, 'divInfo'))
            divInfo.parentNode.removeChild(divInfo);
    }

    if (divSearch)
        divSearch.parentNode.removeChild(divSearch);
}

function showIcon(event) {
    var divInfo = getId('divInfo');
    var divSearch = getId('divSearch');

    if (!clickedInsideID(event.target, 'divInfo'))
        txtSelection = getSelection(event);
    else
        return;
    if (txtSelection == '') {
        return;
    } else {
        q = txtSelection;
    }
    divSearch = createElement('div', {
        id: 'divSearch',
        style: 'top:' + (event.clientY + window.pageYOffset + 10) + 'px; left:' + (event.clientX + window.pageXOffset + 10) + 'px;'
    });
    divSearch.appendChild(imgDouban.cloneNode(false));
    divSearch.addEventListener('mouseover', showDouban, false);
    document.body.appendChild(divSearch);
}

function showDouban(event) {
    var divResult = null;
    var divInfo = getId('divInfo');
    var divSearch = getId('divSearch');
    var top = divSearch.style.top;
    var left = divSearch.style.left;

    divInfo = createElement('div', {
        id: 'divInfo'
    });
    divInfo.style.top = top;
    divInfo.style.left = left;
    document.body.appendChild(divInfo);

    var bookDiv = createElement('div', {
        id: 'bookDiv',
        title: 'book'
    }, null, null);
    var bookClickDiv = createElement('div', {
        id: 'bookClickDiv'
    }, 'mouseup showDoubanBook false', '+豆瓣读书');
    bookDiv.appendChild(bookClickDiv);
    divInfo.appendChild(bookDiv);

    var movieDiv = createElement('div', {
        id: 'movieDiv',
        title: 'movie'
    }, null, null);
    var movieClickDiv = createElement('div', {
        id: 'movieClickDiv'
    }, 'mouseup showDoubanMovie false', '+豆瓣电影');
    movieDiv.appendChild(movieClickDiv);
    divInfo.appendChild(movieDiv);

    var musicDiv = createElement('div', {
        id: 'musicDiv',
        title: 'music'
    }, null, null);
    var musicClickDiv = createElement('div', {
        id: 'musicClickDiv'
    }, 'mouseup showDoubanMusic false', '+豆瓣音乐');
    musicDiv.appendChild(musicClickDiv);
    divInfo.appendChild(musicDiv);

}

function showDoubanBook(event) {
    if (isBookClicked == false) {
        getId('bookClickDiv').innerHTML = '-豆瓣读书 loading...';
        isBookClicked = true;
        showBookInfo();
    } else if (isBookClicked == true) {
        getId('bookClickDiv').innerHTML = '+豆瓣读书';
        cleanBook();
        //getId('bookDiv')
        isBookClicked = false;
    }
}

function cleanBook() {
    var bookInfo = getId('bookInfo');
    var morebooks = getId('morebooks');
    if (bookInfo != null)
        bookInfo.parentNode.removeChild(bookInfo);
    if (morebooks != null)
        morebooks.parentNode.removeChild(morebooks);
}

function showBookInfo() {
    var bookurl = 'http://api.douban.com/book/subjects?q=' + q + '&apikey=' + apikey;
    var moreurl = 'http://book.douban.com/subject_search?search_text=' + q + '&cat=1001';
    GM_xmlhttpRequest({
        method: 'GET',
        url: bookurl,
        onload: function(resp) {
            var book = parseBook(resp.responseText);
            var bookInfo = createElement('div', {
                id: 'bookInfo'
            }, null, book);
            getId('bookDiv').appendChild(bookInfo);
            var more = createElement('div', {
                id: 'more'
            }, null, null);
            getId('bookDiv').appendChild(more);
            more.appendChild(createElement('a', {
                id: 'morebooks',
                href: moreurl,
                target: '_blank'
            }, null, '--更多书籍--'));
            getId('bookClickDiv').innerHTML = '-豆瓣读书';
        }
    });
}

function parseBook(text) {
    return parse(text, 'Book');
}
// Douban Movie

function showDoubanMovie(event) {
    if (isMovieClicked == false) {
        getId('movieClickDiv').innerHTML = '-豆瓣电影 loading...';
        isMovieClicked = true;
        // showMovieInfo();
        showMovieInfo2();
    } else if (isMovieClicked == true) {
        getId('movieClickDiv').innerHTML = '+豆瓣电影';
        cleanMovie();
        //getId('bookDiv')
        isMovieClicked = false;
    }
}

function cleanMovie() {
    var movieInfo = getId('movieInfo');
    var moremovies = getId('moremovies');
    if (movieInfo != null)
        movieInfo.parentNode.removeChild(movieInfo);
    if (moremovies != null)
        moremovies.parentNode.removeChild(moremovies);
}

// version 2
function showMovieInfo2() {
    var movieurl = 'https://api.douban.com/v2/movie/search?q=' + q;
    var moreurl = 'http://movie.douban.com/subject_search?search_text=' + q + '&cat=1002';
    GM_xmlhttpRequest({
        method: 'GET',
        url: movieurl,
        onload: function(res) {
            var obj = JSON.parse(res.responseText);
            var movie = obj.subjects[0];
            var html;
            if(movie){
                movie.subtype = (movie.subtype == 'tv') ? "电视剧" : "电影";
                movie.original_title = (movie.original_title == movie.title) ? "" : movie.original_title;

                var template = '\
                    <img src="{images.small}" alt={alt} align="right"/>\
                    {subtype}: <a id = "turl" href="{alt}" target="_blank">{title}</a><br/>\
                    原名: {original_title}<br/>\
                    时间: {year}<br/>\
                    <span class="_allstar{rating.stars}"></span>\
                    <span>{rating.average}</span>\
                    <span>({collect_count}评价)</span>\
                ';
                html = nano(template, movie);
            }else{
                html = "对不起,找不到相关的电影";
            }

            var movieInfo = createElement('div', {
                id: 'movieInfo'
            }, null, html);
            getId('movieDiv').appendChild(movieInfo);
            var more = createElement('div', {
                id: 'more'
            }, null, null);
            getId('movieDiv').appendChild(more);
            more.appendChild(createElement('a', {
                id: 'moremovies',
                href: moreurl,
                target: '_blank'
            }, null, '--更多电影--'));
            getId('movieClickDiv').innerHTML = '-豆瓣电影';
        }
    });
}

function showMovieInfo() {
    //alert(q);
    var movieurl = 'http://api.douban.com/movie/subjects?q=' + q + '&apikey=' + apikey;
    var moreurl = 'http://movie.douban.com/subject_search?search_text=' + q + '&cat=1002';
    GM_xmlhttpRequest({
        method: 'GET',
        url: movieurl,
        onload: function(resp) {
            var movie = parseMovie(resp.responseText);
            var movieInfo = createElement('div', {
                id: 'movieInfo'
            }, null, movie);
            getId('movieDiv').appendChild(movieInfo);
            var more = createElement('div', {
                id: 'more'
            }, null, null);
            getId('movieDiv').appendChild(more);
            more.appendChild(createElement('a', {
                id: 'moremovies',
                href: moreurl,
                target: '_blank'
            }, null, '--更多电影--'));
            getId('movieClickDiv').innerHTML = '-豆瓣电影';
        }
    });
}

function parseMovie(text) {
    return parse(text, 'Movie');
}
//Douban Music

function showDoubanMusic(event) {
    if (isMusicClicked == false) {
        getId('musicClickDiv').innerHTML = '-豆瓣音乐 loading...';
        isMusicClicked = true;
        showMusicInfo();
    } else if (isMusicClicked == true) {
        getId('musicClickDiv').innerHTML = '+豆瓣音乐';
        cleanMusic();
        //getId('bookDiv')
        isMusicClicked = false;
    }
}

function cleanMusic() {
    var musicInfo = getId('musicInfo');
    var moremusics = getId('moremusics');
    if (musicInfo != null)
        musicInfo.parentNode.removeChild(musicInfo);
    if (moremusics != null)
        moremusics.parentNode.removeChild(moremusics);
}

function showMusicInfo() {
    var musicurl = 'http://api.douban.com/music/subjects?q=' + q + '&apikey=' + apikey;
    var moreurl = 'http://music.douban.com/subject_search?search_text=' + q + '&cat=1003';
    GM_xmlhttpRequest({
        method: 'GET',
        url: musicurl,
        onload: function(resp) {
            var music = parseMusic(resp.responseText);
            var musicInfo = createElement('div', {
                id: 'musicInfo'
            }, null, music);
            getId('musicDiv').appendChild(musicInfo);
            var more = createElement('div', {
                id: 'more'
            }, null, null);
            getId('musicDiv').appendChild(more);
            more.appendChild(createElement('a', {
                id: 'moremusics',
                href: moreurl,
                target: '_blank'
            }, null, '--更多音乐--'));
            getId('musicClickDiv').innerHTML = '-豆瓣音乐';
        }
    });
}

function parseMusic(text) {
    return parse(text, 'Music');
}

function parse(text, category) {
    var cat = category;
    if (category == 'Book')
        cat = '书籍';
    else if (category == 'Music')
        cat = '音乐';
    else if (category == 'Movie')
        cat = '电影';

    var ratingTag = 'rating';
    var attributeTag = 'attribute';
    if (userAgent == 'Firefox') {
        ratingTag = 'gd:' + ratingTag;
        attributeTag = 'db:' + attributeTag;
    }
    var res = '';

    var parser = new DOMParser();
    var dom = parser.parseFromString(text, "text/xml");
    var entities = dom.getElementsByTagName("entry");

    if (entities.length > 0) {

        var entry = entities[0];

        var id = entry.getElementsByTagName("id")[0].textContent;
        var title = entry.getElementsByTagName("title")[0].textContent;
        var rate = entry.getElementsByTagName(ratingTag)[0].getAttribute('average');
        var total = entry.getElementsByTagName(ratingTag)[0].getAttribute('numRaters');

        var attrs = entry.getElementsByTagName(attributeTag);
        var links = entry.getElementsByTagName('link');
        if (category == 'Book') {
            var author = '';
            var price = '';
            var publisher = '';
            var pubdate = '';
            for (var i = 0; i < attrs.length; i++) {
                var name = attrs[i].getAttribute('name').toString();

                if (name == "author") {
                    if (author == '')
                        author = attrs[i].textContent;
                    else author += ', ' + attrs[i].textContent;
                } else if (name == 'price') {
                    price = attrs[i].textContent;
                } else if (name == 'publisher') {
                    publisher = attrs[i].textContent;
                } else if (name == 'pubdate') {
                    pubdate = attrs[i].textContent;
                }

            }
            var url = '';
            if (links.length > 0) {
                for (var i = links.length - 1; i >= 0; i--) {
                    var rel = links[i].getAttribute('rel').toString();
                    if (rel == 'alternate') {
                        url = links[i].getAttribute('href').toString();
                        break;
                    }
                };
            }

            var imgSrc = entry.querySelector('link[rel="image"]').getAttribute('href');

            res = '<img src="' + imgSrc + '" align="right"/>' +
                '书籍: <a id = "turl" href = "' + url + '" target = "_blank">' + title + '</a><br/>' +
                '作者: ' + author + '<br/>' +
                '价格: ' + price + '<br/>' +
                '发行: ' + publisher + '<br/>' +
                '时间: ' + pubdate + '<br/>' +
                '评分: ' + rate + '(共' + total + ' 条评价)';

        } else if (category == 'Music') {
            var singer = '';
            var pubdate = '';
            var publisher = '';

            for (var i = 0; i < attrs.length; i++) {
                var name = attrs[i].getAttribute('name');
                if (name == 'singer') {
                    if (singer == '')
                        singer = attrs[i].textContent;
                    else singer += ', ' + attrs[i].textContent;
                } else if (name == 'pubdate') {
                    pubdate = attrs[i].textContent;
                } else if (name == 'publisher') {
                    publisher = attrs[i].textContent;
                }

            }
            var url = '';
            if (links.length > 0) {
                for (var i = links.length - 1; i >= 0; i--) {
                    var rel = links[i].getAttribute('rel').toString();
                    if (rel == 'alternate') {
                        url = links[i].getAttribute('href').toString();
                        break;
                    }
                };
            }
            res = cat + ': <a id = "turl" href = "' + url + '" target = "_blank">' + title + '</a><br/>' +
                '歌手: ' + singer + '<br/>' +
                '时间: ' + pubdate + '<br/>' +
                '发行: ' + publisher + '<br/>' +
                '评分: ' + rate + '(共' + total + ' 条评价)';

        } else if (category == 'Movie') {
            var country = '';
            var director = '';
            var pubdate = '';
            var lang = '';
            var cast = '';
            for (var i = 0; i < attrs.length; i++) {
                var name = attrs[i].getAttribute('name');
                if (name == 'country') {
                    if (country == '')
                        country = attrs[i].textContent;
                    else country += ', ' + attrs[i].textContent;
                } else if (name == 'director') {
                    if (director == '')
                        director = attrs[i].textContent;
                    else director += ', ' + attrs[i].textContent;
                } else if (name == 'pubdate') {
                    pubdate = attrs[i].textContent;
                } else if (name == 'language') {
                    if (lang == '')
                        lang = attrs[i].textContent;
                    else lang += ', ' + attrs[i].textContent;
                } else if (name == 'cast') {
                    if (cast == '')
                        cast = attrs[i].textContent;
                    else cast += ', ' + attrs[i].textContent;
                }

            }
            var url = '';
            if (links.length > 0) {
                for (var i = links.length - 1; i >= 0; i--) {
                    var rel = links[i].getAttribute('rel').toString();
                    if (rel == 'alternate') {
                        url = links[i].getAttribute('href').toString();
                        break;
                    }
                };
            }
            res = cat + ': <a id = "turl" href = "' + url + '" target = "_blank">' + title + '</a><br/>' +
                '导演: ' + director + '<br/>' +
                '主演: ' + cast + '<br/>' +
                '国家: ' + country + '<br/>' +
                '时间: ' + pubdate + '<br/>' +
                '评分: ' + rate + '(共' + total + ' 条评价)';
        }

        return res;
    }
    return '对不起,找不到相关的' + cat;
}

function getSelection(event) {
    var txt = null;

    if (event && event.target.nodeName == 'TextArea') {
        txt = event.target.value.substr(event.target.selectionStart, event.target.selectionEnd - event.target.selectionStart);
    } else if (window.getSelection) {
        txt = window.getSelection();
    } else if (document.getSelection) {
        txt = window.getSelection();
    } else if (document.selection) {
        txt = document.selection.createRange().text;
    }
    return txt.toString();

}

function getId(id, parent) {
    if (!parent)
        return document.getElementById(id);
    return parent.getElementById(id);
}

function createElement(type, attrArray, evtListener, html) {
    var node = document.createElement(type);

    for (var attr in attrArray)
        if (attrArray.hasOwnProperty(attr)) {
            node.setAttribute(attr, attrArray[attr]);
        }

    if (evtListener) {
        var a = evtListener.split(' ');
        node.addEventListener(a[0], eval(a[1]), eval(a[2]));
    }

    if (html)
        node.innerHTML = html;

    return node;
}

function getTag(name, parent) {
    if (!parent)
        return document.getElementsByTagName(name);
    return parent.getElementsByTagName(name);
}

function clickedInsideID(target, id) {

    if (target.getAttribute('id') == id)
        return getId(id);

    if (target.parentNode) {
        while (target = target.parentNode) {
            try {
                if (target.getAttribute('id') == id)
                    return getId(id);
            } catch (e) {}
        }
    }

    return null;
}

// initialize

function initialize() {
    images();
    css();
    checkUserAgent();
}

function checkUserAgent() {
    if (navigator["userAgent"].indexOf('Firefox') != -1)
        userAgent = 'Firefox';
    else if (navigator['userAgent'].indexOf('Chrome') != -1)
        userAgent = 'Chrome';
}

function css() {

    var style = createElement('style', {
            id: 'douban-view',
            type: "text/css"
        }, null, "" +
        '#bookClickDiv {cursor : pointer; color: #FFFFFF;}' +
        '#musicClickDiv {cursor : pointer;color: #FFFFFF;}' +
        '#movieClickDiv {cursor: pointer;color: #FFFFFF;}' +
        '#bookInfo {color: #FFFFFF;}' +
        '#musicInfo {color: #FFFFFF;}' +
        '#movieInfo {color: #FFFFFF;}' +
        '#divSearch { background-color:#FFFFFF; color:#000000; position:absolute; padding:3px; z-index:999999999; -moz-border-radius:3px; }' +
        '#divInfo { background-color:#000000; color:#FFFFFF !important; filter: Alpha(opacity=10);opacity:0.75;  position:absolute; min-width:250px; min-height:50px; max-width:100%; padding:7px; font-size:small; text-align:left; z-index:999999999; -moz-border-radius:3px; }' +
        '#more{ text-align: right;}' +
        '#morebooks{color: #FFAA00}' +
        '#moremusics{color: #FFAA00}' +
        '#moremovies{color: #FFAA00}' +
        '#turl{color: #FFAA00}' +
        '._allstar50, ._allstar45, ._allstar40, ._allstar35, ._allstar30, ._allstar25, ._allstar20, ._allstar15, ._allstar10, ._allstar05 {\
            background: url("http://www.douban.com/pics/movie/midstars.gif") no-repeat scroll 0 0 transparent;\
            display: inline-block;\
            height: 11px;\
            margin: 0 3px 0 0;\
            overflow: hidden;\
            width: 55px;\
        }'
    );
    getTag('head')[0].appendChild(style);
}

function images() {
    imgDouban = createElement('img', {
        border: 0
    });
    imgDouban.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzEAAADHmlDQ1BJQ0MgUHJvZmlsZQAAeAGFVN9r01AU/tplnbDhizpnEQk+aJFuZFN0Q5y2a1e6zVrqNrchSJumbVyaxiTtfrAH2YtvOsV38Qc++QcM2YNve5INxhRh+KyIIkz2IrOemzRNJ1MDufe73/nuOSfn5F6g+XFa0xQvDxRVU0/FwvzE5BTf8gFeHEMr/GhNi4YWSiZHQA/Tsnnvs/MOHsZsdO5v36v+Y9WalQwR8BwgvpQ1xCLhWaBpXNR0E+DWie+dMTXCzUxzWKcECR9nOG9jgeGMjSOWZjQ1QJoJwgfFQjpLuEA4mGng8w3YzoEU5CcmqZIuizyrRVIv5WRFsgz28B9zg/JfsKiU6Zut5xCNbZoZTtF8it4fOX1wjOYA1cE/Xxi9QbidcFg246M1fkLNJK4RJr3n7nRpmO1lmpdZKRIlHCS8YlSuM2xp5gsDiZrm0+30UJKwnzS/NDNZ8+PtUJUE6zHF9fZLRvS6vdfbkZMH4zU+pynWf0D+vff1corleZLw67QejdX0W5I6Vtvb5M2mI8PEd1E/A0hCgo4cZCjgkUIMYZpjxKr4TBYZIkqk0ml0VHmyONY7KJOW7RxHeMlfDrheFvVbsrj24Pue3SXXjrwVhcW3o9hR7bWB6bqyE5obf3VhpaNu4Te55ZsbbasLCFH+iuWxSF5lyk+CUdd1NuaQU5f8dQvPMpTuJXYSWAy6rPBe+CpsCk+FF8KXv9TIzt6tEcuAcSw+q55TzcbsJdJM0utkuL+K9ULGGPmQMUNanb4kTZyKOfLaUAsnBneC6+biXC/XB567zF3h+rkIrS5yI47CF/VFfCHwvjO+Pl+3b4hhp9u+02TrozFa67vTkbqisXqUj9sn9j2OqhMZsrG+sX5WCCu0omNqSrN0TwADJW1Ol/MFk+8RhAt8iK4tiY+rYleQTysKb5kMXpcMSa9I2S6wO4/tA7ZT1l3maV9zOfMqcOkb/cPrLjdVBl4ZwNFzLhegM3XkCbB8XizrFdsfPJ63gJE722OtPW1huos+VqvbdC5bHgG7D6vVn8+q1d3n5H8LeKP8BqkjCtbCoV8yAAACAUlEQVQ4EZVTz0sbQRh9+0tTbf0RFRWprawGEbQgDa5NcpP2Iu3BlmqN/4v/gCBePIiIKBEvHooULAEvEUSxtqJio1ZLwepajJqou0k2cWY3WbNJhTjLzM735r038307y0S1WNK3PIvAzhJCV+fIp5UXl8Hd7MIn6SO4hteOwflvX6DElHy0Oodyg393oWgqOLtUNajGo3mLM4knoWPwl0pYxzzkSO/auzPX753vy78w6h8D1fJp1tafbezLB1CjKsCk0ax3EhB4HnFNMxdMg7OrEED625fdeFZZTwi5LhHlEnMrn3FxfZFrQJE6ex16ne8xuTQNlRQo2+SDswdHZydY2Pj6fwOe4yCH/xGC3yRkTl48bYUgmIfWlyyRRnKrfGwHLehNTAXLGGkkQR6Sv1glYvd4L9PzrogUPQ2fYmHTD0ns0EkcxxpkItYSCQTlINYOvxtYarScQI1FMRXw4U1bFw7kQwRTu9mEQgx4vBhfnEAimbAYpLawYHhUWAS3w2WCjpomPK+ozxFTgmnAMiwKeEHvO0c/oZGd0rHkkLD++4cZUzzdmJ6RPpIh4HX3QawWDZzkS0GGNfxrS6oRuj6HEqefFoioEQzND+tzvsT2RL+S04EZHXjIQLWsp8XzEI2F625+Bd7b2Ys4+RuX91YtV9TCzApKi0ohNTox4OrHLRsAtvjqiOggAAAAAElFTkSuQmCC';
}


var _regex = /\{([\w\.]*)\}/g;
function nano(template, data) {
    return template.replace(this._regex, function(str, key) {
        var keys = key.split('.'),
            value = data[keys.shift()];
        keys.forEach(function(key) {
            value = value[key];
        });
        return (value === null || value === undefined) ? '' : value;
    });
}