diff --git a/ajax/libs/embedly-jquery/3.0.2/jquery.embedly.js b/ajax/libs/embedly-jquery/3.0.2/jquery.embedly.js new file mode 100644 index 000000000..b4cefcc8e --- /dev/null +++ b/ajax/libs/embedly-jquery/3.0.2/jquery.embedly.js @@ -0,0 +1,408 @@ +/*! Embedly jQuery - v3.0.2 - 2013-02-28 + * https://github.com/embedly/embedly-jquery + * Copyright (c) 2013 Sean Creeley + * Licensed BSD + */ +(function($) { + + /* + * Util Functions + */ + + // Defaults for Embedly. + var defaults = { + key: null, + endpoint: 'oembed', // default endpoint is oembed (preview and objectify available too) + secure: null, // use https endpoint vs http + query: {}, + method: 'replace', // embed handling option for standard callback + addImageStyles: true, // add style="" attribute to images for query.maxwidth and query.maxhidth + wrapElement: 'div', // standard wrapper around all returned embeds + className: 'embed', // class on the wrapper element + batch: 20, // Default Batch Size. + urlRe: null + }; + + var urlRe = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; + + function none(obj){ + return obj === null || obj === undefined; + } + // Split a list into a bunch of batchs. + function batch(list, split){ + var batches = [], current = []; + $.each(list, function(i, obj){ + current.push(obj); + if (current.length === split){ + batches.push(current); + current = []; + } + }); + if (current.length !== 0){ + batches.push(current); + } + return batches; + } + // Make an argument a list + function listify(obj){ + if (none(obj)){ + return []; + } else if (!$.isArray(obj)){ + return [obj]; + } + return obj; + } + + // From: http://bit.ly/T9SjVv + function zip(arrays) { + return arrays[0].map(function(_,i){ + return arrays.map(function(array){return array[i];}); + }); + } + + /* Keeper + * + * alittle wrapper around Deferred that lets us keep track of + * all the callbacks that we have. + */ + var Keeper = function (len, each, after) { + this.init(len, each, after); + }; + Keeper.prototype = { + + init: function(urls){ + this.urls = urls; + this.count = 0; + this.results = {}; + this._deferred = $.Deferred(); + }, + // Only 2 methods we really care about. + notify : function(result) { + // Store the result. + this.results[result.original_url] = result; + // Increase the count. + this.count++; + // Notify the success functions + this._deferred.notify.apply(this._deferred, [result]); + // If all the callbacks have completed, do your thing. + if (this.count === this.urls.length){ + // This sorts the results in the manner in which they were added. + var self = this; + var results = this.urls.map(function(url){ return self.results[url];}); + this._deferred.resolve(results); + } + return this; + }, + state: function() { + return this._deferred.state.apply(this._deferred, arguments); + } + }; + window.Keeper = Keeper; + + // direct API for dealing with the + var API = function () {}; + API.prototype = { + /* + For dealing directly with Embedly's API. + + options: { + key: 'Your API key' + secure: false, + query: { + maxwidth: 500, + colors: true, + } + } + */ + defaults: {}, + + log: function(level, message){ + if (!none(window.console) && !none(window.console[level])){ + window.console[level].apply(window.console, [message]); + } + }, + // Based on the method and options, build the url, + build: function(method, urls, options){ + // Technically, not great. + options = none(options) ? {}: options; + // Base method. + + var secure = options.secure; + if (none(secure)){ + // If the secure param was not see, use the protocol instead. + secure = window.location.protocol === 'https:'? true:false; + } + + var base = (secure ? 'https': 'http') + + '://api.embed.ly/' + (method === 'objectify' ? '2/' : '1/') + method; + + // Base Query; + var query = none(options.query) ? {} : options.query; + query.key = options.key; + base += '?'+$.param(query); + + // Add the urls the way we like. + base += '&urls='+urls.map(encodeURIComponent).join(','); + + return base; + }, + // Batch a bunch of URLS up for processing. Will split longer lists out + // into many batches and return the callback on each and after on done. + ajax: function(method, urls, options){ + + // Use the defaults. + options = $.extend({}, defaults, $.embedly.defaults, typeof options === 'object' && options); + + if (none(options.key)){ + this.log('error', 'Embedly jQuery requires an API Key. Please sign up for one at http://embed.ly'); + return null; + } + + // Everything is dealt with in lists. + urls = listify(urls); + + // add a keeper that holds everything till we are good to go. + var keeper = new Keeper(urls); + + var valid_urls = [], rejects = [], valid; + // Debunk the invalid urls right now. + $.each(urls, function(i, url){ + valid = false; + // Make sure it's a URL + if (urlRe.test(url)){ + valid = true; + // If the urlRe has been defined make sure it works. + if (options.urlRe !== null && options.urlRe.test && !options.urlRe.test(url)){ + valid = false; + } + } + // deal with the valid urls + if(valid === true){ + valid_urls.push(url); + } else { + // Notify the keeper that we have a bad url. + rejects.push({ + url: url, + original_url: url, + error: true, + invalid: true, + type: 'error', + error_message: 'Invalid URL "'+ url+'"' + }); + } + }); + + // Put everything into batches, even if these is only one. + var batches = batch(valid_urls, options.batch), self = this; + + // Actually make those calls. + $.each(batches, function(i, batch){ + $.ajax({ + url: self.build(method, batch, options), + dataType: 'jsonp', + success: function(data){ + // We zip together the urls and the data so we have the original_url + $.each(zip([batch, data]), function(i, obj){ + var result = obj[1]; + result.original_url = obj[0]; + result.invalid = false; + keeper.notify(result); + }); + } + }); + }); + + if (rejects.length){ + // set a short timeout so we can set up progress and done, otherwise + // the progress notifier will not get all the events. + setTimeout(function(){ + $.each(rejects, function(i, reject){ + keeper.notify(reject); + }); + }, 1); + } + + return keeper._deferred; + }, + + // Wrappers around ajax. + oembed: function(urls, options){ + return this.ajax('oembed', urls, options); + }, + preview: function(urls, options){ + return this.ajax('preview', urls, options); + }, + objectify: function(urls, options){ + return this.ajax('objectify', urls, options); + } + }; + + var Embedly = function (element, url, options) { + this.init(element, url, options); + }; + + Embedly.prototype = { + init: function(elem, original_url, options){ + this.elem = elem; + this.$elem = $(elem); + this.original_url = original_url; + this.options = options; + this.loaded = $.Deferred(); + + // Sets up some triggers. + var self = this; + this.loaded.done(function(){ + self.$elem.trigger('loaded', [self]); + }); + + // So you can listen when the tag has been initialized; + this.$elem.trigger('initialized', [this]); + }, + progress: function(obj){ + $.extend(this, obj); + + // if there is a custom display method, use it. + if (this.options.display){ + this.options.display.apply(this.elem, [this, this.elem]); + } + // We only have a simple case for oEmbed. Everything else should be a custom + // success method. + else if(this.options.endpoint === 'oembed'){ + this.display(); + } + + // Notifies all listeners that the data has been loaded. + this.loaded.resolve(this); + }, + imageStyle: function(){ + var style = [], units; + if (this.options.addImageStyles) { + if (this.options.query.maxwidth) { + units = isNaN(parseInt(this.options.query.maxwidth, 10)) ? '' : 'px'; + style.push("max-width: " + (this.options.query.maxwidth)+units); + } + if (this.options.query.maxheight) { + units = isNaN(parseInt(this.options.query.maxheight,10)) ? '' : 'px'; + style.push("max-height: " + (this.options.query.maxheight)+units); + } + } + return style.join(';'); + }, + + display: function(){ + // Ignore errors + if (this.type === 'error'){ + return false; + } + + // Image Style. + this.style = this.imageStyle(); + + var html; + if (this.type === 'photo'){ + html = ""; + html += "" + this.title + ""; + } else if (this.type === 'video' || this.type === 'rich'){ + html = this.html; + } else { + this.title = this.title || this.url; + html = this.thumbnail_url ? "" : ""; + html += "" + this.title + ""; + html += this.provider_name ? "" + this.provider_name + "" : ""; + html += this.description ? '
' + this.description + '
' : ''; + } + + if (this.options.wrapElement) { + html = '<' + this.options.wrapElement+ ' class="' + this.options.className + '">' + html + ''; + } + + this.code = html; + // Yay. + if (this.options.method === 'replace'){ + this.$elem.replaceWith(this.code); + } else if (this.options.method === 'after'){ + this.$elem.after(this.code); + } else if (this.options.method === 'afterParent'){ + this.$elem.parent().after(this.code); + } else if (this.options.method === 'replaceParent'){ + this.$elem.parent().replaceWith(this.code); + } + // for DOM elements we add the oembed object as a data field to that element and trigger a custom event called oembed + // with the custom event, developers can do any number of custom interactions with the data that is returned. + this.$elem.trigger('displayed', [this]); + } + }; + + // Sets up a generic API for use. + $.embedly = new API(); + + $.fn.embedly = function ( options ) { + if (options === undefined || typeof options === 'object') { + + // Use the defaults + options = $.extend({}, defaults, $.embedly.defaults, typeof options === 'object' && options); + + // Kill these early. + if (none(options.key)){ + $.embedly.log('error', 'Embedly jQuery requires an API Key. Please sign up for one at http://embed.ly'); + return this.each($.noop); + } + // Keep track of the nodes we are working on so we can add them to the + // progress events. + var nodes = {}; + + // Create the node. + var create = function (elem){ + if (!$.data($(elem), 'embedly')) { + var url = $(elem).attr('href'); + + var node = new Embedly(elem, url, options); + $.data(elem, 'embedly', node); + + if (nodes.hasOwnProperty(url)){ + nodes[url].push(node); + } else { + nodes[url] = [node]; + } + } + }; + + // Find everything with a URL on it. + var elems = this.each(function () { + if ( !none($(this).attr('href')) ){ + create(this); + } else { + $(this).find('a').each(function(){ + if ( ! none($(this).attr('href')) ){ + create(this); + } + }); + } + }); + + // set up the api call. + var deferred = $.embedly.ajax(options.endpoint, + $.map(nodes, function(value, key) {return key;}), + options) + .progress(function(obj){ + $.each(nodes[obj.original_url], function(i, node){ + node.progress(obj); + }); + }); + + if (options.progress){ + deferred.progress(options.progress); + } + if (options.done){ + deferred.done(options.done); + } + return elems; + } + }; + + // Custom selector. + $.expr[':'].embedly = function(elem) { + return ! none($(elem).data('embedly')); + }; + +}(jQuery)); diff --git a/ajax/libs/embedly-jquery/3.0.2/jquery.embedly.min.js b/ajax/libs/embedly-jquery/3.0.2/jquery.embedly.min.js new file mode 100644 index 000000000..6117bcb93 --- /dev/null +++ b/ajax/libs/embedly-jquery/3.0.2/jquery.embedly.min.js @@ -0,0 +1,6 @@ +/*! Embedly jQuery - v3.0.2 - 2013-02-28 + * https://github.com/embedly/embedly-jquery + * Copyright (c) 2013 Sean Creeley + * Licensed BSD + */ +(function(t){function e(t){return null===t||void 0===t}function i(e,i){var r=[],s=[];return t.each(e,function(t,e){s.push(e),s.length===i&&(r.push(s),s=[])}),0!==s.length&&r.push(s),r}function r(i){return e(i)?[]:t.isArray(i)?i:[i]}function s(t){return t[0].map(function(e,i){return t.map(function(t){return t[i]})})}var n={key:null,endpoint:"oembed",secure:null,query:{},method:"replace",addImageStyles:!0,wrapElement:"div",className:"embed",batch:20,urlRe:null},o=/(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/,h=function(t,e,i){this.init(t,e,i)};h.prototype={init:function(e){this.urls=e,this.count=0,this.results={},this._deferred=t.Deferred()},notify:function(t){if(this.results[t.original_url]=t,this.count++,this._deferred.notify.apply(this._deferred,[t]),this.count===this.urls.length){var e=this,i=this.urls.map(function(t){return e.results[t]});this._deferred.resolve(i)}return this},state:function(){return this._deferred.state.apply(this._deferred,arguments)}},window.Keeper=h;var a=function(){};a.prototype={defaults:{},log:function(t,i){e(window.console)||e(window.console[t])||window.console[t].apply(window.console,[i])},build:function(i,r,s){s=e(s)?{}:s;var n=s.secure;e(n)&&(n="https:"===window.location.protocol?!0:!1);var o=(n?"https":"http")+"://api.embed.ly/"+("objectify"===i?"2/":"1/")+i,h=e(s.query)?{}:s.query;return h.key=s.key,o+="?"+t.param(h),o+="&urls="+r.map(encodeURIComponent).join(",")},ajax:function(a,l,u){if(u=t.extend({},n,t.embedly.defaults,"object"==typeof u&&u),e(u.key))return this.log("error","Embedly jQuery requires an API Key. Please sign up for one at http://embed.ly"),null;l=r(l);var d,p=new h(l),c=[],f=[];t.each(l,function(t,e){d=!1,o.test(e)&&(d=!0,null!==u.urlRe&&u.urlRe.test&&!u.urlRe.test(e)&&(d=!1)),d===!0?c.push(e):f.push({url:e,original_url:e,error:!0,invalid:!0,type:"error",error_message:'Invalid URL "'+e+'"'})});var y=i(c,u.batch),m=this;return t.each(y,function(e,i){t.ajax({url:m.build(a,i,u),dataType:"jsonp",success:function(e){t.each(s([i,e]),function(t,e){var i=e[1];i.original_url=e[0],i.invalid=!1,p.notify(i)})}})}),f.length&&setTimeout(function(){t.each(f,function(t,e){p.notify(e)})},1),p._deferred},oembed:function(t,e){return this.ajax("oembed",t,e)},preview:function(t,e){return this.ajax("preview",t,e)},objectify:function(t,e){return this.ajax("objectify",t,e)}};var l=function(t,e,i){this.init(t,e,i)};l.prototype={init:function(e,i,r){this.elem=e,this.$elem=t(e),this.original_url=i,this.options=r,this.loaded=t.Deferred();var s=this;this.loaded.done(function(){s.$elem.trigger("loaded",[s])}),this.$elem.trigger("initialized",[this])},progress:function(e){t.extend(this,e),this.options.display?this.options.display.apply(this.elem,[this,this.elem]):"oembed"===this.options.endpoint&&this.display(),this.loaded.resolve(this)},imageStyle:function(){var t,e=[];return this.options.addImageStyles&&(this.options.query.maxwidth&&(t=isNaN(parseInt(this.options.query.maxwidth,10))?"":"px",e.push("max-width: "+this.options.query.maxwidth+t)),this.options.query.maxheight&&(t=isNaN(parseInt(this.options.query.maxheight,10))?"":"px",e.push("max-height: "+this.options.query.maxheight+t))),e.join(";")},display:function(){if("error"===this.type)return!1;this.style=this.imageStyle();var t;"photo"===this.type?(t="",t+=""+this.title+""):"video"===this.type||"rich"===this.type?t=this.html:(this.title=this.title||this.url,t=this.thumbnail_url?"":"",t+=""+this.title+"",t+=this.provider_name?""+this.provider_name+"":"",t+=this.description?'
'+this.description+"
":""),this.options.wrapElement&&(t="<"+this.options.wrapElement+' class="'+this.options.className+'">'+t+""),this.code=t,"replace"===this.options.method?this.$elem.replaceWith(this.code):"after"===this.options.method?this.$elem.after(this.code):"afterParent"===this.options.method?this.$elem.parent().after(this.code):"replaceParent"===this.options.method&&this.$elem.parent().replaceWith(this.code),this.$elem.trigger("displayed",[this])}},t.embedly=new a,t.fn.embedly=function(i){if(void 0===i||"object"==typeof i){if(i=t.extend({},n,t.embedly.defaults,"object"==typeof i&&i),e(i.key))return t.embedly.log("error","Embedly jQuery requires an API Key. Please sign up for one at http://embed.ly"),this.each(t.noop);var r={},s=function(e){if(!t.data(t(e),"embedly")){var s=t(e).attr("href"),n=new l(e,s,i);t.data(e,"embedly",n),r.hasOwnProperty(s)?r[s].push(n):r[s]=[n]}},o=this.each(function(){e(t(this).attr("href"))?t(this).find("a").each(function(){e(t(this).attr("href"))||s(this)}):s(this)}),h=t.embedly.ajax(i.endpoint,t.map(r,function(t,e){return e}),i).progress(function(e){t.each(r[e.original_url],function(t,i){i.progress(e)})});return i.progress&&h.progress(i.progress),i.done&&h.done(i.done),o}},t.expr[":"].embedly=function(i){return!e(t(i).data("embedly"))}})(jQuery); \ No newline at end of file diff --git a/ajax/libs/embedly-jquery/package.json b/ajax/libs/embedly-jquery/package.json index 791be6e06..1bb683eca 100755 --- a/ajax/libs/embedly-jquery/package.json +++ b/ajax/libs/embedly-jquery/package.json @@ -1,6 +1,6 @@ { "name": "embedly-jquery", - "version": "3.0.1", + "version": "3.0.2", "filename": "jquery.embedly.min.js", "description": "Embedly - jQuery is a jQuery Library for Embedly that will replace links with content. It follows the oEmbed spec (oembed.com) for content retrieval, while utilizing http://api.embed.ly as a single endpoint.", "homepage": "https://github.com/embedly/embedly-jquery",