Commit dc59cb43
Changed files (4)
app
assets
javascripts
backbone
views
tutorials
service
views
my
kitchens
vendor
assets
javascripts
app/assets/javascripts/backbone/views/tutorials/new_view.js.coffee
@@ -30,7 +30,7 @@ class CakeSide.Views.Tutorials.NewView extends Marionette.ItemView
url: attributes.url
heading: attributes.title
description: attributes.description
- image_url: attributes.thumbnail_url
+ image_url: if _.any(attributes.images) then attributes.images[0].url else ''
author: attributes.provider_name
author_url: attributes.provider_url
app/assets/javascripts/service/embedly_service.js.coffee
@@ -1,3 +1,3 @@
class window.EmbedlyService
retrieve_info_on: (url, callback) ->
- $.embedly(url, {}, callback)
+ $.embedly.extract(url, {}).progress(callback)
app/views/my/kitchens/show.html.erb
@@ -10,7 +10,7 @@
};
CakeSide.initialize({
access_token: '<%= current_user.authentication_token %>',
- disqus_shortname: disqus_shortname
+ disqus_shortname: disqus_shortname,
});
<% end %>
<% end %>
vendor/assets/javascripts/jquery.embedly.js
@@ -1,254 +1,527 @@
-/*
- * Embedly JQuery v2.2.0
- * ==============
- * This library allows you to easily embed objects on any page.
- *
- * Requirements:
- * -------------
- * jquery-1.3 or higher
- *
- * Usage:
- * ------
- * There are two ways to interact with this lib. One exposes a simple method to call embedly directly
- *
- * >>> $.embedly('http://www.youtube.com/watch?v=LfamTmY5REw', {}, function(oembed){ alert(oembed.title);});
- *
- * The oembed is either a json object or null
- *
- * You can also reference it this way, which will try and replace every link on the page with an embed
- *
- * Documentation is availiable at http://github.com/embedly/embedly-jquery
- *
- * $('a').embedly();
- *
- * The Options Are as Follows
- *
- * endpoint: 'oembed', // default endpoint is oembed (preview and objectify available too)
- * chars: null, // Default number of characters in description
- * words: null, // Default number of words in description
- * maxWidth: null, // force a maxWidth on all returned media
- * maxHeight: null, // force a maxHeight on all returned media
- * secure: false, // use https endpoint vs http
- * frame: false, // serves all embeds within an iframe to avoid XSS issues
- * wmode: 'opaque', // for flash elements set a wmode
- * autoplay: null, // tell videos to autoplay
- * width: null, // force a width on all video/rich media
- * method: 'replace', // embed handling option for standard callback
- * addImageStyles: true, // add style="" attribute to images for maxWidth and maxHeight
- * wrapElement: 'div', // standard wrapper around all returned embeds
- * className: 'embed', // class on the wrapper element
- * urlRe: null, // custom regex function
- * key: null, // an embed.ly key
- * elems: [], // array to hold nodes
- * success: null, // default callback
- * error: null // error-handling function
- *
- * http://api.embed.ly/tools/generator - generate your own regex for only sources you want
- *
- */
-
- (function($){
- window.embedlyURLre = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
-
- $.embedly = $.embedly || {};
- if ( $.embedly.version ) { return; }
-
- $.extend({
- embedly: function(urls, options, callback){
- var elems = [];
- var path = "https://api.embed.ly/";
-
- var settings;
- options = options ? options : {};
- settings = $.extend({}, $.embedly.defaults, options);
- if (!settings.urlRe) {settings.urlRe = window.embedlyURLre; }
- if (typeof urls === "string"){ urls = new Array(urls); }
- if (typeof callback !== "undefined"){ settings.success = callback; }
- if (settings.secure){ path = 'https://api.embed.ly/';}
- if (!settings.success) {
- settings.success = function(oembed, dict){
- var _a, elem = $(dict.node);
- if (! (oembed) ) { return null; }
- if ((_a = settings.method) === 'replace') { return elem.replaceWith(oembed.code); }
- else if (_a === 'after') { return elem.after(oembed.code); }
- else if (_a === 'afterParent') { return elem.parent().after(oembed.code); }
- else if (_a === 'replaceParent') { return elem.parent().replaceWith(oembed.code); }
- };
- }
- if (!settings.error) {
- settings.error = function(node, dict){
- // we don't by default handle error cases
- // node is the jQuery representation of the <a> tag
- // dict contains error information
- };
- }
- var urlValid = function(url){
- return settings.urlRe.test(url);
- };
-
- var getParams = function(urls){
- var _p = "urls="+urls;
- if (settings.maxWidth) {_p += '&maxwidth='+ settings.maxWidth;}
- else if (typeof dimensions !== "undefined") { _p += '&maxwidth='+ dimensions.width;}
- if (settings.maxHeight) {_p += '&maxheight=' +settings.maxHeight;}
- if (settings.chars) {_p += '&chars='+ settings.chars;}
- if (settings.words) {_p += '&words='+ settings.words;}
- if (settings.secure) {_p += '&secure=true';}
- if (settings.frame) {_p += '&frame=true';}
- _p += '&wmode='+ settings.wmode;
- if (typeof settings.key === "string"){ _p += "&key="+settings.key;}
- if (typeof settings.autoplay === "string" || typeof settings.autoplay === "boolean"){ _p += "&autoplay="+settings.autoplay;}
- if (settings.width){_p += "&width="+settings.width;}
- return _p;
- };
- var getUrl = function(){
- if (typeof settings.key === "string"){
- if (settings.endpoint.search(/objectify/i) >= 0){
- return path + '2/objectify';
- }
- else if (settings.endpoint.search(/preview/i) >= 0){
- return path + '1/preview';
- }
- }
- return path + "1/oembed";
- };
-
- var createImageStyle = function() {
- var style = [];
- if (settings.addImageStyles) {
- if (settings.maxWidth) {
- units = isNaN(parseInt(settings.maxWidth, 10)) ? '' : 'px';
- style.push("max-width: " + (settings.maxWidth)+units);
- }
- if (settings.maxHeight) {
- units = isNaN(parseInt(settings.maxHeight,10)) ? '' : 'px';
- style.push("max-height: " + (settings.maxHeight)+units);
- }
- }
- return style.join(';');
- }
+/*! Embedly jQuery - v3.1.1 - 2013-06-05
+ * https://github.com/embedly/embedly-jquery
+ * Copyright (c) 2013 Sean Creeley
+ * Licensed BSD
+ */
+(function($) {
- var processEmbed = function(oembed, dict) {
- // bypass any embed processing for preview, objectify endpoints
- // for advanced users only
- if(settings.endpoint !== 'oembed'){
- return settings.success(oembed, dict);
- }
-
- var _a, code, style, title, units, thumb, provider, description;
- if ((_a = oembed.type) === 'photo') {
- title = oembed.title || '';
- code = "<a href='" + dict.url + "' target='_blank'><img style='" + createImageStyle() + "' src='" + oembed.url + "' alt='" + title + "' /></a>";
- } else if (_a === 'video') {
- code = oembed.html;
- } else if (_a === 'rich') {
- code = oembed.html;
- } else {
- title = oembed.title || dict.url;
- thumb = oembed.thumbnail_url ? "<img src='"+oembed.thumbnail_url+"' class='thumb' style='" + createImageStyle() + "'/>" : "";
- description = oembed.description ? '<div class="description">'+oembed.description+'</div>' : '';
- provider = oembed.provider_name ? "<a href='" + oembed.provider_url + "' class='provider'>" + oembed.provider_name + "</a>" : "";
- code = thumb + "<a href='" + dict.url + "'>" + title + "</a>";
- code += provider;
- code += description;
- }
- if (settings.wrapElement && settings.wrapElement === 'div' && $.browser.msie && $.browser.version < 9){
- settings.wrapElement = 'span';
- }
- if (settings.wrapElement) {
- code = '<' + settings.wrapElement+ ' class="'+settings.className+'">' + code + '</'+settings.wrapElement+'>';
- }
- oembed.code = 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.
- if (typeof dict.node !== "undefined") { $(dict.node).data('oembed', oembed).trigger('embedly-oembed', [oembed]); }
- return settings.success(oembed, dict);
- };
-
- var processBatch = function(batch){
- var data, embed, urls, dimensions, node;
- urls = $.map(batch,
- function(e, i) {
- if (i === 0) {
- if ( e.node !== null){
- node = $(e.node);
- dimensions = {
- "width": node.parent().width(),
- "height": node.parent().height()
- };
- }
- }
- return encodeURIComponent(e.url);
- }).join(',');
- $.ajax({
- url: getUrl(),
- dataType: 'jsonp',
- data: getParams(urls),
- success: function(data) {
- return $.each(data,
- function(index, elem) {
- return elem.type !== 'error' ? processEmbed(elem, batch[index]) : settings.error(batch[index].node, elem);
- });
- }
- });
- };
- $.each(urls, function(i, v){
- var node = typeof settings.elems !== "undefined" ? settings.elems[i] : null;
- if(typeof node !== "undefined" && !urlValid(v)){
- $(node).data('oembed', false);
- }
- var err = {url: v, error_code:400, error_message:'HTTP 400: Bad Request', type:'error'};
- return (v && urlValid(v)) ? elems.push({'url':v, 'node':node }) : settings.error(node, err);
- });
- var _a = [];
- var _b = elems.length;
- for (var i = 0; (0 <= _b ? i < _b: i > _b); i += 20) {
- _a = _a.concat(processBatch(elems.slice(i, i + 20)));
- }
- if(settings.elems){
- return settings.elems;
- } else {
- return this;
+ /*
+ * 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#!:.?+=&%@!\-\/]))?/;
+
+ var none = function(obj){
+ return obj === null || obj === undefined;
+ };
+ // Split a list into a bunch of batchs.
+ var batch = function(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
+ var listify = function(obj){
+ if (none(obj)){
+ return [];
+ } else if (!$.isArray(obj)){
+ return [obj];
+ }
+ return obj;
+ };
+
+ // From: http://bit.ly/T9SjVv
+ var zip = function(arrays) {
+ return $.map(arrays[0], function(_,i){
+ return [$.map(arrays, 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 = $.map(this.urls, 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='+ $.map(urls, 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);
+ },
+ extract: function(urls, options){
+ return this.ajax('extract', urls, options);
+ }
+ };
+
+ // direct API dealing directly with Embedly's Display API.
+ var ImageAPI = function () {};
+ ImageAPI.prototype = {
+
+ // Based on the method and options, build the image url,
+ build: function(method, url, options){
+ options = $.extend({}, $.embedly.defaults, typeof options === 'object' && options);
+
+ var secure = options.secure;
+ if (none(secure)){
+ // If the secure param was not seen, use the protocol instead.
+ secure = window.location.protocol === 'https:'? true:false;
+ }
+
+ var base = (secure ? 'https': 'http') +
+ '://i.embed.ly/' + (method === 'display' ? '1/' : '1/display/') + method;
+
+ // Base Query
+ var query = none(options.query) ? {} : options.query;
+ query.key = options.key;
+ base += '?'+$.param(query);
+
+ // Add the image url
+ base += '&url='+ encodeURIComponent(url);
+
+ return base;
+ },
+ // Wrappers around build image url function.
+ display: function(url, options){
+ return this.build('display', url, options);
+ },
+ resize: function(url, options){
+ return this.build('resize', url, options);
+ },
+ fill: function(url, options){
+ return this.build('fill', url, options);
+ },
+ crop: function(url, options){
+ return this.build('crop', url, 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);
+ }
}
- }
- });
-
- // Versions
- $.embedly.version = "2.2.0";
-
- // Once the function is we can add defaults as an attribute
- $.embedly.defaults = {
- endpoint: 'oembed', // default endpoint is oembed (preview and objectify available too)
- secure: false, // use https endpoint vs http
- frame: false, // serves all embeds within an iframe to avoid XSS issues
- wmode: 'opaque', // for flash elements set a wmode
- method: 'replace', // embed handling option for standard callback
- addImageStyles: true, // add style="" attribute to images for maxWidth and maxHeight
- wrapElement: 'div', // standard wrapper around all returned embeds
- className: 'embed', // class on the wrapper element
- elems: []
- };
-
- $.fn.embedly = function(options, callback){
- var settings = typeof options !== "undefined" ? options : {};
- // callback is a legacy option, we should be moving towards including a success method in the options
- if (typeof callback !== "undefined") {options.success = callback; }
- //settings.elems = this;
- var urls = new Array();
- var nodes = new Array();
- this.each(function(){
- if (typeof $(this).attr('href') !== "undefined"){
- urls.push($(this).attr('href'));
- nodes.push($(this));
- } else {
- $(this).find('a').each(function(){
- urls.push($(this).attr('href'));
- nodes.push($(this));
- });
- }
- settings.elems = nodes;
- });
- var elems = $.embedly(urls, settings);
- return this;
- };
- })(jQuery);
+ 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 = "<a href='" + this.original_url + "' target='_blank'>";
+ html += "<img style='" + this.style + "' src='" + this.url + "' alt='" + this.title + "' /></a>";
+ } else if (this.type === 'video' || this.type === 'rich'){
+ html = this.html;
+ } else {
+ this.title = this.title || this.url;
+ html = this.thumbnail_url ? "<img src='" + this.thumbnail_url + "' class='thumb' style='" + this.style + "'/>" : "";
+ html += "<a href='" + this.original_url + "'>" + this.title + "</a>";
+ html += this.provider_name ? "<a href='" + this.provider_url + "' class='provider'>" + this.provider_name + "</a>" : "";
+ html += this.description ? '<div class="description">' + this.description + '</div>' : '';
+ }
+
+ if (this.options.wrapElement) {
+ html = '<' + this.options.wrapElement+ ' class="' + this.options.className + '">' + html + '</' + this.options.wrapElement + '>';
+ }
+
+ 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();
+
+ // Add display to it.
+ $.embedly.display = new ImageAPI();
+
+ $.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'));
+ };
+
+ // Use with selector to find img tags with data-src attribute
+ // e.g. <img data-src="http://embed.ly/static/images/logo.png"></img>
+ $.fn.display = function (endpoint, options) {
+
+ // default to display
+ if (none(endpoint)) {
+ endpoint = 'display';
+ }
+
+ if (options === undefined || typeof options === 'object') {
+
+ // Use the defaults
+ options = $.extend({}, defaults, $.embedly.defaults, typeof options === 'object' && options);
+
+ // Key Check.
+ if (none(options.key)){
+ $.embedly.log('error', 'Embedly jQuery requires an API Key. Please sign up for one at http://embed.ly/display');
+ return this.each($.noop);
+ }
+
+ // Create the node for all elements
+ var create = function (elem){
+ var $elem = $(elem);
+ if (!$elem.data('display')) {
+ var url = $elem.data('src') || $elem.attr('href');
+
+ var data = {
+ original_url : url,
+ url : $.embedly.display.build(endpoint, url, options)
+ };
+
+ $elem.data('display', data);
+ $elem.trigger('initialized', [elem]);
+
+ var html = "<img src='" + data.url + "' />";
+ if ($elem.is('a')){
+ $elem.append(html);
+ }else {
+ $elem.replaceWith(html);
+ }
+ }
+ };
+ var doCreate = function(elem){
+ if (none($(elem).data('src')) && none($(elem).attr('href'))){
+ return false;
+ }
+ return true;
+ };
+
+ // Find every image or a tag with a data-src attribute
+ var elems = this.each(function () {
+ if ( doCreate(this) ){
+ create(this);
+ } else {
+ $(this).find('img,a').each(function(){
+ if ( doCreate(this) ){
+ create(this);
+ }
+ });
+ }
+ });
+
+ return elems;
+ }
+ };
+
+ // Custom selector.
+ $.expr[':'].display = function(elem) {
+ return ! none($(elem).data('display'));
+ };
+
+}(jQuery, window));