angularjs-rails 1.2.19 → 1.2.20
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/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +75 -19
- data/vendor/assets/javascripts/angular-cookies.js +17 -15
- data/vendor/assets/javascripts/angular-loader.js +2 -2
- data/vendor/assets/javascripts/angular-mocks.js +1 -1
- data/vendor/assets/javascripts/angular-resource.js +1 -1
- data/vendor/assets/javascripts/angular-route.js +1 -1
- data/vendor/assets/javascripts/angular-sanitize.js +25 -23
- data/vendor/assets/javascripts/angular-scenario.js +505 -461
- data/vendor/assets/javascripts/angular-touch.js +1 -1
- data/vendor/assets/javascripts/angular.js +505 -461
- data/vendor/assets/javascripts/unstable/angular-animate.js +118 -41
- data/vendor/assets/javascripts/unstable/angular-cookies.js +17 -15
- data/vendor/assets/javascripts/unstable/angular-loader.js +2 -2
- data/vendor/assets/javascripts/unstable/angular-messages.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-mocks.js +2 -2
- data/vendor/assets/javascripts/unstable/angular-resource.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-route.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +25 -23
- data/vendor/assets/javascripts/unstable/angular-scenario.js +980 -759
- data/vendor/assets/javascripts/unstable/angular-touch.js +1 -1
- data/vendor/assets/javascripts/unstable/angular.js +980 -759
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.0-beta.
|
2
|
+
* @license AngularJS v1.3.0-beta.15
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -57,20 +57,21 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
|
|
57
57
|
* @returns {string} Sanitized html.
|
58
58
|
*
|
59
59
|
* @example
|
60
|
-
<example module="
|
60
|
+
<example module="sanitizeExample" deps="angular-sanitize.js">
|
61
61
|
<file name="index.html">
|
62
62
|
<script>
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
angular.module('sanitizeExample', ['ngSanitize'])
|
64
|
+
.controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
|
65
|
+
$scope.snippet =
|
66
|
+
'<p style="color:blue">an html\n' +
|
67
|
+
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
|
68
|
+
'snippet</p>';
|
69
|
+
$scope.deliberatelyTrustDangerousSnippet = function() {
|
70
|
+
return $sce.trustAsHtml($scope.snippet);
|
71
|
+
};
|
72
|
+
}]);
|
72
73
|
</script>
|
73
|
-
<div ng-controller="
|
74
|
+
<div ng-controller="ExampleController">
|
74
75
|
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
|
75
76
|
<table>
|
76
77
|
<tr>
|
@@ -498,20 +499,21 @@ angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
|
|
498
499
|
<span ng-bind-html="linky_expression | linky"></span>
|
499
500
|
*
|
500
501
|
* @example
|
501
|
-
<example module="
|
502
|
+
<example module="linkyExample" deps="angular-sanitize.js">
|
502
503
|
<file name="index.html">
|
503
504
|
<script>
|
504
|
-
|
505
|
-
$scope
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
505
|
+
angular.module('linkyExample', ['ngSanitize'])
|
506
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
507
|
+
$scope.snippet =
|
508
|
+
'Pretty text with some links:\n'+
|
509
|
+
'http://angularjs.org/,\n'+
|
510
|
+
'mailto:us@somewhere.org,\n'+
|
511
|
+
'another@somewhere.org,\n'+
|
512
|
+
'and one more: ftp://127.0.0.1/.';
|
513
|
+
$scope.snippetWithTarget = 'http://angularjs.org/';
|
514
|
+
}]);
|
513
515
|
</script>
|
514
|
-
<div ng-controller="
|
516
|
+
<div ng-controller="ExampleController">
|
515
517
|
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
|
516
518
|
<table>
|
517
519
|
<tr>
|
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
|
|
9790
9790
|
})( window );
|
9791
9791
|
|
9792
9792
|
/**
|
9793
|
-
* @license AngularJS v1.3.0-beta.
|
9793
|
+
* @license AngularJS v1.3.0-beta.15
|
9794
9794
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
9795
9795
|
* License: MIT
|
9796
9796
|
*/
|
@@ -9860,7 +9860,7 @@ function minErr(module) {
|
|
9860
9860
|
return match;
|
9861
9861
|
});
|
9862
9862
|
|
9863
|
-
message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.
|
9863
|
+
message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.15/' +
|
9864
9864
|
(module ? module + '/' : '') + code;
|
9865
9865
|
for (i = 2; i < arguments.length; i++) {
|
9866
9866
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -9872,89 +9872,87 @@ function minErr(module) {
|
|
9872
9872
|
}
|
9873
9873
|
|
9874
9874
|
/* We need to tell jshint what variables are being exported */
|
9875
|
-
/* global
|
9876
|
-
|
9877
|
-
|
9878
|
-
|
9879
|
-
|
9880
|
-
|
9881
|
-
|
9882
|
-
|
9883
|
-
|
9884
|
-
|
9885
|
-
|
9886
|
-
|
9887
|
-
|
9888
|
-
|
9889
|
-
|
9890
|
-
|
9891
|
-
|
9892
|
-
|
9893
|
-
|
9894
|
-
|
9895
|
-
|
9896
|
-
|
9897
|
-
|
9898
|
-
|
9899
|
-
|
9900
|
-
|
9901
|
-
|
9902
|
-
|
9903
|
-
|
9904
|
-
|
9905
|
-
|
9906
|
-
|
9907
|
-
|
9908
|
-
|
9909
|
-
|
9910
|
-
|
9911
|
-
|
9912
|
-
|
9913
|
-
|
9914
|
-
|
9915
|
-
|
9916
|
-
|
9917
|
-
|
9918
|
-
|
9919
|
-
|
9920
|
-
|
9921
|
-
|
9922
|
-
|
9923
|
-
|
9924
|
-
|
9925
|
-
|
9926
|
-
|
9927
|
-
|
9928
|
-
|
9929
|
-
|
9930
|
-
|
9931
|
-
|
9932
|
-
|
9933
|
-
|
9934
|
-
|
9935
|
-
|
9936
|
-
|
9937
|
-
|
9938
|
-
|
9939
|
-
|
9940
|
-
|
9941
|
-
|
9942
|
-
|
9943
|
-
|
9944
|
-
|
9945
|
-
|
9946
|
-
|
9947
|
-
|
9948
|
-
|
9949
|
-
|
9950
|
-
|
9951
|
-
|
9952
|
-
|
9953
|
-
|
9954
|
-
|
9955
|
-
|
9956
|
-
-hasOwnProperty,
|
9957
|
-
|
9875
|
+
/* global angular: true,
|
9876
|
+
msie: true,
|
9877
|
+
jqLite: true,
|
9878
|
+
jQuery: true,
|
9879
|
+
slice: true,
|
9880
|
+
push: true,
|
9881
|
+
toString: true,
|
9882
|
+
ngMinErr: true,
|
9883
|
+
angularModule: true,
|
9884
|
+
nodeName_: true,
|
9885
|
+
uid: true,
|
9886
|
+
REGEX_STRING_REGEXP: true,
|
9887
|
+
VALIDITY_STATE_PROPERTY: true,
|
9888
|
+
|
9889
|
+
lowercase: true,
|
9890
|
+
uppercase: true,
|
9891
|
+
manualLowercase: true,
|
9892
|
+
manualUppercase: true,
|
9893
|
+
nodeName_: true,
|
9894
|
+
isArrayLike: true,
|
9895
|
+
forEach: true,
|
9896
|
+
sortedKeys: true,
|
9897
|
+
forEachSorted: true,
|
9898
|
+
reverseParams: true,
|
9899
|
+
nextUid: true,
|
9900
|
+
setHashKey: true,
|
9901
|
+
extend: true,
|
9902
|
+
int: true,
|
9903
|
+
inherit: true,
|
9904
|
+
noop: true,
|
9905
|
+
identity: true,
|
9906
|
+
valueFn: true,
|
9907
|
+
isUndefined: true,
|
9908
|
+
isDefined: true,
|
9909
|
+
isObject: true,
|
9910
|
+
isString: true,
|
9911
|
+
isNumber: true,
|
9912
|
+
isDate: true,
|
9913
|
+
isArray: true,
|
9914
|
+
isFunction: true,
|
9915
|
+
isRegExp: true,
|
9916
|
+
isWindow: true,
|
9917
|
+
isScope: true,
|
9918
|
+
isFile: true,
|
9919
|
+
isBlob: true,
|
9920
|
+
isBoolean: true,
|
9921
|
+
trim: true,
|
9922
|
+
isElement: true,
|
9923
|
+
makeMap: true,
|
9924
|
+
map: true,
|
9925
|
+
size: true,
|
9926
|
+
includes: true,
|
9927
|
+
indexOf: true,
|
9928
|
+
arrayRemove: true,
|
9929
|
+
isLeafNode: true,
|
9930
|
+
copy: true,
|
9931
|
+
shallowCopy: true,
|
9932
|
+
equals: true,
|
9933
|
+
csp: true,
|
9934
|
+
concat: true,
|
9935
|
+
sliceArgs: true,
|
9936
|
+
bind: true,
|
9937
|
+
toJsonReplacer: true,
|
9938
|
+
toJson: true,
|
9939
|
+
fromJson: true,
|
9940
|
+
startingTag: true,
|
9941
|
+
tryDecodeURIComponent: true,
|
9942
|
+
parseKeyValue: true,
|
9943
|
+
toKeyValue: true,
|
9944
|
+
encodeUriSegment: true,
|
9945
|
+
encodeUriQuery: true,
|
9946
|
+
angularInit: true,
|
9947
|
+
bootstrap: true,
|
9948
|
+
snake_case: true,
|
9949
|
+
bindJQuery: true,
|
9950
|
+
assertArg: true,
|
9951
|
+
assertArgFn: true,
|
9952
|
+
assertNotHasOwnProperty: true,
|
9953
|
+
getter: true,
|
9954
|
+
getBlockElements: true,
|
9955
|
+
hasOwnProperty: true,
|
9958
9956
|
*/
|
9959
9957
|
|
9960
9958
|
////////////////////////////////////
|
@@ -10592,9 +10590,9 @@ function isLeafNode (node) {
|
|
10592
10590
|
* @returns {*} The copy or updated `destination`, if `destination` was specified.
|
10593
10591
|
*
|
10594
10592
|
* @example
|
10595
|
-
<example>
|
10593
|
+
<example module="copyExample">
|
10596
10594
|
<file name="index.html">
|
10597
|
-
<div ng-controller="
|
10595
|
+
<div ng-controller="ExampleController">
|
10598
10596
|
<form novalidate class="simple-form">
|
10599
10597
|
Name: <input type="text" ng-model="user.name" /><br />
|
10600
10598
|
E-mail: <input type="email" ng-model="user.email" /><br />
|
@@ -10608,21 +10606,22 @@ function isLeafNode (node) {
|
|
10608
10606
|
</div>
|
10609
10607
|
|
10610
10608
|
<script>
|
10611
|
-
|
10612
|
-
$scope
|
10609
|
+
angular.module('copyExample')
|
10610
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
10611
|
+
$scope.master= {};
|
10613
10612
|
|
10614
|
-
|
10615
|
-
|
10616
|
-
|
10617
|
-
|
10613
|
+
$scope.update = function(user) {
|
10614
|
+
// Example with 1 argument
|
10615
|
+
$scope.master= angular.copy(user);
|
10616
|
+
};
|
10618
10617
|
|
10619
|
-
|
10620
|
-
|
10621
|
-
|
10622
|
-
|
10618
|
+
$scope.reset = function() {
|
10619
|
+
// Example with 2 arguments
|
10620
|
+
angular.copy($scope.master, $scope.user);
|
10621
|
+
};
|
10623
10622
|
|
10624
|
-
|
10625
|
-
|
10623
|
+
$scope.reset();
|
10624
|
+
}]);
|
10626
10625
|
</script>
|
10627
10626
|
</file>
|
10628
10627
|
</example>
|
@@ -10962,7 +10961,7 @@ function parseKeyValue(/**string*/keyValue) {
|
|
10962
10961
|
key = tryDecodeURIComponent(key_value[0]);
|
10963
10962
|
if ( isDefined(key) ) {
|
10964
10963
|
var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
|
10965
|
-
if (!obj
|
10964
|
+
if (!hasOwnProperty.call(obj, key)) {
|
10966
10965
|
obj[key] = val;
|
10967
10966
|
} else if(isArray(obj[key])) {
|
10968
10967
|
obj[key].push(val);
|
@@ -11760,89 +11759,88 @@ function setupModuleLoader(window) {
|
|
11760
11759
|
|
11761
11760
|
}
|
11762
11761
|
|
11763
|
-
/* global
|
11764
|
-
|
11765
|
-
|
11766
|
-
|
11767
|
-
|
11768
|
-
|
11769
|
-
|
11770
|
-
|
11771
|
-
|
11772
|
-
|
11773
|
-
|
11774
|
-
|
11775
|
-
|
11776
|
-
|
11777
|
-
|
11778
|
-
|
11779
|
-
|
11780
|
-
|
11781
|
-
|
11782
|
-
|
11783
|
-
|
11784
|
-
|
11785
|
-
|
11786
|
-
|
11787
|
-
|
11788
|
-
|
11789
|
-
|
11790
|
-
|
11791
|
-
|
11792
|
-
|
11793
|
-
|
11794
|
-
|
11795
|
-
|
11796
|
-
|
11797
|
-
|
11798
|
-
|
11799
|
-
|
11800
|
-
|
11801
|
-
|
11802
|
-
|
11803
|
-
|
11804
|
-
|
11805
|
-
|
11806
|
-
|
11807
|
-
|
11808
|
-
|
11809
|
-
|
11810
|
-
|
11811
|
-
|
11812
|
-
|
11813
|
-
|
11814
|
-
|
11815
|
-
|
11816
|
-
|
11817
|
-
|
11818
|
-
|
11819
|
-
|
11820
|
-
|
11821
|
-
|
11822
|
-
|
11823
|
-
|
11824
|
-
|
11825
|
-
|
11826
|
-
|
11827
|
-
|
11828
|
-
|
11829
|
-
|
11830
|
-
|
11831
|
-
|
11832
|
-
|
11833
|
-
|
11834
|
-
|
11835
|
-
|
11836
|
-
|
11837
|
-
|
11838
|
-
|
11839
|
-
|
11840
|
-
|
11841
|
-
|
11842
|
-
|
11843
|
-
|
11844
|
-
|
11845
|
-
$WindowProvider
|
11762
|
+
/* global angularModule: true,
|
11763
|
+
version: true,
|
11764
|
+
|
11765
|
+
$LocaleProvider,
|
11766
|
+
$CompileProvider,
|
11767
|
+
|
11768
|
+
htmlAnchorDirective,
|
11769
|
+
inputDirective,
|
11770
|
+
inputDirective,
|
11771
|
+
formDirective,
|
11772
|
+
scriptDirective,
|
11773
|
+
selectDirective,
|
11774
|
+
styleDirective,
|
11775
|
+
optionDirective,
|
11776
|
+
ngBindDirective,
|
11777
|
+
ngBindHtmlDirective,
|
11778
|
+
ngBindTemplateDirective,
|
11779
|
+
ngClassDirective,
|
11780
|
+
ngClassEvenDirective,
|
11781
|
+
ngClassOddDirective,
|
11782
|
+
ngCspDirective,
|
11783
|
+
ngCloakDirective,
|
11784
|
+
ngControllerDirective,
|
11785
|
+
ngFormDirective,
|
11786
|
+
ngHideDirective,
|
11787
|
+
ngIfDirective,
|
11788
|
+
ngIncludeDirective,
|
11789
|
+
ngIncludeFillContentDirective,
|
11790
|
+
ngInitDirective,
|
11791
|
+
ngNonBindableDirective,
|
11792
|
+
ngPluralizeDirective,
|
11793
|
+
ngRepeatDirective,
|
11794
|
+
ngShowDirective,
|
11795
|
+
ngStyleDirective,
|
11796
|
+
ngSwitchDirective,
|
11797
|
+
ngSwitchWhenDirective,
|
11798
|
+
ngSwitchDefaultDirective,
|
11799
|
+
ngOptionsDirective,
|
11800
|
+
ngTranscludeDirective,
|
11801
|
+
ngModelDirective,
|
11802
|
+
ngListDirective,
|
11803
|
+
ngChangeDirective,
|
11804
|
+
patternDirective,
|
11805
|
+
patternDirective,
|
11806
|
+
requiredDirective,
|
11807
|
+
requiredDirective,
|
11808
|
+
minlengthDirective,
|
11809
|
+
minlengthDirective,
|
11810
|
+
maxlengthDirective,
|
11811
|
+
maxlengthDirective,
|
11812
|
+
ngValueDirective,
|
11813
|
+
ngModelOptionsDirective,
|
11814
|
+
ngAttributeAliasDirectives,
|
11815
|
+
ngEventDirectives,
|
11816
|
+
|
11817
|
+
$AnchorScrollProvider,
|
11818
|
+
$AnimateProvider,
|
11819
|
+
$BrowserProvider,
|
11820
|
+
$CacheFactoryProvider,
|
11821
|
+
$ControllerProvider,
|
11822
|
+
$DocumentProvider,
|
11823
|
+
$ExceptionHandlerProvider,
|
11824
|
+
$FilterProvider,
|
11825
|
+
$InterpolateProvider,
|
11826
|
+
$IntervalProvider,
|
11827
|
+
$HttpProvider,
|
11828
|
+
$HttpBackendProvider,
|
11829
|
+
$LocationProvider,
|
11830
|
+
$LogProvider,
|
11831
|
+
$ParseProvider,
|
11832
|
+
$RootScopeProvider,
|
11833
|
+
$QProvider,
|
11834
|
+
$$QProvider,
|
11835
|
+
$$SanitizeUriProvider,
|
11836
|
+
$SceProvider,
|
11837
|
+
$SceDelegateProvider,
|
11838
|
+
$SnifferProvider,
|
11839
|
+
$TemplateCacheProvider,
|
11840
|
+
$TimeoutProvider,
|
11841
|
+
$$RAFProvider,
|
11842
|
+
$$AsyncCallbackProvider,
|
11843
|
+
$WindowProvider
|
11846
11844
|
*/
|
11847
11845
|
|
11848
11846
|
|
@@ -11861,11 +11859,11 @@ function setupModuleLoader(window) {
|
|
11861
11859
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
11862
11860
|
*/
|
11863
11861
|
var version = {
|
11864
|
-
full: '1.3.0-beta.
|
11862
|
+
full: '1.3.0-beta.15', // all of these placeholder strings will be replaced by grunt's
|
11865
11863
|
major: 1, // package task
|
11866
11864
|
minor: 3,
|
11867
11865
|
dot: 0,
|
11868
|
-
codeName: '
|
11866
|
+
codeName: 'unbelievable-advancement'
|
11869
11867
|
};
|
11870
11868
|
|
11871
11869
|
|
@@ -11997,13 +11995,11 @@ function publishExternalAPI(angular){
|
|
11997
11995
|
]);
|
11998
11996
|
}
|
11999
11997
|
|
12000
|
-
/* global
|
12001
|
-
|
12002
|
-
|
12003
|
-
|
12004
|
-
|
12005
|
-
-BOOLEAN_ATTR,
|
12006
|
-
-ALIASED_ATTR
|
11998
|
+
/* global JQLitePrototype: true,
|
11999
|
+
addEventListenerFn: true,
|
12000
|
+
removeEventListenerFn: true,
|
12001
|
+
BOOLEAN_ATTR: true,
|
12002
|
+
ALIASED_ATTR: true,
|
12007
12003
|
*/
|
12008
12004
|
|
12009
12005
|
//////////////////////////////////
|
@@ -12242,12 +12238,16 @@ function jqLiteClone(element) {
|
|
12242
12238
|
return element.cloneNode(true);
|
12243
12239
|
}
|
12244
12240
|
|
12245
|
-
function jqLiteDealoc(element){
|
12246
|
-
jqLiteRemoveData(element);
|
12247
|
-
|
12248
|
-
|
12249
|
-
|
12250
|
-
|
12241
|
+
function jqLiteDealoc(element, onlyDescendants){
|
12242
|
+
if (!onlyDescendants) jqLiteRemoveData(element);
|
12243
|
+
|
12244
|
+
if (element.childNodes && element.childNodes.length) {
|
12245
|
+
// we use querySelectorAll because documentFragments don't have getElementsByTagName
|
12246
|
+
var descendants = element.getElementsByTagName ? element.getElementsByTagName('*') :
|
12247
|
+
element.querySelectorAll ? element.querySelectorAll('*') : [];
|
12248
|
+
for (var i = 0, l = descendants.length; i < l; i++) {
|
12249
|
+
jqLiteRemoveData(descendants[i]);
|
12250
|
+
}
|
12251
12251
|
}
|
12252
12252
|
}
|
12253
12253
|
|
@@ -12429,9 +12429,7 @@ function jqLiteInheritedData(element, name, value) {
|
|
12429
12429
|
}
|
12430
12430
|
|
12431
12431
|
function jqLiteEmpty(element) {
|
12432
|
-
|
12433
|
-
jqLiteDealoc(childNodes[i]);
|
12434
|
-
}
|
12432
|
+
jqLiteDealoc(element, true);
|
12435
12433
|
while (element.firstChild) {
|
12436
12434
|
element.removeChild(element.firstChild);
|
12437
12435
|
}
|
@@ -12629,9 +12627,7 @@ forEach({
|
|
12629
12627
|
if (isUndefined(value)) {
|
12630
12628
|
return element.innerHTML;
|
12631
12629
|
}
|
12632
|
-
|
12633
|
-
jqLiteDealoc(childNodes[i]);
|
12634
|
-
}
|
12630
|
+
jqLiteDealoc(element, true);
|
12635
12631
|
element.innerHTML = value;
|
12636
12632
|
},
|
12637
12633
|
|
@@ -12751,8 +12747,6 @@ function createEventHandler(element, events) {
|
|
12751
12747
|
forEach({
|
12752
12748
|
removeData: jqLiteRemoveData,
|
12753
12749
|
|
12754
|
-
dealoc: jqLiteDealoc,
|
12755
|
-
|
12756
12750
|
on: function onFn(element, type, fn, unsupported){
|
12757
12751
|
if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
|
12758
12752
|
|
@@ -13904,24 +13898,26 @@ createInjector.$$annotate = annotate;
|
|
13904
13898
|
* This can be disabled by calling `$anchorScrollProvider.disableAutoScrolling()`.
|
13905
13899
|
*
|
13906
13900
|
* @example
|
13907
|
-
<example>
|
13901
|
+
<example module="anchorScrollExample">
|
13908
13902
|
<file name="index.html">
|
13909
|
-
<div id="scrollArea" ng-controller="
|
13903
|
+
<div id="scrollArea" ng-controller="ScrollController">
|
13910
13904
|
<a ng-click="gotoBottom()">Go to bottom</a>
|
13911
13905
|
<a id="bottom"></a> You're at the bottom!
|
13912
13906
|
</div>
|
13913
13907
|
</file>
|
13914
13908
|
<file name="script.js">
|
13915
|
-
|
13916
|
-
$scope
|
13917
|
-
|
13918
|
-
|
13919
|
-
|
13920
|
-
|
13921
|
-
|
13922
|
-
|
13923
|
-
|
13924
|
-
|
13909
|
+
angular.module('anchorScrollExample', [])
|
13910
|
+
.controller('ScrollController', ['$scope', '$location', '$anchorScroll',
|
13911
|
+
function ($scope, $location, $anchorScroll) {
|
13912
|
+
$scope.gotoBottom = function() {
|
13913
|
+
// set the location.hash to the id of
|
13914
|
+
// the element you wish to scroll to.
|
13915
|
+
$location.hash('bottom');
|
13916
|
+
|
13917
|
+
// call $anchorScroll()
|
13918
|
+
$anchorScroll();
|
13919
|
+
};
|
13920
|
+
}]);
|
13925
13921
|
</file>
|
13926
13922
|
<file name="style.css">
|
13927
13923
|
#scrollArea {
|
@@ -14115,6 +14111,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
14115
14111
|
? after.after(element)
|
14116
14112
|
: parent.prepend(element);
|
14117
14113
|
async(done);
|
14114
|
+
return noop;
|
14118
14115
|
},
|
14119
14116
|
|
14120
14117
|
/**
|
@@ -14131,6 +14128,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
14131
14128
|
leave : function(element, done) {
|
14132
14129
|
element.remove();
|
14133
14130
|
async(done);
|
14131
|
+
return noop;
|
14134
14132
|
},
|
14135
14133
|
|
14136
14134
|
/**
|
@@ -14154,7 +14152,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
14154
14152
|
move : function(element, parent, after, done) {
|
14155
14153
|
// Do not remove element before insert. Removing will cause data associated with the
|
14156
14154
|
// element to be dropped. Insert will implicitly do the remove.
|
14157
|
-
this.enter(element, parent, after, done);
|
14155
|
+
return this.enter(element, parent, after, done);
|
14158
14156
|
},
|
14159
14157
|
|
14160
14158
|
/**
|
@@ -14171,13 +14169,14 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
14171
14169
|
* className value has been added to the element
|
14172
14170
|
*/
|
14173
14171
|
addClass : function(element, className, done) {
|
14174
|
-
className = isString(className)
|
14175
|
-
|
14176
|
-
|
14172
|
+
className = !isString(className)
|
14173
|
+
? (isArray(className) ? className.join(' ') : '')
|
14174
|
+
: className;
|
14177
14175
|
forEach(element, function (element) {
|
14178
14176
|
jqLiteAddClass(element, className);
|
14179
14177
|
});
|
14180
14178
|
async(done);
|
14179
|
+
return noop;
|
14181
14180
|
},
|
14182
14181
|
|
14183
14182
|
/**
|
@@ -14201,6 +14200,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
14201
14200
|
jqLiteRemoveClass(element, className);
|
14202
14201
|
});
|
14203
14202
|
async(done);
|
14203
|
+
return noop;
|
14204
14204
|
},
|
14205
14205
|
|
14206
14206
|
/**
|
@@ -14223,6 +14223,7 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
14223
14223
|
jqLiteRemoveClass(element, remove);
|
14224
14224
|
});
|
14225
14225
|
async(done);
|
14226
|
+
return noop;
|
14226
14227
|
},
|
14227
14228
|
|
14228
14229
|
enabled : noop
|
@@ -15182,7 +15183,7 @@ function $TemplateCacheProvider() {
|
|
15182
15183
|
* local name. Given `<widget my-attr="count = count + value">` and widget definition of
|
15183
15184
|
* `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to
|
15184
15185
|
* a function wrapper for the `count = count + value` expression. Often it's desirable to
|
15185
|
-
* pass data from the isolated scope via an expression
|
15186
|
+
* pass data from the isolated scope via an expression to the parent scope, this can be
|
15186
15187
|
* done by passing a map of local variable names and values into the expression wrapper fn.
|
15187
15188
|
* For example, if the expression is `increment(amount)` then we can specify the amount value
|
15188
15189
|
* by calling the `localFn` as `localFn({amount: 22})`.
|
@@ -15422,10 +15423,10 @@ function $TemplateCacheProvider() {
|
|
15422
15423
|
* to illustrate how `$compile` works.
|
15423
15424
|
* </div>
|
15424
15425
|
*
|
15425
|
-
<example module="
|
15426
|
+
<example module="compileExample">
|
15426
15427
|
<file name="index.html">
|
15427
15428
|
<script>
|
15428
|
-
angular.module('
|
15429
|
+
angular.module('compileExample', [], function($compileProvider) {
|
15429
15430
|
// configure new 'compile' directive by passing a directive
|
15430
15431
|
// factory function. The factory function injects the '$compile'
|
15431
15432
|
$compileProvider.directive('compile', function($compile) {
|
@@ -15449,15 +15450,14 @@ function $TemplateCacheProvider() {
|
|
15449
15450
|
}
|
15450
15451
|
);
|
15451
15452
|
};
|
15452
|
-
})
|
15453
|
-
})
|
15454
|
-
|
15455
|
-
function Ctrl($scope) {
|
15453
|
+
});
|
15454
|
+
})
|
15455
|
+
.controller('GreeterController', ['$scope', function($scope) {
|
15456
15456
|
$scope.name = 'Angular';
|
15457
15457
|
$scope.html = 'Hello {{name}}';
|
15458
|
-
}
|
15458
|
+
}]);
|
15459
15459
|
</script>
|
15460
|
-
<div ng-controller="
|
15460
|
+
<div ng-controller="GreeterController">
|
15461
15461
|
<input ng-model="name"> <br>
|
15462
15462
|
<textarea ng-model="html"></textarea> <br>
|
15463
15463
|
<div compile="html"></div>
|
@@ -15885,14 +15885,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
15885
15885
|
$linkNode.data('$' + name + 'Controller', instance);
|
15886
15886
|
});
|
15887
15887
|
|
15888
|
-
|
15889
|
-
for(var i = 0, ii = $linkNode.length; i<ii; i++) {
|
15890
|
-
var node = $linkNode[i],
|
15891
|
-
nodeType = node.nodeType;
|
15892
|
-
if (nodeType === 1 /* element */ || nodeType === 9 /* document */) {
|
15893
|
-
$linkNode.eq(i).data('$scope', scope);
|
15894
|
-
}
|
15895
|
-
}
|
15888
|
+
$linkNode.data('$scope', scope);
|
15896
15889
|
|
15897
15890
|
if (cloneConnectFn) cloneConnectFn($linkNode, scope);
|
15898
15891
|
if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
|
@@ -17148,6 +17141,7 @@ function tokenDifference(str1, str2) {
|
|
17148
17141
|
*/
|
17149
17142
|
function $ControllerProvider() {
|
17150
17143
|
var controllers = {},
|
17144
|
+
globals = false,
|
17151
17145
|
CNTRL_REG = /^(\S+)(\s+as\s+(\w+))?$/;
|
17152
17146
|
|
17153
17147
|
|
@@ -17168,6 +17162,15 @@ function $ControllerProvider() {
|
|
17168
17162
|
}
|
17169
17163
|
};
|
17170
17164
|
|
17165
|
+
/**
|
17166
|
+
* @ngdoc method
|
17167
|
+
* @name $controllerProvider#allowGlobals
|
17168
|
+
* @description If called, allows `$controller` to find controller constructors on `window`
|
17169
|
+
*/
|
17170
|
+
this.allowGlobals = function() {
|
17171
|
+
globals = true;
|
17172
|
+
};
|
17173
|
+
|
17171
17174
|
|
17172
17175
|
this.$get = ['$injector', '$window', function($injector, $window) {
|
17173
17176
|
|
@@ -17182,7 +17185,8 @@ function $ControllerProvider() {
|
|
17182
17185
|
*
|
17183
17186
|
* * check if a controller with given name is registered via `$controllerProvider`
|
17184
17187
|
* * check if evaluating the string on the current scope returns a constructor
|
17185
|
-
* * check `window[constructor]` on the global
|
17188
|
+
* * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
|
17189
|
+
* `window` object (not recommended)
|
17186
17190
|
*
|
17187
17191
|
* @param {Object} locals Injection locals for Controller.
|
17188
17192
|
* @return {Object} Instance of given controller.
|
@@ -17202,7 +17206,8 @@ function $ControllerProvider() {
|
|
17202
17206
|
identifier = match[3];
|
17203
17207
|
expression = controllers.hasOwnProperty(constructor)
|
17204
17208
|
? controllers[constructor]
|
17205
|
-
: getter(locals.$scope, constructor, true) ||
|
17209
|
+
: getter(locals.$scope, constructor, true) ||
|
17210
|
+
(globals ? getter($window, constructor, true) : undefined);
|
17206
17211
|
|
17207
17212
|
assertArgFn(expression, constructor, true);
|
17208
17213
|
}
|
@@ -17233,18 +17238,19 @@ function $ControllerProvider() {
|
|
17233
17238
|
* A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.
|
17234
17239
|
*
|
17235
17240
|
* @example
|
17236
|
-
<example>
|
17241
|
+
<example module="documentExample">
|
17237
17242
|
<file name="index.html">
|
17238
|
-
<div ng-controller="
|
17243
|
+
<div ng-controller="ExampleController">
|
17239
17244
|
<p>$document title: <b ng-bind="title"></b></p>
|
17240
17245
|
<p>window.document title: <b ng-bind="windowTitle"></b></p>
|
17241
17246
|
</div>
|
17242
17247
|
</file>
|
17243
17248
|
<file name="script.js">
|
17244
|
-
|
17245
|
-
$scope
|
17246
|
-
|
17247
|
-
|
17249
|
+
angular.module('documentExample', [])
|
17250
|
+
.controller('ExampleController', ['$scope', '$document', function($scope, $document) {
|
17251
|
+
$scope.title = $document[0].title;
|
17252
|
+
$scope.windowTitle = angular.element(window.document)[0].title;
|
17253
|
+
}]);
|
17248
17254
|
</file>
|
17249
17255
|
</example>
|
17250
17256
|
*/
|
@@ -17377,12 +17383,39 @@ function isSuccess(status) {
|
|
17377
17383
|
}
|
17378
17384
|
|
17379
17385
|
|
17386
|
+
/**
|
17387
|
+
* @ngdoc provider
|
17388
|
+
* @name $httpProvider
|
17389
|
+
* @description
|
17390
|
+
* Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
|
17391
|
+
* */
|
17380
17392
|
function $HttpProvider() {
|
17381
17393
|
var JSON_START = /^\s*(\[|\{[^\{])/,
|
17382
17394
|
JSON_END = /[\}\]]\s*$/,
|
17383
17395
|
PROTECTION_PREFIX = /^\)\]\}',?\n/,
|
17384
17396
|
CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'};
|
17385
17397
|
|
17398
|
+
/**
|
17399
|
+
* @ngdoc property
|
17400
|
+
* @name $httpProvider#defaults
|
17401
|
+
* @description
|
17402
|
+
*
|
17403
|
+
* Object containing default values for all {@link ng.$http $http} requests.
|
17404
|
+
*
|
17405
|
+
* - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
|
17406
|
+
* Defaults value is `'XSRF-TOKEN'`.
|
17407
|
+
*
|
17408
|
+
* - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the
|
17409
|
+
* XSRF token. Defaults value is `'X-XSRF-TOKEN'`.
|
17410
|
+
*
|
17411
|
+
* - **`defaults.headers`** - {Object} - Default headers for all $http requests.
|
17412
|
+
* Refer to {@link ng.$http#setting-http-headers $http} for documentation on
|
17413
|
+
* setting default headers.
|
17414
|
+
* - **`defaults.headers.common`**
|
17415
|
+
* - **`defaults.headers.post`**
|
17416
|
+
* - **`defaults.headers.put`**
|
17417
|
+
* - **`defaults.headers.patch`**
|
17418
|
+
**/
|
17386
17419
|
var defaults = this.defaults = {
|
17387
17420
|
// transform incoming response data
|
17388
17421
|
transformResponse: [function(data) {
|
@@ -17800,9 +17833,9 @@ function $HttpProvider() {
|
|
17800
17833
|
*
|
17801
17834
|
*
|
17802
17835
|
* @example
|
17803
|
-
<example>
|
17836
|
+
<example module="httpExample">
|
17804
17837
|
<file name="index.html">
|
17805
|
-
<div ng-controller="
|
17838
|
+
<div ng-controller="FetchController">
|
17806
17839
|
<select ng-model="method">
|
17807
17840
|
<option>GET</option>
|
17808
17841
|
<option>JSONP</option>
|
@@ -17824,30 +17857,32 @@ function $HttpProvider() {
|
|
17824
17857
|
</div>
|
17825
17858
|
</file>
|
17826
17859
|
<file name="script.js">
|
17827
|
-
|
17828
|
-
$scope
|
17829
|
-
|
17830
|
-
|
17831
|
-
|
17832
|
-
|
17833
|
-
|
17834
|
-
|
17835
|
-
|
17836
|
-
|
17837
|
-
$scope.
|
17838
|
-
|
17839
|
-
|
17840
|
-
|
17841
|
-
|
17842
|
-
|
17843
|
-
|
17844
|
-
|
17860
|
+
angular.module('httpExample', [])
|
17861
|
+
.controller('FetchController', ['$scope', '$http', '$templateCache',
|
17862
|
+
function($scope, $http, $templateCache) {
|
17863
|
+
$scope.method = 'GET';
|
17864
|
+
$scope.url = 'http-hello.html';
|
17865
|
+
|
17866
|
+
$scope.fetch = function() {
|
17867
|
+
$scope.code = null;
|
17868
|
+
$scope.response = null;
|
17869
|
+
|
17870
|
+
$http({method: $scope.method, url: $scope.url, cache: $templateCache}).
|
17871
|
+
success(function(data, status) {
|
17872
|
+
$scope.status = status;
|
17873
|
+
$scope.data = data;
|
17874
|
+
}).
|
17875
|
+
error(function(data, status) {
|
17876
|
+
$scope.data = data || "Request failed";
|
17877
|
+
$scope.status = status;
|
17878
|
+
});
|
17879
|
+
};
|
17845
17880
|
|
17846
|
-
|
17847
|
-
|
17848
|
-
|
17849
|
-
|
17850
|
-
|
17881
|
+
$scope.updateModel = function(method, url) {
|
17882
|
+
$scope.method = method;
|
17883
|
+
$scope.url = url;
|
17884
|
+
};
|
17885
|
+
}]);
|
17851
17886
|
</file>
|
17852
17887
|
<file name="http-hello.html">
|
17853
17888
|
Hello, $http!
|
@@ -17901,7 +17936,7 @@ function $HttpProvider() {
|
|
17901
17936
|
var reqData = transformData(config.data, headersGetter(headers), config.transformRequest);
|
17902
17937
|
|
17903
17938
|
// strip content-type if data is undefined
|
17904
|
-
if (isUndefined(
|
17939
|
+
if (isUndefined(reqData)) {
|
17905
17940
|
forEach(headers, function(value, header) {
|
17906
17941
|
if (lowercase(header) === 'content-type') {
|
17907
17942
|
delete headers[header];
|
@@ -17970,10 +18005,6 @@ function $HttpProvider() {
|
|
17970
18005
|
|
17971
18006
|
defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
|
17972
18007
|
|
17973
|
-
// execute if header value is function
|
17974
|
-
execHeaders(defHeaders);
|
17975
|
-
execHeaders(reqHeaders);
|
17976
|
-
|
17977
18008
|
// using for-in instead of forEach to avoid unecessary iteration after header has been found
|
17978
18009
|
defaultHeadersIteration:
|
17979
18010
|
for (defHeaderName in defHeaders) {
|
@@ -17988,6 +18019,8 @@ function $HttpProvider() {
|
|
17988
18019
|
reqHeaders[defHeaderName] = defHeaders[defHeaderName];
|
17989
18020
|
}
|
17990
18021
|
|
18022
|
+
// execute if header value is a function for merged headers
|
18023
|
+
execHeaders(reqHeaders);
|
17991
18024
|
return reqHeaders;
|
17992
18025
|
|
17993
18026
|
function execHeaders(headers) {
|
@@ -18895,25 +18928,27 @@ function $IntervalProvider() {
|
|
18895
18928
|
* @returns {promise} A promise which will be notified on each iteration.
|
18896
18929
|
*
|
18897
18930
|
* @example
|
18898
|
-
* <example module="
|
18899
|
-
*
|
18900
|
-
*
|
18901
|
-
*
|
18902
|
-
*
|
18903
|
-
* $scope
|
18904
|
-
*
|
18931
|
+
* <example module="intervalExample">
|
18932
|
+
* <file name="index.html">
|
18933
|
+
* <script>
|
18934
|
+
* angular.module('intervalExample', [])
|
18935
|
+
* .controller('ExampleController', ['$scope', '$interval',
|
18936
|
+
* function($scope, $interval) {
|
18937
|
+
* $scope.format = 'M/d/yy h:mm:ss a';
|
18938
|
+
* $scope.blood_1 = 100;
|
18939
|
+
* $scope.blood_2 = 120;
|
18905
18940
|
*
|
18906
|
-
*
|
18907
|
-
*
|
18908
|
-
*
|
18909
|
-
*
|
18941
|
+
* var stop;
|
18942
|
+
* $scope.fight = function() {
|
18943
|
+
* // Don't start a new fight if we are already fighting
|
18944
|
+
* if ( angular.isDefined(stop) ) return;
|
18910
18945
|
*
|
18911
18946
|
* stop = $interval(function() {
|
18912
18947
|
* if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
|
18913
|
-
*
|
18914
|
-
*
|
18948
|
+
* $scope.blood_1 = $scope.blood_1 - 3;
|
18949
|
+
* $scope.blood_2 = $scope.blood_2 - 4;
|
18915
18950
|
* } else {
|
18916
|
-
*
|
18951
|
+
* $scope.stopFight();
|
18917
18952
|
* }
|
18918
18953
|
* }, 100);
|
18919
18954
|
* };
|
@@ -18928,22 +18963,21 @@ function $IntervalProvider() {
|
|
18928
18963
|
* $scope.resetFight = function() {
|
18929
18964
|
* $scope.blood_1 = 100;
|
18930
18965
|
* $scope.blood_2 = 120;
|
18931
|
-
* }
|
18966
|
+
* };
|
18932
18967
|
*
|
18933
18968
|
* $scope.$on('$destroy', function() {
|
18934
|
-
* // Make sure that the interval
|
18969
|
+
* // Make sure that the interval nis destroyed too
|
18935
18970
|
* $scope.stopFight();
|
18936
18971
|
* });
|
18937
|
-
* }
|
18938
|
-
*
|
18939
|
-
*
|
18940
|
-
*
|
18941
|
-
*
|
18942
|
-
* .directive('myCurrentTime', function($interval, dateFilter) {
|
18972
|
+
* })
|
18973
|
+
* // Register the 'myCurrentTime' directive factory method.
|
18974
|
+
* // We inject $interval and dateFilter service since the factory method is DI.
|
18975
|
+
* .directive('myCurrentTime', ['$interval', 'dateFilter',
|
18976
|
+
* function($interval, dateFilter) {
|
18943
18977
|
* // return the directive link function. (compile function not needed)
|
18944
18978
|
* return function(scope, element, attrs) {
|
18945
18979
|
* var format, // date format
|
18946
|
-
*
|
18980
|
+
* stopTime; // so that we can cancel the time updates
|
18947
18981
|
*
|
18948
18982
|
* // used to update the UI
|
18949
18983
|
* function updateTime() {
|
@@ -18959,28 +18993,28 @@ function $IntervalProvider() {
|
|
18959
18993
|
* stopTime = $interval(updateTime, 1000);
|
18960
18994
|
*
|
18961
18995
|
* // listen on DOM destroy (removal) event, and cancel the next UI update
|
18962
|
-
* // to prevent updating time
|
18996
|
+
* // to prevent updating time after the DOM element was removed.
|
18963
18997
|
* element.on('$destroy', function() {
|
18964
18998
|
* $interval.cancel(stopTime);
|
18965
18999
|
* });
|
18966
19000
|
* }
|
18967
19001
|
* });
|
18968
|
-
*
|
19002
|
+
* </script>
|
18969
19003
|
*
|
18970
|
-
*
|
18971
|
-
*
|
18972
|
-
*
|
18973
|
-
*
|
18974
|
-
*
|
18975
|
-
*
|
18976
|
-
*
|
18977
|
-
*
|
18978
|
-
*
|
18979
|
-
*
|
18980
|
-
* </div>
|
19004
|
+
* <div>
|
19005
|
+
* <div ng-controller="ExampleController">
|
19006
|
+
* Date format: <input ng-model="format"> <hr/>
|
19007
|
+
* Current time is: <span my-current-time="format"></span>
|
19008
|
+
* <hr/>
|
19009
|
+
* Blood 1 : <font color='red'>{{blood_1}}</font>
|
19010
|
+
* Blood 2 : <font color='red'>{{blood_2}}</font>
|
19011
|
+
* <button type="button" data-ng-click="fight()">Fight</button>
|
19012
|
+
* <button type="button" data-ng-click="stopFight()">StopFight</button>
|
19013
|
+
* <button type="button" data-ng-click="resetFight()">resetFight</button>
|
18981
19014
|
* </div>
|
19015
|
+
* </div>
|
18982
19016
|
*
|
18983
|
-
*
|
19017
|
+
* </file>
|
18984
19018
|
* </example>
|
18985
19019
|
*/
|
18986
19020
|
function interval(fn, delay, count, invokeApply) {
|
@@ -19537,14 +19571,17 @@ LocationHashbangInHtml5Url.prototype =
|
|
19537
19571
|
* If the argument is a hash object containing an array of values, these values will be encoded
|
19538
19572
|
* as duplicate search parameters in the url.
|
19539
19573
|
*
|
19540
|
-
* @param {(string|Array<string
|
19541
|
-
* override only a single search property.
|
19574
|
+
* @param {(string|Array<string>|boolean)=} paramValue If `search` is a string, then `paramValue`
|
19575
|
+
* will override only a single search property.
|
19542
19576
|
*
|
19543
19577
|
* If `paramValue` is an array, it will override the property of the `search` component of
|
19544
19578
|
* `$location` specified via the first argument.
|
19545
19579
|
*
|
19546
19580
|
* If `paramValue` is `null`, the property specified via the first argument will be deleted.
|
19547
19581
|
*
|
19582
|
+
* If `paramValue` is `true`, the property specified via the first argument will be added with no
|
19583
|
+
* value nor trailing equal sign.
|
19584
|
+
*
|
19548
19585
|
* @return {Object} If called with no arguments returns the parsed `search` object. If called with
|
19549
19586
|
* one or more arguments returns `$location` object itself.
|
19550
19587
|
*/
|
@@ -19556,6 +19593,11 @@ LocationHashbangInHtml5Url.prototype =
|
|
19556
19593
|
if (isString(search)) {
|
19557
19594
|
this.$$search = parseKeyValue(search);
|
19558
19595
|
} else if (isObject(search)) {
|
19596
|
+
// remove object undefined or null properties
|
19597
|
+
forEach(search, function(value, key) {
|
19598
|
+
if (value == null) delete search[key];
|
19599
|
+
});
|
19600
|
+
|
19559
19601
|
this.$$search = search;
|
19560
19602
|
} else {
|
19561
19603
|
throw $locationMinErr('isrcharg',
|
@@ -19877,15 +19919,16 @@ function $LocationProvider(){
|
|
19877
19919
|
* {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
|
19878
19920
|
*
|
19879
19921
|
* @example
|
19880
|
-
<example>
|
19922
|
+
<example module="logExample">
|
19881
19923
|
<file name="script.js">
|
19882
|
-
|
19883
|
-
$scope
|
19884
|
-
|
19885
|
-
|
19924
|
+
angular.module('logExample', [])
|
19925
|
+
.controller('LogController', ['$scope', '$log', function($scope, $log) {
|
19926
|
+
$scope.$log = $log;
|
19927
|
+
$scope.message = 'Hello World!';
|
19928
|
+
}]);
|
19886
19929
|
</file>
|
19887
19930
|
<file name="index.html">
|
19888
|
-
<div ng-controller="
|
19931
|
+
<div ng-controller="LogController">
|
19889
19932
|
<p>Reload this page with open console, enter text and hit the log button...</p>
|
19890
19933
|
Message:
|
19891
19934
|
<input type="text" ng-model="message"/>
|
@@ -19909,7 +19952,7 @@ function $LogProvider(){
|
|
19909
19952
|
self = this;
|
19910
19953
|
|
19911
19954
|
/**
|
19912
|
-
* @ngdoc
|
19955
|
+
* @ngdoc method
|
19913
19956
|
* @name $logProvider#debugEnabled
|
19914
19957
|
* @description
|
19915
19958
|
* @param {boolean=} flag enable or disable debug level messages
|
@@ -20898,26 +20941,6 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp) {
|
|
20898
20941
|
};
|
20899
20942
|
}
|
20900
20943
|
|
20901
|
-
function simpleGetterFn1(key0, fullExp) {
|
20902
|
-
ensureSafeMemberName(key0, fullExp);
|
20903
|
-
|
20904
|
-
return function simpleGetterFn1(scope, locals) {
|
20905
|
-
if (scope == null) return undefined;
|
20906
|
-
return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
|
20907
|
-
};
|
20908
|
-
}
|
20909
|
-
|
20910
|
-
function simpleGetterFn2(key0, key1, fullExp) {
|
20911
|
-
ensureSafeMemberName(key0, fullExp);
|
20912
|
-
ensureSafeMemberName(key1, fullExp);
|
20913
|
-
|
20914
|
-
return function simpleGetterFn2(scope, locals) {
|
20915
|
-
if (scope == null) return undefined;
|
20916
|
-
scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
|
20917
|
-
return scope == null ? undefined : scope[key1];
|
20918
|
-
};
|
20919
|
-
}
|
20920
|
-
|
20921
20944
|
function getterFn(path, options, fullExp) {
|
20922
20945
|
// Check whether the cache has this getter already.
|
20923
20946
|
// We can use hasOwnProperty directly on the cache because we ensure,
|
@@ -20930,13 +20953,8 @@ function getterFn(path, options, fullExp) {
|
|
20930
20953
|
pathKeysLength = pathKeys.length,
|
20931
20954
|
fn;
|
20932
20955
|
|
20933
|
-
// When we have only 1 or 2 tokens, use optimized special case closures.
|
20934
20956
|
// http://jsperf.com/angularjs-parse-getter/6
|
20935
|
-
if (
|
20936
|
-
fn = simpleGetterFn1(pathKeys[0], fullExp);
|
20937
|
-
} else if (pathKeysLength === 2) {
|
20938
|
-
fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp);
|
20939
|
-
} else if (options.csp) {
|
20957
|
+
if (options.csp) {
|
20940
20958
|
if (pathKeysLength < 6) {
|
20941
20959
|
fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp);
|
20942
20960
|
} else {
|
@@ -23074,19 +23092,21 @@ function adjustMatchers(matchers) {
|
|
23074
23092
|
*
|
23075
23093
|
* Here is what a secure configuration for this scenario might look like:
|
23076
23094
|
*
|
23077
|
-
*
|
23078
|
-
*
|
23079
|
-
*
|
23080
|
-
*
|
23081
|
-
*
|
23082
|
-
*
|
23083
|
-
*
|
23084
|
-
*
|
23085
|
-
*
|
23086
|
-
*
|
23087
|
-
*
|
23088
|
-
*
|
23089
|
-
*
|
23095
|
+
* ```
|
23096
|
+
* angular.module('myApp', []).config(function($sceDelegateProvider) {
|
23097
|
+
* $sceDelegateProvider.resourceUrlWhitelist([
|
23098
|
+
* // Allow same origin resource loads.
|
23099
|
+
* 'self',
|
23100
|
+
* // Allow loading from our assets domain. Notice the difference between * and **.
|
23101
|
+
* 'http://srv*.assets.example.com/**'
|
23102
|
+
* ]);
|
23103
|
+
*
|
23104
|
+
* // The blacklist overrides the whitelist so the open redirect here is blocked.
|
23105
|
+
* $sceDelegateProvider.resourceUrlBlacklist([
|
23106
|
+
* 'http://myapp.example.com/clickThru**'
|
23107
|
+
* ]);
|
23108
|
+
* });
|
23109
|
+
* ```
|
23090
23110
|
*/
|
23091
23111
|
|
23092
23112
|
function $SceDelegateProvider() {
|
@@ -23381,10 +23401,10 @@ function $SceDelegateProvider() {
|
|
23381
23401
|
*
|
23382
23402
|
* Here's an example of a binding in a privileged context:
|
23383
23403
|
*
|
23384
|
-
*
|
23385
|
-
*
|
23386
|
-
*
|
23387
|
-
*
|
23404
|
+
* ```
|
23405
|
+
* <input ng-model="userHtml">
|
23406
|
+
* <div ng-bind-html="userHtml"></div>
|
23407
|
+
* ```
|
23388
23408
|
*
|
23389
23409
|
* Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE
|
23390
23410
|
* disabled, this application allows the user to render arbitrary HTML into the DIV.
|
@@ -23424,15 +23444,15 @@ function $SceDelegateProvider() {
|
|
23424
23444
|
* ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly
|
23425
23445
|
* simplified):
|
23426
23446
|
*
|
23427
|
-
*
|
23428
|
-
*
|
23429
|
-
*
|
23430
|
-
*
|
23431
|
-
*
|
23432
|
-
*
|
23433
|
-
*
|
23434
|
-
*
|
23435
|
-
*
|
23447
|
+
* ```
|
23448
|
+
* var ngBindHtmlDirective = ['$sce', function($sce) {
|
23449
|
+
* return function(scope, element, attr) {
|
23450
|
+
* scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
|
23451
|
+
* element.html(value || '');
|
23452
|
+
* });
|
23453
|
+
* };
|
23454
|
+
* }];
|
23455
|
+
* ```
|
23436
23456
|
*
|
23437
23457
|
* ## Impact on loading templates
|
23438
23458
|
*
|
@@ -23536,66 +23556,65 @@ function $SceDelegateProvider() {
|
|
23536
23556
|
*
|
23537
23557
|
* ## Show me an example using SCE.
|
23538
23558
|
*
|
23539
|
-
*
|
23540
|
-
<
|
23541
|
-
<
|
23542
|
-
|
23543
|
-
|
23544
|
-
|
23545
|
-
|
23546
|
-
|
23547
|
-
|
23548
|
-
|
23549
|
-
|
23550
|
-
|
23551
|
-
|
23552
|
-
|
23553
|
-
|
23554
|
-
|
23555
|
-
|
23556
|
-
|
23557
|
-
|
23558
|
-
|
23559
|
-
|
23560
|
-
|
23561
|
-
|
23562
|
-
|
23563
|
-
|
23564
|
-
|
23565
|
-
|
23566
|
-
|
23567
|
-
|
23568
|
-
|
23569
|
-
|
23570
|
-
|
23571
|
-
|
23572
|
-
|
23573
|
-
|
23574
|
-
|
23575
|
-
|
23576
|
-
|
23577
|
-
|
23578
|
-
|
23579
|
-
|
23580
|
-
|
23581
|
-
|
23582
|
-
|
23583
|
-
|
23584
|
-
|
23585
|
-
|
23586
|
-
|
23587
|
-
|
23588
|
-
|
23589
|
-
|
23590
|
-
|
23591
|
-
|
23592
|
-
|
23593
|
-
|
23594
|
-
|
23595
|
-
|
23596
|
-
|
23597
|
-
</
|
23598
|
-
</example>
|
23559
|
+
* <example module="mySceApp" deps="angular-sanitize.js">
|
23560
|
+
* <file name="index.html">
|
23561
|
+
* <div ng-controller="AppController as myCtrl">
|
23562
|
+
* <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
|
23563
|
+
* <b>User comments</b><br>
|
23564
|
+
* By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
|
23565
|
+
* $sanitize is available. If $sanitize isn't available, this results in an error instead of an
|
23566
|
+
* exploit.
|
23567
|
+
* <div class="well">
|
23568
|
+
* <div ng-repeat="userComment in myCtrl.userComments">
|
23569
|
+
* <b>{{userComment.name}}</b>:
|
23570
|
+
* <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
|
23571
|
+
* <br>
|
23572
|
+
* </div>
|
23573
|
+
* </div>
|
23574
|
+
* </div>
|
23575
|
+
* </file>
|
23576
|
+
*
|
23577
|
+
* <file name="script.js">
|
23578
|
+
* angular.module('mySceApp', ['ngSanitize'])
|
23579
|
+
* .controller('AppController', ['$http', '$templateCache', '$sce',
|
23580
|
+
* function($http, $templateCache, $sce) {
|
23581
|
+
* var self = this;
|
23582
|
+
* $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
|
23583
|
+
* self.userComments = userComments;
|
23584
|
+
* });
|
23585
|
+
* self.explicitlyTrustedHtml = $sce.trustAsHtml(
|
23586
|
+
* '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
|
23587
|
+
* 'sanitization."">Hover over this text.</span>');
|
23588
|
+
* }]);
|
23589
|
+
* </file>
|
23590
|
+
*
|
23591
|
+
* <file name="test_data.json">
|
23592
|
+
* [
|
23593
|
+
* { "name": "Alice",
|
23594
|
+
* "htmlComment":
|
23595
|
+
* "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
|
23596
|
+
* },
|
23597
|
+
* { "name": "Bob",
|
23598
|
+
* "htmlComment": "<i>Yes!</i> Am I the only other one?"
|
23599
|
+
* }
|
23600
|
+
* ]
|
23601
|
+
* </file>
|
23602
|
+
*
|
23603
|
+
* <file name="protractor.js" type="protractor">
|
23604
|
+
* describe('SCE doc demo', function() {
|
23605
|
+
* it('should sanitize untrusted values', function() {
|
23606
|
+
* expect(element.all(by.css('.htmlComment')).first().getInnerHtml())
|
23607
|
+
* .toBe('<span>Is <i>anyone</i> reading this?</span>');
|
23608
|
+
* });
|
23609
|
+
*
|
23610
|
+
* it('should NOT sanitize explicitly trusted values', function() {
|
23611
|
+
* expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
|
23612
|
+
* '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
|
23613
|
+
* 'sanitization."">Hover over this text.</span>');
|
23614
|
+
* });
|
23615
|
+
* });
|
23616
|
+
* </file>
|
23617
|
+
* </example>
|
23599
23618
|
*
|
23600
23619
|
*
|
23601
23620
|
*
|
@@ -23609,13 +23628,13 @@ function $SceDelegateProvider() {
|
|
23609
23628
|
*
|
23610
23629
|
* That said, here's how you can completely disable SCE:
|
23611
23630
|
*
|
23612
|
-
*
|
23613
|
-
*
|
23614
|
-
*
|
23615
|
-
*
|
23616
|
-
*
|
23617
|
-
*
|
23618
|
-
*
|
23631
|
+
* ```
|
23632
|
+
* angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
|
23633
|
+
* // Completely disable SCE. For demonstration purposes only!
|
23634
|
+
* // Do not use in new projects.
|
23635
|
+
* $sceProvider.enabled(false);
|
23636
|
+
* });
|
23637
|
+
* ```
|
23619
23638
|
*
|
23620
23639
|
*/
|
23621
23640
|
/* jshint maxlen: 100 */
|
@@ -24314,17 +24333,18 @@ function urlIsSameOrigin(requestUrl) {
|
|
24314
24333
|
* expression.
|
24315
24334
|
*
|
24316
24335
|
* @example
|
24317
|
-
<example>
|
24336
|
+
<example module="windowExample">
|
24318
24337
|
<file name="index.html">
|
24319
24338
|
<script>
|
24320
|
-
|
24321
|
-
$scope
|
24322
|
-
|
24339
|
+
angular.module('windowExample', [])
|
24340
|
+
.controller('ExampleController', ['$scope', '$window', function ($scope, $window) {
|
24341
|
+
$scope.greeting = 'Hello, World!';
|
24342
|
+
$scope.doGreeting = function(greeting) {
|
24323
24343
|
$window.alert(greeting);
|
24324
|
-
|
24325
|
-
|
24344
|
+
};
|
24345
|
+
}]);
|
24326
24346
|
</script>
|
24327
|
-
<div ng-controller="
|
24347
|
+
<div ng-controller="ExampleController">
|
24328
24348
|
<input type="text" ng-model="greeting" />
|
24329
24349
|
<button ng-click="doGreeting(greeting)">ALERT</button>
|
24330
24350
|
</div>
|
@@ -24342,6 +24362,17 @@ function $WindowProvider(){
|
|
24342
24362
|
this.$get = valueFn(window);
|
24343
24363
|
}
|
24344
24364
|
|
24365
|
+
/* global currencyFilter: true,
|
24366
|
+
dateFilter: true,
|
24367
|
+
filterFilter: true,
|
24368
|
+
jsonFilter: true,
|
24369
|
+
limitToFilter: true,
|
24370
|
+
lowercaseFilter: true,
|
24371
|
+
numberFilter: true,
|
24372
|
+
orderByFilter: true,
|
24373
|
+
uppercaseFilter: true,
|
24374
|
+
*/
|
24375
|
+
|
24345
24376
|
/**
|
24346
24377
|
* @ngdoc provider
|
24347
24378
|
* @name $filterProvider
|
@@ -24723,14 +24754,15 @@ function filterFilter() {
|
|
24723
24754
|
*
|
24724
24755
|
*
|
24725
24756
|
* @example
|
24726
|
-
<example>
|
24757
|
+
<example module="currencyExample">
|
24727
24758
|
<file name="index.html">
|
24728
24759
|
<script>
|
24729
|
-
|
24730
|
-
$scope
|
24731
|
-
|
24760
|
+
angular.module('currencyExample', [])
|
24761
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
24762
|
+
$scope.amount = 1234.56;
|
24763
|
+
}]);
|
24732
24764
|
</script>
|
24733
|
-
<div ng-controller="
|
24765
|
+
<div ng-controller="ExampleController">
|
24734
24766
|
<input type="number" ng-model="amount"> <br>
|
24735
24767
|
default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
|
24736
24768
|
custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
|
@@ -24782,14 +24814,15 @@ function currencyFilter($locale) {
|
|
24782
24814
|
* @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
|
24783
24815
|
*
|
24784
24816
|
* @example
|
24785
|
-
<example>
|
24817
|
+
<example module="numberFilterExample">
|
24786
24818
|
<file name="index.html">
|
24787
24819
|
<script>
|
24788
|
-
|
24789
|
-
$scope
|
24790
|
-
|
24820
|
+
angular.module('numberFilterExample', [])
|
24821
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
24822
|
+
$scope.val = 1234.56789;
|
24823
|
+
}]);
|
24791
24824
|
</script>
|
24792
|
-
<div ng-controller="
|
24825
|
+
<div ng-controller="ExampleController">
|
24793
24826
|
Enter number: <input ng-model='val'><br>
|
24794
24827
|
Default formatting: <span id='number-default'>{{val | number}}</span><br>
|
24795
24828
|
No fractions: <span>{{val | number:0}}</span><br>
|
@@ -25243,17 +25276,18 @@ var uppercaseFilter = valueFn(uppercase);
|
|
25243
25276
|
* had less than `limit` elements.
|
25244
25277
|
*
|
25245
25278
|
* @example
|
25246
|
-
<example>
|
25279
|
+
<example module="limitToExample">
|
25247
25280
|
<file name="index.html">
|
25248
25281
|
<script>
|
25249
|
-
|
25250
|
-
$scope
|
25251
|
-
|
25252
|
-
|
25253
|
-
|
25254
|
-
|
25282
|
+
angular.module('limitToExample', [])
|
25283
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
25284
|
+
$scope.numbers = [1,2,3,4,5,6,7,8,9];
|
25285
|
+
$scope.letters = "abcdefghi";
|
25286
|
+
$scope.numLimit = 3;
|
25287
|
+
$scope.letterLimit = 3;
|
25288
|
+
}]);
|
25255
25289
|
</script>
|
25256
|
-
<div ng-controller="
|
25290
|
+
<div ng-controller="ExampleController">
|
25257
25291
|
Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
|
25258
25292
|
<p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
|
25259
25293
|
Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
|
@@ -25365,20 +25399,21 @@ function limitToFilter(){
|
|
25365
25399
|
* @returns {Array} Sorted copy of the source array.
|
25366
25400
|
*
|
25367
25401
|
* @example
|
25368
|
-
<example>
|
25402
|
+
<example module="orderByExample">
|
25369
25403
|
<file name="index.html">
|
25370
25404
|
<script>
|
25371
|
-
|
25372
|
-
$scope
|
25373
|
-
|
25374
|
-
|
25375
|
-
|
25376
|
-
|
25377
|
-
|
25378
|
-
|
25379
|
-
|
25405
|
+
angular.module('orderByExample', [])
|
25406
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
25407
|
+
$scope.friends =
|
25408
|
+
[{name:'John', phone:'555-1212', age:10},
|
25409
|
+
{name:'Mary', phone:'555-9876', age:19},
|
25410
|
+
{name:'Mike', phone:'555-4321', age:21},
|
25411
|
+
{name:'Adam', phone:'555-5678', age:35},
|
25412
|
+
{name:'Julie', phone:'555-8765', age:29}];
|
25413
|
+
$scope.predicate = '-age';
|
25414
|
+
}]);
|
25380
25415
|
</script>
|
25381
|
-
<div ng-controller="
|
25416
|
+
<div ng-controller="ExampleController">
|
25382
25417
|
<pre>Sorting predicate = {{predicate}}; reverse = {{reverse}}</pre>
|
25383
25418
|
<hr/>
|
25384
25419
|
[ <a href="" ng-click="predicate=''">unsorted</a> ]
|
@@ -25406,7 +25441,7 @@ function limitToFilter(){
|
|
25406
25441
|
* Example:
|
25407
25442
|
*
|
25408
25443
|
* @example
|
25409
|
-
<example>
|
25444
|
+
<example module="orderByExample">
|
25410
25445
|
<file name="index.html">
|
25411
25446
|
<div ng-controller="Ctrl">
|
25412
25447
|
<table class="friend">
|
@@ -25426,21 +25461,21 @@ function limitToFilter(){
|
|
25426
25461
|
</file>
|
25427
25462
|
|
25428
25463
|
<file name="script.js">
|
25429
|
-
|
25430
|
-
|
25431
|
-
|
25432
|
-
|
25433
|
-
|
25434
|
-
|
25435
|
-
|
25436
|
-
|
25437
|
-
|
25438
|
-
|
25439
|
-
|
25440
|
-
|
25441
|
-
|
25442
|
-
|
25443
|
-
|
25464
|
+
angular.module('orderByExample', [])
|
25465
|
+
.controller('ExampleController', ['$scope', '$filter', function($scope, $filter) {
|
25466
|
+
var orderBy = $filter('orderBy');
|
25467
|
+
$scope.friends = [
|
25468
|
+
{ name: 'John', phone: '555-1212', age: 10 },
|
25469
|
+
{ name: 'Mary', phone: '555-9876', age: 19 },
|
25470
|
+
{ name: 'Mike', phone: '555-4321', age: 21 },
|
25471
|
+
{ name: 'Adam', phone: '555-5678', age: 35 },
|
25472
|
+
{ name: 'Julie', phone: '555-8765', age: 29 }
|
25473
|
+
];
|
25474
|
+
$scope.order = function(predicate, reverse) {
|
25475
|
+
$scope.friends = orderBy($scope.friends, predicate, reverse);
|
25476
|
+
};
|
25477
|
+
$scope.order('-age',false);
|
25478
|
+
}]);
|
25444
25479
|
</file>
|
25445
25480
|
</example>
|
25446
25481
|
*/
|
@@ -25626,7 +25661,7 @@ var htmlAnchorDirective = valueFn({
|
|
25626
25661
|
return browser.driver.getCurrentUrl().then(function(url) {
|
25627
25662
|
return url.match(/\/123$/);
|
25628
25663
|
});
|
25629
|
-
},
|
25664
|
+
}, 5000, 'page should navigate to /123');
|
25630
25665
|
});
|
25631
25666
|
|
25632
25667
|
xit('should execute ng-click but not reload when href empty string and name specified', function() {
|
@@ -25654,7 +25689,7 @@ var htmlAnchorDirective = valueFn({
|
|
25654
25689
|
return browser.driver.getCurrentUrl().then(function(url) {
|
25655
25690
|
return url.match(/\/6$/);
|
25656
25691
|
});
|
25657
|
-
},
|
25692
|
+
}, 5000, 'page should navigate to /6');
|
25658
25693
|
});
|
25659
25694
|
</file>
|
25660
25695
|
</example>
|
@@ -26053,6 +26088,23 @@ function FormController(element, attrs, $scope, $animate) {
|
|
26053
26088
|
$animate.addClass(element, (isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
|
26054
26089
|
}
|
26055
26090
|
|
26091
|
+
/**
|
26092
|
+
* @ngdoc method
|
26093
|
+
* @name form.FormController#$rollbackViewValue
|
26094
|
+
*
|
26095
|
+
* @description
|
26096
|
+
* Rollback all form controls pending updates to the `$modelValue`.
|
26097
|
+
*
|
26098
|
+
* Updates may be pending by a debounced event or because the input is waiting for a some future
|
26099
|
+
* event defined in `ng-model-options`. This method is typically needed by the reset button of
|
26100
|
+
* a form that uses `ng-model-options` to pend updates.
|
26101
|
+
*/
|
26102
|
+
form.$rollbackViewValue = function() {
|
26103
|
+
forEach(controls, function(control) {
|
26104
|
+
control.$rollbackViewValue();
|
26105
|
+
});
|
26106
|
+
};
|
26107
|
+
|
26056
26108
|
/**
|
26057
26109
|
* @ngdoc method
|
26058
26110
|
* @name form.FormController#$commitViewValue
|
@@ -26314,12 +26366,13 @@ function FormController(element, attrs, $scope, $animate) {
|
|
26314
26366
|
* </pre>
|
26315
26367
|
*
|
26316
26368
|
* @example
|
26317
|
-
<example deps="angular-animate.js" animations="true" fixBase="true">
|
26369
|
+
<example deps="angular-animate.js" animations="true" fixBase="true" module="formExample">
|
26318
26370
|
<file name="index.html">
|
26319
26371
|
<script>
|
26320
|
-
|
26321
|
-
$scope
|
26322
|
-
|
26372
|
+
angular.module('formExample', [])
|
26373
|
+
.controller('FormController', ['$scope', function($scope) {
|
26374
|
+
$scope.userType = 'guest';
|
26375
|
+
}]);
|
26323
26376
|
</script>
|
26324
26377
|
<style>
|
26325
26378
|
.my-form {
|
@@ -26331,7 +26384,7 @@ function FormController(element, attrs, $scope, $animate) {
|
|
26331
26384
|
background: red;
|
26332
26385
|
}
|
26333
26386
|
</style>
|
26334
|
-
<form name="myForm" ng-controller="
|
26387
|
+
<form name="myForm" ng-controller="FormController" class="my-form">
|
26335
26388
|
userType: <input name="input" ng-model="userType" required>
|
26336
26389
|
<span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
|
26337
26390
|
<tt>userType = {{userType}}</tt><br>
|
@@ -26429,18 +26482,16 @@ var formDirectiveFactory = function(isNgForm) {
|
|
26429
26482
|
var formDirective = formDirectiveFactory();
|
26430
26483
|
var ngFormDirective = formDirectiveFactory(true);
|
26431
26484
|
|
26432
|
-
/* global
|
26433
|
-
|
26434
|
-
|
26435
|
-
|
26436
|
-
|
26437
|
-
|
26438
|
-
-UNTOUCHED_CLASS,
|
26439
|
-
-TOUCHED_CLASS
|
26485
|
+
/* global VALID_CLASS: true,
|
26486
|
+
INVALID_CLASS: true,
|
26487
|
+
PRISTINE_CLASS: true,
|
26488
|
+
DIRTY_CLASS: true,
|
26489
|
+
UNTOUCHED_CLASS: true,
|
26490
|
+
TOUCHED_CLASS: true,
|
26440
26491
|
*/
|
26441
26492
|
|
26442
26493
|
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
|
26443
|
-
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9-]
|
26494
|
+
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
|
26444
26495
|
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
|
26445
26496
|
var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
|
26446
26497
|
var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)$/;
|
@@ -26476,15 +26527,16 @@ var inputType = {
|
|
26476
26527
|
* @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
|
26477
26528
|
*
|
26478
26529
|
* @example
|
26479
|
-
<example name="text-input-directive">
|
26530
|
+
<example name="text-input-directive" module="textInputExample">
|
26480
26531
|
<file name="index.html">
|
26481
26532
|
<script>
|
26482
|
-
|
26483
|
-
$scope
|
26484
|
-
|
26485
|
-
|
26533
|
+
angular.module('textInputExample', [])
|
26534
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
26535
|
+
$scope.text = 'guest';
|
26536
|
+
$scope.word = /^\s*\w*\s*$/;
|
26537
|
+
}]);
|
26486
26538
|
</script>
|
26487
|
-
<form name="myForm" ng-controller="
|
26539
|
+
<form name="myForm" ng-controller="ExampleController">
|
26488
26540
|
Single word: <input type="text" name="input" ng-model="text"
|
26489
26541
|
ng-pattern="word" required ng-trim="false">
|
26490
26542
|
<span class="error" ng-show="myForm.input.$error.required">
|
@@ -26551,14 +26603,15 @@ var inputType = {
|
|
26551
26603
|
* interaction with the input element.
|
26552
26604
|
*
|
26553
26605
|
* @example
|
26554
|
-
<example name="date-input-directive">
|
26606
|
+
<example name="date-input-directive" module="dateInputExample">
|
26555
26607
|
<file name="index.html">
|
26556
26608
|
<script>
|
26557
|
-
|
26558
|
-
|
26559
|
-
|
26609
|
+
angular.module('dateInputExample', [])
|
26610
|
+
.controller('DateController', ['$scope', function($scope) {
|
26611
|
+
$scope.value = new Date(2013, 9, 22);
|
26612
|
+
}]);
|
26560
26613
|
</script>
|
26561
|
-
<form name="myForm" ng-controller="
|
26614
|
+
<form name="myForm" ng-controller="DateController as dateCtrl">
|
26562
26615
|
Pick a date between in 2013:
|
26563
26616
|
<input type="date" id="exampleInput" name="input" ng-model="value"
|
26564
26617
|
placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
|
@@ -26635,14 +26688,15 @@ var inputType = {
|
|
26635
26688
|
* interaction with the input element.
|
26636
26689
|
*
|
26637
26690
|
* @example
|
26638
|
-
<example name="datetimelocal-input-directive">
|
26691
|
+
<example name="datetimelocal-input-directive" module="dateExample">
|
26639
26692
|
<file name="index.html">
|
26640
26693
|
<script>
|
26641
|
-
|
26642
|
-
|
26643
|
-
|
26694
|
+
angular.module('dateExample', [])
|
26695
|
+
.controller('DateController', ['$scope', function($scope) {
|
26696
|
+
$scope.value = new Date(2010, 11, 28, 14, 57);
|
26697
|
+
}]);
|
26644
26698
|
</script>
|
26645
|
-
<form name="myForm" ng-controller="
|
26699
|
+
<form name="myForm" ng-controller="DateController as dateCtrl">
|
26646
26700
|
Pick a date between in 2013:
|
26647
26701
|
<input type="datetime-local" id="exampleInput" name="input" ng-model="value"
|
26648
26702
|
placeholder="yyyy-MM-ddTHH:mm" min="2001-01-01T00:00" max="2013-12-31T00:00" required />
|
@@ -26720,14 +26774,15 @@ var inputType = {
|
|
26720
26774
|
* interaction with the input element.
|
26721
26775
|
*
|
26722
26776
|
* @example
|
26723
|
-
<example name="time-input-directive">
|
26777
|
+
<example name="time-input-directive" module="timeExample">
|
26724
26778
|
<file name="index.html">
|
26725
26779
|
<script>
|
26726
|
-
|
26727
|
-
|
26728
|
-
|
26780
|
+
angular.module('timeExample', [])
|
26781
|
+
.controller('DateController', ['$scope', function($scope) {
|
26782
|
+
$scope.value = new Date(0, 0, 1, 14, 57);
|
26783
|
+
}]);
|
26729
26784
|
</script>
|
26730
|
-
<form name="myForm" ng-controller="
|
26785
|
+
<form name="myForm" ng-controller="DateController as dateCtrl">
|
26731
26786
|
Pick a between 8am and 5pm:
|
26732
26787
|
<input type="time" id="exampleInput" name="input" ng-model="value"
|
26733
26788
|
placeholder="HH:mm" min="08:00" max="17:00" required />
|
@@ -26804,14 +26859,15 @@ var inputType = {
|
|
26804
26859
|
* interaction with the input element.
|
26805
26860
|
*
|
26806
26861
|
* @example
|
26807
|
-
<example name="week-input-directive">
|
26862
|
+
<example name="week-input-directive" module="weekExample">
|
26808
26863
|
<file name="index.html">
|
26809
26864
|
<script>
|
26810
|
-
|
26811
|
-
|
26812
|
-
|
26865
|
+
angular.module('weekExample', [])
|
26866
|
+
.controller('DateController', ['$scope', function($scope) {
|
26867
|
+
$scope.value = new Date(2013, 0, 3);
|
26868
|
+
}]);
|
26813
26869
|
</script>
|
26814
|
-
<form name="myForm" ng-controller="
|
26870
|
+
<form name="myForm" ng-controller="DateController as dateCtrl">
|
26815
26871
|
Pick a date between in 2013:
|
26816
26872
|
<input id="exampleInput" type="week" name="input" ng-model="value"
|
26817
26873
|
placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
|
@@ -26887,14 +26943,15 @@ var inputType = {
|
|
26887
26943
|
* interaction with the input element.
|
26888
26944
|
*
|
26889
26945
|
* @example
|
26890
|
-
<example name="month-input-directive">
|
26946
|
+
<example name="month-input-directive" module="monthExample">
|
26891
26947
|
<file name="index.html">
|
26892
26948
|
<script>
|
26893
|
-
|
26894
|
-
|
26895
|
-
|
26949
|
+
angular.module('monthExample', [])
|
26950
|
+
.controller('DateController', ['$scope', function($scope) {
|
26951
|
+
$scope.value = new Date(2013, 9, 1);
|
26952
|
+
}]);
|
26896
26953
|
</script>
|
26897
|
-
<form name="myForm" ng-controller="
|
26954
|
+
<form name="myForm" ng-controller="DateController as dateCtrl">
|
26898
26955
|
Pick a month int 2013:
|
26899
26956
|
<input id="exampleInput" type="month" name="input" ng-model="value"
|
26900
26957
|
placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
|
@@ -26975,14 +27032,15 @@ var inputType = {
|
|
26975
27032
|
* interaction with the input element.
|
26976
27033
|
*
|
26977
27034
|
* @example
|
26978
|
-
<example name="number-input-directive">
|
27035
|
+
<example name="number-input-directive" module="numberExample">
|
26979
27036
|
<file name="index.html">
|
26980
27037
|
<script>
|
26981
|
-
|
26982
|
-
$scope
|
26983
|
-
|
27038
|
+
angular.module('numberExample', [])
|
27039
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
27040
|
+
$scope.value = 12;
|
27041
|
+
}]);
|
26984
27042
|
</script>
|
26985
|
-
<form name="myForm" ng-controller="
|
27043
|
+
<form name="myForm" ng-controller="ExampleController">
|
26986
27044
|
Number: <input type="number" name="input" ng-model="value"
|
26987
27045
|
min="0" max="99" required>
|
26988
27046
|
<span class="error" ng-show="myForm.input.$error.required">
|
@@ -27050,14 +27108,15 @@ var inputType = {
|
|
27050
27108
|
* interaction with the input element.
|
27051
27109
|
*
|
27052
27110
|
* @example
|
27053
|
-
<example name="url-input-directive">
|
27111
|
+
<example name="url-input-directive" module="urlExample">
|
27054
27112
|
<file name="index.html">
|
27055
27113
|
<script>
|
27056
|
-
|
27057
|
-
$scope
|
27058
|
-
|
27114
|
+
angular.module('urlExample', [])
|
27115
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
27116
|
+
$scope.text = 'http://google.com';
|
27117
|
+
}]);
|
27059
27118
|
</script>
|
27060
|
-
<form name="myForm" ng-controller="
|
27119
|
+
<form name="myForm" ng-controller="ExampleController">
|
27061
27120
|
URL: <input type="url" name="input" ng-model="text" required>
|
27062
27121
|
<span class="error" ng-show="myForm.input.$error.required">
|
27063
27122
|
Required!</span>
|
@@ -27126,14 +27185,15 @@ var inputType = {
|
|
27126
27185
|
* interaction with the input element.
|
27127
27186
|
*
|
27128
27187
|
* @example
|
27129
|
-
<example name="email-input-directive">
|
27188
|
+
<example name="email-input-directive" module="emailExample">
|
27130
27189
|
<file name="index.html">
|
27131
27190
|
<script>
|
27132
|
-
|
27133
|
-
$scope
|
27134
|
-
|
27191
|
+
angular.module('emailExample', [])
|
27192
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
27193
|
+
$scope.text = 'me@example.com';
|
27194
|
+
}]);
|
27135
27195
|
</script>
|
27136
|
-
<form name="myForm" ng-controller="
|
27196
|
+
<form name="myForm" ng-controller="ExampleController">
|
27137
27197
|
Email: <input type="email" name="input" ng-model="text" required>
|
27138
27198
|
<span class="error" ng-show="myForm.input.$error.required">
|
27139
27199
|
Required!</span>
|
@@ -27192,18 +27252,19 @@ var inputType = {
|
|
27192
27252
|
* be set when selected.
|
27193
27253
|
*
|
27194
27254
|
* @example
|
27195
|
-
<example name="radio-input-directive">
|
27255
|
+
<example name="radio-input-directive" module="radioExample">
|
27196
27256
|
<file name="index.html">
|
27197
27257
|
<script>
|
27198
|
-
|
27199
|
-
$scope
|
27200
|
-
|
27201
|
-
|
27202
|
-
|
27203
|
-
|
27204
|
-
|
27258
|
+
angular.module('radioExample', [])
|
27259
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
27260
|
+
$scope.color = 'blue';
|
27261
|
+
$scope.specialValue = {
|
27262
|
+
"id": "12345",
|
27263
|
+
"value": "green"
|
27264
|
+
};
|
27265
|
+
}]);
|
27205
27266
|
</script>
|
27206
|
-
<form name="myForm" ng-controller="
|
27267
|
+
<form name="myForm" ng-controller="ExampleController">
|
27207
27268
|
<input type="radio" ng-model="color" value="red"> Red <br/>
|
27208
27269
|
<input type="radio" ng-model="color" ng-value="specialValue"> Green <br/>
|
27209
27270
|
<input type="radio" ng-model="color" value="blue"> Blue <br/>
|
@@ -27236,24 +27297,25 @@ var inputType = {
|
|
27236
27297
|
*
|
27237
27298
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
27238
27299
|
* @param {string=} name Property name of the form under which the control is published.
|
27239
|
-
* @param {
|
27240
|
-
* @param {
|
27300
|
+
* @param {expression=} ngTrueValue The value to which the expression should be set when selected.
|
27301
|
+
* @param {expression=} ngFalseValue The value to which the expression should be set when not selected.
|
27241
27302
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
27242
27303
|
* interaction with the input element.
|
27243
27304
|
*
|
27244
27305
|
* @example
|
27245
|
-
<example name="checkbox-input-directive">
|
27306
|
+
<example name="checkbox-input-directive" module="checkboxExample">
|
27246
27307
|
<file name="index.html">
|
27247
27308
|
<script>
|
27248
|
-
|
27249
|
-
$scope
|
27250
|
-
|
27251
|
-
|
27309
|
+
angular.module('checkboxExample', [])
|
27310
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
27311
|
+
$scope.value1 = true;
|
27312
|
+
$scope.value2 = 'YES'
|
27313
|
+
}]);
|
27252
27314
|
</script>
|
27253
|
-
<form name="myForm" ng-controller="
|
27315
|
+
<form name="myForm" ng-controller="ExampleController">
|
27254
27316
|
Value1: <input type="checkbox" ng-model="value1"> <br/>
|
27255
27317
|
Value2: <input type="checkbox" ng-model="value2"
|
27256
|
-
ng-true-value="YES" ng-false-value="NO"> <br/>
|
27318
|
+
ng-true-value="'YES'" ng-false-value="'NO'"> <br/>
|
27257
27319
|
<tt>value1 = {{value1}}</tt><br/>
|
27258
27320
|
<tt>value2 = {{value2}}</tt><br/>
|
27259
27321
|
</form>
|
@@ -27612,12 +27674,22 @@ function radioInputType(scope, element, attr, ctrl) {
|
|
27612
27674
|
attr.$observe('value', ctrl.$render);
|
27613
27675
|
}
|
27614
27676
|
|
27615
|
-
function
|
27616
|
-
var
|
27617
|
-
|
27677
|
+
function parseConstantExpr($parse, context, name, expression, fallback) {
|
27678
|
+
var parseFn;
|
27679
|
+
if (isDefined(expression)) {
|
27680
|
+
parseFn = $parse(expression);
|
27681
|
+
if (!parseFn.constant) {
|
27682
|
+
throw new minErr('ngModel')('constexpr', 'Expected constant expression for `{0}`, but saw ' +
|
27683
|
+
'`{1}`.', name, expression);
|
27684
|
+
}
|
27685
|
+
return parseFn(context);
|
27686
|
+
}
|
27687
|
+
return fallback;
|
27688
|
+
}
|
27618
27689
|
|
27619
|
-
|
27620
|
-
|
27690
|
+
function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
|
27691
|
+
var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);
|
27692
|
+
var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);
|
27621
27693
|
|
27622
27694
|
var listener = function(ev) {
|
27623
27695
|
scope.$apply(function() {
|
@@ -27637,7 +27709,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
27637
27709
|
};
|
27638
27710
|
|
27639
27711
|
ctrl.$formatters.push(function(value) {
|
27640
|
-
return value
|
27712
|
+
return equals(value, trueValue);
|
27641
27713
|
});
|
27642
27714
|
|
27643
27715
|
ctrl.$parsers.push(function(value) {
|
@@ -27699,14 +27771,15 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
27699
27771
|
* interaction with the input element.
|
27700
27772
|
*
|
27701
27773
|
* @example
|
27702
|
-
<example name="input-directive">
|
27774
|
+
<example name="input-directive" module="inputExample">
|
27703
27775
|
<file name="index.html">
|
27704
27776
|
<script>
|
27705
|
-
|
27706
|
-
|
27707
|
-
|
27777
|
+
angular.module('inputExample', [])
|
27778
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
27779
|
+
$scope.user = {name: 'guest', last: 'visitor'};
|
27780
|
+
}]);
|
27708
27781
|
</script>
|
27709
|
-
<div ng-controller="
|
27782
|
+
<div ng-controller="ExampleController">
|
27710
27783
|
<form name="myForm">
|
27711
27784
|
User name: <input type="text" name="userName" ng-model="user.name" required>
|
27712
27785
|
<span class="error" ng-show="myForm.userName.$error.required">
|
@@ -27785,14 +27858,15 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
27785
27858
|
</file>
|
27786
27859
|
</example>
|
27787
27860
|
*/
|
27788
|
-
var inputDirective = ['$browser', '$sniffer', '$filter',
|
27861
|
+
var inputDirective = ['$browser', '$sniffer', '$filter', '$parse',
|
27862
|
+
function($browser, $sniffer, $filter, $parse) {
|
27789
27863
|
return {
|
27790
27864
|
restrict: 'E',
|
27791
27865
|
require: ['?ngModel'],
|
27792
27866
|
link: function(scope, element, attr, ctrls) {
|
27793
27867
|
if (ctrls[0]) {
|
27794
27868
|
(inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,
|
27795
|
-
$browser, $filter);
|
27869
|
+
$browser, $filter, $parse);
|
27796
27870
|
}
|
27797
27871
|
}
|
27798
27872
|
};
|
@@ -27986,6 +28060,18 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
27986
28060
|
* @description
|
27987
28061
|
* Called when the view needs to be updated. It is expected that the user of the ng-model
|
27988
28062
|
* directive will implement this method.
|
28063
|
+
*
|
28064
|
+
* The `$render()` method is invoked in the following situations:
|
28065
|
+
*
|
28066
|
+
* * `$rollbackViewValue()` is called. If we are rolling back the view value to the last
|
28067
|
+
* committed value then `$render()` is called to update the input control.
|
28068
|
+
* * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and
|
28069
|
+
* the `$viewValue` are different to last time.
|
28070
|
+
*
|
28071
|
+
* Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
|
28072
|
+
* `$modelValue` and `$viewValue` are actually different to their previous value. If `$modelValue`
|
28073
|
+
* or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
|
28074
|
+
* invoked if you only change a property on the objects.
|
27989
28075
|
*/
|
27990
28076
|
this.$render = noop;
|
27991
28077
|
|
@@ -28151,7 +28237,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28151
28237
|
* <file name="app.js">
|
28152
28238
|
* angular.module('cancel-update-example', [])
|
28153
28239
|
*
|
28154
|
-
* .controller('
|
28240
|
+
* .controller('CancelUpdateController', ['$scope', function($scope) {
|
28155
28241
|
* $scope.resetWithCancel = function (e) {
|
28156
28242
|
* if (e.keyCode == 27) {
|
28157
28243
|
* $scope.myForm.myInput1.$rollbackViewValue();
|
@@ -28163,10 +28249,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28163
28249
|
* $scope.myValue = '';
|
28164
28250
|
* }
|
28165
28251
|
* };
|
28166
|
-
* });
|
28252
|
+
* }]);
|
28167
28253
|
* </file>
|
28168
28254
|
* <file name="index.html">
|
28169
|
-
* <div ng-controller="
|
28255
|
+
* <div ng-controller="CancelUpdateController">
|
28170
28256
|
* <p>Try typing something in each input. See that the model only updates when you
|
28171
28257
|
* blur off the input.
|
28172
28258
|
* </p>
|
@@ -28199,13 +28285,24 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28199
28285
|
* Runs each of the registered validations set on the $validators object.
|
28200
28286
|
*/
|
28201
28287
|
this.$validate = function() {
|
28202
|
-
|
28288
|
+
// ignore $validate before model initialized
|
28289
|
+
if (ctrl.$modelValue !== ctrl.$modelValue) {
|
28290
|
+
return;
|
28291
|
+
}
|
28292
|
+
|
28293
|
+
var prev = ctrl.$modelValue;
|
28294
|
+
ctrl.$$runValidators(ctrl.$$invalidModelValue || ctrl.$modelValue, ctrl.$viewValue);
|
28295
|
+
if (prev !== ctrl.$modelValue) {
|
28296
|
+
ctrl.$$writeModelToScope();
|
28297
|
+
}
|
28203
28298
|
};
|
28204
28299
|
|
28205
28300
|
this.$$runValidators = function(modelValue, viewValue) {
|
28206
28301
|
forEach(ctrl.$validators, function(fn, name) {
|
28207
28302
|
ctrl.$setValidity(name, fn(modelValue, viewValue));
|
28208
28303
|
});
|
28304
|
+
ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
|
28305
|
+
ctrl.$$invalidModelValue = ctrl.$valid ? undefined : modelValue;
|
28209
28306
|
};
|
28210
28307
|
|
28211
28308
|
/**
|
@@ -28244,20 +28341,28 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28244
28341
|
|
28245
28342
|
if (ctrl.$modelValue !== modelValue &&
|
28246
28343
|
(isUndefined(ctrl.$$invalidModelValue) || ctrl.$$invalidModelValue != modelValue)) {
|
28247
|
-
|
28248
28344
|
ctrl.$$runValidators(modelValue, viewValue);
|
28249
|
-
ctrl
|
28250
|
-
|
28345
|
+
ctrl.$$writeModelToScope();
|
28346
|
+
}
|
28347
|
+
};
|
28348
|
+
|
28349
|
+
this.$$writeModelToScope = function() {
|
28350
|
+
var getterSetter;
|
28351
|
+
|
28352
|
+
if (ctrl.$options && ctrl.$options.getterSetter &&
|
28353
|
+
isFunction(getterSetter = ngModelGet($scope))) {
|
28251
28354
|
|
28355
|
+
getterSetter(ctrl.$modelValue);
|
28356
|
+
} else {
|
28252
28357
|
ngModelSet($scope, ctrl.$modelValue);
|
28253
|
-
forEach(ctrl.$viewChangeListeners, function(listener) {
|
28254
|
-
try {
|
28255
|
-
listener();
|
28256
|
-
} catch(e) {
|
28257
|
-
$exceptionHandler(e);
|
28258
|
-
}
|
28259
|
-
});
|
28260
28358
|
}
|
28359
|
+
forEach(ctrl.$viewChangeListeners, function(listener) {
|
28360
|
+
try {
|
28361
|
+
listener();
|
28362
|
+
} catch(e) {
|
28363
|
+
$exceptionHandler(e);
|
28364
|
+
}
|
28365
|
+
});
|
28261
28366
|
};
|
28262
28367
|
|
28263
28368
|
/**
|
@@ -28267,13 +28372,25 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28267
28372
|
* @description
|
28268
28373
|
* Update the view value.
|
28269
28374
|
*
|
28270
|
-
* This method should be called when
|
28271
|
-
*
|
28272
|
-
*
|
28375
|
+
* This method should be called when an input directive want to change the view value; typically,
|
28376
|
+
* this is done from within a DOM event handler.
|
28377
|
+
*
|
28378
|
+
* For example {@link ng.directive:input input} calls it when the value of the input changes and
|
28379
|
+
* {@link ng.directive:select select} calls it when an option is selected.
|
28273
28380
|
*
|
28274
|
-
*
|
28275
|
-
*
|
28276
|
-
*
|
28381
|
+
* If the new `value` is an object (rather than a string or a number), we should make a copy of the
|
28382
|
+
* object before passing it to `$setViewValue`. This is because `ngModel` does not perform a deep
|
28383
|
+
* watch of objects, it only looks for a change of identity. If you only change the property of
|
28384
|
+
* the object then ngModel will not realise that the object has changed and will not invoke the
|
28385
|
+
* `$parsers` and `$validators` pipelines.
|
28386
|
+
*
|
28387
|
+
* For this reason, you should not change properties of the copy once it has been passed to
|
28388
|
+
* `$setViewValue`. Otherwise you may cause the model value on the scope to change incorrectly.
|
28389
|
+
*
|
28390
|
+
* When this method is called, the new `value` will be staged for committing through the `$parsers`
|
28391
|
+
* and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged
|
28392
|
+
* value sent directly for processing, finally to be applied to `$modelValue` and then the
|
28393
|
+
* **expression** specified in the `ng-model` attribute.
|
28277
28394
|
*
|
28278
28395
|
* Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
|
28279
28396
|
*
|
@@ -28325,6 +28442,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28325
28442
|
$scope.$watch(function ngModelWatch() {
|
28326
28443
|
var modelValue = ngModelGet($scope);
|
28327
28444
|
|
28445
|
+
if (ctrl.$options && ctrl.$options.getterSetter && isFunction(modelValue)) {
|
28446
|
+
modelValue = modelValue();
|
28447
|
+
}
|
28448
|
+
|
28328
28449
|
// if scope model value and ngModel value are out of sync
|
28329
28450
|
if (ctrl.$modelValue !== modelValue &&
|
28330
28451
|
(isUndefined(ctrl.$$invalidModelValue) || ctrl.$$invalidModelValue != modelValue)) {
|
@@ -28338,8 +28459,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28338
28459
|
}
|
28339
28460
|
|
28340
28461
|
ctrl.$$runValidators(modelValue, viewValue);
|
28341
|
-
ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
|
28342
|
-
ctrl.$$invalidModelValue = ctrl.$valid ? undefined : modelValue;
|
28343
28462
|
|
28344
28463
|
if (ctrl.$viewValue !== viewValue) {
|
28345
28464
|
ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
|
@@ -28433,12 +28552,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28433
28552
|
* </pre>
|
28434
28553
|
*
|
28435
28554
|
* @example
|
28436
|
-
* <example deps="angular-animate.js" animations="true" fixBase="true">
|
28555
|
+
* <example deps="angular-animate.js" animations="true" fixBase="true" module="inputExample">
|
28437
28556
|
<file name="index.html">
|
28438
28557
|
<script>
|
28439
|
-
|
28440
|
-
$scope
|
28441
|
-
|
28558
|
+
angular.module('inputExample', [])
|
28559
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
28560
|
+
$scope.val = '1';
|
28561
|
+
}]);
|
28442
28562
|
</script>
|
28443
28563
|
<style>
|
28444
28564
|
.my-input {
|
@@ -28453,11 +28573,60 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
28453
28573
|
</style>
|
28454
28574
|
Update input to see transitions when valid/invalid.
|
28455
28575
|
Integer is a valid value.
|
28456
|
-
<form name="testForm" ng-controller="
|
28576
|
+
<form name="testForm" ng-controller="ExampleController">
|
28457
28577
|
<input ng-model="val" ng-pattern="/^\d+$/" name="anim" class="my-input" />
|
28458
28578
|
</form>
|
28459
28579
|
</file>
|
28460
28580
|
* </example>
|
28581
|
+
*
|
28582
|
+
* ## Binding to a getter/setter
|
28583
|
+
*
|
28584
|
+
* Sometimes it's helpful to bind `ngModel` to a getter/setter function. A getter/setter is a
|
28585
|
+
* function that returns a representation of the model when called with zero arguments, and sets
|
28586
|
+
* the internal state of a model when called with an argument. It's sometimes useful to use this
|
28587
|
+
* for models that have an internal representation that's different than what the model exposes
|
28588
|
+
* to the view.
|
28589
|
+
*
|
28590
|
+
* <div class="alert alert-success">
|
28591
|
+
* **Best Practice:** It's best to keep getters fast because Angular is likely to call them more
|
28592
|
+
* frequently than other parts of your code.
|
28593
|
+
* </div>
|
28594
|
+
*
|
28595
|
+
* You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that
|
28596
|
+
* has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to
|
28597
|
+
* a `<form>`, which will enable this behavior for all `<input>`s within it. See
|
28598
|
+
* {@link ng.directive:ngModelOptions `ngModelOptions`} for more.
|
28599
|
+
*
|
28600
|
+
* The following example shows how to use `ngModel` with a getter/setter:
|
28601
|
+
*
|
28602
|
+
* @example
|
28603
|
+
* <example name="ngModel-getter-setter" module="getterSetterExample">
|
28604
|
+
<file name="index.html">
|
28605
|
+
<div ng-controller="ExampleController">
|
28606
|
+
<form name="userForm">
|
28607
|
+
Name:
|
28608
|
+
<input type="text" name="userName"
|
28609
|
+
ng-model="user.name"
|
28610
|
+
ng-model-options="{ getterSetter: true }" />
|
28611
|
+
</form>
|
28612
|
+
<pre>user.name = <span ng-bind="user.name()"></span></pre>
|
28613
|
+
</div>
|
28614
|
+
</file>
|
28615
|
+
<file name="app.js">
|
28616
|
+
angular.module('getterSetterExample', [])
|
28617
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
28618
|
+
var _name = 'Brian';
|
28619
|
+
$scope.user = {
|
28620
|
+
name: function (newName) {
|
28621
|
+
if (angular.isDefined(newName)) {
|
28622
|
+
_name = newName;
|
28623
|
+
}
|
28624
|
+
return _name;
|
28625
|
+
}
|
28626
|
+
};
|
28627
|
+
}]);
|
28628
|
+
</file>
|
28629
|
+
* </example>
|
28461
28630
|
*/
|
28462
28631
|
var ngModelDirective = function() {
|
28463
28632
|
return {
|
@@ -28520,17 +28689,18 @@ var ngModelDirective = function() {
|
|
28520
28689
|
* in input value.
|
28521
28690
|
*
|
28522
28691
|
* @example
|
28523
|
-
* <example name="ngChange-directive">
|
28692
|
+
* <example name="ngChange-directive" module="changeExample">
|
28524
28693
|
* <file name="index.html">
|
28525
28694
|
* <script>
|
28526
|
-
*
|
28527
|
-
* $scope
|
28528
|
-
*
|
28529
|
-
* $scope.
|
28530
|
-
*
|
28531
|
-
*
|
28695
|
+
* angular.module('changeExample', [])
|
28696
|
+
* .controller('ExampleController', ['$scope', function($scope) {
|
28697
|
+
* $scope.counter = 0;
|
28698
|
+
* $scope.change = function() {
|
28699
|
+
* $scope.counter++;
|
28700
|
+
* };
|
28701
|
+
* }]);
|
28532
28702
|
* </script>
|
28533
|
-
* <div ng-controller="
|
28703
|
+
* <div ng-controller="ExampleController">
|
28534
28704
|
* <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
|
28535
28705
|
* <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
|
28536
28706
|
* <label for="ng-change-example2">Confirmed</label><br />
|
@@ -28669,14 +28839,15 @@ var minlengthDirective = function() {
|
|
28669
28839
|
* specified in form `/something/` then the value will be converted into a regular expression.
|
28670
28840
|
*
|
28671
28841
|
* @example
|
28672
|
-
<example name="ngList-directive">
|
28842
|
+
<example name="ngList-directive" module="listExample">
|
28673
28843
|
<file name="index.html">
|
28674
28844
|
<script>
|
28675
|
-
|
28676
|
-
|
28677
|
-
|
28845
|
+
angular.module('listExample', [])
|
28846
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
28847
|
+
$scope.names = ['igor', 'misko', 'vojta'];
|
28848
|
+
}]);
|
28678
28849
|
</script>
|
28679
|
-
<form name="myForm" ng-controller="
|
28850
|
+
<form name="myForm" ng-controller="ExampleController">
|
28680
28851
|
List: <input name="namesInput" ng-model="names" ng-list required>
|
28681
28852
|
<span class="error" ng-show="myForm.namesInput.$error.required">
|
28682
28853
|
Required!</span>
|
@@ -28768,15 +28939,16 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
|
|
28768
28939
|
* of the `input` element
|
28769
28940
|
*
|
28770
28941
|
* @example
|
28771
|
-
<example name="ngValue-directive">
|
28942
|
+
<example name="ngValue-directive" module="valueExample">
|
28772
28943
|
<file name="index.html">
|
28773
28944
|
<script>
|
28774
|
-
|
28775
|
-
|
28776
|
-
|
28777
|
-
|
28945
|
+
angular.module('valueExample', [])
|
28946
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
28947
|
+
$scope.names = ['pizza', 'unicorns', 'robots'];
|
28948
|
+
$scope.my = { favorite: 'unicorns' };
|
28949
|
+
}]);
|
28778
28950
|
</script>
|
28779
|
-
<form ng-controller="
|
28951
|
+
<form ng-controller="ExampleController">
|
28780
28952
|
<h2>Which is your favorite?</h2>
|
28781
28953
|
<label ng-repeat="name in names" for="{{name}}">
|
28782
28954
|
{{name}}
|
@@ -28852,6 +29024,8 @@ var ngValueDirective = function() {
|
|
28852
29024
|
* value of 0 triggers an immediate update. If an object is supplied instead, you can specify a
|
28853
29025
|
* custom value for each event. For example:
|
28854
29026
|
* `ngModelOptions="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }"`
|
29027
|
+
* - `getterSetter`: boolean value which determines whether or not to treat functions bound to
|
29028
|
+
`ngModel` as getters/setters.
|
28855
29029
|
*
|
28856
29030
|
* @example
|
28857
29031
|
|
@@ -28859,9 +29033,9 @@ var ngValueDirective = function() {
|
|
28859
29033
|
form will update the model only when the control loses focus (blur event). If `escape` key is
|
28860
29034
|
pressed while the input field is focused, the value is reset to the value in the current model.
|
28861
29035
|
|
28862
|
-
<example name="ngModelOptions-directive-blur">
|
29036
|
+
<example name="ngModelOptions-directive-blur" module="optionsExample">
|
28863
29037
|
<file name="index.html">
|
28864
|
-
<div ng-controller="
|
29038
|
+
<div ng-controller="ExampleController">
|
28865
29039
|
<form name="userForm">
|
28866
29040
|
Name:
|
28867
29041
|
<input type="text" name="userName"
|
@@ -28876,15 +29050,16 @@ var ngValueDirective = function() {
|
|
28876
29050
|
</div>
|
28877
29051
|
</file>
|
28878
29052
|
<file name="app.js">
|
28879
|
-
|
28880
|
-
|
29053
|
+
angular.module('optionsExample', [])
|
29054
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
29055
|
+
$scope.user = { name: 'say', data: '' };
|
28881
29056
|
|
28882
|
-
|
28883
|
-
|
28884
|
-
|
28885
|
-
|
28886
|
-
|
28887
|
-
|
29057
|
+
$scope.cancel = function (e) {
|
29058
|
+
if (e.keyCode == 27) {
|
29059
|
+
$scope.userForm.userName.$rollbackViewValue();
|
29060
|
+
}
|
29061
|
+
};
|
29062
|
+
}]);
|
28888
29063
|
</file>
|
28889
29064
|
<file name="protractor.js" type="protractor">
|
28890
29065
|
var model = element(by.binding('user.name'));
|
@@ -28913,9 +29088,9 @@ var ngValueDirective = function() {
|
|
28913
29088
|
This one shows how to debounce model changes. Model will be updated only 1 sec after last change.
|
28914
29089
|
If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.
|
28915
29090
|
|
28916
|
-
<example name="ngModelOptions-directive-debounce">
|
29091
|
+
<example name="ngModelOptions-directive-debounce" module="optionsExample">
|
28917
29092
|
<file name="index.html">
|
28918
|
-
<div ng-controller="
|
29093
|
+
<div ng-controller="ExampleController">
|
28919
29094
|
<form name="userForm">
|
28920
29095
|
Name:
|
28921
29096
|
<input type="text" name="userName"
|
@@ -28927,9 +29102,37 @@ var ngValueDirective = function() {
|
|
28927
29102
|
</div>
|
28928
29103
|
</file>
|
28929
29104
|
<file name="app.js">
|
28930
|
-
|
28931
|
-
$scope
|
28932
|
-
|
29105
|
+
angular.module('optionsExample', [])
|
29106
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
29107
|
+
$scope.user = { name: 'say' };
|
29108
|
+
}]);
|
29109
|
+
</file>
|
29110
|
+
</example>
|
29111
|
+
|
29112
|
+
This one shows how to bind to getter/setters:
|
29113
|
+
|
29114
|
+
<example name="ngModelOptions-directive-getter-setter" module="getterSetterExample">
|
29115
|
+
<file name="index.html">
|
29116
|
+
<div ng-controller="ExampleController">
|
29117
|
+
<form name="userForm">
|
29118
|
+
Name:
|
29119
|
+
<input type="text" name="userName"
|
29120
|
+
ng-model="user.name"
|
29121
|
+
ng-model-options="{ getterSetter: true }" />
|
29122
|
+
</form>
|
29123
|
+
<pre>user.name = <span ng-bind="user.name()"></span></pre>
|
29124
|
+
</div>
|
29125
|
+
</file>
|
29126
|
+
<file name="app.js">
|
29127
|
+
angular.module('getterSetterExample', [])
|
29128
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
29129
|
+
var _name = 'Brian';
|
29130
|
+
$scope.user = {
|
29131
|
+
name: function (newName) {
|
29132
|
+
return angular.isDefined(newName) ? (_name = newName) : _name;
|
29133
|
+
}
|
29134
|
+
};
|
29135
|
+
}]);
|
28933
29136
|
</file>
|
28934
29137
|
</example>
|
28935
29138
|
*/
|
@@ -28979,14 +29182,15 @@ var ngModelOptionsDirective = function() {
|
|
28979
29182
|
*
|
28980
29183
|
* @example
|
28981
29184
|
* Enter a name in the Live Preview text box; the greeting below the text box changes instantly.
|
28982
|
-
<example>
|
29185
|
+
<example module="bindExample">
|
28983
29186
|
<file name="index.html">
|
28984
29187
|
<script>
|
28985
|
-
|
28986
|
-
$scope
|
28987
|
-
|
29188
|
+
angular.module('bindExample', [])
|
29189
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
29190
|
+
$scope.name = 'Whirled';
|
29191
|
+
}]);
|
28988
29192
|
</script>
|
28989
|
-
<div ng-controller="
|
29193
|
+
<div ng-controller="ExampleController">
|
28990
29194
|
Enter name: <input type="text" ng-model="name"><br>
|
28991
29195
|
Hello <span ng-bind="name"></span>!
|
28992
29196
|
</div>
|
@@ -29037,15 +29241,16 @@ var ngBindDirective = ngDirective({
|
|
29037
29241
|
*
|
29038
29242
|
* @example
|
29039
29243
|
* Try it here: enter text in text box and watch the greeting change.
|
29040
|
-
<example>
|
29244
|
+
<example module="bindExample">
|
29041
29245
|
<file name="index.html">
|
29042
29246
|
<script>
|
29043
|
-
|
29044
|
-
$scope
|
29045
|
-
|
29046
|
-
|
29247
|
+
angular.module('bindExample', [])
|
29248
|
+
.controller('ExampleController', ['$scope', function ($scope) {
|
29249
|
+
$scope.salutation = 'Hello';
|
29250
|
+
$scope.name = 'World';
|
29251
|
+
}]);
|
29047
29252
|
</script>
|
29048
|
-
<div ng-controller="
|
29253
|
+
<div ng-controller="ExampleController">
|
29049
29254
|
Salutation: <input type="text" ng-model="salutation"><br>
|
29050
29255
|
Name: <input type="text" ng-model="name"><br>
|
29051
29256
|
<pre ng-bind-template="{{salutation}} {{name}}!"></pre>
|
@@ -29103,20 +29308,20 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
|
29103
29308
|
* @example
|
29104
29309
|
Try it here: enter text in text box and watch the greeting change.
|
29105
29310
|
|
29106
|
-
<example module="
|
29311
|
+
<example module="bindHtmlExample" deps="angular-sanitize.js">
|
29107
29312
|
<file name="index.html">
|
29108
|
-
<div ng-controller="
|
29313
|
+
<div ng-controller="ExampleController">
|
29109
29314
|
<p ng-bind-html="myHTML"></p>
|
29110
29315
|
</div>
|
29111
29316
|
</file>
|
29112
29317
|
|
29113
29318
|
<file name="script.js">
|
29114
|
-
angular.module('
|
29115
|
-
|
29116
|
-
|
29117
|
-
|
29118
|
-
|
29119
|
-
|
29319
|
+
angular.module('bindHtmlExample', ['ngSanitize'])
|
29320
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
29321
|
+
$scope.myHTML =
|
29322
|
+
'I am an <code>HTML</code>string with ' +
|
29323
|
+
'<a href="#">links!</a> and other <em>stuff</em>';
|
29324
|
+
}]);
|
29120
29325
|
</file>
|
29121
29326
|
|
29122
29327
|
<file name="protractor.js" type="protractor">
|
@@ -29619,7 +29824,7 @@ var ngCloakDirective = ngDirective({
|
|
29619
29824
|
*
|
29620
29825
|
* This example demonstrates the `controller as` syntax.
|
29621
29826
|
*
|
29622
|
-
* <example name="ngControllerAs">
|
29827
|
+
* <example name="ngControllerAs" module="controllerAsExample">
|
29623
29828
|
* <file name="index.html">
|
29624
29829
|
* <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
|
29625
29830
|
* Name: <input type="text" ng-model="settings.name"/>
|
@@ -29640,6 +29845,9 @@ var ngCloakDirective = ngDirective({
|
|
29640
29845
|
* </div>
|
29641
29846
|
* </file>
|
29642
29847
|
* <file name="app.js">
|
29848
|
+
* angular.module('controllerAsExample', [])
|
29849
|
+
* .controller('SettingsController1', SettingsController1);
|
29850
|
+
*
|
29643
29851
|
* function SettingsController1() {
|
29644
29852
|
* this.name = "John Smith";
|
29645
29853
|
* this.contacts = [
|
@@ -29668,29 +29876,29 @@ var ngCloakDirective = ngDirective({
|
|
29668
29876
|
* <file name="protractor.js" type="protractor">
|
29669
29877
|
* it('should check controller as', function() {
|
29670
29878
|
* var container = element(by.id('ctrl-as-exmpl'));
|
29671
|
-
* expect(container.
|
29879
|
+
* expect(container.element(by.model('settings.name'))
|
29672
29880
|
* .getAttribute('value')).toBe('John Smith');
|
29673
29881
|
*
|
29674
29882
|
* var firstRepeat =
|
29675
|
-
* container.
|
29883
|
+
* container.element(by.repeater('contact in settings.contacts').row(0));
|
29676
29884
|
* var secondRepeat =
|
29677
|
-
* container.
|
29885
|
+
* container.element(by.repeater('contact in settings.contacts').row(1));
|
29678
29886
|
*
|
29679
|
-
* expect(firstRepeat.
|
29887
|
+
* expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
|
29680
29888
|
* .toBe('408 555 1212');
|
29681
29889
|
*
|
29682
|
-
* expect(secondRepeat.
|
29890
|
+
* expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
|
29683
29891
|
* .toBe('john.smith@example.org');
|
29684
29892
|
*
|
29685
|
-
* firstRepeat.
|
29893
|
+
* firstRepeat.element(by.linkText('clear')).click();
|
29686
29894
|
*
|
29687
|
-
* expect(firstRepeat.
|
29895
|
+
* expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
|
29688
29896
|
* .toBe('');
|
29689
29897
|
*
|
29690
|
-
* container.
|
29898
|
+
* container.element(by.linkText('add')).click();
|
29691
29899
|
*
|
29692
|
-
* expect(container.
|
29693
|
-
* .
|
29900
|
+
* expect(container.element(by.repeater('contact in settings.contacts').row(2))
|
29901
|
+
* .element(by.model('contact.value'))
|
29694
29902
|
* .getAttribute('value'))
|
29695
29903
|
* .toBe('yourname@example.org');
|
29696
29904
|
* });
|
@@ -29699,7 +29907,7 @@ var ngCloakDirective = ngDirective({
|
|
29699
29907
|
*
|
29700
29908
|
* This example demonstrates the "attach to `$scope`" style of controller.
|
29701
29909
|
*
|
29702
|
-
* <example name="ngController">
|
29910
|
+
* <example name="ngController" module="controllerExample">
|
29703
29911
|
* <file name="index.html">
|
29704
29912
|
* <div id="ctrl-exmpl" ng-controller="SettingsController2">
|
29705
29913
|
* Name: <input type="text" ng-model="name"/>
|
@@ -29720,6 +29928,9 @@ var ngCloakDirective = ngDirective({
|
|
29720
29928
|
* </div>
|
29721
29929
|
* </file>
|
29722
29930
|
* <file name="app.js">
|
29931
|
+
* angular.module('controllerExample', [])
|
29932
|
+
* .controller('SettingsController2', ['$scope', SettingsController2]);
|
29933
|
+
*
|
29723
29934
|
* function SettingsController2($scope) {
|
29724
29935
|
* $scope.name = "John Smith";
|
29725
29936
|
* $scope.contacts = [
|
@@ -29749,28 +29960,28 @@ var ngCloakDirective = ngDirective({
|
|
29749
29960
|
* it('should check controller', function() {
|
29750
29961
|
* var container = element(by.id('ctrl-exmpl'));
|
29751
29962
|
*
|
29752
|
-
* expect(container.
|
29963
|
+
* expect(container.element(by.model('name'))
|
29753
29964
|
* .getAttribute('value')).toBe('John Smith');
|
29754
29965
|
*
|
29755
29966
|
* var firstRepeat =
|
29756
|
-
* container.
|
29967
|
+
* container.element(by.repeater('contact in contacts').row(0));
|
29757
29968
|
* var secondRepeat =
|
29758
|
-
* container.
|
29969
|
+
* container.element(by.repeater('contact in contacts').row(1));
|
29759
29970
|
*
|
29760
|
-
* expect(firstRepeat.
|
29971
|
+
* expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
|
29761
29972
|
* .toBe('408 555 1212');
|
29762
|
-
* expect(secondRepeat.
|
29973
|
+
* expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
|
29763
29974
|
* .toBe('john.smith@example.org');
|
29764
29975
|
*
|
29765
|
-
* firstRepeat.
|
29976
|
+
* firstRepeat.element(by.linkText('clear')).click();
|
29766
29977
|
*
|
29767
|
-
* expect(firstRepeat.
|
29978
|
+
* expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
|
29768
29979
|
* .toBe('');
|
29769
29980
|
*
|
29770
|
-
* container.
|
29981
|
+
* container.element(by.linkText('add')).click();
|
29771
29982
|
*
|
29772
|
-
* expect(container.
|
29773
|
-
* .
|
29983
|
+
* expect(container.element(by.repeater('contact in contacts').row(2))
|
29984
|
+
* .element(by.model('contact.value'))
|
29774
29985
|
* .getAttribute('value'))
|
29775
29986
|
* .toBe('yourname@example.org');
|
29776
29987
|
* });
|
@@ -30141,21 +30352,22 @@ forEach(
|
|
30141
30352
|
* ({@link guide/expression#-event- Event object is available as `$event`})
|
30142
30353
|
*
|
30143
30354
|
* @example
|
30144
|
-
<example>
|
30355
|
+
<example module="submitExample">
|
30145
30356
|
<file name="index.html">
|
30146
30357
|
<script>
|
30147
|
-
|
30148
|
-
$scope
|
30149
|
-
|
30150
|
-
|
30151
|
-
|
30152
|
-
$scope.
|
30153
|
-
|
30154
|
-
|
30155
|
-
|
30156
|
-
|
30358
|
+
angular.module('submitExample', [])
|
30359
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
30360
|
+
$scope.list = [];
|
30361
|
+
$scope.text = 'hello';
|
30362
|
+
$scope.submit = function() {
|
30363
|
+
if ($scope.text) {
|
30364
|
+
$scope.list.push(this.text);
|
30365
|
+
$scope.text = '';
|
30366
|
+
}
|
30367
|
+
};
|
30368
|
+
}]);
|
30157
30369
|
</script>
|
30158
|
-
<form ng-submit="submit()" ng-controller="
|
30370
|
+
<form ng-submit="submit()" ng-controller="ExampleController">
|
30159
30371
|
Enter text and hit enter:
|
30160
30372
|
<input type="text" ng-model="text" name="text" />
|
30161
30373
|
<input type="submit" id="submit" value="Submit" />
|
@@ -30167,7 +30379,7 @@ forEach(
|
|
30167
30379
|
expect(element(by.binding('list')).getText()).toBe('list=[]');
|
30168
30380
|
element(by.css('#submit')).click();
|
30169
30381
|
expect(element(by.binding('list')).getText()).toContain('hello');
|
30170
|
-
expect(element(by.
|
30382
|
+
expect(element(by.model('text')).getAttribute('value')).toBe('');
|
30171
30383
|
});
|
30172
30384
|
it('should ignore empty strings', function() {
|
30173
30385
|
expect(element(by.binding('list')).getText()).toBe('list=[]');
|
@@ -30440,9 +30652,9 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
30440
30652
|
* - Otherwise enable scrolling only if the expression evaluates to truthy value.
|
30441
30653
|
*
|
30442
30654
|
* @example
|
30443
|
-
<example module="
|
30655
|
+
<example module="includeExample" deps="angular-animate.js" animations="true">
|
30444
30656
|
<file name="index.html">
|
30445
|
-
<div ng-controller="
|
30657
|
+
<div ng-controller="ExampleController">
|
30446
30658
|
<select ng-model="template" ng-options="t.name for t in templates">
|
30447
30659
|
<option value="">(blank)</option>
|
30448
30660
|
</select>
|
@@ -30454,12 +30666,13 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
30454
30666
|
</div>
|
30455
30667
|
</file>
|
30456
30668
|
<file name="script.js">
|
30457
|
-
|
30458
|
-
$scope
|
30459
|
-
|
30460
|
-
{ name: '
|
30461
|
-
|
30462
|
-
|
30669
|
+
angular.module('includeExample', ['ngAnimate'])
|
30670
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
30671
|
+
$scope.templates =
|
30672
|
+
[ { name: 'template1.html', url: 'template1.html'},
|
30673
|
+
{ name: 'template2.html', url: 'template2.html'} ];
|
30674
|
+
$scope.template = $scope.templates[0];
|
30675
|
+
}]);
|
30463
30676
|
</file>
|
30464
30677
|
<file name="template1.html">
|
30465
30678
|
Content of template1.html
|
@@ -30522,7 +30735,7 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
30522
30735
|
return;
|
30523
30736
|
}
|
30524
30737
|
templateSelect.click();
|
30525
|
-
templateSelect.
|
30738
|
+
templateSelect.all(by.css('option')).get(2).click();
|
30526
30739
|
expect(includeElem.getText()).toMatch(/Content of template2.html/);
|
30527
30740
|
});
|
30528
30741
|
|
@@ -30532,7 +30745,7 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
30532
30745
|
return;
|
30533
30746
|
}
|
30534
30747
|
templateSelect.click();
|
30535
|
-
templateSelect.
|
30748
|
+
templateSelect.all(by.css('option')).get(0).click();
|
30536
30749
|
expect(includeElem.isPresent()).toBe(false);
|
30537
30750
|
});
|
30538
30751
|
</file>
|
@@ -30560,8 +30773,7 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
30560
30773
|
|
30561
30774
|
/**
|
30562
30775
|
* @ngdoc event
|
30563
|
-
* @name
|
30564
|
-
* @eventOf ng.directive:ngInclude
|
30776
|
+
* @name ngInclude#$includeContentError
|
30565
30777
|
* @eventType emit on the scope ngInclude was declared in
|
30566
30778
|
* @description
|
30567
30779
|
* Emitted when a template HTTP request yields an erronous response (status < 200 || status > 299)
|
@@ -30697,14 +30909,15 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
30697
30909
|
* @param {expression} ngInit {@link guide/expression Expression} to eval.
|
30698
30910
|
*
|
30699
30911
|
* @example
|
30700
|
-
<example>
|
30912
|
+
<example module="initExample">
|
30701
30913
|
<file name="index.html">
|
30702
30914
|
<script>
|
30703
|
-
|
30704
|
-
|
30705
|
-
|
30915
|
+
angular.module('initExample', [])
|
30916
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
30917
|
+
$scope.list = [['a', 'b'], ['c', 'd']];
|
30918
|
+
}]);
|
30706
30919
|
</script>
|
30707
|
-
<div ng-controller="
|
30920
|
+
<div ng-controller="ExampleController">
|
30708
30921
|
<div ng-repeat="innerList in list" ng-init="outerIndex = $index">
|
30709
30922
|
<div ng-repeat="value in innerList" ng-init="innerIndex = $index">
|
30710
30923
|
<span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
|
@@ -30857,16 +31070,17 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
30857
31070
|
* @param {number=} offset Offset to deduct from the total number.
|
30858
31071
|
*
|
30859
31072
|
* @example
|
30860
|
-
<example>
|
31073
|
+
<example module="pluralizeExample">
|
30861
31074
|
<file name="index.html">
|
30862
31075
|
<script>
|
30863
|
-
|
30864
|
-
$scope
|
30865
|
-
|
30866
|
-
|
30867
|
-
|
31076
|
+
angular.module('pluralizeExample', [])
|
31077
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
31078
|
+
$scope.person1 = 'Igor';
|
31079
|
+
$scope.person2 = 'Misko';
|
31080
|
+
$scope.personCount = 1;
|
31081
|
+
}]);
|
30868
31082
|
</script>
|
30869
|
-
<div ng-controller="
|
31083
|
+
<div ng-controller="ExampleController">
|
30870
31084
|
Person 1:<input type="text" ng-model="person1" value="Igor" /><br/>
|
30871
31085
|
Person 2:<input type="text" ng-model="person2" value="Misko" /><br/>
|
30872
31086
|
Number of People:<input type="text" ng-model="personCount" value="1" /><br/>
|
@@ -31798,9 +32012,9 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
31798
32012
|
*
|
31799
32013
|
*
|
31800
32014
|
* @example
|
31801
|
-
<example module="
|
32015
|
+
<example module="switchExample" deps="angular-animate.js" animations="true">
|
31802
32016
|
<file name="index.html">
|
31803
|
-
<div ng-controller="
|
32017
|
+
<div ng-controller="ExampleController">
|
31804
32018
|
<select ng-model="selection" ng-options="item for item in items">
|
31805
32019
|
</select>
|
31806
32020
|
<tt>selection={{selection}}</tt>
|
@@ -31814,10 +32028,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
31814
32028
|
</div>
|
31815
32029
|
</file>
|
31816
32030
|
<file name="script.js">
|
31817
|
-
|
31818
|
-
|
31819
|
-
|
31820
|
-
|
32031
|
+
angular.module('switchExample', ['ngAnimate'])
|
32032
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
32033
|
+
$scope.items = ['settings', 'home', 'other'];
|
32034
|
+
$scope.selection = $scope.items[0];
|
32035
|
+
}]);
|
31821
32036
|
</file>
|
31822
32037
|
<file name="animations.css">
|
31823
32038
|
.animate-switch-container {
|
@@ -31860,11 +32075,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
31860
32075
|
expect(switchElem.getText()).toMatch(/Settings Div/);
|
31861
32076
|
});
|
31862
32077
|
it('should change to home', function() {
|
31863
|
-
select.
|
32078
|
+
select.all(by.css('option')).get(1).click();
|
31864
32079
|
expect(switchElem.getText()).toMatch(/Home Span/);
|
31865
32080
|
});
|
31866
32081
|
it('should select default', function() {
|
31867
|
-
select.
|
32082
|
+
select.all(by.css('option')).get(2).click();
|
31868
32083
|
expect(switchElem.getText()).toMatch(/default/);
|
31869
32084
|
});
|
31870
32085
|
</file>
|
@@ -31956,15 +32171,10 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
31956
32171
|
* @element ANY
|
31957
32172
|
*
|
31958
32173
|
* @example
|
31959
|
-
<example module="
|
32174
|
+
<example module="transcludeExample">
|
31960
32175
|
<file name="index.html">
|
31961
32176
|
<script>
|
31962
|
-
|
31963
|
-
$scope.title = 'Lorem Ipsum';
|
31964
|
-
$scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
|
31965
|
-
}
|
31966
|
-
|
31967
|
-
angular.module('transclude', [])
|
32177
|
+
angular.module('transcludeExample', [])
|
31968
32178
|
.directive('pane', function(){
|
31969
32179
|
return {
|
31970
32180
|
restrict: 'E',
|
@@ -31975,9 +32185,13 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
31975
32185
|
'<div ng-transclude></div>' +
|
31976
32186
|
'</div>'
|
31977
32187
|
};
|
31978
|
-
})
|
32188
|
+
})
|
32189
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
32190
|
+
$scope.title = 'Lorem Ipsum';
|
32191
|
+
$scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
|
32192
|
+
}]);
|
31979
32193
|
</script>
|
31980
|
-
<div ng-controller="
|
32194
|
+
<div ng-controller="ExampleController">
|
31981
32195
|
<input ng-model="title"><br>
|
31982
32196
|
<textarea ng-model="text"></textarea> <br/>
|
31983
32197
|
<pane title="{{title}}">{{text}}</pane>
|
@@ -32136,21 +32350,22 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
32136
32350
|
* `value` variable (e.g. `value.propertyName`).
|
32137
32351
|
*
|
32138
32352
|
* @example
|
32139
|
-
<example>
|
32353
|
+
<example module="selectExample">
|
32140
32354
|
<file name="index.html">
|
32141
32355
|
<script>
|
32142
|
-
|
32143
|
-
$scope
|
32144
|
-
|
32145
|
-
|
32146
|
-
|
32147
|
-
|
32148
|
-
|
32149
|
-
|
32150
|
-
|
32151
|
-
|
32356
|
+
angular.module('selectExample', [])
|
32357
|
+
.controller('ExampleController', ['$scope', function($scope) {
|
32358
|
+
$scope.colors = [
|
32359
|
+
{name:'black', shade:'dark'},
|
32360
|
+
{name:'white', shade:'light'},
|
32361
|
+
{name:'red', shade:'dark'},
|
32362
|
+
{name:'blue', shade:'dark'},
|
32363
|
+
{name:'yellow', shade:'light'}
|
32364
|
+
];
|
32365
|
+
$scope.myColor = $scope.colors[2]; // red
|
32366
|
+
}]);
|
32152
32367
|
</script>
|
32153
|
-
<div ng-controller="
|
32368
|
+
<div ng-controller="ExampleController">
|
32154
32369
|
<ul>
|
32155
32370
|
<li ng-repeat="color in colors">
|
32156
32371
|
Name: <input ng-model="color.name">
|
@@ -32187,7 +32402,7 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
32187
32402
|
<file name="protractor.js" type="protractor">
|
32188
32403
|
it('should check ng-options', function() {
|
32189
32404
|
expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');
|
32190
|
-
element.all(by.
|
32405
|
+
element.all(by.model('myColor')).first().click();
|
32191
32406
|
element.all(by.css('select[ng-model="myColor"] option')).first().click();
|
32192
32407
|
expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');
|
32193
32408
|
element(by.css('.nullable select[ng-model="myColor"]')).click();
|
@@ -32227,7 +32442,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
32227
32442
|
};
|
32228
32443
|
|
32229
32444
|
|
32230
|
-
self.addOption = function(value) {
|
32445
|
+
self.addOption = function(value, element) {
|
32231
32446
|
assertNotHasOwnProperty(value, '"option value"');
|
32232
32447
|
optionsMap[value] = true;
|
32233
32448
|
|
@@ -32235,6 +32450,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
32235
32450
|
$element.val(value);
|
32236
32451
|
if (unknownOption.parent()) unknownOption.remove();
|
32237
32452
|
}
|
32453
|
+
// Workaround for https://code.google.com/p/chromium/issues/detail?id=381459
|
32454
|
+
// Adding an <option selected="selected"> element to a <select required="required"> should
|
32455
|
+
// automatically select the new element
|
32456
|
+
if (element[0].hasAttribute('selected')) {
|
32457
|
+
element[0].selected = true;
|
32458
|
+
}
|
32238
32459
|
};
|
32239
32460
|
|
32240
32461
|
|
@@ -32688,10 +32909,10 @@ var optionDirective = ['$interpolate', function($interpolate) {
|
|
32688
32909
|
if (oldVal !== newVal) {
|
32689
32910
|
selectCtrl.removeOption(oldVal);
|
32690
32911
|
}
|
32691
|
-
selectCtrl.addOption(newVal);
|
32912
|
+
selectCtrl.addOption(newVal, element);
|
32692
32913
|
});
|
32693
32914
|
} else {
|
32694
|
-
selectCtrl.addOption(attr.value);
|
32915
|
+
selectCtrl.addOption(attr.value, element);
|
32695
32916
|
}
|
32696
32917
|
|
32697
32918
|
element.on('$destroy', function() {
|