angular-gem 1.2.5 → 1.2.6

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.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>');