angularjs-rails 1.2.5 → 1.2.6

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.2.5
2
+ * @license AngularJS v1.2.6
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.5
2
+ * @license AngularJS v1.2.6
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.2.5/' +
71
+ message = message + '\nhttp://errors.angularjs.org/1.2.6/' +
72
72
  (module ? module + '/' : '') + code;
73
73
  for (i = 2; i < arguments.length; i++) {
74
74
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -292,7 +292,9 @@ function forEach(obj, iterator, context) {
292
292
  if (obj) {
293
293
  if (isFunction(obj)){
294
294
  for (key in obj) {
295
- if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
295
+ // Need to check if hasOwnProperty exists,
296
+ // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
297
+ if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
296
298
  iterator.call(context, obj[key], key);
297
299
  }
298
300
  }
@@ -848,7 +850,7 @@ function shallowCopy(src, dst) {
848
850
  for(var key in src) {
849
851
  // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
850
852
  // so we don't need to worry about using our custom hasOwnProperty here
851
- if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
853
+ if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') {
852
854
  dst[key] = src[key];
853
855
  }
854
856
  }
@@ -1829,11 +1831,11 @@ function setupModuleLoader(window) {
1829
1831
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
1830
1832
  */
1831
1833
  var version = {
1832
- full: '1.2.5', // all of these placeholder strings will be replaced by grunt's
1834
+ full: '1.2.6', // all of these placeholder strings will be replaced by grunt's
1833
1835
  major: 1, // package task
1834
1836
  minor: 2,
1835
- dot: 5,
1836
- codeName: 'singularity-expansion'
1837
+ dot: 6,
1838
+ codeName: 'taco-salsafication'
1837
1839
  };
1838
1840
 
1839
1841
 
@@ -2009,6 +2011,7 @@ function publishExternalAPI(angular){
2009
2011
  * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
2010
2012
  * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
2011
2013
  * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
2014
+ * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
2012
2015
  * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
2013
2016
  * - [`prepend()`](http://api.jquery.com/prepend/)
2014
2017
  * - [`prop()`](http://api.jquery.com/prop/)
@@ -2600,7 +2603,10 @@ function createEventHandler(element, events) {
2600
2603
  return event.defaultPrevented || event.returnValue === false;
2601
2604
  };
2602
2605
 
2603
- forEach(events[type || event.type], function(fn) {
2606
+ // Copy event handlers in case event handlers array is modified during execution.
2607
+ var eventHandlersCopy = shallowCopy(events[type || event.type] || []);
2608
+
2609
+ forEach(eventHandlersCopy, function(fn) {
2604
2610
  fn.call(element, event);
2605
2611
  });
2606
2612
 
@@ -2696,6 +2702,19 @@ forEach({
2696
2702
 
2697
2703
  off: jqLiteOff,
2698
2704
 
2705
+ one: function(element, type, fn) {
2706
+ element = jqLite(element);
2707
+
2708
+ //add the listener twice so that when it is called
2709
+ //you can remove the original function and still be
2710
+ //able to call element.off(ev, fn) normally
2711
+ element.on(type, function onFn() {
2712
+ element.off(type, fn);
2713
+ element.off(type, onFn);
2714
+ });
2715
+ element.on(type, fn);
2716
+ },
2717
+
2699
2718
  replaceWith: function(element, replaceNode) {
2700
2719
  var index, parent = element.parentNode;
2701
2720
  jqLiteDealoc(element);
@@ -3389,15 +3408,15 @@ function annotate(fn) {
3389
3408
  * {@link AUTO.$provide#methods_service $provide.service(class)} that is defined as a CoffeeScript class.
3390
3409
  * <pre>
3391
3410
  * class Ping
3392
- * constructor: (@$http)->
3393
- * send: ()=>
3411
+ * constructor: (@$http) ->
3412
+ * send: () =>
3394
3413
  * @$http.get('/ping')
3395
3414
  *
3396
3415
  * $provide.service('ping', ['$http', Ping])
3397
3416
  * </pre>
3398
3417
  * You would then inject and use this service like this:
3399
3418
  * <pre>
3400
- * someModule.controller 'Ctrl', ['ping', (ping)->
3419
+ * someModule.controller 'Ctrl', ['ping', (ping) ->
3401
3420
  * ping.send()
3402
3421
  * ]
3403
3422
  * </pre>
@@ -3864,6 +3883,28 @@ var $AnimateProvider = ['$provide', function($provide) {
3864
3883
  $provide.factory(key, factory);
3865
3884
  };
3866
3885
 
3886
+ /**
3887
+ * @ngdoc function
3888
+ * @name ng.$animateProvider#classNameFilter
3889
+ * @methodOf ng.$animateProvider
3890
+ *
3891
+ * @description
3892
+ * Sets and/or returns the CSS class regular expression that is checked when performing
3893
+ * an animation. Upon bootstrap the classNameFilter value is not set at all and will
3894
+ * therefore enable $animate to attempt to perform an animation on any element.
3895
+ * When setting the classNameFilter value, animations will only be performed on elements
3896
+ * that successfully match the filter expression. This in turn can boost performance
3897
+ * for low-powered devices as well as applications containing a lot of structural operations.
3898
+ * @param {RegExp=} expression The className expression which will be checked against all animations
3899
+ * @return {RegExp} The current CSS className expression value. If null then there is no expression value
3900
+ */
3901
+ this.classNameFilter = function(expression) {
3902
+ if(arguments.length === 1) {
3903
+ this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
3904
+ }
3905
+ return this.$$classNameFilter;
3906
+ };
3907
+
3867
3908
  this.$get = ['$timeout', function($timeout) {
3868
3909
 
3869
3910
  /**
@@ -5111,14 +5152,14 @@ function $TemplateCacheProvider() {
5111
5152
  * example would not point to the clone, but rather to the original template that was cloned. In
5112
5153
  * this case, you can access the clone via the cloneAttachFn:
5113
5154
  * <pre>
5114
- * var templateHTML = angular.element('<p>{{total}}</p>'),
5155
+ * var templateElement = angular.element('<p>{{total}}</p>'),
5115
5156
  * scope = ....;
5116
5157
  *
5117
- * var clonedElement = $compile(templateHTML)(scope, function(clonedElement, scope) {
5158
+ * var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
5118
5159
  * //attach the clone to DOM document at the right place
5119
5160
  * });
5120
5161
  *
5121
- * //now we have reference to the cloned DOM via `clone`
5162
+ * //now we have reference to the cloned DOM via `clonedElement`
5122
5163
  * </pre>
5123
5164
  *
5124
5165
  *
@@ -5460,6 +5501,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5460
5501
  var compositeLinkFn =
5461
5502
  compileNodes($compileNodes, transcludeFn, $compileNodes,
5462
5503
  maxPriority, ignoreDirective, previousCompileContext);
5504
+ safeAddClass($compileNodes, 'ng-scope');
5463
5505
  return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
5464
5506
  assertArg(scope, 'scope');
5465
5507
  // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
@@ -5474,12 +5516,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5474
5516
 
5475
5517
  // Attach scope only to non-text nodes.
5476
5518
  for(var i = 0, ii = $linkNode.length; i<ii; i++) {
5477
- var node = $linkNode[i];
5478
- if (node.nodeType == 1 /* element */ || node.nodeType == 9 /* document */) {
5519
+ var node = $linkNode[i],
5520
+ nodeType = node.nodeType;
5521
+ if (nodeType === 1 /* element */ || nodeType === 9 /* document */) {
5479
5522
  $linkNode.eq(i).data('$scope', scope);
5480
5523
  }
5481
5524
  }
5482
- safeAddClass($linkNode, 'ng-scope');
5525
+
5483
5526
  if (cloneConnectFn) cloneConnectFn($linkNode, scope);
5484
5527
  if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode);
5485
5528
  return $linkNode;
@@ -5507,15 +5550,15 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5507
5550
  * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then
5508
5551
  * the rootElement must be set the jqLite collection of the compile root. This is
5509
5552
  * needed so that the jqLite collection items can be replaced with widgets.
5510
- * @param {number=} max directive priority
5553
+ * @param {number=} maxPriority Max directive priority.
5511
5554
  * @returns {?function} A composite linking function of all of the matched directives or null.
5512
5555
  */
5513
5556
  function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
5514
5557
  previousCompileContext) {
5515
5558
  var linkFns = [],
5516
- nodeLinkFn, childLinkFn, directives, attrs, linkFnFound;
5559
+ attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound;
5517
5560
 
5518
- for(var i = 0; i < nodeList.length; i++) {
5561
+ for (var i = 0; i < nodeList.length; i++) {
5519
5562
  attrs = new Attributes();
5520
5563
 
5521
5564
  // we must always refer to nodeList[i] since the nodes can be replaced underneath us.
@@ -5527,16 +5570,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5527
5570
  null, [], [], previousCompileContext)
5528
5571
  : null;
5529
5572
 
5573
+ if (nodeLinkFn && nodeLinkFn.scope) {
5574
+ safeAddClass(jqLite(nodeList[i]), 'ng-scope');
5575
+ }
5576
+
5530
5577
  childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
5531
- !nodeList[i].childNodes ||
5532
- !nodeList[i].childNodes.length)
5578
+ !(childNodes = nodeList[i].childNodes) ||
5579
+ !childNodes.length)
5533
5580
  ? null
5534
- : compileNodes(nodeList[i].childNodes,
5581
+ : compileNodes(childNodes,
5535
5582
  nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
5536
5583
 
5537
- linkFns.push(nodeLinkFn);
5538
- linkFns.push(childLinkFn);
5539
- linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn);
5584
+ linkFns.push(nodeLinkFn, childLinkFn);
5585
+ linkFnFound = linkFnFound || nodeLinkFn || childLinkFn;
5540
5586
  //use the previous context only for the first element in the virtual group
5541
5587
  previousCompileContext = null;
5542
5588
  }
@@ -5548,9 +5594,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5548
5594
  var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n;
5549
5595
 
5550
5596
  // copy nodeList so that linking doesn't break due to live list updates.
5551
- var stableNodeList = [];
5552
- for (i = 0, ii = nodeList.length; i < ii; i++) {
5553
- stableNodeList.push(nodeList[i]);
5597
+ var nodeListLength = nodeList.length,
5598
+ stableNodeList = new Array(nodeListLength);
5599
+ for (i = 0; i < nodeListLength; i++) {
5600
+ stableNodeList[i] = nodeList[i];
5554
5601
  }
5555
5602
 
5556
5603
  for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) {
@@ -5563,7 +5610,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5563
5610
  if (nodeLinkFn.scope) {
5564
5611
  childScope = scope.$new();
5565
5612
  $node.data('$scope', childScope);
5566
- safeAddClass($node, 'ng-scope');
5567
5613
  } else {
5568
5614
  childScope = scope;
5569
5615
  }
@@ -5646,9 +5692,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
5646
5692
 
5647
5693
  nName = directiveNormalize(name.toLowerCase());
5648
5694
  attrsMap[nName] = name;
5649
- attrs[nName] = value = trim((msie && name == 'href')
5650
- ? decodeURIComponent(node.getAttribute(name, 2))
5651
- : attr.value);
5695
+ attrs[nName] = value = trim(attr.value);
5652
5696
  if (getBooleanAttrName(node, nName)) {
5653
5697
  attrs[nName] = true; // presence means true
5654
5698
  }
@@ -8243,6 +8287,14 @@ function $IntervalProvider() {
8243
8287
  * In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to
8244
8288
  * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
8245
8289
  * time.
8290
+ *
8291
+ * <div class="alert alert-warning">
8292
+ * **Note**: Intervals created by this service must be explicitly destroyed when you are finished
8293
+ * with them. In particular they are not automatically destroyed when a controller's scope or a
8294
+ * directive's element are destroyed.
8295
+ * You should take this into consideration and make sure to always cancel the interval at the
8296
+ * appropriate moment. See the example below for more details on how and when to do this.
8297
+ * </div>
8246
8298
  *
8247
8299
  * @param {function()} fn A function that should be called repeatedly.
8248
8300
  * @param {number} delay Number of milliseconds between each function call.
@@ -8251,6 +8303,95 @@ function $IntervalProvider() {
8251
8303
  * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
8252
8304
  * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block.
8253
8305
  * @returns {promise} A promise which will be notified on each iteration.
8306
+ *
8307
+ * @example
8308
+ <doc:example module="time">
8309
+ <doc:source>
8310
+ <script>
8311
+ function Ctrl2($scope,$interval) {
8312
+ $scope.format = 'M/d/yy h:mm:ss a';
8313
+ $scope.blood_1 = 100;
8314
+ $scope.blood_2 = 120;
8315
+
8316
+ var stop;
8317
+ $scope.fight = function() {
8318
+ // Don't start a new fight if we are already fighting
8319
+ if ( angular.isDefined(stop) ) return;
8320
+
8321
+ stop = $interval(function() {
8322
+ if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
8323
+ $scope.blood_1 = $scope.blood_1 - 3;
8324
+ $scope.blood_2 = $scope.blood_2 - 4;
8325
+ } else {
8326
+ $scope.stopFight();
8327
+ }
8328
+ }, 100);
8329
+ };
8330
+
8331
+ $scope.stopFight = function() {
8332
+ if (angular.isDefined(stop)) {
8333
+ $interval.cancel(stop);
8334
+ stop = undefined;
8335
+ }
8336
+ };
8337
+
8338
+ $scope.resetFight = function() {
8339
+ $scope.blood_1 = 100;
8340
+ $scope.blood_2 = 120;
8341
+ }
8342
+
8343
+ $scope.$on('$destroy', function() {
8344
+ // Make sure that the interval is destroyed too
8345
+ $scope.stopFight();
8346
+ });
8347
+ }
8348
+
8349
+ angular.module('time', [])
8350
+ // Register the 'myCurrentTime' directive factory method.
8351
+ // We inject $interval and dateFilter service since the factory method is DI.
8352
+ .directive('myCurrentTime', function($interval, dateFilter) {
8353
+ // return the directive link function. (compile function not needed)
8354
+ return function(scope, element, attrs) {
8355
+ var format, // date format
8356
+ stopTime; // so that we can cancel the time updates
8357
+
8358
+ // used to update the UI
8359
+ function updateTime() {
8360
+ element.text(dateFilter(new Date(), format));
8361
+ }
8362
+
8363
+ // watch the expression, and update the UI on change.
8364
+ scope.$watch(attrs.myCurrentTime, function(value) {
8365
+ format = value;
8366
+ updateTime();
8367
+ });
8368
+
8369
+ stopTime = $interval(updateTime, 1000);
8370
+
8371
+ // listen on DOM destroy (removal) event, and cancel the next UI update
8372
+ // to prevent updating time ofter the DOM element was removed.
8373
+ element.bind('$destroy', function() {
8374
+ $interval.cancel(stopTime);
8375
+ });
8376
+ }
8377
+ });
8378
+ </script>
8379
+
8380
+ <div>
8381
+ <div ng-controller="Ctrl2">
8382
+ Date format: <input ng-model="format"> <hr/>
8383
+ Current time is: <span my-current-time="format"></span>
8384
+ <hr/>
8385
+ Blood 1 : <font color='red'>{{blood_1}}</font>
8386
+ Blood 2 : <font color='red'>{{blood_2}}</font>
8387
+ <button type="button" data-ng-click="fight()">Fight</button>
8388
+ <button type="button" data-ng-click="stopFight()">StopFight</button>
8389
+ <button type="button" data-ng-click="resetFight()">resetFight</button>
8390
+ </div>
8391
+ </div>
8392
+
8393
+ </doc:source>
8394
+ </doc:example>
8254
8395
  */
8255
8396
  function interval(fn, delay, count, invokeApply) {
8256
8397
  var setInterval = $window.setInterval,
@@ -9009,6 +9150,13 @@ function $LocationProvider(){
9009
9150
  }
9010
9151
 
9011
9152
  var absHref = elm.prop('href');
9153
+
9154
+ if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
9155
+ // SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during
9156
+ // an animation.
9157
+ absHref = urlResolve(absHref.animVal).href;
9158
+ }
9159
+
9012
9160
  var rewrittenUrl = $location.$$rewrite(absHref);
9013
9161
 
9014
9162
  if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) {
@@ -9217,9 +9365,16 @@ function $LogProvider(){
9217
9365
 
9218
9366
  function consoleLog(type) {
9219
9367
  var console = $window.console || {},
9220
- logFn = console[type] || console.log || noop;
9368
+ logFn = console[type] || console.log || noop,
9369
+ hasApply = false;
9370
+
9371
+ // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
9372
+ // The reason behind this is that console.log has type "object" in IE8...
9373
+ try {
9374
+ hasApply = !! logFn.apply;
9375
+ } catch (e) {}
9221
9376
 
9222
- if (logFn.apply) {
9377
+ if (hasApply) {
9223
9378
  return function() {
9224
9379
  var args = [];
9225
9380
  forEach(arguments, function(arg) {
@@ -10129,19 +10284,19 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10129
10284
  ? function cspSafeGetter(scope, locals) {
10130
10285
  var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope;
10131
10286
 
10132
- if (pathVal === null || pathVal === undefined) return pathVal;
10287
+ if (pathVal == null) return pathVal;
10133
10288
  pathVal = pathVal[key0];
10134
10289
 
10135
- if (!key1 || pathVal === null || pathVal === undefined) return pathVal;
10290
+ if (pathVal == null) return key1 ? undefined : pathVal;
10136
10291
  pathVal = pathVal[key1];
10137
10292
 
10138
- if (!key2 || pathVal === null || pathVal === undefined) return pathVal;
10293
+ if (pathVal == null) return key2 ? undefined : pathVal;
10139
10294
  pathVal = pathVal[key2];
10140
10295
 
10141
- if (!key3 || pathVal === null || pathVal === undefined) return pathVal;
10296
+ if (pathVal == null) return key3 ? undefined : pathVal;
10142
10297
  pathVal = pathVal[key3];
10143
10298
 
10144
- if (!key4 || pathVal === null || pathVal === undefined) return pathVal;
10299
+ if (pathVal == null) return key4 ? undefined : pathVal;
10145
10300
  pathVal = pathVal[key4];
10146
10301
 
10147
10302
  return pathVal;
@@ -10150,7 +10305,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10150
10305
  var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope,
10151
10306
  promise;
10152
10307
 
10153
- if (pathVal === null || pathVal === undefined) return pathVal;
10308
+ if (pathVal == null) return pathVal;
10154
10309
 
10155
10310
  pathVal = pathVal[key0];
10156
10311
  if (pathVal && pathVal.then) {
@@ -10162,7 +10317,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10162
10317
  }
10163
10318
  pathVal = pathVal.$$v;
10164
10319
  }
10165
- if (!key1 || pathVal === null || pathVal === undefined) return pathVal;
10320
+ if (pathVal == null) return key1 ? undefined : pathVal;
10166
10321
 
10167
10322
  pathVal = pathVal[key1];
10168
10323
  if (pathVal && pathVal.then) {
@@ -10174,7 +10329,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10174
10329
  }
10175
10330
  pathVal = pathVal.$$v;
10176
10331
  }
10177
- if (!key2 || pathVal === null || pathVal === undefined) return pathVal;
10332
+ if (pathVal == null) return key2 ? undefined : pathVal;
10178
10333
 
10179
10334
  pathVal = pathVal[key2];
10180
10335
  if (pathVal && pathVal.then) {
@@ -10186,7 +10341,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10186
10341
  }
10187
10342
  pathVal = pathVal.$$v;
10188
10343
  }
10189
- if (!key3 || pathVal === null || pathVal === undefined) return pathVal;
10344
+ if (pathVal == null) return key3 ? undefined : pathVal;
10190
10345
 
10191
10346
  pathVal = pathVal[key3];
10192
10347
  if (pathVal && pathVal.then) {
@@ -10198,7 +10353,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10198
10353
  }
10199
10354
  pathVal = pathVal.$$v;
10200
10355
  }
10201
- if (!key4 || pathVal === null || pathVal === undefined) return pathVal;
10356
+ if (pathVal == null) return key4 ? undefined : pathVal;
10202
10357
 
10203
10358
  pathVal = pathVal[key4];
10204
10359
  if (pathVal && pathVal.then) {
@@ -10214,6 +10369,26 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp, options) {
10214
10369
  };
10215
10370
  }
10216
10371
 
10372
+ function simpleGetterFn1(key0, fullExp) {
10373
+ ensureSafeMemberName(key0, fullExp);
10374
+
10375
+ return function simpleGetterFn1(scope, locals) {
10376
+ if (scope == null) return undefined;
10377
+ return ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
10378
+ };
10379
+ }
10380
+
10381
+ function simpleGetterFn2(key0, key1, fullExp) {
10382
+ ensureSafeMemberName(key0, fullExp);
10383
+ ensureSafeMemberName(key1, fullExp);
10384
+
10385
+ return function simpleGetterFn2(scope, locals) {
10386
+ if (scope == null) return undefined;
10387
+ scope = ((locals && locals.hasOwnProperty(key0)) ? locals : scope)[key0];
10388
+ return scope == null ? undefined : scope[key1];
10389
+ };
10390
+ }
10391
+
10217
10392
  function getterFn(path, options, fullExp) {
10218
10393
  // Check whether the cache has this getter already.
10219
10394
  // We can use hasOwnProperty directly on the cache because we ensure,
@@ -10226,7 +10401,13 @@ function getterFn(path, options, fullExp) {
10226
10401
  pathKeysLength = pathKeys.length,
10227
10402
  fn;
10228
10403
 
10229
- if (options.csp) {
10404
+ // When we have only 1 or 2 tokens, use optimized special case closures.
10405
+ // http://jsperf.com/angularjs-parse-getter/6
10406
+ if (!options.unwrapPromises && pathKeysLength === 1) {
10407
+ fn = simpleGetterFn1(pathKeys[0], fullExp);
10408
+ } else if (!options.unwrapPromises && pathKeysLength === 2) {
10409
+ fn = simpleGetterFn2(pathKeys[0], pathKeys[1], fullExp);
10410
+ } else if (options.csp) {
10230
10411
  if (pathKeysLength < 6) {
10231
10412
  fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp,
10232
10413
  options);
@@ -10244,11 +10425,10 @@ function getterFn(path, options, fullExp) {
10244
10425
  };
10245
10426
  }
10246
10427
  } else {
10247
- var code = 'var l, fn, p;\n';
10428
+ var code = 'var p;\n';
10248
10429
  forEach(pathKeys, function(key, index) {
10249
10430
  ensureSafeMemberName(key, fullExp);
10250
- code += 'if(s === null || s === undefined) return s;\n' +
10251
- 'l=s;\n' +
10431
+ code += 'if(s == null) return undefined;\n' +
10252
10432
  's='+ (index
10253
10433
  // we simply dereference 's' on any .dot notation
10254
10434
  ? 's'
@@ -10271,10 +10451,10 @@ function getterFn(path, options, fullExp) {
10271
10451
  /* jshint -W054 */
10272
10452
  var evaledFnGetter = new Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning
10273
10453
  /* jshint +W054 */
10274
- evaledFnGetter.toString = function() { return code; };
10275
- fn = function(scope, locals) {
10454
+ evaledFnGetter.toString = valueFn(code);
10455
+ fn = options.unwrapPromises ? function(scope, locals) {
10276
10456
  return evaledFnGetter(scope, locals, promiseWarning);
10277
- };
10457
+ } : evaledFnGetter;
10278
10458
  }
10279
10459
 
10280
10460
  // Only cache the value if it's not going to mess up the cache object
@@ -13285,6 +13465,7 @@ function $SnifferProvider() {
13285
13465
  vendorPrefix: vendorPrefix,
13286
13466
  transitions : transitions,
13287
13467
  animations : animations,
13468
+ android: android,
13288
13469
  msie : msie,
13289
13470
  msieDocumentMode: documentMode
13290
13471
  };
@@ -13322,93 +13503,6 @@ function $TimeoutProvider() {
13322
13503
  * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
13323
13504
  * promise will be resolved with is the return value of the `fn` function.
13324
13505
  *
13325
- * @example
13326
- <doc:example module="time">
13327
- <doc:source>
13328
- <script>
13329
- function Ctrl2($scope,$timeout) {
13330
- $scope.format = 'M/d/yy h:mm:ss a';
13331
- $scope.blood_1 = 100;
13332
- $scope.blood_2 = 120;
13333
-
13334
- var stop;
13335
- $scope.fight = function() {
13336
- stop = $timeout(function() {
13337
- if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
13338
- $scope.blood_1 = $scope.blood_1 - 3;
13339
- $scope.blood_2 = $scope.blood_2 - 4;
13340
- $scope.fight();
13341
- } else {
13342
- $timeout.cancel(stop);
13343
- }
13344
- }, 100);
13345
- };
13346
-
13347
- $scope.stopFight = function() {
13348
- $timeout.cancel(stop);
13349
- };
13350
-
13351
- $scope.resetFight = function() {
13352
- $scope.blood_1 = 100;
13353
- $scope.blood_2 = 120;
13354
- }
13355
- }
13356
-
13357
- angular.module('time', [])
13358
- // Register the 'myCurrentTime' directive factory method.
13359
- // We inject $timeout and dateFilter service since the factory method is DI.
13360
- .directive('myCurrentTime', function($timeout, dateFilter) {
13361
- // return the directive link function. (compile function not needed)
13362
- return function(scope, element, attrs) {
13363
- var format, // date format
13364
- timeoutId; // timeoutId, so that we can cancel the time updates
13365
-
13366
- // used to update the UI
13367
- function updateTime() {
13368
- element.text(dateFilter(new Date(), format));
13369
- }
13370
-
13371
- // watch the expression, and update the UI on change.
13372
- scope.$watch(attrs.myCurrentTime, function(value) {
13373
- format = value;
13374
- updateTime();
13375
- });
13376
-
13377
- // schedule update in one second
13378
- function updateLater() {
13379
- // save the timeoutId for canceling
13380
- timeoutId = $timeout(function() {
13381
- updateTime(); // update DOM
13382
- updateLater(); // schedule another update
13383
- }, 1000);
13384
- }
13385
-
13386
- // listen on DOM destroy (removal) event, and cancel the next UI update
13387
- // to prevent updating time ofter the DOM element was removed.
13388
- element.bind('$destroy', function() {
13389
- $timeout.cancel(timeoutId);
13390
- });
13391
-
13392
- updateLater(); // kick off the UI update process.
13393
- }
13394
- });
13395
- </script>
13396
-
13397
- <div>
13398
- <div ng-controller="Ctrl2">
13399
- Date format: <input ng-model="format"> <hr/>
13400
- Current time is: <span my-current-time="format"></span>
13401
- <hr/>
13402
- Blood 1 : <font color='red'>{{blood_1}}</font>
13403
- Blood 2 : <font color='red'>{{blood_2}}</font>
13404
- <button type="button" data-ng-click="fight()">Fight</button>
13405
- <button type="button" data-ng-click="stopFight()">StopFight</button>
13406
- <button type="button" data-ng-click="resetFight()">resetFight</button>
13407
- </div>
13408
- </div>
13409
-
13410
- </doc:source>
13411
- </doc:example>
13412
13506
  */
13413
13507
  function timeout(fn, delay, invokeApply) {
13414
13508
  var deferred = $q.defer(),
@@ -14720,6 +14814,7 @@ var htmlAnchorDirective = valueFn({
14720
14814
  * @ngdoc directive
14721
14815
  * @name ng.directive:ngHref
14722
14816
  * @restrict A
14817
+ * @priority 99
14723
14818
  *
14724
14819
  * @description
14725
14820
  * Using Angular markup like `{{hash}}` in an href attribute will
@@ -14803,6 +14898,7 @@ var htmlAnchorDirective = valueFn({
14803
14898
  * @ngdoc directive
14804
14899
  * @name ng.directive:ngSrc
14805
14900
  * @restrict A
14901
+ * @priority 99
14806
14902
  *
14807
14903
  * @description
14808
14904
  * Using Angular markup like `{{hash}}` in a `src` attribute doesn't
@@ -14828,6 +14924,7 @@ var htmlAnchorDirective = valueFn({
14828
14924
  * @ngdoc directive
14829
14925
  * @name ng.directive:ngSrcset
14830
14926
  * @restrict A
14927
+ * @priority 99
14831
14928
  *
14832
14929
  * @description
14833
14930
  * Using Angular markup like `{{hash}}` in a `srcset` attribute doesn't
@@ -14853,6 +14950,7 @@ var htmlAnchorDirective = valueFn({
14853
14950
  * @ngdoc directive
14854
14951
  * @name ng.directive:ngDisabled
14855
14952
  * @restrict A
14953
+ * @priority 100
14856
14954
  *
14857
14955
  * @description
14858
14956
  *
@@ -14896,6 +14994,7 @@ var htmlAnchorDirective = valueFn({
14896
14994
  * @ngdoc directive
14897
14995
  * @name ng.directive:ngChecked
14898
14996
  * @restrict A
14997
+ * @priority 100
14899
14998
  *
14900
14999
  * @description
14901
15000
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -14930,6 +15029,7 @@ var htmlAnchorDirective = valueFn({
14930
15029
  * @ngdoc directive
14931
15030
  * @name ng.directive:ngReadonly
14932
15031
  * @restrict A
15032
+ * @priority 100
14933
15033
  *
14934
15034
  * @description
14935
15035
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -14939,7 +15039,6 @@ var htmlAnchorDirective = valueFn({
14939
15039
  * The `ngReadonly` directive solves this problem for the `readonly` attribute.
14940
15040
  * This complementary directive is not removed by the browser and so provides
14941
15041
  * a permanent reliable place to store the binding information.
14942
-
14943
15042
  * @example
14944
15043
  <doc:example>
14945
15044
  <doc:source>
@@ -14965,6 +15064,7 @@ var htmlAnchorDirective = valueFn({
14965
15064
  * @ngdoc directive
14966
15065
  * @name ng.directive:ngSelected
14967
15066
  * @restrict A
15067
+ * @priority 100
14968
15068
  *
14969
15069
  * @description
14970
15070
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -14974,6 +15074,7 @@ var htmlAnchorDirective = valueFn({
14974
15074
  * The `ngSelected` directive solves this problem for the `selected` atttribute.
14975
15075
  * This complementary directive is not removed by the browser and so provides
14976
15076
  * a permanent reliable place to store the binding information.
15077
+ *
14977
15078
  * @example
14978
15079
  <doc:example>
14979
15080
  <doc:source>
@@ -15001,6 +15102,7 @@ var htmlAnchorDirective = valueFn({
15001
15102
  * @ngdoc directive
15002
15103
  * @name ng.directive:ngOpen
15003
15104
  * @restrict A
15105
+ * @priority 100
15004
15106
  *
15005
15107
  * @description
15006
15108
  * The HTML specification does not require browsers to preserve the values of boolean attributes
@@ -15010,8 +15112,6 @@ var htmlAnchorDirective = valueFn({
15010
15112
  * The `ngOpen` directive solves this problem for the `open` attribute.
15011
15113
  * This complementary directive is not removed by the browser and so provides
15012
15114
  * a permanent reliable place to store the binding information.
15013
-
15014
- *
15015
15115
  * @example
15016
15116
  <doc:example>
15017
15117
  <doc:source>
@@ -15856,15 +15956,17 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15856
15956
  // In composition mode, users are still inputing intermediate text buffer,
15857
15957
  // hold the listener until composition is done.
15858
15958
  // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
15859
- var composing = false;
15959
+ if (!$sniffer.android) {
15960
+ var composing = false;
15860
15961
 
15861
- element.on('compositionstart', function() {
15862
- composing = true;
15863
- });
15962
+ element.on('compositionstart', function(data) {
15963
+ composing = true;
15964
+ });
15864
15965
 
15865
- element.on('compositionend', function() {
15866
- composing = false;
15867
- });
15966
+ element.on('compositionend', function() {
15967
+ composing = false;
15968
+ });
15969
+ }
15868
15970
 
15869
15971
  var listener = function() {
15870
15972
  if (composing) return;
@@ -17429,7 +17531,7 @@ var ngClassEvenDirective = classDirective('Even', 1);
17429
17531
  *
17430
17532
  * Legacy browsers, like IE7, do not provide attribute selector support (added in CSS 2.1) so they
17431
17533
  * cannot match the `[ng\:cloak]` selector. To work around this limitation, you must add the css
17432
- * class `ngCloak` in addition to the `ngCloak` directive as shown in the example below.
17534
+ * class `ng-cloak` in addition to the `ngCloak` directive as shown in the example below.
17433
17535
  *
17434
17536
  * @element ANY
17435
17537
  *
@@ -17740,7 +17842,14 @@ forEach(
17740
17842
  * a dblclick. (The Event object is available as `$event`)
17741
17843
  *
17742
17844
  * @example
17743
- * See {@link ng.directive:ngClick ngClick}
17845
+ <doc:example>
17846
+ <doc:source>
17847
+ <button ng-dblclick="count = count + 1" ng-init="count=0">
17848
+ Increment (on double click)
17849
+ </button>
17850
+ count: {{count}}
17851
+ </doc:source>
17852
+ </doc:example>
17744
17853
  */
17745
17854
 
17746
17855
 
@@ -17756,7 +17865,14 @@ forEach(
17756
17865
  * mousedown. (Event object is available as `$event`)
17757
17866
  *
17758
17867
  * @example
17759
- * See {@link ng.directive:ngClick ngClick}
17868
+ <doc:example>
17869
+ <doc:source>
17870
+ <button ng-mousedown="count = count + 1" ng-init="count=0">
17871
+ Increment (on mouse down)
17872
+ </button>
17873
+ count: {{count}}
17874
+ </doc:source>
17875
+ </doc:example>
17760
17876
  */
17761
17877
 
17762
17878
 
@@ -17772,7 +17888,14 @@ forEach(
17772
17888
  * mouseup. (Event object is available as `$event`)
17773
17889
  *
17774
17890
  * @example
17775
- * See {@link ng.directive:ngClick ngClick}
17891
+ <doc:example>
17892
+ <doc:source>
17893
+ <button ng-mouseup="count = count + 1" ng-init="count=0">
17894
+ Increment (on mouse up)
17895
+ </button>
17896
+ count: {{count}}
17897
+ </doc:source>
17898
+ </doc:example>
17776
17899
  */
17777
17900
 
17778
17901
  /**
@@ -17787,7 +17910,14 @@ forEach(
17787
17910
  * mouseover. (Event object is available as `$event`)
17788
17911
  *
17789
17912
  * @example
17790
- * See {@link ng.directive:ngClick ngClick}
17913
+ <doc:example>
17914
+ <doc:source>
17915
+ <button ng-mouseover="count = count + 1" ng-init="count=0">
17916
+ Increment (when mouse is over)
17917
+ </button>
17918
+ count: {{count}}
17919
+ </doc:source>
17920
+ </doc:example>
17791
17921
  */
17792
17922
 
17793
17923
 
@@ -17803,7 +17933,14 @@ forEach(
17803
17933
  * mouseenter. (Event object is available as `$event`)
17804
17934
  *
17805
17935
  * @example
17806
- * See {@link ng.directive:ngClick ngClick}
17936
+ <doc:example>
17937
+ <doc:source>
17938
+ <button ng-mouseenter="count = count + 1" ng-init="count=0">
17939
+ Increment (when mouse enters)
17940
+ </button>
17941
+ count: {{count}}
17942
+ </doc:source>
17943
+ </doc:example>
17807
17944
  */
17808
17945
 
17809
17946
 
@@ -17819,7 +17956,14 @@ forEach(
17819
17956
  * mouseleave. (Event object is available as `$event`)
17820
17957
  *
17821
17958
  * @example
17822
- * See {@link ng.directive:ngClick ngClick}
17959
+ <doc:example>
17960
+ <doc:source>
17961
+ <button ng-mouseleave="count = count + 1" ng-init="count=0">
17962
+ Increment (when mouse leaves)
17963
+ </button>
17964
+ count: {{count}}
17965
+ </doc:source>
17966
+ </doc:example>
17823
17967
  */
17824
17968
 
17825
17969
 
@@ -17835,7 +17979,14 @@ forEach(
17835
17979
  * mousemove. (Event object is available as `$event`)
17836
17980
  *
17837
17981
  * @example
17838
- * See {@link ng.directive:ngClick ngClick}
17982
+ <doc:example>
17983
+ <doc:source>
17984
+ <button ng-mousemove="count = count + 1" ng-init="count=0">
17985
+ Increment (when mouse moves)
17986
+ </button>
17987
+ count: {{count}}
17988
+ </doc:source>
17989
+ </doc:example>
17839
17990
  */
17840
17991
 
17841
17992
 
@@ -17851,7 +18002,12 @@ forEach(
17851
18002
  * keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
17852
18003
  *
17853
18004
  * @example
17854
- * See {@link ng.directive:ngClick ngClick}
18005
+ <doc:example>
18006
+ <doc:source>
18007
+ <input ng-keydown="count = count + 1" ng-init="count=0">
18008
+ key down count: {{count}}
18009
+ </doc:source>
18010
+ </doc:example>
17855
18011
  */
17856
18012
 
17857
18013
 
@@ -17867,7 +18023,12 @@ forEach(
17867
18023
  * keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
17868
18024
  *
17869
18025
  * @example
17870
- * See {@link ng.directive:ngClick ngClick}
18026
+ <doc:example>
18027
+ <doc:source>
18028
+ <input ng-keyup="count = count + 1" ng-init="count=0">
18029
+ key up count: {{count}}
18030
+ </doc:source>
18031
+ </doc:example>
17871
18032
  */
17872
18033
 
17873
18034
 
@@ -17883,7 +18044,12 @@ forEach(
17883
18044
  * keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
17884
18045
  *
17885
18046
  * @example
17886
- * See {@link ng.directive:ngClick ngClick}
18047
+ <doc:example>
18048
+ <doc:source>
18049
+ <input ng-keypress="count = count + 1" ng-init="count=0">
18050
+ key press count: {{count}}
18051
+ </doc:source>
18052
+ </doc:example>
17887
18053
  */
17888
18054
 
17889
18055
 
@@ -17982,7 +18148,12 @@ forEach(
17982
18148
  * copy. (Event object is available as `$event`)
17983
18149
  *
17984
18150
  * @example
17985
- * See {@link ng.directive:ngClick ngClick}
18151
+ <doc:example>
18152
+ <doc:source>
18153
+ <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value">
18154
+ copied: {{copied}}
18155
+ </doc:source>
18156
+ </doc:example>
17986
18157
  */
17987
18158
 
17988
18159
  /**
@@ -17997,7 +18168,12 @@ forEach(
17997
18168
  * cut. (Event object is available as `$event`)
17998
18169
  *
17999
18170
  * @example
18000
- * See {@link ng.directive:ngClick ngClick}
18171
+ <doc:example>
18172
+ <doc:source>
18173
+ <input ng-cut="cut=true" ng-init="cut=false; value='cut me'" ng-model="value">
18174
+ cut: {{cut}}
18175
+ </doc:source>
18176
+ </doc:example>
18001
18177
  */
18002
18178
 
18003
18179
  /**
@@ -18012,7 +18188,12 @@ forEach(
18012
18188
  * paste. (Event object is available as `$event`)
18013
18189
  *
18014
18190
  * @example
18015
- * See {@link ng.directive:ngClick ngClick}
18191
+ <doc:example>
18192
+ <doc:source>
18193
+ <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'>
18194
+ pasted: {{paste}}
18195
+ </doc:source>
18196
+ </doc:example>
18016
18197
  */
18017
18198
 
18018
18199
  /**
@@ -18074,9 +18255,6 @@ forEach(
18074
18255
  padding:10px;
18075
18256
  }
18076
18257
 
18077
- /&#42;
18078
- The transition styles can also be placed on the CSS base class above
18079
- &#42;/
18080
18258
  .animate-if.ng-enter, .animate-if.ng-leave {
18081
18259
  -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
18082
18260
  transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
@@ -18384,7 +18562,7 @@ var ngIncludeFillContentDirective = ['$compile',
18384
18562
  * current scope.
18385
18563
  *
18386
18564
  * <div class="alert alert-error">
18387
- * The only appropriate use of `ngInit` for aliasing special properties of
18565
+ * The only appropriate use of `ngInit` is for aliasing special properties of
18388
18566
  * {@link api/ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below. Besides this case, you
18389
18567
  * should use {@link guide/controller controllers} rather than `ngInit`
18390
18568
  * to initialize values on a scope.
@@ -18883,7 +19061,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
18883
19061
  $$tlb: true,
18884
19062
  link: function($scope, $element, $attr, ctrl, $transclude){
18885
19063
  var expression = $attr.ngRepeat;
18886
- var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
19064
+ var match = expression.match(/^\s*(.+)\s+in\s+([\r\n\s\S]*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
18887
19065
  trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
18888
19066
  lhs, rhs, valueIdentifier, keyIdentifier,
18889
19067
  hashFnLocals = {$id: hashKey};
@@ -19941,18 +20119,10 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
19941
20119
  selectCtrl.init(ngModelCtrl, nullOption, unknownOption);
19942
20120
 
19943
20121
  // required validator
19944
- if (multiple && (attr.required || attr.ngRequired)) {
19945
- var requiredValidator = function(value) {
19946
- ngModelCtrl.$setValidity('required', !attr.required || (value && value.length));
19947
- return value;
20122
+ if (multiple) {
20123
+ ngModelCtrl.$isEmpty = function(value) {
20124
+ return !value || value.length === 0;
19948
20125
  };
19949
-
19950
- ngModelCtrl.$parsers.push(requiredValidator);
19951
- ngModelCtrl.$formatters.unshift(requiredValidator);
19952
-
19953
- attr.$observe('required', function() {
19954
- requiredValidator(ngModelCtrl.$viewValue);
19955
- });
19956
20126
  }
19957
20127
 
19958
20128
  if (optionsExp) setupAsOptions(scope, element, ngModelCtrl);
@@ -20366,4 +20536,4 @@ var styleDirective = valueFn({
20366
20536
 
20367
20537
  })(window, document);
20368
20538
 
20369
- !angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-start{border-spacing:1px 1px;-ms-zoom:1.0001;}.ng-animate-active{border-spacing:0px 0px;-ms-zoom:1;}</style>');
20539
+ !angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>');