photon
Advanced tools
Comparing version 1.0.3 to 1.0.4
@@ -45,19 +45,24 @@ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;"undefined"!=typeof window?o=window:"undefined"!=typeof global?o=global:"undefined"!=typeof self&&(o=self),o.photon=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
// strip any leading `http(s)://` | ||
imageUrl = imageUrl.replace(/^https?\:\/\/(i\d.wp.com\/)?/i, ''); | ||
// parse the URL, assuming //host.com/path style URLs are ok and parse the querystring | ||
var parsedUrl = url.parse( imageUrl, true, true ); | ||
// determine which Photon server to connect to: `i0`, `i1`, or `i2`. | ||
// statically hash the subdomain based on the URL, to optimize browser caches. | ||
var hash = crc32(imageUrl); | ||
var rng = seed(hash); | ||
var server = 'i' + Math.floor(rng() * 3); | ||
debug('determined server "%s" to use with "%s"', server, imageUrl); | ||
delete parsedUrl.protocol; | ||
delete parsedUrl.auth; | ||
delete parsedUrl.port; | ||
var params = { | ||
slashes: true, | ||
pathname: imageUrl, | ||
protocol: 'https:', | ||
hostname: server + '.wp.com' | ||
protocol: 'https:' | ||
}; | ||
if ( isAlreadyPhotoned( parsedUrl.host ) ) { | ||
// We already have a server to use. | ||
// Use it, even if it doesn't match our hash. | ||
params.pathname = parsedUrl.pathname; | ||
params.hostname = parsedUrl.hostname; | ||
} else { | ||
params.pathname = url.format( parsedUrl ).substring(1); | ||
params.hostname = serverFromPathname( params.pathname ); | ||
} | ||
if (opts) { | ||
@@ -85,10 +90,2 @@ for (var i in opts) { | ||
// prevent inception (attempting to Photon-ify a link that | ||
// already is already pointing to the Photon hostname) | ||
var h = params.hostname + '/'; | ||
if (0 === params.pathname.indexOf(h)) { | ||
debug('preventing Photon URL "inception", stripping leading "%s"', h); | ||
params.pathname = params.pathname.substring(h.length); | ||
} | ||
var photonUrl = url.format(params); | ||
@@ -99,2 +96,22 @@ debug('generated Photon URL: %s', photonUrl); | ||
function isAlreadyPhotoned( host ) { | ||
return /^i[0-2]\.wp\.com$/.test(host); | ||
} | ||
/** | ||
* Determine which Photon server to connect to: `i0`, `i1`, or `i2`. | ||
* | ||
* Statically hash the subdomain based on the URL, to optimize browser caches. | ||
* @param {string} pathname The pathname to use | ||
* @return {string} The hostname for the pathname | ||
*/ | ||
function serverFromPathname( pathname ) { | ||
var hash = crc32(pathname); | ||
var rng = seed(hash); | ||
var server = 'i' + Math.floor(rng() * 3); | ||
debug('determined server "%s" to use with "%s"', server, pathname); | ||
return server + '.wp.com'; | ||
} | ||
},{"crc32":7,"debug":8,"seed-random":11,"url":6}],2:[function(require,module,exports){ | ||
@@ -101,0 +118,0 @@ (function (global){ |
1.0.4 / 2015-01-26 | ||
================== | ||
* package: allow any "debug" v2 | ||
* package: update "browserify" to v8.1.1 | ||
* Fix how querystrings are dealt with for photon hosts, protcolless URLs (#3, @blowery) | ||
1.0.3 / 2014-12-20 | ||
@@ -3,0 +10,0 @@ ================== |
55
index.js
@@ -44,19 +44,24 @@ | ||
// strip any leading `http(s)://` | ||
imageUrl = imageUrl.replace(/^https?\:\/\/(i\d.wp.com\/)?/i, ''); | ||
// parse the URL, assuming //host.com/path style URLs are ok and parse the querystring | ||
var parsedUrl = url.parse( imageUrl, true, true ); | ||
// determine which Photon server to connect to: `i0`, `i1`, or `i2`. | ||
// statically hash the subdomain based on the URL, to optimize browser caches. | ||
var hash = crc32(imageUrl); | ||
var rng = seed(hash); | ||
var server = 'i' + Math.floor(rng() * 3); | ||
debug('determined server "%s" to use with "%s"', server, imageUrl); | ||
delete parsedUrl.protocol; | ||
delete parsedUrl.auth; | ||
delete parsedUrl.port; | ||
var params = { | ||
slashes: true, | ||
pathname: imageUrl, | ||
protocol: 'https:', | ||
hostname: server + '.wp.com' | ||
protocol: 'https:' | ||
}; | ||
if ( isAlreadyPhotoned( parsedUrl.host ) ) { | ||
// We already have a server to use. | ||
// Use it, even if it doesn't match our hash. | ||
params.pathname = parsedUrl.pathname; | ||
params.hostname = parsedUrl.hostname; | ||
} else { | ||
params.pathname = url.format( parsedUrl ).substring(1); | ||
params.hostname = serverFromPathname( params.pathname ); | ||
} | ||
if (opts) { | ||
@@ -84,10 +89,2 @@ for (var i in opts) { | ||
// prevent inception (attempting to Photon-ify a link that | ||
// already is already pointing to the Photon hostname) | ||
var h = params.hostname + '/'; | ||
if (0 === params.pathname.indexOf(h)) { | ||
debug('preventing Photon URL "inception", stripping leading "%s"', h); | ||
params.pathname = params.pathname.substring(h.length); | ||
} | ||
var photonUrl = url.format(params); | ||
@@ -97,1 +94,21 @@ debug('generated Photon URL: %s', photonUrl); | ||
} | ||
function isAlreadyPhotoned( host ) { | ||
return /^i[0-2]\.wp\.com$/.test(host); | ||
} | ||
/** | ||
* Determine which Photon server to connect to: `i0`, `i1`, or `i2`. | ||
* | ||
* Statically hash the subdomain based on the URL, to optimize browser caches. | ||
* @param {string} pathname The pathname to use | ||
* @return {string} The hostname for the pathname | ||
*/ | ||
function serverFromPathname( pathname ) { | ||
var hash = crc32(pathname); | ||
var rng = seed(hash); | ||
var server = 'i' + Math.floor(rng() * 3); | ||
debug('determined server "%s" to use with "%s"', server, pathname); | ||
return server + '.wp.com'; | ||
} | ||
{ | ||
"name": "photon", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"description": "JavaScript library for the WordPress.com Photon image manipulation service", | ||
@@ -35,9 +35,9 @@ "main": "index.js", | ||
"crc32": "0.2.2", | ||
"debug": "~1.0.0", | ||
"debug": "2", | ||
"seed-random": "2.2.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "6.1.0", | ||
"browserify": "8.1.1", | ||
"mocha": "1.20.0" | ||
} | ||
} |
@@ -8,7 +8,28 @@ | ||
var assert = require('assert'); | ||
var parseUrl = require('url').parse; | ||
function assertHostedOnPhoton( url ) { | ||
assert(RegExp('^https://i[0-2].wp.com').test(url)); | ||
} | ||
function assertHostedOnPhotonInsecurely( url ) { | ||
assert(RegExp('^http://i[0-2].wp.com').test(url)); | ||
} | ||
function assertPathname ( url, expected ) { | ||
var parsedUrl = parseUrl(url, true, true); | ||
assert.strictEqual(parsedUrl.pathname, expected); | ||
} | ||
function assertQuery ( url, expected ) { | ||
var query = parseUrl(url, true, true).query, | ||
key; | ||
assert.deepEqual(query, expected); | ||
} | ||
describe('photon()', function () { | ||
it('should be a "function"', function () { | ||
assert('function' === typeof photon); | ||
assert.strictEqual(typeof photon, 'function'); | ||
}); | ||
@@ -18,9 +39,73 @@ | ||
var url = 'http://example.com/image.png'; | ||
assert(RegExp('https://i[0-2].wp.com/example.com/image.png').test(photon(url))); | ||
}); | ||
it('should not Photon-ify a Photon URL', function () { | ||
var url = 'https://i0.wp.com/www.gravatar.com/avatar/693307b4e0cb9366f34862c9dfacd7fc'; | ||
assert(photon(url) === url); | ||
it('should not Photon-ify an existing Photon URL, even if the host is wrong', function () { | ||
var photonedUrl = photon('http://www.gravatar.com/avatar/693307b4e0cb9366f34862c9dfacd7fc'); | ||
var alternateUrl = 'https://i1.wp.com/www.gravatar.com/avatar/693307b4e0cb9366f34862c9dfacd7fc'; | ||
assertHostedOnPhoton(photonedUrl); | ||
assert.notStrictEqual(alternateUrl, photonedUrl); | ||
assert.strictEqual(alternateUrl, photon(alternateUrl)); | ||
}); | ||
it('should handle photoning a photoned url', function() { | ||
var url = photon('http://example.com/image.png'); | ||
assert.strictEqual(url, photon(url)); | ||
}); | ||
it('should add width parameters if specified', function() { | ||
var photonedUrl = photon('http://example.com/image.png', { width: 50 }); | ||
var parsedUrl = parseUrl(photonedUrl, true, true); | ||
assertQuery(photonedUrl, { 'w':'50' }); | ||
}); | ||
it('should encode query args for non-photon hosts', function() { | ||
var photonedUrl = photon('http://example.com/image.png?foo=bar'); | ||
assertPathname(photonedUrl, '/example.com/image.png%3Ffoo=bar'); | ||
}); | ||
it('should handle protocolless URLs', function() { | ||
var url = '//example.com/image.png'; | ||
var photonedUrl = photon(url); | ||
assertHostedOnPhoton( photonedUrl ); | ||
assertPathname(photonedUrl, '/example.com/image.png'); | ||
}); | ||
it('should strip existing size params from photoned URLs', function () { | ||
var url = 'https://i0.wp.com/www.gravatar.com/avatar/693307b4e0cb9366f34862c9dfacd7fc?resize=120'; | ||
var photonedUrl = photon(url, { width: 150, height: 300 }); | ||
assertHostedOnPhoton(photonedUrl); | ||
assertPathname(photonedUrl, '/www.gravatar.com/avatar/693307b4e0cb9366f34862c9dfacd7fc'); | ||
assertQuery(photonedUrl, { w: '150', h: '300' }); | ||
}); | ||
it('should allow you to do everything at once', function() { | ||
var url = 'https://i0.wp.com/example.com/foo.png?w=50&lb=10&unknown=true'; | ||
var photonedUrl = photon(url, { | ||
width: 10, | ||
height: 20, | ||
letterboxing: '120,120', | ||
removeLetterboxing: true | ||
}); | ||
assertHostedOnPhoton( photonedUrl ); | ||
assertPathname( photonedUrl, '/example.com/foo.png' ); | ||
assertQuery( photonedUrl, { w: '10', h: '20', 'lb': '120,120', ulb: 'true' }); | ||
}); | ||
it('should allow you to turn off https', function() { | ||
var photonedUrl = photon('http://example.com/foo.png', { secure: false }); | ||
assertHostedOnPhotonInsecurely(photonedUrl); | ||
photonedUrl = photon('https://i0.wp.com/example.com/foo.png', { secure: false }); | ||
assertHostedOnPhotonInsecurely(photonedUrl); | ||
}); | ||
}); |
74869
2116
+ Addeddebug@2.6.9(transitive)
- Removeddebug@1.0.5(transitive)
Updateddebug@2