--- /dev/null
+/*!
+ * jQuery Feeds v0.5
+ * https://camagu.github.com/jquery-feeds
+ *
+ * Copyright (c) 2013, Camilo Aguilar
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Includes a modified version of Simple JavaScript Templating
+ * http://ejohn.org/blog/javascript-micro-templating/
+ * Copyright (c) John Resig (http://ejohn.org)
+ * MIT licensed
+ *
+ * Date: 2013-02-18
+ */
+
+/*jshint evil: true */\r
+( function( $ ) {\r
+ \r
+ var cache = {};\r
+ \r
+ $.fn.feeds = function( options ) {\r
+\r
+ var engine = {\r
+ service: '//ajax.googleapis.com/ajax/services/feed/load?v=1.0',\r
+ \r
+ settings: {\r
+ loadingTemplate: '<div class="feeds-loader">Loading entries ...</div>',\r
+ entryTemplate: '<div class="feeds-entry feeds-source-<!=source!>">' + \r
+ '<a class="feeds-entry-title" target="_blank" href="<!=link!>" title="<!=title!>"><!=title!></a>' +\r
+ '<div class="feeds-entry-date"><!=publishedDate!></div>' + \r
+ '<div class="feeds-entry-contentSnippet"><!=contentSnippet!></div>' + \r
+ '</div>',\r
+ feeds: {},\r
+ max: -1,\r
+ xml: false,\r
+ ssl: 'auto',\r
+ onComplete: function( entries ) {\r
+\r
+ },\r
+ preprocess: function( feed ) {\r
+\r
+ }\r
+ },\r
+ \r
+ feeds: { },\r
+ entries: [ ],\r
+ \r
+ feedsLength: 0,\r
+ feedsLoaded: 0,\r
+ \r
+ $element: null,\r
+ $loader: null,\r
+ \r
+ init: function( element, options ) {\r
+ this.settings = $.extend( this.settings, options );\r
+ this.feeds = this.settings.feeds;\r
+ \r
+ for ( var i in this.feeds ) {\r
+ if ( this.feeds.hasOwnProperty( i ) ) {\r
+ this.feedsLength++;\r
+ }\r
+ }\r
+ \r
+ var protocol = this.settings.ssl === 'auto' ? document.location.protocol : this.settings.ssl ? 'https:' : 'http:';\r
+ if ( $.inArray( protocol, [ 'http:', 'https' ]) === -1 ) {\r
+ protocol = 'https:';\r
+ }\r
+ \r
+ this.service = protocol + this.service;\r
+ \r
+ this.$element = $( element );\r
+ \r
+ var render = typeof this.settings.loadingTemplate === 'function' ? this.settings.loadingTemplate : this.tmpl( this.settings.loadingTemplate );\r
+ this.$loader = $( render.call( this, { } ) );\r
+ this.$element.html( this.$loader );\r
+ \r
+ var output = this.settings.xml ? 'json_xml' : 'json';\r
+ \r
+ for ( var j in this.feeds ) {\r
+ this.fetchFeed( j, this.feeds[ j ], this.settings.max, output );\r
+ }\r
+ },\r
+ \r
+ fetchFeed: function( key, feed, max, output ) {\r
+ var self = this;\r
+ \r
+ var cacheKey = feed + '**' + max + '**' + output;\r
+ if ( typeof cache[ cacheKey ] !== 'undefined' ) {\r
+ self.processResponse( cache[ cacheKey ], key, feed );\r
+ return;\r
+ }\r
+ \r
+ $.ajax( {\r
+ url: this.service,\r
+ dataType: 'jsonp',\r
+ data: {\r
+ q: feed,\r
+ num: max,\r
+ output: output\r
+ },\r
+ beforeSend: function( ) {\r
+ this.feed = feed;\r
+ this.key = key;\r
+ },\r
+ success: function( data ) {\r
+ cache[ cacheKey ] = data;\r
+ self.processResponse( data, this.key, this.feed );\r
+ }\r
+ } );\r
+ },\r
+ \r
+ processResponse: function( data, key, feed ) {\r
+ if ( data.responseStatus !== 200 ) {\r
+ if ( window.console && window.console.log ) {\r
+ console.log( 'Unable to load feed ' + feed + ': (' + data.responseStatus + ') ' + data.responseDetails );\r
+ }\r
+ } else {\r
+ var currentFeed = data.responseData.feed;\r
+ var feedEntries = currentFeed.entries;\r
+ \r
+ var type = data.responseData.feed.type;\r
+ \r
+ if ( this.settings.xml ) {\r
+ var $xml = $( data.responseData.xmlString );\r
+ \r
+ if ( type.match( /^rss.*/ ) ) {\r
+ $xml = $xml.filter( 'rss' ).find( 'channel' );\r
+ } else if ( type.match( /^atom.*/ ) ) {\r
+ $xml = $xml.filter( 'feed' );\r
+ }\r
+ \r
+ currentFeed.xml = $xml;\r
+ }\r
+ \r
+ for ( var i in feedEntries ) {\r
+ var entry = $.extend( {}, feedEntries[ i ] );\r
+ entry.source = key;\r
+ entry.publishedDateRaw = entry.publishedDate;\r
+ \r
+ entry.feedUrl = currentFeed.feedUrl;\r
+ entry.feedTitle = currentFeed.title;\r
+ entry.feedLink = currentFeed.link;\r
+ entry.feedDescription = currentFeed.description;\r
+ entry.feedAuthor = currentFeed.author;\r
+ \r
+ if ( this.settings.xml ) {\r
+ if ( type.match( /^rss.*/ ) ) {\r
+ entry.xml = currentFeed.xml.find( 'item' ).eq( i );\r
+ } else if ( type.match( /^atom.*/ ) ) {\r
+ entry.xml = currentFeed.xml.find( 'entry' ).eq( i );\r
+ } else {\r
+ entry.xml = { };\r
+ }\r
+ }\r
+ \r
+ if ( this.settings.preprocess.call( entry, currentFeed ) !== false ) {\r
+ this.entries.push( entry );\r
+ }\r
+ }\r
+ }\r
+ \r
+ this.feedsLoaded++;\r
+ this.checkComplete();\r
+ },\r
+ \r
+ checkComplete: function( ) {\r
+ if ( this.feedsLoaded === this.feedsLength ) {\r
+ this.$loader.remove( );\r
+ \r
+ this.entries.sort( function( a, b) {\r
+ var aDate = new Date( a.publishedDateRaw ).getTime( );\r
+ var bDate = new Date( b.publishedDateRaw ).getTime( );\r
+\r
+ return bDate - aDate;\r
+ } );\r
+ \r
+ var render = typeof this.settings.entryTemplate === 'function' ? this.settings.entryTemplate : this.tmpl( this.settings.entryTemplate );\r
+ \r
+ for ( var i in this.entries ) {\r
+ var entry = this.entries[ i ];\r
+ \r
+ var html = render.call( this, entry );\r
+ \r
+ this.$element.append( html );\r
+ }\r
+ \r
+ this.settings.onComplete.call( this.$element[ 0 ], this.entries );\r
+ }\r
+ },\r
+ \r
+\r
+ // Simple JavaScript Templating (modified)\r
+ // John Resig - http://ejohn.org/ - MIT Licensed\r
+ // @see http://ejohn.org/blog/javascript-micro-templating/\r
+ tmplCache: {},\r
+ tmpl: function tmpl( str, data ) {\r
+\r
+ var fn = !/\W/.test( str ) ? this.tmplCache[ str ] = this.tmplCache[ str ] || this.tmpl( document.getElementById( str ).innerHTML ) :\r
+\r
+ new Function( "obj",\r
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +\r
+\r
+ "with(obj){p.push('" +\r
+ str\r
+ .replace( /[\r\t\n]/g, " " )\r
+ .split( "<!" ).join( "\t" )\r
+ .replace( /((^|!>)[^\t]*)'/g, "$1\r" )\r
+ .replace( /\t=(.*?)!>/g, "',typeof $1 != 'undefined' ? $1 : '','" )\r
+ .split( "\t" ).join( "');" )\r
+ .split( "!>" ).join( "p.push('" )\r
+ .split( "\r" ).join( "\\'" ) +\r
+ "');}return p.join('');"\r
+ );\r
+\r
+ return data ? fn( data ) : fn;\r
+ }\r
+ };\r
+ \r
+ return $( this ).each( function( ) {\r
+ engine.init( this, options );\r
+ });\r
+ };\r
+}( jQuery ) );
\ No newline at end of file
--- /dev/null
+/*!
+ * jQuery Feeds v0.5
+ * https://camagu.github.com/jquery-feeds
+ *
+ * Copyright (c) 2013, Camilo Aguilar
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Includes a modified version of Simple JavaScript Templating
+ * http://ejohn.org/blog/javascript-micro-templating/
+ * Copyright (c) John Resig (http://ejohn.org)
+ * MIT licensed
+ *
+ * Date: 2013-02-18
+ */
+(function(e){var t={};e.fn.feeds=function(n){var r={service:"//ajax.googleapis.com/ajax/services/feed/load?v=1.0",settings:{loadingTemplate:'<div class="feeds-loader">Loading entries ...</div>',entryTemplate:'<div class="feeds-entry feeds-source-<!=source!>"><a class="feeds-entry-title" target="_blank" href="<!=link!>" title="<!=title!>"><!=title!></a><div class="feeds-entry-date"><!=publishedDate!></div><div class="feeds-entry-contentSnippet"><!=contentSnippet!></div></div>',feeds:{},max:-1,xml:!1,ssl:"auto",onComplete:function(e){},preprocess:function(e){}},feeds:{},entries:[],feedsLength:0,feedsLoaded:0,$element:null,$loader:null,init:function(t,n){this.settings=e.extend(this.settings,n),this.feeds=this.settings.feeds;for(var r in this.feeds)this.feeds.hasOwnProperty(r)&&this.feedsLength++;var i=this.settings.ssl==="auto"?document.location.protocol:this.settings.ssl?"https:":"http:";e.inArray(i,["http:","https"])===-1&&(i="https:"),this.service=i+this.service,this.$element=e(t);var s=typeof this.settings.loadingTemplate=="function"?this.settings.loadingTemplate:this.tmpl(this.settings.loadingTemplate);this.$loader=e(s.call(this,{})),this.$element.html(this.$loader);var o=this.settings.xml?"json_xml":"json";for(var u in this.feeds)this.fetchFeed(u,this.feeds[u],this.settings.max,o)},fetchFeed:function(n,r,i,s){var o=this,u=r+"**"+i+"**"+s;if(typeof t[u]!="undefined"){o.processResponse(t[u],n,r);return}e.ajax({url:this.service,dataType:"jsonp",data:{q:r,num:i,output:s},beforeSend:function(){this.feed=r,this.key=n},success:function(e){t[u]=e,o.processResponse(e,this.key,this.feed)}})},processResponse:function(t,n,r){if(t.responseStatus!==200)window.console&&window.console.log&&console.log("Unable to load feed "+r+": ("+t.responseStatus+") "+t.responseDetails);else{var i=t.responseData.feed,s=i.entries,o=t.responseData.feed.type;if(this.settings.xml){var u=e(t.responseData.xmlString);o.match(/^rss.*/)?u=u.filter("rss").find("channel"):o.match(/^atom.*/)&&(u=u.filter("feed")),i.xml=u}for(var a in s){var f=e.extend({},s[a]);f.source=n,f.publishedDateRaw=f.publishedDate,f.feedUrl=i.feedUrl,f.feedTitle=i.title,f.feedLink=i.link,f.feedDescription=i.description,f.feedAuthor=i.author,this.settings.xml&&(o.match(/^rss.*/)?f.xml=i.xml.find("item").eq(a):o.match(/^atom.*/)?f.xml=i.xml.find("entry").eq(a):f.xml={}),this.settings.preprocess.call(f,i)!==!1&&this.entries.push(f)}}this.feedsLoaded++,this.checkComplete()},checkComplete:function(){if(this.feedsLoaded===this.feedsLength){this.$loader.remove(),this.entries.sort(function(e,t){var n=(new Date(e.publishedDateRaw)).getTime(),r=(new Date(t.publishedDateRaw)).getTime();return r-n});var e=typeof this.settings.entryTemplate=="function"?this.settings.entryTemplate:this.tmpl(this.settings.entryTemplate);for(var t in this.entries){var n=this.entries[t],r=e.call(this,n);this.$element.append(r)}this.settings.onComplete.call(this.$element[0],this.entries)}},tmplCache:{},tmpl:function(t,n){var r=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.replace(/[\r\t\n]/g," ").split("<!").join(" ").replace(/((^|!>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)!>/g,"',typeof $1 != 'undefined' ? $1 : '','").split(" ").join("');").split("!>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):this.tmplCache[t]=this.tmplCache[t]||this.tmpl(document.getElementById(t).innerHTML);return n?r(n):r}};return e(this).each(function(){r.init(this,n)})}})(jQuery);
\ No newline at end of file