angular-gem 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.6
2
+ * @license AngularJS v1.2.7
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -616,9 +616,14 @@ angular.module('ngAnimate', ['ng'])
616
616
  }
617
617
 
618
618
  var animations = [];
619
+
619
620
  //only add animations if the currently running animation is not structural
620
621
  //or if there is no animation running at all
621
- if(!ngAnimateState.running || !(isClassBased && ngAnimateState.structural)) {
622
+ var allowAnimations = isClassBased ?
623
+ !ngAnimateState.disabled && (!ngAnimateState.running || !ngAnimateState.structural) :
624
+ true;
625
+
626
+ if(allowAnimations) {
622
627
  forEach(matches, function(animation) {
623
628
  //add the animation to the queue to if it is allowed to be cancelled
624
629
  if(!animation.allowCancel || animation.allowCancel(element, animationEvent, className)) {
@@ -1147,7 +1152,7 @@ angular.module('ngAnimate', ['ng'])
1147
1152
  var propertyStyle = timings.transitionPropertyStyle;
1148
1153
  if(propertyStyle.indexOf('all') == -1) {
1149
1154
  style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';';
1150
- style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + 's;';
1155
+ style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ';';
1151
1156
  appliedStyles.push(CSS_PREFIX + 'transition-property');
1152
1157
  appliedStyles.push(CSS_PREFIX + 'transition-duration');
1153
1158
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.6
2
+ * @license AngularJS v1.2.7
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.2.6
2
+ * @license AngularJS v1.2.7
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -69,7 +69,7 @@ function minErr(module) {
69
69
  return match;
70
70
  });
71
71
 
72
- message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
72
+ message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
73
73
  (module ? module + '/' : '') + code;
74
74
  for (i = 2; i < arguments.length; i++) {
75
75
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.6
2
+ * @license AngularJS v1.2.7
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1579,6 +1579,10 @@ function MockHttpExpectation(method, url, data, headers) {
1579
1579
  };
1580
1580
  }
1581
1581
 
1582
+ function createMockXhr() {
1583
+ return new MockXhr();
1584
+ }
1585
+
1582
1586
  function MockXhr() {
1583
1587
 
1584
1588
  // hack for testing $http, $httpBackend
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.6
2
+ * @license AngularJS v1.2.7
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -406,7 +406,7 @@ angular.module('ngResource', ['ng']).
406
406
  });
407
407
 
408
408
  // strip trailing slashes and set the url
409
- url = url.replace(/\/+$/, '');
409
+ url = url.replace(/\/+$/, '') || '/';
410
410
  // then replace collapse `/.` if found in the last URL path segment before the query
411
411
  // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
412
412
  url = url.replace(/\/\.(?=\w+($|\?))/, '.');
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.6
2
+ * @license AngularJS v1.2.7
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -842,7 +842,7 @@ function ngViewFactory( $route, $anchorScroll, $animate) {
842
842
  var locals = $route.current && $route.current.locals,
843
843
  template = locals && locals.$template;
844
844
 
845
- if (template) {
845
+ if (angular.isDefined(template)) {
846
846
  var newScope = scope.$new();
847
847
  var current = $route.current;
848
848
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.6
2
+ * @license AngularJS v1.2.7
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -211,7 +211,7 @@ var validAttrs = angular.extend({}, uriAttrs, makeMap(
211
211
  'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
212
212
  'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
213
213
  'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
214
- 'scope,scrolling,shape,span,start,summary,target,title,type,'+
214
+ 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
215
215
  'valign,value,vspace,width'));
216
216
 
217
217
  function makeMap(str) {
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
9790
9790
  })( window );
9791
9791
 
9792
9792
  /**
9793
- * @license AngularJS v1.2.6
9793
+ * @license AngularJS v1.2.7
9794
9794
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9795
9795
  * License: MIT
9796
9796
  */
@@ -9860,7 +9860,7 @@ function minErr(module) {
9860
9860
  return match;
9861
9861
  });
9862
9862
 
9863
- message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
9863
+ message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
9864
9864
  (module ? module + '/' : '') + code;
9865
9865
  for (i = 2; i < arguments.length; i++) {
9866
9866
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -10830,7 +10830,9 @@ function fromJson(json) {
10830
10830
 
10831
10831
 
10832
10832
  function toBoolean(value) {
10833
- if (value && value.length !== 0) {
10833
+ if (typeof value === 'function') {
10834
+ value = true;
10835
+ } else if (value && value.length !== 0) {
10834
10836
  var v = lowercase("" + value);
10835
10837
  value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
10836
10838
  } else {
@@ -11623,11 +11625,11 @@ function setupModuleLoader(window) {
11623
11625
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11624
11626
  */
11625
11627
  var version = {
11626
- full: '1.2.6', // all of these placeholder strings will be replaced by grunt's
11628
+ full: '1.2.7', // all of these placeholder strings will be replaced by grunt's
11627
11629
  major: 1, // package task
11628
11630
  minor: 2,
11629
- dot: 6,
11630
- codeName: 'taco-salsafication'
11631
+ dot: 7,
11632
+ codeName: 'emoji-clairvoyance'
11631
11633
  };
11632
11634
 
11633
11635
 
@@ -13455,6 +13457,11 @@ function createInjector(modulesToLoad) {
13455
13457
  path.unshift(serviceName);
13456
13458
  cache[serviceName] = INSTANTIATING;
13457
13459
  return cache[serviceName] = factory(serviceName);
13460
+ } catch (err) {
13461
+ if (cache[serviceName] === INSTANTIATING) {
13462
+ delete cache[serviceName];
13463
+ }
13464
+ throw err;
13458
13465
  } finally {
13459
13466
  path.shift();
13460
13467
  }
@@ -13989,8 +13996,9 @@ function Browser(window, document, $log, $sniffer) {
13989
13996
  * @param {boolean=} replace Should new url replace current history record ?
13990
13997
  */
13991
13998
  self.url = function(url, replace) {
13992
- // Android Browser BFCache causes location reference to become stale.
13999
+ // Android Browser BFCache causes location, history reference to become stale.
13993
14000
  if (location !== window.location) location = window.location;
14001
+ if (history !== window.history) history = window.history;
13994
14002
 
13995
14003
  // setter
13996
14004
  if (url) {
@@ -14042,7 +14050,7 @@ function Browser(window, document, $log, $sniffer) {
14042
14050
  * @description
14043
14051
  * Register callback function that will be called, when url changes.
14044
14052
  *
14045
- * It's only called when the url is changed by outside of angular:
14053
+ * It's only called when the url is changed from outside of angular:
14046
14054
  * - user types different url into address bar
14047
14055
  * - user clicks on history (forward/back) button
14048
14056
  * - user clicks on a link
@@ -14084,7 +14092,7 @@ function Browser(window, document, $log, $sniffer) {
14084
14092
  /**
14085
14093
  * @name ng.$browser#baseHref
14086
14094
  * @methodOf ng.$browser
14087
- *
14095
+ *
14088
14096
  * @description
14089
14097
  * Returns current <base href>
14090
14098
  * (always relative - without domain)
@@ -14093,7 +14101,7 @@ function Browser(window, document, $log, $sniffer) {
14093
14101
  */
14094
14102
  self.baseHref = function() {
14095
14103
  var href = baseElement.attr('href');
14096
- return href ? href.replace(/^https?\:\/\/[^\/]*/, '') : '';
14104
+ return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
14097
14105
  };
14098
14106
 
14099
14107
  //////////////////////////////////////////////////////////////
@@ -14115,13 +14123,13 @@ function Browser(window, document, $log, $sniffer) {
14115
14123
  * It is not meant to be used directly, use the $cookie service instead.
14116
14124
  *
14117
14125
  * The return values vary depending on the arguments that the method was called with as follows:
14118
- *
14126
+ *
14119
14127
  * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
14120
14128
  * it
14121
14129
  * - cookies(name, value) -> set name to value, if value is undefined delete the cookie
14122
14130
  * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
14123
14131
  * way)
14124
- *
14132
+ *
14125
14133
  * @returns {Object} Hash of all cookies (if called without any parameter)
14126
14134
  */
14127
14135
  self.cookies = function(name, value) {
@@ -14499,7 +14507,7 @@ function $TemplateCacheProvider() {
14499
14507
  * @function
14500
14508
  *
14501
14509
  * @description
14502
- * Compiles a piece of HTML string or DOM into a template and produces a template function, which
14510
+ * Compiles an HTML string or DOM into a template and produces a template function, which
14503
14511
  * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.
14504
14512
  *
14505
14513
  * The compilation is a process of walking the DOM tree and matching DOM elements to
@@ -16841,7 +16849,7 @@ function $HttpProvider() {
16841
16849
  * will result in the success callback being called. Note that if the response is a redirect,
16842
16850
  * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
16843
16851
  * called for such responses.
16844
- *
16852
+ *
16845
16853
  * # Calling $http from outside AngularJS
16846
16854
  * The `$http` service will not actually send the request until the next `$digest()` is
16847
16855
  * executed. Normally this is not an issue, since almost all the time your call to `$http` will
@@ -17028,19 +17036,20 @@ function $HttpProvider() {
17028
17036
  * return responseOrNewPromise
17029
17037
  * }
17030
17038
  * return $q.reject(rejection);
17031
- * };
17032
- * }
17039
+ * }
17040
+ * };
17033
17041
  * });
17034
17042
  *
17035
17043
  * $httpProvider.interceptors.push('myHttpInterceptor');
17036
17044
  *
17037
17045
  *
17038
- * // register the interceptor via an anonymous factory
17046
+ * // alternatively, register the interceptor via an anonymous factory
17039
17047
  * $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
17040
17048
  * return {
17041
17049
  * 'request': function(config) {
17042
17050
  * // same as above
17043
17051
  * },
17052
+ *
17044
17053
  * 'response': function(response) {
17045
17054
  * // same as above
17046
17055
  * }
@@ -17656,13 +17665,13 @@ function $HttpProvider() {
17656
17665
  }];
17657
17666
  }
17658
17667
 
17659
- var XHR = window.XMLHttpRequest || function() {
17668
+ function createXhr(method) {
17669
+ // IE8 doesn't support PATCH method, but the ActiveX object does
17660
17670
  /* global ActiveXObject */
17661
- try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
17662
- try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
17663
- try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
17664
- throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
17665
- };
17671
+ return (msie <= 8 && lowercase(method) === 'patch')
17672
+ ? new ActiveXObject('Microsoft.XMLHTTP')
17673
+ : new window.XMLHttpRequest();
17674
+ }
17666
17675
 
17667
17676
 
17668
17677
  /**
@@ -17684,11 +17693,11 @@ var XHR = window.XMLHttpRequest || function() {
17684
17693
  */
17685
17694
  function $HttpBackendProvider() {
17686
17695
  this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
17687
- return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]);
17696
+ return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]);
17688
17697
  }];
17689
17698
  }
17690
17699
 
17691
- function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) {
17700
+ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
17692
17701
  var ABORTED = -1;
17693
17702
 
17694
17703
  // TODO(vojta): fix the signature
@@ -17713,7 +17722,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
17713
17722
  delete callbacks[callbackId];
17714
17723
  });
17715
17724
  } else {
17716
- var xhr = new XHR();
17725
+
17726
+ var xhr = createXhr(method);
17727
+
17717
17728
  xhr.open(method, url, true);
17718
17729
  forEach(headers, function(value, key) {
17719
17730
  if (isDefined(value)) {
@@ -17725,7 +17736,14 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument)
17725
17736
  // response is in the cache. the promise api will ensure that to the app code the api is
17726
17737
  // always async
17727
17738
  xhr.onreadystatechange = function() {
17728
- if (xhr.readyState == 4) {
17739
+ // onreadystatechange might by called multiple times with readyState === 4 on mobile webkit caused by
17740
+ // xhrs that are resolved while the app is in the background (see #5426).
17741
+ // since calling completeRequest sets the `xhr` variable to null, we just check if it's not null before
17742
+ // continuing
17743
+ //
17744
+ // we can't set xhr.onreadystatechange to undefined or delete it because that breaks IE8 (method=PATCH) and
17745
+ // Safari respectively.
17746
+ if (xhr && xhr.readyState == 4) {
17729
17747
  var responseHeaders = null,
17730
17748
  response = null;
17731
17749
 
@@ -18972,16 +18990,17 @@ function $LocationProvider(){
18972
18990
  // update $location when $browser url changes
18973
18991
  $browser.onUrlChange(function(newUrl) {
18974
18992
  if ($location.absUrl() != newUrl) {
18975
- if ($rootScope.$broadcast('$locationChangeStart', newUrl,
18976
- $location.absUrl()).defaultPrevented) {
18977
- $browser.url($location.absUrl());
18978
- return;
18979
- }
18980
18993
  $rootScope.$evalAsync(function() {
18981
18994
  var oldUrl = $location.absUrl();
18982
18995
 
18983
18996
  $location.$$parse(newUrl);
18984
- afterLocationChange(oldUrl);
18997
+ if ($rootScope.$broadcast('$locationChangeStart', newUrl,
18998
+ oldUrl).defaultPrevented) {
18999
+ $location.$$parse(oldUrl);
19000
+ $browser.url(oldUrl);
19001
+ } else {
19002
+ afterLocationChange(oldUrl);
19003
+ }
18985
19004
  });
18986
19005
  if (!$rootScope.$$phase) $rootScope.$digest();
18987
19006
  }
@@ -21091,6 +21110,7 @@ function $RootScopeProvider(){
21091
21110
  this.$$asyncQueue = [];
21092
21111
  this.$$postDigestQueue = [];
21093
21112
  this.$$listeners = {};
21113
+ this.$$listenerCount = {};
21094
21114
  this.$$isolateBindings = {};
21095
21115
  }
21096
21116
 
@@ -21150,6 +21170,7 @@ function $RootScopeProvider(){
21150
21170
  }
21151
21171
  child['this'] = child;
21152
21172
  child.$$listeners = {};
21173
+ child.$$listenerCount = {};
21153
21174
  child.$parent = this;
21154
21175
  child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
21155
21176
  child.$$prevSibling = this.$$childTail;
@@ -21309,6 +21330,7 @@ function $RootScopeProvider(){
21309
21330
 
21310
21331
  return function() {
21311
21332
  arrayRemove(array, watcher);
21333
+ lastDirtyWatch = null;
21312
21334
  };
21313
21335
  },
21314
21336
 
@@ -21654,6 +21676,8 @@ function $RootScopeProvider(){
21654
21676
  this.$$destroyed = true;
21655
21677
  if (this === $rootScope) return;
21656
21678
 
21679
+ forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
21680
+
21657
21681
  if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
21658
21682
  if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
21659
21683
  if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
@@ -21843,8 +21867,18 @@ function $RootScopeProvider(){
21843
21867
  }
21844
21868
  namedListeners.push(listener);
21845
21869
 
21870
+ var current = this;
21871
+ do {
21872
+ if (!current.$$listenerCount[name]) {
21873
+ current.$$listenerCount[name] = 0;
21874
+ }
21875
+ current.$$listenerCount[name]++;
21876
+ } while ((current = current.$parent));
21877
+
21878
+ var self = this;
21846
21879
  return function() {
21847
21880
  namedListeners[indexOf(namedListeners, listener)] = null;
21881
+ decrementListenerCount(self, 1, name);
21848
21882
  };
21849
21883
  },
21850
21884
 
@@ -21956,8 +21990,7 @@ function $RootScopeProvider(){
21956
21990
  listeners, i, length;
21957
21991
 
21958
21992
  //down while you can, then up and next sibling or up and next sibling until back at root
21959
- do {
21960
- current = next;
21993
+ while ((current = next)) {
21961
21994
  event.currentScope = current;
21962
21995
  listeners = current.$$listeners[name] || [];
21963
21996
  for (i=0, length = listeners.length; i<length; i++) {
@@ -21979,12 +22012,14 @@ function $RootScopeProvider(){
21979
22012
  // Insanity Warning: scope depth-first traversal
21980
22013
  // yes, this code is a bit crazy, but it works and we have tests to prove it!
21981
22014
  // this piece should be kept in sync with the traversal in $digest
21982
- if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) {
22015
+ // (though it differs due to having the extra check for $$listenerCount)
22016
+ if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
22017
+ (current !== target && current.$$nextSibling)))) {
21983
22018
  while(current !== target && !(next = current.$$nextSibling)) {
21984
22019
  current = current.$parent;
21985
22020
  }
21986
22021
  }
21987
- } while ((current = next));
22022
+ }
21988
22023
 
21989
22024
  return event;
21990
22025
  }
@@ -22013,6 +22048,16 @@ function $RootScopeProvider(){
22013
22048
  return fn;
22014
22049
  }
22015
22050
 
22051
+ function decrementListenerCount(current, count, name) {
22052
+ do {
22053
+ current.$$listenerCount[name] -= count;
22054
+
22055
+ if (current.$$listenerCount[name] === 0) {
22056
+ delete current.$$listenerCount[name];
22057
+ }
22058
+ } while ((current = current.$parent));
22059
+ }
22060
+
22016
22061
  /**
22017
22062
  * function used as an initial value for watchers.
22018
22063
  * because it's unique we can easily tell it apart from other values
@@ -23231,7 +23276,7 @@ function $SnifferProvider() {
23231
23276
  // http://code.google.com/p/android/issues/detail?id=17471
23232
23277
  // https://github.com/angular/angular.js/issues/904
23233
23278
 
23234
- // older webit browser (533.9) on Boxee box has exactly the same problem as Android has
23279
+ // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has
23235
23280
  // so let's not use the history API also
23236
23281
  // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
23237
23282
  // jshint -W018
@@ -23653,21 +23698,21 @@ function $FilterProvider($provide) {
23653
23698
  * property of the object. That's equivalent to the simple substring match with a `string`
23654
23699
  * as described above.
23655
23700
  *
23656
- * - `function`: A predicate function can be used to write arbitrary filters. The function is
23701
+ * - `function(value)`: A predicate function can be used to write arbitrary filters. The function is
23657
23702
  * called for each element of `array`. The final result is an array of those elements that
23658
23703
  * the predicate returned true for.
23659
23704
  *
23660
- * @param {function(expected, actual)|true|undefined} comparator Comparator which is used in
23705
+ * @param {function(actual, expected)|true|undefined} comparator Comparator which is used in
23661
23706
  * determining if the expected value (from the filter expression) and actual value (from
23662
23707
  * the object in the array) should be considered a match.
23663
23708
  *
23664
23709
  * Can be one of:
23665
23710
  *
23666
- * - `function(expected, actual)`:
23711
+ * - `function(actual, expected)`:
23667
23712
  * The function will be given the object value and the predicate value to compare and
23668
23713
  * should return true if the item should be included in filtered result.
23669
23714
  *
23670
- * - `true`: A shorthand for `function(expected, actual) { return angular.equals(expected, actual)}`.
23715
+ * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
23671
23716
  * this is essentially strict comparison of expected and actual.
23672
23717
  *
23673
23718
  * - `false|undefined`: A short hand for a function which will look for a substring match in case
@@ -25772,9 +25817,13 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
25772
25817
  }
25773
25818
 
25774
25819
  if (ctrl.$viewValue !== value) {
25775
- scope.$apply(function() {
25820
+ if (scope.$$phase) {
25776
25821
  ctrl.$setViewValue(value);
25777
- });
25822
+ } else {
25823
+ scope.$apply(function() {
25824
+ ctrl.$setViewValue(value);
25825
+ });
25826
+ }
25778
25827
  }
25779
25828
  };
25780
25829
 
@@ -28853,7 +28902,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
28853
28902
  $$tlb: true,
28854
28903
  link: function($scope, $element, $attr, ctrl, $transclude){
28855
28904
  var expression = $attr.ngRepeat;
28856
- var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
28905
+ var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
28857
28906
  trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
28858
28907
  lhs, rhs, valueIdentifier, keyIdentifier,
28859
28908
  hashFnLocals = {$id: hashKey};
@@ -28865,7 +28914,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
28865
28914
 
28866
28915
  lhs = match[1];
28867
28916
  rhs = match[2];
28868
- trackByExp = match[4];
28917
+ trackByExp = match[3];
28869
28918
 
28870
28919
  if (trackByExp) {
28871
28920
  trackByExpGetter = $parse(trackByExp);
@@ -30554,7 +30603,8 @@ function callerFile(offset) {
30554
30603
  * To work around this we instead use our own handler that fires a real event.
30555
30604
  */
30556
30605
  (function(fn){
30557
- var parentTrigger = fn.trigger;
30606
+ // We need a handle to the original trigger function for input tests.
30607
+ var parentTrigger = fn._originalTrigger = fn.trigger;
30558
30608
  fn.trigger = function(type) {
30559
30609
  if (/(click|change|keydown|blur|input|mousedown|mouseup)/.test(type)) {
30560
30610
  var processDefaults = [];