angularjs-rails 1.0.3 → 1.0.4

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
  module AngularJS
2
2
  module Rails
3
- VERSION = "1.0.3"
3
+ VERSION = "1.0.4"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -10,10 +10,10 @@ var directive = {};
10
10
  var service = { value: {} };
11
11
 
12
12
  var DEPENDENCIES = {
13
- 'angular.js': 'http://code.angularjs.org/angular-' + angular.version.full + '.min.js',
14
- 'angular-resource.js': 'http://code.angularjs.org/angular-resource-' + angular.version.full + '.min.js',
15
- 'angular-sanitize.js': 'http://code.angularjs.org/angular-sanitize-' + angular.version.full + '.min.js',
16
- 'angular-cookies.js': 'http://code.angularjs.org/angular-cookies-' + angular.version.full + '.min.js'
13
+ 'angular.js': 'http://code.angularjs.org/' + angular.version.full + 'angular.min.js',
14
+ 'angular-resource.js': 'http://code.angularjs.org/' + angular.version.full + 'angular-resource.min.js',
15
+ 'angular-sanitize.js': 'http://code.angularjs.org/' + angular.version.full + 'angular-sanitize.min.js',
16
+ 'angular-cookies.js': 'http://code.angularjs.org/' + angular.version.full + 'angular-cookies.min.js'
17
17
  };
18
18
 
19
19
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,6 +1,5 @@
1
-
2
1
  /**
3
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
4
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
5
4
  * License: MIT
6
5
  *
@@ -203,6 +202,30 @@ angular.mock.$Browser.prototype = {
203
202
  * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
204
203
  * into it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration
205
204
  * information.
205
+ *
206
+ *
207
+ * <pre>
208
+ * describe('$exceptionHandlerProvider', function() {
209
+ *
210
+ * it('should capture log messages and exceptions', function() {
211
+ *
212
+ * module(function($exceptionHandlerProvider) {
213
+ * $exceptionHandlerProvider.mode('log');
214
+ * });
215
+ *
216
+ * inject(function($log, $exceptionHandler, $timeout) {
217
+ * $timeout(function() { $log.log(1); });
218
+ * $timeout(function() { $log.log(2); throw 'banana peel'; });
219
+ * $timeout(function() { $log.log(3); });
220
+ * expect($exceptionHandler.errors).toEqual([]);
221
+ * expect($log.assertEmpty());
222
+ * $timeout.flush();
223
+ * expect($exceptionHandler.errors).toEqual(['banana peel']);
224
+ * expect($log.log.logs).toEqual([[1], [2], [3]]);
225
+ * });
226
+ * });
227
+ * });
228
+ * </pre>
206
229
  */
207
230
 
