3939 * * `'/files/*path'` - ditto.
4040 *
4141 * @param {string } pattern The pattern to compile into a matcher.
42- * @param {config } config A configuration object hash:
42+ * @param {Object } config A configuration object hash:
4343 *
4444 * * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.
4545 * * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.
@@ -158,14 +158,14 @@ function UrlMatcher(pattern, config) {
158158 *
159159 * @example
160160 * The following two matchers are equivalent:
161- * ```
161+ * <pre>
162162 * new UrlMatcher('/user/{id}?q').concat('/details?date');
163163 * new UrlMatcher('/user/{id}/details?q&date');
164- * ```
164+ * </pre>
165165 *
166166 * @param {string } pattern The pattern to append.
167- * @param {object } config An object hash of the configuration for the matcher.
168- * @returns {ui.router.util.type: UrlMatcher } A matcher for the concatenated pattern.
167+ * @param {Object } config An object hash of the configuration for the matcher.
168+ * @returns {UrlMatcher } A matcher for the concatenated pattern.
169169 */
170170UrlMatcher . prototype . concat = function ( pattern , config ) {
171171 // Because order of search parameters is irrelevant, we can add our own search
@@ -191,10 +191,12 @@ UrlMatcher.prototype.toString = function () {
191191 * as optional.
192192 *
193193 * @example
194- * ```
195- * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', { x:'1', q:'hello' });
196- * // returns { id:'bob', q:'hello', r:null }
197- * ```
194+ * <pre>
195+ * new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {
196+ * x: '1', q: 'hello'
197+ * });
198+ * // returns { id: 'bob', q: 'hello', r: null }
199+ * </pre>
198200 *
199201 * @param {string } path The URL path to match, e.g. `$location.path()`.
200202 * @param {Object } searchParams URL search parameters, e.g. `$location.search()`.
@@ -251,7 +253,7 @@ UrlMatcher.prototype.parameters = function (param) {
251253 * types of this `UrlMatcher`.
252254 *
253255 * @param {Object } params The object hash of parameters to validate.
254- * @returns {Boolean } Returns `true` if `params` validates, otherwise `false`.
256+ * @returns {boolean } Returns `true` if `params` validates, otherwise `false`.
255257 */
256258UrlMatcher . prototype . validates = function ( params ) {
257259 var result = true , isOptional , cfg , self = this ;
@@ -276,10 +278,10 @@ UrlMatcher.prototype.validates = function (params) {
276278 * treated as empty strings.
277279 *
278280 * @example
279- * ```
281+ * <pre>
280282 * new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
281283 * // returns '/user/bob?q=yes'
282- * ```
284+ * </pre>
283285 *
284286 * @param {Object } values the values to substitute for the parameters in this pattern.
285287 * @returns {string } the formatted URL (path and optionally search part).
@@ -315,22 +317,98 @@ UrlMatcher.prototype.format = function (values) {
315317
316318UrlMatcher . prototype . $types = { } ;
317319
318- function Type ( options ) {
319- extend ( this , options ) ;
320+ /**
321+ * @ngdoc object
322+ * @name ui.router.util.type:Type
323+ *
324+ * @description
325+ * Implements an interface to define custom parameter types that can be decoded from and encoded to
326+ * string parameters matched in a URL. Used by {@link ui.router.util.type:UrlMatcher `UrlMatcher`}
327+ * objects when matching or formatting URLs, or comparing or validating parameter values.
328+ *
329+ * See {@link ui.router.util.$urlMatcherFactory#methods_type `$urlMatcherFactory#type()`} for more
330+ * information on registering custom types.
331+ *
332+ * @param {Object } config A configuration object hash that includes any method in `Type`'s public
333+ * interface, and/or `pattern`, which should contain a custom regular expression used to match
334+ * string parameters originating from a URL.
335+ *
336+ * @property {RegExp } pattern The regular expression pattern used to match values of this type when
337+ * coming from a substring of a URL.
338+ *
339+ * @returns {Object } Returns a new `Type` object.
340+ */
341+ function Type ( config ) {
342+ extend ( this , config ) ;
320343}
321344
345+ /**
346+ * @ngdoc function
347+ * @name ui.router.util.type:Type#is
348+ * @methodOf ui.router.util.type:Type
349+ *
350+ * @description
351+ * Detects whether a value is of a particular type. Accepts a native (decoded) value
352+ * and determines whether it matches the current `Type` object.
353+ *
354+ * @param {* } val The value to check.
355+ * @param {string } key Optional. If the type check is happening in the context of a specific
356+ * {@link ui.router.util.type:UrlMatcher `UrlMatcher`} object, this is the name of the
357+ * parameter in which `val` is stored. Can be used for meta-programming of `Type` objects.
358+ * @returns {Boolean } Returns `true` if the value matches the type, otherwise `false`.
359+ */
322360Type . prototype . is = function ( val , key ) {
323361 return true ;
324362} ;
325363
364+ /**
365+ * @ngdoc function
366+ * @name ui.router.util.type:Type#encode
367+ * @methodOf ui.router.util.type:Type
368+ *
369+ * @description
370+ * Encodes a custom/native type value to a string that can be embedded in a URL. Note that the
371+ * return value does *not* need to be URL-safe (i.e. passed through `encodeURIComponent()`), it
372+ * only needs to be a representation of `val` that has been coerced to a string.
373+ *
374+ * @param {* } val The value to encode.
375+ * @param {string } key The name of the parameter in which `val` is stored. Can be used for
376+ * meta-programming of `Type` objects.
377+ * @returns {string } Returns a string representation of `val` that can be encoded in a URL.
378+ */
326379Type . prototype . encode = function ( val , key ) {
327380 return val ;
328381} ;
329382
383+ /**
384+ * @ngdoc function
385+ * @name ui.router.util.type:Type#decode
386+ * @methodOf ui.router.util.type:Type
387+ *
388+ * @description
389+ * Converts a string URL parameter value to a custom/native value.
390+ *
391+ * @param {string } val The URL parameter value to decode.
392+ * @param {string } key The name of the parameter in which `val` is stored. Can be used for
393+ * meta-programming of `Type` objects.
394+ * @returns {* } Returns a custom representation of the URL parameter value.
395+ */
330396Type . prototype . decode = function ( val , key ) {
331397 return val ;
332398} ;
333399
400+ /**
401+ * @ngdoc function
402+ * @name ui.router.util.type:Type#equals
403+ * @methodOf ui.router.util.type:Type
404+ *
405+ * @description
406+ * Determines whether two decoded values are equivalent.
407+ *
408+ * @param {* } a A value to compare against.
409+ * @param {* } b A value to compare against.
410+ * @returns {Boolean } Returns `true` if the values are equivalent/equal, otherwise `false`.
411+ */
334412Type . prototype . equals = function ( a , b ) {
335413 return a == b ;
336414} ;
@@ -347,8 +425,8 @@ Type.prototype.pattern = /.*/;
347425 * @name ui.router.util.$urlMatcherFactory
348426 *
349427 * @description
350- * Factory for {@link ui.router.util.type:UrlMatcher} instances. The factory is also available to providers
351- * under the name `$urlMatcherFactoryProvider`.
428+ * Factory for {@link ui.router.util.type:UrlMatcher `UrlMatcher` } instances. The factory
429+ * is also available to providers under the name `$urlMatcherFactoryProvider`.
352430 */
353431function $UrlMatcherFactory ( ) {
354432
@@ -413,7 +491,7 @@ function $UrlMatcherFactory() {
413491 * @description
414492 * Defines whether URL matching should be case sensitive (the default behavior), or not.
415493 *
416- * @param {bool } value `false` to match URL in a case sensitive manner; otherwise `true`;
494+ * @param {boolean } value `false` to match URL in a case sensitive manner; otherwise `true`;
417495 */
418496 this . caseInsensitive = function ( value ) {
419497 isCaseInsensitive = value ;
@@ -427,7 +505,7 @@ function $UrlMatcherFactory() {
427505 * @description
428506 * Defines whether URLs should match trailing slashes, or not (the default behavior).
429507 *
430- * @param {bool } value `false` to match trailing slashes in URLs, otherwise `true`.
508+ * @param {boolean } value `false` to match trailing slashes in URLs, otherwise `true`.
431509 */
432510 this . strictMode = function ( value ) {
433511 isStrictMode = value ;
@@ -439,11 +517,11 @@ function $UrlMatcherFactory() {
439517 * @methodOf ui.router.util.$urlMatcherFactory
440518 *
441519 * @description
442- * Creates a {@link ui.router.util.type:UrlMatcher} for the specified pattern.
520+ * Creates a {@link ui.router.util.type:UrlMatcher `UrlMatcher` } for the specified pattern.
443521 *
444522 * @param {string } pattern The URL pattern.
445- * @param {object } config The config object hash.
446- * @returns {ui.router.util.type: UrlMatcher } The UrlMatcher.
523+ * @param {Object } config The config object hash.
524+ * @returns {UrlMatcher } The UrlMatcher.
447525 */
448526 this . compile = function ( pattern , config ) {
449527 return new UrlMatcher ( pattern , extend ( getDefaultConfig ( ) , config ) ) ;
@@ -473,6 +551,110 @@ function $UrlMatcherFactory() {
473551 return result ;
474552 } ;
475553
554+ /**
555+ * @ngdoc function
556+ * @name ui.router.util.$urlMatcherFactory#type
557+ * @methodOf ui.router.util.$urlMatcherFactory
558+ *
559+ * @description
560+ * Registers a custom {@link ui.router.util.type:Type `Type`} object that can be used to
561+ * generate URLs with typed parameters.
562+ *
563+ * @param {string } name The type name.
564+ * @param {Object|Function } def The type definition. See
565+ * {@link ui.router.util.type:Type `Type`} for information on the values accepted.
566+ *
567+ * @returns {Object } Returns `$urlMatcherFactoryProvider`.
568+ *
569+ * @example
570+ * This is a simple example of a custom type that encodes and decodes items from an
571+ * array, using the array index as the URL-encoded value:
572+ *
573+ * <pre>
574+ * var list = ['John', 'Paul', 'George', 'Ringo'];
575+ *
576+ * $urlMatcherFactoryProvider.type('listItem', {
577+ * encode: function(item) {
578+ * // Represent the list item in the URL using its corresponding index
579+ * return list.indexOf(item);
580+ * },
581+ * decode: function(item) {
582+ * // Look up the list item by index
583+ * return list[parseInt(item, 10)];
584+ * },
585+ * is: function(item) {
586+ * // Ensure the item is valid by checking to see that it appears
587+ * // in the list
588+ * return list.indexOf(item) > -1;
589+ * }
590+ * });
591+ *
592+ * $stateProvider.state('list', {
593+ * url: "/list/{item:listItem}",
594+ * controller: function($scope, $stateParams) {
595+ * console.log($stateParams.item);
596+ * }
597+ * });
598+ *
599+ * // ...
600+ *
601+ * // Changes URL to '/list/3', logs "Ringo" to the console
602+ * $state.go('list', { item: "Ringo" });
603+ * </pre>
604+ *
605+ * This is a more complex example of a type that relies on dependency injection to
606+ * interact with services, and uses the parameter name from the URL to infer how to
607+ * handle encoding and decoding parameter values:
608+ *
609+ * <pre>
610+ * // Defines a custom type that gets a value from a service,
611+ * // where each service gets different types of values from
612+ * // a backend API:
613+ * $urlMatcherFactoryProvider.type('dbObject', function(Users, Posts) {
614+ *
615+ * // Matches up services to URL parameter names
616+ * var services = {
617+ * user: Users,
618+ * post: Posts
619+ * };
620+ *
621+ * return {
622+ * encode: function(object) {
623+ * // Represent the object in the URL using its unique ID
624+ * return object.id;
625+ * },
626+ * decode: function(value, key) {
627+ * // Look up the object by ID, using the parameter
628+ * // name (key) to call the correct service
629+ * return services[key].findById(value);
630+ * },
631+ * is: function(object, key) {
632+ * // Check that object is a valid dbObject
633+ * return angular.isObject(object) && object.id && services[key];
634+ * }
635+ * equals: function(a, b) {
636+ * // Check the equality of decoded objects by comparing
637+ * // their unique IDs
638+ * return a.id === b.id;
639+ * }
640+ * };
641+ * });
642+ *
643+ * // In a config() block, you can then attach URLs with
644+ * // type-annotated parameters:
645+ * $stateProvider.state('users', {
646+ * url: "/users",
647+ * // ...
648+ * }).state('users.item', {
649+ * url: "/{user:dbObject}",
650+ * controller: function($scope, $stateParams) {
651+ * // $stateParams.user will now be an object returned from
652+ * // the Users service
653+ * },
654+ * // ...
655+ * });
656+ * </pre>
657+ */
476658 this . type = function ( name , def ) {
477659 if ( ! isDefined ( def ) ) return UrlMatcher . prototype . $types [ name ] ;
478660 typeQueue . push ( { name : name , def : def } ) ;
0 commit comments