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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-beta.14
2
+ * @license AngularJS v1.3.0-beta.15
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-beta.14
2
+ * @license AngularJS v1.3.0-beta.15
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -68,7 +68,7 @@ function minErr(module) {
68
68
  return match;
69
69
  });
70
70
 
71
- message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.14/' +
71
+ message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.15/' +
72
72
  (module ? module + '/' : '') + code;
73
73
  for (i = 2; i < arguments.length; i++) {
74
74
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -80,89 +80,87 @@ function minErr(module) {
80
80
  }
81
81
 
82
82
  /* We need to tell jshint what variables are being exported */
83
- /* global
84
- -angular,
85
- -msie,
86
- -jqLite,
87
- -jQuery,
88
- -slice,
89
- -push,
90
- -toString,
91
- -ngMinErr,
92
- -angularModule,
93
- -nodeName_,
94
- -uid,
95
- -REGEX_STRING_REGEXP,
96
- -VALIDITY_STATE_PROPERTY,
97
-
98
- -lowercase,
99
- -uppercase,
100
- -manualLowercase,
101
- -manualUppercase,
102
- -nodeName_,
103
- -isArrayLike,
104
- -forEach,
105
- -sortedKeys,
106
- -forEachSorted,
107
- -reverseParams,
108
- -nextUid,
109
- -setHashKey,
110
- -extend,
111
- -int,
112
- -inherit,
113
- -noop,
114
- -identity,
115
- -valueFn,
116
- -isUndefined,
117
- -isDefined,
118
- -isObject,
119
- -isString,
120
- -isNumber,
121
- -isDate,
122
- -isArray,
123
- -isFunction,
124
- -isRegExp,
125
- -isWindow,
126
- -isScope,
127
- -isFile,
128
- -isBlob,
129
- -isBoolean,
130
- -trim,
131
- -isElement,
132
- -makeMap,
133
- -map,
134
- -size,
135
- -includes,
136
- -indexOf,
137
- -arrayRemove,
138
- -isLeafNode,
139
- -copy,
140
- -shallowCopy,
141
- -equals,
142
- -csp,
143
- -concat,
144
- -sliceArgs,
145
- -bind,
146
- -toJsonReplacer,
147
- -toJson,
148
- -fromJson,
149
- -startingTag,
150
- -tryDecodeURIComponent,
151
- -parseKeyValue,
152
- -toKeyValue,
153
- -encodeUriSegment,
154
- -encodeUriQuery,
155
- -angularInit,
156
- -bootstrap,
157
- -snake_case,
158
- -bindJQuery,
159
- -assertArg,
160
- -assertArgFn,
161
- -assertNotHasOwnProperty,
162
- -getter,
163
- -getBlockElements,
164
- -hasOwnProperty,
165
-
83
+ /* global angular: true,
84
+ msie: true,
85
+ jqLite: true,
86
+ jQuery: true,
87
+ slice: true,
88
+ push: true,
89
+ toString: true,
90
+ ngMinErr: true,
91
+ angularModule: true,
92
+ nodeName_: true,
93
+ uid: true,
94
+ REGEX_STRING_REGEXP: true,
95
+ VALIDITY_STATE_PROPERTY: true,
96
+
97
+ lowercase: true,
98
+ uppercase: true,
99
+ manualLowercase: true,
100
+ manualUppercase: true,
101
+ nodeName_: true,
102
+ isArrayLike: true,
103
+ forEach: true,
104
+ sortedKeys: true,
105
+ forEachSorted: true,
106
+ reverseParams: true,
107
+ nextUid: true,
108
+ setHashKey: true,
109
+ extend: true,
110
+ int: true,
111
+ inherit: true,
112
+ noop: true,
113
+ identity: true,
114
+ valueFn: true,
115
+ isUndefined: true,
116
+ isDefined: true,
117
+ isObject: true,
118
+ isString: true,
119
+ isNumber: true,
120
+ isDate: true,
121
+ isArray: true,
122
+ isFunction: true,
123
+ isRegExp: true,
124
+ isWindow: true,
125
+ isScope: true,
126
+ isFile: true,
127
+ isBlob: true,
128
+ isBoolean: true,
129
+ trim: true,
130
+ isElement: true,
131
+ makeMap: true,
132
+ map: true,
133
+ size: true,
134
+ includes: true,
135
+ indexOf: true,
136
+ arrayRemove: true,
137
+ isLeafNode: true,
138
+ copy: true,
139
+ shallowCopy: true,
140
+ equals: true,
141
+ csp: true,
142
+ concat: true,
143
+ sliceArgs: true,
144
+ bind: true,
145
+ toJsonReplacer: true,
146
+ toJson: true,
147
+ fromJson: true,
148
+ startingTag: true,
149
+ tryDecodeURIComponent: true,
150
+ parseKeyValue: true,
151
+ toKeyValue: true,
152
+ encodeUriSegment: true,
153
+ encodeUriQuery: true,
154
+ angularInit: true,
155
+ bootstrap: true,
156
+ snake_case: true,
157
+ bindJQuery: true,
158
+ assertArg: true,
159
+ assertArgFn: true,
160
+ assertNotHasOwnProperty: true,
161
+ getter: true,
162
+ getBlockElements: true,
163
+ hasOwnProperty: true,
166
164
  */
167
165
 
168
166
  ////////////////////////////////////
@@ -800,9 +798,9 @@ function isLeafNode (node) {
800
798
  * @returns {*} The copy or updated `destination`, if `destination` was specified.
801
799
  *
802
800
  * @example
803
- <example>
801
+ <example module="copyExample">
804
802
  <file name="index.html">
805
- <div ng-controller="Controller">
803
+ <div ng-controller="ExampleController">
806
804
  <form novalidate class="simple-form">
807
805
  Name: <input type="text" ng-model="user.name" /><br />
808
806
  E-mail: <input type="email" ng-model="user.email" /><br />
@@ -816,21 +814,22 @@ function isLeafNode (node) {
816
814
  </div>
817
815
 
818
816
  <script>
819
- function Controller($scope) {
820
- $scope.master= {};
817
+ angular.module('copyExample')
818
+ .controller('ExampleController', ['$scope', function($scope) {
819
+ $scope.master= {};
821
820
 
822
- $scope.update = function(user) {
823
- // Example with 1 argument
824
- $scope.master= angular.copy(user);
825
- };
821
+ $scope.update = function(user) {
822
+ // Example with 1 argument
823
+ $scope.master= angular.copy(user);
824
+ };
826
825
 
827
- $scope.reset = function() {
828
- // Example with 2 arguments
829
- angular.copy($scope.master, $scope.user);
830
- };
826
+ $scope.reset = function() {
827
+ // Example with 2 arguments
828
+ angular.copy($scope.master, $scope.user);
829
+ };
831
830
 
832
- $scope.reset();
833
- }
831
+ $scope.reset();
832
+ }]);
834
833
  </script>
835
834
  </file>
836
835
  </example>
@@ -1170,7 +1169,7 @@ function parseKeyValue(/**string*/keyValue) {
1170
1169
  key = tryDecodeURIComponent(key_value[0]);
1171
1170
  if ( isDefined(key) ) {
1172
1171
  var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
1173
- if (!obj[key]) {
1172
+ if (!hasOwnProperty.call(obj, key)) {
1174
1173
  obj[key] = val;
1175
1174
  } else if(isArray(obj[key])) {
1176
1175
  obj[key].push(val);
@@ -1968,89 +1967,88 @@ function setupModuleLoader(window) {
1968
1967
 
1969
1968
  }
1970
1969
 
1971
- /* global
1972
- angularModule: true,
1973
- version: true,
1974
-
1975
- $LocaleProvider,
1976
- $CompileProvider,
1977
-
1978
- htmlAnchorDirective,
1979
- inputDirective,
1980
- inputDirective,
1981
- formDirective,
1982
- scriptDirective,
1983
- selectDirective,
1984
- styleDirective,
1985
- optionDirective,
1986
- ngBindDirective,
1987
- ngBindHtmlDirective,
1988
- ngBindTemplateDirective,
1989
- ngClassDirective,
1990
- ngClassEvenDirective,
1991
- ngClassOddDirective,
1992
- ngCspDirective,
1993
- ngCloakDirective,
1994
- ngControllerDirective,
1995
- ngFormDirective,
1996
- ngHideDirective,
1997
- ngIfDirective,
1998
- ngIncludeDirective,
1999
- ngIncludeFillContentDirective,
2000
- ngInitDirective,
2001
- ngNonBindableDirective,
2002
- ngPluralizeDirective,
2003
- ngRepeatDirective,
2004
- ngShowDirective,
2005
- ngStyleDirective,
2006
- ngSwitchDirective,
2007
- ngSwitchWhenDirective,
2008
- ngSwitchDefaultDirective,
2009
- ngOptionsDirective,
2010
- ngTranscludeDirective,
2011
- ngModelDirective,
2012
- ngListDirective,
2013
- ngChangeDirective,
2014
- patternDirective,
2015
- patternDirective,
2016
- requiredDirective,
2017
- requiredDirective,
2018
- minlengthDirective,
2019
- minlengthDirective,
2020
- maxlengthDirective,
2021
- maxlengthDirective,
2022
- ngValueDirective,
2023
- ngModelOptionsDirective,
2024
- ngAttributeAliasDirectives,
2025
- ngEventDirectives,
2026
-
2027
- $AnchorScrollProvider,
2028
- $AnimateProvider,
2029
- $BrowserProvider,
2030
- $CacheFactoryProvider,
2031
- $ControllerProvider,
2032
- $DocumentProvider,
2033
- $ExceptionHandlerProvider,
2034
- $FilterProvider,
2035
- $InterpolateProvider,
2036
- $IntervalProvider,
2037
- $HttpProvider,
2038
- $HttpBackendProvider,
2039
- $LocationProvider,
2040
- $LogProvider,
2041
- $ParseProvider,
2042
- $RootScopeProvider,
2043
- $QProvider,
2044
- $$QProvider,
2045
- $$SanitizeUriProvider,
2046
- $SceProvider,
2047
- $SceDelegateProvider,
2048
- $SnifferProvider,
2049
- $TemplateCacheProvider,
2050
- $TimeoutProvider,
2051
- $$RAFProvider,
2052
- $$AsyncCallbackProvider,
2053
- $WindowProvider
1970
+ /* global angularModule: true,
1971
+ version: true,
1972
+
1973
+ $LocaleProvider,
1974
+ $CompileProvider,
1975
+
1976
+ htmlAnchorDirective,
1977
+ inputDirective,
1978
+ inputDirective,
1979
+ formDirective,
1980
+ scriptDirective,
1981
+ selectDirective,
1982
+ styleDirective,
1983
+ optionDirective,
1984
+ ngBindDirective,
1985
+ ngBindHtmlDirective,
1986
+ ngBindTemplateDirective,
1987
+ ngClassDirective,
1988
+ ngClassEvenDirective,
1989
+ ngClassOddDirective,
1990
+ ngCspDirective,
1991
+ ngCloakDirective,
1992
+ ngControllerDirective,
1993
+ ngFormDirective,
1994
+ ngHideDirective,
1995
+ ngIfDirective,
1996
+ ngIncludeDirective,
1997
+ ngIncludeFillContentDirective,
1998
+ ngInitDirective,
1999
+ ngNonBindableDirective,
2000
+ ngPluralizeDirective,
2001
+ ngRepeatDirective,
2002
+ ngShowDirective,
2003
+ ngStyleDirective,
2004
+ ngSwitchDirective,
2005
+ ngSwitchWhenDirective,
2006
+ ngSwitchDefaultDirective,
2007
+ ngOptionsDirective,
2008
+ ngTranscludeDirective,
2009
+ ngModelDirective,
2010
+ ngListDirective,
2011
+ ngChangeDirective,
2012
+ patternDirective,
2013
+ patternDirective,
2014
+ requiredDirective,
2015
+ requiredDirective,
2016
+ minlengthDirective,
2017
+ minlengthDirective,
2018
+ maxlengthDirective,
2019
+ maxlengthDirective,
2020
+ ngValueDirective,
2021
+ ngModelOptionsDirective,
2022
+ ngAttributeAliasDirectives,
2023
+ ngEventDirectives,
2024
+
2025
+ $AnchorScrollProvider,
2026
+ $AnimateProvider,
2027
+ $BrowserProvider,
2028
+ $CacheFactoryProvider,
2029
+ $ControllerProvider,
2030
+ $DocumentProvider,
2031
+ $ExceptionHandlerProvider,
2032
+ $FilterProvider,
2033
+ $InterpolateProvider,
2034
+ $IntervalProvider,
2035
+ $HttpProvider,
2036
+ $HttpBackendProvider,
2037
+ $LocationProvider,
2038
+ $LogProvider,
2039
+ $ParseProvider,
2040
+ $RootScopeProvider,
2041
+ $QProvider,
2042
+ $$QProvider,
2043
+ $$SanitizeUriProvider,
2044
+ $SceProvider,
2045
+ $SceDelegateProvider,
2046
+ $SnifferProvider,
2047
+ $TemplateCacheProvider,
2048
+ $TimeoutProvider,
2049
+ $$RAFProvider,
2050
+ $$AsyncCallbackProvider,
2051
+ $WindowProvider
2054
2052
  */
2055
2053
 
2056
2054
 
@@ -2069,11 +2067,11 @@ function setupModuleLoader(window) {
2069
2067
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2070
2068
  */
2071
2069
  var version = {
2072
- full: '1.3.0-beta.14', // all of these placeholder strings will be replaced by grunt's
2070
+ full: '1.3.0-beta.15', // all of these placeholder strings will be replaced by grunt's
2073
2071
  major: 1, // package task
2074
2072
  minor: 3,
2075
2073
  dot: 0,
2076
- codeName: 'harmonious-cacophonies'
2074
+ codeName: 'unbelievable-advancement'
2077
2075
  };
2078
2076
 
2079
2077
 
@@ -2205,13 +2203,11 @@ function publishExternalAPI(angular){
2205
2203
  ]);
2206
2204
  }
2207
2205
 
2208
- /* global
2209
-
2210
- -JQLitePrototype,
2211
- -addEventListenerFn,
2212
- -removeEventListenerFn,
2213
- -BOOLEAN_ATTR,
2214
- -ALIASED_ATTR
2206
+ /* global JQLitePrototype: true,
2207
+ addEventListenerFn: true,
2208
+ removeEventListenerFn: true,
2209
+ BOOLEAN_ATTR: true,
2210
+ ALIASED_ATTR: true,
2215
2211
  */
2216
2212
 
2217
2213
  //////////////////////////////////
@@ -2450,12 +2446,16 @@ function jqLiteClone(element) {
2450
2446
  return element.cloneNode(true);
2451
2447
  }
2452
2448
 
2453
- function jqLiteDealoc(element){
2454
- jqLiteRemoveData(element);
2455
- var childElement;
2456
- for ( var i = 0, children = element.children, l = (children && children.length) || 0; i < l; i++) {
2457
- childElement = children[i];
2458
- jqLiteDealoc(childElement);
2449
+ function jqLiteDealoc(element, onlyDescendants){
2450
+ if (!onlyDescendants) jqLiteRemoveData(element);
2451
+
2452
+ if (element.childNodes && element.childNodes.length) {
2453
+ // we use querySelectorAll because documentFragments don't have getElementsByTagName
2454
+ var descendants = element.getElementsByTagName ? element.getElementsByTagName('*') :
2455
+ element.querySelectorAll ? element.querySelectorAll('*') : [];
2456
+ for (var i = 0, l = descendants.length; i < l; i++) {
2457
+ jqLiteRemoveData(descendants[i]);
2458
+ }
2459
2459
  }
2460
2460
  }
2461
2461
 
@@ -2637,9 +2637,7 @@ function jqLiteInheritedData(element, name, value) {
2637
2637
  }
2638
2638
 
2639
2639
  function jqLiteEmpty(element) {
2640
- for (var i = 0, childNodes = element.childNodes; i < childNodes.length; i++) {
2641
- jqLiteDealoc(childNodes[i]);
2642
- }
2640
+ jqLiteDealoc(element, true);
2643
2641
  while (element.firstChild) {
2644
2642
  element.removeChild(element.firstChild);
2645
2643
  }
@@ -2837,9 +2835,7 @@ forEach({
2837
2835
  if (isUndefined(value)) {
2838
2836
  return element.innerHTML;
2839
2837
  }
2840
- for (var i = 0, childNodes = element.childNodes; i < childNodes.length; i++) {
2841
- jqLiteDealoc(childNodes[i]);
2842
- }
2838
+ jqLiteDealoc(element, true);
2843
2839
  element.innerHTML = value;
2844
2840
  },
2845
2841
 
@@ -2959,8 +2955,6 @@ function createEventHandler(element, events) {
2959
2955
  forEach({
2960
2956
  removeData: jqLiteRemoveData,
2961
2957
 
2962
- dealoc: jqLiteDealoc,
2963
-
2964
2958
  on: function onFn(element, type, fn, unsupported){
2965
2959
  if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
2966
2960
 
@@ -4112,24 +4106,26 @@ createInjector.$$annotate = annotate;
4112
4106
  * This can be disabled by calling `$anchorScrollProvider.disableAutoScrolling()`.
4113
4107
  *
4114
4108
  * @example
4115
- <example>
4109
+ <example module="anchorScrollExample">
4116
4110
  <file name="index.html">
4117
- <div id="scrollArea" ng-controller="ScrollCtrl">
4111
+ <div id="scrollArea" ng-controller="ScrollController">
4118
4112
  <a ng-click="gotoBottom()">Go to bottom</a>
4119
4113
  <a id="bottom"></a> You're at the bottom!
4120
4114
  </div>
4121
4115
  </file>
4122
4116
  <file name="script.js">
4123
- function ScrollCtrl($scope, $location, $anchorScroll) {
4124
- $scope.gotoBottom = function (){
4125
- // set the location.hash to the id of
4126
- // the element you wish to scroll to.
4127
- $location.hash('bottom');
4128
-
4129
- // call $anchorScroll()
4130
- $anchorScroll();
4131
- };
4132
- }
4117
+ angular.module('anchorScrollExample', [])
4118
+ .controller('ScrollController', ['$scope', '$location', '$anchorScroll',
4119
+ function ($scope, $location, $anchorScroll) {
4120
+ $scope.gotoBottom = function() {
4121
+ // set the location.hash to the id of
4122
+ // the element you wish to scroll to.
4123
+ $location.hash('bottom');
4124
+
4125
+ // call $anchorScroll()
4126
+ $anchorScroll();
4127
+ };
4128
+ }]);
4133
4129
  </file>
4134
4130
  <file name="style.css">
4135
4131
  #scrollArea {
@@ -4323,6 +4319,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4323
4319
  ? after.after(element)
4324
4320
  : parent.prepend(element);
4325
4321
  async(done);
4322
+ return noop;
4326
4323
  },
4327
4324
 
4328
4325
  /**
@@ -4339,6 +4336,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4339
4336
  leave : function(element, done) {
4340
4337
  element.remove();
4341
4338
  async(done);
4339
+ return noop;
4342
4340
  },
4343
4341
 
4344
4342
  /**
@@ -4362,7 +4360,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4362
4360
  move : function(element, parent, after, done) {
4363
4361
  // Do not remove element before insert. Removing will cause data associated with the
4364
4362
  // element to be dropped. Insert will implicitly do the remove.
4365
- this.enter(element, parent, after, done);
4363
+ return this.enter(element, parent, after, done);
4366
4364
  },
4367
4365
 
4368
4366
  /**
@@ -4379,13 +4377,14 @@ var $AnimateProvider = ['$provide', function($provide) {
4379
4377
  * className value has been added to the element
4380
4378
  */
4381
4379
  addClass : function(element, className, done) {
4382
- className = isString(className) ?
4383
- className :
4384
- isArray(className) ? className.join(' ') : '';
4380
+ className = !isString(className)
4381
+ ? (isArray(className) ? className.join(' ') : '')
4382
+ : className;
4385
4383
  forEach(element, function (element) {
4386
4384
  jqLiteAddClass(element, className);
4387
4385
  });
4388
4386
  async(done);
4387
+ return noop;
4389
4388
  },
4390
4389
 
4391
4390
  /**
@@ -4409,6 +4408,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4409
4408
  jqLiteRemoveClass(element, className);
4410
4409
  });
4411
4410
  async(done);
4411
+ return noop;
4412
4412
  },
4413
4413
 
4414
4414
  /**
@@ -4431,6 +4431,7 @@ var $AnimateProvider = ['$provide', function($provide) {
4431
4431
  jqLiteRemoveClass(element, remove);
4432
4432
  });
4433
4433
  async(done);
4434
+ return noop;
4434
4435
  },
4435
4436
 
4436
4437
  enabled : noop
@@ -5390,7 +5391,7 @@ function $TemplateCacheProvider() {
5390
5391
  * local name. Given `<widget my-attr="count = count + value">` and widget definition of
5391
5392
  * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to
5392
5393
  * a function wrapper for the `count = count + value` expression. Often it's desirable to
5393
- * pass data from the isolated scope via an expression and to the parent scope, this can be
5394
+ * pass data from the isolated scope via an expression to the parent scope, this can be
5394
5395
  * done by passing a map of local variable names and values into the expression wrapper fn.
5395
5396
  * For example, if the expression is `increment(amount)` then we can specify the amount value
5396
5397
  * by calling the `localFn` as `localFn({amount: 22})`.
@@ -5630,10 +5631,10 @@ function $TemplateCacheProvider() {
5630
5631
  * to illustrate how `$compile` works.
5631
5632
  * </div>
5632
5633
  *
5633
- <example module="compile">
5634
+ <example module="compileExample">
5634
5635
  <file name="index.html">
5635
5636
  <script>
5636
- angular.module('compile', [], function($compileProvider) {
5637
+ angular.module('compileExample', [], function($compileProvider) {
5637
5638
  // configure new 'compile' directive by passing a directive
5638
5639
  // factory function. The factory function injects the '$compile'
5639
5640
  $compileProvider.directive('compile', function($compile) {
@@ -5657,15 +5658,14 @@ function $TemplateCacheProvider() {
5657
5658
  }
5658
5659
  );
5659
5660
  };
5660
- })
5661
- });
5662
-
5663
- function Ctrl($scope) {
5661
+ });
5662
+ })
5663
+ .controller('GreeterController', ['$scope', function($scope) {
5664
5664
  $scope.name = 'Angular';
5665
5665
  $scope.html = 'Hello {{name}}';
5666
- }
5666
+ }]);
5667
5667
  </script>
5668
- <div ng-controller="Ctrl">
5668
+ <div ng-controller="GreeterController">
5669
5669
  <input ng-model="name"> <br>
5670
5670
  <textarea ng-model="html"></textarea> <br>
5671
5671
  <div compile="html"></div>
@@ -6093,14 +6093,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6093
6093
  $linkNode.data('$' + name + 'Controller', instance);
6094
6094
  });
6095
6095
 
6096
- // Attach scope only to non-text nodes.
6097
- for(var i = 0, ii = $linkNode.length; i<ii; i++) {
6098
- var node = $linkNode[i],
6099
- nodeType = node.nodeType;
6100
- if (nodeType === 1 /* element */ || nodeType === 9 /* document */) {
6101
- $linkNode.eq(i).data('$scope', scope);
6102
- }
6103
- }
6096
+ $linkNode.data('$scope', scope);
6104
6097
 
6105
6098
  if (cloneConnectFn) cloneConnectFn($linkNode, scope);
6106
6099
  if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
@@ -7356,6 +7349,7 @@ function tokenDifference(str1, str2) {
7356
7349
  */
7357
7350
  function $ControllerProvider() {
7358
7351
  var controllers = {},
7352
+ globals = false,
7359
7353
  CNTRL_REG = /^(\S+)(\s+as\s+(\w+))?$/;
7360
7354
 
7361
7355
 
@@ -7376,6 +7370,15 @@ function $ControllerProvider() {
7376
7370
  }
7377
7371
  };
7378
7372
 
7373
+ /**
7374
+ * @ngdoc method
7375
+ * @name $controllerProvider#allowGlobals
7376
+ * @description If called, allows `$controller` to find controller constructors on `window`
7377
+ */
7378
+ this.allowGlobals = function() {
7379
+ globals = true;
7380
+ };
7381
+
7379
7382
 
7380
7383
  this.$get = ['$injector', '$window', function($injector, $window) {
7381
7384
 
@@ -7390,7 +7393,8 @@ function $ControllerProvider() {
7390
7393
  *
7391
7394
  * * check if a controller with given name is registered via `$controllerProvider`
7392
7395
  * * check if evaluating the string on the current scope returns a constructor
7393
- * * check `window[constructor]` on the global `window` object
7396
+ * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
7397
+ * `window` object (not recommended)
7394
7398
  *
7395
7399
  * @param {Object} locals Injection locals for Controller.
7396
7400
  * @return {Object} Instance of given controller.
@@ -7410,7 +7414,8 @@ function $ControllerProvider() {
7410
7414
  identifier = match[3];
7411
7415
  expression = controllers.hasOwnProperty(constructor)
7412
7416
  ? controllers[constructor]
7413
- : getter(locals.$scope, constructor, true) || getter($window, constructor, true);
7417
+ : getter(locals.$scope, constructor, true) ||
7418
+ (globals ? getter($window, constructor, true) : undefined);
7414
7419
 
7415
7420
  assertArgFn(expression, constructor, true);
7416
7421
  }
@@ -7441,18 +7446,19 @@ function $ControllerProvider() {
7441
7446
  * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.
7442
7447
  *
7443
7448
  * @example
7444
- <example>
7449
+ <example module="documentExample">
7445
7450
  <file name="index.html">
7446
- <div ng-controller="MainCtrl">
7451
+ <div ng-controller="ExampleController">
7447
7452
  <p>$document title: <b ng-bind="title"></b></p>
7448
7453
  <p>window.document title: <b ng-bind="windowTitle"></b></p>
7449
7454
  </div>
7450
7455
  </file>
7451
7456
  <file name="script.js">
7452
- function MainCtrl($scope, $document) {
7453
- $scope.title = $document[0].title;
7454
- $scope.windowTitle = angular.element(window.document)[0].title;
7455
- }
7457
+ angular.module('documentExample', [])
7458
+ .controller('ExampleController', ['$scope', '$document', function($scope, $document) {
7459
+ $scope.title = $document[0].title;
7460
+ $scope.windowTitle = angular.element(window.document)[0].title;
7461
+ }]);
7456
7462
  </file>
7457
7463
  </example>
7458
7464
  */
@@ -7585,12 +7591,39 @@ function isSuccess(status) {
7585
7591
  }
7586
7592
 
7587
7593
 
7594
+ /**
7595
+ * @ngdoc provider
7596
+ * @name $httpProvider
7597
+ * @description
7598
+ * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
7599
+ * */
7588
7600
  function $HttpProvider() {
7589
7601
  var JSON_START = /^\s*(\[|\{[^\{])/,
7590
7602
  JSON_END = /[\}\]]\s*$/,
7591
7603
  PROTECTION_PREFIX = /^\)\]\}',?\n/,
7592
7604
  CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'};
7593
7605
 
7606
+ /**
7607
+ * @ngdoc property
7608
+ * @name $httpProvider#defaults
7609
+ * @description
7610
+ *
7611
+ * Object containing default values for all {@link ng.$http $http} requests.
7612
+ *
7613
+ * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
7614
+ * Defaults value is `'XSRF-TOKEN'`.
7615
+ *
7616
+ * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the
7617
+ * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.
7618
+ *
7619
+ * - **`defaults.headers`** - {Object} - Default headers for all $http requests.
7620
+ * Refer to {@link ng.$http#setting-http-headers $http} for documentation on
7621
+ * setting default headers.
7622
+ * - **`defaults.headers.common`**
7623
+ * - **`defaults.headers.post`**
7624
+ * - **`defaults.headers.put`**
7625
+ * - **`defaults.headers.patch`**
7626
+ **/
7594
7627
  var defaults = this.defaults = {
7595
7628
  // transform incoming response data
7596
7629
  transformResponse: [function(data) {
@@ -8008,9 +8041,9 @@ function $HttpProvider() {
8008
8041
  *
8009
8042
  *
8010
8043
  * @example
8011
- <example>
8044
+ <example module="httpExample">
8012
8045
  <file name="index.html">
8013
- <div ng-controller="FetchCtrl">
8046
+ <div ng-controller="FetchController">
8014
8047
  <select ng-model="method">
8015
8048
  <option>GET</option>
8016
8049
  <option>JSONP</option>
@@ -8032,30 +8065,32 @@ function $HttpProvider() {
8032
8065
  </div>
8033
8066
  </file>
8034
8067
  <file name="script.js">
8035
- function FetchCtrl($scope, $http, $templateCache) {
8036
- $scope.method = 'GET';
8037
- $scope.url = 'http-hello.html';
8038
-
8039
- $scope.fetch = function() {
8040
- $scope.code = null;
8041
- $scope.response = null;
8042
-
8043
- $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
8044
- success(function(data, status) {
8045
- $scope.status = status;
8046
- $scope.data = data;
8047
- }).
8048
- error(function(data, status) {
8049
- $scope.data = data || "Request failed";
8050
- $scope.status = status;
8051
- });
8052
- };
8068
+ angular.module('httpExample', [])
8069
+ .controller('FetchController', ['$scope', '$http', '$templateCache',
8070
+ function($scope, $http, $templateCache) {
8071
+ $scope.method = 'GET';
8072
+ $scope.url = 'http-hello.html';
8073
+
8074
+ $scope.fetch = function() {
8075
+ $scope.code = null;
8076
+ $scope.response = null;
8077
+
8078
+ $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
8079
+ success(function(data, status) {
8080
+ $scope.status = status;
8081
+ $scope.data = data;
8082
+ }).
8083
+ error(function(data, status) {
8084
+ $scope.data = data || "Request failed";
8085
+ $scope.status = status;
8086
+ });
8087
+ };
8053
8088
 
8054
- $scope.updateModel = function(method, url) {
8055
- $scope.method = method;
8056
- $scope.url = url;
8057
- };
8058
- }
8089
+ $scope.updateModel = function(method, url) {
8090
+ $scope.method = method;
8091
+ $scope.url = url;
8092
+ };
8093
+ }]);
8059
8094
  </file>
8060
8095
  <file name="http-hello.html">
8061
8096
  Hello, $http!
@@ -8109,7 +8144,7 @@ function $HttpProvider() {
8109
8144
  var reqData = transformData(config.data, headersGetter(headers), config.transformRequest);
8110
8145
 
8111
8146
  // strip content-type if data is undefined
8112
- if (isUndefined(config.data)) {
8147
+ if (isUndefined(reqData)) {
8113
8148
  forEach(headers, function(value, header) {
8114
8149
  if (lowercase(header) === 'content-type') {
8115
8150
  delete headers[header];
@@ -8178,10 +8213,6 @@ function $HttpProvider() {
8178
8213
 
8179
8214
  defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
8180
8215
 
8181
- // execute if header value is function
8182
- execHeaders(defHeaders);
8183
- execHeaders(reqHeaders);
8184
-
8185
8216
  // using for-in instead of forEach to avoid unecessary iteration after header has been found
8186
8217
  defaultHeadersIteration:
8187
8218
  for (defHeaderName in defHeaders) {
@@ -8196,6 +8227,8 @@ function $HttpProvider() {
8196
8227
  reqHeaders[defHeaderName] = defHeaders[defHeaderName];
8197
8228
  }
8198
8229
 
8230
+ // execute if header value is a function for merged headers
8231
+ execHeaders(reqHeaders);
8199
8232
  return reqHeaders;
8200
8233
 
8201
8234
  function execHeaders(headers) {
@@ -9103,25 +9136,27 @@ function $IntervalProvider() {
9103
9136
  * @returns {promise} A promise which will be notified on each iteration.
9104
9137
  *
9105
9138
  * @example
9106
- * <example module="time">
9107
- * <file name="index.html">
9108
- * <script>
9109
- * function Ctrl2($scope,$interval) {
9110
- * $scope.format = 'M/d/yy h:mm:ss a';
9111
- * $scope.blood_1 = 100;
9112
- * $scope.blood_2 = 120;
9139
+ * <example module="intervalExample">
9140
+ * <file name="index.html">
9141
+ * <script>
9142
+ * angular.module('intervalExample', [])
9143
+ * .controller('ExampleController', ['$scope', '$interval',
9144
+ * function($scope, $interval) {
9145
+ * $scope.format = 'M/d/yy h:mm:ss a';
9146
+ * $scope.blood_1 = 100;
9147
+ * $scope.blood_2 = 120;
9113
9148
  *
9114
- * var stop;
9115
- * $scope.fight = function() {
9116
- * // Don't start a new fight if we are already fighting
9117
- * if ( angular.isDefined(stop) ) return;
9149
+ * var stop;
9150
+ * $scope.fight = function() {
9151
+ * // Don't start a new fight if we are already fighting
9152
+ * if ( angular.isDefined(stop) ) return;
9118
9153
  *
9119
9154
  * stop = $interval(function() {
9120
9155
  * if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
9121
- * $scope.blood_1 = $scope.blood_1 - 3;
9122
- * $scope.blood_2 = $scope.blood_2 - 4;
9156
+ * $scope.blood_1 = $scope.blood_1 - 3;
9157
+ * $scope.blood_2 = $scope.blood_2 - 4;
9123
9158
  * } else {
9124
- * $scope.stopFight();
9159
+ * $scope.stopFight();
9125
9160
  * }
9126
9161
  * }, 100);
9127
9162
  * };
@@ -9136,22 +9171,21 @@ function $IntervalProvider() {
9136
9171
  * $scope.resetFight = function() {
9137
9172
  * $scope.blood_1 = 100;
9138
9173
  * $scope.blood_2 = 120;
9139
- * }
9174
+ * };
9140
9175
  *
9141
9176
  * $scope.$on('$destroy', function() {
9142
- * // Make sure that the interval is destroyed too
9177
+ * // Make sure that the interval nis destroyed too
9143
9178
  * $scope.stopFight();
9144
9179
  * });
9145
- * }
9146
- *
9147
- * angular.module('time', [])
9148
- * // Register the 'myCurrentTime' directive factory method.
9149
- * // We inject $interval and dateFilter service since the factory method is DI.
9150
- * .directive('myCurrentTime', function($interval, dateFilter) {
9180
+ * })
9181
+ * // Register the 'myCurrentTime' directive factory method.
9182
+ * // We inject $interval and dateFilter service since the factory method is DI.
9183
+ * .directive('myCurrentTime', ['$interval', 'dateFilter',
9184
+ * function($interval, dateFilter) {
9151
9185
  * // return the directive link function. (compile function not needed)
9152
9186
  * return function(scope, element, attrs) {
9153
9187
  * var format, // date format
9154
- * stopTime; // so that we can cancel the time updates
9188
+ * stopTime; // so that we can cancel the time updates
9155
9189
  *
9156
9190
  * // used to update the UI
9157
9191
  * function updateTime() {
@@ -9167,28 +9201,28 @@ function $IntervalProvider() {
9167
9201
  * stopTime = $interval(updateTime, 1000);
9168
9202
  *
9169
9203
  * // listen on DOM destroy (removal) event, and cancel the next UI update
9170
- * // to prevent updating time ofter the DOM element was removed.
9204
+ * // to prevent updating time after the DOM element was removed.
9171
9205
  * element.on('$destroy', function() {
9172
9206
  * $interval.cancel(stopTime);
9173
9207
  * });
9174
9208
  * }
9175
9209
  * });
9176
- * </script>
9210
+ * </script>
9177
9211
  *
9178
- * <div>
9179
- * <div ng-controller="Ctrl2">
9180
- * Date format: <input ng-model="format"> <hr/>
9181
- * Current time is: <span my-current-time="format"></span>
9182
- * <hr/>
9183
- * Blood 1 : <font color='red'>{{blood_1}}</font>
9184
- * Blood 2 : <font color='red'>{{blood_2}}</font>
9185
- * <button type="button" data-ng-click="fight()">Fight</button>
9186
- * <button type="button" data-ng-click="stopFight()">StopFight</button>
9187
- * <button type="button" data-ng-click="resetFight()">resetFight</button>
9188
- * </div>
9212
+ * <div>
9213
+ * <div ng-controller="ExampleController">
9214
+ * Date format: <input ng-model="format"> <hr/>
9215
+ * Current time is: <span my-current-time="format"></span>
9216
+ * <hr/>
9217
+ * Blood 1 : <font color='red'>{{blood_1}}</font>
9218
+ * Blood 2 : <font color='red'>{{blood_2}}</font>
9219
+ * <button type="button" data-ng-click="fight()">Fight</button>
9220
+ * <button type="button" data-ng-click="stopFight()">StopFight</button>
9221
+ * <button type="button" data-ng-click="resetFight()">resetFight</button>
9189
9222
  * </div>
9223
+ * </div>
9190
9224
  *
9191
- * </file>
9225
+ * </file>
9192
9226
  * </example>
9193
9227
  */
9194
9228
  function interval(fn, delay, count, invokeApply) {
@@ -9745,14 +9779,17 @@ LocationHashbangInHtml5Url.prototype =
9745
9779
  * If the argument is a hash object containing an array of values, these values will be encoded
9746
9780
  * as duplicate search parameters in the url.
9747
9781
  *
9748
- * @param {(string|Array<string>)=} paramValue If `search` is a string, then `paramValue` will
9749
- * override only a single search property.
9782
+ * @param {(string|Array<string>|boolean)=} paramValue If `search` is a string, then `paramValue`
9783
+ * will override only a single search property.
9750
9784
  *
9751
9785
  * If `paramValue` is an array, it will override the property of the `search` component of
9752
9786
  * `$location` specified via the first argument.
9753
9787
  *
9754
9788
  * If `paramValue` is `null`, the property specified via the first argument will be deleted.
9755
9789
  *
9790
+ * If `paramValue` is `true`, the property specified via the first argument will be added with no
9791
+ * value nor trailing equal sign.
9792
+ *
9756
9793
  * @return {Object} If called with no arguments returns the parsed `search` object. If called with
9757
9794
  * one or more arguments returns `$location` object itself.
9758
9795
  */
@@ -9764,6 +9801,11 @@ LocationHashbangInHtml5Url.prototype =
9764
9801
  if (isString(search)) {
9765
9802
  this.$$search = parseKeyValue(search);
9766
9803
  } else if (isObject(search)) {
9804
+ // remove object undefined or null properties
9805
+ forEach(search, function(value, key) {
9806
+ if (value == null) delete search[key];
9807
+ });
9808
+
9767
9809
  this.$$search = search;
9768
9810
  } else {
9769
9811
  throw $locationMinErr('isrcharg',
@@ -10085,15 +10127,16 @@ function $LocationProvider(){
10085
10127
  * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
10086
10128
  *
10087
10129
  * @example
10088
- <example>
10130
+ <example module="logExample">
10089
10131
  <file name="script.js">
10090
- function LogCtrl($scope, $log) {
10091
- $scope.$log = $log;
10092
- $scope.message = 'Hello World!';
10093
- }
10132
+ angular.module('logExample', [])
10133
+ .controller('LogController', ['$scope', '$log', function($scope, $log) {
10134
+ $scope.$log = $log;
10135
+ $scope.message = 'Hello World!';
10136
+ }]);
10094
10137
  </file>
10095
10138
  <file name="index.html">
10096
- <div ng-controller="LogCtrl">
10139
+ <div ng-controller="LogController">
10097
10140
  <p>Reload this page with open console, enter text and hit the log button...</p>
10098
10141
  Message:
10099
10142
  <input type="text" ng-model="message"/>
@@ -10117,7 +10160,7 @@ function $LogProvider(){
10117
10160
  self = this;
10118
10161
 
10119
10162
  /**
10120
- * @ngdoc property
10163
+ * @ngdoc method
10121
10164
  * @name $logProvider#debugEnabled
10122
10165
  * @description
10123
10166
  * @param {boolean=} flag enable or disable debug level messages
@@ -11106,26 +11149,6 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp) {
11106
11149
  };
11107
11150
  }
11108
11151
 
11109
- function simpleGetterFn1(key0, fullExp) {
11110
- ensureSafeMemberName(key0, fullExp);
11111
-
11112
- return function simpleGetterFn1(scope, locals) {
11113
- if (scope == null) return undefined;
11114
- return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
11115
- };
11116
- }
11117
-
11118
- function simpleGetterFn2(key0, key1, fullExp) {
11119
- ensureSafeMemberName(key0, fullExp);
11120
- ensureSafeMemberName(key1, fullExp);
11121
-
11122
- return function simpleGetterFn2(scope, locals) {
11123
- if (scope == null) return undefined;
11124
- scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
11125
- return scope == null ? undefined : scope[key1];
11126
- };
11127
- }
11128
-
11129
11152
  function getterFn(path, options, fullExp) {
11130
11153
  // Check whether the cache has this getter already.
11131
11154
  // We can use hasOwnProperty directly on the cache because we ensure,
@@ -11138,13 +11161,8 @@ function getterFn(path, options, fullExp) {
11138
11161
  pathKeysLength = pathKeys.length,
11139
11162
  fn;
11140
11163
 
11141
- // When we have only 1 or 2 tokens, use optimized special case closures.
11142
11164
  // http://jsperf.com/angularjs-parse-getter/6
11143
- if (pathKeysLength === 1) {
11144
- fn = simpleGetterFn1(pathKeys[0], fullExp);
11145
- } else if (pathKeysLength === 2) {
11146
- fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp);
11147
- } else if (options.csp) {
11165
+ if (options.csp) {
11148
11166
  if (pathKeysLength < 6) {
11149
11167
  fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp);
11150
11168
  } else {
@@ -13282,19 +13300,21 @@ function adjustMatchers(matchers) {
13282
13300
  *
13283
13301
  * Here is what a secure configuration for this scenario might look like:
13284
13302
  *
13285
- * <pre class="prettyprint">
13286
- * angular.module('myApp', []).config(function($sceDelegateProvider) {
13287
- * $sceDelegateProvider.resourceUrlWhitelist([
13288
- * // Allow same origin resource loads.
13289
- * 'self',
13290
- * // Allow loading from our assets domain. Notice the difference between * and **.
13291
- * 'http://srv*.assets.example.com/**']);
13292
- *
13293
- * // The blacklist overrides the whitelist so the open redirect here is blocked.
13294
- * $sceDelegateProvider.resourceUrlBlacklist([
13295
- * 'http://myapp.example.com/clickThru**']);
13296
- * });
13297
- * </pre>
13303
+ * ```
13304
+ * angular.module('myApp', []).config(function($sceDelegateProvider) {
13305
+ * $sceDelegateProvider.resourceUrlWhitelist([
13306
+ * // Allow same origin resource loads.
13307
+ * 'self',
13308
+ * // Allow loading from our assets domain. Notice the difference between * and **.
13309
+ * 'http://srv*.assets.example.com/**'
13310
+ * ]);
13311
+ *
13312
+ * // The blacklist overrides the whitelist so the open redirect here is blocked.
13313
+ * $sceDelegateProvider.resourceUrlBlacklist([
13314
+ * 'http://myapp.example.com/clickThru**'
13315
+ * ]);
13316
+ * });
13317
+ * ```
13298
13318
  */
13299
13319
 
13300
13320
  function $SceDelegateProvider() {
@@ -13589,10 +13609,10 @@ function $SceDelegateProvider() {
13589
13609
  *
13590
13610
  * Here's an example of a binding in a privileged context:
13591
13611
  *
13592
- * <pre class="prettyprint">
13593
- * <input ng-model="userHtml">
13594
- * <div ng-bind-html="userHtml">
13595
- * </pre>
13612
+ * ```
13613
+ * <input ng-model="userHtml">
13614
+ * <div ng-bind-html="userHtml"></div>
13615
+ * ```
13596
13616
  *
13597
13617
  * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE
13598
13618
  * disabled, this application allows the user to render arbitrary HTML into the DIV.
@@ -13632,15 +13652,15 @@ function $SceDelegateProvider() {
13632
13652
  * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly
13633
13653
  * simplified):
13634
13654
  *
13635
- * <pre class="prettyprint">
13636
- * var ngBindHtmlDirective = ['$sce', function($sce) {
13637
- * return function(scope, element, attr) {
13638
- * scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
13639
- * element.html(value || '');
13640
- * });
13641
- * };
13642
- * }];
13643
- * </pre>
13655
+ * ```
13656
+ * var ngBindHtmlDirective = ['$sce', function($sce) {
13657
+ * return function(scope, element, attr) {
13658
+ * scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
13659
+ * element.html(value || '');
13660
+ * });
13661
+ * };
13662
+ * }];
13663
+ * ```
13644
13664
  *
13645
13665
  * ## Impact on loading templates
13646
13666
  *
@@ -13744,66 +13764,65 @@ function $SceDelegateProvider() {
13744
13764
  *
13745
13765
  * ## Show me an example using SCE.
13746
13766
  *
13747
- * @example
13748
- <example module="mySceApp" deps="angular-sanitize.js">
13749
- <file name="index.html">
13750
- <div ng-controller="myAppController as myCtrl">
13751
- <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
13752
- <b>User comments</b><br>
13753
- By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
13754
- $sanitize is available. If $sanitize isn't available, this results in an error instead of an
13755
- exploit.
13756
- <div class="well">
13757
- <div ng-repeat="userComment in myCtrl.userComments">
13758
- <b>{{userComment.name}}</b>:
13759
- <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
13760
- <br>
13761
- </div>
13762
- </div>
13763
- </div>
13764
- </file>
13765
-
13766
- <file name="script.js">
13767
- var mySceApp = angular.module('mySceApp', ['ngSanitize']);
13768
-
13769
- mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) {
13770
- var self = this;
13771
- $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
13772
- self.userComments = userComments;
13773
- });
13774
- self.explicitlyTrustedHtml = $sce.trustAsHtml(
13775
- '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
13776
- 'sanitization.&quot;">Hover over this text.</span>');
13777
- });
13778
- </file>
13779
-
13780
- <file name="test_data.json">
13781
- [
13782
- { "name": "Alice",
13783
- "htmlComment":
13784
- "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
13785
- },
13786
- { "name": "Bob",
13787
- "htmlComment": "<i>Yes!</i> Am I the only other one?"
13788
- }
13789
- ]
13790
- </file>
13791
-
13792
- <file name="protractor.js" type="protractor">
13793
- describe('SCE doc demo', function() {
13794
- it('should sanitize untrusted values', function() {
13795
- expect(element(by.css('.htmlComment')).getInnerHtml())
13796
- .toBe('<span>Is <i>anyone</i> reading this?</span>');
13797
- });
13798
-
13799
- it('should NOT sanitize explicitly trusted values', function() {
13800
- expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
13801
- '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
13802
- 'sanitization.&quot;">Hover over this text.</span>');
13803
- });
13804
- });
13805
- </file>
13806
- </example>
13767
+ * <example module="mySceApp" deps="angular-sanitize.js">
13768
+ * <file name="index.html">
13769
+ * <div ng-controller="AppController as myCtrl">
13770
+ * <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
13771
+ * <b>User comments</b><br>
13772
+ * By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
13773
+ * $sanitize is available. If $sanitize isn't available, this results in an error instead of an
13774
+ * exploit.
13775
+ * <div class="well">
13776
+ * <div ng-repeat="userComment in myCtrl.userComments">
13777
+ * <b>{{userComment.name}}</b>:
13778
+ * <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
13779
+ * <br>
13780
+ * </div>
13781
+ * </div>
13782
+ * </div>
13783
+ * </file>
13784
+ *
13785
+ * <file name="script.js">
13786
+ * angular.module('mySceApp', ['ngSanitize'])
13787
+ * .controller('AppController', ['$http', '$templateCache', '$sce',
13788
+ * function($http, $templateCache, $sce) {
13789
+ * var self = this;
13790
+ * $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
13791
+ * self.userComments = userComments;
13792
+ * });
13793
+ * self.explicitlyTrustedHtml = $sce.trustAsHtml(
13794
+ * '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
13795
+ * 'sanitization.&quot;">Hover over this text.</span>');
13796
+ * }]);
13797
+ * </file>
13798
+ *
13799
+ * <file name="test_data.json">
13800
+ * [
13801
+ * { "name": "Alice",
13802
+ * "htmlComment":
13803
+ * "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
13804
+ * },
13805
+ * { "name": "Bob",
13806
+ * "htmlComment": "<i>Yes!</i> Am I the only other one?"
13807
+ * }
13808
+ * ]
13809
+ * </file>
13810
+ *
13811
+ * <file name="protractor.js" type="protractor">
13812
+ * describe('SCE doc demo', function() {
13813
+ * it('should sanitize untrusted values', function() {
13814
+ * expect(element.all(by.css('.htmlComment')).first().getInnerHtml())
13815
+ * .toBe('<span>Is <i>anyone</i> reading this?</span>');
13816
+ * });
13817
+ *
13818
+ * it('should NOT sanitize explicitly trusted values', function() {
13819
+ * expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
13820
+ * '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
13821
+ * 'sanitization.&quot;">Hover over this text.</span>');
13822
+ * });
13823
+ * });
13824
+ * </file>
13825
+ * </example>
13807
13826
  *
13808
13827
  *
13809
13828
  *
@@ -13817,13 +13836,13 @@ function $SceDelegateProvider() {
13817
13836
  *
13818
13837
  * That said, here's how you can completely disable SCE:
13819
13838
  *
13820
- * <pre class="prettyprint">
13821
- * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
13822
- * // Completely disable SCE. For demonstration purposes only!
13823
- * // Do not use in new projects.
13824
- * $sceProvider.enabled(false);
13825
- * });
13826
- * </pre>
13839
+ * ```
13840
+ * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
13841
+ * // Completely disable SCE. For demonstration purposes only!
13842
+ * // Do not use in new projects.
13843
+ * $sceProvider.enabled(false);
13844
+ * });
13845
+ * ```
13827
13846
  *
13828
13847
  */
13829
13848
  /* jshint maxlen: 100 */
@@ -14522,17 +14541,18 @@ function urlIsSameOrigin(requestUrl) {
14522
14541
  * expression.
14523
14542
  *
14524
14543
  * @example
14525
- <example>
14544
+ <example module="windowExample">
14526
14545
  <file name="index.html">
14527
14546
  <script>
14528
- function Ctrl($scope, $window) {
14529
- $scope.greeting = 'Hello, World!';
14530
- $scope.doGreeting = function(greeting) {
14547
+ angular.module('windowExample', [])
14548
+ .controller('ExampleController', ['$scope', '$window', function ($scope, $window) {
14549
+ $scope.greeting = 'Hello, World!';
14550
+ $scope.doGreeting = function(greeting) {
14531
14551
  $window.alert(greeting);
14532
- };
14533
- }
14552
+ };
14553
+ }]);
14534
14554
  </script>
14535
- <div ng-controller="Ctrl">
14555
+ <div ng-controller="ExampleController">
14536
14556
  <input type="text" ng-model="greeting" />
14537
14557
  <button ng-click="doGreeting(greeting)">ALERT</button>
14538
14558
  </div>
@@ -14550,6 +14570,17 @@ function $WindowProvider(){
14550
14570
  this.$get = valueFn(window);
14551
14571
  }
14552
14572
 
14573
+ /* global currencyFilter: true,
14574
+ dateFilter: true,
14575
+ filterFilter: true,
14576
+ jsonFilter: true,
14577
+ limitToFilter: true,
14578
+ lowercaseFilter: true,
14579
+ numberFilter: true,
14580
+ orderByFilter: true,
14581
+ uppercaseFilter: true,
14582
+ */
14583
+
14553
14584
  /**
14554
14585
  * @ngdoc provider
14555
14586
  * @name $filterProvider
@@ -14931,14 +14962,15 @@ function filterFilter() {
14931
14962
  *
14932
14963
  *
14933
14964
  * @example
14934
- <example>
14965
+ <example module="currencyExample">
14935
14966
  <file name="index.html">
14936
14967
  <script>
14937
- function Ctrl($scope) {
14938
- $scope.amount = 1234.56;
14939
- }
14968
+ angular.module('currencyExample', [])
14969
+ .controller('ExampleController', ['$scope', function($scope) {
14970
+ $scope.amount = 1234.56;
14971
+ }]);
14940
14972
  </script>
14941
- <div ng-controller="Ctrl">
14973
+ <div ng-controller="ExampleController">
14942
14974
  <input type="number" ng-model="amount"> <br>
14943
14975
  default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
14944
14976
  custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
@@ -14990,14 +15022,15 @@ function currencyFilter($locale) {
14990
15022
  * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
14991
15023
  *
14992
15024
  * @example
14993
- <example>
15025
+ <example module="numberFilterExample">
14994
15026
  <file name="index.html">
14995
15027
  <script>
14996
- function Ctrl($scope) {
14997
- $scope.val = 1234.56789;
14998
- }
15028
+ angular.module('numberFilterExample', [])
15029
+ .controller('ExampleController', ['$scope', function($scope) {
15030
+ $scope.val = 1234.56789;
15031
+ }]);
14999
15032
  </script>
15000
- <div ng-controller="Ctrl">
15033
+ <div ng-controller="ExampleController">
15001
15034
  Enter number: <input ng-model='val'><br>
15002
15035
  Default formatting: <span id='number-default'>{{val | number}}</span><br>
15003
15036
  No fractions: <span>{{val | number:0}}</span><br>
@@ -15451,17 +15484,18 @@ var uppercaseFilter = valueFn(uppercase);
15451
15484
  * had less than `limit` elements.
15452
15485
  *
15453
15486
  * @example
15454
- <example>
15487
+ <example module="limitToExample">
15455
15488
  <file name="index.html">
15456
15489
  <script>
15457
- function Ctrl($scope) {
15458
- $scope.numbers = [1,2,3,4,5,6,7,8,9];
15459
- $scope.letters = "abcdefghi";
15460
- $scope.numLimit = 3;
15461
- $scope.letterLimit = 3;
15462
- }
15490
+ angular.module('limitToExample', [])
15491
+ .controller('ExampleController', ['$scope', function($scope) {
15492
+ $scope.numbers = [1,2,3,4,5,6,7,8,9];
15493
+ $scope.letters = "abcdefghi";
15494
+ $scope.numLimit = 3;
15495
+ $scope.letterLimit = 3;
15496
+ }]);
15463
15497
  </script>
15464
- <div ng-controller="Ctrl">
15498
+ <div ng-controller="ExampleController">
15465
15499
  Limit {{numbers}} to: <input type="integer" ng-model="numLimit">
15466
15500
  <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
15467
15501
  Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
@@ -15573,20 +15607,21 @@ function limitToFilter(){
15573
15607
  * @returns {Array} Sorted copy of the source array.
15574
15608
  *
15575
15609
  * @example
15576
- <example>
15610
+ <example module="orderByExample">
15577
15611
  <file name="index.html">
15578
15612
  <script>
15579
- function Ctrl($scope) {
15580
- $scope.friends =
15581
- [{name:'John', phone:'555-1212', age:10},
15582
- {name:'Mary', phone:'555-9876', age:19},
15583
- {name:'Mike', phone:'555-4321', age:21},
15584
- {name:'Adam', phone:'555-5678', age:35},
15585
- {name:'Julie', phone:'555-8765', age:29}]
15586
- $scope.predicate = '-age';
15587
- }
15613
+ angular.module('orderByExample', [])
15614
+ .controller('ExampleController', ['$scope', function($scope) {
15615
+ $scope.friends =
15616
+ [{name:'John', phone:'555-1212', age:10},
15617
+ {name:'Mary', phone:'555-9876', age:19},
15618
+ {name:'Mike', phone:'555-4321', age:21},
15619
+ {name:'Adam', phone:'555-5678', age:35},
15620
+ {name:'Julie', phone:'555-8765', age:29}];
15621
+ $scope.predicate = '-age';
15622
+ }]);
15588
15623
  </script>
15589
- <div ng-controller="Ctrl">
15624
+ <div ng-controller="ExampleController">
15590
15625
  <pre>Sorting predicate = {{predicate}}; reverse = {{reverse}}</pre>
15591
15626
  <hr/>
15592
15627
  [ <a href="" ng-click="predicate=''">unsorted</a> ]
@@ -15614,7 +15649,7 @@ function limitToFilter(){
15614
15649
  * Example:
15615
15650
  *
15616
15651
  * @example
15617
- <example>
15652
+ <example module="orderByExample">
15618
15653
  <file name="index.html">
15619
15654
  <div ng-controller="Ctrl">
15620
15655
  <table class="friend">
@@ -15634,21 +15669,21 @@ function limitToFilter(){
15634
15669
  </file>
15635
15670
 
15636
15671
  <file name="script.js">
15637
- function Ctrl($scope, $filter) {
15638
- var orderBy = $filter('orderBy');
15639
- $scope.friends = [
15640
- { name: 'John', phone: '555-1212', age: 10 },
15641
- { name: 'Mary', phone: '555-9876', age: 19 },
15642
- { name: 'Mike', phone: '555-4321', age: 21 },
15643
- { name: 'Adam', phone: '555-5678', age: 35 },
15644
- { name: 'Julie', phone: '555-8765', age: 29 }
15645
- ];
15646
-
15647
- $scope.order = function(predicate, reverse) {
15648
- $scope.friends = orderBy($scope.friends, predicate, reverse);
15649
- };
15650
- $scope.order('-age',false);
15651
- }
15672
+ angular.module('orderByExample', [])
15673
+ .controller('ExampleController', ['$scope', '$filter', function($scope, $filter) {
15674
+ var orderBy = $filter('orderBy');
15675
+ $scope.friends = [
15676
+ { name: 'John', phone: '555-1212', age: 10 },
15677
+ { name: 'Mary', phone: '555-9876', age: 19 },
15678
+ { name: 'Mike', phone: '555-4321', age: 21 },
15679
+ { name: 'Adam', phone: '555-5678', age: 35 },
15680
+ { name: 'Julie', phone: '555-8765', age: 29 }
15681
+ ];
15682
+ $scope.order = function(predicate, reverse) {
15683
+ $scope.friends = orderBy($scope.friends, predicate, reverse);
15684
+ };
15685
+ $scope.order('-age',false);
15686
+ }]);
15652
15687
  </file>
15653
15688
  </example>
15654
15689
  */
@@ -15834,7 +15869,7 @@ var htmlAnchorDirective = valueFn({
15834
15869
  return browser.driver.getCurrentUrl().then(function(url) {
15835
15870
  return url.match(/\/123$/);
15836
15871
  });
15837
- }, 1000, 'page should navigate to /123');
15872
+ }, 5000, 'page should navigate to /123');
15838
15873
  });
15839
15874
 
15840
15875
  xit('should execute ng-click but not reload when href empty string and name specified', function() {
@@ -15862,7 +15897,7 @@ var htmlAnchorDirective = valueFn({
15862
15897
  return browser.driver.getCurrentUrl().then(function(url) {
15863
15898
  return url.match(/\/6$/);
15864
15899
  });
15865
- }, 1000, 'page should navigate to /6');
15900
+ }, 5000, 'page should navigate to /6');
15866
15901
  });
15867
15902
  </file>
15868
15903
  </example>
@@ -16261,6 +16296,23 @@ function FormController(element, attrs, $scope, $animate) {
16261
16296
  $animate.addClass(element, (isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
16262
16297
  }
16263
16298
 
16299
+ /**
16300
+ * @ngdoc method
16301
+ * @name form.FormController#$rollbackViewValue
16302
+ *
16303
+ * @description
16304
+ * Rollback all form controls pending updates to the `$modelValue`.
16305
+ *
16306
+ * Updates may be pending by a debounced event or because the input is waiting for a some future
16307
+ * event defined in `ng-model-options`. This method is typically needed by the reset button of
16308
+ * a form that uses `ng-model-options` to pend updates.
16309
+ */
16310
+ form.$rollbackViewValue = function() {
16311
+ forEach(controls, function(control) {
16312
+ control.$rollbackViewValue();
16313
+ });
16314
+ };
16315
+
16264
16316
  /**
16265
16317
  * @ngdoc method
16266
16318
  * @name form.FormController#$commitViewValue
@@ -16522,12 +16574,13 @@ function FormController(element, attrs, $scope, $animate) {
16522
16574
  * </pre>
16523
16575
  *
16524
16576
  * @example
16525
- <example deps="angular-animate.js" animations="true" fixBase="true">
16577
+ <example deps="angular-animate.js" animations="true" fixBase="true" module="formExample">
16526
16578
  <file name="index.html">
16527
16579
  <script>
16528
- function Ctrl($scope) {
16529
- $scope.userType = 'guest';
16530
- }
16580
+ angular.module('formExample', [])
16581
+ .controller('FormController', ['$scope', function($scope) {
16582
+ $scope.userType = 'guest';
16583
+ }]);
16531
16584
  </script>
16532
16585
  <style>
16533
16586
  .my-form {
@@ -16539,7 +16592,7 @@ function FormController(element, attrs, $scope, $animate) {
16539
16592
  background: red;
16540
16593
  }
16541
16594
  </style>
16542
- <form name="myForm" ng-controller="Ctrl" class="my-form">
16595
+ <form name="myForm" ng-controller="FormController" class="my-form">
16543
16596
  userType: <input name="input" ng-model="userType" required>
16544
16597
  <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
16545
16598
  <tt>userType = {{userType}}</tt><br>
@@ -16637,18 +16690,16 @@ var formDirectiveFactory = function(isNgForm) {
16637
16690
  var formDirective = formDirectiveFactory();
16638
16691
  var ngFormDirective = formDirectiveFactory(true);
16639
16692
 
16640
- /* global
16641
-
16642
- -VALID_CLASS,
16643
- -INVALID_CLASS,
16644
- -PRISTINE_CLASS,
16645
- -DIRTY_CLASS,
16646
- -UNTOUCHED_CLASS,
16647
- -TOUCHED_CLASS
16693
+ /* global VALID_CLASS: true,
16694
+ INVALID_CLASS: true,
16695
+ PRISTINE_CLASS: true,
16696
+ DIRTY_CLASS: true,
16697
+ UNTOUCHED_CLASS: true,
16698
+ TOUCHED_CLASS: true,
16648
16699
  */
16649
16700
 
16650
16701
  var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
16651
- var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
16702
+ 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;
16652
16703
  var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
16653
16704
  var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
16654
16705
  var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)$/;
@@ -16684,15 +16735,16 @@ var inputType = {
16684
16735
  * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
16685
16736
  *
16686
16737
  * @example
16687
- <example name="text-input-directive">
16738
+ <example name="text-input-directive" module="textInputExample">
16688
16739
  <file name="index.html">
16689
16740
  <script>
16690
- function Ctrl($scope) {
16691
- $scope.text = 'guest';
16692
- $scope.word = /^\s*\w*\s*$/;
16693
- }
16741
+ angular.module('textInputExample', [])
16742
+ .controller('ExampleController', ['$scope', function($scope) {
16743
+ $scope.text = 'guest';
16744
+ $scope.word = /^\s*\w*\s*$/;
16745
+ }]);
16694
16746
  </script>
16695
- <form name="myForm" ng-controller="Ctrl">
16747
+ <form name="myForm" ng-controller="ExampleController">
16696
16748
  Single word: <input type="text" name="input" ng-model="text"
16697
16749
  ng-pattern="word" required ng-trim="false">
16698
16750
  <span class="error" ng-show="myForm.input.$error.required">
@@ -16759,14 +16811,15 @@ var inputType = {
16759
16811
  * interaction with the input element.
16760
16812
  *
16761
16813
  * @example
16762
- <example name="date-input-directive">
16814
+ <example name="date-input-directive" module="dateInputExample">
16763
16815
  <file name="index.html">
16764
16816
  <script>
16765
- function Ctrl($scope) {
16766
- $scope.value = new Date(2013, 9, 22);
16767
- }
16817
+ angular.module('dateInputExample', [])
16818
+ .controller('DateController', ['$scope', function($scope) {
16819
+ $scope.value = new Date(2013, 9, 22);
16820
+ }]);
16768
16821
  </script>
16769
- <form name="myForm" ng-controller="Ctrl as dateCtrl">
16822
+ <form name="myForm" ng-controller="DateController as dateCtrl">
16770
16823
  Pick a date between in 2013:
16771
16824
  <input type="date" id="exampleInput" name="input" ng-model="value"
16772
16825
  placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
@@ -16843,14 +16896,15 @@ var inputType = {
16843
16896
  * interaction with the input element.
16844
16897
  *
16845
16898
  * @example
16846
- <example name="datetimelocal-input-directive">
16899
+ <example name="datetimelocal-input-directive" module="dateExample">
16847
16900
  <file name="index.html">
16848
16901
  <script>
16849
- function Ctrl($scope) {
16850
- $scope.value = new Date(2010, 11, 28, 14, 57);
16851
- }
16902
+ angular.module('dateExample', [])
16903
+ .controller('DateController', ['$scope', function($scope) {
16904
+ $scope.value = new Date(2010, 11, 28, 14, 57);
16905
+ }]);
16852
16906
  </script>
16853
- <form name="myForm" ng-controller="Ctrl as dateCtrl">
16907
+ <form name="myForm" ng-controller="DateController as dateCtrl">
16854
16908
  Pick a date between in 2013:
16855
16909
  <input type="datetime-local" id="exampleInput" name="input" ng-model="value"
16856
16910
  placeholder="yyyy-MM-ddTHH:mm" min="2001-01-01T00:00" max="2013-12-31T00:00" required />
@@ -16928,14 +16982,15 @@ var inputType = {
16928
16982
  * interaction with the input element.
16929
16983
  *
16930
16984
  * @example
16931
- <example name="time-input-directive">
16985
+ <example name="time-input-directive" module="timeExample">
16932
16986
  <file name="index.html">
16933
16987
  <script>
16934
- function Ctrl($scope) {
16935
- $scope.value = new Date(0, 0, 1, 14, 57);
16936
- }
16988
+ angular.module('timeExample', [])
16989
+ .controller('DateController', ['$scope', function($scope) {
16990
+ $scope.value = new Date(0, 0, 1, 14, 57);
16991
+ }]);
16937
16992
  </script>
16938
- <form name="myForm" ng-controller="Ctrl as dateCtrl">
16993
+ <form name="myForm" ng-controller="DateController as dateCtrl">
16939
16994
  Pick a between 8am and 5pm:
16940
16995
  <input type="time" id="exampleInput" name="input" ng-model="value"
16941
16996
  placeholder="HH:mm" min="08:00" max="17:00" required />
@@ -17012,14 +17067,15 @@ var inputType = {
17012
17067
  * interaction with the input element.
17013
17068
  *
17014
17069
  * @example
17015
- <example name="week-input-directive">
17070
+ <example name="week-input-directive" module="weekExample">
17016
17071
  <file name="index.html">
17017
17072
  <script>
17018
- function Ctrl($scope) {
17019
- $scope.value = new Date(2013, 0, 3);
17020
- }
17073
+ angular.module('weekExample', [])
17074
+ .controller('DateController', ['$scope', function($scope) {
17075
+ $scope.value = new Date(2013, 0, 3);
17076
+ }]);
17021
17077
  </script>
17022
- <form name="myForm" ng-controller="Ctrl as dateCtrl">
17078
+ <form name="myForm" ng-controller="DateController as dateCtrl">
17023
17079
  Pick a date between in 2013:
17024
17080
  <input id="exampleInput" type="week" name="input" ng-model="value"
17025
17081
  placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
@@ -17095,14 +17151,15 @@ var inputType = {
17095
17151
  * interaction with the input element.
17096
17152
  *
17097
17153
  * @example
17098
- <example name="month-input-directive">
17154
+ <example name="month-input-directive" module="monthExample">
17099
17155
  <file name="index.html">
17100
17156
  <script>
17101
- function Ctrl($scope) {
17102
- $scope.value = new Date(2013, 9, 1);
17103
- }
17157
+ angular.module('monthExample', [])
17158
+ .controller('DateController', ['$scope', function($scope) {
17159
+ $scope.value = new Date(2013, 9, 1);
17160
+ }]);
17104
17161
  </script>
17105
- <form name="myForm" ng-controller="Ctrl as dateCtrl">
17162
+ <form name="myForm" ng-controller="DateController as dateCtrl">
17106
17163
  Pick a month int 2013:
17107
17164
  <input id="exampleInput" type="month" name="input" ng-model="value"
17108
17165
  placeholder="yyyy-MM" min="2013-01" max="2013-12" required />
@@ -17183,14 +17240,15 @@ var inputType = {
17183
17240
  * interaction with the input element.
17184
17241
  *
17185
17242
  * @example
17186
- <example name="number-input-directive">
17243
+ <example name="number-input-directive" module="numberExample">
17187
17244
  <file name="index.html">
17188
17245
  <script>
17189
- function Ctrl($scope) {
17190
- $scope.value = 12;
17191
- }
17246
+ angular.module('numberExample', [])
17247
+ .controller('ExampleController', ['$scope', function($scope) {
17248
+ $scope.value = 12;
17249
+ }]);
17192
17250
  </script>
17193
- <form name="myForm" ng-controller="Ctrl">
17251
+ <form name="myForm" ng-controller="ExampleController">
17194
17252
  Number: <input type="number" name="input" ng-model="value"
17195
17253
  min="0" max="99" required>
17196
17254
  <span class="error" ng-show="myForm.input.$error.required">
@@ -17258,14 +17316,15 @@ var inputType = {
17258
17316
  * interaction with the input element.
17259
17317
  *
17260
17318
  * @example
17261
- <example name="url-input-directive">
17319
+ <example name="url-input-directive" module="urlExample">
17262
17320
  <file name="index.html">
17263
17321
  <script>
17264
- function Ctrl($scope) {
17265
- $scope.text = 'http://google.com';
17266
- }
17322
+ angular.module('urlExample', [])
17323
+ .controller('ExampleController', ['$scope', function($scope) {
17324
+ $scope.text = 'http://google.com';
17325
+ }]);
17267
17326
  </script>
17268
- <form name="myForm" ng-controller="Ctrl">
17327
+ <form name="myForm" ng-controller="ExampleController">
17269
17328
  URL: <input type="url" name="input" ng-model="text" required>
17270
17329
  <span class="error" ng-show="myForm.input.$error.required">
17271
17330
  Required!</span>
@@ -17334,14 +17393,15 @@ var inputType = {
17334
17393
  * interaction with the input element.
17335
17394
  *
17336
17395
  * @example
17337
- <example name="email-input-directive">
17396
+ <example name="email-input-directive" module="emailExample">
17338
17397
  <file name="index.html">
17339
17398
  <script>
17340
- function Ctrl($scope) {
17341
- $scope.text = 'me@example.com';
17342
- }
17399
+ angular.module('emailExample', [])
17400
+ .controller('ExampleController', ['$scope', function($scope) {
17401
+ $scope.text = 'me@example.com';
17402
+ }]);
17343
17403
  </script>
17344
- <form name="myForm" ng-controller="Ctrl">
17404
+ <form name="myForm" ng-controller="ExampleController">
17345
17405
  Email: <input type="email" name="input" ng-model="text" required>
17346
17406
  <span class="error" ng-show="myForm.input.$error.required">
17347
17407
  Required!</span>
@@ -17400,18 +17460,19 @@ var inputType = {
17400
17460
  * be set when selected.
17401
17461
  *
17402
17462
  * @example
17403
- <example name="radio-input-directive">
17463
+ <example name="radio-input-directive" module="radioExample">
17404
17464
  <file name="index.html">
17405
17465
  <script>
17406
- function Ctrl($scope) {
17407
- $scope.color = 'blue';
17408
- $scope.specialValue = {
17409
- "id": "12345",
17410
- "value": "green"
17411
- };
17412
- }
17466
+ angular.module('radioExample', [])
17467
+ .controller('ExampleController', ['$scope', function($scope) {
17468
+ $scope.color = 'blue';
17469
+ $scope.specialValue = {
17470
+ "id": "12345",
17471
+ "value": "green"
17472
+ };
17473
+ }]);
17413
17474
  </script>
17414
- <form name="myForm" ng-controller="Ctrl">
17475
+ <form name="myForm" ng-controller="ExampleController">
17415
17476
  <input type="radio" ng-model="color" value="red"> Red <br/>
17416
17477
  <input type="radio" ng-model="color" ng-value="specialValue"> Green <br/>
17417
17478
  <input type="radio" ng-model="color" value="blue"> Blue <br/>
@@ -17444,24 +17505,25 @@ var inputType = {
17444
17505
  *
17445
17506
  * @param {string} ngModel Assignable angular expression to data-bind to.
17446
17507
  * @param {string=} name Property name of the form under which the control is published.
17447
- * @param {string=} ngTrueValue The value to which the expression should be set when selected.
17448
- * @param {string=} ngFalseValue The value to which the expression should be set when not selected.
17508
+ * @param {expression=} ngTrueValue The value to which the expression should be set when selected.
17509
+ * @param {expression=} ngFalseValue The value to which the expression should be set when not selected.
17449
17510
  * @param {string=} ngChange Angular expression to be executed when input changes due to user
17450
17511
  * interaction with the input element.
17451
17512
  *
17452
17513
  * @example
17453
- <example name="checkbox-input-directive">
17514
+ <example name="checkbox-input-directive" module="checkboxExample">
17454
17515
  <file name="index.html">
17455
17516
  <script>
17456
- function Ctrl($scope) {
17457
- $scope.value1 = true;
17458
- $scope.value2 = 'YES'
17459
- }
17517
+ angular.module('checkboxExample', [])
17518
+ .controller('ExampleController', ['$scope', function($scope) {
17519
+ $scope.value1 = true;
17520
+ $scope.value2 = 'YES'
17521
+ }]);
17460
17522
  </script>
17461
- <form name="myForm" ng-controller="Ctrl">
17523
+ <form name="myForm" ng-controller="ExampleController">
17462
17524
  Value1: <input type="checkbox" ng-model="value1"> <br/>
17463
17525
  Value2: <input type="checkbox" ng-model="value2"
17464
- ng-true-value="YES" ng-false-value="NO"> <br/>
17526
+ ng-true-value="'YES'" ng-false-value="'NO'"> <br/>
17465
17527
  <tt>value1 = {{value1}}</tt><br/>
17466
17528
  <tt>value2 = {{value2}}</tt><br/>
17467
17529
  </form>
@@ -17820,12 +17882,22 @@ function radioInputType(scope, element, attr, ctrl) {
17820
17882
  attr.$observe('value', ctrl.$render);
17821
17883
  }
17822
17884
 
17823
- function checkboxInputType(scope, element, attr, ctrl) {
17824
- var trueValue = attr.ngTrueValue,
17825
- falseValue = attr.ngFalseValue;
17885
+ function parseConstantExpr($parse, context, name, expression, fallback) {
17886
+ var parseFn;
17887
+ if (isDefined(expression)) {
17888
+ parseFn = $parse(expression);
17889
+ if (!parseFn.constant) {
17890
+ throw new minErr('ngModel')('constexpr', 'Expected constant expression for `{0}`, but saw ' +
17891
+ '`{1}`.', name, expression);
17892
+ }
17893
+ return parseFn(context);
17894
+ }
17895
+ return fallback;
17896
+ }
17826
17897
 
17827
- if (!isString(trueValue)) trueValue = true;
17828
- if (!isString(falseValue)) falseValue = false;
17898
+ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
17899
+ var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);
17900
+ var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);
17829
17901
 
17830
17902
  var listener = function(ev) {
17831
17903
  scope.$apply(function() {
@@ -17845,7 +17917,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
17845
17917
  };
17846
17918
 
17847
17919
  ctrl.$formatters.push(function(value) {
17848
- return value === trueValue;
17920
+ return equals(value, trueValue);
17849
17921
  });
17850
17922
 
17851
17923
  ctrl.$parsers.push(function(value) {
@@ -17907,14 +17979,15 @@ function checkboxInputType(scope, element, attr, ctrl) {
17907
17979
  * interaction with the input element.
17908
17980
  *
17909
17981
  * @example
17910
- <example name="input-directive">
17982
+ <example name="input-directive" module="inputExample">
17911
17983
  <file name="index.html">
17912
17984
  <script>
17913
- function Ctrl($scope) {
17914
- $scope.user = {name: 'guest', last: 'visitor'};
17915
- }
17985
+ angular.module('inputExample', [])
17986
+ .controller('ExampleController', ['$scope', function($scope) {
17987
+ $scope.user = {name: 'guest', last: 'visitor'};
17988
+ }]);
17916
17989
  </script>
17917
- <div ng-controller="Ctrl">
17990
+ <div ng-controller="ExampleController">
17918
17991
  <form name="myForm">
17919
17992
  User name: <input type="text" name="userName" ng-model="user.name" required>
17920
17993
  <span class="error" ng-show="myForm.userName.$error.required">
@@ -17993,14 +18066,15 @@ function checkboxInputType(scope, element, attr, ctrl) {
17993
18066
  </file>
17994
18067
  </example>
17995
18068
  */
17996
- var inputDirective = ['$browser', '$sniffer', '$filter', function($browser, $sniffer, $filter) {
18069
+ var inputDirective = ['$browser', '$sniffer', '$filter', '$parse',
18070
+ function($browser, $sniffer, $filter, $parse) {
17997
18071
  return {
17998
18072
  restrict: 'E',
17999
18073
  require: ['?ngModel'],
18000
18074
  link: function(scope, element, attr, ctrls) {
18001
18075
  if (ctrls[0]) {
18002
18076
  (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,
18003
- $browser, $filter);
18077
+ $browser, $filter, $parse);
18004
18078
  }
18005
18079
  }
18006
18080
  };
@@ -18194,6 +18268,18 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18194
18268
  * @description
18195
18269
  * Called when the view needs to be updated. It is expected that the user of the ng-model
18196
18270
  * directive will implement this method.
18271
+ *
18272
+ * The `$render()` method is invoked in the following situations:
18273
+ *
18274
+ * * `$rollbackViewValue()` is called. If we are rolling back the view value to the last
18275
+ * committed value then `$render()` is called to update the input control.
18276
+ * * The value referenced by `ng-model` is changed programmatically and both the `$modelValue` and
18277
+ * the `$viewValue` are different to last time.
18278
+ *
18279
+ * Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
18280
+ * `$modelValue` and `$viewValue` are actually different to their previous value. If `$modelValue`
18281
+ * or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
18282
+ * invoked if you only change a property on the objects.
18197
18283
  */
18198
18284
  this.$render = noop;
18199
18285
 
@@ -18359,7 +18445,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18359
18445
  * <file name="app.js">
18360
18446
  * angular.module('cancel-update-example', [])
18361
18447
  *
18362
- * .controller('CancelUpdateCtrl', function($scope) {
18448
+ * .controller('CancelUpdateController', ['$scope', function($scope) {
18363
18449
  * $scope.resetWithCancel = function (e) {
18364
18450
  * if (e.keyCode == 27) {
18365
18451
  * $scope.myForm.myInput1.$rollbackViewValue();
@@ -18371,10 +18457,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18371
18457
  * $scope.myValue = '';
18372
18458
  * }
18373
18459
  * };
18374
- * });
18460
+ * }]);
18375
18461
  * </file>
18376
18462
  * <file name="index.html">
18377
- * <div ng-controller="CancelUpdateCtrl">
18463
+ * <div ng-controller="CancelUpdateController">
18378
18464
  * <p>Try typing something in each input. See that the model only updates when you
18379
18465
  * blur off the input.
18380
18466
  * </p>
@@ -18407,13 +18493,24 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18407
18493
  * Runs each of the registered validations set on the $validators object.
18408
18494
  */
18409
18495
  this.$validate = function() {
18410
- this.$$runValidators(ctrl.$modelValue, ctrl.$viewValue);
18496
+ // ignore $validate before model initialized
18497
+ if (ctrl.$modelValue !== ctrl.$modelValue) {
18498
+ return;
18499
+ }
18500
+
18501
+ var prev = ctrl.$modelValue;
18502
+ ctrl.$$runValidators(ctrl.$$invalidModelValue || ctrl.$modelValue, ctrl.$viewValue);
18503
+ if (prev !== ctrl.$modelValue) {
18504
+ ctrl.$$writeModelToScope();
18505
+ }
18411
18506
  };
18412
18507
 
18413
18508
  this.$$runValidators = function(modelValue, viewValue) {
18414
18509
  forEach(ctrl.$validators, function(fn, name) {
18415
18510
  ctrl.$setValidity(name, fn(modelValue, viewValue));
18416
18511
  });
18512
+ ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
18513
+ ctrl.$$invalidModelValue = ctrl.$valid ? undefined : modelValue;
18417
18514
  };
18418
18515
 
18419
18516
  /**
@@ -18452,20 +18549,28 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18452
18549
 
18453
18550
  if (ctrl.$modelValue !== modelValue &&
18454
18551
  (isUndefined(ctrl.$$invalidModelValue) || ctrl.$$invalidModelValue != modelValue)) {
18455
-
18456
18552
  ctrl.$$runValidators(modelValue, viewValue);
18457
- ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
18458
- ctrl.$$invalidModelValue = ctrl.$valid ? undefined : modelValue;
18553
+ ctrl.$$writeModelToScope();
18554
+ }
18555
+ };
18556
+
18557
+ this.$$writeModelToScope = function() {
18558
+ var getterSetter;
18559
+
18560
+ if (ctrl.$options && ctrl.$options.getterSetter &&
18561
+ isFunction(getterSetter = ngModelGet($scope))) {
18459
18562
 
18563
+ getterSetter(ctrl.$modelValue);
18564
+ } else {
18460
18565
  ngModelSet($scope, ctrl.$modelValue);
18461
- forEach(ctrl.$viewChangeListeners, function(listener) {
18462
- try {
18463
- listener();
18464
- } catch(e) {
18465
- $exceptionHandler(e);
18466
- }
18467
- });
18468
18566
  }
18567
+ forEach(ctrl.$viewChangeListeners, function(listener) {
18568
+ try {
18569
+ listener();
18570
+ } catch(e) {
18571
+ $exceptionHandler(e);
18572
+ }
18573
+ });
18469
18574
  };
18470
18575
 
18471
18576
  /**
@@ -18475,13 +18580,25 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18475
18580
  * @description
18476
18581
  * Update the view value.
18477
18582
  *
18478
- * This method should be called when the view value changes, typically from within a DOM event handler.
18479
- * For example {@link ng.directive:input input} and
18480
- * {@link ng.directive:select select} directives call it.
18583
+ * This method should be called when an input directive want to change the view value; typically,
18584
+ * this is done from within a DOM event handler.
18585
+ *
18586
+ * For example {@link ng.directive:input input} calls it when the value of the input changes and
18587
+ * {@link ng.directive:select select} calls it when an option is selected.
18481
18588
  *
18482
- * It will update the $viewValue, then pass this value through each of the functions in `$parsers`,
18483
- * which includes any validators. The value that comes out of this `$parsers` pipeline, be applied to
18484
- * `$modelValue` and the **expression** specified in the `ng-model` attribute.
18589
+ * If the new `value` is an object (rather than a string or a number), we should make a copy of the
18590
+ * object before passing it to `$setViewValue`. This is because `ngModel` does not perform a deep
18591
+ * watch of objects, it only looks for a change of identity. If you only change the property of
18592
+ * the object then ngModel will not realise that the object has changed and will not invoke the
18593
+ * `$parsers` and `$validators` pipelines.
18594
+ *
18595
+ * For this reason, you should not change properties of the copy once it has been passed to
18596
+ * `$setViewValue`. Otherwise you may cause the model value on the scope to change incorrectly.
18597
+ *
18598
+ * When this method is called, the new `value` will be staged for committing through the `$parsers`
18599
+ * and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged
18600
+ * value sent directly for processing, finally to be applied to `$modelValue` and then the
18601
+ * **expression** specified in the `ng-model` attribute.
18485
18602
  *
18486
18603
  * Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
18487
18604
  *
@@ -18533,6 +18650,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18533
18650
  $scope.$watch(function ngModelWatch() {
18534
18651
  var modelValue = ngModelGet($scope);
18535
18652
 
18653
+ if (ctrl.$options && ctrl.$options.getterSetter && isFunction(modelValue)) {
18654
+ modelValue = modelValue();
18655
+ }
18656
+
18536
18657
  // if scope model value and ngModel value are out of sync
18537
18658
  if (ctrl.$modelValue !== modelValue &&
18538
18659
  (isUndefined(ctrl.$$invalidModelValue) || ctrl.$$invalidModelValue != modelValue)) {
@@ -18546,8 +18667,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18546
18667
  }
18547
18668
 
18548
18669
  ctrl.$$runValidators(modelValue, viewValue);
18549
- ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
18550
- ctrl.$$invalidModelValue = ctrl.$valid ? undefined : modelValue;
18551
18670
 
18552
18671
  if (ctrl.$viewValue !== viewValue) {
18553
18672
  ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
@@ -18641,12 +18760,13 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18641
18760
  * </pre>
18642
18761
  *
18643
18762
  * @example
18644
- * <example deps="angular-animate.js" animations="true" fixBase="true">
18763
+ * <example deps="angular-animate.js" animations="true" fixBase="true" module="inputExample">
18645
18764
  <file name="index.html">
18646
18765
  <script>
18647
- function Ctrl($scope) {
18648
- $scope.val = '1';
18649
- }
18766
+ angular.module('inputExample', [])
18767
+ .controller('ExampleController', ['$scope', function($scope) {
18768
+ $scope.val = '1';
18769
+ }]);
18650
18770
  </script>
18651
18771
  <style>
18652
18772
  .my-input {
@@ -18661,11 +18781,60 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
18661
18781
  </style>
18662
18782
  Update input to see transitions when valid/invalid.
18663
18783
  Integer is a valid value.
18664
- <form name="testForm" ng-controller="Ctrl">
18784
+ <form name="testForm" ng-controller="ExampleController">
18665
18785
  <input ng-model="val" ng-pattern="/^\d+$/" name="anim" class="my-input" />
18666
18786
  </form>
18667
18787
  </file>
18668
18788
  * </example>
18789
+ *
18790
+ * ## Binding to a getter/setter
18791
+ *
18792
+ * Sometimes it's helpful to bind `ngModel` to a getter/setter function. A getter/setter is a
18793
+ * function that returns a representation of the model when called with zero arguments, and sets
18794
+ * the internal state of a model when called with an argument. It's sometimes useful to use this
18795
+ * for models that have an internal representation that's different than what the model exposes
18796
+ * to the view.
18797
+ *
18798
+ * <div class="alert alert-success">
18799
+ * **Best Practice:** It's best to keep getters fast because Angular is likely to call them more
18800
+ * frequently than other parts of your code.
18801
+ * </div>
18802
+ *
18803
+ * You use this behavior by adding `ng-model-options="{ getterSetter: true }"` to an element that
18804
+ * has `ng-model` attached to it. You can also add `ng-model-options="{ getterSetter: true }"` to
18805
+ * a `<form>`, which will enable this behavior for all `<input>`s within it. See
18806
+ * {@link ng.directive:ngModelOptions `ngModelOptions`} for more.
18807
+ *
18808
+ * The following example shows how to use `ngModel` with a getter/setter:
18809
+ *
18810
+ * @example
18811
+ * <example name="ngModel-getter-setter" module="getterSetterExample">
18812
+ <file name="index.html">
18813
+ <div ng-controller="ExampleController">
18814
+ <form name="userForm">
18815
+ Name:
18816
+ <input type="text" name="userName"
18817
+ ng-model="user.name"
18818
+ ng-model-options="{ getterSetter: true }" />
18819
+ </form>
18820
+ <pre>user.name = <span ng-bind="user.name()"></span></pre>
18821
+ </div>
18822
+ </file>
18823
+ <file name="app.js">
18824
+ angular.module('getterSetterExample', [])
18825
+ .controller('ExampleController', ['$scope', function($scope) {
18826
+ var _name = 'Brian';
18827
+ $scope.user = {
18828
+ name: function (newName) {
18829
+ if (angular.isDefined(newName)) {
18830
+ _name = newName;
18831
+ }
18832
+ return _name;
18833
+ }
18834
+ };
18835
+ }]);
18836
+ </file>
18837
+ * </example>
18669
18838
  */
18670
18839
  var ngModelDirective = function() {
18671
18840
  return {
@@ -18728,17 +18897,18 @@ var ngModelDirective = function() {
18728
18897
  * in input value.
18729
18898
  *
18730
18899
  * @example
18731
- * <example name="ngChange-directive">
18900
+ * <example name="ngChange-directive" module="changeExample">
18732
18901
  * <file name="index.html">
18733
18902
  * <script>
18734
- * function Controller($scope) {
18735
- * $scope.counter = 0;
18736
- * $scope.change = function() {
18737
- * $scope.counter++;
18738
- * };
18739
- * }
18903
+ * angular.module('changeExample', [])
18904
+ * .controller('ExampleController', ['$scope', function($scope) {
18905
+ * $scope.counter = 0;
18906
+ * $scope.change = function() {
18907
+ * $scope.counter++;
18908
+ * };
18909
+ * }]);
18740
18910
  * </script>
18741
- * <div ng-controller="Controller">
18911
+ * <div ng-controller="ExampleController">
18742
18912
  * <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
18743
18913
  * <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
18744
18914
  * <label for="ng-change-example2">Confirmed</label><br />
@@ -18877,14 +19047,15 @@ var minlengthDirective = function() {
18877
19047
  * specified in form `/something/` then the value will be converted into a regular expression.
18878
19048
  *
18879
19049
  * @example
18880
- <example name="ngList-directive">
19050
+ <example name="ngList-directive" module="listExample">
18881
19051
  <file name="index.html">
18882
19052
  <script>
18883
- function Ctrl($scope) {
18884
- $scope.names = ['igor', 'misko', 'vojta'];
18885
- }
19053
+ angular.module('listExample', [])
19054
+ .controller('ExampleController', ['$scope', function($scope) {
19055
+ $scope.names = ['igor', 'misko', 'vojta'];
19056
+ }]);
18886
19057
  </script>
18887
- <form name="myForm" ng-controller="Ctrl">
19058
+ <form name="myForm" ng-controller="ExampleController">
18888
19059
  List: <input name="namesInput" ng-model="names" ng-list required>
18889
19060
  <span class="error" ng-show="myForm.namesInput.$error.required">
18890
19061
  Required!</span>
@@ -18976,15 +19147,16 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
18976
19147
  * of the `input` element
18977
19148
  *
18978
19149
  * @example
18979
- <example name="ngValue-directive">
19150
+ <example name="ngValue-directive" module="valueExample">
18980
19151
  <file name="index.html">
18981
19152
  <script>
18982
- function Ctrl($scope) {
18983
- $scope.names = ['pizza', 'unicorns', 'robots'];
18984
- $scope.my = { favorite: 'unicorns' };
18985
- }
19153
+ angular.module('valueExample', [])
19154
+ .controller('ExampleController', ['$scope', function($scope) {
19155
+ $scope.names = ['pizza', 'unicorns', 'robots'];
19156
+ $scope.my = { favorite: 'unicorns' };
19157
+ }]);
18986
19158
  </script>
18987
- <form ng-controller="Ctrl">
19159
+ <form ng-controller="ExampleController">
18988
19160
  <h2>Which is your favorite?</h2>
18989
19161
  <label ng-repeat="name in names" for="{{name}}">
18990
19162
  {{name}}
@@ -19060,6 +19232,8 @@ var ngValueDirective = function() {
19060
19232
  * value of 0 triggers an immediate update. If an object is supplied instead, you can specify a
19061
19233
  * custom value for each event. For example:
19062
19234
  * `ngModelOptions="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }"`
19235
+ * - `getterSetter`: boolean value which determines whether or not to treat functions bound to
19236
+ `ngModel` as getters/setters.
19063
19237
  *
19064
19238
  * @example
19065
19239
 
@@ -19067,9 +19241,9 @@ var ngValueDirective = function() {
19067
19241
  form will update the model only when the control loses focus (blur event). If `escape` key is
19068
19242
  pressed while the input field is focused, the value is reset to the value in the current model.
19069
19243
 
19070
- <example name="ngModelOptions-directive-blur">
19244
+ <example name="ngModelOptions-directive-blur" module="optionsExample">
19071
19245
  <file name="index.html">
19072
- <div ng-controller="Ctrl">
19246
+ <div ng-controller="ExampleController">
19073
19247
  <form name="userForm">
19074
19248
  Name:
19075
19249
  <input type="text" name="userName"
@@ -19084,15 +19258,16 @@ var ngValueDirective = function() {
19084
19258
  </div>
19085
19259
  </file>
19086
19260
  <file name="app.js">
19087
- function Ctrl($scope) {
19088
- $scope.user = { name: 'say', data: '' };
19261
+ angular.module('optionsExample', [])
19262
+ .controller('ExampleController', ['$scope', function($scope) {
19263
+ $scope.user = { name: 'say', data: '' };
19089
19264
 
19090
- $scope.cancel = function (e) {
19091
- if (e.keyCode == 27) {
19092
- $scope.userForm.userName.$rollbackViewValue();
19093
- }
19094
- };
19095
- }
19265
+ $scope.cancel = function (e) {
19266
+ if (e.keyCode == 27) {
19267
+ $scope.userForm.userName.$rollbackViewValue();
19268
+ }
19269
+ };
19270
+ }]);
19096
19271
  </file>
19097
19272
  <file name="protractor.js" type="protractor">
19098
19273
  var model = element(by.binding('user.name'));
@@ -19121,9 +19296,9 @@ var ngValueDirective = function() {
19121
19296
  This one shows how to debounce model changes. Model will be updated only 1 sec after last change.
19122
19297
  If the `Clear` button is pressed, any debounced action is canceled and the value becomes empty.
19123
19298
 
19124
- <example name="ngModelOptions-directive-debounce">
19299
+ <example name="ngModelOptions-directive-debounce" module="optionsExample">
19125
19300
  <file name="index.html">
19126
- <div ng-controller="Ctrl">
19301
+ <div ng-controller="ExampleController">
19127
19302
  <form name="userForm">
19128
19303
  Name:
19129
19304
  <input type="text" name="userName"
@@ -19135,9 +19310,37 @@ var ngValueDirective = function() {
19135
19310
  </div>
19136
19311
  </file>
19137
19312
  <file name="app.js">
19138
- function Ctrl($scope) {
19139
- $scope.user = { name: 'say' };
19140
- }
19313
+ angular.module('optionsExample', [])
19314
+ .controller('ExampleController', ['$scope', function($scope) {
19315
+ $scope.user = { name: 'say' };
19316
+ }]);
19317
+ </file>
19318
+ </example>
19319
+
19320
+ This one shows how to bind to getter/setters:
19321
+
19322
+ <example name="ngModelOptions-directive-getter-setter" module="getterSetterExample">
19323
+ <file name="index.html">
19324
+ <div ng-controller="ExampleController">
19325
+ <form name="userForm">
19326
+ Name:
19327
+ <input type="text" name="userName"
19328
+ ng-model="user.name"
19329
+ ng-model-options="{ getterSetter: true }" />
19330
+ </form>
19331
+ <pre>user.name = <span ng-bind="user.name()"></span></pre>
19332
+ </div>
19333
+ </file>
19334
+ <file name="app.js">
19335
+ angular.module('getterSetterExample', [])
19336
+ .controller('ExampleController', ['$scope', function($scope) {
19337
+ var _name = 'Brian';
19338
+ $scope.user = {
19339
+ name: function (newName) {
19340
+ return angular.isDefined(newName) ? (_name = newName) : _name;
19341
+ }
19342
+ };
19343
+ }]);
19141
19344
  </file>
19142
19345
  </example>
19143
19346
  */
@@ -19187,14 +19390,15 @@ var ngModelOptionsDirective = function() {
19187
19390
  *
19188
19391
  * @example
19189
19392
  * Enter a name in the Live Preview text box; the greeting below the text box changes instantly.
19190
- <example>
19393
+ <example module="bindExample">
19191
19394
  <file name="index.html">
19192
19395
  <script>
19193
- function Ctrl($scope) {
19194
- $scope.name = 'Whirled';
19195
- }
19396
+ angular.module('bindExample', [])
19397
+ .controller('ExampleController', ['$scope', function($scope) {
19398
+ $scope.name = 'Whirled';
19399
+ }]);
19196
19400
  </script>
19197
- <div ng-controller="Ctrl">
19401
+ <div ng-controller="ExampleController">
19198
19402
  Enter name: <input type="text" ng-model="name"><br>
19199
19403
  Hello <span ng-bind="name"></span>!
19200
19404
  </div>
@@ -19245,15 +19449,16 @@ var ngBindDirective = ngDirective({
19245
19449
  *
19246
19450
  * @example
19247
19451
  * Try it here: enter text in text box and watch the greeting change.
19248
- <example>
19452
+ <example module="bindExample">
19249
19453
  <file name="index.html">
19250
19454
  <script>
19251
- function Ctrl($scope) {
19252
- $scope.salutation = 'Hello';
19253
- $scope.name = 'World';
19254
- }
19455
+ angular.module('bindExample', [])
19456
+ .controller('ExampleController', ['$scope', function ($scope) {
19457
+ $scope.salutation = 'Hello';
19458
+ $scope.name = 'World';
19459
+ }]);
19255
19460
  </script>
19256
- <div ng-controller="Ctrl">
19461
+ <div ng-controller="ExampleController">
19257
19462
  Salutation: <input type="text" ng-model="salutation"><br>
19258
19463
  Name: <input type="text" ng-model="name"><br>
19259
19464
  <pre ng-bind-template="{{salutation}} {{name}}!"></pre>
@@ -19311,20 +19516,20 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
19311
19516
  * @example
19312
19517
  Try it here: enter text in text box and watch the greeting change.
19313
19518
 
19314
- <example module="ngBindHtmlExample" deps="angular-sanitize.js">
19519
+ <example module="bindHtmlExample" deps="angular-sanitize.js">
19315
19520
  <file name="index.html">
19316
- <div ng-controller="ngBindHtmlCtrl">
19521
+ <div ng-controller="ExampleController">
19317
19522
  <p ng-bind-html="myHTML"></p>
19318
19523
  </div>
19319
19524
  </file>
19320
19525
 
19321
19526
  <file name="script.js">
19322
- angular.module('ngBindHtmlExample', ['ngSanitize'])
19323
-
19324
- .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
19325
- $scope.myHTML =
19326
- 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
19327
- }]);
19527
+ angular.module('bindHtmlExample', ['ngSanitize'])
19528
+ .controller('ExampleController', ['$scope', function($scope) {
19529
+ $scope.myHTML =
19530
+ 'I am an <code>HTML</code>string with ' +
19531
+ '<a href="#">links!</a> and other <em>stuff</em>';
19532
+ }]);
19328
19533
  </file>
19329
19534
 
19330
19535
  <file name="protractor.js" type="protractor">
@@ -19827,7 +20032,7 @@ var ngCloakDirective = ngDirective({
19827
20032
  *
19828
20033
  * This example demonstrates the `controller as` syntax.
19829
20034
  *
19830
- * <example name="ngControllerAs">
20035
+ * <example name="ngControllerAs" module="controllerAsExample">
19831
20036
  * <file name="index.html">
19832
20037
  * <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
19833
20038
  * Name: <input type="text" ng-model="settings.name"/>
@@ -19848,6 +20053,9 @@ var ngCloakDirective = ngDirective({
19848
20053
  * </div>
19849
20054
  * </file>
19850
20055
  * <file name="app.js">
20056
+ * angular.module('controllerAsExample', [])
20057
+ * .controller('SettingsController1', SettingsController1);
20058
+ *
19851
20059
  * function SettingsController1() {
19852
20060
  * this.name = "John Smith";
19853
20061
  * this.contacts = [
@@ -19876,29 +20084,29 @@ var ngCloakDirective = ngDirective({
19876
20084
  * <file name="protractor.js" type="protractor">
19877
20085
  * it('should check controller as', function() {
19878
20086
  * var container = element(by.id('ctrl-as-exmpl'));
19879
- * expect(container.findElement(by.model('settings.name'))
20087
+ * expect(container.element(by.model('settings.name'))
19880
20088
  * .getAttribute('value')).toBe('John Smith');
19881
20089
  *
19882
20090
  * var firstRepeat =
19883
- * container.findElement(by.repeater('contact in settings.contacts').row(0));
20091
+ * container.element(by.repeater('contact in settings.contacts').row(0));
19884
20092
  * var secondRepeat =
19885
- * container.findElement(by.repeater('contact in settings.contacts').row(1));
20093
+ * container.element(by.repeater('contact in settings.contacts').row(1));
19886
20094
  *
19887
- * expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
20095
+ * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
19888
20096
  * .toBe('408 555 1212');
19889
20097
  *
19890
- * expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
20098
+ * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
19891
20099
  * .toBe('john.smith@example.org');
19892
20100
  *
19893
- * firstRepeat.findElement(by.linkText('clear')).click();
20101
+ * firstRepeat.element(by.linkText('clear')).click();
19894
20102
  *
19895
- * expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
20103
+ * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
19896
20104
  * .toBe('');
19897
20105
  *
19898
- * container.findElement(by.linkText('add')).click();
20106
+ * container.element(by.linkText('add')).click();
19899
20107
  *
19900
- * expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
19901
- * .findElement(by.model('contact.value'))
20108
+ * expect(container.element(by.repeater('contact in settings.contacts').row(2))
20109
+ * .element(by.model('contact.value'))
19902
20110
  * .getAttribute('value'))
19903
20111
  * .toBe('yourname@example.org');
19904
20112
  * });
@@ -19907,7 +20115,7 @@ var ngCloakDirective = ngDirective({
19907
20115
  *
19908
20116
  * This example demonstrates the "attach to `$scope`" style of controller.
19909
20117
  *
19910
- * <example name="ngController">
20118
+ * <example name="ngController" module="controllerExample">
19911
20119
  * <file name="index.html">
19912
20120
  * <div id="ctrl-exmpl" ng-controller="SettingsController2">
19913
20121
  * Name: <input type="text" ng-model="name"/>
@@ -19928,6 +20136,9 @@ var ngCloakDirective = ngDirective({
19928
20136
  * </div>
19929
20137
  * </file>
19930
20138
  * <file name="app.js">
20139
+ * angular.module('controllerExample', [])
20140
+ * .controller('SettingsController2', ['$scope', SettingsController2]);
20141
+ *
19931
20142
  * function SettingsController2($scope) {
19932
20143
  * $scope.name = "John Smith";
19933
20144
  * $scope.contacts = [
@@ -19957,28 +20168,28 @@ var ngCloakDirective = ngDirective({
19957
20168
  * it('should check controller', function() {
19958
20169
  * var container = element(by.id('ctrl-exmpl'));
19959
20170
  *
19960
- * expect(container.findElement(by.model('name'))
20171
+ * expect(container.element(by.model('name'))
19961
20172
  * .getAttribute('value')).toBe('John Smith');
19962
20173
  *
19963
20174
  * var firstRepeat =
19964
- * container.findElement(by.repeater('contact in contacts').row(0));
20175
+ * container.element(by.repeater('contact in contacts').row(0));
19965
20176
  * var secondRepeat =
19966
- * container.findElement(by.repeater('contact in contacts').row(1));
20177
+ * container.element(by.repeater('contact in contacts').row(1));
19967
20178
  *
19968
- * expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
20179
+ * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
19969
20180
  * .toBe('408 555 1212');
19970
- * expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
20181
+ * expect(secondRepeat.element(by.model('contact.value')).getAttribute('value'))
19971
20182
  * .toBe('john.smith@example.org');
19972
20183
  *
19973
- * firstRepeat.findElement(by.linkText('clear')).click();
20184
+ * firstRepeat.element(by.linkText('clear')).click();
19974
20185
  *
19975
- * expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
20186
+ * expect(firstRepeat.element(by.model('contact.value')).getAttribute('value'))
19976
20187
  * .toBe('');
19977
20188
  *
19978
- * container.findElement(by.linkText('add')).click();
20189
+ * container.element(by.linkText('add')).click();
19979
20190
  *
19980
- * expect(container.findElement(by.repeater('contact in contacts').row(2))
19981
- * .findElement(by.model('contact.value'))
20191
+ * expect(container.element(by.repeater('contact in contacts').row(2))
20192
+ * .element(by.model('contact.value'))
19982
20193
  * .getAttribute('value'))
19983
20194
  * .toBe('yourname@example.org');
19984
20195
  * });
@@ -20349,21 +20560,22 @@ forEach(
20349
20560
  * ({@link guide/expression#-event- Event object is available as `$event`})
20350
20561
  *
20351
20562
  * @example
20352
- <example>
20563
+ <example module="submitExample">
20353
20564
  <file name="index.html">
20354
20565
  <script>
20355
- function Ctrl($scope) {
20356
- $scope.list = [];
20357
- $scope.text = 'hello';
20358
- $scope.submit = function() {
20359
- if ($scope.text) {
20360
- $scope.list.push(this.text);
20361
- $scope.text = '';
20362
- }
20363
- };
20364
- }
20566
+ angular.module('submitExample', [])
20567
+ .controller('ExampleController', ['$scope', function($scope) {
20568
+ $scope.list = [];
20569
+ $scope.text = 'hello';
20570
+ $scope.submit = function() {
20571
+ if ($scope.text) {
20572
+ $scope.list.push(this.text);
20573
+ $scope.text = '';
20574
+ }
20575
+ };
20576
+ }]);
20365
20577
  </script>
20366
- <form ng-submit="submit()" ng-controller="Ctrl">
20578
+ <form ng-submit="submit()" ng-controller="ExampleController">
20367
20579
  Enter text and hit enter:
20368
20580
  <input type="text" ng-model="text" name="text" />
20369
20581
  <input type="submit" id="submit" value="Submit" />
@@ -20375,7 +20587,7 @@ forEach(
20375
20587
  expect(element(by.binding('list')).getText()).toBe('list=[]');
20376
20588
  element(by.css('#submit')).click();
20377
20589
  expect(element(by.binding('list')).getText()).toContain('hello');
20378
- expect(element(by.input('text')).getAttribute('value')).toBe('');
20590
+ expect(element(by.model('text')).getAttribute('value')).toBe('');
20379
20591
  });
20380
20592
  it('should ignore empty strings', function() {
20381
20593
  expect(element(by.binding('list')).getText()).toBe('list=[]');
@@ -20648,9 +20860,9 @@ var ngIfDirective = ['$animate', function($animate) {
20648
20860
  * - Otherwise enable scrolling only if the expression evaluates to truthy value.
20649
20861
  *
20650
20862
  * @example
20651
- <example module="ngAnimate" deps="angular-animate.js" animations="true">
20863
+ <example module="includeExample" deps="angular-animate.js" animations="true">
20652
20864
  <file name="index.html">
20653
- <div ng-controller="Ctrl">
20865
+ <div ng-controller="ExampleController">
20654
20866
  <select ng-model="template" ng-options="t.name for t in templates">
20655
20867
  <option value="">(blank)</option>
20656
20868
  </select>
@@ -20662,12 +20874,13 @@ var ngIfDirective = ['$animate', function($animate) {
20662
20874
  </div>
20663
20875
  </file>
20664
20876
  <file name="script.js">
20665
- function Ctrl($scope) {
20666
- $scope.templates =
20667
- [ { name: 'template1.html', url: 'template1.html'},
20668
- { name: 'template2.html', url: 'template2.html'} ];
20669
- $scope.template = $scope.templates[0];
20670
- }
20877
+ angular.module('includeExample', ['ngAnimate'])
20878
+ .controller('ExampleController', ['$scope', function($scope) {
20879
+ $scope.templates =
20880
+ [ { name: 'template1.html', url: 'template1.html'},
20881
+ { name: 'template2.html', url: 'template2.html'} ];
20882
+ $scope.template = $scope.templates[0];
20883
+ }]);
20671
20884
  </file>
20672
20885
  <file name="template1.html">
20673
20886
  Content of template1.html
@@ -20730,7 +20943,7 @@ var ngIfDirective = ['$animate', function($animate) {
20730
20943
  return;
20731
20944
  }
20732
20945
  templateSelect.click();
20733
- templateSelect.element.all(by.css('option')).get(2).click();
20946
+ templateSelect.all(by.css('option')).get(2).click();
20734
20947
  expect(includeElem.getText()).toMatch(/Content of template2.html/);
20735
20948
  });
20736
20949
 
@@ -20740,7 +20953,7 @@ var ngIfDirective = ['$animate', function($animate) {
20740
20953
  return;
20741
20954
  }
20742
20955
  templateSelect.click();
20743
- templateSelect.element.all(by.css('option')).get(0).click();
20956
+ templateSelect.all(by.css('option')).get(0).click();
20744
20957
  expect(includeElem.isPresent()).toBe(false);
20745
20958
  });
20746
20959
  </file>
@@ -20768,8 +20981,7 @@ var ngIfDirective = ['$animate', function($animate) {
20768
20981
 
20769
20982
  /**
20770
20983
  * @ngdoc event
20771
- * @name ng.directive:ngInclude#$includeContentError
20772
- * @eventOf ng.directive:ngInclude
20984
+ * @name ngInclude#$includeContentError
20773
20985
  * @eventType emit on the scope ngInclude was declared in
20774
20986
  * @description
20775
20987
  * Emitted when a template HTTP request yields an erronous response (status < 200 || status > 299)
@@ -20905,14 +21117,15 @@ var ngIncludeFillContentDirective = ['$compile',
20905
21117
  * @param {expression} ngInit {@link guide/expression Expression} to eval.
20906
21118
  *
20907
21119
  * @example
20908
- <example>
21120
+ <example module="initExample">
20909
21121
  <file name="index.html">
20910
21122
  <script>
20911
- function Ctrl($scope) {
20912
- $scope.list = [['a', 'b'], ['c', 'd']];
20913
- }
21123
+ angular.module('initExample', [])
21124
+ .controller('ExampleController', ['$scope', function($scope) {
21125
+ $scope.list = [['a', 'b'], ['c', 'd']];
21126
+ }]);
20914
21127
  </script>
20915
- <div ng-controller="Ctrl">
21128
+ <div ng-controller="ExampleController">
20916
21129
  <div ng-repeat="innerList in list" ng-init="outerIndex = $index">
20917
21130
  <div ng-repeat="value in innerList" ng-init="innerIndex = $index">
20918
21131
  <span class="example-init">list[ {{outerIndex}} ][ {{innerIndex}} ] = {{value}};</span>
@@ -21065,16 +21278,17 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
21065
21278
  * @param {number=} offset Offset to deduct from the total number.
21066
21279
  *
21067
21280
  * @example
21068
- <example>
21281
+ <example module="pluralizeExample">
21069
21282
  <file name="index.html">
21070
21283
  <script>
21071
- function Ctrl($scope) {
21072
- $scope.person1 = 'Igor';
21073
- $scope.person2 = 'Misko';
21074
- $scope.personCount = 1;
21075
- }
21284
+ angular.module('pluralizeExample', [])
21285
+ .controller('ExampleController', ['$scope', function($scope) {
21286
+ $scope.person1 = 'Igor';
21287
+ $scope.person2 = 'Misko';
21288
+ $scope.personCount = 1;
21289
+ }]);
21076
21290
  </script>
21077
- <div ng-controller="Ctrl">
21291
+ <div ng-controller="ExampleController">
21078
21292
  Person 1:<input type="text" ng-model="person1" value="Igor" /><br/>
21079
21293
  Person 2:<input type="text" ng-model="person2" value="Misko" /><br/>
21080
21294
  Number of People:<input type="text" ng-model="personCount" value="1" /><br/>
@@ -22006,9 +22220,9 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
22006
22220
  *
22007
22221
  *
22008
22222
  * @example
22009
- <example module="ngAnimate" deps="angular-animate.js" animations="true">
22223
+ <example module="switchExample" deps="angular-animate.js" animations="true">
22010
22224
  <file name="index.html">
22011
- <div ng-controller="Ctrl">
22225
+ <div ng-controller="ExampleController">
22012
22226
  <select ng-model="selection" ng-options="item for item in items">
22013
22227
  </select>
22014
22228
  <tt>selection={{selection}}</tt>
@@ -22022,10 +22236,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
22022
22236
  </div>
22023
22237
  </file>
22024
22238
  <file name="script.js">
22025
- function Ctrl($scope) {
22026
- $scope.items = ['settings', 'home', 'other'];
22027
- $scope.selection = $scope.items[0];
22028
- }
22239
+ angular.module('switchExample', ['ngAnimate'])
22240
+ .controller('ExampleController', ['$scope', function($scope) {
22241
+ $scope.items = ['settings', 'home', 'other'];
22242
+ $scope.selection = $scope.items[0];
22243
+ }]);
22029
22244
  </file>
22030
22245
  <file name="animations.css">
22031
22246
  .animate-switch-container {
@@ -22068,11 +22283,11 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
22068
22283
  expect(switchElem.getText()).toMatch(/Settings Div/);
22069
22284
  });
22070
22285
  it('should change to home', function() {
22071
- select.element.all(by.css('option')).get(1).click();
22286
+ select.all(by.css('option')).get(1).click();
22072
22287
  expect(switchElem.getText()).toMatch(/Home Span/);
22073
22288
  });
22074
22289
  it('should select default', function() {
22075
- select.element.all(by.css('option')).get(2).click();
22290
+ select.all(by.css('option')).get(2).click();
22076
22291
  expect(switchElem.getText()).toMatch(/default/);
22077
22292
  });
22078
22293
  </file>
@@ -22164,15 +22379,10 @@ var ngSwitchDefaultDirective = ngDirective({
22164
22379
  * @element ANY
22165
22380
  *
22166
22381
  * @example
22167
- <example module="transclude">
22382
+ <example module="transcludeExample">
22168
22383
  <file name="index.html">
22169
22384
  <script>
22170
- function Ctrl($scope) {
22171
- $scope.title = 'Lorem Ipsum';
22172
- $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
22173
- }
22174
-
22175
- angular.module('transclude', [])
22385
+ angular.module('transcludeExample', [])
22176
22386
  .directive('pane', function(){
22177
22387
  return {
22178
22388
  restrict: 'E',
@@ -22183,9 +22393,13 @@ var ngSwitchDefaultDirective = ngDirective({
22183
22393
  '<div ng-transclude></div>' +
22184
22394
  '</div>'
22185
22395
  };
22186
- });
22396
+ })
22397
+ .controller('ExampleController', ['$scope', function($scope) {
22398
+ $scope.title = 'Lorem Ipsum';
22399
+ $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
22400
+ }]);
22187
22401
  </script>
22188
- <div ng-controller="Ctrl">
22402
+ <div ng-controller="ExampleController">
22189
22403
  <input ng-model="title"><br>
22190
22404
  <textarea ng-model="text"></textarea> <br/>
22191
22405
  <pane title="{{title}}">{{text}}</pane>
@@ -22344,21 +22558,22 @@ var ngOptionsMinErr = minErr('ngOptions');
22344
22558
  * `value` variable (e.g. `value.propertyName`).
22345
22559
  *
22346
22560
  * @example
22347
- <example>
22561
+ <example module="selectExample">
22348
22562
  <file name="index.html">
22349
22563
  <script>
22350
- function MyCntrl($scope) {
22351
- $scope.colors = [
22352
- {name:'black', shade:'dark'},
22353
- {name:'white', shade:'light'},
22354
- {name:'red', shade:'dark'},
22355
- {name:'blue', shade:'dark'},
22356
- {name:'yellow', shade:'light'}
22357
- ];
22358
- $scope.myColor = $scope.colors[2]; // red
22359
- }
22564
+ angular.module('selectExample', [])
22565
+ .controller('ExampleController', ['$scope', function($scope) {
22566
+ $scope.colors = [
22567
+ {name:'black', shade:'dark'},
22568
+ {name:'white', shade:'light'},
22569
+ {name:'red', shade:'dark'},
22570
+ {name:'blue', shade:'dark'},
22571
+ {name:'yellow', shade:'light'}
22572
+ ];
22573
+ $scope.myColor = $scope.colors[2]; // red
22574
+ }]);
22360
22575
  </script>
22361
- <div ng-controller="MyCntrl">
22576
+ <div ng-controller="ExampleController">
22362
22577
  <ul>
22363
22578
  <li ng-repeat="color in colors">
22364
22579
  Name: <input ng-model="color.name">
@@ -22395,7 +22610,7 @@ var ngOptionsMinErr = minErr('ngOptions');
22395
22610
  <file name="protractor.js" type="protractor">
22396
22611
  it('should check ng-options', function() {
22397
22612
  expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('red');
22398
- element.all(by.select('myColor')).first().click();
22613
+ element.all(by.model('myColor')).first().click();
22399
22614
  element.all(by.css('select[ng-model="myColor"] option')).first().click();
22400
22615
  expect(element(by.binding('{selected_color:myColor}')).getText()).toMatch('black');
22401
22616
  element(by.css('.nullable select[ng-model="myColor"]')).click();
@@ -22435,7 +22650,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
22435
22650
  };
22436
22651
 
22437
22652
 
22438
- self.addOption = function(value) {
22653
+ self.addOption = function(value, element) {
22439
22654
  assertNotHasOwnProperty(value, '"option value"');
22440
22655
  optionsMap[value] = true;
22441
22656
 
@@ -22443,6 +22658,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
22443
22658
  $element.val(value);
22444
22659
  if (unknownOption.parent()) unknownOption.remove();
22445
22660
  }
22661
+ // Workaround for https://code.google.com/p/chromium/issues/detail?id=381459
22662
+ // Adding an <option selected="selected"> element to a <select required="required"> should
22663
+ // automatically select the new element
22664
+ if (element[0].hasAttribute('selected')) {
22665
+ element[0].selected = true;
22666
+ }
22446
22667
  };
22447
22668
 
22448
22669
 
@@ -22896,10 +23117,10 @@ var optionDirective = ['$interpolate', function($interpolate) {
22896
23117
  if (oldVal !== newVal) {
22897
23118
  selectCtrl.removeOption(oldVal);
22898
23119
  }
22899
- selectCtrl.addOption(newVal);
23120
+ selectCtrl.addOption(newVal, element);
22900
23121
  });
22901
23122
  } else {
22902
- selectCtrl.addOption(attr.value);
23123
+ selectCtrl.addOption(attr.value, element);
22903
23124
  }
22904
23125
 
22905
23126
  element.on('$destroy', function() {