UNPKG

ui-router-core

Version:

UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps

140 lines 5.29 kB
/** * @coreapi * @module params */ /** */ import { extend, filter, map } from "../common/common"; import { isArray, isDefined } from "../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; 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; }()); export { 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 isArray(val) ? val : (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 (isArray(val) && val.length === 0) return val; var arr = arrayWrap(val); var result = map(arr, callback); return (allTruthyMode === true) ? 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); }); 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