208
231
  angular.mock.$ExceptionHandlerProvider = function() {
@@ -221,8 +244,8 @@ angular.mock.$ExceptionHandlerProvider = function() {
221
244
  * - `rethrow`: If any errors are are passed into the handler in tests, it typically
222
245
  * means that there is a bug in the application or test, so this mock will
223
246
  * make these tests fail.
224
- * - `log`: Sometimes it is desirable to test that an error is throw, for this case the `log` mode stores the
225
- * error and allows later assertion of it.
247
+ * - `log`: Sometimes it is desirable to test that an error is throw, for this case the `log` mode stores an
248
+ * array of errors in `$exceptionHandler.errors`, to allow later assertion of them.
226
249
  * See {@link ngMock.$log#assertEmpty assertEmpty()} and
227
250
  * {@link ngMock.$log#reset reset()}
228
251
  */
@@ -562,7 +585,7 @@ angular.mock.$LogProvider = function() {
562
585
 
563
586
  /**
564
587
  * @ngdoc function
565
- * @name angular.mock.debug
588
+ * @name angular.mock.dump
566
589
  * @description
567
590
  *
568
591
  * *NOTE*: this is not an injectable instance, just a globally available function.
@@ -745,7 +768,7 @@ angular.mock.dump = function(object) {
745
768
  }
746
769
 
747
770
  // testing controller
748
- var $http;
771
+ var $httpBackend;
749
772
 
750
773
  beforeEach(inject(function($injector) {
751
774
  $httpBackend = $injector.get('$httpBackend');
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -12,7 +12,7 @@
12
12
  * @description
13
13
  */
14
14
 
15
- /**
15
+ /**
16
16
  * @ngdoc object
17
17
  * @name ngResource.$resource
18
18
  * @requires $http
@@ -25,7 +25,9 @@
25
25
  * the need to interact with the low level {@link ng.$http $http} service.
26
26
  *
27
27
  * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
28
- * `/user/:username`.
28
+ * `/user/:username`. If you are using a URL with a port number (e.g.
29
+ * `http://example.com:8080/api`), you'll need to escape the colon character before the port
30
+ * number, like this: `$resource('http://example.com\\:8080/api')`.
29
31
  *
30
32
  * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
31
33
  * `actions` methods.
@@ -230,46 +232,46 @@ angular.module('ngResource', ['ng']).
230
232
  return $parse(path)(obj);
231
233
  };
232
234
 
233
- /**
234
- * We need our custom mehtod because encodeURIComponent is too aggressive and doesn't follow
235
- * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
236
- * segments:
237
- * segment = *pchar
238
- * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
239
- * pct-encoded = "%" HEXDIG HEXDIG
240
- * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
241
- * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
242
- * / "*" / "+" / "," / ";" / "="
243
- */
244
- function encodeUriSegment(val) {
245
- return encodeUriQuery(val, true).
246
- replace(/%26/gi, '&').
247
- replace(/%3D/gi, '=').
248
- replace(/%2B/gi, '+');
249
- }
250
-
251
-
252
- /**
253
- * This method is intended for encoding *key* or *value* parts of query component. We need a custom
254
- * method becuase encodeURIComponent is too agressive and encodes stuff that doesn't have to be
255
- * encoded per http://tools.ietf.org/html/rfc3986:
256
- * query = *( pchar / "/" / "?" )
257
- * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
258
- * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
259
- * pct-encoded = "%" HEXDIG HEXDIG
260
- * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
261
- * / "*" / "+" / "," / ";" / "="
262
- */
263
- function encodeUriQuery(val, pctEncodeSpaces) {
264
- return encodeURIComponent(val).
265
- replace(/%40/gi, '@').
266
- replace(/%3A/gi, ':').
267
- replace(/%24/g, '$').
268
- replace(/%2C/gi, ',').
269
- replace((pctEncodeSpaces ? null : /%20/g), '+');
270
- }
271
-
272
- function Route(template, defaults) {
235
+ /**
236
+ * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
237
+ * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
238
+ * segments:
239
+ * segment = *pchar
240
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
241
+ * pct-encoded = "%" HEXDIG HEXDIG
242
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
243
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
244
+ * / "*" / "+" / "," / ";" / "="
245
+ */
246
+ function encodeUriSegment(val) {
247
+ return encodeUriQuery(val, true).
248
+ replace(/%26/gi, '&').
249
+ replace(/%3D/gi, '=').
250
+ replace(/%2B/gi, '+');
251
+ }
252
+
253
+
254
+ /**
255
+ * This method is intended for encoding *key* or *value* parts of query component. We need a custom
256
+ * method becuase encodeURIComponent is too agressive and encodes stuff that doesn't have to be
257
+ * encoded per http://tools.ietf.org/html/rfc3986:
258
+ * query = *( pchar / "/" / "?" )
259
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
260
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
261
+ * pct-encoded = "%" HEXDIG HEXDIG
262
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
263
+ * / "*" / "+" / "," / ";" / "="
264
+ */
265
+ function encodeUriQuery(val, pctEncodeSpaces) {
266
+ return encodeURIComponent(val).
267
+ replace(/%40/gi, '@').
268
+ replace(/%3A/gi, ':').
269
+ replace(/%24/g, '$').
270
+ replace(/%2C/gi, ',').
271
+ replace((pctEncodeSpaces ? null : /%20/g), '+');
272
+ }
273
+
274
+ function Route(template, defaults) {
273
275
  this.template = template = template + '#';
274
276
  this.defaults = defaults || {};
275
277
  var urlParams = this.urlParams = {};
@@ -295,7 +297,14 @@ angular.module('ngResource', ['ng']).
295
297
  encodedVal = encodeUriSegment(val);
296
298
  url = url.replace(new RegExp(":" + urlParam + "(\\W)", "g"), encodedVal + "$1");
297
299
  } else {
298
- url = url.replace(new RegExp("/?:" + urlParam + "(\\W)", "g"), '$1');
300
+ url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W)", "g"), function(match,
301
+ leadingSlashes, tail) {
302
+ if (tail.charAt(0) == '/') {
303
+ return tail;
304
+ } else {
305
+ return leadingSlashes + tail;
306
+ }
307
+ });
299
308
  }
300
309
  });
301
310
  url = url.replace(/\/?#$/, '');
@@ -331,6 +340,7 @@ angular.module('ngResource', ['ng']).
331
340
  }
332
341
 
333
342
  forEach(actions, function(action, name) {
343
+ action.method = angular.uppercase(action.method);
334
344
  var hasBody = action.method == 'POST' || action.method == 'PUT' || action.method == 'PATCH';
335
345
  Resource[name] = function(a1, a2, a3, a4) {
336
346
  var params = {};
@@ -396,11 +406,6 @@ angular.module('ngResource', ['ng']).
396
406
  };
397
407
 
398
408
 
399
- Resource.bind = function(additionalParamDefaults){
400
- return ResourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
401
- };
402
-
403
-
404
409
  Resource.prototype['$' + name] = function(a1, a2, a3) {
405
410
  var params = extractParams(this),
406
411
  success = noop,
@@ -426,6 +431,11 @@ angular.module('ngResource', ['ng']).
426
431
  Resource[name].call(this, params, data, success, error);
427
432
  };
428
433
  });
434
+
435
+ Resource.bind = function(additionalParamDefaults){
436
+ return ResourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
437
+ };
438
+
429
439
  return Resource;
430
440
  }
431
441
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.0.3
2
+ * @license AngularJS v1.0.4
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -9404,7 +9404,7 @@ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9404
9404
 
9405
9405
  })( window );
9406
9406
  /**
9407
- * @license AngularJS v1.0.3
9407
+ * @license AngularJS v1.0.4
9408
9408
  * (c) 2010-2012 Google, Inc. http://angularjs.org
9409
9409
  * License: MIT
9410
9410
  */
@@ -10032,13 +10032,15 @@ function equals(o1, o2) {
10032
10032
  if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
10033
10033
  keySet = {};
10034
10034
  for(key in o1) {
10035
- if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
10036
- return false;
10037
- }
10035
+ if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
10036
+ if (!equals(o1[key], o2[key])) return false;
10038
10037
  keySet[key] = true;
10039
10038
  }
10040
10039
  for(key in o2) {
10041
- if (!keySet[key] && key.charAt(0) !== '$' && !isFunction(o2[key])) return false;
10040
+ if (!keySet[key] &&
10041
+ key.charAt(0) !== '$' &&
10042
+ o2[key] !== undefined &&
10043
+ !isFunction(o2[key])) return false;
10042
10044
  }
10043
10045
  return true;
10044
10046
  }
