angularjs-rails 1.5.8 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/engine.rb +1 -1
- data/lib/angularjs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/angular-animate.js +75 -60
- data/vendor/assets/javascripts/angular-aria.js +29 -32
- data/vendor/assets/javascripts/angular-cookies.js +19 -11
- data/vendor/assets/javascripts/angular-loader.js +9 -8
- data/vendor/assets/javascripts/angular-message-format.js +61 -70
- data/vendor/assets/javascripts/angular-messages.js +10 -8
- data/vendor/assets/javascripts/angular-mocks.js +392 -114
- data/vendor/assets/javascripts/angular-parse-ext.js +3 -1
- data/vendor/assets/javascripts/angular-resource.js +79 -95
- data/vendor/assets/javascripts/angular-route.js +219 -72
- data/vendor/assets/javascripts/angular-sanitize.js +52 -51
- data/vendor/assets/javascripts/angular-scenario.js +3421 -2491
- data/vendor/assets/javascripts/angular-touch.js +31 -19
- data/vendor/assets/javascripts/angular.js +3332 -2205
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
2
|
+
* @license AngularJS v1.6.0
|
3
3
|
* (c) 2010-2016 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -1223,6 +1223,8 @@ function IDC_Y(cp) {
|
|
1223
1223
|
return false;
|
1224
1224
|
}
|
1225
1225
|
|
1226
|
+
/* eslint-disable new-cap */
|
1227
|
+
|
1226
1228
|
/**
|
1227
1229
|
* @ngdoc module
|
1228
1230
|
* @name ngParseExt
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
2
|
+
* @license AngularJS v1.6.0
|
3
3
|
* (c) 2010-2016 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -137,9 +137,12 @@ function shallowClearAndCopy(src, dst) {
|
|
137
137
|
* Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
|
138
138
|
* method that does not accept a request body)
|
139
139
|
*
|
140
|
-
* @param {Object.<Object>=} actions Hash with declaration of custom actions that
|
141
|
-
* the default set of resource actions.
|
142
|
-
*
|
140
|
+
* @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available
|
141
|
+
* in addition to the default set of resource actions (see below). If a custom action has the same
|
142
|
+
* key as a default action (e.g. `save`), then the default action will be *overwritten*, and not
|
143
|
+
* extended.
|
144
|
+
*
|
145
|
+
* The declaration should be created in the format of {@link ng.$http#usage $http.config}:
|
143
146
|
*
|
144
147
|
* {action1: {method:?, params:?, isArray:?, headers:?, ...},
|
145
148
|
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
@@ -164,12 +167,13 @@ function shallowClearAndCopy(src, dst) {
|
|
164
167
|
* transform function or an array of such functions. The transform function takes the http
|
165
168
|
* request body and headers and returns its transformed (typically serialized) version.
|
166
169
|
* By default, transformRequest will contain one function that checks if the request data is
|
167
|
-
* an object and serializes
|
170
|
+
* an object and serializes it using `angular.toJson`. To prevent this behavior, set
|
168
171
|
* `transformRequest` to an empty array: `transformRequest: []`
|
169
172
|
* - **`transformResponse`** –
|
170
|
-
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
173
|
+
* `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
|
171
174
|
* transform function or an array of such functions. The transform function takes the http
|
172
|
-
* response body and
|
175
|
+
* response body, headers and status and returns its transformed (typically deserialized)
|
176
|
+
* version.
|
173
177
|
* By default, transformResponse will contain one function that checks if the response looks
|
174
178
|
* like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,
|
175
179
|
* set `transformResponse` to an empty array: `transformResponse: []`
|
@@ -243,9 +247,9 @@ function shallowClearAndCopy(src, dst) {
|
|
243
247
|
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
|
244
248
|
*
|
245
249
|
*
|
246
|
-
* Success callback is called with (value, responseHeaders)
|
247
|
-
*
|
248
|
-
* with (httpResponse) argument.
|
250
|
+
* Success callback is called with (value (Object|Array), responseHeaders (Function),
|
251
|
+
* status (number), statusText (string)) arguments, where the value is the populated resource
|
252
|
+
* instance or collection object. The error callback is called with (httpResponse) argument.
|
249
253
|
*
|
250
254
|
* Class actions return empty instance (with additional properties below).
|
251
255
|
* Instance actions return promise of the action.
|
@@ -430,8 +434,9 @@ function shallowClearAndCopy(src, dst) {
|
|
430
434
|
*
|
431
435
|
*/
|
432
436
|
angular.module('ngResource', ['ng']).
|
433
|
-
provider('$resource', function() {
|
434
|
-
var
|
437
|
+
provider('$resource', function ResourceProvider() {
|
438
|
+
var PROTOCOL_AND_IPV6_REGEX = /^https?:\/\/\[[^\]]*][^/]*/;
|
439
|
+
|
435
440
|
var provider = this;
|
436
441
|
|
437
442
|
/**
|
@@ -475,7 +480,7 @@ angular.module('ngResource', ['ng']).
|
|
475
480
|
* ```js
|
476
481
|
* angular.
|
477
482
|
* module('myApp').
|
478
|
-
* config(['resourceProvider', function ($resourceProvider) {
|
483
|
+
* config(['$resourceProvider', function ($resourceProvider) {
|
479
484
|
* $resourceProvider.defaults.actions.update = {
|
480
485
|
* method: 'PUT'
|
481
486
|
* };
|
@@ -487,9 +492,9 @@ angular.module('ngResource', ['ng']).
|
|
487
492
|
* ```js
|
488
493
|
* angular.
|
489
494
|
* module('myApp').
|
490
|
-
* config(['resourceProvider', function ($resourceProvider) {
|
495
|
+
* config(['$resourceProvider', function ($resourceProvider) {
|
491
496
|
* $resourceProvider.defaults.actions = {
|
492
|
-
* create: {method: 'POST'}
|
497
|
+
* create: {method: 'POST'},
|
493
498
|
* get: {method: 'GET'},
|
494
499
|
* getAll: {method: 'GET', isArray:true},
|
495
500
|
* update: {method: 'PUT'},
|
@@ -519,49 +524,15 @@ angular.module('ngResource', ['ng']).
|
|
519
524
|
this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {
|
520
525
|
|
521
526
|
var noop = angular.noop,
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
* segment = *pchar
|
532
|
-
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
533
|
-
* pct-encoded = "%" HEXDIG HEXDIG
|
534
|
-
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
535
|
-
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
536
|
-
* / "*" / "+" / "," / ";" / "="
|
537
|
-
*/
|
538
|
-
function encodeUriSegment(val) {
|
539
|
-
return encodeUriQuery(val, true).
|
540
|
-
replace(/%26/gi, '&').
|
541
|
-
replace(/%3D/gi, '=').
|
542
|
-
replace(/%2B/gi, '+');
|
543
|
-
}
|
544
|
-
|
545
|
-
|
546
|
-
/**
|
547
|
-
* This method is intended for encoding *key* or *value* parts of query component. We need a
|
548
|
-
* custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
|
549
|
-
* have to be encoded per http://tools.ietf.org/html/rfc3986:
|
550
|
-
* query = *( pchar / "/" / "?" )
|
551
|
-
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
552
|
-
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
553
|
-
* pct-encoded = "%" HEXDIG HEXDIG
|
554
|
-
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
555
|
-
* / "*" / "+" / "," / ";" / "="
|
556
|
-
*/
|
557
|
-
function encodeUriQuery(val, pctEncodeSpaces) {
|
558
|
-
return encodeURIComponent(val).
|
559
|
-
replace(/%40/gi, '@').
|
560
|
-
replace(/%3A/gi, ':').
|
561
|
-
replace(/%24/g, '$').
|
562
|
-
replace(/%2C/gi, ',').
|
563
|
-
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
|
564
|
-
}
|
527
|
+
forEach = angular.forEach,
|
528
|
+
extend = angular.extend,
|
529
|
+
copy = angular.copy,
|
530
|
+
isArray = angular.isArray,
|
531
|
+
isDefined = angular.isDefined,
|
532
|
+
isFunction = angular.isFunction,
|
533
|
+
isNumber = angular.isNumber,
|
534
|
+
encodeUriQuery = angular.$$encodeUriQuery,
|
535
|
+
encodeUriSegment = angular.$$encodeUriSegment;
|
565
536
|
|
566
537
|
function Route(template, defaults) {
|
567
538
|
this.template = template;
|
@@ -575,42 +546,42 @@ angular.module('ngResource', ['ng']).
|
|
575
546
|
url = actionUrl || self.template,
|
576
547
|
val,
|
577
548
|
encodedVal,
|
578
|
-
|
549
|
+
protocolAndIpv6 = '';
|
579
550
|
|
580
|
-
var urlParams = self.urlParams =
|
551
|
+
var urlParams = self.urlParams = Object.create(null);
|
581
552
|
forEach(url.split(/\W/), function(param) {
|
582
553
|
if (param === 'hasOwnProperty') {
|
583
|
-
throw $resourceMinErr('badname',
|
554
|
+
throw $resourceMinErr('badname', 'hasOwnProperty is not a valid parameter name.');
|
584
555
|
}
|
585
|
-
if (!(new RegExp(
|
586
|
-
(new RegExp(
|
556
|
+
if (!(new RegExp('^\\d+$').test(param)) && param &&
|
557
|
+
(new RegExp('(^|[^\\\\]):' + param + '(\\W|$)').test(url))) {
|
587
558
|
urlParams[param] = {
|
588
|
-
isQueryParamValue: (new RegExp(
|
559
|
+
isQueryParamValue: (new RegExp('\\?.*=:' + param + '(?:\\W|$)')).test(url)
|
589
560
|
};
|
590
561
|
}
|
591
562
|
});
|
592
563
|
url = url.replace(/\\:/g, ':');
|
593
|
-
url = url.replace(
|
594
|
-
|
564
|
+
url = url.replace(PROTOCOL_AND_IPV6_REGEX, function(match) {
|
565
|
+
protocolAndIpv6 = match;
|
595
566
|
return '';
|
596
567
|
});
|
597
568
|
|
598
569
|
params = params || {};
|
599
570
|
forEach(self.urlParams, function(paramInfo, urlParam) {
|
600
571
|
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
|
601
|
-
if (
|
572
|
+
if (isDefined(val) && val !== null) {
|
602
573
|
if (paramInfo.isQueryParamValue) {
|
603
574
|
encodedVal = encodeUriQuery(val, true);
|
604
575
|
} else {
|
605
576
|
encodedVal = encodeUriSegment(val);
|
606
577
|
}
|
607
|
-
url = url.replace(new RegExp(
|
578
|
+
url = url.replace(new RegExp(':' + urlParam + '(\\W|$)', 'g'), function(match, p1) {
|
608
579
|
return encodedVal + p1;
|
609
580
|
});
|
610
581
|
} else {
|
611
|
-
url = url.replace(new RegExp(
|
582
|
+
url = url.replace(new RegExp('(/?):' + urlParam + '(\\W|$)', 'g'), function(match,
|
612
583
|
leadingSlashes, tail) {
|
613
|
-
if (tail.charAt(0)
|
584
|
+
if (tail.charAt(0) === '/') {
|
614
585
|
return tail;
|
615
586
|
} else {
|
616
587
|
return leadingSlashes + tail;
|
@@ -628,7 +599,7 @@ angular.module('ngResource', ['ng']).
|
|
628
599
|
// E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
|
629
600
|
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
|
630
601
|
// replace escaped `/\.` with `/.`
|
631
|
-
config.url =
|
602
|
+
config.url = protocolAndIpv6 + url.replace(/\/\\\./, '/.');
|
632
603
|
|
633
604
|
|
634
605
|
// set params - delegate param encoding to $http
|
@@ -652,7 +623,7 @@ angular.module('ngResource', ['ng']).
|
|
652
623
|
actionParams = extend({}, paramDefaults, actionParams);
|
653
624
|
forEach(actionParams, function(value, key) {
|
654
625
|
if (isFunction(value)) { value = value(data); }
|
655
|
-
ids[key] = value && value.charAt && value.charAt(0)
|
626
|
+
ids[key] = value && value.charAt && value.charAt(0) === '@' ?
|
656
627
|
lookupDottedPath(data, value.substr(1)) : value;
|
657
628
|
});
|
658
629
|
return ids;
|
@@ -676,11 +647,10 @@ angular.module('ngResource', ['ng']).
|
|
676
647
|
forEach(actions, function(action, name) {
|
677
648
|
var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
|
678
649
|
var numericTimeout = action.timeout;
|
679
|
-
var cancellable =
|
680
|
-
|
681
|
-
provider.defaults.cancellable;
|
650
|
+
var cancellable = isDefined(action.cancellable) ?
|
651
|
+
action.cancellable : route.defaults.cancellable;
|
682
652
|
|
683
|
-
if (numericTimeout && !
|
653
|
+
if (numericTimeout && !isNumber(numericTimeout)) {
|
684
654
|
$log.debug('ngResource:\n' +
|
685
655
|
' Only numeric values are allowed as `timeout`.\n' +
|
686
656
|
' Promises are not supported in $resource, because the same value would ' +
|
@@ -693,12 +663,11 @@ angular.module('ngResource', ['ng']).
|
|
693
663
|
Resource[name] = function(a1, a2, a3, a4) {
|
694
664
|
var params = {}, data, success, error;
|
695
665
|
|
696
|
-
/* jshint -W086 */ /* (purposefully fall through case statements) */
|
697
666
|
switch (arguments.length) {
|
698
667
|
case 4:
|
699
668
|
error = a4;
|
700
669
|
success = a3;
|
701
|
-
|
670
|
+
// falls through
|
702
671
|
case 3:
|
703
672
|
case 2:
|
704
673
|
if (isFunction(a2)) {
|
@@ -710,13 +679,14 @@ angular.module('ngResource', ['ng']).
|
|
710
679
|
|
711
680
|
success = a2;
|
712
681
|
error = a3;
|
713
|
-
//
|
682
|
+
// falls through
|
714
683
|
} else {
|
715
684
|
params = a1;
|
716
685
|
data = a2;
|
717
686
|
success = a3;
|
718
687
|
break;
|
719
688
|
}
|
689
|
+
// falls through
|
720
690
|
case 1:
|
721
691
|
if (isFunction(a1)) success = a1;
|
722
692
|
else if (hasBody) data = a1;
|
@@ -725,10 +695,9 @@ angular.module('ngResource', ['ng']).
|
|
725
695
|
case 0: break;
|
726
696
|
default:
|
727
697
|
throw $resourceMinErr('badargs',
|
728
|
-
|
698
|
+
'Expected up to 4 arguments [params, data, success, error], got {0} arguments',
|
729
699
|
arguments.length);
|
730
700
|
}
|
731
|
-
/* jshint +W086 */ /* (purposefully fall through case statements) */
|
732
701
|
|
733
702
|
var isInstanceCall = this instanceof Resource;
|
734
703
|
var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
|
@@ -737,6 +706,8 @@ angular.module('ngResource', ['ng']).
|
|
737
706
|
defaultResponseInterceptor;
|
738
707
|
var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
|
739
708
|
undefined;
|
709
|
+
var hasError = !!error;
|
710
|
+
var hasResponseErrorInterceptor = !!responseErrorInterceptor;
|
740
711
|
var timeoutDeferred;
|
741
712
|
var numericTimeoutPromise;
|
742
713
|
|
@@ -772,18 +743,16 @@ angular.module('ngResource', ['ng']).
|
|
772
743
|
|
773
744
|
if (data) {
|
774
745
|
// Need to convert action.isArray to boolean in case it is undefined
|
775
|
-
|
776
|
-
if (angular.isArray(data) !== (!!action.isArray)) {
|
746
|
+
if (isArray(data) !== (!!action.isArray)) {
|
777
747
|
throw $resourceMinErr('badcfg',
|
778
748
|
'Error in resource configuration for action `{0}`. Expected response to ' +
|
779
749
|
'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
|
780
|
-
|
750
|
+
isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
|
781
751
|
}
|
782
|
-
// jshint +W018
|
783
752
|
if (action.isArray) {
|
784
753
|
value.length = 0;
|
785
754
|
forEach(data, function(item) {
|
786
|
-
if (typeof item ===
|
755
|
+
if (typeof item === 'object') {
|
787
756
|
value.push(new Resource(item));
|
788
757
|
} else {
|
789
758
|
// Valid JSON values may be string literals, and these should not be converted
|
@@ -801,15 +770,12 @@ angular.module('ngResource', ['ng']).
|
|
801
770
|
response.resource = value;
|
802
771
|
|
803
772
|
return response;
|
804
|
-
}, function(response) {
|
805
|
-
(error || noop)(response);
|
806
|
-
return $q.reject(response);
|
807
773
|
});
|
808
774
|
|
809
|
-
promise['finally'](function() {
|
775
|
+
promise = promise['finally'](function() {
|
810
776
|
value.$resolved = true;
|
811
777
|
if (!isInstanceCall && cancellable) {
|
812
|
-
value.$cancelRequest =
|
778
|
+
value.$cancelRequest = noop;
|
813
779
|
$timeout.cancel(numericTimeoutPromise);
|
814
780
|
timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;
|
815
781
|
}
|
@@ -818,10 +784,22 @@ angular.module('ngResource', ['ng']).
|
|
818
784
|
promise = promise.then(
|
819
785
|
function(response) {
|
820
786
|
var value = responseInterceptor(response);
|
821
|
-
(success || noop)(value, response.headers);
|
787
|
+
(success || noop)(value, response.headers, response.status, response.statusText);
|
822
788
|
return value;
|
823
789
|
},
|
824
|
-
|
790
|
+
(hasError || hasResponseErrorInterceptor) ?
|
791
|
+
function(response) {
|
792
|
+
if (hasError) error(response);
|
793
|
+
return hasResponseErrorInterceptor ?
|
794
|
+
responseErrorInterceptor(response) :
|
795
|
+
$q.reject(response);
|
796
|
+
} :
|
797
|
+
undefined);
|
798
|
+
if (hasError && !hasResponseErrorInterceptor) {
|
799
|
+
// Avoid `Possibly Unhandled Rejection` error,
|
800
|
+
// but still fulfill the returned promise with a rejection
|
801
|
+
promise.catch(noop);
|
802
|
+
}
|
825
803
|
|
826
804
|
if (!isInstanceCall) {
|
827
805
|
// we are creating instance / collection
|
@@ -829,13 +807,18 @@ angular.module('ngResource', ['ng']).
|
|
829
807
|
// - return the instance / collection
|
830
808
|
value.$promise = promise;
|
831
809
|
value.$resolved = false;
|
832
|
-
if (cancellable) value.$cancelRequest =
|
810
|
+
if (cancellable) value.$cancelRequest = cancelRequest;
|
833
811
|
|
834
812
|
return value;
|
835
813
|
}
|
836
814
|
|
837
815
|
// instance call
|
838
816
|
return promise;
|
817
|
+
|
818
|
+
function cancelRequest(value) {
|
819
|
+
promise.catch(noop);
|
820
|
+
timeoutDeferred.resolve(value);
|
821
|
+
}
|
839
822
|
};
|
840
823
|
|
841
824
|
|
@@ -849,7 +832,8 @@ angular.module('ngResource', ['ng']).
|
|
849
832
|
});
|
850
833
|
|
851
834
|
Resource.bind = function(additionalParamDefaults) {
|
852
|
-
|
835
|
+
var extendedParamDefaults = extend({}, paramDefaults, additionalParamDefaults);
|
836
|
+
return resourceFactory(url, extendedParamDefaults, actions, options);
|
853
837
|
};
|
854
838
|
|
855
839
|
return Resource;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
2
|
+
* @license AngularJS v1.6.0
|
3
3
|
* (c) 2010-2016 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -34,10 +34,11 @@ function shallowCopy(src, dst) {
|
|
34
34
|
|
35
35
|
/* global shallowCopy: false */
|
36
36
|
|
37
|
-
//
|
37
|
+
// `isArray` and `isObject` are necessary for `shallowCopy()` (included via `src/shallowCopy.js`).
|
38
38
|
// They are initialized inside the `$RouteProvider`, to ensure `window.angular` is available.
|
39
39
|
var isArray;
|
40
40
|
var isObject;
|
41
|
+
var isDefined;
|
41
42
|
|
42
43
|
/**
|
43
44
|
* @ngdoc module
|
@@ -54,14 +55,22 @@ var isObject;
|
|
54
55
|
*
|
55
56
|
* <div doc-module-components="ngRoute"></div>
|
56
57
|
*/
|
57
|
-
|
58
|
-
var ngRouteModule = angular.
|
59
|
-
|
60
|
-
|
58
|
+
/* global -ngRouteModule */
|
59
|
+
var ngRouteModule = angular.
|
60
|
+
module('ngRoute', []).
|
61
|
+
provider('$route', $RouteProvider).
|
62
|
+
// Ensure `$route` will be instantiated in time to capture the initial `$locationChangeSuccess`
|
63
|
+
// event (unless explicitly disabled). This is necessary in case `ngView` is included in an
|
64
|
+
// asynchronously loaded template.
|
65
|
+
run(instantiateRoute);
|
66
|
+
var $routeMinErr = angular.$$minErr('ngRoute');
|
67
|
+
var isEagerInstantiationEnabled;
|
68
|
+
|
61
69
|
|
62
70
|
/**
|
63
71
|
* @ngdoc provider
|
64
72
|
* @name $routeProvider
|
73
|
+
* @this
|
65
74
|
*
|
66
75
|
* @description
|
67
76
|
*
|
@@ -76,6 +85,7 @@ var ngRouteModule = angular.module('ngRoute', ['ng']).
|
|
76
85
|
function $RouteProvider() {
|
77
86
|
isArray = angular.isArray;
|
78
87
|
isObject = angular.isObject;
|
88
|
+
isDefined = angular.isDefined;
|
79
89
|
|
80
90
|
function inherit(parent, extra) {
|
81
91
|
return angular.extend(Object.create(parent), extra);
|
@@ -112,12 +122,12 @@ function $RouteProvider() {
|
|
112
122
|
*
|
113
123
|
* Object properties:
|
114
124
|
*
|
115
|
-
* - `controller` – `{(string|
|
125
|
+
* - `controller` – `{(string|Function)=}` – Controller fn that should be associated with
|
116
126
|
* newly created scope or the name of a {@link angular.Module#controller registered
|
117
127
|
* controller} if passed as a string.
|
118
128
|
* - `controllerAs` – `{string=}` – An identifier name for a reference to the controller.
|
119
129
|
* If present, the controller will be published to scope under the `controllerAs` name.
|
120
|
-
* - `template` – `{string
|
130
|
+
* - `template` – `{(string|Function)=}` – html template as a string or a function that
|
121
131
|
* returns an html template as a string which should be used by {@link
|
122
132
|
* ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
|
123
133
|
* This property takes precedence over `templateUrl`.
|
@@ -127,7 +137,9 @@ function $RouteProvider() {
|
|
127
137
|
* - `{Array.<Object>}` - route parameters extracted from the current
|
128
138
|
* `$location.path()` by applying the current route
|
129
139
|
*
|
130
|
-
*
|
140
|
+
* One of `template` or `templateUrl` is required.
|
141
|
+
*
|
142
|
+
* - `templateUrl` – `{(string|Function)=}` – path or function that returns a path to an html
|
131
143
|
* template that should be used by {@link ngRoute.directive:ngView ngView}.
|
132
144
|
*
|
133
145
|
* If `templateUrl` is a function, it will be called with the following parameters:
|
@@ -135,7 +147,9 @@ function $RouteProvider() {
|
|
135
147
|
* - `{Array.<Object>}` - route parameters extracted from the current
|
136
148
|
* `$location.path()` by applying the current route
|
137
149
|
*
|
138
|
-
*
|
150
|
+
* One of `templateUrl` or `template` is required.
|
151
|
+
*
|
152
|
+
* - `resolve` - `{Object.<string, Function>=}` - An optional map of dependencies which should
|
139
153
|
* be injected into the controller. If any of these dependencies are promises, the router
|
140
154
|
* will wait for them all to be resolved or one to be rejected before the controller is
|
141
155
|
* instantiated.
|
@@ -155,7 +169,7 @@ function $RouteProvider() {
|
|
155
169
|
* The map object is:
|
156
170
|
*
|
157
171
|
* - `key` – `{string}`: a name of a dependency to be injected into the controller.
|
158
|
-
* - `factory` - `{string|
|
172
|
+
* - `factory` - `{string|Function}`: If `string` then it is an alias for a service.
|
159
173
|
* Otherwise if function, then it is {@link auto.$injector#invoke injected}
|
160
174
|
* and the return value is treated as the dependency. If the result is a promise, it is
|
161
175
|
* resolved before its value is injected into the controller. Be aware that
|
@@ -165,7 +179,7 @@ function $RouteProvider() {
|
|
165
179
|
* - `resolveAs` - `{string=}` - The name under which the `resolve` map will be available on
|
166
180
|
* the scope of the route. If omitted, defaults to `$resolve`.
|
167
181
|
*
|
168
|
-
* - `redirectTo` – `{(string|
|
182
|
+
* - `redirectTo` – `{(string|Function)=}` – value to update
|
169
183
|
* {@link ng.$location $location} path with and trigger route redirection.
|
170
184
|
*
|
171
185
|
* If `redirectTo` is a function, it will be called with the following parameters:
|
@@ -176,7 +190,31 @@ function $RouteProvider() {
|
|
176
190
|
* - `{Object}` - current `$location.search()`
|
177
191
|
*
|
178
192
|
* The custom `redirectTo` function is expected to return a string which will be used
|
179
|
-
* to update `$location.
|
193
|
+
* to update `$location.url()`. If the function throws an error, no further processing will
|
194
|
+
* take place and the {@link ngRoute.$route#$routeChangeError $routeChangeError} event will
|
195
|
+
* be fired.
|
196
|
+
*
|
197
|
+
* Routes that specify `redirectTo` will not have their controllers, template functions
|
198
|
+
* or resolves called, the `$location` will be changed to the redirect url and route
|
199
|
+
* processing will stop. The exception to this is if the `redirectTo` is a function that
|
200
|
+
* returns `undefined`. In this case the route transition occurs as though there was no
|
201
|
+
* redirection.
|
202
|
+
*
|
203
|
+
* - `resolveRedirectTo` – `{Function=}` – a function that will (eventually) return the value
|
204
|
+
* to update {@link ng.$location $location} URL with and trigger route redirection. In
|
205
|
+
* contrast to `redirectTo`, dependencies can be injected into `resolveRedirectTo` and the
|
206
|
+
* return value can be either a string or a promise that will be resolved to a string.
|
207
|
+
*
|
208
|
+
* Similar to `redirectTo`, if the return value is `undefined` (or a promise that gets
|
209
|
+
* resolved to `undefined`), no redirection takes place and the route transition occurs as
|
210
|
+
* though there was no redirection.
|
211
|
+
*
|
212
|
+
* If the function throws an error or the returned promise gets rejected, no further
|
213
|
+
* processing will take place and the
|
214
|
+
* {@link ngRoute.$route#$routeChangeError $routeChangeError} event will be fired.
|
215
|
+
*
|
216
|
+
* `redirectTo` takes precedence over `resolveRedirectTo`, so specifying both on the same
|
217
|
+
* route definition, will cause the latter to be ignored.
|
180
218
|
*
|
181
219
|
* - `[reloadOnSearch=true]` - `{boolean=}` - reload route when only `$location.search()`
|
182
220
|
* or `$location.hash()` changes.
|
@@ -210,7 +248,7 @@ function $RouteProvider() {
|
|
210
248
|
|
211
249
|
// create redirection for trailing slashes
|
212
250
|
if (path) {
|
213
|
-
var redirectPath = (path[path.length - 1]
|
251
|
+
var redirectPath = (path[path.length - 1] === '/')
|
214
252
|
? path.substr(0, path.length - 1)
|
215
253
|
: path + '/';
|
216
254
|
|
@@ -255,7 +293,7 @@ function $RouteProvider() {
|
|
255
293
|
|
256
294
|
path = path
|
257
295
|
.replace(/([().])/g, '\\$1')
|
258
|
-
.replace(/(\/)?:(\w+)(\*\?|[
|
296
|
+
.replace(/(\/)?:(\w+)(\*\?|[?*])?/g, function(_, slash, key, option) {
|
259
297
|
var optional = (option === '?' || option === '*?') ? '?' : null;
|
260
298
|
var star = (option === '*' || option === '*?') ? '*' : null;
|
261
299
|
keys.push({ name: key, optional: !!optional });
|
@@ -269,7 +307,7 @@ function $RouteProvider() {
|
|
269
307
|
+ ')'
|
270
308
|
+ (optional || '');
|
271
309
|
})
|
272
|
-
.replace(/([
|
310
|
+
.replace(/([/$*])/g, '\\$1');
|
273
311
|
|
274
312
|
ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
|
275
313
|
return ret;
|
@@ -295,6 +333,47 @@ function $RouteProvider() {
|
|
295
333
|
return this;
|
296
334
|
};
|
297
335
|
|
336
|
+
/**
|
337
|
+
* @ngdoc method
|
338
|
+
* @name $routeProvider#eagerInstantiationEnabled
|
339
|
+
* @kind function
|
340
|
+
*
|
341
|
+
* @description
|
342
|
+
* Call this method as a setter to enable/disable eager instantiation of the
|
343
|
+
* {@link ngRoute.$route $route} service upon application bootstrap. You can also call it as a
|
344
|
+
* getter (i.e. without any arguments) to get the current value of the
|
345
|
+
* `eagerInstantiationEnabled` flag.
|
346
|
+
*
|
347
|
+
* Instantiating `$route` early is necessary for capturing the initial
|
348
|
+
* {@link ng.$location#$locationChangeStart $locationChangeStart} event and navigating to the
|
349
|
+
* appropriate route. Usually, `$route` is instantiated in time by the
|
350
|
+
* {@link ngRoute.ngView ngView} directive. Yet, in cases where `ngView` is included in an
|
351
|
+
* asynchronously loaded template (e.g. in another directive's template), the directive factory
|
352
|
+
* might not be called soon enough for `$route` to be instantiated _before_ the initial
|
353
|
+
* `$locationChangeSuccess` event is fired. Eager instantiation ensures that `$route` is always
|
354
|
+
* instantiated in time, regardless of when `ngView` will be loaded.
|
355
|
+
*
|
356
|
+
* The default value is true.
|
357
|
+
*
|
358
|
+
* **Note**:<br />
|
359
|
+
* You may want to disable the default behavior when unit-testing modules that depend on
|
360
|
+
* `ngRoute`, in order to avoid an unexpected request for the default route's template.
|
361
|
+
*
|
362
|
+
* @param {boolean=} enabled - If provided, update the internal `eagerInstantiationEnabled` flag.
|
363
|
+
*
|
364
|
+
* @returns {*} The current value of the `eagerInstantiationEnabled` flag if used as a getter or
|
365
|
+
* itself (for chaining) if used as a setter.
|
366
|
+
*/
|
367
|
+
isEagerInstantiationEnabled = true;
|
368
|
+
this.eagerInstantiationEnabled = function eagerInstantiationEnabled(enabled) {
|
369
|
+
if (isDefined(enabled)) {
|
370
|
+
isEagerInstantiationEnabled = enabled;
|
371
|
+
return this;
|
372
|
+
}
|
373
|
+
|
374
|
+
return isEagerInstantiationEnabled;
|
375
|
+
};
|
376
|
+
|
298
377
|
|
299
378
|
this.$get = ['$rootScope',
|
300
379
|
'$location',
|
@@ -388,12 +467,12 @@ function $RouteProvider() {
|
|
388
467
|
* })
|
389
468
|
*
|
390
469
|
* .controller('BookController', function($scope, $routeParams) {
|
391
|
-
* $scope.name =
|
470
|
+
* $scope.name = 'BookController';
|
392
471
|
* $scope.params = $routeParams;
|
393
472
|
* })
|
394
473
|
*
|
395
474
|
* .controller('ChapterController', function($scope, $routeParams) {
|
396
|
-
* $scope.name =
|
475
|
+
* $scope.name = 'ChapterController';
|
397
476
|
* $scope.params = $routeParams;
|
398
477
|
* })
|
399
478
|
*
|
@@ -426,15 +505,15 @@ function $RouteProvider() {
|
|
426
505
|
* it('should load and compile correct template', function() {
|
427
506
|
* element(by.linkText('Moby: Ch1')).click();
|
428
507
|
* var content = element(by.css('[ng-view]')).getText();
|
429
|
-
* expect(content).toMatch(/controller
|
430
|
-
* expect(content).toMatch(/Book Id
|
431
|
-
* expect(content).toMatch(/Chapter Id
|
508
|
+
* expect(content).toMatch(/controller: ChapterController/);
|
509
|
+
* expect(content).toMatch(/Book Id: Moby/);
|
510
|
+
* expect(content).toMatch(/Chapter Id: 1/);
|
432
511
|
*
|
433
512
|
* element(by.partialLinkText('Scarlet')).click();
|
434
513
|
*
|
435
514
|
* content = element(by.css('[ng-view]')).getText();
|
436
|
-
* expect(content).toMatch(/controller
|
437
|
-
* expect(content).toMatch(/Book Id
|
515
|
+
* expect(content).toMatch(/controller: BookController/);
|
516
|
+
* expect(content).toMatch(/Book Id: Scarlet/);
|
438
517
|
* });
|
439
518
|
* </file>
|
440
519
|
* </example>
|
@@ -482,12 +561,14 @@ function $RouteProvider() {
|
|
482
561
|
* @name $route#$routeChangeError
|
483
562
|
* @eventType broadcast on root scope
|
484
563
|
* @description
|
485
|
-
* Broadcasted if any
|
564
|
+
* Broadcasted if a redirection function fails or any redirection or resolve promises are
|
565
|
+
* rejected.
|
486
566
|
*
|
487
567
|
* @param {Object} angularEvent Synthetic event object
|
488
568
|
* @param {Route} current Current route information.
|
489
569
|
* @param {Route} previous Previous route information.
|
490
|
-
* @param {Route} rejection
|
570
|
+
* @param {Route} rejection The thrown error or the rejection reason of the promise. Usually
|
571
|
+
* the rejection reason is the error that caused the promise to get rejected.
|
491
572
|
*/
|
492
573
|
|
493
574
|
/**
|
@@ -628,37 +709,103 @@ function $RouteProvider() {
|
|
628
709
|
} else if (nextRoute || lastRoute) {
|
629
710
|
forceReload = false;
|
630
711
|
$route.current = nextRoute;
|
631
|
-
if (nextRoute) {
|
632
|
-
if (nextRoute.redirectTo) {
|
633
|
-
if (angular.isString(nextRoute.redirectTo)) {
|
634
|
-
$location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params)
|
635
|
-
.replace();
|
636
|
-
} else {
|
637
|
-
$location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search()))
|
638
|
-
.replace();
|
639
|
-
}
|
640
|
-
}
|
641
|
-
}
|
642
712
|
|
643
|
-
$q.
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
713
|
+
var nextRoutePromise = $q.resolve(nextRoute);
|
714
|
+
|
715
|
+
nextRoutePromise.
|
716
|
+
then(getRedirectionData).
|
717
|
+
then(handlePossibleRedirection).
|
718
|
+
then(function(keepProcessingRoute) {
|
719
|
+
return keepProcessingRoute && nextRoutePromise.
|
720
|
+
then(resolveLocals).
|
721
|
+
then(function(locals) {
|
722
|
+
// after route change
|
723
|
+
if (nextRoute === $route.current) {
|
724
|
+
if (nextRoute) {
|
725
|
+
nextRoute.locals = locals;
|
726
|
+
angular.copy(nextRoute.params, $routeParams);
|
727
|
+
}
|
728
|
+
$rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute);
|
729
|
+
}
|
730
|
+
});
|
731
|
+
}).catch(function(error) {
|
732
|
+
if (nextRoute === $route.current) {
|
656
733
|
$rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error);
|
657
734
|
}
|
658
735
|
});
|
659
736
|
}
|
660
737
|
}
|
661
738
|
|
739
|
+
function getRedirectionData(route) {
|
740
|
+
var data = {
|
741
|
+
route: route,
|
742
|
+
hasRedirection: false
|
743
|
+
};
|
744
|
+
|
745
|
+
if (route) {
|
746
|
+
if (route.redirectTo) {
|
747
|
+
if (angular.isString(route.redirectTo)) {
|
748
|
+
data.path = interpolate(route.redirectTo, route.params);
|
749
|
+
data.search = route.params;
|
750
|
+
data.hasRedirection = true;
|
751
|
+
} else {
|
752
|
+
var oldPath = $location.path();
|
753
|
+
var oldSearch = $location.search();
|
754
|
+
var newUrl = route.redirectTo(route.pathParams, oldPath, oldSearch);
|
755
|
+
|
756
|
+
if (angular.isDefined(newUrl)) {
|
757
|
+
data.url = newUrl;
|
758
|
+
data.hasRedirection = true;
|
759
|
+
}
|
760
|
+
}
|
761
|
+
} else if (route.resolveRedirectTo) {
|
762
|
+
return $q.
|
763
|
+
resolve($injector.invoke(route.resolveRedirectTo)).
|
764
|
+
then(function(newUrl) {
|
765
|
+
if (angular.isDefined(newUrl)) {
|
766
|
+
data.url = newUrl;
|
767
|
+
data.hasRedirection = true;
|
768
|
+
}
|
769
|
+
|
770
|
+
return data;
|
771
|
+
});
|
772
|
+
}
|
773
|
+
}
|
774
|
+
|
775
|
+
return data;
|
776
|
+
}
|
777
|
+
|
778
|
+
function handlePossibleRedirection(data) {
|
779
|
+
var keepProcessingRoute = true;
|
780
|
+
|
781
|
+
if (data.route !== $route.current) {
|
782
|
+
keepProcessingRoute = false;
|
783
|
+
} else if (data.hasRedirection) {
|
784
|
+
var oldUrl = $location.url();
|
785
|
+
var newUrl = data.url;
|
786
|
+
|
787
|
+
if (newUrl) {
|
788
|
+
$location.
|
789
|
+
url(newUrl).
|
790
|
+
replace();
|
791
|
+
} else {
|
792
|
+
newUrl = $location.
|
793
|
+
path(data.path).
|
794
|
+
search(data.search).
|
795
|
+
replace().
|
796
|
+
url();
|
797
|
+
}
|
798
|
+
|
799
|
+
if (newUrl !== oldUrl) {
|
800
|
+
// Exit out and don't process current next value,
|
801
|
+
// wait for next location change from redirect
|
802
|
+
keepProcessingRoute = false;
|
803
|
+
}
|
804
|
+
}
|
805
|
+
|
806
|
+
return keepProcessingRoute;
|
807
|
+
}
|
808
|
+
|
662
809
|
function resolveLocals(route) {
|
663
810
|
if (route) {
|
664
811
|
var locals = angular.extend({}, route.resolve);
|
@@ -675,7 +822,6 @@ function $RouteProvider() {
|
|
675
822
|
}
|
676
823
|
}
|
677
824
|
|
678
|
-
|
679
825
|
function getTemplateFor(route) {
|
680
826
|
var template, templateUrl;
|
681
827
|
if (angular.isDefined(template = route.template)) {
|
@@ -694,7 +840,6 @@ function $RouteProvider() {
|
|
694
840
|
return template;
|
695
841
|
}
|
696
842
|
|
697
|
-
|
698
843
|
/**
|
699
844
|
* @returns {Object} the current active route, by matching it against the URL
|
700
845
|
*/
|
@@ -734,6 +879,14 @@ function $RouteProvider() {
|
|
734
879
|
}];
|
735
880
|
}
|
736
881
|
|
882
|
+
instantiateRoute.$inject = ['$injector'];
|
883
|
+
function instantiateRoute($injector) {
|
884
|
+
if (isEagerInstantiationEnabled) {
|
885
|
+
// Instantiate `$route`
|
886
|
+
$injector.get('$route');
|
887
|
+
}
|
888
|
+
}
|
889
|
+
|
737
890
|
ngRouteModule.provider('$routeParams', $RouteParamsProvider);
|
738
891
|
|
739
892
|
|
@@ -741,6 +894,7 @@ ngRouteModule.provider('$routeParams', $RouteParamsProvider);
|
|
741
894
|
* @ngdoc service
|
742
895
|
* @name $routeParams
|
743
896
|
* @requires $route
|
897
|
+
* @this
|
744
898
|
*
|
745
899
|
* @description
|
746
900
|
* The `$routeParams` service allows you to retrieve the current set of route parameters.
|
@@ -800,13 +954,6 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
|
|
800
954
|
*
|
801
955
|
* The enter and leave animation occur concurrently.
|
802
956
|
*
|
803
|
-
* @knownIssue If `ngView` is contained in an asynchronously loaded template (e.g. in another
|
804
|
-
* directive's templateUrl or in a template loaded using `ngInclude`), then you need to
|
805
|
-
* make sure that `$route` is instantiated in time to capture the initial
|
806
|
-
* `$locationChangeStart` event and load the appropriate view. One way to achieve this
|
807
|
-
* is to have it as a dependency in a `.run` block:
|
808
|
-
* `myModule.run(['$route', function() {}]);`
|
809
|
-
*
|
810
957
|
* @scope
|
811
958
|
* @priority 400
|
812
959
|
* @param {string=} onload Expression to evaluate whenever the view updates.
|
@@ -917,17 +1064,17 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
|
|
917
1064
|
$locationProvider.html5Mode(true);
|
918
1065
|
}])
|
919
1066
|
.controller('MainCtrl', ['$route', '$routeParams', '$location',
|
920
|
-
function($route, $routeParams, $location) {
|
1067
|
+
function MainCtrl($route, $routeParams, $location) {
|
921
1068
|
this.$route = $route;
|
922
1069
|
this.$location = $location;
|
923
1070
|
this.$routeParams = $routeParams;
|
924
1071
|
}])
|
925
|
-
.controller('BookCtrl', ['$routeParams', function($routeParams) {
|
926
|
-
this.name =
|
1072
|
+
.controller('BookCtrl', ['$routeParams', function BookCtrl($routeParams) {
|
1073
|
+
this.name = 'BookCtrl';
|
927
1074
|
this.params = $routeParams;
|
928
1075
|
}])
|
929
|
-
.controller('ChapterCtrl', ['$routeParams', function($routeParams) {
|
930
|
-
this.name =
|
1076
|
+
.controller('ChapterCtrl', ['$routeParams', function ChapterCtrl($routeParams) {
|
1077
|
+
this.name = 'ChapterCtrl';
|
931
1078
|
this.params = $routeParams;
|
932
1079
|
}]);
|
933
1080
|
|
@@ -937,15 +1084,15 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
|
|
937
1084
|
it('should load and compile correct template', function() {
|
938
1085
|
element(by.linkText('Moby: Ch1')).click();
|
939
1086
|
var content = element(by.css('[ng-view]')).getText();
|
940
|
-
expect(content).toMatch(/controller
|
941
|
-
expect(content).toMatch(/Book Id
|
942
|
-
expect(content).toMatch(/Chapter Id
|
1087
|
+
expect(content).toMatch(/controller: ChapterCtrl/);
|
1088
|
+
expect(content).toMatch(/Book Id: Moby/);
|
1089
|
+
expect(content).toMatch(/Chapter Id: 1/);
|
943
1090
|
|
944
1091
|
element(by.partialLinkText('Scarlet')).click();
|
945
1092
|
|
946
1093
|
content = element(by.css('[ng-view]')).getText();
|
947
|
-
expect(content).toMatch(/controller
|
948
|
-
expect(content).toMatch(/Book Id
|
1094
|
+
expect(content).toMatch(/controller: BookCtrl/);
|
1095
|
+
expect(content).toMatch(/Book Id: Scarlet/);
|
949
1096
|
});
|
950
1097
|
</file>
|
951
1098
|
</example>
|
@@ -988,8 +1135,8 @@ function ngViewFactory($route, $anchorScroll, $animate) {
|
|
988
1135
|
}
|
989
1136
|
if (currentElement) {
|
990
1137
|
previousLeaveAnimation = $animate.leave(currentElement);
|
991
|
-
previousLeaveAnimation.
|
992
|
-
previousLeaveAnimation = null;
|
1138
|
+
previousLeaveAnimation.done(function(response) {
|
1139
|
+
if (response !== false) previousLeaveAnimation = null;
|
993
1140
|
});
|
994
1141
|
currentElement = null;
|
995
1142
|
}
|
@@ -1010,8 +1157,8 @@ function ngViewFactory($route, $anchorScroll, $animate) {
|
|
1010
1157
|
// function is called before linking the content, which would apply child
|
1011
1158
|
// directives to non existing elements.
|
1012
1159
|
var clone = $transclude(newScope, function(clone) {
|
1013
|
-
$animate.enter(clone, null, currentElement || $element).
|
1014
|
-
if (angular.isDefined(autoScrollExp)
|
1160
|
+
$animate.enter(clone, null, currentElement || $element).done(function onNgViewEnter(response) {
|
1161
|
+
if (response !== false && angular.isDefined(autoScrollExp)
|
1015
1162
|
&& (!autoScrollExp || scope.$eval(autoScrollExp))) {
|
1016
1163
|
$anchorScroll();
|
1017
1164
|
}
|