angularjs-rails 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 057e98f881260457560c9c3c48db4315c9ed9274
4
- data.tar.gz: 1472731f282bbfe48e9f70bedd9e60952cf90f51
3
+ metadata.gz: ff35c5f1c0d084a8bae307cf16c9ebd6fc000d94
4
+ data.tar.gz: 14b3dd9904a2ef1e7500273bef92f861fbbaaee8
5
5
  SHA512:
6
- metadata.gz: 51a1b04c1ddf80a54cd25787cb1c03107c942bb52aae366a8a69921f67a0851e277ee1fe1b10ee871c22d6534c56bdee88ee9b5e8bb490087145c145ad89ec9a
7
- data.tar.gz: 51f3e1f860e730c6b5c43f3eace759b111ffaff3d1df91b452cd8c527dfbba7400f3641fbcf9582d959f6d6e9337f4f1ad772b6e71ffdfe8ef581a9e96a7f69d
6
+ metadata.gz: 9d013f75a6420a655bde4f8c166c0bdceee3781fd71e579686c25a9ef84200618a9ff2bc9b5fd2a3984035b0e8b28806f3ea1c5dcea6d9e9b485b8c2c7cf70d0
7
+ data.tar.gz: 23032f7c161ea8f1c978f0af642ee77b700e61f557d1411cbcff5e2610d4e109fc431508615ac5b8fe252235f571c13385942d32005992739359af45490419c1
@@ -1,6 +1,6 @@
1
1
  module AngularJS
2
2
  module Rails
