// ==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;
});
}