There are 3 previous versions of this script.
// ==UserScript==
// @name Google Reader with favicon
// @description Adds favicons to feeds and entries
// @namespace Yamamaya
// @version 1.0.2
// @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
***************************************************/
(function(){
var GOOGLE_READER_INFO = eval(GM_getValue('googleReaderInformation')) || {};
var FAVICON = GOOGLE_READER_INFO.favicon || (GOOGLE_READER_INFO.favicon = {});
var FAVICON_URL = ['http://', '/favicon.ico'];
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 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(){
this.addBaseCss();
(RSS_NUMBERS === null || FOLDER_NUMBERS === null || RSS !== RSS_NUMBERS || FOLDER !== FOLDER_NUMBERS) ?
this.noCacheAddFavicon(): this.addFavicon();
GOOGLE_READER_INFO.rssNumber = RSS;
GOOGLE_READER_INFO.folderNumber = FOLDER;
setValue();
GM_registerMenuCommand('Google Reader with favicon - clear cache', clearCache);
},
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();
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');
var s = favicon.style;
favicon.width = '16';
favicon.height= '16';
if(title.parentNode.className === 'entry-source-title-parent'){
s.marginRight = '10px';
s.verticalAlign = 'middle';
}
else {
s.position = 'absolute';
s.top = '3px';
s.left = '1.6em';
}
(FAVICON.hasOwnProperty(match)) ? favicon.src = FAVICON[match] : favicon.src = FAVICON_DEFAULT_IMG;
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 title;
var favicon = document.createElement('img');
var s = favicon.style;
s.width = '16px';
s.height = '16px';
if(target.firstChild.className === 'card card-common'){
title = target.getElementsByClassName('entry-source-title')[0]; // 前文表示 .//span[@class='entry-source-title-parent']
s.marginRight = '5px';
s.verticalAlign = 'middle';
}
else{
if(target.firstChild.className === 'search-result'){ // 検索
title = target.getElementsByClassName('entry-source-title')[0];
s.verticalAlign = 'middle';
s.marginRight = '5px';
}
else
if(target.firstChild.className === 'comment-entry'){ // コメント共有
title = target.getElementsByClassName('entry-source-title')[0];
s.marginRight = '5px';
s.verticalAlign = 'middle';
s.border = 'none';
}
else{
title = target.getElementsByTagName('span')[0]; // リスト表示 .//span[contains(@class,'entry-source-title')]
s.position = 'absolute';
s.top = '3px';
s.left = '1.6em';
}
}
var match = title.textContent;
if(match.length > 24) match = match.substr(0,21) + '...';
(FAVICON.hasOwnProperty(match)) ? favicon.src = FAVICON[match] : favicon.src = FAVICON_DEFAULT_IMG;
title.parentNode.insertBefore(favicon, title);
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){
var title = e.nextSibling;
var match = title.firstChild.textContent;
if(match.length > 24) match = match.substr(0,21) + '...';
if(FAVICON.hasOwnProperty(match)){
title.style.paddingLeft = '7px';
var favicon = document.createElement('img');
e.parentNode.insertBefore(favicon,e);
e.parentNode.removeChild(e);
(FAVICON.hasOwnProperty(match)) ? favicon.src = FAVICON[match] : favicon.src = FAVICON_DEFAULT_IMG;
favicon.removeEventListener('error',revertFavicon,false);
favicon.addEventListener('error',revertFavicon,false);
}
});
},
addBaseCss: function(){
GM_addStyle(<><![CDATA[
#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;
}
#entries.list .read .collapsed {
opacity:0.6;
}
#entries.list .entry .collapsed:hover {
background:#C2CFF1;
}
#entries.list .read .collapsed:hover {
opacity: 1.0; background: #C2CFF1;
}
]]></>);
}
};
googleReader.init();
function revertFavicon(event){
this.src = FAVICON_DEFAULT_IMG;
};
function setValue(){
GM_setValue('googleReaderInformation',GOOGLE_READER_INFO.toSource());
};
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;
};
})();
