angularjs-rails 1.2.19 → 1.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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() {
|