+ * **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.
+ * They must use {@link ng.directive:ngApp ngApp}.
+ *
+ *
+ *
+ * **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},
+ * such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
+ * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
+ * causing animations to stop working and making the injector inaccessible from outside the app.
+ *
+ *
* ```html
*
*
@@ -2424,11 +2443,11 @@ function toDebugString(obj) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.5.0', // all of these placeholder strings will be replaced by grunt's
+ full: '1.5.2', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 5,
- dot: 0,
- codeName: 'ennoblement-facilitation'
+ dot: 2,
+ codeName: 'differential-recovery'
};
@@ -4287,14 +4306,13 @@ function annotate(fn, strictDi, name) {
* @description
*
* Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
- * number, an array, an object or a function. This is short for registering a service where its
+ * number, an array, an object or a function. This is short for registering a service where its
* provider's `$get` property is a factory function that takes no arguments and returns the **value
- * service**.
+ * service**. That also means it is not possible to inject other services into a value service.
*
* Value services are similar to constant services, except that they cannot be injected into a
* module configuration function (see {@link angular.Module#config}) but they can be overridden by
- * an Angular
- * {@link auto.$provide#decorator decorator}.
+ * an Angular {@link auto.$provide#decorator decorator}.
*
* @param {string} name The name of the instance.
* @param {*} value The value.
@@ -4319,8 +4337,11 @@ function annotate(fn, strictDi, name) {
* @name $provide#constant
* @description
*
- * Register a **constant service**, such as a string, a number, an array, an object or a function,
- * with the {@link auto.$injector $injector}. Unlike {@link auto.$provide#value value} it can be
+ * Register a **constant service** with the {@link auto.$injector $injector}, such as a string,
+ * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not
+ * possible to inject other services into a constant.
+ *
+ * But unlike {@link auto.$provide#value value}, a constant can be
* injected into a module configuration function (see {@link angular.Module#config}) and it cannot
* be overridden by an Angular {@link auto.$provide#decorator decorator}.
*
@@ -4959,7 +4980,7 @@ function prepareAnimateOptions(options) {
}
var $$CoreAnimateJsProvider = function() {
- this.$get = function() {};
+ this.$get = noop;
};
// this is prefixed with Core since it conflicts with
@@ -5779,7 +5800,6 @@ var $CoreAnimateCssProvider = function() {
*/
function Browser(window, document, $log, $sniffer) {
var self = this,
- rawDocument = document[0],
location = window.location,
history = window.history,
setTimeout = window.setTimeout,
@@ -7367,6 +7387,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// The assumption is that future DOM event attribute names will begin with
// 'on' and be composed of only English letters.
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
+ var bindingCache = createMap();
function parseIsolateBindings(scope, directiveName, isController) {
var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;
@@ -7374,6 +7395,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
var bindings = {};
forEach(scope, function(definition, scopeName) {
+ if (definition in bindingCache) {
+ bindings[scopeName] = bindingCache[definition];
+ return;
+ }
var match = definition.match(LOCAL_REGEXP);
if (!match) {
@@ -7391,6 +7416,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
optional: match[3] === '?',
attrName: match[4] || scopeName
};
+ if (match[4]) {
+ bindingCache[definition] = bindings[scopeName];
+ }
});
return bindings;
@@ -7460,7 +7488,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* {@link guide/directive directive guide} and the {@link $compile compile API} for more info.
* @returns {ng.$compileProvider} Self for chaining.
*/
- this.directive = function registerDirective(name, directiveFactory) {
+ this.directive = function registerDirective(name, directiveFactory) {
assertNotHasOwnProperty(name, 'directive');
if (isString(name)) {
assertValidDirectiveName(name);
@@ -7483,11 +7511,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
directive.name = directive.name || name;
directive.require = directive.require || (directive.controller && directive.name);
directive.restrict = directive.restrict || 'EA';
- var bindings = directive.$$bindings =
- parseDirectiveBindings(directive, directive.name);
- if (isObject(bindings.isolateScope)) {
- directive.$$isolateBindings = bindings.isolateScope;
- }
directive.$$moduleName = directiveFactory.$$moduleName;
directives.push(directive);
} catch (e) {
@@ -7543,7 +7566,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* See {@link ng.$compile#-bindtocontroller- `bindToController`}.
* - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.
* Disabled by default.
- * - `$...` – `{function()=}` – additional annotations to provide to the directive factory function.
+ * - `$...` – additional properties to attach to the directive factory function and the controller
+ * constructor function. (This is used by the component router to annotate)
*
* @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.
* @description
@@ -7575,7 +7599,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
*
* myMod.component('myComp', {
* templateUrl: 'views/my-comp.html',
- * controller: 'MyCtrl as ctrl',
+ * controller: 'MyCtrl',
+ * controllerAs: 'ctrl',
* bindings: {name: '@'}
* });
*
@@ -7586,7 +7611,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* See also {@link ng.$compileProvider#directive $compileProvider.directive()}.
*/
this.component = function registerComponent(name, options) {
- var controller = options.controller || function() {};
+ var controller = options.controller || noop;
function factory($injector) {
function makeInjectable(fn) {
@@ -7618,6 +7643,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
forEach(options, function(val, key) {
if (key.charAt(0) === '$') {
factory[key] = val;
+ controller[key] = val;
}
});
@@ -7725,7 +7751,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
var SIMPLE_ATTR_NAME = /^\w/;
var specialAttrHolder = document.createElement('div');
- var Attributes = function(element, attributesToCopy) {
+ function Attributes(element, attributesToCopy) {
if (attributesToCopy) {
var keys = Object.keys(attributesToCopy);
var i, l, key;
@@ -7739,7 +7765,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
this.$$element = element;
- };
+ }
Attributes.prototype = {
/**
@@ -8020,6 +8046,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');
} : noop;
+ compile.$$createComment = function(directiveName, comment) {
+ var content = '';
+ if (debugInfoEnabled) {
+ content = ' ' + (directiveName || '') + ': ' + (comment || '') + ' ';
+ }
+ return document.createComment(content);
+ };
+
return compile;
//================================
@@ -8233,8 +8267,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
-
- var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
+ function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
if (!transcludedScope) {
transcludedScope = scope.$new(false, containingScope);
@@ -8246,7 +8279,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
transcludeControllers: controllers,
futureParentElement: futureParentElement
});
- };
+ }
// We need to attach the transclusion slots onto the `boundTranscludeFn`
// so that they are available inside the `controllersBoundTransclude` function
@@ -8411,7 +8444,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* @returns {Function}
*/
function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
- return function(scope, element, attrs, controllers, transcludeFn) {
+ return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {
element = groupScan(element[0], attrStart, attrEnd);
return linkFn(scope, element, attrs, controllers, transcludeFn);
};
@@ -8429,23 +8462,21 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
* @returns {Function}
*/
function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
- if (eager) {
- return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
- }
+ var compiled;
- var compiled;
-
- return function() {
- if (!compiled) {
- compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
-
- // Null out all of these references in order to make them eligible for garbage collection
- // since this is a potentially long lived closure
- $compileNodes = transcludeFn = previousCompileContext = null;
- }
+ if (eager) {
+ return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
+ }
+ return function lazyCompilation() {
+ if (!compiled) {
+ compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
- return compiled.apply(this, arguments);
- };
+ // Null out all of these references in order to make them eligible for garbage collection
+ // since this is a potentially long lived closure
+ $compileNodes = transcludeFn = previousCompileContext = null;
+ }
+ return compiled.apply(this, arguments);
+ };
}
/**
@@ -8581,8 +8612,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
terminalPriority = directive.priority;
$template = $compileNode;
$compileNode = templateAttrs.$$element =
- jqLite(document.createComment(' ' + directiveName + ': ' +
- templateAttrs[directiveName] + ' '));
+ jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));
compileNode = $compileNode[0];
replaceWith(jqCollection, sliceArgs($template), compileNode);
@@ -8788,82 +8818,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
}
-
- function getControllers(directiveName, require, $element, elementControllers) {
- var value;
-
- if (isString(require)) {
- var match = require.match(REQUIRE_PREFIX_REGEXP);
- var name = require.substring(match[0].length);
- var inheritType = match[1] || match[3];
- var optional = match[2] === '?';
-
- //If only parents then start at the parent element
- if (inheritType === '^^') {
- $element = $element.parent();
- //Otherwise attempt getting the controller from elementControllers in case
- //the element is transcluded (and has no data) and to avoid .data if possible
- } else {
- value = elementControllers && elementControllers[name];
- value = value && value.instance;
- }
-
- if (!value) {
- var dataName = '$' + name + 'Controller';
- value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
- }
-
- if (!value && !optional) {
- throw $compileMinErr('ctreq',
- "Controller '{0}', required by directive '{1}', can't be found!",
- name, directiveName);
- }
- } else if (isArray(require)) {
- value = [];
- for (var i = 0, ii = require.length; i < ii; i++) {
- value[i] = getControllers(directiveName, require[i], $element, elementControllers);
- }
- } else if (isObject(require)) {
- value = {};
- forEach(require, function(controller, property) {
- value[property] = getControllers(directiveName, controller, $element, elementControllers);
- });
- }
-
- return value || null;
- }
-
- function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) {
- var elementControllers = createMap();
- for (var controllerKey in controllerDirectives) {
- var directive = controllerDirectives[controllerKey];
- var locals = {
- $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
- $element: $element,
- $attrs: attrs,
- $transclude: transcludeFn
- };
-
- var controller = directive.controller;
- if (controller == '@') {
- controller = attrs[directive.name];
- }
-
- var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
-
- // For directives with element transclusion the element is a comment,
- // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
- // clean up (http://bugs.jquery.com/ticket/8335).
- // Instead, we save the controllers for the element in a local hash and attach to .data
- // later, once we have the actual element.
- elementControllers[directive.name] = controllerInstance;
- if (!hasElementTranscludeDirective) {
- $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
- }
- }
- return elementControllers;
- }
-
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
attrs, removeScopeBindingWatches, removeControllerBindingWatches;
@@ -8895,7 +8849,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
if (controllerDirectives) {
- elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope);
+ elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);
}
if (newIsolateScopeDirective) {
@@ -9023,6 +8977,78 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
}
+ function getControllers(directiveName, require, $element, elementControllers) {
+ var value;
+
+ if (isString(require)) {
+ var match = require.match(REQUIRE_PREFIX_REGEXP);
+ var name = require.substring(match[0].length);
+ var inheritType = match[1] || match[3];
+ var optional = match[2] === '?';
+
+ //If only parents then start at the parent element
+ if (inheritType === '^^') {
+ $element = $element.parent();
+ //Otherwise attempt getting the controller from elementControllers in case
+ //the element is transcluded (and has no data) and to avoid .data if possible
+ } else {
+ value = elementControllers && elementControllers[name];
+ value = value && value.instance;
+ }
+
+ if (!value) {
+ var dataName = '$' + name + 'Controller';
+ value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
+ }
+
+ if (!value && !optional) {
+ throw $compileMinErr('ctreq',
+ "Controller '{0}', required by directive '{1}', can't be found!",
+ name, directiveName);
+ }
+ } else if (isArray(require)) {
+ value = [];
+ for (var i = 0, ii = require.length; i < ii; i++) {
+ value[i] = getControllers(directiveName, require[i], $element, elementControllers);
+ }
+ } else if (isObject(require)) {
+ value = {};
+ forEach(require, function(controller, property) {
+ value[property] = getControllers(directiveName, controller, $element, elementControllers);
+ });
+ }
+
+ return value || null;
+ }
+
+ function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {
+ var elementControllers = createMap();
+ for (var controllerKey in controllerDirectives) {
+ var directive = controllerDirectives[controllerKey];
+ var locals = {
+ $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
+ $element: $element,
+ $attrs: attrs,
+ $transclude: transcludeFn
+ };
+
+ var controller = directive.controller;
+ if (controller == '@') {
+ controller = attrs[directive.name];
+ }
+
+ var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
+
+ // For directives with element transclusion the element is a comment.
+ // In this case .data will not attach any data.
+ // Instead, we save the controllers for the element in a local hash and attach to .data
+ // later, once we have the actual element.
+ elementControllers[directive.name] = controllerInstance;
+ $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
+ }
+ return elementControllers;
+ }
+
// Depending upon the context in which a directive finds itself it might need to have a new isolated
// or child scope created. For instance:
// * if the directive has been pulled into a template because another directive with a higher priority
@@ -9063,6 +9089,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
if (startAttrName) {
directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
}
+ if (!directive.$$bindings) {
+ var bindings = directive.$$bindings =
+ parseDirectiveBindings(directive, directive.name);
+ if (isObject(bindings.isolateScope)) {
+ directive.$$isolateBindings = bindings.isolateScope;
+ }
+ }
tDirectives.push(directive);
match = directive;
}
@@ -9500,7 +9533,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// only occurs for isolate scopes and new scopes with controllerAs.
function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {
var removeWatchCollection = [];
- forEach(bindings, function(definition, scopeName) {
+ forEach(bindings, function initializeBinding(definition, scopeName) {
var attrName = definition.attrName,
optional = definition.optional,
mode = definition.mode, // @, =, or &
@@ -9542,7 +9575,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
if (parentGet.literal) {
compare = equals;
} else {
- compare = function(a, b) { return a === b || (a !== a && b !== b); };
+ compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); };
}
parentSet = parentGet.assign || function() {
// reset the change, or we will throw this exception on every $digest
@@ -9744,6 +9777,15 @@ function $ControllerProvider() {
var controllers = {},
globals = false;
+ /**
+ * @ngdoc method
+ * @name $controllerProvider#has
+ * @param {string} name Controller name to check.
+ */
+ this.has = function(name) {
+ return controllers.hasOwnProperty(name);
+ };
+
/**
* @ngdoc method
* @name $controllerProvider#register
@@ -9800,7 +9842,7 @@ function $ControllerProvider() {
* It's just a simple call to {@link auto.$injector $injector}, but extracted into
* a service, so that one can override this service with [BC version](https://gist.github.com/1649788).
*/
- return function(expression, locals, later, ident) {
+ return function $controller(expression, locals, later, ident) {
// PRIVATE API:
// param `later` --- indicates that the controller's constructor is invoked at a later time.
// If true, $controller will allocate the object with the correct
@@ -9851,7 +9893,7 @@ function $ControllerProvider() {
}
var instantiate;
- return instantiate = extend(function() {
+ return instantiate = extend(function $controllerInit() {
var result = $injector.invoke(expression, instance, locals, constructor);
if (result !== instance && (isObject(result) || isFunction(result))) {
instance = result;
@@ -10037,7 +10079,7 @@ function $HttpParamSerializerProvider() {
forEachSorted(params, function(value, key) {
if (value === null || isUndefined(value)) return;
if (isArray(value)) {
- forEach(value, function(v, k) {
+ forEach(value, function(v) {
parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v)));
});
} else {
@@ -10247,10 +10289,9 @@ function $HttpProvider() {
*
* Object containing default values for all {@link ng.$http $http} requests.
*
- * - **`defaults.cache`** - {Object} - an object built with {@link ng.$cacheFactory `$cacheFactory`}
- * that will provide the cache for all requests who set their `cache` property to `true`.
- * If you set the `defaults.cache = false` then only requests that specify their own custom
- * cache object will be cached. See {@link $http#caching $http Caching} for more information.
+ * - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with
+ * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses
+ * by default. See {@link $http#caching $http Caching} for more information.
*
* - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
* Defaults value is `'XSRF-TOKEN'`.
@@ -10541,6 +10582,15 @@ function $HttpProvider() {
* the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,
* which allows you to `push` or `unshift` a new transformation function into the transformation chain.
*
+ *
+ * **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.
+ * That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).
+ * For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest
+ * function will be reflected on the scope and in any templates where the object is data-bound.
+ * To prevent his, transform functions should have no side-effects.
+ * If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.
+ *
+ *
* ### Default Transformations
*
* The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and
@@ -10598,26 +10648,35 @@ function $HttpProvider() {
*
* ## Caching
*
- * To enable caching, set the request configuration `cache` property to `true` (to use default
- * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).
- * When the cache is enabled, `$http` stores the response from the server in the specified
- * cache. The next time the same request is made, the response is served from the cache without
- * sending a request to the server.
+ * {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must
+ * set the config.cache value or the default cache value to TRUE or to a cache object (created
+ * with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes
+ * precedence over the default cache value.
+ *
+ * In order to:
+ * * cache all responses - set the default cache value to TRUE or to a cache object
+ * * cache a specific response - set config.cache value to TRUE or to a cache object
+ *
+ * If caching is enabled, but neither the default cache nor config.cache are set to a cache object,
+ * then the default `$cacheFactory($http)` object is used.
*
- * Note that even if the response is served from cache, delivery of the data is asynchronous in
- * the same way that real requests are.
+ * The default cache value can be set by updating the
+ * {@link ng.$http#defaults `$http.defaults.cache`} property or the
+ * {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.
*
- * If there are multiple GET requests for the same URL that should be cached using the same
- * cache, but the cache is not populated yet, only one request to the server will be made and
- * the remaining requests will be fulfilled using the response from the first request.
+ * When caching is enabled, {@link ng.$http `$http`} stores the response from the server using
+ * the relevant cache object. The next time the same request is made, the response is returned
+ * from the cache without sending a request to the server.
*
- * You can change the default cache to a new object (built with
- * {@link ng.$cacheFactory `$cacheFactory`}) by updating the
- * {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set
- * their `cache` property to `true` will now use this cache object.
+ * Take note that:
+ *
+ * * Only GET and JSONP requests are cached.
+ * * The cache key is the request URL including search parameters; headers are not considered.
+ * * Cached responses are returned asynchronously, in the same way as responses from the server.
+ * * If multiple identical requests are made using the same cache, which is not yet populated,
+ * one request will be made to the server and remaining requests will return the same response.
+ * * A cache-control header on the response does not affect if or how responses are cached.
*
- * If you set the default cache to `false` then only requests that specify their own custom
- * cache object will be cached.
*
* ## Interceptors
*
@@ -10787,7 +10846,7 @@ function $HttpProvider() {
* transform function or an array of such functions. The transform function takes the http
* response body, headers and status and returns its transformed (typically deserialized) version.
* See {@link ng.$http#overriding-the-default-transformations-per-request
- * Overriding the Default TransformationjqLiks}
+ * Overriding the Default Transformations}
* - **paramSerializer** - `{string|function(Object):string}` - A function used to
* prepare the string representation of request parameters (specified as an object).
* If specified as string, it is interpreted as function registered with the
@@ -10795,10 +10854,9 @@ function $HttpProvider() {
* by registering it as a {@link auto.$provide#service service}.
* The default serializer is the {@link $httpParamSerializer $httpParamSerializer};
* alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}
- * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
- * GET request, otherwise if a cache instance built with
- * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
- * caching.
+ * - **cache** – `{boolean|Object}` – A boolean value or object created with
+ * {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
+ * See {@link $http#caching $http Caching} for more information.
* - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
* that should abort the request when resolved.
* - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
@@ -13709,8 +13767,10 @@ AST.prototype = {
primary = this.arrayDeclaration();
} else if (this.expect('{')) {
primary = this.object();
- } else if (this.constants.hasOwnProperty(this.peek().text)) {
- primary = copy(this.constants[this.consume().text]);
+ } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {
+ primary = copy(this.selfReferential[this.consume().text]);
+ } else if (this.options.literals.hasOwnProperty(this.peek().text)) {
+ primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};
} else if (this.peek().identifier) {
primary = this.identifier();
} else if (this.peek().constant) {
@@ -13862,15 +13922,7 @@ AST.prototype = {
return false;
},
-
- /* `undefined` is not a constant, it is an identifier,
- * but using it as an identifier is not supported
- */
- constants: {
- 'true': { type: AST.Literal, value: true },
- 'false': { type: AST.Literal, value: false },
- 'null': { type: AST.Literal, value: null },
- 'undefined': {type: AST.Literal, value: undefined },
+ selfReferential: {
'this': {type: AST.ThisExpression },
'$locals': {type: AST.LocalsExpression }
}
@@ -14560,7 +14612,7 @@ ASTInterpreter.prototype = {
forEach(ast.body, function(expression) {
expressions.push(self.recurse(expression.expression));
});
- var fn = ast.body.length === 0 ? function() {} :
+ var fn = ast.body.length === 0 ? noop :
ast.body.length === 1 ? expressions[0] :
function(scope, locals) {
var lastValue;
@@ -14701,7 +14753,7 @@ ASTInterpreter.prototype = {
return context ? {value: locals} : locals;
};
case AST.NGValueParameter:
- return function(scope, locals, assign, inputs) {
+ return function(scope, locals, assign) {
return context ? {value: assign} : assign;
};
}
@@ -14915,7 +14967,7 @@ var Parser = function(lexer, $filter, options) {
this.lexer = lexer;
this.$filter = $filter;
this.options = options;
- this.ast = new AST(this.lexer);
+ this.ast = new AST(lexer, options);
this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :
new ASTCompiler(this.ast, $filter);
};
@@ -14992,16 +15044,39 @@ function getValueOf(value) {
function $ParseProvider() {
var cacheDefault = createMap();
var cacheExpensive = createMap();
+ var literals = {
+ 'true': true,
+ 'false': false,
+ 'null': null,
+ 'undefined': undefined
+ };
+
+ /**
+ * @ngdoc method
+ * @name $parseProvider#addLiteral
+ * @description
+ *
+ * Configure $parse service to add literal values that will be present as literal at expressions.
+ *
+ * @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.
+ * @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.
+ *
+ **/
+ this.addLiteral = function(literalName, literalValue) {
+ literals[literalName] = literalValue;
+ };
this.$get = ['$filter', function($filter) {
var noUnsafeEval = csp().noUnsafeEval;
var $parseOptions = {
csp: noUnsafeEval,
- expensiveChecks: false
+ expensiveChecks: false,
+ literals: copy(literals)
},
$parseOptionsExpensive = {
csp: noUnsafeEval,
- expensiveChecks: true
+ expensiveChecks: true,
+ literals: copy(literals)
};
var runningChecksEnabled = false;
@@ -15423,7 +15498,7 @@ function $ParseProvider() {
* - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
* all the important functionality needed for common async tasks.
*
- * # Testing
+ * # Testing
*
* ```js
* it('should simulate promise', inject(function($q, $rootScope) {
@@ -16611,7 +16686,7 @@ function $RootScopeProvider() {
dirty, ttl = TTL,
next, current, target = this,
watchLog = [],
- logIdx, logMsg, asyncTask;
+ logIdx, asyncTask;
beginPhase('$digest');
// Check for changes to browser url that happened in sync before the call to $digest
@@ -18466,7 +18541,7 @@ function $SnifferProvider() {
}];
}
-var $compileMinErr = minErr('$compile');
+var $templateRequestMinErr = minErr('$compile');
/**
* @ngdoc provider
@@ -18562,7 +18637,7 @@ function $TemplateRequestProvider() {
function handleError(resp) {
if (!ignoreRequestError) {
- throw $compileMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})',
+ throw $templateRequestMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})',
tpl, resp.status, resp.statusText);
}
return $q.reject(resp);
@@ -19484,7 +19559,7 @@ function currencyFilter($locale) {
* Formats a number as text.
*
* If the input is null or undefined, it will just be returned.
- * If the input is infinite (Infinity/-Infinity) the Infinity symbol '∞' is returned.
+ * If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.
* If the input is not a number an empty string is returned.
*
*
@@ -19574,7 +19649,7 @@ function parse(numStr) {
}
// Count the number of leading zeros.
- for (i = 0; numStr.charAt(i) == ZERO_CHAR; i++);
+ for (i = 0; numStr.charAt(i) == ZERO_CHAR; i++) {/* jshint noempty: false */}
if (i == (zeros = numStr.length)) {
// The digits are all zero.
@@ -19620,18 +19695,37 @@ function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
var digit = digits[roundAt];
if (roundAt > 0) {
- digits.splice(roundAt);
+ // Drop fractional digits beyond `roundAt`
+ digits.splice(Math.max(parsedNumber.i, roundAt));
+
+ // Set non-fractional digits beyond `roundAt` to 0
+ for (var j = roundAt; j < digits.length; j++) {
+ digits[j] = 0;
+ }
} else {
// We rounded to zero so reset the parsedNumber
+ fractionLen = Math.max(0, fractionLen);
parsedNumber.i = 1;
- digits.length = roundAt = fractionSize + 1;
- for (var i=0; i < roundAt; i++) digits[i] = 0;
+ digits.length = Math.max(1, roundAt = fractionSize + 1);
+ digits[0] = 0;
+ for (var i = 1; i < roundAt; i++) digits[i] = 0;
}
- if (digit >= 5) digits[roundAt - 1]++;
+ if (digit >= 5) {
+ if (roundAt - 1 < 0) {
+ for (var k = 0; k > roundAt; k--) {
+ digits.unshift(0);
+ parsedNumber.i++;
+ }
+ digits.unshift(1);
+ parsedNumber.i++;
+ } else {
+ digits[roundAt - 1]++;
+ }
+ }
// Pad out with zeros to get the required fraction length
- for (; fractionLen < fractionSize; fractionLen++) digits.push(0);
+ for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
// Do any carrying, e.g. a digit was rounded up to 10
@@ -19730,11 +19824,15 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
}
}
-function padNumber(num, digits, trim) {
+function padNumber(num, digits, trim, negWrap) {
var neg = '';
- if (num < 0) {
- neg = '-';
- num = -num;
+ if (num < 0 || (negWrap && num <= 0)) {
+ if (negWrap) {
+ num = -num + 1;
+ } else {
+ num = -num;
+ neg = '-';
+ }
}
num = '' + num;
while (num.length < digits) num = ZERO_CHAR + num;
@@ -19745,7 +19843,7 @@ function padNumber(num, digits, trim) {
}
-function dateGetter(name, size, offset, trim) {
+function dateGetter(name, size, offset, trim, negWrap) {
offset = offset || 0;
return function(date) {
var value = date['get' + name]();
@@ -19753,14 +19851,15 @@ function dateGetter(name, size, offset, trim) {
value += offset;
}
if (value === 0 && offset == -12) value = 12;
- return padNumber(value, size, trim);
+ return padNumber(value, size, trim, negWrap);
};
}
-function dateStrGetter(name, shortForm) {
+function dateStrGetter(name, shortForm, standAlone) {
return function(date, formats) {
var value = date['get' + name]();
- var get = uppercase(shortForm ? ('SHORT' + name) : name);
+ var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
+ var get = uppercase(propPrefix + name);
return formats[get][value];
};
@@ -19815,13 +19914,14 @@ function longEraGetter(date, formats) {
}
var DATE_FORMATS = {
- yyyy: dateGetter('FullYear', 4),
- yy: dateGetter('FullYear', 2, 0, true),
- y: dateGetter('FullYear', 1),
+ yyyy: dateGetter('FullYear', 4, 0, false, true),
+ yy: dateGetter('FullYear', 2, 0, true, true),
+ y: dateGetter('FullYear', 1, 0, false, true),
MMMM: dateStrGetter('Month'),
MMM: dateStrGetter('Month', true),
MM: dateGetter('Month', 2, 1),
M: dateGetter('Month', 1, 1),
+ LLLL: dateStrGetter('Month', false, true),
dd: dateGetter('Date', 2),
d: dateGetter('Date', 1),
HH: dateGetter('Hours', 2),
@@ -19847,7 +19947,7 @@ var DATE_FORMATS = {
GGGG: longEraGetter
};
-var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
+var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
NUMBER_STRING = /^\-?\d+$/;
/**
@@ -19867,6 +19967,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|
* * `'MMM'`: Month in year (Jan-Dec)
* * `'MM'`: Month in year, padded (01-12)
* * `'M'`: Month in year (1-12)
+ * * `'LLLL'`: Stand-alone month in year (January-December)
* * `'dd'`: Day in month, padded (01-31)
* * `'d'`: Day in month (1-31)
* * `'EEEE'`: Day in Week,(Sunday-Saturday)
@@ -21548,8 +21649,8 @@ var ngFormDirective = formDirectiveFactory(true);
ngModelMinErr: false,
*/
-// Regex code is obtained from SO: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
-var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/;
+// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
+var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;
// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
// Note: We are being more lenient, because browsers are too.
// 1. Scheme
@@ -21565,12 +21666,18 @@ var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-
var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
-var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
-var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
-var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
-var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
+var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
+var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
+var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
+var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
+var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';
+var PARTIAL_VALIDATION_TYPES = createMap();
+forEach('date,datetime-local,month,time,week'.split(','), function(type) {
+ PARTIAL_VALIDATION_TYPES[type] = true;
+});
+
var inputType = {
/**
@@ -22647,7 +22754,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
if (!$sniffer.android) {
var composing = false;
- element.on('compositionstart', function(data) {
+ element.on('compositionstart', function() {
composing = true;
});
@@ -22657,6 +22764,8 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
});
}
+ var timeout;
+
var listener = function(ev) {
if (timeout) {
$browser.defer.cancel(timeout);
@@ -22686,8 +22795,6 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
if ($sniffer.hasEvent('input')) {
element.on('input', listener);
} else {
- var timeout;
-
var deferListener = function(ev, input, origValue) {
if (!timeout) {
timeout = $browser.defer(function() {
@@ -22719,6 +22826,26 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
// or form autocomplete on newer browser, we need "change" event to catch it
element.on('change', listener);
+ // Some native input types (date-family) have the ability to change validity without
+ // firing any input/change events.
+ // For these event types, when native validators are present and the browser supports the type,
+ // check for validity changes on various DOM events.
+ if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {
+ element.on(PARTIAL_VALIDATION_EVENTS, function(ev) {
+ if (!timeout) {
+ var validity = this[VALIDITY_STATE_PROPERTY];
+ var origBadInput = validity.badInput;
+ var origTypeMismatch = validity.typeMismatch;
+ timeout = $browser.defer(function() {
+ timeout = null;
+ if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {
+ listener(ev);
+ }
+ });
+ }
+ });
+ }
+
ctrl.$render = function() {
// Workaround for Firefox validation #12102.
var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;
@@ -23739,9 +23866,10 @@ function classDirective(name, selector) {
* new classes added.
*
* @animations
- * **add** - happens just before the class is applied to the elements
- *
- * **remove** - happens just before the class is removed from the element
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#addClass addClass} | just before the class is applied to the element |
+ * | {@link ng.$animate#removeClass removeClass} | just before the class is removed from the element |
*
* @element ANY
* @param {expression} ngClass {@link guide/expression Expression} to eval. The result
@@ -25000,8 +25128,10 @@ forEach(
* and `leave` effects.
*
* @animations
- * enter - happens just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container
- * leave - happens just before the `ngIf` contents are removed from the DOM
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter} | just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container |
+ * | {@link ng.$animate#leave leave} | just before the `ngIf` contents are removed from the DOM |
*
* @element ANY
* @scope
@@ -25042,7 +25172,7 @@ forEach(
*/
-var ngIfDirective = ['$animate', function($animate) {
+var ngIfDirective = ['$animate', '$compile', function($animate, $compile) {
return {
multiElement: true,
transclude: 'element',
@@ -25058,7 +25188,7 @@ var ngIfDirective = ['$animate', function($animate) {
if (!childScope) {
$transclude(function(clone, newScope) {
childScope = newScope;
- clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ');
+ clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);
// Note: We only need the first/last node of the cloned nodes.
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
// by a directive with templateUrl when its template arrives.
@@ -25113,8 +25243,10 @@ var ngIfDirective = ['$animate', function($animate) {
* access on some browsers.
*
* @animations
- * enter - animation is used to bring new content into the browser.
- * leave - animation is used to animate existing content away.
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter} | when the expression changes, on the new include |
+ * | {@link ng.$animate#leave leave} | when the expression changes, on the old include |
*
* The enter and leave animation occur concurrently.
*
@@ -25855,9 +25987,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
};
ngModelSet = function($scope, newValue) {
if (isFunction(parsedNgModel($scope))) {
- invokeModelSetter($scope, {$$$p: ctrl.$modelValue});
+ invokeModelSetter($scope, {$$$p: newValue});
} else {
- parsedNgModelAssign($scope, ctrl.$modelValue);
+ parsedNgModelAssign($scope, newValue);
}
};
} else if (!parsedNgModel.assign) {
@@ -25882,7 +26014,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
* the `$viewValue` are different from last time.
*
* Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
- * `$modelValue` and `$viewValue` are actually different from their previous value. If `$modelValue`
+ * `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`
* or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
* invoked if you only change a property on the objects.
*/
@@ -26234,7 +26366,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
setValidity(name, undefined);
validatorPromises.push(promise.then(function() {
setValidity(name, true);
- }, function(error) {
+ }, function() {
allValid = false;
setValidity(name, false);
}));
@@ -26708,7 +26840,7 @@ var ngModelDirective = ['$rootScope', function($rootScope) {
});
}
- element.on('blur', function(ev) {
+ element.on('blur', function() {
if (modelCtrl.$touched) return;
if ($rootScope.$$phase) {
@@ -27391,8 +27523,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
var value = optionValues[key];
- var locals = getLocals(optionValues[key], key);
- var selectValue = getTrackByValueFn(optionValues[key], locals);
+ var locals = getLocals(value, key);
+ var selectValue = getTrackByValueFn(value, locals);
watchedArray.push(selectValue);
// Only need to watch the displayFn if there is a specific label expression
@@ -27517,14 +27649,20 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
var option = options.getOptionFromViewValue(value);
if (option && !option.disabled) {
+ // Don't update the option when it is already selected.
+ // For example, the browser will select the first option by default. In that case,
+ // most properties are set automatically - except the `selected` attribute, which we
+ // set always
+
if (selectElement[0].value !== option.selectValue) {
removeUnknownOption();
removeEmptyOption();
selectElement[0].value = option.selectValue;
option.element.selected = true;
- option.element.setAttribute('selected', 'selected');
}
+
+ option.element.setAttribute('selected', 'selected');
} else {
if (value === null || providedEmptyOption) {
removeUnknownOption();
@@ -28083,17 +28221,23 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
*
...
* ```
*
- * You need to be aware that the JavaScript specification does not define the order of keys
- * returned for an object. (To mitigate this in Angular 1.3 the `ngRepeat` directive
- * used to sort the keys alphabetically.)
+ * However, there are a limitations compared to array iteration:
+ *
+ * - The JavaScript specification does not define the order of keys
+ * returned for an object, so Angular relies on the order returned by the browser
+ * when running `for key in myObj`. Browsers generally follow the strategy of providing
+ * keys in the order in which they were defined, although there are exceptions when keys are deleted
+ * and reinstated. See the
+ * [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
+ *
+ * - `ngRepeat` will silently *ignore* object keys starting with `$`, because
+ * it's a prefix used by Angular for public (`$`) and private (`$$`) properties.
*
- * Version 1.4 removed the alphabetic sorting. We now rely on the order returned by the browser
- * when running `for key in myObj`. It seems that browsers generally follow the strategy of providing
- * keys in the order in which they were defined, although there are exceptions when keys are deleted
- * and reinstated. See the [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
+ * - The built-in filters {@link ng.orderBy orderBy} and {@link ng.filter filter} do not work with
+ * objects, and will throw if used with one.
*
- * If this is not desired, the recommended workaround is to convert your object into an array
- * that is sorted into the order that you prefer before providing it to `ngRepeat`. You could
+ * If you are hitting any of these limitations, the recommended workaround is to convert your object into an array
+ * that is sorted into the order that you prefer before providing it to `ngRepeat`. You could
* do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
* or implement a `$watch` on the object yourself.
*
@@ -28211,11 +28355,11 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
* as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).
*
* @animations
- * **.enter** - when a new item is added to the list or when an item is revealed after a filter
- *
- * **.leave** - when an item is removed from the list or when an item is filtered out
- *
- * **.move** - when an adjacent item is filtered out causing a reorder or when the item contents are reordered
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter} | when a new item is added to the list or when an item is revealed after a filter |
+ * | {@link ng.$animate#leave leave} | when an item is removed from the list or when an item is filtered out |
+ * | {@link ng.$animate#move move } | when an adjacent item is filtered out causing a reorder or when the item contents are reordered |
*
* See the example below for defining CSS animations with ngRepeat.
*
@@ -28363,7 +28507,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
*/
-var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
+var ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {
var NG_REMOVED = '$$NG_REMOVED';
var ngRepeatMinErr = minErr('ngRepeat');
@@ -28398,7 +28542,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
$$tlb: true,
compile: function ngRepeatCompile($element, $attr) {
var expression = $attr.ngRepeat;
- var ngRepeatEndComment = document.createComment(' end ngRepeat: ' + expression + ' ');
+ var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);
var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
@@ -28562,7 +28706,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
if (getBlockStart(block) != nextNode) {
// existing item which got moved
- $animate.move(getBlockNodes(block.clone), null, jqLite(previousNode));
+ $animate.move(getBlockNodes(block.clone), null, previousNode);
}
previousNode = getBlockEnd(block);
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
@@ -28574,8 +28718,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
var endNode = ngRepeatEndComment.cloneNode(false);
clone[clone.length++] = endNode;
- // TODO(perf): support naked previousNode in `enter` to avoid creation of jqLite wrapper?
- $animate.enter(clone, null, jqLite(previousNode));
+ $animate.enter(clone, null, previousNode);
previousNode = endNode;
// Note: We only need the first/last node of the cloned nodes.
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
@@ -28678,12 +28821,14 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
* .my-element.ng-hide-remove.ng-hide-remove-active { ... }
* ```
*
- * Keep in mind that, as of AngularJS version 1.3.0-beta.11, there is no need to change the display
+ * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display
* property to block during animation states--ngAnimate will handle the style toggling automatically for you.
*
* @animations
- * addClass: `.ng-hide` - happens after the `ngShow` expression evaluates to a truthy value and the just before contents are set to visible
- * removeClass: `.ng-hide` - happens after the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link $animate#addClass addClass} `.ng-hide` | after the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden |
+ * | {@link $animate#removeClass removeClass} `.ng-hide` | after the `ngShow` expression evaluates to a truthy value and just before contents are set to visible |
*
* @element ANY
* @param {expression} ngShow If the {@link guide/expression expression} is truthy
@@ -28842,12 +28987,15 @@ var ngShowDirective = ['$animate', function($animate) {
* .my-element.ng-hide-remove.ng-hide-remove-active { ... }
* ```
*
- * Keep in mind that, as of AngularJS version 1.3.0-beta.11, there is no need to change the display
+ * Keep in mind that, as of AngularJS version 1.3, there is no need to change the display
* property to block during animation states--ngAnimate will handle the style toggling automatically for you.
*
* @animations
- * removeClass: `.ng-hide` - happens after the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden
- * addClass: `.ng-hide` - happens after the `ngHide` expression evaluates to a non truthy value and just before the contents are set to visible
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link $animate#addClass addClass} `.ng-hide` | after the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden |
+ * | {@link $animate#removeClass removeClass} `.ng-hide` | after the `ngHide` expression evaluates to a non truthy value and just before contents are set to visible |
+ *
*
* @element ANY
* @param {expression} ngHide If the {@link guide/expression expression} is truthy then
@@ -29009,8 +29157,10 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
*
* @animations
- * enter - happens after the ngSwitch contents change and the matched child element is placed inside the container
- * leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM
+ * | Animation | Occurs |
+ * |----------------------------------|-------------------------------------|
+ * | {@link ng.$animate#enter enter} | after the ngSwitch contents change and the matched child element is placed inside the container |
+ * | {@link ng.$animate#leave leave} | after the ngSwitch contents change and just before the former contents are removed from the DOM |
*
* @usage
*
@@ -29109,7 +29259,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
*/
-var ngSwitchDirective = ['$animate', function($animate) {
+var ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {
return {
require: 'ngSwitch',
@@ -29150,7 +29300,7 @@ var ngSwitchDirective = ['$animate', function($animate) {
selectedTransclude.transclude(function(caseElement, selectedScope) {
selectedScopes.push(selectedScope);
var anchor = selectedTransclude.element;
- caseElement[caseElement.length++] = document.createComment(' end ngSwitchWhen: ');
+ caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');
var block = { clone: caseElement };
selectedElements.push(block);
@@ -29444,7 +29594,7 @@ function chromeHack(optionElement) {
* added `