There are 32 previous versions of this script.
// ==UserScript==
// @name Google Reader Favicon ++
// @description Adds favicons to feeds and entries
// @namespace Yamamaya
// @version 4.0.3
// @include http://*google.tld/reader/view*
// @include https://*google.tld/reader/view*
// ==/UserScript==
/*************************************************
This script is based on
Ultimate GReader favicons
http://userscripts.org/scripts/show/27739
Google Reader - Colorful List View
http://userscripts.org/scripts/show/8782
***************************************************/
(function(){
var GOOGLE_READER_INFO = eval(GM_getValue('googleReaderInformation')) || {};
var FAVICON = GOOGLE_READER_INFO.favicon || (GOOGLE_READER_INFO.favicon = {});
var FAVICON_URL = ['http://getfavicon.appspot.com/http://', ''];
var FAVICON_DEFAULT_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABdUExURa2z+H6CrWtwpnN5uWNopejp9Pf3/6+08Kes6G50uePm/qSr+MTG6ZSZzbW4593e93R4qs3R/JOWu5Oa8dbZ/ISJvJ6l9Ovs/sXJ+amszL3C9/P0/7W6+J+izP////fbRfQAAAEbSURBVHjaYpCTFYICOTAACCAGWT5pNml+QQkpPlGwAEAAMcgKCvKLy7FKsXMISAKBHEAAMchKychIyYjLSbAzioiI8EgCBBCDLIO4HJsMg7i0jCgbUKcsQAAxyMpIMAKBAAjIiUjIAgQQUIsoh7i0uAhQpywTm6AsQAABDRWVkhARl5OWYOBmkRORBQggBlkRUQYxMQYZaTkpMRZpVkmAAGLgZRcV45KTlhGTluZg4ZKWBAggBjleUTEZCS45GRk5KRZ+VkmAAGKQkxNlEBYWE5cWE+dnkuKRBAggkICEtLiwhJywCCsT0KUAAQQSEJSTE5YS55bgZwL6BSCAgAKMYlLsYsJAIAsSAAggoIAcMycnMzMQCYB8CxBgAB2IFJeOuyn5AAAAAElFTkSuQmCC';
var COLORFUL_FLAG = GOOGLE_READER_INFO.colorfulViewFlag || false;
var COLORFUL_BUTTON_TEXT = GOOGLE_READER_INFO.colorfulViewText || 'Colorful View On';
var COLORFUL_BUTTON_CLASS_CONTENT = GOOGLE_READER_INFO.colorfulViewButtonContentClass || '';
var COLORFUL_BUTTON_CLASS_POS = GOOGLE_READER_INFO.colorfulViewButtonPosClass || '';
var COLORFUL_BUTTON_CLASS_TOP_SHADOW = GOOGLE_READER_INFO.colorfulViewButtonTopShadowClass || '';
var COLORFUL_BUTTON_CLASS_INNER_BOX = GOOGLE_READER_INFO.colorfulViewButtonInnerBoxClass || '';
var RSS = $X('id("sub-tree-item-0-main")/ul/li/ul/li').length;
var FOLDER = $X('id("sub-tree-item-0-main")/ul/li').length;
var RSS_NUMBERS = GOOGLE_READER_INFO.rssNumber || null;
var FOLDER_NUMBERS = GOOGLE_READER_INFO.folderNumber || null;
var googleReader = {
init: function(){
(RSS_NUMBERS === null || FOLDER_NUMBERS === null || RSS !== RSS_NUMBERS || FOLDER !== FOLDER_NUMBERS) ?
this.noCacheAddFavicon(): this.addFavicon();
this.addBaseCss();
if(COLORFUL_FLAG == false)
this.addNoColorfulListViewCss();
GM_registerMenuCommand('GoogleReaderFavicon++ - clear cache', clearCache);
GOOGLE_READER_INFO.rssNumber = RSS;
GOOGLE_READER_INFO.folderNumber = FOLDER;
setValue();
},
noCacheAddFavicon: function(){
var xhr = new XMLHttpRequest();
xhr.open('get', '/reader/subscriptions/export', true);
xhr.onload = function(){
var responseXML = xhr.responseXML;
Array.forEach(responseXML.getElementsByTagName('outline'), function(outline){
if (!outline.hasAttribute('htmlUrl')) return;
var title = outline.getAttribute('title');
var url = outline.getAttribute('htmlUrl');
var favicon;
url = url.split(/\/|\?/)[2];
(title.length > 24) ?
FAVICON[title.substr(0, 21) + '...'] = FAVICON_URL.join(url):
FAVICON[title] = FAVICON_URL.join(url);
});
googleReader.addFavicon();
setValue();
};
xhr.send(null);
},
addFavicon: function(){
entryFaviconNoDOMNodeInserted();
if(COLORFUL_FLAG == true)
this.colorfulListView.setColor();
this.colorfulListView.button();
this.entryFavicon();
this.sideBarFavicon();
function entryFaviconNoDOMNodeInserted(){
$X('.//span[@class="entry-source-title"] | .//a[@class="entry-source-title"]').forEach(function(title){
var match = title.textContent;
if(match.length > 24)
match = match.substr(0,21) + '...';
var favicon = document.createElement('img');
favicon.className = 'entry-favicon';
if(COLORFUL_FLAG == true){
var target;
(title.tagName === 'SPAN') ?
target = title.parentNode.parentNode.parentNode:
target = title.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
if(target.getAttribute('color') === null)
target.setAttribute('color',match.replace(/"/g,''));
}
if(FAVICON.hasOwnProperty(match)){
favicon.src = FAVICON[match]
}
else{
favicon.src = FAVICON_DEFAULT_IMG;
}
if(title.tagName !== 'SPAN'){
title = title.parentNode.parentNode.getElementsByTagName('a')[0];
}
title.parentNode.insertBefore(favicon,title);
favicon.removeEventListener('error',revertFavicon,false);
favicon.addEventListener('error',revertFavicon,false);
});
};
},
entryFavicon: function(){
document.addEventListener('DOMNodeInserted', function(e){
var target = e.target;
entry(target);
sideBar(target);
}, false);
function entry(target){
if(/^entry\s/i.test(target.className) && target.tagName === 'DIV'){
var point, match;
var favicon = document.createElement('img');
favicon.className = 'entry-favicon';
if(target.firstChild.className === 'collapsed'){ // リスト表示 .//span[contains(@class,'entry-source-title')]
point = target.getElementsByTagName('span')[0];
match = point.textContent;
}
else{// 前文表示 .//span[@class='entry-source-title-parent'], 検索, コメント共有
point = target.getElementsByClassName('entry-title-link')[0] || target.getElementsByClassName('comment-entry-title')[0];
var title = target.getElementsByClassName('entry-source-title')[0];
match = title.textContent;
}
if(match.length > 24)
match = match.substr(0,21) + '...';
if(target.getAttribute('color') === null)
target.setAttribute('color',match.replace(/"/g,''));
if(FAVICON.hasOwnProperty(match)){
favicon.src = FAVICON[match];
}
else{ // popular items | recommended sources
var fs = target.getElementsByClassName('entry-original')[0] || target.getElementsByClassName('entry-title-link')[0];
if(fs){
fs = FAVICON_URL.join(fs.href.split(/\/|\?/)[2]);
favicon.src = fs;
}
else{
favicon.src = FAVICON_DEFAULT_IMG;
}
}
point.parentNode.insertBefore(favicon, point);
favicon.removeEventListener('error', revertFavicon, false);
favicon.addEventListener('error', revertFavicon, false);
}
};
function sideBar(target){
if(target.nodeName.toLowerCase() === 'li' && target.className.match(/^folder/))
googleReader.sideBarFavicon();
};
},
sideBarFavicon: function(){
$X('id("sub-tree")//span[contains(@class,"sub-icon")]').forEach(function(e){
if(e.parentNode.firstChild.nodeName.toLowerCase() === 'img') return;
var title = e.nextSibling;
var match = title.firstChild.textContent;
if(match.length > 24) match = match.substr(0,21) + '...';
title.style.paddingLeft = '7px';
var favicon = document.createElement('img');
e.parentNode.insertBefore(favicon,e);
e.parentNode.removeChild(e);
if(FAVICON.hasOwnProperty(match)){
favicon.src = FAVICON[match];
}
else{
favicon.src = FAVICON_DEFAULT_IMG;
}
favicon.removeEventListener('error',revertFavicon,false);
favicon.addEventListener('error',revertFavicon,false);
});
},
addBaseCss: function(){
GM_addStyle(<><![CDATA[
img.entry-favicon {
width: 16px !important;
height: 16px !important;
border: none !important;
margin-right: 5px;
}
.collapsed img.entry-favicon {
position: absolute !important;
top: 3px !important;
left: 1.6em !important;
margin-right: 0px !important;
vertical-align: baseline !important;
}
#entries.list .collapsed .entry-main .entry-source-title {
left: 3.25em !important;
width:9em !important;
}
#sub-tree ul ul li a {
padding-left:22px !important;
}
#sub-tree a img {
width:16px;
height:16px;
border:none;
vertical-align:middle;
}
#entries.list .collapsed .entry-secondary {
margin: 0 8.5em 0 14em !important;
}
#entries.single-source .collapsed .entry-source-title {
display:block !important;
}
.colorful-view-content {
color: #EEEEEE !important;
}
.colorful-view-base-top-shadow {
background-color:#999999 !important;
border-bottom-color:#888888 !important;
}
.colorful-view-inner-box {
background-color:#777777 !important;
background:#F9F9F9 none repeat scroll 0 0 !important;
border-color:#888888 !important;
}
.colorful-view-base-pos {
background-color:#777777 !important;
border-color:#888888 !important;
}
]]></>);
},
addNoColorfulListViewCss: function(){
GM_addStyle(<><![CDATA[
#entries.list .read .collapsed {
opacity:0.6;
}
#entries.list .entry .collapsed:hover {
background:#C2CFF1;
}
#entries.list .read .collapsed:hover {
opacity:1.0;
background:#C2CFF1;
}
]]></>);
},
/*----------------------------------------------------------------------------------
Google Reader - Colorful List View / http://userscripts.org/scripts/show/8782
-----------------------------------------------------------------------------------*/
colorfulListView: {
button: function(){
var insert = document.getElementById('stream-prefs-menu');
var div = document.createElement('div');
var divStyle = div.style;
divStyle.marginLeft = '0.5em';
div.className = 'goog-button goog-button-base unselectable goog-inline-block goog-button-float-left goog-menu-button goog-button-tight scour-disabled';
div.setAttribute('tabindex','0');
div.setAttribute('role','wairole:button');
div.innerHTML = '<div class="goog-button-base-outer-box goog-inline-block">\
<div class="goog-button-base-inner-box '+COLORFUL_BUTTON_CLASS_INNER_BOX+'">\
<div class="goog-button-base-pos '+COLORFUL_BUTTON_CLASS_POS+'">\
<div class="goog-button-base-top-shadow '+COLORFUL_BUTTON_CLASS_TOP_SHADOW+'"> </div>\
<div class="goog-button-base-content '+COLORFUL_BUTTON_CLASS_CONTENT+'">\
<div class="goog-button-body">'+COLORFUL_BUTTON_TEXT+'</div>\
</div>\
</div>\
</div>\
</div>';
insert.parentNode.insertBefore(div,insert.nextSibling);
div.addEventListener('click',function(e){
var buttonBody = $X('.//div[contains(@class,"goog-button-body")]',div)[0];
var buttonPos = $X('.//div[contains(@class,"goog-button-base-pos")]',div)[0];
var buttonTopShadow = $X('.//div[contains(@class,"goog-button-base-top-shadow")]',div)[0];
var buttonInnerBox = $X('.//div[contains(@class,"goog-button-base-inner-box")]',div)[0];
if(buttonBody.textContent.match(/on/igm)){
buttonClickEvent(true);
}
else{
buttonClickEvent(false);
}
function buttonClickEvent(flag){
var head = document.getElementsByTagName('head')[0];
var style = head.getElementsByTagName('style');
if(flag === true){
buttonBody.parentNode.className = 'goog-button-base-content colorful-view-content';
buttonTopShadow.className = 'goog-button-base-top-shadow colorful-view-base-top-shadow';
buttonPos.className = 'goog-button-base-pos colorful-view-base-pos';
buttonInnerBox.className = 'goog-button-base-inner-box goog-inline-block colorful-view-inner-box';
buttonBody.innerHTML = 'Colorful View Off';
GOOGLE_READER_INFO.colorfulViewFlag = flag;
GOOGLE_READER_INFO.colorfulViewButtonContentClass = 'colorful-view-content';
GOOGLE_READER_INFO.colorfulViewButtonTopShadowClass = 'colorful-view-base-top-shadow';
GOOGLE_READER_INFO.colorfulViewButtonPosClass = 'colorful-view-base-pos';
GOOGLE_READER_INFO.colorfulViewButtonInnerBoxClass = 'colorful-view-inner-box';
GOOGLE_READER_INFO.colorfulViewText = buttonBody.textContent;
setValue();
}
else{
buttonBody.parentNode.className = 'goog-button-base-content';
buttonTopShadow.className = 'goog-button-base-top-shadow';
buttonPos.className = 'goog-button-base-pos';
buttonInnerBox.className = 'goog-button-base-inner-box goog-inline-block';
buttonBody.innerHTML = 'Colorful View On';
GOOGLE_READER_INFO.colorfulViewFlag = flag;
GOOGLE_READER_INFO.colorfulViewButtonContentClass = '';
GOOGLE_READER_INFO.colorfulViewButtonTopShadowClass = '';
GOOGLE_READER_INFO.colorfulViewButtonPosClass = '';
GOOGLE_READER_INFO.colorfulViewButtonInnerBoxClass = '';
GOOGLE_READER_INFO.colorfulViewText = buttonBody.textContent;
setValue();
}
};
},false);
},
setColor: function(){
var style = '.card {background-color: transparent !important;}'
+ '.collapsed {border-color: transparent !important;}'
+ '#entries.list #current-entry .collapsed {border: 2px solid #8181DC !important;}'
+ '#entries.list #current-entry.expanded .collapsed {border-bottom-color: transparent !important;border-width: 2px 0 !important;}';
for(var i in FAVICON){
var title = i.replace(/"/g,'');
var c = 0;
var l = parseInt(title.length);
c += title.charCodeAt(0);
c = Math.floor(l*c);
c = Math.floor(c%270);
style += 'div[color="'+title+'"] .collapsed{background: hsl('+c+', '+(l+70)+'%, 70%) !important;}'
+ 'div[color="'+title+'"]:hover .collapsed {background: hsl('+c+', '+(l+80)+'%, 60%) !important;}'
+ 'div.read[color="'+title+'"] .collapsed {background: hsla('+c+', '+(l+80)+'%, 85%, 0.9) !important;}'
+ 'div.read[color="'+title+'"]:hover .collapsed {background: hsla('+c+', '+(l+70)+'%, 70%, 1.0) !important;}'
+ 'div[color="'+title+'"] .card{background: hsl('+c+', '+(l+70)+'%, 75%) !important;}'
+ 'div[color="'+title+'"]:hover .card {background: hsl('+c+', '+(l+80)+'%, 65%) !important;}'
+ 'div.read[color="'+title+'"] .card {background: hsl('+c+', '+(l+85)+'%, 88%) !important;}'
+ 'div.read[color="'+title+'"]:hover .card {background: hsl('+c+', '+(l+70)+'%, 80%) !important;}'
+ 'div.read[color="'+title+'"] .collapsed .entry-title {color: #8F8F8F !important;}'
+ 'div.read[color="'+title+'"] .collapsed .entry-source-title {color: #8F8F8F !important;}'
+ 'div.read[color="'+title+'"] .collapsed .entry-secondary {color: #8F8F8F !important;}'
+ 'div.read[color="'+title+'"]:hover .collapsed .entry-title {color: #000000 !important;}'
+ 'div.read[color="'+title+'"]:hover .collapsed .entry-source-title {color: #555555 !important;}'
+ 'div.read[color="'+title+'"]:hover .collapsed .entry-secondary {color: #777777 !important;}';
};
// set color is error
style += '#entries.list .collapsed {background: hsl(180, 70%, 70%);}'
+ '#entries.list .collapsed:hover {background: hsl(180, 80%, 60%);}'
+ '#entries.list .read .collapsed {background: hsl(180, 80%, 85%); opacity:1.0;}'
+ '#entries.list .read .collapsed:hover {background: hsl(180, 70%, 70%);}'
+ 'div .card {background: hsl(180, 70%, 70%);}'
+ 'div .card:hover {background: hsl(180, 80%, 60%);}'
+ 'div .read .card {background: hsl(180, 85%, 90%);}'
+ 'div .read .card:hover {background: hsl(180, 70%, 85%);}'
GM_addStyle(style);
}
}
};
googleReader.init();
function revertFavicon(event){
this.src = FAVICON_DEFAULT_IMG;
};
function setValue(){
GM_setValue('googleReaderInformation',uneval(GOOGLE_READER_INFO));
};
function clearCache(){
GM_setValue('googleReaderInformation','');
};
function $X(exp, ctx){
var xp = (ctx && ctx.ownerDocument || document).evaluate(exp, ctx || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null),
r = [];
for (var i = 0;i < xp.snapshotLength;++i) r.push(xp.snapshotItem(i));
return r;
};
})();