@@ -10652,11 +10654,11 @@ function setupModuleLoader(window) {
10652
10654
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
10653
10655
  */
10654
10656
  var version = {
10655
- full: '1.0.3', // all of these placeholder strings will be replaced by rake's
10657
+ full: '1.0.4', // all of these placeholder strings will be replaced by rake's
10656
10658
  major: 1, // compile task
10657
10659
  minor: 0,
10658
- dot: 3,
10659
- codeName: 'bouncy-thunder'
10660
+ dot: 4,
10661
+ codeName: 'bewildering-hair'
10660
10662
  };
10661
10663
 
10662
10664
 
@@ -10828,7 +10830,7 @@ function publishExternalAPI(angular){
10828
10830
  * - [val()](http://api.jquery.com/val/)
10829
10831
  * - [wrap()](http://api.jquery.com/wrap/)
10830
10832
  *
10831
- * ## In addtion to the above, Angular privides an additional method to both jQuery and jQuery lite:
10833
+ * ## In addtion to the above, Angular provides additional methods to both jQuery and jQuery lite:
10832
10834
  *
10833
10835
  * - `controller(name)` - retrieves the controller of the current element or its parent. By default
10834
10836
  * retrieves controller associated with the `ngController` directive. If `name` is provided as
@@ -11416,14 +11418,14 @@ forEach({
11416
11418
  children: function(element) {
11417
11419
  var children = [];
11418
11420
  forEach(element.childNodes, function(element){
11419
- if (element.nodeName != '#text')
11421
+ if (element.nodeType === 1)
11420
11422
  children.push(element);
11421
11423
  });
11422
11424
  return children;
11423
11425
  },
11424
11426
 
11425
11427
  contents: function(element) {
11426
- return element.childNodes;
11428
+ return element.childNodes || [];
11427
11429
  },
11428
11430
 
11429
11431
  append: function(element, node) {
@@ -11486,7 +11488,16 @@ forEach({
11486
11488
  },
11487
11489
 
11488
11490
  next: function(element) {
11489
- return element.nextSibling;
11491
+ if (element.nextElementSibling) {
11492
+ return element.nextElementSibling;
11493
+ }
11494
+
11495
+ // IE8 doesn't have nextElementSibling
11496
+ var elm = element.nextSibling;
11497
+ while (elm != null && elm.nodeType !== 1) {
11498
+ elm = elm.nextSibling;
11499
+ }
11500
+ return elm;
11490
11501
  },
11491
11502
 
11492
11503
  find: function(element, selector) {
@@ -12072,7 +12083,7 @@ function createInjector(modulesToLoad) {
12072
12083
  }
12073
12084
 
12074
12085
  function provider(name, provider_) {
12075
- if (isFunction(provider_)) {
12086
+ if (isFunction(provider_) || isArray(provider_)) {
12076
12087
  provider_ = providerInjector.instantiate(provider_);
12077
12088
  }
12078
12089
  if (!provider_.$get) {
@@ -12189,7 +12200,7 @@ function createInjector(modulesToLoad) {
12189
12200
  args.push(
12190
12201
  locals && locals.hasOwnProperty(key)
12191
12202
  ? locals[key]
12192
- : getService(key, path)
12203
+ : getService(key)
12193
12204
  );
12194
12205
  }
12195
12206
  if (!fn.$inject) {
@@ -12289,7 +12300,7 @@ function $AnchorScrollProvider() {
12289
12300
  }
12290
12301
 
12291
12302
  // does not scroll when user clicks on anchor link that is currently on
12292
- // (no url change, no $locaiton.hash() change), browser native does scroll
12303
+ // (no url change, no $location.hash() change), browser native does scroll
12293
12304
  if (autoScrollingEnabled) {
12294
12305
  $rootScope.$watch(function autoScrollWatch() {return $location.hash();},
12295
12306
  function autoScrollWatchAction() {
@@ -12577,14 +12588,15 @@ function Browser(window, document, $log, $sniffer) {
12577
12588
  } else {
12578
12589
  if (isString(value)) {
12579
12590
  cookieLength = (rawDocument.cookie = escape(name) + '=' + escape(value) + ';path=' + cookiePath).length + 1;
12591
+
12592
+ // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
12593
+ // - 300 cookies
12594
+ // - 20 cookies per unique domain
12595
+ // - 4096 bytes per cookie
12580
12596
  if (cookieLength > 4096) {
12581
12597
  $log.warn("Cookie '"+ name +"' possibly not set or overflowed because it was too large ("+
12582
12598
  cookieLength + " > 4096 bytes)!");
12583
12599
  }
12584
- if (lastCookies.length > 20) {
12585
- $log.warn("Cookie '"+ name +"' possibly not set or overflowed because too many cookies " +
12586
- "were already set (" + lastCookies.length + " > 20 )");
12587
- }
12588
12600
  }
12589
12601
  }
12590
12602
  } else {
@@ -13150,7 +13162,7 @@ function $CompileProvider($provide) {
13150
13162
  // We can not compile top level text elements since text nodes can be merged and we will
13151
13163
  // not be able to attach scope data to them, so we will wrap them in <span>
13152
13164
  forEach($compileNodes, function(node, index){
13153
- if (node.nodeType == 3 /* text node */) {
13165
+ if (node.nodeType == 3 /* text node */ && node.nodeValue.match(/\S+/) /* non-empty */ ) {
13154
13166
  $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
13155
13167
  }
13156
13168
  });
@@ -13199,68 +13211,74 @@ function $CompileProvider($provide) {
13199
13211
  * @returns {?function} A composite linking function of all of the matched directives or null.
13200
13212
  */
13201
13213
  function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority) {
13202
- var linkFns = [],
13203
- nodeLinkFn, childLinkFn, directives, attrs, linkFnFound;
13214
+ var linkFns = [],
13215
+ nodeLinkFn, childLinkFn, directives, attrs, linkFnFound;
13204
13216
 
13205
- for(var i = 0; i < nodeList.length; i++) {
13206
- attrs = new Attributes();
13217
+ for(var i = 0; i < nodeList.length; i++) {
13218
+ attrs = new Attributes();
13207
13219
 
13208
- // we must always refer to nodeList[i] since the nodes can be replaced underneath us.
13209
- directives = collectDirectives(nodeList[i], [], attrs, maxPriority);
13220
+ // we must always refer to nodeList[i] since the nodes can be replaced underneath us.
13221
+ directives = collectDirectives(nodeList[i], [], attrs, maxPriority);
13210
13222
 
13211
- nodeLinkFn = (directives.length)
13212
- ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
13213
- : null;
13223
+ nodeLinkFn = (directives.length)
13224
+ ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
13225
+ : null;
13214
13226
 
13215
- childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes.length)
13216
- ? null
13217
- : compileNodes(nodeList[i].childNodes,
13218
- nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
13227
+ childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes.length)
13228
+ ? null
13229
+ : compileNodes(nodeList[i].childNodes,
13230
+ nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
13219
13231
 
13220
- linkFns.push(nodeLinkFn);
13221
- linkFns.push(childLinkFn);
13222
- linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn);
13223
- }
13232
+ linkFns.push(nodeLinkFn);
13233
+ linkFns.push(childLinkFn);
13234
+ linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn);
13235
+ }
13224
13236
 
13225
- // return a linking function if we have found anything, null otherwise
13226
- return linkFnFound ? compositeLinkFn : null;
13237
+ // return a linking function if we have found anything, null otherwise
13238
+ return linkFnFound ? compositeLinkFn : null;
13227
13239
 
13228
- function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) {
13229
- var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn;
13240
+ function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) {
13241
+ var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn, i, ii, n;
13230
13242
 
13231
- for(var i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
13232
- node = nodeList[n];
13233
- nodeLinkFn = linkFns[i++];
13234
- childLinkFn = linkFns[i++];
13243
+ // copy nodeList so that linking doesn't break due to live list updates.
13244
+ var stableNodeList = [];
13245
+ for (i = 0, ii = nodeList.length; i < ii; i++) {
13246
+ stableNodeList.push(nodeList[i]);
13247
+ }
13235
13248
 
13236
- if (nodeLinkFn) {
13237
- if (nodeLinkFn.scope) {
13238
- childScope = scope.$new(isObject(nodeLinkFn.scope));
13239
- jqLite(node).data('$scope', childScope);
13240
- } else {
13241
- childScope = scope;
13242
- }
13243
- childTranscludeFn = nodeLinkFn.transclude;
13244
- if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) {
13245
- nodeLinkFn(childLinkFn, childScope, node, $rootElement,
13246
- (function(transcludeFn) {
13247
- return function(cloneFn) {
13248
- var transcludeScope = scope.$new();
13249
-
13250
- return transcludeFn(transcludeScope, cloneFn).
13251
- bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
13249
+ for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
13250
+ node = stableNodeList[n];
13251
+ nodeLinkFn = linkFns[i++];
13252
+ childLinkFn = linkFns[i++];
13253
+
13254
+ if (nodeLinkFn) {
13255
+ if (nodeLinkFn.scope) {
13256
+ childScope = scope.$new(isObject(nodeLinkFn.scope));
13257
+ jqLite(node).data('$scope', childScope);
13258
+ } else {
13259
+ childScope = scope;
13260
+ }
13261
+ childTranscludeFn = nodeLinkFn.transclude;
13262
+ if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) {
13263
+ nodeLinkFn(childLinkFn, childScope, node, $rootElement,
13264
+ (function(transcludeFn) {
13265
+ return function(cloneFn) {
13266
+ var transcludeScope = scope.$new();
13267
+
13268
+ return transcludeFn(transcludeScope, cloneFn).
13269
+ bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
13252
13270
  };
13253
13271
  })(childTranscludeFn || transcludeFn)
13254
- );
13255
- } else {
13256
- nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn);
13257
- }
13258
- } else if (childLinkFn) {
13259
- childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn);
13260
- }
13261
- }
13262
- }
13263
- }
13272
+ );
13273
+ } else {
13274
+ nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn);
13275
+ }
13276
+ } else if (childLinkFn) {
13277
+ childLinkFn(scope, node.childNodes, undefined, boundTranscludeFn);
13278
+ }
13279
+ }
13280
+ }
13281
+ }
13264
13282
 
13265
13283
 
13266
13284
  /**
@@ -13407,7 +13425,7 @@ function $CompileProvider($provide) {
13407
13425
  if (directiveValue == 'element') {
13408
13426
  $template = jqLite(compileNode);
13409
13427
  $compileNode = templateAttrs.$$element =
13410
- jqLite('<!-- ' + directiveName + ': ' + templateAttrs[directiveName] + ' -->');
13428
+ jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
13411
13429
  compileNode = $compileNode[0];
13412
13430
  replaceWith($rootElement, jqLite($template[0]), compileNode);
13413
13431
  childTranscludeFn = compile($template, transcludeFn, terminalPriority);
@@ -14072,11 +14090,12 @@ function $DocumentProvider(){
14072
14090
  * the browser console.
14073
14091
  *
14074
14092
  * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by
14075
- * {@link ngMock.$exceptionHandler mock $exceptionHandler}
14093
+ * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.
14076
14094
  *
14077
14095
  * @param {Error} exception Exception associated with the error.
14078
14096
  * @param {string=} cause optional information about the context in which
14079
14097
  * the error was thrown.
14098
+ *
14080
14099
  */
14081
14100
  function $ExceptionHandlerProvider() {
14082
14101
  this.$get = ['$log', function($log){
@@ -15876,7 +15895,7 @@ function $ParseProvider() {
15876
15895
  * performed asynchronously, and may or may not be finished at any given point in time.
15877
15896
  *
15878
15897
  * From the perspective of dealing with error handling, deferred and promise apis are to
15879
- * asynchronous programing what `try`, `catch` and `throw` keywords are to synchronous programing.
15898
+ * asynchronous programming what `try`, `catch` and `throw` keywords are to synchronous programming.
15880
15899
  *
15881
15900
  * <pre>
15882
15901
  * // for the purpose of this example let's assume that variables `$q` and `scope` are
@@ -15986,6 +16005,30 @@ function $ParseProvider() {
15986
16005
  * you can treat promises attached to a scope as if they were the resulting values.
15987
16006
  * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains
15988
16007
  * all the important functionality needed for common async tasks.
16008
+ *
16009
+ * # Testing
16010
+ *
16011
+ * <pre>
16012
+ * it('should simulate promise', inject(function($q, $rootSCope) {
16013
+ * var deferred = $q.defer();
16014
+ * var promise = deferred.promise;
16015
+ * var resolvedValue;
16016
+ *
16017
+ * promise.then(function(value) { resolvedValue = value; });
16018
+ * expect(resolvedValue).toBeUndefined();
16019
+ *
16020
+ * // Simulate resolving of promise
16021
+ * defered.resolve(123);
16022
+ * // Note that the 'then' function does not get called synchronously.
16023
+ * // This is because we want the promise API to always be async, whether or not
16024
+ * // it got called synchronously or asynchronously.
16025
+ * expect(resolvedValue).toBeUndefined();
16026
+ *
16027
+ * // Propagate promise resolution to 'then' functions using $apply().
16028
+ * $rootScope.$apply();
16029
+ * expect(resolvedValue).toEqual(123);
16030
+ * });
16031
+ * </pre>
15989
16032
  */
15990
16033
  function $QProvider() {
15991
16034
 
@@ -16272,8 +16315,13 @@ function $RouteProvider(){
16272
16315
  *
16273
16316
  * @param {string} path Route path (matched against `$location.path`). If `$location.path`
16274
16317
  * contains redundant trailing slash or is missing one, the route will still match and the
16275
- * `$location.path` will be updated to add or drop the trailing slash to exacly match the
16318
+ * `$location.path` will be updated to add or drop the trailing slash to exactly match the
16276
16319
  * route definition.
16320
+ *
16321
+ * `path` can contain named groups starting with a colon (`:name`). All characters up to the
16322
+ * next slash are matched and stored in `$routeParams` under the given `name` when the route
16323
+ * matches.
16324
+ *
16277
16325
  * @param {Object} route Mapping information to be assigned to `$route.current` on route
16278
16326
  * match.
16279
16327
  *
@@ -16538,8 +16586,7 @@ function $RouteProvider(){
16538
16586
  * instance of the Controller.
16539
16587
  */
16540
16588
 
16541
- var matcher = switchRouteMatcher,
16542
- forceReload = false,
16589
+ var forceReload = false,
16543
16590
  $route = {
16544
16591
  routes: routes,
16545
16592
 
@@ -16567,21 +16614,36 @@ function $RouteProvider(){
16567
16614
 
16568
16615
  /////////////////////////////////////////////////////
16569
16616
 
16617
+ /**
16618
+ * @param on {string} current url
16619
+ * @param when {string} route when template to match the url against
16620
+ * @return {?Object}
16621
+ */
16570
16622
  function switchRouteMatcher(on, when) {
16571
16623
  // TODO(i): this code is convoluted and inefficient, we should construct the route matching
16572
16624
  // regex only once and then reuse it
16573
- var regex = '^' + when.replace(/([\.\\\(\)\^\$])/g, "\\$1") + '$',
16625
+
16626
+ // Escape regexp special characters.
16627
+ when = '^' + when.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") + '$';
16628
+ var regex = '',
16574
16629
  params = [],
16575
16630
  dst = {};
16576
- forEach(when.split(/\W/), function(param) {
16577
- if (param) {
16578
- var paramRegExp = new RegExp(":" + param + "([\\W])");
16579
- if (regex.match(paramRegExp)) {
16580
- regex = regex.replace(paramRegExp, "([^\\/]*)$1");
16581
- params.push(param);
16582
- }
16583
- }
16584
- });
16631
+
16632
+ var re = /:(\w+)/g,
16633
+ paramMatch,
16634
+ lastMatchedIndex = 0;
16635
+
16636
+ while ((paramMatch = re.exec(when)) !== null) {
16637
+ // Find each :param in `when` and replace it with a capturing group.
16638
+ // Append all other sections of when unchanged.
16639
+ regex += when.slice(lastMatchedIndex, paramMatch.index);
16640
+ regex += '([^\\/]*)';
16641
+ params.push(paramMatch[1]);
16642
+ lastMatchedIndex = re.lastIndex;
16643
+ }
16644
+ // Append trailing path part.
16645
+ regex += when.substr(lastMatchedIndex);
16646
+
16585
16647
  var match = on.match(new RegExp(regex));
16586
16648
  if (match) {
16587
16649
  forEach(params, function(name, index) {
@@ -16670,7 +16732,7 @@ function $RouteProvider(){
16670
16732
  // Match a route
16671
16733
  var params, match;
16672
16734
  forEach(routes, function(route, path) {
16673
- if (!match && (params = matcher($location.path(), path))) {
16735
+ if (!match && (params = switchRouteMatcher($location.path(), path))) {
16674
16736
  match = inherit(route, {
16675
16737
  params: extend({}, $location.search(), params),
16676
16738
  pathParams: params});
@@ -16822,7 +16884,7 @@ function $RootScopeProvider(){
16822
16884
  expect(scope.greeting).toEqual(undefined);
16823
16885
 
16824
16886
  scope.$watch('name', function() {
16825
- this.greeting = this.salutation + ' ' + this.name + '!';
16887
+ scope.greeting = scope.salutation + ' ' + scope.name + '!';
16826
16888
  }); // initialize the watch
16827
16889
 
16828
16890
  expect(scope.greeting).toEqual(undefined);
@@ -16865,6 +16927,7 @@ function $RootScopeProvider(){
16865
16927
  this.$$nextSibling = this.$$prevSibling =
16866
16928
  this.$$childHead = this.$$childTail = null;
16867
16929
  this['this'] = this.$root = this;
16930
+ this.$$destroyed = false;
16868
16931
  this.$$asyncQueue = [];
16869
16932
  this.$$listeners = {};
16870
16933
  }
@@ -16983,7 +17046,7 @@ function $RootScopeProvider(){
16983
17046
  scope.counter = 0;
16984
17047
 
16985
17048
  expect(scope.counter).toEqual(0);
16986
- scope.$watch('name', function(newValue, oldValue) { counter = counter + 1; });
17049
+ scope.$watch('name', function(newValue, oldValue) { scope.counter = scope.counter + 1; });
16987
17050
  expect(scope.counter).toEqual(0);
16988
17051
 
16989
17052
  scope.$digest();
@@ -17076,7 +17139,7 @@ function $RootScopeProvider(){
17076
17139
 
17077
17140
  expect(scope.counter).toEqual(0);
17078
17141
  scope.$watch('name', function(newValue, oldValue) {
17079
- counter = counter + 1;
17142
+ scope.counter = scope.counter + 1;
17080
17143
  });
17081
17144
  expect(scope.counter).toEqual(0);
17082
17145
 
@@ -17198,10 +17261,12 @@ function $RootScopeProvider(){
17198
17261
  * perform any necessary cleanup.
17199
17262
  */
17200
17263
  $destroy: function() {
17201
- if ($rootScope == this) return; // we can't remove the root node;
17264
+ // we can't destroy the root scope or a scope that has been already destroyed
17265
+ if ($rootScope == this || this.$$destroyed) return;
17202
17266
  var parent = this.$parent;
17203
17267
 
17204
17268
  this.$broadcast('$destroy');
17269
+ this.$$destroyed = true;
17205
17270
 
17206
17271
  if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
17207
17272
  if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
@@ -17751,7 +17816,7 @@ function $HttpProvider() {
17751
17816
  /**
17752
17817
  * @ngdoc function
17753
17818
  * @name ng.$http
17754
- * @requires $httpBacked
17819
+ * @requires $httpBackend
17755
17820
  * @requires $browser
17756
17821
  * @requires $cacheFactory
17757
17822
  * @requires $rootScope
@@ -17787,8 +17852,7 @@ function $HttpProvider() {
17787
17852
  * }).
17788
17853
  * error(function(data, status, headers, config) {
17789
17854
  * // called asynchronously if an error occurs
17790
- * // or server returns response with status
17791
- * // code outside of the <200, 400) range
17855
+ * // or server returns response with an error status.
17792
17856
  * });
17793
17857
  * </pre>
17794
17858
  *
@@ -17797,6 +17861,10 @@ function $HttpProvider() {
17797
17861
  * an object representing the response. See the api signature and type info below for more
17798
17862
  * details.
17799
17863
  *
17864
+ * A response status code that falls in the [200, 300) range is considered a success status and
17865
+ * will result in the success callback being called. Note that if the response is a redirect,
17866
+ * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
17867
+ * called for such responses.
17800
17868
  *
17801
17869
  * # Shortcut methods
17802
17870
  *
@@ -19634,7 +19702,6 @@ var htmlAnchorDirective = valueFn({
19634
19702
  // if we have no href url, then don't navigate anywhere.
19635
19703
  if (!element.attr('href')) {
19636
19704
  event.preventDefault();
19637
- return false; // Needed for opera
19638
19705
  }
19639
19706
  });
19640
19707
  }
@@ -19971,13 +20038,13 @@ var nullFormCtrl = {
19971
20038
  *
19972
20039
  * @property {boolean} $pristine True if user has not interacted with the form yet.
19973
20040
  * @property {boolean} $dirty True if user has already interacted with the form.
19974
- * @property {boolean} $valid True if all of the containg forms and controls are valid.
20041
+ * @property {boolean} $valid True if all of the containing forms and controls are valid.
19975
20042
  * @property {boolean} $invalid True if at least one containing control or form is invalid.
19976
20043
  *
19977
20044
  * @property {Object} $error Is an object hash, containing references to all invalid controls or
19978
20045
  * forms, where:
19979
20046
  *
19980
- * - keys are validation tokens (error names) — such as `REQUIRED`, `URL` or `EMAIL`),
20047
+ * - keys are validation tokens (error names) — such as `required`, `url` or `email`),
19981
20048
  * - values are arrays of controls or forms that are invalid with given error.
19982
20049
  *
19983
20050
  * @description
@@ -20090,7 +20157,7 @@ function FormController(element, attrs) {
20090
20157
  * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
20091
20158
  * sub-group of controls needs to be determined.
20092
20159
  *
20093
- * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into
20160
+ * @param {string=} name|ngForm Name of the form. If specified, the form controller will be published into
20094
20161
  * related scope, under this name.
20095
20162
  *
20096
20163
  */
@@ -20163,12 +20230,12 @@ function FormController(element, attrs) {
20163
20230
  </script>
20164
20231
  <form name="myForm" ng-controller="Ctrl">
20165
20232
  userType: <input name="input" ng-model="userType" required>
20166
- <span class="error" ng-show="myForm.input.$error.REQUIRED">Required!</span><br>
20233
+ <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
20167
20234
  <tt>userType = {{userType}}</tt><br>
20168
20235
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br>
20169
20236
  <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br>
20170
20237
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
20171
- <tt>myForm.$error.REQUIRED = {{!!myForm.$error.REQUIRED}}</tt><br>
20238
+ <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
20172
20239
  </form>
20173
20240
  </doc:source>
20174
20241
  <doc:scenario>
@@ -22758,14 +22825,17 @@ var ngRepeatDirective = ngDirective({
22758
22825
  scope.$watch(function ngRepeatWatch(scope){
22759
22826
  var index, length,
22760
22827
  collection = scope.$eval(rhs),
22761
- collectionLength = size(collection, true),
22762
- childScope,
22828
+ cursor = iterStartElement, // current position of the node
22763
22829
  // Same as lastOrder but it has the current state. It will become the
22764
22830
  // lastOrder on the next iteration.
22765
22831
  nextOrder = new HashQueueMap(),
22832
+ arrayLength,
22833
+ childScope,
22766
22834
  key, value, // key/value of iteration
22767
- array, last, // last object information {scope, element, index}
22768
- cursor = iterStartElement; // current position of the node
22835
+ array,
22836
+ last; // last object information {scope, element, index}
22837
+
22838
+
22769
22839
 
22770
22840
  if (!isArray(collection)) {
22771
22841
  // if object, extract keys, sort them and use to determine order of iteration over obj props
@@ -22780,6 +22850,8 @@ var ngRepeatDirective = ngDirective({
22780
22850
  array = collection || [];
22781
22851
  }
22782
22852
 
22853
+ arrayLength = array.length;
22854
+
22783
22855
  // we are not using forEach for perf reasons (trying to avoid #call)
22784
22856
  for (index = 0, length = array.length; index < length; index++) {
22785
22857
  key = (collection === array) ? index : array[index];
@@ -22815,7 +22887,7 @@ var ngRepeatDirective = ngDirective({
22815
22887
  childScope.$index = index;
22816
22888
 
22817
22889
  childScope.$first = (index === 0);
22818
- childScope.$last = (index === (collectionLength - 1));
22890
+ childScope.$last = (index === (arrayLength - 1));
22819
22891
  childScope.$middle = !(childScope.$first || childScope.$last);
22820
22892
 
22821
22893
  if (!last) {
@@ -23036,52 +23108,53 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
23036
23108
  var NG_SWITCH = 'ng-switch';
23037
23109
  var ngSwitchDirective = valueFn({
23038
23110
  restrict: 'EA',
23039
- compile: function(element, attr) {
23111
+ require: 'ngSwitch',
23112
+ controller: function ngSwitchController() {
23113
+ this.cases = {};
23114
+ },
23115
+ link: function(scope, element, attr, ctrl) {
23040
23116
  var watchExpr = attr.ngSwitch || attr.on,
23041
- cases = {};
23042
-
23043
- element.data(NG_SWITCH, cases);
23044
- return function(scope, element){
23045
- var selectedTransclude,
23046
- selectedElement,
23047
- selectedScope;
23048
-
23049
- scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
23050
- if (selectedElement) {
23051
- selectedScope.$destroy();
23052
- selectedElement.remove();
23053
- selectedElement = selectedScope = null;
23054
- }
23055
- if ((selectedTransclude = cases['!' + value] || cases['?'])) {
23056
- scope.$eval(attr.change);
23057
- selectedScope = scope.$new();
23058
- selectedTransclude(selectedScope, function(caseElement) {
23059
- selectedElement = caseElement;
23060
- element.append(caseElement);
23061
- });
23062
- }
23063
- });
23064
- };
23117
+ selectedTransclude,
23118
+ selectedElement,
23119
+ selectedScope;
23120
+
23121
+ scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
23122
+ if (selectedElement) {
23123
+ selectedScope.$destroy();
23124
+ selectedElement.remove();
23125
+ selectedElement = selectedScope = null;
23126
+ }
23127
+ if ((selectedTransclude = ctrl.cases['!' + value] || ctrl.cases['?'])) {
23128
+ scope.$eval(attr.change);
23129
+ selectedScope = scope.$new();
23130
+ selectedTransclude(selectedScope, function(caseElement) {
23131
+ selectedElement = caseElement;
23132
+ element.append(caseElement);
23133
+ });
23134
+ }
23135
+ });
23065
23136
  }
23066
23137
  });
23067
23138
 
23068
23139
  var ngSwitchWhenDirective = ngDirective({
23069
23140
  transclude: 'element',
23070
23141
  priority: 500,
23142
+ require: '^ngSwitch',
23071
23143
  compile: function(element, attrs, transclude) {
23072
- var cases = element.inheritedData(NG_SWITCH);
23073
- assertArg(cases);
23074
- cases['!' + attrs.ngSwitchWhen] = transclude;
23144
+ return function(scope, element, attr, ctrl) {
23145
+ ctrl.cases['!' + attrs.ngSwitchWhen] = transclude;
23146
+ };
23075
23147
  }
23076
23148
  });
23077
23149
 
23078
23150
  var ngSwitchDefaultDirective = ngDirective({
23079
23151
  transclude: 'element',
23080
23152
  priority: 500,
23153
+ require: '^ngSwitch',
23081
23154
  compile: function(element, attrs, transclude) {
23082
- var cases = element.inheritedData(NG_SWITCH);
23083
- assertArg(cases);
23084
- cases['?'] = transclude;
23155
+ return function(scope, element, attr, ctrl) {
23156
+ ctrl.cases['?'] = transclude;
23157
+ };
23085
23158
  }
23086
23159
  });
23087
23160
 
@@ -23170,7 +23243,7 @@ var ngTranscludeDirective = ngDirective({
23170
23243
  <hr />
23171
23244
 
23172
23245
  <pre>$location.path() = {{$location.path()}}</pre>
23173
- <pre>$route.current.template = {{$route.current.template}}</pre>
23246
+ <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
23174
23247
  <pre>$route.current.params = {{$route.current.params}}</pre>
23175
23248
  <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
23176
23249
  <pre>$routeParams = {{$routeParams}}</pre>
@@ -23616,7 +23689,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23616
23689
  var lastView;
23617
23690
  ctrl.$render = function() {
23618
23691
  var items = new HashMap(ctrl.$viewValue);
23619
- forEach(selectElement.children(), function(option) {
23692
+ forEach(selectElement.find('option'), function(option) {
23620
23693
  option.selected = isDefined(items.get(option.value));
23621
23694
  });
23622
23695
  };
@@ -23633,7 +23706,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23633
23706
  selectElement.bind('change', function() {
23634
23707
  scope.$apply(function() {
23635
23708
  var array = [];
23636
- forEach(selectElement.children(), function(option) {
23709
+ forEach(selectElement.find('option'), function(option) {
23637
23710
  if (option.selected) {
23638
23711
  array.push(option.value);
23639
23712
  }
@@ -24911,160 +24984,6 @@ angular.scenario.ObjectModel.Step.prototype.setErrorStatus = function(status, er
24911
24984
  this.line = line;
24912
24985
  };
24913
24986
 
24914
- /**
24915
- * The representation of define blocks. Don't used directly, instead use
24916
- * define() in your tests.
24917
- *
24918
- * @param {string} descName Name of the block
24919
- * @param {Object} parent describe or undefined if the root.
24920
- */
24921
- angular.scenario.Describe = function(descName, parent) {
24922
- this.only = parent && parent.only;
24923
- this.beforeEachFns = [];
24924
- this.afterEachFns = [];
24925
- this.its = [];
24926
- this.children = [];
24927
- this.name = descName;
24928
- this.parent = parent;
24929
- this.id = angular.scenario.Describe.id++;
24930
-
24931
- /**
24932
- * Calls all before functions.
24933
- */
24934
- var beforeEachFns = this.beforeEachFns;
24935
- this.setupBefore = function() {
24936
- if (parent) parent.setupBefore.call(this);
24937
- angular.forEach(beforeEachFns, function(fn) { fn.call(this); }, this);
24938
- };
24939
-
24940
- /**
24941
- * Calls all after functions.
24942
- */
24943
- var afterEachFns = this.afterEachFns;
24944
- this.setupAfter = function() {
24945
- angular.forEach(afterEachFns, function(fn) { fn.call(this); }, this);
24946
- if (parent) parent.setupAfter.call(this);
24947
- };
24948
- };
24949
-
24950
- // Shared Unique ID generator for every describe block
24951
- angular.scenario.Describe.id = 0;
24952
-
24953
- // Shared Unique ID generator for every it (spec)
24954
- angular.scenario.Describe.specId = 0;
24955
-
24956
- /**
24957
- * Defines a block to execute before each it or nested describe.
24958
- *
24959
- * @param {function()} body Body of the block.
24960
- */
24961
- angular.scenario.Describe.prototype.beforeEach = function(body) {
24962
- this.beforeEachFns.push(body);
24963
- };
24964
-
24965
- /**
24966
- * Defines a block to execute after each it or nested describe.
24967
- *
24968
- * @param {function()} body Body of the block.
24969
- */
24970
- angular.scenario.Describe.prototype.afterEach = function(body) {
24971
- this.afterEachFns.push(body);
24972
- };
24973
-
24974
- /**
24975
- * Creates a new describe block that's a child of this one.
24976
- *
24977
- * @param {string} name Name of the block. Appended to the parent block's name.
24978
- * @param {function()} body Body of the block.
24979
- */
24980
- angular.scenario.Describe.prototype.describe = function(name, body) {
24981
- var child = new angular.scenario.Describe(name, this);
24982
- this.children.push(child);
24983
- body.call(child);
24984
- };
24985
-
24986
- /**
24987
- * Same as describe() but makes ddescribe blocks the only to run.
24988
- *
24989
- * @param {string} name Name of the test.
24990
- * @param {function()} body Body of the block.
24991
- */
24992
- angular.scenario.Describe.prototype.ddescribe = function(name, body) {
24993
- var child = new angular.scenario.Describe(name, this);
24994
- child.only = true;
24995
- this.children.push(child);
24996
- body.call(child);
24997
- };
24998
-
24999
- /**
25000
- * Use to disable a describe block.
25001
- */
25002
- angular.scenario.Describe.prototype.xdescribe = angular.noop;
25003
-
25004
- /**
25005
- * Defines a test.
25006
- *
25007
- * @param {string} name Name of the test.
25008
- * @param {function()} vody Body of the block.
25009
- */
25010
- angular.scenario.Describe.prototype.it = function(name, body) {
25011
- this.its.push({
25012
- id: angular.scenario.Describe.specId++,
25013
- definition: this,
25014
- only: this.only,
25015
- name: name,
25016
- before: this.setupBefore,
25017
- body: body,
25018
- after: this.setupAfter
25019
- });
25020
- };
25021
-
25022
- /**
25023
- * Same as it() but makes iit tests the only test to run.
25024
- *
25025
- * @param {string} name Name of the test.
25026
- * @param {function()} body Body of the block.
25027
- */
25028
- angular.scenario.Describe.prototype.iit = function(name, body) {
25029
- this.it.apply(this, arguments);
25030
- this.its[this.its.length-1].only = true;
25031
- };
25032
-
25033
- /**
25034
- * Use to disable a test block.
25035
- */
25036
- angular.scenario.Describe.prototype.xit = angular.noop;
25037
-
25038
- /**
25039
- * Gets an array of functions representing all the tests (recursively).
25040
- * that can be executed with SpecRunner's.
25041
- *
25042
- * @return {Array<Object>} Array of it blocks {
25043
- * definition : Object // parent Describe
25044
- * only: boolean
25045
- * name: string
25046
- * before: Function
25047
- * body: Function
25048
- * after: Function
25049
- * }
25050
- */
25051
- angular.scenario.Describe.prototype.getSpecs = function() {
25052
- var specs = arguments[0] || [];
25053
- angular.forEach(this.children, function(child) {
25054
- child.getSpecs(specs);
25055
- });
25056
- angular.forEach(this.its, function(it) {
25057
- specs.push(it);
25058
- });
25059
- var only = [];
25060
- angular.forEach(specs, function(it) {
25061
- if (it.only) {
25062
- only.push(it);
25063
- }
25064
- });
25065
- return (only.length && only) || specs;
25066
- };
25067
-
25068
24987
  /**
25069
24988
  * Runner for scenarios
25070
24989
  *
@@ -25635,13 +25554,13 @@ angular.scenario.dsl('binding', function() {
25635
25554
  */
25636
25555
  angular.scenario.dsl('input', function() {
25637
25556
  var chain = {};
25638
- var supportInputEvent = 'oninput' in document.createElement('div');
25557
+ var supportInputEvent = 'oninput' in document.createElement('div') && msie != 9;
25639
25558
 
25640
25559
  chain.enter = function(value, event) {
25641
25560
  return this.addFutureAction("input '" + this.name + "' enter '" + value + "'", function($window, $document, done) {
25642
25561
  var input = $document.elements('[ng\\:model="$1"]', this.name).filter(':input');
25643
25562
  input.val(value);
25644
- input.trigger(event || supportInputEvent && 'input' || 'change');
25563
+ input.trigger(event || (supportInputEvent ? 'input' : 'change'));
25645
25564
  done();
25646
25565
  });
25647
25566
  };