Skip to content

Commit

Permalink
Fix #11, add validation params in build function
Browse files Browse the repository at this point in the history
  • Loading branch information
ruslankerimov committed Oct 16, 2014
1 parent e1a22e0 commit ff417d7
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 47 deletions.
68 changes: 45 additions & 23 deletions dist/susanin.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ function Route(options) {
GROUP_CLOSED_CHAR;
this._conditions[QUERY_STRING_PARAM_NAME] = '.*';

this._paramsMap = [];
this._mainParamsMap = {};
this._requiredParams = [];

/**
* @type {Array}
* @private
Expand All @@ -312,10 +316,11 @@ function Route(options) {

/**
* @param {String} pattern
* @param {Boolean} [isOptional=false]
* @returns {Array}
* @private
*/
Route.prototype._parsePattern = function(pattern) {
Route.prototype._parsePattern = function(pattern, isOptional) {
var parts = [],
part = '',
character,
Expand All @@ -332,7 +337,7 @@ Route.prototype._parsePattern = function(pattern) {
++countOpened;
part += character;
} else {
this._parseParams(part, parts);
this._parseParams(part, parts, isOptional);
part = '';
countOpened = 0;
isFindingClosed = true;
Expand All @@ -343,7 +348,7 @@ Route.prototype._parsePattern = function(pattern) {
part = {
what : 'optional',
dependOnParams : [],
parts : this._parsePattern(part)
parts : this._parsePattern(part, true)
};

parts.push(part);
Expand All @@ -368,29 +373,36 @@ Route.prototype._parsePattern = function(pattern) {
}
}

this._parseParams(part, parts);
this._parseParams(part, parts, isOptional);

return parts;
};

/**
* @param {String} pattern
* @param {Array} parts
* @param {Boolean} isOptional
* @private
*/
Route.prototype._parseParams = function(pattern, parts) {
Route.prototype._parseParams = function(pattern, parts, isOptional) {
var matches = pattern.match(PARSE_PARAMS_REGEXP),
i, size,
part;
part,
paramName;

if (matches) {
for (i = 0, size = matches.length; i < size; ++i) {
part = matches[i];

if (part.charAt(0) === PARAM_OPENED_CHAR && part.charAt(part.length - 1) === PARAM_CLOSED_CHAR) {
paramName = part.substr(1, part.length - 2);
this._paramsMap.push(paramName);
this._mainParamsMap[paramName] = true;
isOptional || this._requiredParams.push(paramName);

parts.push({
what : 'param',
name : part.substr(1, part.length - 2)
name : paramName
});
} else {
parts.push(part);
Expand All @@ -403,7 +415,6 @@ Route.prototype._parseParams = function(pattern, parts) {
* @private
*/
Route.prototype._buildParseRegExp = function() {
this._reqExpParamsMap = [];
this._parseRegExpSource = '^' + this._buildParseRegExpParts(this._parts) + '$';
this._parseRegExp = new RegExp(this._parseRegExpSource);
};
Expand All @@ -424,7 +435,6 @@ Route.prototype._buildParseRegExpParts = function(parts) {
if (typeof part === 'string') {
ret += escape(part);
} else if (part.what === 'param') {
this._reqExpParamsMap.push(part.name);
ret += '(' + (this._getParamValueRegExpSource(part.name) || PARAM_VALUE_REGEXP_SOURCE) + ')';
} else {
ret += '(?:' + this._buildParseRegExpParts(part.parts) + ')?';
Expand Down Expand Up @@ -494,7 +504,6 @@ Route.prototype._checkParamValue = function(paramName, paramValue) {
* @private
*/
Route.prototype._buildBuildFn = function() {
this._mainParamsMap = {};
this._buildFnSource = 'var h=({}).hasOwnProperty;return ' + this._buildBuildFnParts(this._parts) + ';';
/*jshint evil:true */
this._buildFn = new Function('p', this._buildFnSource);
Expand Down Expand Up @@ -598,7 +607,7 @@ Route.prototype.match = function(path, data) {

for (i = 1, size = matches.length; i < size; ++i) {
if (typeof matches[i] !== 'undefined' && /* for IE lt 9*/ matches[i] !== '') {
paramName = this._reqExpParamsMap[i - 1];
paramName = this._paramsMap[i - 1];
if (paramName === QUERY_STRING_PARAM_NAME) {
queryString = matches[i];
} else if (paramName === TRAILING_SLASH_PARAM_NAME) {
Expand Down Expand Up @@ -654,31 +663,44 @@ Route.prototype.match = function(path, data) {
/**
* Build path from params
* @param {Object} params
* @returns {String}
* @param {Boolean} [isStrict=false]
* @returns {?String}
*/
Route.prototype.build = function(params) {
Route.prototype.build = function(params, isStrict) {
var options = this._options,
newParams = {},
useQueryString = options.useQueryString !== false,
queryParams = {},
queryString,
key,
filter = options.preBuild;
paramName,
paramValue,
filter = options.preBuild,
i, size;

if (typeof filter === 'function') {
params = filter(params);
}

for (key in params) {
for (paramName in params) {
if (
has(params, key) &&
params[key] !== null &&
typeof params[key] !== 'undefined'
has(params, paramName) &&
params[paramName] !== null &&
typeof params[paramName] !== 'undefined' &&
(this._mainParamsMap[paramName] || useQueryString)
) {
if (this._mainParamsMap[key]) {
newParams[key] = params[key];
} else if (useQueryString) {
queryParams[key] = params[key];
paramValue = params[paramName];
if (isStrict && ! this._checkParamValue(paramName, paramValue)) {
return null;
}

(this._mainParamsMap[paramName] ? newParams : queryParams)[paramName] = paramValue;
}
}

if (isStrict) {
for (i = 0, size = this._requiredParams.length; i < size; ++i) {
if ( ! has(newParams, this._requiredParams[i])) {
return null;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion dist/susanin.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ff417d7

Please sign in to comment.