39
39
* * `'/files/*path'` - ditto.
40
40
*
41
41
* @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:
43
43
*
44
44
* * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.
45
45
* * `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) {
158
158
*
159
159
* @example
160
160
* The following two matchers are equivalent:
161
- * ```
161
+ * <pre>
162
162
* new UrlMatcher('/user/{id}?q').concat('/details?date');
163
163
* new UrlMatcher('/user/{id}/details?q&date');
164
- * ```
164
+ * </pre>
165
165
*
166
166
* @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.
169
169
*/
170
170
UrlMatcher . prototype . concat = function ( pattern , config ) {
171
171
// Because order of search parameters is irrelevant, we can add our own search
@@ -191,10 +191,12 @@ UrlMatcher.prototype.toString = function () {
191
191
* as optional.
192
192
*
193
193
* @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>
198
200
*
199
201
* @param {string } path The URL path to match, e.g. `$location.path()`.
200
202
* @param {Object } searchParams URL search parameters, e.g. `$location.search()`.
@@ -251,7 +253,7 @@ UrlMatcher.prototype.parameters = function (param) {
251
253
* types of this `UrlMatcher`.
252
254
*
253
255
* @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`.
255
257
*/
256
258
UrlMatcher . prototype . validates = function ( params ) {
257
259
var result = true , isOptional , cfg , self = this ;
@@ -276,10 +278,10 @@ UrlMatcher.prototype.validates = function (params) {
276
278
* treated as empty strings.
277
279
*
278
280
* @example
279
- * ```
281
+ * <pre>
280
282
* new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
281
283
* // returns '/user/bob?q=yes'
282
- * ```
284
+ * </pre>
283
285
*
284
286
* @param {Object } values the values to substitute for the parameters in this pattern.
285
287
* @returns {string } the formatted URL (path and optionally search part).
@@ -315,22 +317,98 @@ UrlMatcher.prototype.format = function (values) {
315
317
316
318
UrlMatcher . prototype . $types = { } ;
317
319
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 ) ;
320
343
}
321
344
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
+ */
322
360
Type . prototype . is = function ( val , key ) {
323
361
return true ;
324
362
} ;
325
363
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
+ */
326
379
Type . prototype . encode = function ( val , key ) {
327
380
return val ;
328
381
} ;
329
382
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
+ */
330
396
Type . prototype . decode = function ( val , key ) {
331
397
return val ;
332
398
} ;
333
399
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
+ */
334
412
Type . prototype . equals = function ( a , b ) {
335
413
return a == b ;
336
414
} ;
@@ -347,8 +425,8 @@ Type.prototype.pattern = /.*/;
347
425
* @name ui.router.util.$urlMatcherFactory
348
426
*
349
427
* @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`.
352
430
*/
353
431
function $UrlMatcherFactory ( ) {
354
432
@@ -413,7 +491,7 @@ function $UrlMatcherFactory() {
413
491
* @description
414
492
* Defines whether URL matching should be case sensitive (the default behavior), or not.
415
493
*
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`;
417
495
*/
418
496
this . caseInsensitive = function ( value ) {
419
497
isCaseInsensitive = value ;
@@ -427,7 +505,7 @@ function $UrlMatcherFactory() {
427
505
* @description
428
506
* Defines whether URLs should match trailing slashes, or not (the default behavior).
429
507
*
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`.
431
509
*/
432
510
this . strictMode = function ( value ) {
433
511
isStrictMode = value ;
@@ -439,11 +517,11 @@ function $UrlMatcherFactory() {
439
517
* @methodOf ui.router.util.$urlMatcherFactory
440
518
*
441
519
* @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.
443
521
*
444
522
* @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.
447
525
*/
448
526
this . compile = function ( pattern , config ) {
449
527
return new UrlMatcher ( pattern , extend ( getDefaultConfig ( ) , config ) ) ;
@@ -473,6 +551,110 @@ function $UrlMatcherFactory() {
473
551
return result ;
474
552
} ;
475
553
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
+ */
476
658
this . type = function ( name , def ) {
477
659
if ( ! isDefined ( def ) ) return UrlMatcher . prototype . $types [ name ] ;
478
660
typeQueue . push ( { name : name , def : def } ) ;
0 commit comments