diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fe61ec..d21421a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +### [1.0.0](https://github.com/jmeas/backbone.radio/releases/tag/v1.0.0) + +- **Enhancement**: Adds support for multiple query parameters of the same name. They + are returned as an array. + +### [0.5.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.0) + +- Updated Backbone dependency +- Tests against multiple versions of Backbone/Underscore + ### [0.4.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.4.1) - **Bug fix**: Uses the constructor on the Router's prototype diff --git a/bower.json b/bower.json index 970666d..0952ced 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "backbone.base-router", - "version": "0.5.0", + "version": "1.0.0", "homepage": "https://github.com/jmeas/backbone.base-router", "authors": [ "Jmeas " diff --git a/dist/backbone.base-router.js b/dist/backbone.base-router.js index d7af9f4..0cdd195 100644 --- a/dist/backbone.base-router.js +++ b/dist/backbone.base-router.js @@ -1,4 +1,4 @@ -// Backbone.BaseRouter v0.5.0 +// Backbone.BaseRouter v1.0.0 (function(root, factory) { if (typeof define === 'function' && define.amd) { define(['backbone', 'underscore'], function(Backbone, _) { @@ -20,8 +20,10 @@ // Backbone.BaseRouter // - // Copied over from Backbone, because it doesn't expose them. - var namedParam = /(\(\?)?:\w+/g; + // This is copied over from Backbone, because it doesn't expose it + var NAMED_PARAM = /(\(\?)?:\w+/g; + // Find plus symbols + var PLUS_SYMBOL = /\+/g; Backbone.BaseRouter = Backbone.Router.extend({ constructor: function() { @@ -81,7 +83,7 @@ _extractRouteParams: function(route) { var namedParams = []; - route.replace(namedParam, function(match, optional) { + route.replace(NAMED_PARAM, function(match, optional) { namedParams.push(match.substr(1)); }); @@ -94,20 +96,33 @@ _getQueryParameters: function(queryString) { if (!queryString) { return {}; } - var match; - var search = /([^&=]+)=?([^&]*)/g; - var urlParams = {}; - - while (match = search.exec(queryString)) { - urlParams[this._decodeParams(match[1])] = this._decodeParams(match[2]); - } - - return urlParams; - }, - - _decodeParams: function (queryString) { - // Replace addition symbol with a space - return decodeURIComponent(queryString.replace(/\+/g, ' ')); + return _.reduce(queryString.split('&'), function(memo, param) { + var parts = param.replace(PLUS_SYMBOL, ' ').split('='); + var key = parts[0]; + var val = parts[1]; + + key = decodeURIComponent(key); + val = val === undefined ? null : decodeURIComponent(val); + + // If we don't have the value, then we set it. + if (!memo[key]) { + memo[key] = val; + } + + // Otherwise, if we have the value, and it's an array, + // then we push to it. + else if (_.isArray(memo[key])) { + memo[key].push(val); + } + + // Otherwise, we have a value that is not yet an array, + // so we convert it to an array, adding the newest value. + else { + memo[key] = [memo[key], val]; + } + + return memo; + }, {}); }, // Returns the named parameters of the route diff --git a/dist/backbone.base-router.min.js b/dist/backbone.base-router.min.js index 534e250..69cf1da 100644 --- a/dist/backbone.base-router.min.js +++ b/dist/backbone.base-router.min.js @@ -1,4 +1,4 @@ -// Backbone.BaseRouter v0.5.0 +// Backbone.BaseRouter v1.0.0 -!function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=/(\(\?)?:\w+/g;return a.BaseRouter=a.Router.extend({constructor:function(){this.routeParams={},a.Router.prototype.constructor.apply(this,arguments)},onNavigate:function(){},route:function(c,d){var e,f;b.isRegExp(c)?(e=c,f=""+c):(e=this._routeToRegExp(c),f=c),this.routeParams[c]=this._extractRouteParams(f);var g={route:e,router:this,linked:d};b.isRegExp(c)||(g.originalRoute=c);var h=this;return a.history.route(e,function(a,b){var c=h._extractParameters(e,a),d=c.pop();b&&(g.navOptions=b),g.query=h._getQueryParameters(d),g.params=h._getNamedParams(f,c),g.uriFragment=a,h.onNavigate(g)}),this},_extractRouteParams:function(a){var b=[];return a.replace(c,function(a){b.push(a.substr(1))}),b},_getQueryParameters:function(a){if(!a)return{};for(var b,c=/([^&=]+)=?([^&]*)/g,d={};b=c.exec(a);)d[this._decodeParams(b[1])]=this._decodeParams(b[2]);return d},_decodeParams:function(a){return decodeURIComponent(a.replace(/\+/g," "))},_getNamedParams:function(a,c){if(!c.length)return{};var d=this.routeParams[a],e=c.slice(0,d.length);return b.object(b.zip(d,e))}}),a.BaseRouter}); +!function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=/(\(\?)?:\w+/g,d=/\+/g;return a.BaseRouter=a.Router.extend({constructor:function(){this.routeParams={},a.Router.prototype.constructor.apply(this,arguments)},onNavigate:function(){},route:function(c,d){var e,f;b.isRegExp(c)?(e=c,f=""+c):(e=this._routeToRegExp(c),f=c),this.routeParams[c]=this._extractRouteParams(f);var g={route:e,router:this,linked:d};b.isRegExp(c)||(g.originalRoute=c);var h=this;return a.history.route(e,function(a,b){var c=h._extractParameters(e,a),d=c.pop();b&&(g.navOptions=b),g.query=h._getQueryParameters(d),g.params=h._getNamedParams(f,c),g.uriFragment=a,h.onNavigate(g)}),this},_extractRouteParams:function(a){var b=[];return a.replace(c,function(a){b.push(a.substr(1))}),b},_getQueryParameters:function(a){return a?b.reduce(a.split("&"),function(a,c){var e=c.replace(d," ").split("="),f=e[0],g=e[1];return f=decodeURIComponent(f),g=void 0===g?null:decodeURIComponent(g),a[f]?b.isArray(a[f])?a[f].push(g):a[f]=[a[f],g]:a[f]=g,a},{}):{}},_getNamedParams:function(a,c){if(!c.length)return{};var d=this.routeParams[a],e=c.slice(0,d.length);return b.object(b.zip(d,e))}}),a.BaseRouter}); //# sourceMappingURL=backbone.base-router.min.js.map \ No newline at end of file diff --git a/dist/backbone.base-router.min.js.map b/dist/backbone.base-router.min.js.map index 8c67ce6..f25ad9a 100644 --- a/dist/backbone.base-router.min.js.map +++ b/dist/backbone.base-router.min.js.map @@ -1 +1 @@ -{"version":3,"file":"backbone.base-router.min.js","sources":["backbone.base-router.js"],"names":["root","factory","define","amd","Backbone","_","exports","require","module","this","namedParam","BaseRouter","Router","extend","constructor","routeParams","prototype","apply","arguments","onNavigate","route","origRoute","linked","routeStr","isRegExp","_routeToRegExp","_extractRouteParams","routeData","router","originalRoute","history","fragment","navOptions","_extractParameters","queryString","pop","query","_getQueryParameters","params","_getNamedParams","uriFragment","namedParams","replace","match","push","substr","search","urlParams","exec","_decodeParams","decodeURIComponent","length","routeKeys","routeValues","slice","object","zip"],"mappings":";;CACC,SAASA,EAAMC,GACd,GAAsB,kBAAXC,SAAyBA,OAAOC,IACzCD,QAAQ,WAAY,cAAe,SAASE,EAAUC,GACpD,MAAOJ,GAAQG,EAAUC,SAGxB,IAAuB,mBAAZC,SAAyB,CACvC,GAAIF,GAAWG,QAAQ,YACnBF,EAAIE,QAAQ,aAChBC,QAAOF,QAAUL,EAAQG,EAAUC,OAGnCJ,GAAQD,EAAKI,SAAUJ,EAAKK,IAE9BI,KAAM,SAASL,EAAUC,GACzB,YAOA,IAAIK,GAAa,cAqGjB,OAnGAN,GAASO,WAAaP,EAASQ,OAAOC,QACpCC,YAAa,WACXL,KAAKM,eACLX,EAASQ,OAAOI,UAAUF,YAAYG,MAAMR,KAAMS,YAMpDC,WAAY,aAEZC,MAAO,SAASC,EAAWC,GACzB,GAAIF,GAAOG,CAEPlB,GAAEmB,SAASH,IACbD,EAAQC,EACRE,EAAW,GAAKF,IAEhBD,EAAQX,KAAKgB,eAAeJ,GAC5BE,EAAWF,GAGbZ,KAAKM,YAAYM,GAAaZ,KAAKiB,oBAAoBH,EAIvD,IAAII,IACFP,MAAOA,EACPQ,OAAQnB,KACRa,OAAQA,EAILjB,GAAEmB,SAASH,KACdM,EAAUE,cAAgBR,EAI5B,IAAIO,GAASnB,IAcb,OAbAL,GAAS0B,QAAQV,MAAMA,EAAO,SAASW,EAAUC,GAC/C,GAAIjB,GAAca,EAAOK,mBAAmBb,EAAOW,GAC/CG,EAAcnB,EAAYoB,KAG1BH,KAAcL,EAAUK,WAAaA,GACzCL,EAAUS,MAAQR,EAAOS,oBAAoBH,GAC7CP,EAAUW,OAASV,EAAOW,gBAAgBhB,EAAUR,GACpDY,EAAUa,YAAcT,EAExBH,EAAOT,WAAWQ,KAGblB,MAGTiB,oBAAqB,SAASN,GAC5B,GAAIqB,KAMJ,OAJArB,GAAMsB,QAAQhC,EAAY,SAASiC,GACjCF,EAAYG,KAAKD,EAAME,OAAO,MAGzBJ,GAMTJ,oBAAqB,SAASH,GAC5B,IAAKA,EAAe,QAMpB,KAJA,GAAIS,GACAG,EAAS,qBACTC,KAEGJ,EAAQG,EAAOE,KAAKd,IACxBa,EAAUtC,KAAKwC,cAAcN,EAAM,KAAOlC,KAAKwC,cAAcN,EAAM,GAGtE,OAAOI,IAGTE,cAAe,SAAUf,GAEvB,MAAOgB,oBAAmBhB,EAAYQ,QAAQ,MAAO,OAIvDH,gBAAiB,SAASnB,EAAOL,GAC/B,IAAKA,EAAYoC,OAAU,QAE3B,IAAIC,GAAY3C,KAAKM,YAAYK,GAC7BiC,EAActC,EAAYuC,MAAM,EAAGF,EAAUD,OAEjD,OAAO9C,GAAEkD,OAAOlD,EAAEmD,IAAIJ,EAAWC,OAK9BjD,EAASO"} \ No newline at end of file +{"version":3,"file":"backbone.base-router.min.js","sources":["backbone.base-router.js"],"names":["root","factory","define","amd","Backbone","_","exports","require","module","this","NAMED_PARAM","PLUS_SYMBOL","BaseRouter","Router","extend","constructor","routeParams","prototype","apply","arguments","onNavigate","route","origRoute","linked","routeStr","isRegExp","_routeToRegExp","_extractRouteParams","routeData","router","originalRoute","history","fragment","navOptions","_extractParameters","queryString","pop","query","_getQueryParameters","params","_getNamedParams","uriFragment","namedParams","replace","match","push","substr","reduce","split","memo","param","parts","key","val","decodeURIComponent","undefined","isArray","length","routeKeys","routeValues","slice","object","zip"],"mappings":";;CACC,SAASA,EAAMC,GACd,GAAsB,kBAAXC,SAAyBA,OAAOC,IACzCD,QAAQ,WAAY,cAAe,SAASE,EAAUC,GACpD,MAAOJ,GAAQG,EAAUC,SAGxB,IAAuB,mBAAZC,SAAyB,CACvC,GAAIF,GAAWG,QAAQ,YACnBF,EAAIE,QAAQ,aAChBC,QAAOF,QAAUL,EAAQG,EAAUC,OAGnCJ,GAAQD,EAAKI,SAAUJ,EAAKK,IAE9BI,KAAM,SAASL,EAAUC,GACzB,YAOA,IAAIK,GAAc,eAEdC,EAAc,KAkHlB,OAhHAP,GAASQ,WAAaR,EAASS,OAAOC,QACpCC,YAAa,WACXN,KAAKO,eACLZ,EAASS,OAAOI,UAAUF,YAAYG,MAAMT,KAAMU,YAMpDC,WAAY,aAEZC,MAAO,SAASC,EAAWC,GACzB,GAAIF,GAAOG,CAEPnB,GAAEoB,SAASH,IACbD,EAAQC,EACRE,EAAW,GAAKF,IAEhBD,EAAQZ,KAAKiB,eAAeJ,GAC5BE,EAAWF,GAGbb,KAAKO,YAAYM,GAAab,KAAKkB,oBAAoBH,EAIvD,IAAII,IACFP,MAAOA,EACPQ,OAAQpB,KACRc,OAAQA,EAILlB,GAAEoB,SAASH,KACdM,EAAUE,cAAgBR,EAI5B,IAAIO,GAASpB,IAcb,OAbAL,GAAS2B,QAAQV,MAAMA,EAAO,SAASW,EAAUC,GAC/C,GAAIjB,GAAca,EAAOK,mBAAmBb,EAAOW,GAC/CG,EAAcnB,EAAYoB,KAG1BH,KAAcL,EAAUK,WAAaA,GACzCL,EAAUS,MAAQR,EAAOS,oBAAoBH,GAC7CP,EAAUW,OAASV,EAAOW,gBAAgBhB,EAAUR,GACpDY,EAAUa,YAAcT,EAExBH,EAAOT,WAAWQ,KAGbnB,MAGTkB,oBAAqB,SAASN,GAC5B,GAAIqB,KAMJ,OAJArB,GAAMsB,QAAQjC,EAAa,SAASkC,GAClCF,EAAYG,KAAKD,EAAME,OAAO,MAGzBJ,GAMTJ,oBAAqB,SAASH,GAC5B,MAAKA,GAEE9B,EAAE0C,OAAOZ,EAAYa,MAAM,KAAM,SAASC,EAAMC,GACrD,GAAIC,GAAQD,EAAMP,QAAQhC,EAAa,KAAKqC,MAAM,KAC9CI,EAAMD,EAAM,GACZE,EAAMF,EAAM,EAsBhB,OApBAC,GAAME,mBAAmBF,GACzBC,EAAcE,SAARF,EAAoB,KAAOC,mBAAmBD,GAG/CJ,EAAKG,GAMD/C,EAAEmD,QAAQP,EAAKG,IACtBH,EAAKG,GAAKP,KAAKQ,GAMfJ,EAAKG,IAAQH,EAAKG,GAAMC,GAZxBJ,EAAKG,GAAOC,EAePJ,WAKXT,gBAAiB,SAASnB,EAAOL,GAC/B,IAAKA,EAAYyC,OAAU,QAE3B,IAAIC,GAAYjD,KAAKO,YAAYK,GAC7BsC,EAAc3C,EAAY4C,MAAM,EAAGF,EAAUD,OAEjD,OAAOpD,GAAEwD,OAAOxD,EAAEyD,IAAIJ,EAAWC,OAK9BvD,EAASQ"} \ No newline at end of file diff --git a/package.json b/package.json index 3ee5868..9ea1efe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "backbone.base-router", - "version": "0.5.0", + "version": "1.0.0", "description": "A better starting point for a new Backbone Router.", "main": "dist/backbone.base-router.js", "directories": {