ui-router-core
Version:
UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps
141 lines • 5.36 kB
JavaScript
;
/**
* @coreapi
* @module params
*/
/** */
var common_1 = require("../common/common");
var predicates_1 = require("../common/predicates");
/**
* An internal class which implements [[ParamTypeDefinition]].
*
* A [[ParamTypeDefinition]] is a plain javascript object used to register custom parameter types.
* When a param type definition is registered, an instance of this class is created internally.
*
* This class has naive implementations for all the [[ParamTypeDefinition]] methods.
*
* Used by [[UrlMatcher]] when matching or formatting URLs, or comparing and validating parameter values.
*
* #### Example:
* ```js
* var paramTypeDef = {
* decode: function(val) { return parseInt(val, 10); },
* encode: function(val) { return val && val.toString(); },
* equals: function(a, b) { return this.is(a) && a === b; },
* is: function(val) { return angular.isNumber(val) && isFinite(val) && val % 1 === 0; },
* pattern: /\d+/
* }
*
* var paramType = new ParamType(paramTypeDef);
* ```
* @internalapi
*/
var ParamType = (function () {
/**
* @param def A configuration object which contains the custom type definition. The object's
* properties will override the default methods and/or pattern in `ParamType`'s public interface.
* @returns a new ParamType object
*/
function ParamType(def) {
/** @inheritdoc */
this.pattern = /.*/;
/** @inheritdoc */
this.inherit = true;
common_1.extend(this, def);
}
// consider these four methods to be "abstract methods" that should be overridden
/** @inheritdoc */
ParamType.prototype.is = function (val, key) { return true; };
/** @inheritdoc */
ParamType.prototype.encode = function (val, key) { return val; };
/** @inheritdoc */
ParamType.prototype.decode = function (val, key) { return val; };
/** @inheritdoc */
ParamType.prototype.equals = function (a, b) { return a == b; };
ParamType.prototype.$subPattern = function () {
var sub = this.pattern.toString();
return sub.substr(1, sub.length - 2);
};
ParamType.prototype.toString = function () {
return "{ParamType:" + this.name + "}";
};
/** Given an encoded string, or a decoded object, returns a decoded object */
ParamType.prototype.$normalize = function (val) {
return this.is(val) ? val : this.decode(val);
};
/**
* Wraps an existing custom ParamType as an array of ParamType, depending on 'mode'.
* e.g.:
* - urlmatcher pattern "/path?{queryParam[]:int}"
* - url: "/path?queryParam=1&queryParam=2
* - $stateParams.queryParam will be [1, 2]
* if `mode` is "auto", then
* - url: "/path?queryParam=1 will create $stateParams.queryParam: 1
* - url: "/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]
*/
ParamType.prototype.$asArray = function (mode, isSearch) {
if (!mode)
return this;
if (mode === "auto" && !isSearch)
throw new Error("'auto' array mode is for query parameters only");
return new ArrayType(this, mode);
};
return ParamType;
}());
exports.ParamType = ParamType;
/**
* Wraps up a `ParamType` object to handle array values.
* @internalapi
*/
function ArrayType(type, mode) {
var _this = this;
// Wrap non-array value as array
function arrayWrap(val) {
return predicates_1.isArray(val) ? val : (predicates_1.isDefined(val) ? [val] : []);
}
// Unwrap array value for "auto" mode. Return undefined for empty array.
function arrayUnwrap(val) {
switch (val.length) {
case 0: return undefined;
case 1: return mode === "auto" ? val[0] : val;
default: return val;
}
}
// Wraps type (.is/.encode/.decode) functions to operate on each value of an array
function arrayHandler(callback, allTruthyMode) {
return function handleArray(val) {
if (predicates_1.isArray(val) && val.length === 0)
return val;
var arr = arrayWrap(val);
var result = common_1.map(arr, callback);
return (allTruthyMode === true) ? common_1.filter(result, function (x) { return !x; }).length === 0 : arrayUnwrap(result);
};
}
// Wraps type (.equals) functions to operate on each value of an array
function arrayEqualsHandler(callback) {
return function handleArray(val1, val2) {
var left = arrayWrap(val1), right = arrayWrap(val2);
if (left.length !== right.length)
return false;
for (var i = 0; i < left.length; i++) {
if (!callback(left[i], right[i]))
return false;
}
return true;
};
}
['encode', 'decode', 'equals', '$normalize'].forEach(function (name) {
var paramTypeFn = type[name].bind(type);
var wrapperFn = name === 'equals' ? arrayEqualsHandler : arrayHandler;
_this[name] = wrapperFn(paramTypeFn);
});
common_1.extend(this, {
dynamic: type.dynamic,
name: type.name,
pattern: type.pattern,
inherit: type.inherit,
is: arrayHandler(type.is.bind(type), true),
$arrayMode: mode
});
}
//# sourceMappingURL=paramType.js.map