Last active
December 12, 2015 01:28
-
-
Save adesignl/4691592 to your computer and use it in GitHub Desktop.
Jquery-RSS with ie7/ie8 fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// RSS Feed Reader | |
$("#rss-feeds").rss( "RSSURLHERE", { | |
limit: 3, | |
ssl: false, | |
layoutTemplate: '<div class="feed-container">{entries}</div>', | |
entryTemplate: '<div class="entry"><h5><a href="{url}">{title}</a></h5><p>{shortBodyPlain}</p></div>' | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) { | |
"use strict"; | |
var RSS = function(target, url, options, callback) { | |
this.target = target | |
this.url = url | |
this.html = [] | |
this.effectQueue = [] | |
this.callback = callback | |
this.options = jQuery.extend({ | |
ssl: false, | |
limit: null, | |
key: null, | |
layoutTemplate: '<ul>{entries}</ul>', | |
entryTemplate: '<li><a href="{url}">[{author}@{date}] {title}</a><br/>{shortBodyPlain}</li>', | |
tokens: {}, | |
outputMode: 'json', | |
effect: 'show' | |
}, options || {}) | |
} | |
RSS.htmlTags = ["doctype", "html", "head", "title", "base", "link", "meta", "style", "script", "noscript", "body", "article", "nav", "aside", "section", "header", "footer", "h1-h6", "hgroup", "address", "p", "hr", "pre", "blockquote", "ol", "ul", "li", "dl", "dt", "dd", "figure", "figcaption", "div", "table", "caption", "thead", "tbody", "tfoot", "tr", "th", "td", "col", "colgroup", "form", "fieldset", "legend", "label", "input", "button", "select", "datalist", "optgroup", "option", "textarea", "keygen", "output", "progress", "meter", "details", "summary", "command", "menu", "del", "ins", "img", "iframe", "embed", "object", "param", "video", "audio", "source", "canvas", "track", "map", "area", "a", "em", "strong", "i", "b", "u", "s", "small", "abbr", "q", "cite", "dfn", "sub", "sup", "time", "code", "kbd", "samp", "var", "mark", "bdi", "bdo", "ruby", "rt", "rp", "span", "br", "wbr"] | |
RSS.prototype.load = function(callback) { | |
var apiProtocol = "http" + (this.options.ssl ? "s" : "") | |
, apiHost = apiProtocol + "://ajax.googleapis.com/ajax/services/feed/load" | |
, apiUrl = apiHost + "?v=1.0&output=" + this.options.outputMode + "&callback=?&q=" + encodeURIComponent(this.url) | |
, self = this | |
if (this.options.limit != null) apiUrl += "&num=" + this.options.limit; | |
if (this.options.key != null) apiUrl += "&key=" + this.options.key; | |
$.getJSON(apiUrl, callback) | |
} | |
RSS.prototype.render = function() { | |
var self = this | |
this.load(function(data) { | |
self.entries = data.responseData.feed.entries | |
var html = self.generateHTMLForEntries() | |
self.target.append(html.layout) | |
if (html.entries.length !== 0) { | |
self.appendEntriesAndApplyEffects(html.layout, html.entries) | |
} | |
if (self.effectQueue.length > 0) { | |
self.executeEffectQueue(self.callback) | |
} else { | |
$.isFunction(self.callback) && self.callback.call(self); | |
} | |
}) | |
} | |
RSS.prototype.appendEntriesAndApplyEffects = function(target, entries) { | |
var self = this | |
entries.forEach(function(entry) { | |
var $html = self.wrapContent(entry) | |
if(self.options.effect === 'show') { | |
target.append($html) | |
} else { | |
$html.css({ display: 'none' }) | |
target.append($html) | |
self.applyEffect($html, self.options.effect) | |
} | |
}) | |
} | |
// Added For ie7 & ie8 | |
if (!Array.prototype.forEach) { | |
Array.prototype.forEach = function (fn, scope) { | |
for (var i = 0, len = this.length; i < len; ++i) { | |
fn.call(scope || this, this[i], i, this); | |
} | |
} | |
} | |
// Added For ie7 & ie8 | |
RSS.prototype.generateHTMLForEntries = function() { | |
var self = this | |
, result = { | |
entries: [], | |
layout: null | |
} | |
jQuery(this.entries).each(function() { | |
var entry = this | |
if(self.isRelevant(entry)) { | |
var evaluatedString = self.evaluateStringForEntry(self.options.entryTemplate, entry) | |
result.entries.push(evaluatedString) | |
} | |
}) | |
if(!!this.options.entryTemplate) { | |
// we have an entryTemplate | |
result.layout = this.wrapContent(this.options.layoutTemplate.replace("{entries}", '')) | |
} else { | |
// no entryTemplate available | |
result.layout = this.wrapContent(result.entries.join("\n")) | |
} | |
return result | |
} | |
RSS.prototype.wrapContent = function(content) { | |
if($.trim(content).indexOf('<') !== 0) { | |
// the content has no html => create a surrounding div | |
return $("<div>" + content + "</div>") | |
} else { | |
// the content has html => don't touch it | |
return $(content) | |
} | |
} | |
RSS.prototype.applyEffect = function($element, effect, callback) { | |
var self = this | |
switch(effect) { | |
case 'slide': | |
$element.slideDown('slow', callback) | |
break | |
case 'slideFast': | |
$element.slideDown(callback) | |
break | |
case 'slideSynced': | |
self.effectQueue.push({ element: $element, effect: 'slide' }) | |
break | |
case 'slideFastSynced': | |
self.effectQueue.push({ element: $element, effect: 'slideFast' }) | |
break | |
} | |
} | |
RSS.prototype.executeEffectQueue = function(callback) { | |
var self = this | |
this.effectQueue.reverse() | |
var executeEffectQueueItem = function() { | |
var item = self.effectQueue.pop() | |
if(item) { | |
self.applyEffect(item.element, item.effect, executeEffectQueueItem) | |
} else { | |
callback && callback() | |
} | |
} | |
executeEffectQueueItem() | |
} | |
RSS.prototype.evaluateStringForEntry = function(string, entry) { | |
var result = string | |
, self = this | |
jQuery(string.match(/(\{.*?\})/g)).each(function() { | |
var token = this.toString() | |
result = result.replace(token, self.getValueForToken(token, entry)) | |
}) | |
return result | |
} | |
RSS.prototype.isRelevant = function(entry) { | |
var tokenMap = this.getTokenMap(entry) | |
if(this.options.filter) { | |
if(this.options.filterLimit && (this.options.filterLimit == this.html.length)) { | |
return false | |
} else { | |
return this.options.filter(entry, tokenMap) | |
} | |
} else { | |
return true | |
} | |
} | |
RSS.prototype.getTokenMap = function(entry) { | |
return jQuery.extend({ | |
url: entry.link, | |
author: entry.author, | |
date: entry.publishedDate, | |
title: entry.title, | |
body: entry.content, | |
shortBody: entry.contentSnippet, | |
bodyPlain: (function(entry) { | |
var result = entry.content | |
.replace(/<script[\\r\\\s\S]*<\/script>/mgi, '') | |
.replace(/<\/?[^>]+>/gi, '') | |
for(var i = 0; i < RSS.htmlTags.length; i++) { | |
result = result.replace(new RegExp('<' + RSS.htmlTags[i], 'gi'), '') | |
} | |
return result | |
})(entry), | |
shortBodyPlain: entry.contentSnippet.replace(/<\/?[^>]+>/gi, ''), | |
index: jQuery.inArray(entry, this.entries), | |
totalEntries: this.entries.length, | |
teaserImage: (function(entry){ | |
try { return entry.content.match(/(<img.*?>)/gi)[0] } | |
catch(e) { return "" } | |
})(entry), | |
teaserImageUrl: (function(entry) { | |
try { return entry.content.match(/(<img.*?>)/gi)[0].match(/src="(.*?)"/)[1] } | |
catch(e) { return "" } | |
})(entry) | |
}, this.options.tokens) | |
} | |
RSS.prototype.getValueForToken = function(_token, entry) { | |
var tokenMap = this.getTokenMap(entry) | |
, token = _token.replace(/[\{\}]/g, '') | |
, result = tokenMap[token] | |
if(typeof result != 'undefined') | |
return ((typeof result == 'function') ? result(entry, tokenMap) : result) | |
else | |
throw new Error('Unknown token: ' + _token) | |
} | |
$.fn.rss = function(url, options, callback) { | |
new RSS(this, url, options, callback).render() | |
} | |
})(jQuery) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment