From f4e21e4ec3f37586e675b4c86ff9cd2103e383a0 Mon Sep 17 00:00:00 2001 From: alfredolainez Date: Wed, 19 Feb 2014 11:33:03 +0100 Subject: [PATCH 1/2] Added new interface with already loaded dom and html, avoiding the need of an ajax request to get the html code --- ImageResolver.js | 401 ++++++++++++++++++++++++++++------------------- 1 file changed, 240 insertions(+), 161 deletions(-) diff --git a/ImageResolver.js b/ImageResolver.js index a02cc76..6a5ad72 100644 --- a/ImageResolver.js +++ b/ImageResolver.js @@ -48,18 +48,40 @@ window.ImageResolver = (function(){ clbk(null); }; + ImageResolver.prototype.iterateFilters = function(filters, url, dom){ + if (filters.length){ + var result; + for (var i = 0; i < filters.length; i++){ + result = filters[i].directResolve(url, dom); + if (result !== null){ + return result; + } + } + return null; + } else { + return null; + } + }; + ImageResolver.prototype.resolve = function(url, clbk) { var filters = this.filters; this.next(filters, url, clbk); return this; }; + ImageResolver.prototype.directResolve = function(url, dom) { + var filters = this.filters; + return this.iterateFilters(filters, url, dom); + }; + return new ImageResolver(); })(); /** * Plugins + * + * NOTE THAT NOT ALL OF THEM HAVE DIRECT RESOLUTION */ /** @@ -77,6 +99,14 @@ FileExtensionResolver.prototype.resolve = function(url, clbk) { clbk(null); }; +FileExtensionResolver.prototype.directResolve = function(url, dom) { + var pathname = URI(url).pathname(); + if (pathname.match(/(png|jpg|jpeg|gif|bmp|svg)$/i)) { + return url; + } + return null; +}; + /** * Imgur page */ @@ -91,6 +121,14 @@ ImgurPageResolver.prototype.resolve = function(url, clbk) { clbk(null); }; +ImgurPageResolver.prototype.directResolve = function(url, dom) { + var matches = url.match(/http:\/\/(i\.)*imgur.com\/(gallery\/){0,1}(.*)/); + if (matches && matches.length && (-1 === matches[matches.length-1].indexOf('/'))) { + return 'http://i.imgur.com/' + matches[matches.length-1] + '.jpg' ; //@FIXME : image can be gif or png + } + return null; +}; + /** * Imgur album */ @@ -143,6 +181,18 @@ NineGagResolver.prototype.resolve = function(url, clbk) { clbk(null); }; +NineGagResolver.prototype.directResolve = function(url, dom) { + var matches = url.match(/http:\/\/9gag.com\/gag\/(.*)/) || []; + var id; + var image; + if (matches.length) { + id = matches[1]; + image = 'http://d24w6bsrhbeh9d.cloudfront.net/photo/' + id + '_700b.jpg'; + return image; + } + return null; +}; + /** * Instagram page */ @@ -158,6 +208,17 @@ InstagramResolver.prototype.resolve = function(url, clbk) { clbk(null); }; +InstagramResolver.prototype.directResolve = function(url, dom) { + var id = url.match(/http:\/\/instagr(\.am|am\.com)\/p\/([^\/]+)/); + if (id && id.length > 1) { + url = 'http://instagram.com/p/' + id[2] + '/media/?size=l'; + return url; + } + return null; +}; + + + /** * Flickr photo page */ @@ -265,96 +326,100 @@ WebpageResolver.prototype._score = function(image) { return score; }; -WebpageResolver.prototype.resolve = function(url, clbk) { - var self = this; - ImageResolver.fetch( - url, - function(html) { - var images = html.match(/]*)>/g) || []; - var image; - var candidates = []; - var significant_surface = 16*16; - var significant_surface_count = 0; - var tag; - var src; - var surface; - for (var i=0,l=images.length; i significant_surface) { - significant_surface_count++; - } - candidates.push({ - url: src, - surface: surface, - score: self._score(tag) - }); - } +WebpageResolver.prototype._resolveImageLazily = function(url, html) { + var images = html.match(/]*)>/g) || []; + var image; + var candidates = []; + var significant_surface = 16*16; + var significant_surface_count = 0; + var tag; + var src; + var surface; + for (var i=0,l=images.length; i= 0); - }); - if (!candidates.length) { - clbk(null); - return; + if (tag.attributes['data-lazy-src']) { + src = tag.attributes['data-lazy-src']; + } + if (!src){ + continue; } - //Sort candidates by size, or score - if (significant_surface_count > 0) { - candidates = candidates.sort(function(a,b){ - return b.surface - a.surface; - }); + // Compute surface area, even when only 1 dimension is specified + if (tag.attributes.width) { + if (tag.attributes.height) { + surface = parseInt(tag.attributes.width, 10) * parseInt(tag.attributes.height,10); + } else { + surface = parseInt(tag.attributes.width, 10); + } } else { - candidates = candidates.sort(function(a,b){ - return b.score - a.score; - }); + if (tag.attributes.height) { + surface = parseInt(tag.attributes.height,10); + } else { + surface = 0; + } } - image = candidates[0].url; - //Resolve relative url - if (!image.match(/^http/)) { - var uri = new URI(image); - image = uri.absoluteTo(url); + if (surface > significant_surface) { + significant_surface_count++; } - clbk(image); + candidates.push({ + url: src, + surface: surface, + score: this._score(tag) + }); + } + } + + if (!candidates.length) { + return null + } + + //Remove scores below 0 + candidates = candidates.filter(function(item){ + return (item.score >= 0); + }); + if (!candidates.length) { + return null; + } + + //Sort candidates by size, or score + if (significant_surface_count > 0) { + candidates = candidates.sort(function(a,b){ + return b.surface - a.surface; + }); + } else { + candidates = candidates.sort(function(a,b){ + return b.score - a.score; + }); + } + image = candidates[0].url; + //Resolve relative url + if (!image.match(/^http/)) { + var uri = new URI(image); + image = uri.absoluteTo(url); + } + + return image; +}; + +WebpageResolver.prototype.resolve = function(url, clbk) { + self = this; + ImageResolver.fetch( + url, + function(html) { + clbk(self._resolveImageLazily(url, html)); return; }, function() { @@ -364,97 +429,107 @@ WebpageResolver.prototype.resolve = function(url, clbk) { ); }; +WebpageResolver.prototype.directResolve = function(url, dom) { + return this._resolveImageLazily(url, dom.documentElement.innerHTML) +}; + + /** * Opengraph meta tags */ function OpengraphResolver() { } -OpengraphResolver.prototype.resolve = function(url, clbk) { - var self = this; - ImageResolver.fetch( - url, - function(html) { - // @TODO : add - var meta = html.match(/<(meta|link)([^>]*)>/g) || []; - var tag; - var images = []; - var image = null; - var tags = [ - // Facebook, Google+ - { - type: "facebook", - attribute : "property", - name : "og:image", - value : "content" - }, - // Old Facebook - { - type: "facebook", - attribute : "rel", - name : "image_src", - value : "href" - }, - // Old Twitter card - { - type: "twitter", - attribute : "name", - name : "twitter:image", - value : "value" - }, - // New Twitter card - { - type: "twitter", - attribute : "name", - name : "twitter:image", - value : "content" - } - ]; - - for (var i=0,l=meta.length; i + var meta = html.match(/<(meta|link)([^>]*)>/g) || []; + var tag; + var images = []; + var image = null; + var tags = [ + // Facebook, Google+ + { + type: "facebook", + attribute : "property", + name : "og:image", + value : "content" + }, + // Old Facebook + { + type: "facebook", + attribute : "rel", + name : "image_src", + value : "href" + }, + // Old Twitter card + { + type: "twitter", + attribute : "name", + name : "twitter:image", + value : "value" + }, + // New Twitter card + { + type: "twitter", + attribute : "name", + name : "twitter:image", + value : "content" + } + ]; + + for (var i=0,l=meta.length; i 1) { - for (i=0, l=images.length; i 1) { + for (i=0, l=images.length; i Date: Wed, 19 Feb 2014 12:02:09 +0100 Subject: [PATCH 2/2] Readme updated --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 913e8b3..bf788fd 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,18 @@ The API might break in the future. ImageResolver.resolve(url, callback); +If you already have access to the DOM of the page you can call directResolve, thus avoiding the extra GET request for the html code neccesary in some of the plugins. Furthermore, this gives a direct result without needing any callback. Note that this won't work in plugins requiring more ajax calls than the original html fetch. + + + + + Dependencies ------------