angularjs-rails 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  /**