3
- VERSION = "1.2.0"
3
+ VERSION = "1.2.1"
4
4
  UNSTABLE_VERSION = "1.1.5"
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.0
2
+ * @license AngularJS v1.2.1
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.0
2
+ * @license AngularJS v1.2.1
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,10 +1,84 @@
1
1
  /**
2
- * @license AngularJS v1.2.0
2
+ * @license AngularJS v1.2.1
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
 
7
- (
7
+ (function() {'use strict';
8
+
9
+ /**
10
+ * @description
11
+ *
12
+ * This object provides a utility for producing rich Error messages within
13
+ * Angular. It can be called as follows:
14
+ *
15
+ * var exampleMinErr = minErr('example');
16
+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
17
+ *
18
+ * The above creates an instance of minErr in the example namespace. The
19
+ * resulting error will have a namespaced error code of example.one. The
20
+ * resulting error will replace {0} with the value of foo, and {1} with the
21
+ * value of bar. The object is not restricted in the number of arguments it can
22
+ * take.
23
+ *
24
+ * If fewer arguments are specified than necessary for interpolation, the extra
25
+ * interpolation markers will be preserved in the final string.
26
+ *
27
+ * Since data will be parsed statically during a build step, some restrictions
28
+ * are applied with respect to how minErr instances are created and called.
29
+ * Instances should have names of the form namespaceMinErr for a minErr created
30
+ * using minErr('namespace') . Error codes, namespaces and template strings
31
+ * should all be static strings, not variables or general expressions.
32
+ *
33
+ * @param {string} module The namespace to use for the new minErr instance.
34
+ * @returns {function(string, string, ...): Error} instance
35
+ */
36
+
37
+ function minErr(module) {
38
+ return function () {
39
+ var code = arguments[0],
40
+ prefix = '[' + (module ? module + ':' : '') + code + '] ',
41
+ template = arguments[1],
42
+ templateArgs = arguments,
43
+ stringify = function (obj) {
44
+ if (typeof obj === 'function') {
45
+ return obj.toString().replace(/ \{[\s\S]*$/, '');
46
+ } else if (typeof obj === 'undefined') {
47
+ return 'undefined';
48
+ } else if (typeof obj !== 'string') {
49
+ return JSON.stringify(obj);
50
+ }
51
+ return obj;
52
+ },
53
+ message, i;
54
+
55
+ message = prefix + template.replace(/\{\d+\}/g, function (match) {
56
+ var index = +match.slice(1, -1), arg;
57
+
58
+ if (index + 2 < templateArgs.length) {
59
+ arg = templateArgs[index + 2];
60
+ if (typeof arg === 'function') {
61
+ return arg.toString().replace(/ ?\{[\s\S]*$/, '');
62
+ } else if (typeof arg === 'undefined') {
63
+ return 'undefined';
64
+ } else if (typeof arg !== 'string') {
65
+ return toJson(arg);
66
+ }
67
+ return arg;
68
+ }
69
+ return match;
70
+ });
71
+
72
+ message = message + '\nhttp://errors.angularjs.org/1.2.1/' +
73
+ (module ? module + '/' : '') + code;
74
+ for (i = 2; i < arguments.length; i++) {
75
+ message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
76
+ encodeURIComponent(stringify(arguments[i]));
77
+ }
78
+
79
+ return new Error(message);
80
+ };
81
+ }
8
82
 
9
83
  /**
10
84
  * @ngdoc interface
@@ -17,6 +91,7 @@
17
91
  function setupModuleLoader(window) {
18
92
 
19
93
  var $injectorMinErr = minErr('$injector');
94
+ var ngMinErr = minErr('ng');
20
95
 
21
96
  function ensure(obj, name, factory) {
22
97
  return obj[name] || (obj[name] = factory());
@@ -53,7 +128,7 @@ function setupModuleLoader(window) {
53
128
  * myModule.value('appName', 'MyCoolApp');
54
129
  *
55
130
  * // configure existing services inside initialization blocks.
56
- * myModule.config(function($locationProvider) {'use strict';
131
+ * myModule.config(function($locationProvider) {
57
132
  * // Configure existing providers
58
133
  * $locationProvider.hashPrefix('!');
59
134
  * });
@@ -77,6 +152,12 @@ function setupModuleLoader(window) {
77
152
  * @returns {module} new module with the {@link angular.Module} api.
78
153
  */
79
154
  return function module(name, requires, configFn) {
155
+ var assertNotHasOwnProperty = function(name, context) {
156
+ if (name === 'hasOwnProperty') {
157
+ throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
158
+ }
159
+ };
160
+
80
161
  assertNotHasOwnProperty(name, 'module');
81
162
  if (requires && modules.hasOwnProperty(name)) {
82
163
  modules[name] = null;
@@ -301,7 +382,8 @@ function setupModuleLoader(window) {
301
382
 
302
383
  }
303
384
 
304
- )(window);
385
+ setupModuleLoader(window);
386
+ })(window);
305
387
 
306
388
  /**
307
389
  * Closure compiler type information
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * @license AngularJS v1.2.0
4
+ * @license AngularJS v1.2.1
5
5
  * (c) 2010-2012 Google, Inc. http://angularjs.org
6
6
  * License: MIT
7
7
  *
@@ -1657,21 +1657,6 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
1657
1657
  $browser.defer.flush(delay);
1658
1658
  };
1659
1659
 
1660
- /**
1661
- * @ngdoc method
1662
- * @name ngMock.$timeout#flushNext
1663
- * @methodOf ngMock.$timeout
1664
- * @description
1665
- *
1666
- * Flushes the next timeout in the queue and compares it to the provided delay
1667
- *
1668
- * @param {number=} expectedDelay the delay value that will be asserted against the delay of the
1669
- * next timeout function
1670
- */
1671
- $delegate.flushNext = function(expectedDelay) {
1672
- $browser.defer.flushNext(expectedDelay);
1673
- };
1674
-
1675
1660
  /**
1676
1661
  * @ngdoc method
1677
1662
  * @name ngMock.$timeout#verifyNoPendingTasks
@@ -2127,4 +2112,4 @@ angular.mock.clearDataCache = function() {
2127
2112
  }
2128
2113
  }
2129
2114
  };
2130
- })(window);
2115
+ })(window);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.0
2
+ * @license AngularJS v1.2.1
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -7,6 +7,28 @@
7
7
 
8
8
  var $resourceMinErr = angular.$$minErr('$resource');
9
9
 
10
+ // Helper functions and regex to lookup a dotted path on an object
11
+ // stopping at undefined/null. The path must be composed of ASCII
12
+ // identifiers (just like $parse)
13
+ var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;
14
+
15
+ function isValidDottedPath(path) {
16
+ return (path != null && path !== '' && path !== 'hasOwnProperty' &&
17
+ MEMBER_NAME_REGEX.test('.' + path));
18
+ }
19
+
20
+ function lookupDottedPath(obj, path) {
21
+ if (!isValidDottedPath(path)) {
22
+ throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
23
+ }
24
+ var keys = path.split('.');
25
+ for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) {
26
+ var key = keys[i];
27
+ obj = (obj !== null) ? obj[key] : undefined;
28
+ }
29
+ return obj;
30
+ }
31
+
10
32
  /**
11
33
  * @ngdoc overview
12
34
  * @name ngResource
@@ -134,7 +156,7 @@ var $resourceMinErr = angular.$$minErr('$resource');
134
156
  * usually the resource is assigned to a model which is then rendered by the view. Having an empty
135
157
  * object results in no rendering, once the data arrives from the server then the object is
136
158
  * populated with the data and the view automatically re-renders itself showing the new data. This
137
- * means that in most case one never has to write a callback function for the action methods.
159
+ * means that in most cases one never has to write a callback function for the action methods.
138
160
  *
139
161
  * The action methods on the class object or instance object can be invoked with the following
140
162
  * parameters:
@@ -236,61 +258,10 @@ var $resourceMinErr = angular.$$minErr('$resource');
236
258
  });
237
259
  });
238
260
  </pre>
239
-
240
- * # Buzz client
241
-
242
- Let's look at what a buzz client created with the `$resource` service looks like:
243
- <doc:example>
244
- <doc:source jsfiddle="false">
245
- <script>
246
- function BuzzController($resource) {
247
- this.userId = 'googlebuzz';
248
- this.Activity = $resource(
249
- 'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments',
250
- {alt:'json', callback:'JSON_CALLBACK'},
251
- {
252
- get:{method:'JSONP', params:{visibility:'@self'}},
253
- replies: {method:'JSONP', params:{visibility:'@self', comments:'@comments'}}
254
- }
255
- );
256
- }
257
-
258
- BuzzController.prototype = {
259
- fetch: function() {
260
- this.activities = this.Activity.get({userId:this.userId});
261
- },
262
- expandReplies: function(activity) {
263
- activity.replies = this.Activity.replies({userId:this.userId, activityId:activity.id});
264
- }
265
- };
266
- BuzzController.$inject = ['$resource'];
267
- </script>
268
-
269
- <div ng-controller="BuzzController">
270
- <input ng-model="userId"/>
271
- <button ng-click="fetch()">fetch</button>
272
- <hr/>
273
- <div ng-repeat="item in activities.data.items">
274
- <h1 style="font-size: 15px;">
275
- <img src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
276
- <a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
277
- <a href ng-click="expandReplies(item)" style="float: right;">Expand replies:
278
- {{item.links.replies[0].count}}</a>
279
- </h1>
280
- {{item.object.content | html}}
281
- <div ng-repeat="reply in item.replies.data.items" style="margin-left: 20px;">
282
- <img src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
283
- <a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>: {{reply.content | html}}
284
- </div>
285
- </div>
286
- </div>
287
- </doc:source>
288
- <doc:scenario>
289
- </doc:scenario>
290
- </doc:example>
291
261
  */
292
262
  angular.module('ngResource', ['ng']).
293
- factory('$resource', ['$http', '$parse', '$q', function($http, $parse, $q) {
263
+ factory('$resource', ['$http', '$q', function($http, $q) {
264
+
294
265
  var DEFAULT_ACTIONS = {
295
266
  'get': {method:'GET'},
296
267
  'save': {method:'POST'},
@@ -302,10 +273,7 @@ angular.module('ngResource', ['ng']).
302
273
  forEach = angular.forEach,
303
274
  extend = angular.extend,
304
275
  copy = angular.copy,
305
- isFunction = angular.isFunction,
306
- getter = function(obj, path) {
307
- return $parse(path)(obj);
308
- };
276
+ isFunction = angular.isFunction;
309
277
 
310
278
  /**
311
279
  * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
@@ -420,7 +388,7 @@ angular.module('ngResource', ['ng']).
420
388
  forEach(actionParams, function(value, key){
421
389
  if (isFunction(value)) { value = value(); }
422
390
  ids[key] = value && value.charAt && value.charAt(0) == '@' ?
423
- getter(data, value.substr(1)) : value;
391
+ lookupDottedPath(data, value.substr(1)) : value;
424
392
  });
425
393
  return ids;
426
394
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.0
2
+ * @license AngularJS v1.2.1
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -809,8 +809,7 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller,
809
809
  terminal: true,
810
810
  priority: 400,
811
811
  transclude: 'element',
812
- compile: function(element, attr, linker) {
813
- return function(scope, $element, attr) {
812
+ link: function(scope, $element, attr, ctrl, $transclude) {
814
813
  var currentScope,
815
814
  currentElement,
816
815
  autoScrollExp = attr.autoscroll,
@@ -836,7 +835,7 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller,
836
835
 
837
836
  if (template) {
838
837
  var newScope = scope.$new();
839
- linker(newScope, function(clone) {
838
+ $transclude(newScope, function(clone) {
840
839
  clone.html(template);
841
840
  $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
842
841
  if (angular.isDefined(autoScrollExp)
@@ -871,7 +870,6 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller,
871
870
  cleanupLastView();
872
871
  }
873
872
  }
874
- };
875
873
  }
876
874
  };
877
875
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.0
2
+ * @license AngularJS v1.2.1
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -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.0
9793
+ * @license AngularJS v1.2.1
9794
9794
  * (c) 2010-2012 Google, Inc. http://angularjs.org
9795
9795
  * License: MIT
9796
9796
  */
@@ -9832,11 +9832,11 @@ function minErr(module) {
9832
9832
  template = arguments[1],
9833
9833
  templateArgs = arguments,
9834
9834
  stringify = function (obj) {
9835
- if (isFunction(obj)) {
9835
+ if (typeof obj === 'function') {
9836
9836
  return obj.toString().replace(/ \{[\s\S]*$/, '');
9837
- } else if (isUndefined(obj)) {
9837
+ } else if (typeof obj === 'undefined') {
9838
9838
  return 'undefined';
9839
- } else if (!isString(obj)) {
9839
+ } else if (typeof obj !== 'string') {
9840
9840
  return JSON.stringify(obj);
9841
9841
  }
9842
9842
  return obj;
@@ -9848,11 +9848,11 @@ function minErr(module) {
9848
9848
 
9849
9849
  if (index + 2 < templateArgs.length) {
9850
9850
  arg = templateArgs[index + 2];
9851
- if (isFunction(arg)) {
9851
+ if (typeof arg === 'function') {
9852
9852
  return arg.toString().replace(/ ?\{[\s\S]*$/, '');
9853
- } else if (isUndefined(arg)) {
9853
+ } else if (typeof arg === 'undefined') {
9854
9854
  return 'undefined';
9855
- } else if (!isString(arg)) {
9855
+ } else if (typeof arg !== 'string') {
9856
9856
  return toJson(arg);
9857
9857
  }
9858
9858
  return arg;
@@ -9860,7 +9860,7 @@ function minErr(module) {
9860
9860
  return match;
9861
9861
  });
9862
9862
 
9863
- message = message + '\nhttp://errors.angularjs.org/' + version.full + '/' +
9863
+ message = message + '\nhttp://errors.angularjs.org/1.2.1/' +
9864
9864
  (module ? module + '/' : '') + code;
9865
9865
  for (i = 2; i < arguments.length; i++) {
9866
9866
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -11221,6 +11221,7 @@ function getBlockElements(block) {
11221
11221
  function setupModuleLoader(window) {
11222
11222
 
11223
11223
  var $injectorMinErr = minErr('$injector');
11224
+ var ngMinErr = minErr('ng');
11224
11225
 
11225
11226
  function ensure(obj, name, factory) {
11226
11227
  return obj[name] || (obj[name] = factory());
@@ -11281,6 +11282,12 @@ function setupModuleLoader(window) {
11281
11282
  * @returns {module} new module with the {@link angular.Module} api.
11282
11283
  */
11283
11284
  return function module(name, requires, configFn) {
11285
+ var assertNotHasOwnProperty = function(name, context) {
11286
+ if (name === 'hasOwnProperty') {
11287
+ throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
11288
+ }
11289
+ };
11290
+
11284
11291
  assertNotHasOwnProperty(name, 'module');
11285
11292
  if (requires && modules.hasOwnProperty(name)) {
11286
11293
  modules[name] = null;
@@ -11593,11 +11600,11 @@ function setupModuleLoader(window) {
11593
11600
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11594
11601
  */
11595
11602
  var version = {
11596
- full: '1.2.0', // all of these placeholder strings will be replaced by grunt's
11603
+ full: '1.2.1', // all of these placeholder strings will be replaced by grunt's
11597
11604
  major: 1, // package task
11598
- minor: "NG_VERSION_MINOR",
11599
- dot: 0,
11600
- codeName: 'timely-delivery'
11605
+ minor: 2,
11606
+ dot: 1,
11607
+ codeName: 'underscore-empathy'
11601
11608
  };
11602
11609
 
11603
11610
 
@@ -14488,8 +14495,9 @@ function $TemplateCacheProvider() {
14488
14495
  * When there are multiple directives defined on a single DOM element, sometimes it
14489
14496
  * is necessary to specify the order in which the directives are applied. The `priority` is used
14490
14497
  * to sort the directives before their `compile` functions get called. Priority is defined as a
14491
- * number. Directives with greater numerical `priority` are compiled first. The order of directives with
14492
- * the same priority is undefined. The default priority is `0`.
14498
+ * number. Directives with greater numerical `priority` are compiled first. Pre-link functions
14499
+ * are also run in priority order, but post-link functions are run in reverse order. The order
14500
+ * of directives with the same priority is undefined. The default priority is `0`.
14493
14501
  *
14494
14502
  * #### `terminal`
14495
14503
  * If set to true then the current `priority` will be the last set of directives
@@ -14550,8 +14558,9 @@ function $TemplateCacheProvider() {
14550
14558
  * * `$scope` - Current scope associated with the element
14551
14559
  * * `$element` - Current element
14552
14560
  * * `$attrs` - Current attributes object for the element
14553
- * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
14554
- * `function(cloneLinkingFn)`.
14561
+ * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope.
14562
+ * The scope can be overridden by an optional first argument.
14563
+ * `function([scope], cloneLinkingFn)`.
14555
14564
  *
14556
14565
  *
14557
14566
  * #### `require`
@@ -14644,7 +14653,7 @@ function $TemplateCacheProvider() {
14644
14653
  * * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
14645
14654
  * between all directive compile functions.
14646
14655
  *
14647
- * * `transclude` - A transclude linking function: `function(scope, cloneLinkingFn)`.
14656
+ * * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
14648
14657
  *
14649
14658
  * <div class="alert alert-warning">
14650
14659
  * **Note:** The template instance and the link instance may be different objects if the template has
@@ -14653,6 +14662,12 @@ function $TemplateCacheProvider() {
14653
14662
  * should be done in a linking function rather than in a compile function.
14654
14663
  * </div>
14655
14664
  *
14665
+ * <div class="alert alert-error">
14666
+ * **Note:** The `transclude` function that is passed to the compile function is deperecated, as it
14667
+ * e.g. does not know about the right outer scope. Please use the transclude function that is passed
14668
+ * to the link function instead.
14669
+ * </div>
14670
+
14656
14671
  * A compile function can have a return value which can be either a function or an object.
14657
14672
  *
14658
14673
  * * returning a (post-link) function - is equivalent to registering the linking function via the
@@ -14667,7 +14682,7 @@ function $TemplateCacheProvider() {
14667
14682
  * This property is used only if the `compile` property is not defined.
14668
14683
  *
14669
14684
  * <pre>
14670
- * function link(scope, iElement, iAttrs, controller) { ... }
14685
+ * function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
14671
14686
  * </pre>
14672
14687
  *
14673
14688
  * The link function is responsible for registering DOM listeners as well as updating the DOM. It is
@@ -14688,6 +14703,10 @@ function $TemplateCacheProvider() {
14688
14703
  * element defines a controller. The controller is shared among all the directives, which allows
14689
14704
  * the directives to use the controllers as a communication channel.
14690
14705
  *
14706
+ * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
14707
+ * The scope can be overridden by an optional first argument. This is the same as the `$transclude`
14708
+ * parameter of directive controllers.
14709
+ * `function([scope], cloneLinkingFn)`.
14691
14710
  *
14692
14711
  *
14693
14712
  * #### Pre-linking function
@@ -15193,7 +15212,7 @@ function $CompileProvider($provide) {
15193
15212
  var compositeLinkFn =
15194
15213
  compileNodes($compileNodes, transcludeFn, $compileNodes,
15195
15214
  maxPriority, ignoreDirective, previousCompileContext);
15196
- return function publicLinkFn(scope, cloneConnectFn){
15215
+ return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
15197
15216
  assertArg(scope, 'scope');
15198
15217
  // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
15199
15218
  // and sometimes changes the structure of the DOM.
@@ -15201,6 +15220,10 @@ function $CompileProvider($provide) {
15201
15220
  ? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
15202
15221
  : $compileNodes;
15203
15222
 
15223
+ forEach(transcludeControllers, function(instance, name) {
15224
+ $linkNode.data('$' + name + 'Controller', instance);
15225
+ });
15226
+
15204
15227
  // Attach scope only to non-text nodes.
15205
15228
  for(var i = 0, ii = $linkNode.length; i<ii; i++) {
15206
15229
  var node = $linkNode[i];
@@ -15299,15 +15322,7 @@ function $CompileProvider($provide) {
15299
15322
  childTranscludeFn = nodeLinkFn.transclude;
15300
15323
  if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) {
15301
15324
  nodeLinkFn(childLinkFn, childScope, node, $rootElement,
15302
- (function(transcludeFn) {
15303
- return function(cloneFn) {
15304
- var transcludeScope = scope.$new();
15305
- transcludeScope.$$transcluded = true;
15306
-
15307
- return transcludeFn(transcludeScope, cloneFn).
15308
- on('$destroy', bind(transcludeScope, transcludeScope.$destroy));
15309
- };
15310
- })(childTranscludeFn || transcludeFn)
15325
+ createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn)
15311
15326
  );
15312
15327
  } else {
15313
15328
  nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn);
@@ -15319,6 +15334,23 @@ function $CompileProvider($provide) {
15319
15334
  }
15320
15335
  }
15321
15336
 
15337
+ function createBoundTranscludeFn(scope, transcludeFn) {
15338
+ return function boundTranscludeFn(transcludedScope, cloneFn, controllers) {
15339
+ var scopeCreated = false;
15340
+
15341
+ if (!transcludedScope) {
15342
+ transcludedScope = scope.$new();
15343
+ transcludedScope.$$transcluded = true;
15344
+ scopeCreated = true;
15345
+ }
15346
+
15347
+ var clone = transcludeFn(transcludedScope, cloneFn, controllers);
15348
+ if (scopeCreated) {
15349
+ clone.on('$destroy', bind(transcludedScope, transcludedScope.$destroy));
15350
+ }
15351
+ return clone;
15352
+ };
15353
+ }
15322
15354
 
15323
15355
  /**
15324
15356
  * Looks for directives on the given node and adds them to the directive collection which is
@@ -15456,9 +15488,9 @@ function $CompileProvider($provide) {
15456
15488
  * @returns {Function}
15457
15489
  */
15458
15490
  function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
15459
- return function(scope, element, attrs, controllers) {
15491
+ return function(scope, element, attrs, controllers, transcludeFn) {
15460
15492
  element = groupScan(element[0], attrStart, attrEnd);
15461
- return linkFn(scope, element, attrs, controllers);
15493
+ return linkFn(scope, element, attrs, controllers, transcludeFn);
15462
15494
  };
15463
15495
  }
15464
15496
 
@@ -15495,7 +15527,9 @@ function $CompileProvider($provide) {
15495
15527
  controllerDirectives = previousCompileContext.controllerDirectives,
15496
15528
  newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
15497
15529
  templateDirective = previousCompileContext.templateDirective,
15498
- transcludeDirective = previousCompileContext.transcludeDirective,
15530
+ nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
15531
+ hasTranscludeDirective = false,
15532
+ hasElementTranscludeDirective = false,
15499
15533
  $compileNode = templateAttrs.$$element = jqLite(compileNode),
15500
15534
  directive,
15501
15535
  directiveName,
@@ -15546,15 +15580,18 @@ function $CompileProvider($provide) {
15546
15580
  }
15547
15581
 
15548
15582
  if (directiveValue = directive.transclude) {
15583
+ hasTranscludeDirective = true;
15584
+
15549
15585
  // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
15550
15586
  // This option should only be used by directives that know how to how to safely handle element transclusion,
15551
15587
  // where the transcluded nodes are added or replaced after linking.
15552
15588
  if (!directive.$$tlb) {
15553
- assertNoDuplicate('transclusion', transcludeDirective, directive, $compileNode);
15554
- transcludeDirective = directive;
15589
+ assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
15590
+ nonTlbTranscludeDirective = directive;
15555
15591
  }
15556
15592
 
15557
15593
  if (directiveValue == 'element') {
15594
+ hasElementTranscludeDirective = true;
15558
15595
  terminalPriority = directive.priority;
15559
15596
  $template = groupScan(compileNode, attrStart, attrEnd);
15560
15597
  $compileNode = templateAttrs.$$element =
@@ -15570,9 +15607,9 @@ function $CompileProvider($provide) {
15570
15607
  // - newIsolateScopeDirective or templateDirective - combining templates with
15571
15608
  // element transclusion doesn't make sense.
15572
15609
  //
15573
- // We need only transcludeDirective so that we prevent putting transclusion
15610
+ // We need only nonTlbTranscludeDirective so that we prevent putting transclusion
15574
15611
  // on the same element more than once.
15575
- transcludeDirective: transcludeDirective
15612
+ nonTlbTranscludeDirective: nonTlbTranscludeDirective
15576
15613
  });
15577
15614
  } else {
15578
15615
  $template = jqLite(jqLiteClone(compileNode)).contents();
@@ -15641,7 +15678,7 @@ function $CompileProvider($provide) {
15641
15678
  controllerDirectives: controllerDirectives,
15642
15679
  newIsolateScopeDirective: newIsolateScopeDirective,
15643
15680
  templateDirective: templateDirective,
15644
- transcludeDirective: transcludeDirective
15681
+ nonTlbTranscludeDirective: nonTlbTranscludeDirective
15645
15682
  });
15646
15683
  ii = directives.length;
15647
15684
  } else if (directive.compile) {
@@ -15665,7 +15702,7 @@ function $CompileProvider($provide) {
15665
15702
  }
15666
15703
 
15667
15704
  nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
15668
- nodeLinkFn.transclude = transcludeDirective && childTranscludeFn;
15705
+ nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn;
15669
15706
 
15670
15707
  // might be normal or delayed nodeLinkFn depending on if templateUrl is present
15671
15708
  return nodeLinkFn;
@@ -15692,7 +15729,7 @@ function $CompileProvider($provide) {
15692
15729
  }
15693
15730
 
15694
15731
 
15695
- function getControllers(require, $element) {
15732
+ function getControllers(require, $element, elementControllers) {
15696
15733
  var value, retrievalMethod = 'data', optional = false;
15697
15734
  if (isString(require)) {
15698
15735
  while((value = require.charAt(0)) == '^' || value == '?') {
@@ -15702,13 +15739,12 @@ function $CompileProvider($provide) {
15702
15739
  }
15703
15740
  optional = optional || value == '?';
15704
15741
  }
15742
+ value = null;
15705
15743
 
15706
- value = $element[retrievalMethod]('$' + require + 'Controller');
15707
-
15708
- if ($element[0].nodeType == 8 && $element[0].$$controller) { // Transclusion comment node
15709
- value = value || $element[0].$$controller;
15710
- $element[0].$$controller = null;
15744
+ if (elementControllers && retrievalMethod === 'data') {
15745
+ value = elementControllers[require];
15711
15746
  }
15747
+ value = value || $element[retrievalMethod]('$' + require + 'Controller');
15712
15748
 
15713
15749
  if (!value && !optional) {
15714
15750
  throw $compileMinErr('ctreq',
@@ -15719,7 +15755,7 @@ function $CompileProvider($provide) {
15719
15755
  } else if (isArray(require)) {
15720
15756
  value = [];
15721
15757
  forEach(require, function(require) {
15722
- value.push(getControllers(require, $element));
15758
+ value.push(getControllers(require, $element, elementControllers));
15723
15759
  });
15724
15760
  }
15725
15761
  return value;
@@ -15727,7 +15763,7 @@ function $CompileProvider($provide) {
15727
15763
 
15728
15764
 
15729
15765
  function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
15730
- var attrs, $element, i, ii, linkFn, controller, isolateScope;
15766
+ var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn;
15731
15767
 
15732
15768
  if (compileNode === linkNode) {
15733
15769
  attrs = templateAttrs;
@@ -15821,14 +15857,14 @@ function $CompileProvider($provide) {
15821
15857
  }
15822
15858
  });
15823
15859
  }
15824
-
15860
+ transcludeFn = boundTranscludeFn && controllersBoundTransclude;
15825
15861
  if (controllerDirectives) {
15826
15862
  forEach(controllerDirectives, function(directive) {
15827
15863
  var locals = {
15828
15864
  $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
15829
15865
  $element: $element,
15830
15866
  $attrs: attrs,
15831
- $transclude: boundTranscludeFn
15867
+ $transclude: transcludeFn
15832
15868
  }, controllerInstance;
15833
15869
 
15834
15870
  controller = directive.controller;
@@ -15837,16 +15873,16 @@ function $CompileProvider($provide) {
15837
15873
  }
15838
15874
 
15839
15875
  controllerInstance = $controller(controller, locals);
15840
-
15841
- // Directives with element transclusion and a controller need to attach controller
15842
- // to the comment node created by the compiler, but jQuery .data doesn't support
15843
- // attaching data to comment nodes so instead we set it directly on the element and
15844
- // remove it after we read it later.
15845
- if ($element[0].nodeType == 8) { // Transclusion comment node
15846
- $element[0].$$controller = controllerInstance;
15847
- } else {
15876
+ // For directives with element transclusion the element is a comment,
15877
+ // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
15878
+ // clean up (http://bugs.jquery.com/ticket/8335).
15879
+ // Instead, we save the controllers for the element in a local hash and attach to .data
15880
+ // later, once we have the actual element.
15881
+ elementControllers[directive.name] = controllerInstance;
15882
+ if (!hasElementTranscludeDirective) {
15848
15883
  $element.data('$' + directive.name + 'Controller', controllerInstance);
15849
15884
  }
15885
+
15850
15886
  if (directive.controllerAs) {
15851
15887
  locals.$scope[directive.controllerAs] = controllerInstance;
15852
15888
  }
@@ -15858,7 +15894,7 @@ function $CompileProvider($provide) {
15858
15894
  try {
15859
15895
  linkFn = preLinkFns[i];
15860
15896
  linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
15861
- linkFn.require && getControllers(linkFn.require, $element));
15897
+ linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
15862
15898
  } catch (e) {
15863
15899
  $exceptionHandler(e, startingTag($element));
15864
15900
  }
@@ -15878,11 +15914,28 @@ function $CompileProvider($provide) {
15878
15914
  try {
15879
15915
  linkFn = postLinkFns[i];
15880
15916
  linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
15881
- linkFn.require && getControllers(linkFn.require, $element));
15917
+ linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
15882
15918
  } catch (e) {
15883
15919
  $exceptionHandler(e, startingTag($element));
15884
15920
  }
15885
15921
  }
15922
+
15923
+ // This is the function that is injected as `$transclude`.
15924
+ function controllersBoundTransclude(scope, cloneAttachFn) {
15925
+ var transcludeControllers;
15926
+
15927
+ // no scope passed
15928
+ if (arguments.length < 2) {
15929
+ cloneAttachFn = scope;
15930
+ scope = undefined;
15931
+ }
15932
+
15933
+ if (hasElementTranscludeDirective) {
15934
+ transcludeControllers = elementControllers;
15935
+ }
15936
+
15937
+ return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers);
15938
+ }
15886
15939
  }
15887
15940
  }
15888
15941
 
@@ -15961,6 +16014,7 @@ function $CompileProvider($provide) {
15961
16014
  dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
15962
16015
  } else if (key == 'style') {
15963
16016
  $element.attr('style', $element.attr('style') + ';' + value);
16017
+ dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
15964
16018
  // `dst` will never contain hasOwnProperty as DOM parser won't let it.
15965
16019
  // You will get an "InvalidCharacterError: DOM Exception 5" error if you
15966
16020
  // have an attribute like "has-own-property" or "data-has-own-property", etc.
@@ -15991,7 +16045,7 @@ function $CompileProvider($provide) {
15991
16045
 
15992
16046
  $http.get($sce.getTrustedResourceUrl(templateUrl), {cache: $templateCache}).
15993
16047
  success(function(content) {
15994
- var compileNode, tempTemplateAttrs, $template;
16048
+ var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
15995
16049
 
15996
16050
  content = denormalizeTemplate(content);
15997
16051
 
@@ -16036,7 +16090,7 @@ function $CompileProvider($provide) {
16036
16090
  var scope = linkQueue.shift(),
16037
16091
  beforeTemplateLinkNode = linkQueue.shift(),
16038
16092
  linkRootElement = linkQueue.shift(),
16039
- controller = linkQueue.shift(),
16093
+ boundTranscludeFn = linkQueue.shift(),
16040
16094
  linkNode = $compileNode[0];
16041
16095
 
16042
16096
  if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
@@ -16044,9 +16098,13 @@ function $CompileProvider($provide) {
16044
16098
  linkNode = jqLiteClone(compileNode);
16045
16099
  replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
16046
16100
  }
16047
-
16101
+ if (afterTemplateNodeLinkFn.transclude) {
16102
+ childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
16103
+ } else {
16104
+ childBoundTranscludeFn = boundTranscludeFn;
16105
+ }
16048
16106
  afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
16049
- controller);
16107
+ childBoundTranscludeFn);
16050
16108
  }
16051
16109
  linkQueue = null;
16052
16110
  }).
@@ -16054,14 +16112,14 @@ function $CompileProvider($provide) {
16054
16112
  throw $compileMinErr('tpload', 'Failed to load template: {0}', config.url);
16055
16113
  });
16056
16114
 
16057
- return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, controller) {
16115
+ return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
16058
16116
  if (linkQueue) {
16059
16117
  linkQueue.push(scope);
16060
16118
  linkQueue.push(node);
16061
16119
  linkQueue.push(rootElement);
16062
- linkQueue.push(controller);
16120
+ linkQueue.push(boundTranscludeFn);
16063
16121
  } else {
16064
- afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, controller);
16122
+ afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn);
16065
16123
  }
16066
16124
  };
16067
16125
  }
@@ -16766,9 +16824,11 @@ function $HttpProvider() {
16766
16824
  *
16767
16825
  * # Caching
16768
16826
  *
16769
- * To enable caching, set the configuration property `cache` to `true`. When the cache is
16770
- * enabled, `$http` stores the response from the server in local cache. Next time the
16771
- * response is served from the cache without sending a request to the server.
16827
+ * To enable caching, set the request configuration `cache` property to `true` (to use default
16828
+ * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).
16829
+ * When the cache is enabled, `$http` stores the response from the server in the specified
16830
+ * cache. The next time the same request is made, the response is served from the cache without
16831
+ * sending a request to the server.
16772
16832
  *
16773
16833
  * Note that even if the response is served from cache, delivery of the data is asynchronous in
16774
16834
  * the same way that real requests are.
@@ -16777,9 +16837,13 @@ function $HttpProvider() {
16777
16837
  * cache, but the cache is not populated yet, only one request to the server will be made and
16778
16838
  * the remaining requests will be fulfilled using the response from the first request.
16779
16839
  *
16780
- * A custom default cache built with $cacheFactory can be provided in $http.defaults.cache.
16781
- * To skip it, set configuration property `cache` to `false`.
16840
+ * You can change the default cache to a new object (built with
16841
+ * {@link ng.$cacheFactory `$cacheFactory`}) by updating the
16842
+ * {@link ng.$http#properties_defaults `$http.defaults.cache`} property. All requests who set
16843
+ * their `cache` property to `true` will now use this cache object.
16782
16844
  *
16845
+ * If you set the default cache to `false` then only requests that specify their own custom
16846
+ * cache object will be cached.
16783
16847
  *
16784
16848
  * # Interceptors
16785
16849
  *
@@ -18043,8 +18107,8 @@ function encodePath(path) {
18043
18107
  return segments.join('/');
18044
18108
  }
18045
18109
 
18046
- function parseAbsoluteUrl(absoluteUrl, locationObj) {
18047
- var parsedUrl = urlResolve(absoluteUrl);
18110
+ function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) {
18111
+ var parsedUrl = urlResolve(absoluteUrl, appBase);
18048
18112
 
18049
18113
  locationObj.$$protocol = parsedUrl.protocol;
18050
18114
  locationObj.$$host = parsedUrl.hostname;
@@ -18052,12 +18116,12 @@ function parseAbsoluteUrl(absoluteUrl, locationObj) {
18052
18116
  }
18053
18117
 
18054
18118
 
18055
- function parseAppUrl(relativeUrl, locationObj) {
18119
+ function parseAppUrl(relativeUrl, locationObj, appBase) {
18056
18120
  var prefixed = (relativeUrl.charAt(0) !== '/');
18057
18121
  if (prefixed) {
18058
18122
  relativeUrl = '/' + relativeUrl;
18059
18123
  }
18060
- var match = urlResolve(relativeUrl);
18124
+ var match = urlResolve(relativeUrl, appBase);
18061
18125
  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
18062
18126
  match.pathname.substring(1) : match.pathname);
18063
18127
  locationObj.$$search = parseKeyValue(match.search);
@@ -18112,7 +18176,7 @@ function LocationHtml5Url(appBase, basePrefix) {
18112
18176
  this.$$html5 = true;
18113
18177
  basePrefix = basePrefix || '';
18114
18178
  var appBaseNoFile = stripFile(appBase);
18115
- parseAbsoluteUrl(appBase, this);
18179
+ parseAbsoluteUrl(appBase, this, appBase);
18116
18180
 
18117
18181
 
18118
18182
  /**
@@ -18127,7 +18191,7 @@ function LocationHtml5Url(appBase, basePrefix) {
18127
18191
  appBaseNoFile);
18128
18192
  }
18129
18193
 
18130
- parseAppUrl(pathUrl, this);
18194
+ parseAppUrl(pathUrl, this, appBase);
18131
18195
 
18132
18196
  if (!this.$$path) {
18133
18197
  this.$$path = '/';
@@ -18179,7 +18243,7 @@ function LocationHtml5Url(appBase, basePrefix) {
18179
18243
  function LocationHashbangUrl(appBase, hashPrefix) {
18180
18244
  var appBaseNoFile = stripFile(appBase);
18181
18245
 
18182
- parseAbsoluteUrl(appBase, this);
18246
+ parseAbsoluteUrl(appBase, this, appBase);
18183
18247
 
18184
18248
 
18185
18249
  /**
@@ -18199,7 +18263,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
18199
18263
  throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url,
18200
18264
  hashPrefix);
18201
18265
  }
18202
- parseAppUrl(withoutHashUrl, this);
18266
+ parseAppUrl(withoutHashUrl, this, appBase);
18203
18267
  this.$$compose();
18204
18268
  };
18205
18269
 
@@ -18847,23 +18911,18 @@ var promiseWarning;
18847
18911
  // ------------------------------
18848
18912
  // Angular expressions are generally considered safe because these expressions only have direct
18849
18913
  // access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by
18850
- // obtaining a reference to native JS functions such as the Function constructor, the global Window
18851
- // or Document object. In addition, many powerful functions for use by JavaScript code are
18852
- // published on scope that shouldn't be available from within an Angular expression.
18914
+ // obtaining a reference to native JS functions such as the Function constructor.
18853
18915
  //
18854
18916
  // As an example, consider the following Angular expression:
18855
18917
  //
18856
18918
  // {}.toString.constructor(alert("evil JS code"))
18857
18919
  //
18858
18920
  // We want to prevent this type of access. For the sake of performance, during the lexing phase we
18859
- // disallow any "dotted" access to any member named "constructor" or to any member whose name begins
18860
- // or ends with an underscore. The latter allows one to exclude the private / JavaScript only API
18861
- // available on the scope and controllers from the context of an Angular expression.
18921
+ // disallow any "dotted" access to any member named "constructor".
18862
18922
  //
18863
- // For reflective calls (a[b]), we check that the value of the lookup is not the Function
18864
- // constructor, Window or DOM node while evaluating the expression, which is a stronger but more
18865
- // expensive test. Since reflective calls are expensive anyway, this is not such a big deal compared
18866
- // to static dereferencing.
18923
+ // For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor
18924
+ // while evaluating the expression, which is a stronger but more expensive test. Since reflective
18925
+ // calls are expensive anyway, this is not such a big deal compared to static dereferencing.
18867
18926
  //
18868
18927
  // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
18869
18928
  // against the expression language, but not to prevent exploits that were enabled by exposing
@@ -18877,20 +18936,12 @@ var promiseWarning;
18877
18936
  // In general, it is not possible to access a Window object from an angular expression unless a
18878
18937
  // window or some DOM object that has a reference to window is published onto a Scope.
18879
18938
 
18880
- function ensureSafeMemberName(name, fullExpression, allowConstructor) {
18881
- if (typeof name !== 'string' && toString.apply(name) !== "[object String]") {
18882
- return name;
18883
- }
18884
- if (name === "constructor" && !allowConstructor) {
18939
+ function ensureSafeMemberName(name, fullExpression) {
18940
+ if (name === "constructor") {
18885
18941
  throw $parseMinErr('isecfld',
18886
18942
  'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}',
18887
18943
  fullExpression);
18888
18944
  }
18889
- if (name.charAt(0) === '_' || name.charAt(name.length-1) === '_') {
18890
- throw $parseMinErr('isecprv',
18891
- 'Referencing private fields in Angular expressions is disallowed! Expression: {0}',
18892
- fullExpression);
18893
- }
18894
18945
  return name;
18895
18946
  }
18896
18947
 
@@ -19574,10 +19625,7 @@ Parser.prototype = {
19574
19625
 
19575
19626
  return extend(function(self, locals) {
19576
19627
  var o = obj(self, locals),
19577
- // In the getter, we will not block looking up "constructor" by name in order to support user defined
19578
- // constructors. However, if value looked up is the Function constructor, we will still block it in the
19579
- // ensureSafeObject call right after we look up o[i] (a few lines below.)
19580
- i = ensureSafeMemberName(indexFn(self, locals), parser.text, true /* allowConstructor */),
19628
+ i = indexFn(self, locals),
19581
19629
  v, p;
19582
19630
 
19583
19631
  if (!o) return undefined;
@@ -19593,7 +19641,7 @@ Parser.prototype = {
19593
19641
  return v;
19594
19642
  }, {
19595
19643
  assign: function(self, value, locals) {
19596
- var key = ensureSafeMemberName(indexFn(self, locals), parser.text);
19644
+ var key = indexFn(self, locals);
19597
19645
  // prevent overwriting of Function.constructor which would break ensureSafeObject check
19598
19646
  var safe = ensureSafeObject(obj(self, locals), parser.text);
19599
19647
  return safe[key] = value;
@@ -20253,7 +20301,7 @@ function $ParseProvider() {
20253
20301
  * // Propagate promise resolution to 'then' functions using $apply().
20254
20302
  * $rootScope.$apply();
20255
20303
  * expect(resolvedValue).toEqual(123);
20256
- * });
20304
+ * }));
20257
20305
  * </pre>
20258
20306
  */
20259
20307
  function $QProvider() {
@@ -22070,10 +22118,10 @@ function $SceDelegateProvider() {
22070
22118
  *
22071
22119
  * <pre class="prettyprint">
22072
22120
  * <input ng-model="userHtml">
22073
- * <div ng-bind-html="{{userHtml}}">
22121
+ * <div ng-bind-html="userHtml">
22074
22122
  * </pre>
22075
22123
  *
22076
- * Notice that `ng-bind-html` is bound to `{{userHtml}}` controlled by the user. With SCE
22124
+ * Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE
22077
22125
  * disabled, this application allows the user to render arbitrary HTML into the DIV.
22078
22126
  * In a more realistic example, one may be rendering user comments, blog articles, etc. via
22079
22127
  * bindings. (HTML is just one example of a context where rendering user controlled input creates
@@ -22994,8 +23042,14 @@ function $TimeoutProvider() {
22994
23042
  // exactly the behavior needed here. There is little value is mocking these out for this
22995
23043
  // service.
22996
23044
  var urlParsingNode = document.createElement("a");
23045
+ /*
23046
+ Matches paths for file protocol on windows,
23047
+ such as /C:/foo/bar, and captures only /foo/bar.
23048
+ */
23049
+ var windowsFilePathExp = /^\/?.*?:(\/.*)/;
22997
23050
  var originUrl = urlResolve(window.location.href, true);
22998
23051
 
23052
+
22999
23053
  /**
23000
23054
  *
23001
23055
  * Implementation Notes for non-IE browsers
@@ -23014,7 +23068,7 @@ var originUrl = urlResolve(window.location.href, true);
23014
23068
  * browsers. However, the parsed components will not be set if the URL assigned did not specify
23015
23069
  * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
23016
23070
  * work around that by performing the parsing in a 2nd step by taking a previously normalized
23017
- * URL (e.g. by assining to a.href) and assigning it a.href again. This correctly populates the
23071
+ * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the
23018
23072
  * properties such as protocol, hostname, port, etc.
23019
23073
  *
23020
23074
  * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one
@@ -23048,8 +23102,10 @@ var originUrl = urlResolve(window.location.href, true);
23048
23102
  * | pathname | The pathname, beginning with "/"
23049
23103
  *
23050
23104
  */
23051
- function urlResolve(url) {
23052
- var href = url;
23105
+ function urlResolve(url, base) {
23106
+ var href = url,
23107
+ pathname;
23108
+
23053
23109
  if (msie) {
23054
23110
  // Normalize before parse. Refer Implementation Notes on why this is
23055
23111
  // done in two steps on IE.
@@ -23059,7 +23115,22 @@ function urlResolve(url) {
23059
23115
 
23060
23116
  urlParsingNode.setAttribute('href', href);
23061
23117
 
23062
- // $$urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
23118
+ /*
23119
+ * In Windows, on an anchor node on documents loaded from
23120
+ * the filesystem, the browser will return a pathname
23121
+ * prefixed with the drive name ('/C:/path') when a
23122
+ * pathname without a drive is set:
23123
+ * * a.setAttribute('href', '/foo')
23124
+ * * a.pathname === '/C:/foo' //true
23125
+ *
23126
+ * Inside of Angular, we're always using pathnames that
23127
+ * do not include drive names for routing.
23128
+ */
23129
+
23130
+ pathname = removeWindowsDriveName(urlParsingNode.pathname, url, base);
23131
+ pathname = (pathname.charAt(0) === '/') ? pathname : '/' + pathname;
23132
+
23133
+ // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
23063
23134
  return {
23064
23135
  href: urlParsingNode.href,
23065
23136
  protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
@@ -23068,8 +23139,7 @@ function urlResolve(url) {
23068
23139
  hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
23069
23140
  hostname: urlParsingNode.hostname,
23070
23141
  port: urlParsingNode.port,
23071
- pathname: urlParsingNode.pathname && urlParsingNode.pathname.charAt(0) === '/' ?
23072
- urlParsingNode.pathname : '/' + urlParsingNode.pathname
23142
+ pathname: pathname
23073
23143
  };
23074
23144
  }
23075
23145
 
@@ -23087,6 +23157,26 @@ function urlIsSameOrigin(requestUrl) {
23087
23157
  parsed.host === originUrl.host);
23088
23158
  }
23089
23159
 
23160
+ function removeWindowsDriveName (path, url, base) {
23161
+ var firstPathSegmentMatch;
23162
+
23163
+ //Get the relative path from the input URL.
23164
+ if (url.indexOf(base) === 0) {
23165
+ url = url.replace(base, '');
23166
+ }
23167
+
23168
+ /*
23169
+ * The input URL intentionally contains a
23170
+ * first path segment that ends with a colon.
23171
+ */
23172
+ if (windowsFilePathExp.exec(url)) {
23173
+ return path;
23174
+ }
23175
+
23176
+ firstPathSegmentMatch = windowsFilePathExp.exec(path);
23177
+ return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
23178
+ }
23179
+
23090
23180
  /**
23091
23181
  * @ngdoc object
23092
23182
  * @name ng.$window
@@ -24603,7 +24693,7 @@ var nullFormCtrl = {
24603
24693
  * @property {Object} $error Is an object hash, containing references to all invalid controls or
24604
24694
  * forms, where:
24605
24695
  *
24606
- * - keys are validation tokens (error names) — such as `required`, `url` or `email`),
24696
+ * - keys are validation tokens (error names) — such as `required`, `url` or `email`,
24607
24697
  * - values are arrays of controls or forms that are invalid with given error.
24608
24698
  *
24609
24699
  * @description
@@ -25788,6 +25878,11 @@ var VALID_CLASS = 'ng-valid',
25788
25878
  * }
25789
25879
  * ngModel.$formatters.push(formatter);
25790
25880
  * </pre>
25881
+ *
25882
+ * @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
25883
+ * view value has changed. It is called with no arguments, and its return value is ignored.
25884
+ * This can be used in place of additional $watches against the model value.
25885
+ *
25791
25886
  * @property {Object} $error An object hash with all errors as keys.
25792
25887
  *
25793
25888
  * @property {boolean} $pristine True if user has not interacted with the control yet.
@@ -26051,14 +26146,19 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
26051
26146
  * @methodOf ng.directive:ngModel.NgModelController
26052
26147
  *
26053
26148
  * @description
26054
- * Read a value from view.
26149
+ * Update the view value.
26055
26150
  *
26056
- * This method should be called from within a DOM event handler.
26057
- * For example {@link ng.directive:input input} or
26151
+ * This method should be called when the view value changes, typically from within a DOM event handler.
26152
+ * For example {@link ng.directive:input input} and
26058
26153
  * {@link ng.directive:select select} directives call it.
26059
26154
  *
26060
- * It internally calls all `$parsers` (including validators) and updates the `$modelValue` and the actual model path.
26061
- * Lastly it calls all registered change listeners.
26155
+ * It will update the $viewValue, then pass this value through each of the functions in `$parsers`,
26156
+ * which includes any validators. The value that comes out of this `$parsers` pipeline, be applied to
26157
+ * `$modelValue` and the **expression** specified in the `ng-model` attribute.
26158
+ *
26159
+ * Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
26160
+ *
26161
+ * Note that calling this function does not trigger a `$digest`.
26062
26162
  *
26063
26163
  * @param {string} value Value from the view.
26064
26164
  */
@@ -26560,27 +26660,33 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
26560
26660
  * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
26561
26661
  *
26562
26662
  * @example
26563
- * Try it here: enter text in text box and watch the greeting change.
26564
- <doc:example module="ngBindHtmlExample" deps="angular-sanitize.js" >
26565
- <doc:source>
26566
- <script>
26567
- angular.module('ngBindHtmlExample', ['ngSanitize'])
26568
-
26569
- .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
26570
- $scope.myHTML = 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
26571
- }]);
26572
- </script>
26663
+ Try it here: enter text in text box and watch the greeting change.
26664
+
26665
+ <example module="ngBindHtmlExample" deps="angular-sanitize.js">
26666
+ <file name="index.html">
26573
26667
  <div ng-controller="ngBindHtmlCtrl">
26574
26668
  <p ng-bind-html="myHTML"></p>
26575
26669
  </div>
26576
- </doc:source>
26577
- <doc:scenario>
26670
+ </file>
26671
+
26672
+ <file name="script.js">
26673
+ angular.module('ngBindHtmlExample', ['ngSanitize'])
26674
+
26675
+ .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
26676
+ $scope.myHTML =
26677
+ 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
26678
+ }]);
26679
+ </file>
26680
+
26681
+ <file name="scenario.js">
26578
26682
  it('should check ng-bind-html', function() {
26579
26683
  expect(using('.doc-example-live').binding('myHTML')).
26580
- toBe('I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>');
26684
+ toBe(
26685
+ 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
26686
+ );
26581
26687
  });
26582
- </doc:scenario>
26583
- </doc:example>
26688
+ </file>
26689
+ </example>
26584
26690
  */
26585
26691
  var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) {
26586
26692
  return function(scope, element, attr) {
@@ -26693,18 +26799,18 @@ function classDirective(name, selector) {
26693
26799
  * @example Example that demonstrates basic bindings via ngClass directive.
26694
26800
  <example>
26695
26801
  <file name="index.html">
26696
- <p ng-class="{strike: strike, bold: bold, red: red}">Map Syntax Example</p>
26697
- <input type="checkbox" ng-model="bold"> bold
26698
- <input type="checkbox" ng-model="strike"> strike
26699
- <input type="checkbox" ng-model="red"> red
26802
+ <p ng-class="{strike: deleted, bold: important, red: error}">Map Syntax Example</p>
26803
+ <input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)<br>
26804
+ <input type="checkbox" ng-model="important"> important (apply "bold" class)<br>
26805
+ <input type="checkbox" ng-model="error"> error (apply "red" class)
26700
26806
  <hr>
26701
26807
  <p ng-class="style">Using String Syntax</p>
26702
26808
  <input type="text" ng-model="style" placeholder="Type: bold strike red">
26703
26809
  <hr>
26704
26810
  <p ng-class="[style1, style2, style3]">Using Array Syntax</p>
26705
- <input ng-model="style1" placeholder="Type: bold"><br>
26706
- <input ng-model="style2" placeholder="Type: strike"><br>
26707
- <input ng-model="style3" placeholder="Type: red"><br>
26811
+ <input ng-model="style1" placeholder="Type: bold, strike or red"><br>
26812
+ <input ng-model="style2" placeholder="Type: bold, strike or red"><br>
26813
+ <input ng-model="style3" placeholder="Type: bold, strike or red"><br>
26708
26814
  </file>
26709
26815
  <file name="style.css">
26710
26816
  .strike {
@@ -26723,10 +26829,10 @@ function classDirective(name, selector) {
26723
26829
  expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
26724
26830
  expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);
26725
26831
 
26726
- input('bold').check();
26832
+ input('important').check();
26727
26833
  expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);
26728
26834
 
26729
- input('red').check();
26835
+ input('error').check();
26730
26836
  expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
26731
26837
  });
26732
26838
 
@@ -27572,7 +27678,7 @@ forEach(
27572
27678
  }
27573
27679
 
27574
27680
  /&#42;
27575
- The transition styles can also be placed on the CSS base class above
27681
+ The transition styles can also be placed on the CSS base class above
27576
27682
  &#42;/
27577
27683
  .animate-if.ng-enter, .animate-if.ng-leave {
27578
27684
  -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
@@ -27598,22 +27704,21 @@ var ngIfDirective = ['$animate', function($animate) {
27598
27704
  terminal: true,
27599
27705
  restrict: 'A',
27600
27706
  $$tlb: true,
27601
- compile: function (element, attr, transclude) {
27602
- return function ($scope, $element, $attr) {
27707
+ link: function ($scope, $element, $attr, ctrl, $transclude) {
27603
27708
  var block, childScope;
27604
27709
  $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
27605
27710
 
27606
27711
  if (toBoolean(value)) {
27607
-
27608
- childScope = $scope.$new();
27609
- transclude(childScope, function (clone) {
27610
- block = {
27611
- startNode: clone[0],
27612
- endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ')
27613
- };
27614
- $animate.enter(clone, $element.parent(), $element);
27615
- });
27616
-
27712
+ if (!childScope) {
27713
+ childScope = $scope.$new();
27714
+ $transclude(childScope, function (clone) {
27715
+ block = {
27716
+ startNode: clone[0],
27717
+ endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ')
27718
+ };
27719
+ $animate.enter(clone, $element.parent(), $element);
27720
+ });
27721
+ }
27617
27722
  } else {
27618
27723
 
27619
27724
  if (childScope) {
@@ -27627,7 +27732,6 @@ var ngIfDirective = ['$animate', function($animate) {
27627
27732
  }
27628
27733
  }
27629
27734
  });
27630
- };
27631
27735
  }
27632
27736
  };
27633
27737
  }];
@@ -27786,12 +27890,12 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
27786
27890
  priority: 400,
27787
27891
  terminal: true,
27788
27892
  transclude: 'element',
27789
- compile: function(element, attr, transclusion) {
27893
+ compile: function(element, attr) {
27790
27894
  var srcExp = attr.ngInclude || attr.src,
27791
27895
  onloadExp = attr.onload || '',
27792
27896
  autoScrollExp = attr.autoscroll;
27793
27897
 
27794
- return function(scope, $element) {
27898
+ return function(scope, $element, $attr, ctrl, $transclude) {
27795
27899
  var changeCounter = 0,
27796
27900
  currentScope,
27797
27901
  currentElement;
@@ -27820,7 +27924,7 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
27820
27924
  if (thisChangeId !== changeCounter) return;
27821
27925
  var newScope = scope.$new();
27822
27926
 
27823
- transclusion(newScope, function(clone) {
27927
+ $transclude(newScope, function(clone) {
27824
27928
  cleanupLastIncludeContent();
27825
27929
 
27826
27930
  currentScope = newScope;
@@ -28349,8 +28453,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
28349
28453
  priority: 1000,
28350
28454
  terminal: true,
28351
28455
  $$tlb: true,
28352
- compile: function(element, attr, linker) {
28353
- return function($scope, $element, $attr){
28456
+ link: function($scope, $element, $attr, ctrl, $transclude){
28354
28457
  var expression = $attr.ngRepeat;
28355
28458
  var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
28356
28459
  trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
@@ -28512,7 +28615,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
28512
28615
  // jshint bitwise: true
28513
28616
 
28514
28617
  if (!block.startNode) {
28515
- linker(childScope, function(clone) {
28618
+ $transclude(childScope, function(clone) {
28516
28619
  clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' ');
28517
28620
  $animate.enter(clone, null, jqLite(previousNode));
28518
28621
  previousNode = clone;
@@ -28525,7 +28628,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
28525
28628
  }
28526
28629
  lastBlockMap = nextBlockMap;
28527
28630
  });
28528
- };
28529
28631
  }
28530
28632
  };
28531
28633
  }];
@@ -29034,10 +29136,10 @@ var ngSwitchWhenDirective = ngDirective({
29034
29136
  transclude: 'element',
29035
29137
  priority: 800,
29036
29138
  require: '^ngSwitch',
29037
- compile: function(element, attrs, transclude) {
29038
- return function(scope, element, attr, ctrl) {
29139
+ compile: function(element, attrs) {
29140
+ return function(scope, element, attr, ctrl, $transclude) {
29039
29141
  ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
29040
- ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: transclude, element: element });
29142
+ ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
29041
29143
  };
29042
29144
  }
29043
29145
  });
@@ -29046,12 +29148,10 @@ var ngSwitchDefaultDirective = ngDirective({
29046
29148
  transclude: 'element',
29047
29149
  priority: 800,
29048
29150
  require: '^ngSwitch',
29049
- compile: function(element, attrs, transclude) {
29050
- return function(scope, element, attr, ctrl) {
29051
- ctrl.cases['?'] = (ctrl.cases['?'] || []);
29052
- ctrl.cases['?'].push({ transclude: transclude, element: element });
29053
- };
29054
- }
29151
+ link: function(scope, element, attr, ctrl, $transclude) {
29152
+ ctrl.cases['?'] = (ctrl.cases['?'] || []);
29153
+ ctrl.cases['?'].push({ transclude: $transclude, element: element });
29154
+ }
29055
29155
  });
29056
29156
 
29057
29157
  /**