All pastes #226632 Raw Edit

5M

public javascript v1 · immutable
#226632 ·published 2006-10-28 18:10 UTC
rendered paste body
// ==UserScript==// @name           Gmail + Google Reader// @namespace      http://persistent.info/// @description    Embeds Google Reader into Gmail by adding a "Feeds" link// @include        http://mail.google.com/*// @include        https://mail.google.com/*// @include        http://www.google.com/reader/*// ==/UserScript==var readerFrameNode = null;var feedsContainerNode = null;var hiddenNodes = [];const GMAIL_STYLES = [  "#reader-frame {",  "  width: 100%;",  "  border: 0;",  "}",    ".reader-embedded #ft {",    "display: none",  "}",    // Make currently selected item appear normal  ".reader-embedded table.cv * {",  "  background: #fff;",  "  font-weight: normal",  "}",    // Make the feeds link appear selected  ".reader-embedded #feeds-container {",  "  background: #c3d9ff;",  "  -moz-border-radius: 5px 0 0 5px;",  "  font-weight: bold;",  "  color: #00c;",  "}",].join("\n");const READER_STYLES = [  "body {",  "  background: #fff",    "}",    "#nav,",  "#logo-container,",  "#global-info,",  "#viewer-header {",  "  display: none !important;",  "}",  "",  "#main {",  "  margin-top: 0;",  "}",  "",  "#chrome {",  "  margin-left: 0;",  "}"].join("\n");const READER_UNREAD_COUNT_URL =   "http://www.google.com/reader/api/0/unread-count?" +  "all=true&output=json&client=gm";const READER_LIST_VIEW_URL =  "http://www.google.com/reader/view/user/-/state/com.google/reading-list?" +  "gmail-embed=true&view=list";if (document.location.hostname == "mail.google.com") {  injectGmail();} else if (document.location.hostname == "www.google.com" &&           document.location.search.indexOf("gmail-embed") != -1) {  injectReader();}           function injectGmail() {  if (!getNode("nds") || !getNode("ds_inbox")) return;    GM_addStyle(GMAIL_STYLES);    var feedsNode = newNode("span");  feedsNode.className = "lk";  feedsNode.innerHTML =       'Feeds ' +      '<span id="reader-unread-count"></span>';  feedsNode.onclick = showReaderFrame;    feedsContainerNode = newNode("div");  feedsContainerNode.className = "nl";  feedsContainerNode.id = "feeds-container";  feedsContainerNode.appendChild(feedsNode);    var navNode = getNode("nds");    navNode.insertBefore(feedsContainerNode, navNode.childNodes[2]);    window.addEventListener("resize", resizeReaderFrame, false);    updateUnreadCount();    window.setInterval(updateUnreadCount, 5 * 60 * 1000);     window.setInterval(checkFeedsParent, 1000);}function checkFeedsParent() {  var navNode = getNode("nds");    if (feedsContainerNode.parentNode != navNode) {    navNode.insertBefore(feedsContainerNode, navNode.childNodes[2]);  }  }function updateUnreadCount() {  var unreadCountNode = getNode("reader-unread-count");    if (!unreadCountNode) return;    GM_xmlhttpRequest({    method: "GET",    url: READER_UNREAD_COUNT_URL,    onload: function(details) {      var data = eval("(" + details.responseText + ")");      var isUnread = false;            for (var i = 0, unreadCountPair;            unreadCountPair = data.unreadcounts[i];            i++) {        if (unreadCountPair.id.indexOf("reading-list") != -1) {          var count = unreadCountPair.count;          if (count == 0) break;                    unreadCountNode.innerHTML =               " (" + count + (count == data.max ? "+" : "") + ") ";          isUnread = true;          break;        }      }            if (!isUnread) {        unreadCountNode.innerHTML = "";      }    }  });}function resizeReaderFrame() {  if (!readerFrameNode) return;    readerFrameNode.style.height =       (window.innerHeight - readerFrameNode.offsetTop) + "px";  }function showReaderFrame(event) {  var container = getNode("co");    addClass(document.body, "reader-embedded");    hiddenNodes = [];    for (var i = container.firstChild; i; i = i.nextSibling) {    hiddenNodes.push(i);    i.style.display = "none";  }    readerFrameNode = newNode("iframe");  readerFrameNode.src = READER_LIST_VIEW_URL;  readerFrameNode.id = "reader-frame";    container.appendChild(readerFrameNode);    container.parentNode.style.paddingRight = "0";  container.parentNode.style.paddingBottom = "0";    resizeReaderFrame();    // Make clicks outside the content area hide it    getNode("nav").addEventListener("click", hideReaderFrame, false);    // Since we're in a child of the "nav" element, the above handler will get  // triggered immediately unless we stop this event from propagating  event.stopPropagation();      return false;}function hideReaderFrame() {  var container = getNode("co");  container.removeChild(readerFrameNode);      readerFrameNode = null;    for (var i=0; i < hiddenNodes.length; i++) {    hiddenNodes[i].style.display = "";  }  getNode("nav").removeEventListener("click", hideReaderFrame, false);                                         removeClass(document.body, "reader-embedded");          container.parentNode.style.paddingRight = "1ex";  container.parentNode.style.paddingBottom = "1ex";    return true;}function injectReader() {  GM_addStyle(READER_STYLES);  }// Shorthandfunction newNode(type) {return unsafeWindow.document.createElement(type);}function newText(text) {return unsafeWindow.document.createTextNode(text);}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;}