5
5
var mod = angular . module ( 'route-segment' , [ ] ) ;
6
6
mod . provider ( '$routeSegment' ,
7
7
[ '$routeProvider' , function ( $routeProvider ) {
8
-
8
+
9
9
var $routeSegmentProvider = this ;
10
-
10
+
11
11
var options = $routeSegmentProvider . options = {
12
-
12
+
13
13
/**
14
14
* When true, it will resolve `templateUrl` automatically via $http service and put its
15
15
* contents into `template`.
16
16
* @type {boolean }
17
17
*/
18
18
autoLoadTemplates : true ,
19
-
19
+
20
20
/**
21
21
* When true, all attempts to call `within` method on non-existing segments will throw an error (you would
22
22
* usually want this behavior in production). When false, it will transparently create new empty segment
@@ -25,46 +25,46 @@ mod.provider( '$routeSegment',
25
25
*/
26
26
strictMode : false
27
27
} ;
28
-
28
+
29
29
var segments = this . segments = { } ,
30
30
rootPointer = pointer ( segments , null ) ,
31
31
segmentRoutes = { } ;
32
-
32
+
33
33
function camelCase ( name ) {
34
34
return name . replace ( / ( [ \: \- \_ ] + ( .) ) / g, function ( _ , separator , letter , offset ) {
35
35
return offset ? letter . toUpperCase ( ) : letter ;
36
36
} ) ;
37
37
}
38
-
38
+
39
39
function pointer ( segment , parent ) {
40
-
40
+
41
41
if ( ! segment )
42
42
throw new Error ( 'Invalid pointer segment' ) ;
43
-
43
+
44
44
var lastAddedName ;
45
-
45
+
46
46
return {
47
-
47
+
48
48
/**
49
49
* Adds new segment at current pointer level.
50
- *
50
+ *
51
51
* @param string} name Name of a segment.
52
52
* @param {Object } params Segment's parameters hash. The following params are supported:
53
53
* - `template` provides HTML for the given segment view;
54
54
* - `templateUrl` is a template should be fetched from network via this URL;
55
55
* - `controller` is attached to the given segment view when compiled and linked,
56
56
* this can be any controller definition AngularJS supports;
57
- * - `dependencies` is an array of route param names which are forcing the view
57
+ * - `dependencies` is an array of route param names which are forcing the view
58
58
* to recreate when changed;
59
59
* - `watcher` is a $watch-function for recreating the view when its returning value
60
60
* is changed;
61
61
* - `resolve` is a hash of functions or injectable names which should be resolved
62
62
* prior to instantiating the template and the controller;
63
63
* - `untilResolved` is the alternate set of params (e.g. `template` and `controller`)
64
- * which should be used before resolving is completed;
65
- * - `resolveFailed` is the alternate set of params which should be used
64
+ * which should be used before resolving is completed;
65
+ * - `resolveFailed` is the alternate set of params which should be used
66
66
* if resolving failed;
67
- *
67
+ *
68
68
* @returns {Object } The same level pointer.
69
69
*/
70
70
segment : function ( name , params ) {
@@ -79,11 +79,11 @@ mod.provider( '$routeSegment',
79
79
*
80
80
* @param {string } childName An existing segment's name. If undefined, then the last added segment is selected.
81
81
* @returns {Object } The pointer to the child segment.
82
- */
83
- within : function ( childName ) {
82
+ */
83
+ within : function ( childName ) {
84
84
var child ;
85
85
childName = childName || lastAddedName ;
86
-
86
+
87
87
if ( child = segment [ camelCase ( childName ) ] ) {
88
88
if ( child . children == undefined )
89
89
child . children = { } ;
@@ -93,19 +93,19 @@ mod.provider( '$routeSegment',
93
93
throw new Error ( 'Cannot get into unknown `' + childName + '` segment' ) ;
94
94
else {
95
95
child = segment [ camelCase ( childName ) ] = { params : { } , children : { } } ;
96
- }
96
+ }
97
97
}
98
98
return pointer ( child . children , this ) ;
99
99
} ,
100
-
100
+
101
101
/**
102
102
* Traverses up in the tree.
103
103
* @returns {Object } The pointer which are parent to the current one;
104
104
*/
105
105
up : function ( ) {
106
106
return parent ;
107
107
} ,
108
-
108
+
109
109
/**
110
110
* Traverses to the root.
111
111
* @returns The root pointer.
@@ -115,29 +115,34 @@ mod.provider( '$routeSegment',
115
115
}
116
116
}
117
117
}
118
-
118
+
119
119
/**
120
120
* The shorthand for $routeProvider.when() method with specified route name.
121
- * @param {string } route Route URL, e.g. '/foo/bar'
121
+ * @param {string } path Route URL, e.g. '/foo/bar'
122
122
* @param {string } name Fully qualified route name, e.g. 'foo.bar'
123
+ * @param {Object } route Mapping information to be assigned to $route.current on route match.
123
124
*/
124
- $routeSegmentProvider . when = function ( route , name ) {
125
- $routeProvider . when ( route , { segment : name } ) ;
126
- segmentRoutes [ name ] = route ;
125
+ $routeSegmentProvider . when = function ( path , name , route ) {
126
+ if ( route == undefined )
127
+ route = { } ;
128
+ route . segment = name ;
129
+
130
+ $routeProvider . when ( path , route ) ;
131
+ segmentRoutes [ name ] = path ;
127
132
return this ;
128
133
} ;
129
-
134
+
130
135
// Extending the provider with the methods of rootPointer
131
136
// to start configuration.
132
137
angular . extend ( $routeSegmentProvider , rootPointer ) ;
133
-
134
-
138
+
139
+
135
140
// the service factory
136
141
this . $get = [ '$rootScope' , '$q' , '$http' , '$templateCache' , '$route' , '$routeParams' , '$injector' ,
137
142
function ( $rootScope , $q , $http , $templateCache , $route , $routeParams , $injector ) {
138
-
139
- var $routeSegment = {
140
-
143
+
144
+ var $routeSegment = {
145
+
141
146
/**
142
147
* Fully qualified name of current active route
143
148
* @type {string }
@@ -151,7 +156,7 @@ mod.provider( '$routeSegment',
151
156
* @type {Object }
152
157
*/
153
158
$routeParams : angular . copy ( $routeParams ) ,
154
-
159
+
155
160
/**
156
161
* Array of segments splitted by each level separately. Each item contains the following properties:
157
162
* - `name` is the name of a segment;
@@ -162,7 +167,7 @@ mod.provider( '$routeSegment',
162
167
* @type {Array.<Object> }
163
168
*/
164
169
chain : [ ] ,
165
-
170
+
166
171
/**
167
172
* Helper method for checking whether current route starts with the given string
168
173
* @param {string } val
@@ -172,7 +177,7 @@ mod.provider( '$routeSegment',
172
177
var regexp = new RegExp ( '^' + val ) ;
173
178
return regexp . test ( $routeSegment . name ) ;
174
179
} ,
175
-
180
+
176
181
/**
177
182
* Helper method for checking whether current route contains the given string
178
183
* @param {string } val
@@ -209,22 +214,22 @@ mod.provider( '$routeSegment',
209
214
210
215
return url ;
211
216
}
212
- } ;
217
+ } ;
213
218
214
219
var resolvingSemaphoreChain = { } ;
215
-
220
+
216
221
// When a route changes, all interested parties should be notified about new segment chain
217
222
$rootScope . $on ( '$routeChangeSuccess' , function ( event , args ) {
218
223
219
- var route = args . $route || args . $$route ;
224
+ var route = args . $route || args . $$route ;
220
225
if ( route && route . segment ) {
221
226
222
227
var segmentName = route . segment ;
223
228
var segmentNameChain = segmentName . split ( "." ) ;
224
229
var updates = [ ] , lastUpdateIndex = - 1 ;
225
-
230
+
226
231
for ( var i = 0 ; i < segmentNameChain . length ; i ++ ) {
227
-
232
+
228
233
var newSegment = getSegmentInChain ( i , segmentNameChain ) ;
229
234
230
235
if ( resolvingSemaphoreChain [ i ] != newSegment . name || updates . length > 0 || isDependenciesChanged ( newSegment ) ) {
@@ -237,7 +242,7 @@ mod.provider( '$routeSegment',
237
242
updates . push ( { index : i , newSegment : newSegment } ) ;
238
243
lastUpdateIndex = i ;
239
244
}
240
- }
245
+ }
241
246
}
242
247
243
248
var curSegmentPromise = $q . when ( ) ;
@@ -305,7 +310,7 @@ mod.provider( '$routeSegment',
305
310
lastUpdateIndex = index ;
306
311
}
307
312
} ) ( i , children , index ) ;
308
-
313
+
309
314
310
315
}
311
316
}
@@ -315,7 +320,7 @@ mod.provider( '$routeSegment',
315
320
} ) ;
316
321
}
317
322
} ) ;
318
-
323
+
319
324
function isDependenciesChanged ( segment ) {
320
325
321
326
var result = false ;
@@ -352,22 +357,22 @@ mod.provider( '$routeSegment',
352
357
else
353
358
return resolve ( index , segment . name , segment . params ) ;
354
359
}
355
-
360
+
356
361
function resolve ( index , name , params ) {
357
-
362
+
358
363
var locals = angular . extend ( { } , params . resolve ) ;
359
-
364
+
360
365
angular . forEach ( locals , function ( value , key ) {
361
366
locals [ key ] = angular . isString ( value ) ? $injector . get ( value ) : $injector . invoke ( value ) ;
362
367
} ) ;
363
-
368
+
364
369
if ( params . template ) {
365
370
366
371
locals . $template = params . template ;
367
372
if ( angular . isFunction ( locals . $template ) )
368
373
locals . $template = $injector . invoke ( locals . $template ) ;
369
374
}
370
-
375
+
371
376
if ( options . autoLoadTemplates && params . templateUrl ) {
372
377
373
378
locals . $template = params . templateUrl ;
@@ -382,7 +387,7 @@ mod.provider( '$routeSegment',
382
387
}
383
388
384
389
return $q . all ( locals ) . then (
385
-
390
+
386
391
function ( resolvedLocals ) {
387
392
388
393
if ( resolvingSemaphoreChain [ index ] != name )
@@ -427,9 +432,9 @@ mod.provider( '$routeSegment',
427
432
428
433
return { success : index } ;
429
434
} ,
430
-
435
+
431
436
function ( error ) {
432
-
437
+
433
438
if ( params . resolveFailed ) {
434
439
var newResolve = { error : function ( ) { return $q . when ( error ) ; } } ;
435
440
return resolve ( index , name , angular . extend ( { resolve : newResolve } , params . resolveFailed ) ) ;
@@ -454,34 +459,34 @@ mod.provider( '$routeSegment',
454
459
index : index ,
455
460
segment : $routeSegment . chain [ index ] || null } ) ;
456
461
}
457
-
462
+
458
463
function getSegmentInChain ( segmentIdx , segmentNameChain ) {
459
-
460
- if ( ! segmentNameChain )
461
- return null ;
462
-
463
- if ( segmentIdx >= segmentNameChain . length )
464
- return null ;
465
-
464
+
465
+ if ( ! segmentNameChain )
466
+ return null ;
467
+
468
+ if ( segmentIdx >= segmentNameChain . length )
469
+ return null ;
470
+
466
471
var curSegment = segments , nextName ;
467
- for ( var i = 0 ; i <= segmentIdx ; i ++ ) {
472
+ for ( var i = 0 ; i <= segmentIdx ; i ++ ) {
468
473
469
474
nextName = segmentNameChain [ i ] ;
470
475
471
476
if ( curSegment [ camelCase ( nextName ) ] != undefined )
472
477
curSegment = curSegment [ camelCase ( nextName ) ] ;
473
-
478
+
474
479
if ( i < segmentIdx )
475
480
curSegment = curSegment . children ;
476
481
}
477
-
482
+
478
483
return {
479
484
name : nextName ,
480
485
params : curSegment . params ,
481
486
children : curSegment . children
482
487
} ;
483
488
}
484
-
489
+
485
490
return $routeSegment ;
486
491
} ] ;
487
492
} ] ) ;
0 commit comments