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,7 +115,7 @@ 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
121
* @param {string } path Route URL, e.g. '/foo/bar'
@@ -131,18 +131,18 @@ mod.provider( '$routeSegment',
131
131
segmentRoutes [ name ] = path ;
132
132
return this ;
133
133
} ;
134
-
134
+
135
135
// Extending the provider with the methods of rootPointer
136
136
// to start configuration.
137
137
angular . extend ( $routeSegmentProvider , rootPointer ) ;
138
-
139
-
138
+
139
+
140
140
// the service factory
141
141
this . $get = [ '$rootScope' , '$q' , '$http' , '$templateCache' , '$route' , '$routeParams' , '$injector' ,
142
142
function ( $rootScope , $q , $http , $templateCache , $route , $routeParams , $injector ) {
143
-
144
- var $routeSegment = {
145
-
143
+
144
+ var $routeSegment = {
145
+
146
146
/**
147
147
* Fully qualified name of current active route
148
148
* @type {string }
@@ -156,7 +156,7 @@ mod.provider( '$routeSegment',
156
156
* @type {Object }
157
157
*/
158
158
$routeParams : angular . copy ( $routeParams ) ,
159
-
159
+
160
160
/**
161
161
* Array of segments splitted by each level separately. Each item contains the following properties:
162
162
* - `name` is the name of a segment;
@@ -167,7 +167,7 @@ mod.provider( '$routeSegment',
167
167
* @type {Array.<Object> }
168
168
*/
169
169
chain : [ ] ,
170
-
170
+
171
171
/**
172
172
* Helper method for checking whether current route starts with the given string
173
173
* @param {string } val
@@ -177,7 +177,7 @@ mod.provider( '$routeSegment',
177
177
var regexp = new RegExp ( '^' + val ) ;
178
178
return regexp . test ( $routeSegment . name ) ;
179
179
} ,
180
-
180
+
181
181
/**
182
182
* Helper method for checking whether current route contains the given string
183
183
* @param {string } val
@@ -214,22 +214,22 @@ mod.provider( '$routeSegment',
214
214
215
215
return url ;
216
216
}
217
- } ;
217
+ } ;
218
218
219
219
var resolvingSemaphoreChain = { } ;
220
-
220
+
221
221
// When a route changes, all interested parties should be notified about new segment chain
222
222
$rootScope . $on ( '$routeChangeSuccess' , function ( event , args ) {
223
223
224
- var route = args . $route || args . $$route ;
224
+ var route = args . $route || args . $$route ;
225
225
if ( route && route . segment ) {
226
226
227
227
var segmentName = route . segment ;
228
228
var segmentNameChain = segmentName . split ( "." ) ;
229
229
var updates = [ ] , lastUpdateIndex = - 1 ;
230
-
230
+
231
231
for ( var i = 0 ; i < segmentNameChain . length ; i ++ ) {
232
-
232
+
233
233
var newSegment = getSegmentInChain ( i , segmentNameChain ) ;
234
234
235
235
if ( resolvingSemaphoreChain [ i ] != newSegment . name || updates . length > 0 || isDependenciesChanged ( newSegment ) ) {
@@ -242,7 +242,7 @@ mod.provider( '$routeSegment',
242
242
updates . push ( { index : i , newSegment : newSegment } ) ;
243
243
lastUpdateIndex = i ;
244
244
}
245
- }
245
+ }
246
246
}
247
247
248
248
var curSegmentPromise = $q . when ( ) ;
@@ -310,7 +310,7 @@ mod.provider( '$routeSegment',
310
310
lastUpdateIndex = index ;
311
311
}
312
312
} ) ( i , children , index ) ;
313
-
313
+
314
314
315
315
}
316
316
}
@@ -320,7 +320,7 @@ mod.provider( '$routeSegment',
320
320
} ) ;
321
321
}
322
322
} ) ;
323
-
323
+
324
324
function isDependenciesChanged ( segment ) {
325
325
326
326
var result = false ;
@@ -357,22 +357,22 @@ mod.provider( '$routeSegment',
357
357
else
358
358
return resolve ( index , segment . name , segment . params ) ;
359
359
}
360
-
360
+
361
361
function resolve ( index , name , params ) {
362
-
362
+
363
363
var locals = angular . extend ( { } , params . resolve ) ;
364
-
364
+
365
365
angular . forEach ( locals , function ( value , key ) {
366
366
locals [ key ] = angular . isString ( value ) ? $injector . get ( value ) : $injector . invoke ( value ) ;
367
367
} ) ;
368
-
368
+
369
369
if ( params . template ) {
370
370
371
371
locals . $template = params . template ;
372
372
if ( angular . isFunction ( locals . $template ) )
373
373
locals . $template = $injector . invoke ( locals . $template ) ;
374
374
}
375
-
375
+
376
376
if ( options . autoLoadTemplates && params . templateUrl ) {
377
377
378
378
locals . $template = params . templateUrl ;
@@ -387,7 +387,7 @@ mod.provider( '$routeSegment',
387
387
}
388
388
389
389
return $q . all ( locals ) . then (
390
-
390
+
391
391
function ( resolvedLocals ) {
392
392
393
393
if ( resolvingSemaphoreChain [ index ] != name )
@@ -432,9 +432,9 @@ mod.provider( '$routeSegment',
432
432
433
433
return { success : index } ;
434
434
} ,
435
-
435
+
436
436
function ( error ) {
437
-
437
+
438
438
if ( params . resolveFailed ) {
439
439
var newResolve = { error : function ( ) { return $q . when ( error ) ; } } ;
440
440
return resolve ( index , name , angular . extend ( { resolve : newResolve } , params . resolveFailed ) ) ;
@@ -459,34 +459,34 @@ mod.provider( '$routeSegment',
459
459
index : index ,
460
460
segment : $routeSegment . chain [ index ] || null } ) ;
461
461
}
462
-
462
+
463
463
function getSegmentInChain ( segmentIdx , segmentNameChain ) {
464
-
465
- if ( ! segmentNameChain )
466
- return null ;
467
-
468
- if ( segmentIdx >= segmentNameChain . length )
469
- return null ;
470
-
464
+
465
+ if ( ! segmentNameChain )
466
+ return null ;
467
+
468
+ if ( segmentIdx >= segmentNameChain . length )
469
+ return null ;
470
+
471
471
var curSegment = segments , nextName ;
472
- for ( var i = 0 ; i <= segmentIdx ; i ++ ) {
472
+ for ( var i = 0 ; i <= segmentIdx ; i ++ ) {
473
473
474
474
nextName = segmentNameChain [ i ] ;
475
475
476
476
if ( curSegment [ camelCase ( nextName ) ] != undefined )
477
477
curSegment = curSegment [ camelCase ( nextName ) ] ;
478
-
478
+
479
479
if ( i < segmentIdx )
480
480
curSegment = curSegment . children ;
481
481
}
482
-
482
+
483
483
return {
484
484
name : nextName ,
485
485
params : curSegment . params ,
486
486
children : curSegment . children
487
487
} ;
488
488
}
489
-
489
+
490
490
return $routeSegment ;
491
491
} ] ;
492
492
} ] ) ;
0 commit comments