function GFdynamicFeedControl(feedUrls, container, options) { this.nodes = {}; this.collapseElements = []; this.feeds = []; this.results = []; if (typeof feedUrls == 'string') { this.feeds.push({url:feedUrls});} else if (typeof feedUrls == 'object') { for (var i=0; i<feedUrls.length; i++) { var entry = feedUrls[i]; var o = {}; var feedUrl; if (typeof entry == 'string') { o.url = feedUrls[i];} else if (typeof entry == 'object') { o = feedUrls[i]; if (o && o.title) { var s = o.title; o.title = s.replace(/</g,'&lt;').replace(/>/g, '&gt;');}
}
this.feeds.push(o);}
}
if (typeof container == "string") { container = document.getElementById(container);}
this.parseOptions_(options); this.setup_(container);}
GFdynamicFeedControl.DEFAULT_NUM_RESULTS = 4; GFdynamicFeedControl.DEFAULT_FEED_CYCLE_TIME = 1800000; GFdynamicFeedControl.DEFAULT_DISPLAY_TIME = 5000; GFdynamicFeedControl.DEFAULT_FADEOUT_TIME = 1000; GFdynamicFeedControl.DEFAULT_TRANSISTION_STEP = 40; GFdynamicFeedControl.DEFAULT_HOVER_TIME = 100; GFdynamicFeedControl.prototype.parseOptions_ = function(options) { this.options = { numResults : GFdynamicFeedControl.DEFAULT_NUM_RESULTS, feedCycleTime : GFdynamicFeedControl.DEFAULT_FEED_CYCLE_TIME, linkTarget : google.feeds.LINK_TARGET_BLANK, displayTime : GFdynamicFeedControl.DEFAULT_DISPLAY_TIME, transitionTime : GFdynamicFeedControl.DEFAULT_TRANSISTION_TIME, transitionStep : GFdynamicFeedControl.DEFAULT_TRANSISTION_STEP, fadeOutTime: GFdynamicFeedControl.DEFAULT_FADEOUT_TIME, scrollOnFadeOut : true, pauseOnHover : true, hoverTime : GFdynamicFeedControl.DEFAULT_HOVER_TIME, autoCleanup : true, transitionCallback : null, feedTransitionCallback : null, feedLoadCallback : null, collapseable : false, sortByDate : false, horizontal : false, stacked : false, title : null
}; if (options) { for (var o in this.options) { if (typeof options[o] != 'undefined') { this.options[o] = options[o];}
}
}
if(!this.options.stacked) { this.options.collapseable = false;}
this.options.displayTime = Math.max(200, this.options.displayTime); this.options.fadeOutTime = Math.max(0, this.options.fadeOutTime); var ts = this.options.fadeOutTime / this.options.transitionStep; this.fadeOutDelta = Math.min(1, (1.0/ts)); this.started = false;}; GFdynamicFeedControl.prototype.setup_ = function(container) { if (container == null) return; this.nodes.container = container; if (window.ActiveXObject) { this.ie = this[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;} else if (document.childNodes && !document.all && !navigator.taintEnabled) { this.safari = true;} else if (document.getBoxObjectFor != null) { this.gecko = true;}
this.feedControl = new google.feeds.FeedControl(); this.feedControl.setLinkTarget(this.options.linkTarget); this.expected = this.feeds.length; this.errors = 0; for (var i = 0; i < this.feeds.length; i++) { var feed = new google.feeds.Feed(this.feeds[i].url); feed.setResultFormat(google.feeds.Feed.JSON_FORMAT); feed.setNumEntries(this.options.numResults); feed.load(this.bind_(this.feedLoaded_, i));}
}; GFdynamicFeedControl.prototype.bind_ = function(method) { var self = this; var opt_args = [].slice.call(arguments, 1); return function() { var args = opt_args.concat([].slice.call(arguments)); return method.apply(self, args);}
}; GFdynamicFeedControl.prototype.feedLoaded_ = function(index, result) { if (this.options.feedLoadCallback) { this.options.feedLoadCallback(result);}
if (result.error) { if (++this.errors >= this.expected) { this.nodes.container.innerHTML = 'Feed' + ((this.expected > 1)?'s ':' ') + 'could not be loaded.';}
return;}
if (this.feeds[index].title) { result.feed.title = this.feeds[index].title;}
this.results.push(result); if (!this.started) { this.createSubContainers_(); this.displayResult_(0);} else if (!this.options.horizontal && this.options.stacked) { this.addResult_(this.results.length-1);}
}; GFdynamicFeedControl.prototype.sortByDate_ = function(resultIndex, newTitle, newList) { var newEntryDate = this.results[resultIndex].feed.entries[0].publishedDate; var newEntryDateMS = Date.parse(newEntryDate); var insertIndex = null; for (var i = 0; i < this.results.length; i++) { var mostRecentPost = this.results[i].feed.entries[0].publishedDate; var mostRecentPostMS = Date.parse(mostRecentPost); if(newEntryDateMS > mostRecentPostMS) { insertIndex = i; break;}
}
if(insertIndex == null) { this.nodes.root.appendChild(newTitle); this.nodes.root.appendChild(newList); this.createListEntries_(resultIndex, newList); return;}
var insertBeforeIndex = 2 + (insertIndex * 2); var swapToIndex = insertBeforeIndex + 2; var tempSwap = null; var myResultIndex = resultIndex + 1; var sectionsToChange = this.nodes.root.childNodes; var nodeToInsertBefore = sectionsToChange[insertBeforeIndex]; this.nodes.root.insertBefore(newTitle, nodeToInsertBefore); this.nodes.root.insertBefore(newList, nodeToInsertBefore); this.results.splice(insertIndex, 0, this.results[resultIndex]); this.results.splice(myResultIndex, 1); var nodesToChangeClick = sectionsToChange[swapToIndex].nextSibling.childNodes; this.createListEntries_(insertIndex, newList); if(insertIndex == 0) { this.displayResult_(0);}
insertIndex += 1; for (var i = swapToIndex; i < sectionsToChange.length; i += 2) { var nodesToChangeClick = sectionsToChange[i].nextSibling.childNodes; for (var j=0; j < nodesToChangeClick.length; j++) { nodesToChangeClick[j].onmouseover = this.bind_(this.listMouseOver_, insertIndex, j); nodesToChangeClick[j].onmouseout = this.bind_(this.listMouseOut_, insertIndex, j);}
insertIndex++;}
}; GFdynamicFeedControl.prototype.addResult_ = function(resultIndex) { var result = this.results[resultIndex]; var newTitle = this.createDiv_('gfg-subtitle'); this.setTitle_(result.feed, newTitle); var newList = this.createDiv_('gfg-list'); if(this.options.collapseable) { var collapseLink = document.createElement('div'); newList.style.display = 'none'; collapseLink.className = 'gfg-collapse-closed'; newTitle.appendChild(collapseLink); collapseLink.onclick = this.toggleCollapse(this, newList, collapseLink); this.collapseElements.push({ list : newList, collapse : collapseLink
});}
var clearFloat = document.createElement('div'); clearFloat.className = 'clearFloat'; newTitle.appendChild(clearFloat); if(!this.options.sortByDate) { this.nodes.root.appendChild(newTitle); this.nodes.root.appendChild(newList); this.createListEntries_(resultIndex, newList);} else { this.sortByDate_(resultIndex, newTitle, newList);}
}; GFdynamicFeedControl.prototype.displayResult_ = function(resultIndex) { this.resultIndex = resultIndex; var result = this.results[resultIndex]; if (this.options.feedTransitionCallback) { this.options.feedTransitionCallback(result);}
if (this.options.title) { this.setPlainTitle_(this.options.title);} else { this.setTitle_(result.feed);}
this.clearNode_(this.nodes.entry); if (this.started && !this.options.horizontal && this.options.stacked) { this.entries = result.feed.entries;} else { this.createListEntries_(resultIndex, this.nodes.list);}
this.displayEntries_();}
GFdynamicFeedControl.prototype.setPlainTitle_ = function(title, opt_element) { var el = opt_element || this.nodes.title; el.innerHTML = title;}
GFdynamicFeedControl.prototype.setTitle_ = function(resultFeed, opt_element) { var el = opt_element || this.nodes.title; this.clearNode_(el); var link = document.createElement('a'); link.target = google.feeds.LINK_TARGET_BLANK; link.href = resultFeed.link; link.className = 'gfg-collapse-href'; link.innerHTML = resultFeed.title; el.appendChild(link);}
GFdynamicFeedControl.prototype.toggleCollapse = function(feedControl, listReference, collapseLink) { return function() { var els = feedControl.collapseElements; for (var i=0; i < els.length; i++) { var el = els[i]; el.list.style.display = 'none'; el.collapse.className = 'gfg-collapse-closed';}
listReference.style.display = 'block'; collapseLink.className = 'gfg-collapse-open';}
}
GFdynamicFeedControl.prototype.createListEntries_ = function(resultIndex, node) { var entries = this.results[resultIndex].feed.entries; this.clearNode_(node); for (var i = 0; i < entries.length; i++) { this.feedControl.createHtml(entries[i]); var className = 'gfg-listentry '; className += (i%2)?'gfg-listentry-even':'gfg-listentry-odd'; var listEntry = this.createDiv_(className); var link = this.createLink_(entries[i].link, entries[i].title, this.options.linkTarget); listEntry.appendChild(link); if (this.options.pauseOnHover) { listEntry.onmouseover = this.bind_(this.listMouseOver_, resultIndex, i); listEntry.onmouseout = this.bind_(this.listMouseOut_, resultIndex, i);}
entries[i].listEntry = listEntry; node.appendChild(listEntry);}
if (node == this.nodes.list) { this.entries = entries;}
}
GFdynamicFeedControl.prototype.displayEntries_ = function() { this.entryIndex = 0; this.displayCurrentEntry_(); this.setDisplayTimer_(); this.started = true;}
GFdynamicFeedControl.prototype.displayNextEntry_ = function() { if (this.options.autoCleanup && this.isOrphaned_()) { this.cleanup_(); return;}
if (++this.entryIndex >= this.entries.length) { if (this.results.length > 1) { if (++this.resultIndex >= this.results.length) { this.resultIndex = 0;}
this.displayResult_(this.resultIndex); return;} else { this.entryIndex = 0;}
}
if (this.options.transitionCallback) { this.options.transitionCallback(this.entries[this.entryIndex]);}
this.displayCurrentEntry_(); this.setDisplayTimer_();}
GFdynamicFeedControl.prototype.displayCurrentEntry_ = function() { this.clearNode_(this.nodes.entry); this.current = this.entries[this.entryIndex].html; this.current.style.top = '0px'; this.nodes.entry.appendChild(this.current); this.createOverlay_(); if(this.options.collapseable) { var feedTitle = null; for (var i=0; i < this.results.length; i++) { if(this.results[i].feed.entries == this.entries) { feedTitle = this.results[i].feed.title;}
}
var els = this.collapseElements; for (var i=0; i < els.length; i++) { var el = els[i]; var divfeedTitle = el.collapse.previousSibling.innerHTML; var expandClicker = el.collapse; if(feedTitle == divfeedTitle) { if(this.ie) { expandClicker.click();} else { expandClicker.onclick();}
}
}
}
if (this.currentList) { var className = 'gfg-listentry '; className += (this.currentListIndex%2)?
'gfg-listentry-even':'gfg-listentry-odd'; this.currentList.className = className;}
this.currentList = this.entries[this.entryIndex].listEntry; this.currentListIndex = this.entryIndex; var className = 'gfg-listentry gfg-listentry-highlight '; className += (this.currentListIndex%2)?
'gfg-listentry-even':'gfg-listentry-odd'; this.currentList.className = className;}
GFdynamicFeedControl.prototype.listMouseHover_ = function(resultIndex, listIndex) { var result = this.results[resultIndex]; var listEntry = result.feed.entries[listIndex].listEntry; listEntry.selectTimer = null; this.clearTransitionTimer_(); this.clearDisplayTimer_(); this.resultIndex = resultIndex; this.entries = result.feed.entries; this.entryIndex = listIndex; this.displayCurrentEntry_();}
GFdynamicFeedControl.prototype.listMouseOver_ = function(resultIndex, listIndex) { var result = this.results[resultIndex]; var listEntry = result.feed.entries[listIndex].listEntry; var cb = this.bind_(this.listMouseHover_, resultIndex, listIndex); listEntry.selectTimer = setTimeout(cb, this.options.hoverTime);}
GFdynamicFeedControl.prototype.listMouseOut_ = function(resultIndex, listIndex) { var result = this.results[resultIndex]; var listEntry = result.feed.entries[listIndex].listEntry; if (listEntry.selectTimer) { clearTimeout(listEntry.selectTimer); listEntry.selectTimer = null;} else { this.setDisplayTimer_();}
}
GFdynamicFeedControl.prototype.entryMouseOver_ = function(e) { this.clearDisplayTimer_(); if (this.transitionTimer) { this.clearTransitionTimer_(); this.displayCurrentEntry_();}
}
GFdynamicFeedControl.prototype.entryMouseOut_ = function(e) { this.setDisplayTimer_();}
GFdynamicFeedControl.prototype.createOverlay_ = function() { if (this.current == null) return; if (this.overlay == null) { var overlay = this.createDiv_('gfg-entry'); overlay.style.position = 'absolute'; overlay.style.top = '0px'; overlay.style.left = '0px'; this.overlay = overlay;}
this.setOpacity_(this.overlay, 0); this.nodes.entry.appendChild(this.overlay);}
GFdynamicFeedControl.prototype.setDisplayTimer_ = function() { if (this.displayTimer) { this.clearDisplayTimer_();}
var cb = this.bind_(this.setFadeOutTimer_); this.displayTimer = setTimeout(cb, this.options.displayTime);}; GFdynamicFeedControl.timeNow = function() { var d = new Date(); return d.getTime();}; GFdynamicFeedControl.prototype.fadeOutEntry_ = function() { if (this.overlay) { var delta = this.fadeOutDelta; var ts = this.options.transitionStep; var now = GFdynamicFeedControl.timeNow(); var tick = now - this.lastTick; this.lastTick = now; delta *= (tick/ts); var op = this.overlay.opacity + delta; this.setOpacity_(this.overlay, op); if (this.options.scrollOnFadeOut && (op > .5)) { var r = (op-.5)*2; var newTop = Math.round(this.current.offsetHeight * r); this.current.style.top = newTop + 'px';}
if (op < 1) return;}
this.clearTransitionTimer_(); this.displayNextEntry_();}; GFdynamicFeedControl.prototype.setFadeOutTimer_ = function() { this.clearTransitionTimer_(); this.lastTick = GFdynamicFeedControl.timeNow(); var cb = this.bind_(this.fadeOutEntry_); this.transitionTimer = setInterval(cb, this.options.transitionStep);}; GFdynamicFeedControl.prototype.clearTransitionTimer_ = function() { if (this.transitionTimer) { clearInterval(this.transitionTimer); this.transitionTimer = null;}
}; GFdynamicFeedControl.prototype.clearDisplayTimer_ = function() { if (this.displayTimer) { clearTimeout(this.displayTimer); this.displayTimer = null;}
}; GFdynamicFeedControl.prototype.createSubContainers_ = function() { var nodes = this.nodes; var container = this.nodes.container; this.clearNode_(container); if (this.options.horizontal) { container = this.createDiv_('gfg-horizontal-container'); nodes.root = this.createDiv_('gfg-horizontal-root'); this.nodes.container.appendChild(container);} else { nodes.root = this.createDiv_('gfg-root');}
nodes.title = this.createDiv_('gfg-title'); nodes.entry = this.createDiv_('gfg-entry'); nodes.list = this.createDiv_('gfg-list'); nodes.root.appendChild(nodes.title); nodes.root.appendChild(nodes.entry); if (!this.options.horizontal && this.options.stacked) { var newTitle = this.createDiv_('gfg-subtitle'); nodes.root.appendChild(newTitle); this.setTitle_(this.results[0].feed, newTitle); if(this.options.collapseable) { var collapseLink = document.createElement('div'); collapseLink.className = 'gfg-collapse-open'; newTitle.appendChild(collapseLink); collapseLink.onclick = this.toggleCollapse(this, nodes.list, collapseLink); this.collapseElements.push({ list : nodes.list, collapse : collapseLink
}); nodes.list.style.display = 'block';}
var clearFloat = document.createElement('div'); clearFloat.className = 'clearFloat'; newTitle.appendChild(clearFloat);}
nodes.root.appendChild(nodes.list); container.appendChild(nodes.root); if (this.options.pauseOnHover) { nodes.entry.onmouseover = this.bind_(this.entryMouseOver_); nodes.entry.onmouseout = this.bind_(this.entryMouseOut_);}
if (this.options.horizontal) { nodes.branding = this.createDiv_('gfg-branding'); google.feeds.getBranding(nodes.branding, google.feeds.VERTICAL_BRANDING); container.appendChild(nodes.branding);}
}; GFdynamicFeedControl.prototype.clearNode_ = function(node) { if (node == null) return; var child; while ((child = node.firstChild)) { node.removeChild(child);}
}; GFdynamicFeedControl.prototype.createDiv_ = function(opt_className, opt_text) { var el = document.createElement("div"); if (opt_text) { el.innerHTML = opt_text;}
if (opt_className) { el.className = opt_className;}
return el;}; GFdynamicFeedControl.prototype.createLink_ = function(href, text, opt_target) { var link = document.createElement('a'); link.href = href; link.innerHTML = text; if (opt_target) { link.target = opt_target;}
return link;}; GFdynamicFeedControl.prototype.clearResults_ = function() { for (var i=0; i < this.results.length; i++) { var result = this.results[i]; var entries = result.feed.entries; for (var i = 0; i < entries.length; i++) { var entry = entries[i]; entry.html = null; entry.listEntry.onmouseover = null; entry.listEntry.onmouseout = null; if (entry.listEntry.selectTimer) { clearTimeout(entry.listEntry.selectTimer); entry.listEntry.selectTimer = null;}
entry.listEntry = null;}
}
}
GFdynamicFeedControl.prototype.isOrphaned_ = function() { var root = this.nodes.root; var orphaned = false; if (!root || !root.parentNode) { orphaned = true;} else if (this.options.horizontal && !root.parentNode.parentNode) { orphaned = true;}
return orphaned;}
GFdynamicFeedControl.prototype.cleanup_ = function() { this.started = false; this.clearDisplayTimer_(); this.clearTransitionTimer_(); this.clearResults_(); this.clearNode_(this.nodes.root); this.nodes.container = null;}
GFdynamicFeedControl.prototype.setOpacity_ = function(node, opacity) { if (node == null) return; opacity = Math.max(0, Math.min(1, opacity)); if (opacity == 0) { if (node.style.visibility != 'hidden') { node.style.visibility = 'hidden';}
} else { if (node.style.visibility != 'visible') { node.style.visibility = 'visible';}
}
if (this.ie) { var normalized = Math.round(opacity*100); node.style.filter = 'alpha(opacity=' + normalized + ')';}
node.style.opacity = node.opacity = opacity;}; GFgadget = GFdynamicFeedControl; 