By nickman55
Has 2 other scripts.
////////////////////////////////////////////////////////
// Gmail and Google Reader Integrator v2.2
// Based on Script by Winston Teo (See infomation below)
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//Made some visual changes as well as added some features
//
//Author:
// Nick Chirchirillo
//
//Credits:
// This script is the modification to the script by Winston Teo http://www.winstonyw.com/2006/11/03/greasemonkey-script-gmail-and-reader-integrator/
// Mihai @ http://persistent.info/
// Winston Teo @ http://www.winstonyw.com/2006/11/03/greasemonkey-script-gmail-and-reader-integrator/
// Everything I used to make my changes came from the code that was already here
//
//Changelog:
// 1. 04-11-2007: Moved Collapse Gmail link to under Compose Mail
// 2. 04-11-2007: Removed unnessasary spaces
// 3. 04-11-2007: Added Google Reader favicon to Reader link
// 4. 04-11-2007: Added a Launch Reader link to open Google Reader in a new window
// 5. 04-11-2007: Added a Home link
// 6. 04-11-2007: Made Reader's labels collapsable
/////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//Replaces the dropdown with a tree menu
//
//Author:
// Pradeep Chandiramani (http://chandiramani.info)
//
//Credits:
// This script is the modification to the script by Winston Teo http://www.winstonyw.com/2006/11/03/greasemonkey-script-gmail-and-reader-integrator/
// Mihai @ http://persistent.info/
// Winston Teo @ http://www.winstonyw.com/2006/11/03/greasemonkey-script-gmail-and-reader-integrator/
//
//Changelog:
// 1. 06-02-2007: Replaced dropdown with menu
//
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// Information on Gmail and Google Reader Integrator v2.0
/////////////////////////////////////////////////////////
//Author:
// Winston Teo, inspired by Mihai@http://persistent.info/archives/2006/10/13/google-reader-redux
//Description:
// This script integrates Google Reader into Gmail, built for Greasemonkey.
//Requirements:
// Firefox Browser
// Greasmonkey Extension
//Features:
// 1. Spilt-window view of Gmail and Reader on a single page
// 2. Links to collapse|expand either Gmail or Reader
// 3. Integrated Reader uses start-page as specified in Reader's "Settings"
// 4. Labels selector
// 5. Key 'v' to open Reader links in a new Window
// 6. Automatic resize of Gmail and Reader views
//Credits:
// Mihai @ http://persistent.info/ for having such a good code basis for me to learn and start with.
// I used some of his functions as listed:
// function newNode, getNode, hasClass, addClass, removeClass, getClassMap, updateFeedsCount
//Changelog:
// 1. 06-11-2006: Removed Reader on clicking "Contacts" link
// 2. 09-11-2006: Resolved variable naming bug; from READER_SHARED_URL to READER_BROADCAST_URL
// 3. 10-11-2006: Resolved default start-page issue; able to display "Home" as default start-page
//////////////////////////////////////////////////
// ==UserScript==
// @name Gmail + Reader Integrator
// @namespace http://www.winstonyw.com
// @description Integrates Google Reader into Gmail, built for Greasemonkey.
// @include http://mail.google.com/*
// @include https://mail.google.com/*
// @include http://www.google.com/reader/*
// ==/UserScript==
//////////////////////////////////////////////////
//Setting of DEFAULTS
//////////////////////////////////////////////////
//Note: All Links have to end with ?embed
// In this way, only the Reader view embedded in Gmail would be affected by the style changes,
// and not the Reader view even at its own URL: www.google.com/reader/view
const READER_HOME_URL = 'http://www.google.com/reader/view?embed';
const READER_LIST_URL = 'http://www.google.com/reader/view/user/-/state/com.google/reading-list?embed';
const READER_STARRED_URL = 'http://www.google.com/reader/view/user/-/state/com.google/starred?embed';
const READER_BROADCAST_URL = 'http://www.google.com/reader/view/user/-/state/com.google/broadcast?embed';
const READER_LABEL_URL = 'http://www.google.com/reader/view/user/-/label/' ;
const READER_FEED_URL = 'http://www.google.com/reader/view/'
const UNREAD_COUNT_API = 'http://www.google.com/reader/api/0/unread-count?all=true&output=json&client=gm';
const PREFERENCES_API = 'http://www.google.com/reader/api/0/preference/list?output=json&client=gm';
const LABELS_LIST_API = 'http://www.google.com/reader/api/0/tag/list?output=json&client=gm';
const SUBSCRIPTION_LIST_API = 'http://www.google.com/reader/api/0/subscription/list?output=json&client=gm';
//Images for the subscription panel
const IMAGE_FOLDER_CLOSED = 'http://www.google.com/reader/ui/848719042-tree-view-folder-closed.gif';
const IMAGE_FOLDER_OPEN = 'http://www.google.com/reader/ui/1113767132-tree-view-folder-open.gif';
const IMAGE_PLUS = 'http://www.google.com/reader/ui/3962655764-tree-view-plus.gif';
const IMAGE_MINUS = 'http://www.google.com/reader/ui/2859029755-tree-view-minus.gif';
const IMAGE_FEED = 'http://www.google.com/reader/ui/338499216-feed-icon-12.png';
const IMAGE_SHARED = 'http://www.google.com/reader/ui/2797636568-icon-broadcast.png';
const IMAGE_STARRED = 'http://www.google.com/reader/ui/3499563204-star_active.png';
const IMAGE_ALL = 'http://www.google.com/reader/ui/117279103-icon-reading-list.gif';
const IMAGE_HOME = 'http://www.google.com/reader/ui/2018795750-icon-overview.gif';
const IMAGE_LAUNCH = 'http://mail.google.com/mail/images/tearoff_icon.gif';
//Local Storage for ALL Labels as retrieved from Reader
//Note: GM_setValue only allows for integers, strings and booleans
var LABELS = [];
//Local Storage for all feeds
var FEEDS = [];
//Feed object
function feed()
{
this.title="";
this.url="";
this.categories=[];
}
//Default Heights in Split-Window mode
//Change these according to your preference
const READER_EMBED_HEIGHT = 400;
const GMAIL_SPLIT_HEIGHT = 220;
//////////////////////////////////////////////////
//CSS Styles
//////////////////////////////////////////////////
//Styles for:
// Frame wrapping an iFrame (with Reader in iFrame)
// Reader Links on LHS Navigation
// Labels Selector
const READER_FRAME_STYLES =
"#readerFrame {" +
" width: 100%;" +
" border: 0px;" +
" padding: 0px;" +
"}" +
"#readerEmbed {" +
" width: 100%;" +
" height: " + READER_EMBED_HEIGHT + "px;" +
" border: 0px;" +
" padding: 0px;" +
"}" +
"#readerLabelsSelection {" +
" width: 80%;" +
" font-family: arial,sans-serif;" +
" font-size: 100%;" +
"}" +
//Selected Link appears UNSELECTED
//Usage: hideGmail
".readerEmbed table.cv * {"+
" background: #FFFFFF;" +
" font-weight: normal;" +
"}"+
".readerFeedsList {" +
" margin: 0;"+
" padding: 0 0 0 15px;" +
" list-style-type:none;" +
"}" +
".readerCatList {" +
" margin: 0;"+
" width: 98%;"+
" padding: 0;" +
" list-style-type:none;" +
" overflow:hidden;"+
"}" +
".readerFeedLabel {" +
" list-style-type:none;" +
"}" +
"#FeedsDiv {" +
" background: #C3D9FF;" +
" padding: 0;" +
" width: 95%;"+
" display:none;" +
"}" +
"#LabelsDiv {" +
" background: #C3D9FF;" +
" padding: 0;" +
" width: 95%;"+
" display:none;" +
" overflow:hidden;" +
"}" +
"#BottomDiv {" +
" display:none;" +
"}" +
"b.rtop, b.rbottom{display:block;background: #FFF}"+
"b.rtop b, b.rbottom b{display:block;height: 1px;overflow: hidden; background: #C3D9FF}"+
"b.r1{margin: 0 5px}"+
"b.r2{margin: 0 3px}"+
"b.r3{margin: 0 2px}"+
"b.rtop b.r4, b.rbottom b.r4{margin: 0 1px;height: 2px}";
//Styles for Website (www.google.com/reader...?embed) contained in iFrame
//Removes Logo, Navigation, Menu + Displays Main Window
const FORMAT_READER_STYLES =
"body {" +
" background: #FFFFFF;" +
"}" +
"#nav," +
"#logo-container," +
"#global-info," +
"#viewer-header," +
"#home-header," +
".home-header-box," +
"#recent-activity," +
"#footer {" +
" display: none !important;" +
"}" +
"#main {" +
" margin-top: 0;" +
"}" +
"#chrome {" +
" margin-left: 0;" +
"}";
////////////////////////////////////////////////////////////////////////////////////////////////////
//Start Execution of Script
////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////
//Detects Google Reader (in iFrame) and updates CSS in Google Reader to hide specific elements
//////////////////////////////////////////////////
//Note: Header MUST contain: @include http://www.google.com/reader/*
// Then, http://www.google.com/reader/* will include a copy of JS, and only execute this conditional clause.
//Note: document.location.search returns ONLY QUERY STRING.. ?embed
if (document.location.hostname == 'www.google.com' && document.location.search.indexOf('embed') != -1) {
GM_addStyle(FORMAT_READER_STYLES);
addKeypressEvents();
}
//Method Name: addKeypressEvents()
//Description: Adds keypress events to current window.
// Currently events include:
// 1. Key 'v' opens Reader links in new Window/Tab
function addKeypressEvents() {
document.addEventListener('keypress', openInNewWindow, false);
}
//Method Name: openInNewWindow()
//Description: Key 'v' opens Reader links in new Window/Tab
function openInNewWindow (event) {
var code = event.keyCode ? event.keyCode : event.which;
var char = String.fromCharCode(code);
if (char == 'v') {
var currEntry = getNode('current-entry');
if (!currEntry) return;
currEntryHREF = document.evaluate(
"//div[@id='current-entry']//a[@href]",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
window.open (currEntryHREF.snapshotItem(0).href, 'target=newWin');
}
}
//////////////////////////////////////////////////
//Detects Gmail + Displays Google Reader
//////////////////////////////////////////////////
if (document.location.hostname == 'mail.google.com') {
GM_addStyle(READER_FRAME_STYLES);
addReader();
}
//Method Name: addReader()
//Description: Adds Reader in iFrame below Inbox
// Displays Reader Links (and Feed Counts) in #nav, with Links to specific Labels
// Stores Global Variables: Gmail Frame Height + Default Reader start-page in Reader's settings
function addReader() {
//Only Display in Messages view (Inbox, Starred, Sent etc);
//No Display in misc iFrames, or "Compose Mail" view, or "Contacts" view
if (!getNode('co') || getNode('msgs') || getNode('cm_compose') || getNode('ctm') || getNode('cnt')) return;
//Stores Global Variable
setHeight();
setReaderSourceURL();
//Create Links, Feed Counts
setNavLink(); updateFeedsCount();
//Create Label Selector
setReaderLabelsSelection();
//Create iFrame
setReaderFrame();
window.setInterval (updateFeedsCount, 30 * 1000);
}
//Method Name: setNavLink()
//Description: Displays Reader Links (and Feed Counts), and Show|Hide Gmail Link in #nav.
function setNavLink() {
//Reader Link in #nav
var navReaderLink = newNode('div');
navReaderLink.className = 'nl';
navReaderLink.innerHTML = '<span id="navReaderLink" class="lk">Reader <span id="unreadCount"></span> <img src="http://google.com/reader/ui/favicon.ico"></span>';
//Insert AFTER Trash Link
var custNode = getNode('nds');
custNode.parentNode.insertBefore(navReaderLink, custNode.nextSibling);
//Event to Show|Hide Reader
navReaderLink.addEventListener('click', setReaderVisibility, false);
//Gmail Show|Hide Link
var GmailToggle = newNode ('div');
GmailToggle.className = 'nl';
GmailToggle.innerHTML = '<span id="GmailToggle" class="lk">Collapse Gmail</span>';
//Insert AFTER Compose Link
var navNode = getNode('comp');
navNode.parentNode.insertBefore(GmailToggle, navNode.nextSibling);
//Event to Show|Hide Gmail
GmailToggle.addEventListener('click', setGmailVisibility, false);
//Event to Show Gmail on clicking any link in #nds
getNode('nds').addEventListener('click', showGmail, false);
}
//Method Name: setReaderFrame()
//Description: Creates a Frame that contains an iFrame (embedded with Reader) and appends below #co (Inbox, Starred etc)
function setReaderFrame() {
var readerFrame = newNode('div');
readerFrame.id = 'readerFrame';
readerFrame.className = 'thc';
var readerFrameTop = newNode('div');
readerFrameTop.className = 'tbc';
var readerFrameLinks = newNode('div');
readerFrameLinks.id = 'readerFrameLinks';
readerFrameLinks.className = 'tbcs';
var readerLink = newNode ('div');
readerLink.id = 'readerLink';
readerLink.className = 'l';
readerLink.innerHTML = '<img id="readerLinkImg" src="images/triangle.gif"></img> Google Reader';
readerLink.addEventListener ('click', setReaderVisibility, false);
readerFrame.appendChild (readerFrameTop);
readerFrameTop.appendChild (readerFrameLinks);
readerFrameLinks.appendChild(readerLink);
var mailFrame = getNode('co');
var separator = newNode('div');
separator.innerHTML = '<br>';
mailFrame.appendChild(separator);
mailFrame.appendChild(readerFrame);
}
//Method Name: setReaderSourceURL()
//Description: Retrieves Reader's settings page through API @ PREFERENCES_API,
// and uses value for start-page, as set by User in Google Reader, as start-page for viewReader() method call
function setReaderSourceURL() {
GM_xmlhttpRequest({
method: 'GET',
url: PREFERENCES_API,
onload: function(responseDetails) {
var data = eval ("(" + responseDetails.responseText + ")");
for (var i = 0 ; i<data.prefs.length ; i++) {
var prefsPair = data.prefs[i]
if (prefsPair.id.indexOf("start-page") != -1){
//alert(array[i]);
if (prefsPair.value.indexOf('home') != -1) {
GM_setValue('READER_SOURCE_URL', READER_HOME_URL);
} else
if (prefsPair.value.indexOf('reading-list') != -1) {
GM_setValue('READER_SOURCE_URL', READER_LIST_URL);
} else
if (prefsPair.value.indexOf('starred') != -1) {
GM_setValue('READER_SOURCE_URL', READER_STARRED_URL);
} else
if (prefsPair.value.indexOf('broadcast') != -1) {
GM_setValue('READER_SOURCE_URL', READER_BROADCAST_URL);
} else
if (prefsPair.value.indexOf('label') != -1) {
var LABEL = prefsPair.value.substring(prefsPair.value.lastIndexOf('/')+1, prefsPair.value.length);
//alert (LABEL);
GM_setValue('READER_SOURCE_URL', READER_LABEL_URL + LABEL + '?embed');
GM_setValue('LABEL', LABEL);
}
}
}
}
});
}
/***********************************
//Obsolete: This method reads the HTML of Reader setting's and is easily breakable.
//Refer instead to the same method name which uses API and JSON.
function setReaderSourceURL() {
GM_xmlhttpRequest({
method: 'GET',
url: 'http://www.google.com/reader/settings?nochrome',
onload: function(responseDetails) {
var data = responseDetails.responseText;
var array = data.split('\n');
for (var i=0; i<array.length; i++) {
if (array[i].indexOf('selected="selected"') != -1 ) {
//alert(array[i]);
if (array[i].indexOf('reading-list') != -1 || array[i].indexOf('home') != -1) {
GM_setValue('READER_SOURCE_URL', READER_LIST_URL);
} else
if (array[i].indexOf('starred') != -1) {
GM_setValue('READER_SOURCE_URL', READER_STARRED_URL);
} else
if (array[i].indexOf('broadcast') != -1) {
GM_setValue('READER_SOURCE_URL', READER_BROADCAST_URL);
} else
if (array[i].indexOf('label') != -1) {
var LABEL = array[i].substring(array[i].lastIndexOf('/')+1, array[i].lastIndexOf('\"'));
//alert (LABEL);
GM_setValue('READER_SOURCE_URL', READER_LABEL_URL + LABEL + '?embed');
GM_setValue('LABEL', LABEL);
}
}
}
}
});
}
***********************************/
//////////////////////////////////////////////////
//Reader Labels Selector
//////////////////////////////////////////////////
//Method Name: setReaderLabelsSelection()
//Description: Creates Reader Labels Selection from Global Variable LABELS[] in LHS Navigation when Reader is visible
function setReaderLabelsSelection() {
//Initializes Global Variable, and appends to Selection Node
setReaderLabels();
}
//Method Name: setReaderLabels()
//Description: Retrieves Labels from JSON API and stores as Global Variables
function setReaderLabels() {
GM_xmlhttpRequest({
method: "GET",
url: LABELS_LIST_API,
onload: function(responseDetails) {
var data = eval("(" + responseDetails.responseText + ")");
for (var i = 0 ; i<data.tags.length ; i++) {
var tagsPair = data.tags[i]
if (tagsPair.id.indexOf("label") != -1){
var LABEL = tagsPair.id.substring(tagsPair.id.lastIndexOf('/')+1, tagsPair.id.length);
LABELS.push(LABEL);
}
}
LABELS.push('uc76528q');
setSubscriptions();
}
});
}
//Method Name: setSubscriptions()
//Description: Retrieves Subscriptions from JSON API and stores as Global Variables
function setSubscriptions() {
GM_xmlhttpRequest({
method: "GET",
url: SUBSCRIPTION_LIST_API,
onload: function(responseDetails) {
var data = eval("(" + responseDetails.responseText + ")");
for (var i = 0 ; i<data.subscriptions.length ; i++) {
var subscription= new feed();
subscription.title=data.subscriptions[i].title;
subscription.url=data.subscriptions[i].id;
for (var j = 0 ; j<data.subscriptions[i].categories.length ; j++) {
subscription.categories.push(data.subscriptions[i].categories[j].label);
}
if(0==data.subscriptions[i].categories.length){
subscription.categories.push("uc76528q")
}
FEEDS.push(subscription);
}
setFeedList();
}
});
}
function setFeedList(){
var head=unsafeWindow.document.getElementsByTagName("head");
var collapseScript= newNode('script');
collapseScript.innerHTML = 'function toggleList(label){'+'\n'+
' var IMAGE_MINUS ="'+IMAGE_MINUS+'";'+'\n'+
' var IMAGE_PLUS = "'+IMAGE_PLUS+'";'+'\n'+
' var listElementStyle=document.getElementById(label+"FeedsList").style;'+'\n'+
' if (listElementStyle.display=="none"){'+'\n'+
' listElementStyle.display="block";'+'\n'+
' document.getElementById(label+"Image").src=IMAGE_MINUS;'+'\n'+
' document.getElementById(label+"Image").alt="Close feeds";'+'\n'+
' }else{'+'\n'+
' listElementStyle.display="none";'+'\n'+
' document.getElementById(label+"Image").src=IMAGE_PLUS;'+'\n'+
' document.getElementById(label+"Image").alt="Open feeds";'+'\n'+
' }'+'\n'+
' }';
head[0].appendChild(collapseScript);
var selectionNode = newNode('div');
selectionNode.className = 'nl';
selectionNode.id ='FeedsDiv';
var catList = newNode('ul');
catList.className = 'readerCatList';
catList.id = 'readerCatList';
var currLabel;
currLabel='Launch Reader';
var liLaunch = newNode('li');
liLaunch.className = 'readerLabel';
liLaunch.id = 'readerLabel';
liLaunch.innerHTML = '<img src="'+IMAGE_LAUNCH+'" alt="Launch Reader" style="margin-right:5px;">';
liLaunch.innerHTML +='<a href="http://google.com/reader" target="_blank">'+currLabel+'</a>';
catList.appendChild(liLaunch);
currLabel='Home';
var liHome = newNode('li');
liHome.className = 'readerFeedLabel';
liHome.id = 'readerFeedLabel';
liHome.innerHTML = '<img src="'+IMAGE_HOME+'" alt="All feeds" style="margin-right:5px;">';
liHome.innerHTML +='<a href="javascript:void(0)">'+currLabel+'</a>';
liHome.URL = READER_HOME_URL;
liHome.addEventListener('click', switchView, false);
catList.appendChild(liHome);
currLabel='All';
var liList = newNode('li');
liList.className = 'readerFeedLabel';
liList.id = 'readerFeedLabel';
liList.innerHTML = '<img src="'+IMAGE_ALL+'" alt="All feeds" style="margin-right:5px;">';
liList.innerHTML +='<a href="javascript:void(0)">'+currLabel+'</a>';
liList.URL = READER_LIST_URL;
liList.addEventListener('click', switchView, false);
catList.appendChild(liList);
currLabel='Starred';
var liStarred = newNode('li');
liStarred.className = 'readerFeedLabel';
liStarred.id = 'readerFeedLabel';
liStarred.innerHTML = '<img src="'+IMAGE_STARRED+'" alt="Starred" style="margin-right:5px;">';
liStarred.innerHTML +='<a href="javascript:void(0)">'+currLabel+'</a>';
liStarred.URL = READER_STARRED_URL;
liStarred.addEventListener('click', switchView, false);
catList.appendChild(liStarred);
currLabel='Shared';
var liBroadcast = newNode('li');
liBroadcast.className = 'readerFeedLabel';
liBroadcast.id = 'readerFeedLabel';
liBroadcast.innerHTML = '<img src="'+IMAGE_SHARED+'" alt="Starred" style="margin-right:5px;">';
liBroadcast.innerHTML +='<a href="javascript:void(0)">'+currLabel+'</a>';
liBroadcast.URL = READER_BROADCAST_URL;
liBroadcast.addEventListener('click', switchView, false);
catList.appendChild(liBroadcast);
currLabel='Reader Labels';
var liLabel = newNode('li');
liLabel.className = 'readerLabel';
liLabel.id = 'readerLabel';
liLabel.innerHTML = '<img id="labelImg" src="images/opentriangle.gif"> <a href="javascript:void(0)">'+currLabel+'</a>';
liLabel.addEventListener ('click', setLabelVisibility, false);
catList.appendChild(liLabel);
LABELS.sort();
var selectionNode2 = newNode('div');
selectionNode2.className = 'nl';
selectionNode2.id ='LabelsDiv';
var labelList = newNode('div');
labelList.className = 'readerLabelList';
labelList.id = 'readerLabelList';
for (var i = 0 ; i<LABELS.length ; i++) {
var catListLabel = newNode('li');
if('uc76528q' != LABELS[i])
currLabel = LABELS[i];
else currLabel = "Uncategorized";
catListLabel.className = 'readerFeedLabel';
catListLabel.id = 'readerFeedLabel';
catListLabel.innerHTML = '<img id="'+currLabel+'Image" src="'+IMAGE_PLUS+'" alt="Open feeds" onClick="toggleList(\''+currLabel+'\');" style="padding: 0px 10px 0px 10px;">';
var catListLabelLink= newNode('a');
catListLabelLink.href = 'javascript:void(0)';
catListLabelLink.innerHTML = currLabel;
if('uc76528q' != LABELS[i]){
catListLabelLink.URL = READER_LABEL_URL + currLabel + '?embed';
catListLabelLink.addEventListener('click', switchView, false);
}
catListLabelLink.id='rfl'+ currLabel;
catListLabel.appendChild(catListLabelLink);
var feedsList = newNode('li');
feedsList.className = 'readerFeedsList';
feedsList.id = currLabel+'FeedsList';
feedsList.style.display = 'none';
for (var j = 0 ; j<FEEDS.length ; j++) {
if(FEEDS[j].categories.indexOf(LABELS[i])!=-1){
var feedItem = newNode('li');
feedItem.className = 'readerFeedItem';
feedItem.id = 'readerFeedItem';
feedItem.innerHTML = '<img src="'+IMAGE_FEED+'" alt="Feed" style="margin-right:5px;">';
feedItem.innerHTML +='<a href="javascript:void(0)" id="'+FEEDS[j].url+'">'+FEEDS[j].title+'</a>';
feedItem.URL = READER_FEED_URL+FEEDS[j].url+ '?embed';
feedItem.addEventListener('click', switchView, false);
feedsList.appendChild(feedItem);
}
}
labelList.appendChild(catListLabel);
labelList.appendChild(feedsList);
}
var rtop = newNode('b');
rtop.className='rtop';
rtop.innerHTML = '<b class="r1"></b><b class="r2"></b><b class="r3"></b><b class="r4"></b>';
rbottom = newNode('b');
rbottom.className='rbottom';
rbottom.id = 'BottomDiv';
rbottom.innerHTML = '<b class="r4"></b><b class="r3"></b><b class="r2"></b><b class="r1"></b>';
rbottom.style.width = '95%';
selectionNode.appendChild(rtop );
selectionNode.appendChild(catList);
selectionNode2.appendChild(labelList);
var navReaderLink = getNode('navReaderLink');
navReaderLink.parentNode.parentNode.insertBefore(selectionNode, navReaderLink.parentNode.nextSibling);
selectionNode.parentNode.insertBefore(selectionNode2, selectionNode.nextSibling);
selectionNode2.parentNode.insertBefore(rbottom, selectionNode2.nextSibling);
rbottom = null;
updateFeedsCount();
}
//Method Name: switchView(event)
//Description: Switches Reader view in iFrame according to selection in Reader Labels Selection
function switchView(event) {
GM_setValue('READER_SOURCE_URL', this.URL);
hideReader();
viewReader();
resizeReaderFrame();
return 0;
}
//////////////////////////////////////////////////
//Gmail Visibility
//////////////////////////////////////////////////
//Method Name: setGmailVisibility (event)
//Description: Toggles Gmail Frame visibility by calling showGmail() or hideGmail()
function setGmailVisibility (event) {
var GmailToggle = getNode('GmailToggle');
if (GmailToggle.innerHTML.indexOf('Collapse') != -1) {
hideGmail();
} else {
showGmail();
}
resizeMailFrame();
resizeReaderFrame();
event.stopPropagation();
}
//Method Name: showGmail (event)
//Description: Shows Gmail Frame
function showGmail() {
var GmailToggle = getNode('GmailToggle');
//Shows Gmail
var mailFrame = getNode('co');
for (var i = mailFrame.firstChild; i.id != 'readerFrame'; i = i.nextSibling) {
i.style.display='';
}
//Adds "highlight" to Link in #nav
removeClass(document.body, 'readerEmbed');
//Change Link in #nav, from "Show" to "Hide"
GmailToggle.innerHTML = 'Collapse Gmail';
}
//Method Name: hideGmail (event)
//Description: Hides Gmail Frame
function hideGmail() {
var GmailToggle = getNode('GmailToggle');
//Hides Gmail
var mailFrame = getNode('co');
for (var i = mailFrame.firstChild; i.id != 'readerFrame'; i = i.nextSibling) {
i.style.display='none';
}
//Removes "highlight" from Link in #nav
addClass(document.body, 'readerEmbed');
//Change Link in #nav, from "Hide" to "Show"
GmailToggle.innerHTML = 'Expand Gmail';
}
//////////////////////////////////////////////////
//Reader Visibility
//////////////////////////////////////////////////
//Method Name: setReaderVisibility(event)
//Description: Toggles Reader Frame visibility by calling viewReader() or hideReader()
// In addition, visibility of Label links at #nav is dependent on viewReader() or hideReader() method call
// Event can be activated by 2 Links, Navigation Link and Reader Frame Link
function setReaderVisibility(event) {
var readerEmbed = getNode('readerEmbed');
if (readerEmbed == null || (readerEmbed != null && readerEmbed.style.display == 'none')) {
swapImg('show' , 'readerLinkImg');
viewReaderLabelsSelection();
viewReader();
} else {
swapImg('hide', 'readerLinkImg');
hideReaderLabelsSelection();
hideReader();
}
resizeMailFrame();
resizeReaderFrame();
event.stopPropagation();
}
//Method Name: viewReader()
//Description: Displays Reader Frame, and embeds READER_SOURCE_URL into iFrame
function viewReader() {
var readerEmbed = getNode('readerEmbed');
if (readerEmbed == null) {
readerEmbed = newNode('iframe');
readerEmbed.id = 'readerEmbed';
readerEmbed.name = 'readerEmbed';
readerEmbed.src = GM_getValue('READER_SOURCE_URL');
getNode('readerFrame').appendChild(readerEmbed);
}
//Not Applicable - Reader is ALWAYS REMOVED in hideReader(), and not hidden through style properties
//Reason: Saves on resources + Updated Reader iFrame on every viewReader() method call
else {
readerEmbed.style.display = '';
}
}
//Method Name: hideReader()
//Description: Hides (Removes) Reader Frame
function hideReader() {
var readerEmbed = getNode('readerEmbed');
getNode('readerFrame').removeChild(readerEmbed);
readerEmbed = null;
//Problem with Memory Management?
//readerEmbed.style.display="none";
}
//////////////////////////////////////////////////
//Label Visibility
//////////////////////////////////////////////////
//Method Name: setLabelVisibility(event)
//Description: Toggles Label visibility by calling viewLabels() or hideLabels()
function setLabelVisibility() {
var labels = getNode('LabelsDiv');
if (labels.style.display == 'none') {
swapImg('show' , 'labelImg');
viewLabels();
} else {
swapImg('hide', 'labelImg');
hideLabels();
}
}
//Method Name: hideLabels()
//Description: Hides labels and creates a new bottom for the box
function hideLabels() {
var labelNode = getNode('LabelsDiv')
//Hides the labels
labelNode.style.display = "none";
}
//Method Name: viewLabels()
//Description: Shows Labels and removes the bottom of the box created by hideLabels()
function viewLabels() {
var labelNode = getNode('LabelsDiv');
//Shows the labels
labelNode.style.display = "block";
}
//Method Name: viewReaderLabelsSelection()
//Description: Displays Reader Labels Selection in LHS Navigation when Reader is visible
function viewReaderLabelsSelection() {
getNode('FeedsDiv').style.display = 'block';
getNode('LabelsDiv').style.display = 'block';
getNode('BottomDiv').style.display = 'block';
}
//Method Name: hideReaderLabelsSelection()
//Description: Hidess Reader Labels Selection in LHS Navigation when Reader is invisible (removed)
function hideReaderLabelsSelection() {
getNode('FeedsDiv').style.display = 'none';
getNode('LabelsDiv').style.display = 'none';
getNode('BottomDiv').style.display = 'none';
}
//////////////////////////////////////////////////
//Aesthetic Functions
//////////////////////////////////////////////////
//Method Name: minHeight()
//Description: Determines Height for Gmail Frame
function setHeight() {
//Original
GM_setValue('mailHeightOriginal', getNode('co').childNodes[1].clientHeight);
//Split
if (GM_getValue('mailHeightOriginal') < GMAIL_SPLIT_HEIGHT) {
GM_setValue('mailHeightSplit', getNode('co').childNodes[1].clientHeight);
}
else {
GM_setValue('mailHeightSplit', GMAIL_SPLIT_HEIGHT);
}
}
//Method Name: swapImg(key, id)
//Description: Imitates Contacts, Labels Box with Triangle GIF
function swapImg(key, id) {
var elem = getNode(id);
if (key == 'show')
elem.src = 'images/opentriangle.gif';
else
elem.src = 'images/triangle.gif';
}
//Method Name: resizeMailFrame()
//Description: Resizes Gmail Frame based on presence of Reader Frame, or based on Click Events
function resizeMailFrame() {
//Shrinks Gmail Frame in Split-Window mode
var GMAIL_FRAME_SMALL =
".fs {" +
" height: " + GM_getValue('mailHeightSplit') + "px !important;" +
" overflow: auto;" +
"}";
//Expands Gmail Frame in Single-Window mode
var GMAIL_FRAME_LARGE =
".fs {" +
" height: " + GM_getValue('mailHeightOriginal') + "px !important;" +
" overflow: auto;" +
"}";
if (!getNode('readerEmbed')) {
GM_addStyle (GMAIL_FRAME_LARGE);
}
else {
GM_addStyle (GMAIL_FRAME_SMALL);
}
}
//Method Name: resizeReaderFrame()
//Description: Resizes Reader Frame based on Click Events
function resizeReaderFrame() {
var readerEmbed = getNode('readerEmbed');
if (!readerEmbed) return;
if (getNode('co').firstChild.style.display == 'none') {
readerEmbed.style.height = (window.innerHeight - readerEmbed.offsetTop) + "px";
} else {
readerEmbed.style.height = READER_EMBED_HEIGHT + "px";
}
}
//////////////////////////////////////////////////
//Functions credited to Mihai @ http://persistent.info/
//////////////////////////////////////////////////
function updateFeedsCount() {
var unreadCountNode = getNode("unreadCount");
if (!unreadCountNode) return;
GM_xmlhttpRequest({
method: "GET",
url: UNREAD_COUNT_API,
onload: function(responseDetails) {
var data = eval("(" + responseDetails.responseText + ")");
for (var i = 0, unreadCountPair ; unreadCountPair = data.unreadcounts[i] ; i++) {
var count = unreadCountPair.count;
if (unreadCountPair.id.indexOf("reading-list") != -1) {
unreadCountNode.innerHTML = count == 0 ? '' : ' (' + count + (count == data.max ? '+' : '') + ') ';
if(-1!=top.document.title.indexOf(' Reader'))
top.document.title=top.document.title.substring(0,top.document.title.indexOf(' Reader'))
top.document.title+=' Reader' + ' (' + count + (count == data.max ? '+' : '') + ') ';
}
if (unreadCountPair.id.indexOf("label") != -1){
var LABEL = unreadCountPair.id.substring(unreadCountPair.id.lastIndexOf('/')+1, unreadCountPair.id.length);
var rflLabel = getNode("rfl"+LABEL);
if(!rflLabel) continue;
if (count > 0)
{
if (!rflLabel) continue;
rflLabel.style.fontWeight = 'bold';
}
else{
rflLabel.style.fontWeight = 'normal';
}
}
else{
var rflFeed = getNode(unreadCountPair.id);
if (!rflFeed) continue;
if(count>0)
rflFeed.style.fontWeight = 'bold';
else
rflFeed.style.fontWeight = 'normal';
}
}
}
});
}
function newNode(type) {
return unsafeWindow.document.createElement(type);
}
function getNode(id) {
return unsafeWindow.document.getElementById(id);
}
function hasClass(node, className) {
return className in getClassMap(node);
}
function addClass(node, className) {
if (hasClass(node, className)) return;
node.className += " " + className;
}
function removeClass(node, className) {
var classMap = getClassMap(node);
if (!(className in classMap)) return;
delete classMap[className];
var newClassList = [];
for (var className in classMap) {
newClassList.push(className);
}
node.className = newClassList.join(" ");
}
function getClassMap(node) {
var classMap = {};
var classNames = node.className.split(/\s+/);
for (var i = 0; i < classNames.length; i++) {
classMap[classNames[i]] = true;
}
return classMap;
}