diff options
author | Bernhard Posselt <dev@bernhard-posselt.com> | 2015-09-26 11:43:36 +0200 |
---|---|---|
committer | Bernhard Posselt <dev@bernhard-posselt.com> | 2015-09-26 11:43:36 +0200 |
commit | c6ecb54be7a99b7f3ad9d601100f89151380d3b7 (patch) | |
tree | 8fd8e7cd26d907e03aad90003d07b00bf6b5ceb1 /js/vendor/angular/angular.js | |
parent | 847d9da9226383e69ff02c20bebf46a597e7f7d7 (diff) |
update js deps
Diffstat (limited to 'js/vendor/angular/angular.js')
-rw-r--r-- | js/vendor/angular/angular.js | 365 |
1 files changed, 253 insertions, 112 deletions
diff --git a/js/vendor/angular/angular.js b/js/vendor/angular/angular.js index e488352b2..8204cf35f 100644 --- a/js/vendor/angular/angular.js +++ b/js/vendor/angular/angular.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.15 + * @license AngularJS v1.3.19 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -54,7 +54,7 @@ function minErr(module, ErrorConstructor) { return match; }); - message = message + '\nhttp://errors.angularjs.org/1.3.15/' + + message = message + '\nhttp://errors.angularjs.org/1.3.19/' + (module ? module + '/' : '') + code; for (i = 2; i < arguments.length; i++) { message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' + @@ -149,6 +149,7 @@ function minErr(module, ErrorConstructor) { createMap: true, NODE_TYPE_ELEMENT: true, + NODE_TYPE_ATTRIBUTE: true, NODE_TYPE_TEXT: true, NODE_TYPE_COMMENT: true, NODE_TYPE_DOCUMENT: true, @@ -260,7 +261,9 @@ function isArrayLike(obj) { return false; } - var length = obj.length; + // Support: iOS 8.2 (not reproducible in simulator) + // "length" in obj used to prevent JIT error (gh-11508) + var length = "length" in Object(obj) && obj.length; if (obj.nodeType === NODE_TYPE_ELEMENT && length) { return true; @@ -1042,8 +1045,8 @@ function toJsonReplacer(key, value) { * stripped since angular uses this notation internally. * * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON. - * @param {boolean|number=} pretty If set to true, the JSON output will contain newlines and whitespace. - * If set to an integer, the JSON output will contain that many spaces per indentation (the default is 2). + * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace. + * If set to an integer, the JSON output will contain that many spaces per indentation. * @returns {string|undefined} JSON-ified string representing `obj`. */ function toJson(obj, pretty) { @@ -1675,6 +1678,7 @@ function createMap() { } var NODE_TYPE_ELEMENT = 1; +var NODE_TYPE_ATTRIBUTE = 2; var NODE_TYPE_TEXT = 3; var NODE_TYPE_COMMENT = 8; var NODE_TYPE_DOCUMENT = 9; @@ -1911,10 +1915,17 @@ function setupModuleLoader(window) { * @ngdoc method * @name angular.Module#filter * @module ng - * @param {string} name Filter name. + * @param {string} name Filter name - this must be a valid angular expression identifier * @param {Function} filterFactory Factory function for creating new instance of filter. * @description * See {@link ng.$filterProvider#register $filterProvider.register()}. + * + * <div class="alert alert-warning"> + * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. + * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace + * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores + * (`myapp_subsection_filterx`). + * </div> */ filter: invokeLater('$filterProvider', 'register'), @@ -2128,11 +2139,11 @@ function toDebugString(obj) { * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.3.15', // all of these placeholder strings will be replaced by grunt's + full: '1.3.19', // all of these placeholder strings will be replaced by grunt's major: 1, // package task minor: 3, - dot: 15, - codeName: 'locality-filtration' + dot: 19, + codeName: 'glutinous-shriek' }; @@ -2308,7 +2319,7 @@ function publishExternalAPI(angular) { * Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most * commonly needed functionality with the goal of having a very small footprint.</div> * - * To use jQuery, simply load it before `DOMContentLoaded` event fired. + * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. * * <div class="alert">**Note:** all element references in Angular are always wrapped with jQuery or * jqLite; they are never raw DOM references.</div> @@ -2324,7 +2335,7 @@ function publishExternalAPI(angular) { * - [`children()`](http://api.jquery.com/children/) - Does not support selectors * - [`clone()`](http://api.jquery.com/clone/) * - [`contents()`](http://api.jquery.com/contents/) - * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()` + * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. As a setter, does not convert numbers to strings or append 'px'. * - [`data()`](http://api.jquery.com/data/) * - [`detach()`](http://api.jquery.com/detach/) * - [`empty()`](http://api.jquery.com/empty/) @@ -2867,6 +2878,10 @@ forEach({ }, attr: function(element, name, value) { + var nodeType = element.nodeType; + if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) { + return; + } var lowercasedName = lowercase(name); if (BOOLEAN_ATTR[lowercasedName]) { if (isDefined(value)) { @@ -3557,7 +3572,7 @@ function annotate(fn, strictDi, name) { * Return an instance of the service. * * @param {string} name The name of the instance to retrieve. - * @param {string} caller An optional string to provide the origin of the function call for error messages. + * @param {string=} caller An optional string to provide the origin of the function call for error messages. * @return {*} The instance. */ @@ -3568,8 +3583,8 @@ function annotate(fn, strictDi, name) { * @description * Invoke the method and supply the method arguments from the `$injector`. * - * @param {!Function} fn The function to invoke. Function parameters are injected according to the - * {@link guide/di $inject Annotation} rules. + * @param {Function|Array.<string|Function>} fn The injectable function to invoke. Function parameters are + * injected according to the {@link guide/di $inject Annotation} rules. * @param {Object=} self The `this` for the invoked method. * @param {Object=} locals Optional object. If preset then any argument names are read from this * object first, before the `$injector` is consulted. @@ -3836,8 +3851,8 @@ function annotate(fn, strictDi, name) { * configure your service in a provider. * * @param {string} name The name of the instance. - * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand - * for `$provide.provider(name, {$get: $getFn})`. + * @param {Function|Array.<string|Function>} $getFn The injectable $getFn for the instance creation. + * Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`. * @returns {Object} registered provider instance * * @example @@ -3872,7 +3887,8 @@ function annotate(fn, strictDi, name) { * as a type/class. * * @param {string} name The name of the instance. - * @param {Function} constructor A class (constructor function) that will be instantiated. + * @param {Function|Array.<string|Function>} constructor An injectable class (constructor function) + * that will be instantiated. * @returns {Object} registered provider instance * * @example @@ -3971,7 +3987,7 @@ function annotate(fn, strictDi, name) { * object which replaces or wraps and delegates to the original service. * * @param {string} name The name of the service to decorate. - * @param {function()} decorator This function will be invoked when the service needs to be + * @param {Function|Array.<string|Function>} decorator This function will be invoked when the service needs to be * instantiated and should return the decorated service instance. The function is called using * the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable. * Local injection arguments: @@ -4938,7 +4954,7 @@ function Browser(window, document, $log, $sniffer) { function getHash(url) { var index = url.indexOf('#'); - return index === -1 ? '' : url.substr(index + 1); + return index === -1 ? '' : url.substr(index); } /** @@ -5065,7 +5081,7 @@ function Browser(window, document, $log, $sniffer) { // Do the assignment again so that those two variables are referentially identical. lastHistoryState = cachedState; } else { - if (!sameBase) { + if (!sameBase || reloadLocation) { reloadLocation = url; } if (replace) { @@ -5820,7 +5836,8 @@ function $TemplateCacheProvider() { * templateNamespace: 'html', * scope: false, * controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, - * controllerAs: 'stringAlias', + * controllerAs: 'stringIdentifier', + * bindToController: false, * require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], * compile: function compile(tElement, tAttrs, transclude) { * return { @@ -6139,9 +6156,15 @@ function $TemplateCacheProvider() { * * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared * between all directive linking functions. * - * * `controller` - a controller instance - A controller instance if at least one directive on the - * element defines a controller. The controller is shared among all the directives, which allows - * the directives to use the controllers as a communication channel. + * * `controller` - the directive's required controller instance(s) - Instances are shared + * among all directives, which allows the directives to use the controllers as a communication + * channel. The exact value depends on the directive's `require` property: + * * `string`: the controller instance + * * `array`: array of controller instances + * * no controller(s) required: `undefined` + * + * If a required controller cannot be found, and it is optional, the instance is `null`, + * otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown. * * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope. * This is the same as the `$transclude` @@ -6167,7 +6190,7 @@ function $TemplateCacheProvider() { * * ### Transclusion * - * Transclusion is the process of extracting a collection of DOM element from one part of the DOM and + * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and * copying them to another part of the DOM, while maintaining their connection to the original AngularJS * scope from where they were taken. * @@ -6495,6 +6518,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { return bindings; } + function assertValidDirectiveName(name) { + var letter = name.charAt(0); + if (!letter || letter !== lowercase(letter)) { + throw $compileMinErr('baddir', "Directive name '{0}' is invalid. The first character must be a lowercase letter", name); + } + return name; + } + /** * @ngdoc method * @name $compileProvider#directive @@ -6513,6 +6544,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { this.directive = function registerDirective(name, directiveFactory) { assertNotHasOwnProperty(name, 'directive'); if (isString(name)) { + assertValidDirectiveName(name); assertArg(directiveFactory, 'directiveFactory'); if (!hasDirectives.hasOwnProperty(name)) { hasDirectives[name] = []; @@ -7922,7 +7954,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { $compileNode.empty(); - $templateRequest($sce.getTrustedResourceUrl(templateUrl)) + $templateRequest(templateUrl) .then(function(content) { var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn; @@ -8969,7 +9001,7 @@ function $HttpProvider() { * headers: { * 'Content-Type': undefined * }, - * data: { test: 'test' }, + * data: { test: 'test' } * } * * $http(req).success(function(){...}).error(function(){...}); @@ -9404,6 +9436,8 @@ function $HttpProvider() { } promise.success = function(fn) { + assertArgFn(fn, 'fn'); + promise.then(function(response) { fn(response.data, response.status, response.headers, config); }); @@ -9411,6 +9445,8 @@ function $HttpProvider() { }; promise.error = function(fn) { + assertArgFn(fn, 'fn'); + promise.then(null, function(response) { fn(response.data, response.status, response.headers, config); }); @@ -9704,8 +9740,8 @@ function $HttpProvider() { * Resolves the raw $http promise. */ function resolvePromise(response, status, headers, statusText) { - // normalize internal statuses to 0 - status = Math.max(status, 0); + //status: HTTP response status code, 0, -1 (aborted by timeout / promise) + status = status >= -1 ? status : 0; (isSuccess(status) ? deferred.resolve : deferred.reject)({ data: response, @@ -9812,7 +9848,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc xhr.onload = function requestLoaded() { var statusText = xhr.statusText || ''; - // responseText is the old-school way of retrieving response (supported by IE8 & 9) + // responseText is the old-school way of retrieving response (supported by IE9) // response/responseType properties were introduced in XHR Level2 spec (supported by IE10) var response = ('response' in xhr) ? xhr.response : xhr.responseText; @@ -9891,7 +9927,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc }; function jsonpReq(url, callbackId, done) { - // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.: + // we can't use jQuery/jqLite here because jQuery does crazy stuff with script elements, e.g.: // - fetches local scripts via XHR and evals them // - adds and immediately removes script elements from the document var script = rawDocument.createElement('script'), callback = null; @@ -10628,12 +10664,12 @@ function serverBase(url) { * * @constructor * @param {string} appBase application base URL + * @param {string} appBaseNoFile application base URL stripped of any filename * @param {string} basePrefix url path prefix */ -function LocationHtml5Url(appBase, basePrefix) { +function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) { this.$$html5 = true; basePrefix = basePrefix || ''; - var appBaseNoFile = stripFile(appBase); parseAbsoluteUrl(appBase, this); @@ -10707,10 +10743,10 @@ function LocationHtml5Url(appBase, basePrefix) { * * @constructor * @param {string} appBase application base URL + * @param {string} appBaseNoFile application base URL stripped of any filename * @param {string} hashPrefix hashbang prefix */ -function LocationHashbangUrl(appBase, hashPrefix) { - var appBaseNoFile = stripFile(appBase); +function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) { parseAbsoluteUrl(appBase, this); @@ -10724,7 +10760,7 @@ function LocationHashbangUrl(appBase, hashPrefix) { var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url); var withoutHashUrl; - if (withoutBaseUrl.charAt(0) === '#') { + if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') { // The rest of the url starts with a hash so we have // got either a hashbang path or a plain hash fragment @@ -10738,7 +10774,15 @@ function LocationHashbangUrl(appBase, hashPrefix) { // There was no hashbang path nor hash fragment: // If we are in HTML5 mode we use what is left as the path; // Otherwise we ignore what is left - withoutHashUrl = this.$$html5 ? withoutBaseUrl : ''; + if (this.$$html5) { + withoutHashUrl = withoutBaseUrl; + } else { + withoutHashUrl = ''; + if (isUndefined(withoutBaseUrl)) { + appBase = url; + this.replace(); + } + } } parseAppUrl(withoutHashUrl, this); @@ -10811,14 +10855,13 @@ function LocationHashbangUrl(appBase, hashPrefix) { * * @constructor * @param {string} appBase application base URL + * @param {string} appBaseNoFile application base URL stripped of any filename * @param {string} hashPrefix hashbang prefix */ -function LocationHashbangInHtml5Url(appBase, hashPrefix) { +function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) { this.$$html5 = true; LocationHashbangUrl.apply(this, arguments); - var appBaseNoFile = stripFile(appBase); - this.$$parseLinkUrl = function(url, relHref) { if (relHref && relHref[0] === '#') { // special case for links to hash fragments: @@ -10848,7 +10891,7 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) { hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : ''; this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash; - // include hashPrefix in $$absUrl when $$url is empty so IE8 & 9 do not reload page because of removal of '#' + // include hashPrefix in $$absUrl when $$url is empty so IE9 does not reload page because of removal of '#' this.$$absUrl = appBase + hashPrefix + this.$$url; }; @@ -10952,11 +10995,19 @@ var locationPrototype = { * * Return host of current url. * + * Note: compared to the non-angular version `location.host` which returns `hostname:port`, this returns the `hostname` portion only. + * * * ```js * // given url http://example.com/#/some/path?foo=bar&baz=xoxo * var host = $location.host(); * // => "example.com" + * + * // given url http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo + * host = $location.host(); + * // => "example.com" + * host = location.host; + * // => "example.com:8080" * ``` * * @return {string} host of current url. @@ -11346,7 +11397,9 @@ function $LocationProvider() { appBase = stripHash(initialUrl); LocationMode = LocationHashbangUrl; } - $location = new LocationMode(appBase, '#' + hashPrefix); + var appBaseNoFile = stripFile(appBase); + + $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix); $location.$$parseLinkUrl(initialUrl, initialUrl); $location.$$state = $browser.state(); @@ -11426,6 +11479,13 @@ function $LocationProvider() { // update $location when $browser url changes $browser.onUrlChange(function(newUrl, newState) { + + if (isUndefined(beginsWith(appBaseNoFile, newUrl))) { + // If we are navigating outside of the app then force a reload + $window.location.href = newUrl; + return; + } + $rootScope.$evalAsync(function() { var oldUrl = $location.absUrl(); var oldState = $location.$$state; @@ -11703,6 +11763,15 @@ var $parseMinErr = minErr('$parse'); function ensureSafeMemberName(name, fullExpression) { + // From the JavaScript docs: + // Property names must be strings. This means that non-string objects cannot be used + // as keys in an object. Any non-string object, including a number, is typecasted + // into a string via the toString method. + // + // So, to ensure that we are checking the same `name` that JavaScript would use, + // we cast it to a string, if possible + name = (isObject(name) && name.toString) ? name.toString() : name; + if (name === "__defineGetter__" || name === "__defineSetter__" || name === "__lookupGetter__" || name === "__lookupSetter__" || name === "__proto__") { @@ -13511,7 +13580,7 @@ function $$RAFProvider() { //rAF $window.webkitCancelRequestAnimationFrame; var rafSupported = !!requestAnimationFrame; - var raf = rafSupported + var rafFn = rafSupported ? function(fn) { var id = requestAnimationFrame(fn); return function() { @@ -13525,9 +13594,47 @@ function $$RAFProvider() { //rAF }; }; - raf.supported = rafSupported; + queueFn.supported = rafSupported; + + var cancelLastRAF; + var taskCount = 0; + var taskQueue = []; + return queueFn; + + function flush() { + for (var i = 0; i < taskQueue.length; i++) { + var task = taskQueue[i]; + if (task) { + taskQueue[i] = null; + task(); + } + } + taskCount = taskQueue.length = 0; + } + + function queueFn(asyncFn) { + var index = taskQueue.length; + + taskCount++; + taskQueue.push(asyncFn); + + if (index === 0) { + cancelLastRAF = rafFn(flush); + } + + return function cancelQueueFn() { + if (index >= 0) { + taskQueue[index] = null; + index = null; - return raf; + if (--taskCount === 0 && cancelLastRAF) { + cancelLastRAF(); + cancelLastRAF = null; + taskQueue.length = 0; + } + } + }; + } }]; } @@ -13617,7 +13724,6 @@ function $RootScopeProvider() { this.$$childHead = this.$$childTail = null; this.$$listeners = {}; this.$$listenerCount = {}; - this.$$watchersCount = 0; this.$id = nextUid(); this.$$ChildScope = null; } @@ -13640,12 +13746,9 @@ function $RootScopeProvider() { * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the * {@link auto.$injector $injector}. Child scopes are created using the * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when - * compiled HTML template is executed.) + * compiled HTML template is executed.) See also the {@link guide/scope Scopes guide} for + * an in-depth introduction and usage examples. * - * Here is a simple scope snippet to show how you can interact with the scope. - * ```html - * <file src="./test/ng/rootScopeSpec.js" tag="docs1" /> - * ``` * * # Inheritance * A scope can inherit from a parent scope, as in this example: @@ -13806,9 +13909,9 @@ function $RootScopeProvider() { * * * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called, - * you can register a `watchExpression` function with no `listener`. (Since `watchExpression` - * can execute multiple times per {@link ng.$rootScope.Scope#$digest $digest} cycle when a - * change is detected, be prepared for multiple calls to your listener.) + * you can register a `watchExpression` function with no `listener`. (Be prepared for + * multiple calls to your `watchExpression` because it will execute multiple times in a + * single {@link ng.$rootScope.Scope#$digest $digest} cycle if a change is detected.) * * After a watcher is registered with the scope, the `listener` fn is called asynchronously * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the @@ -15480,7 +15583,7 @@ function $SceDelegateProvider() { * characters: '`:`', '`/`', '`.`', '`?`', '`&`' and ';'. It's a useful wildcard for use * in a whitelist. * - `**`: matches zero or more occurrences of *any* character. As such, it's not - * not appropriate to use in for a scheme, domain, etc. as it would match too much. (e.g. + * appropriate for use in a scheme, domain, etc. as it would match too much. (e.g. * http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might * not have been the intention.) Its usage at the very end of the path is ok. (e.g. * http://foo.example.com/templates/**). @@ -15488,11 +15591,11 @@ function $SceDelegateProvider() { * - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax * (and all the inevitable escaping) makes them *harder to maintain*. It's easy to * accidentally introduce a bug when one updates a complex expression (imho, all regexes should - * have good test coverage.). For instance, the use of `.` in the regex is correct only in a + * have good test coverage). For instance, the use of `.` in the regex is correct only in a * small number of cases. A `.` character in the regex used when matching the scheme or a * subdomain could be matched against a `:` or literal `.` that was likely not intended. It * is highly recommended to use the string patterns and only fall back to regular expressions - * if they as a last resort. + * as a last resort. * - The regular expression must be an instance of RegExp (i.e. not a string.) It is * matched against the **entire** *normalized / absolute URL* of the resource being tested * (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags @@ -15502,7 +15605,7 @@ function $SceDelegateProvider() { * remember to escape your regular expression (and be aware that you might need more than * one level of escaping depending on your templating engine and the way you interpolated * the value.) Do make use of your platform's escaping mechanism as it might be good - * enough before coding your own. e.g. Ruby has + * enough before coding your own. E.g. Ruby has * [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape) * and Python has [re.escape](http://docs.python.org/library/re.html#re.escape). * Javascript lacks a similar built in function for escaping. Take a look at Google @@ -16088,12 +16191,14 @@ var $compileMinErr = minErr('$compile'); * @name $templateRequest * * @description - * The `$templateRequest` service downloads the provided template using `$http` and, upon success, - * stores the contents inside of `$templateCache`. If the HTTP request fails or the response data - * of the HTTP request is empty, a `$compile` error will be thrown (the exception can be thwarted - * by setting the 2nd parameter of the function to true). - * - * @param {string} tpl The HTTP request template URL + * The `$templateRequest` service runs security checks then downloads the provided template using + * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request + * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the + * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the + * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted + * when `tpl` is of type string and `$templateCache` has the matching entry. + * + * @param {string|TrustedResourceUrl} tpl The HTTP request template URL * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty * * @return {Promise} the HTTP Promise for the given. @@ -16101,10 +16206,19 @@ var $compileMinErr = minErr('$compile'); * @property {number} totalPendingRequests total amount of pending template requests being downloaded. */ function $TemplateRequestProvider() { - this.$get = ['$templateCache', '$http', '$q', function($templateCache, $http, $q) { + this.$get = ['$templateCache', '$http', '$q', '$sce', function($templateCache, $http, $q, $sce) { function handleRequestFn(tpl, ignoreRequestError) { handleRequestFn.totalPendingRequests++; + // We consider the template cache holds only trusted templates, so + // there's no need to go through whitelisting again for keys that already + // are included in there. This also makes Angular accept any script + // directive, no matter its name. However, we still need to unwrap trusted + // types. + if (!isString(tpl) || !$templateCache.get(tpl)) { + tpl = $sce.getTrustedResourceUrl(tpl); + } + var transformResponse = $http.defaults && $http.defaults.transformResponse; if (isArray(transformResponse)) { @@ -16365,20 +16479,13 @@ var originUrl = urlResolve(window.location.href); * * Implementation Notes for IE * --------------------------- - * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other + * IE <= 10 normalizes the URL when assigned to the anchor node similar to the other * browsers. However, the parsed components will not be set if the URL assigned did not specify * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We * work around that by performing the parsing in a 2nd step by taking a previously normalized * URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the * properties such as protocol, hostname, port, etc. * - * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one - * uses the inner HTML approach to assign the URL as part of an HTML snippet - - * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL. - * Unfortunately, setting img[src] to something like "javascript:foo" on IE throws an exception. - * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that - * method and IE < 8 is unsupported. - * * References: * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html @@ -16508,6 +16615,13 @@ function $WindowProvider() { * Dependency Injected. To achieve this a filter definition consists of a factory function which is * annotated with dependencies and is responsible for creating a filter function. * + * <div class="alert alert-warning"> + * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. + * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace + * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores + * (`myapp_subsection_filterx`). + * </div> + * * ```js * // Filter registration * function MyModule($provide, $filterProvider) { @@ -16589,6 +16703,13 @@ function $FilterProvider($provide) { * @name $filterProvider#register * @param {string|Object} name Name of the filter function, or an object map of filters where * the keys are the filter names and the values are the filter factories. + * + * <div class="alert alert-warning"> + * **Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`. + * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace + * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores + * (`myapp_subsection_filterx`). + * </div> * @returns {Object} Registered filter instance, or if a map of filters was provided then a map * of the registered filter instances. */ @@ -16762,14 +16883,16 @@ function filterFilter() { return function(array, expression, comparator) { if (!isArray(array)) return array; + var expressionType = (expression !== null) ? typeof expression : 'null'; var predicateFn; var matchAgainstAnyProp; - switch (typeof expression) { + switch (expressionType) { case 'function': predicateFn = expression; break; case 'boolean': + case 'null': case 'number': case 'string': matchAgainstAnyProp = true; @@ -16795,6 +16918,14 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) { comparator = equals; } else if (!isFunction(comparator)) { comparator = function(actual, expected) { + if (isUndefined(actual)) { + // No substring matching against `undefined` + return false; + } + if ((actual === null) || (expected === null)) { + // No substring matching against `null`; only match against `null` + return actual === expected; + } if (isObject(actual) || isObject(expected)) { // Prevent an object to be considered equal to a string like `'[object'` return false; @@ -16945,6 +17076,8 @@ function currencyFilter($locale) { * @description * 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 not a number an empty string is returned. * * @param {number|string} number Number to format. @@ -17553,7 +17686,7 @@ function limitToFilter() { * Can be one of: * * - `function`: Getter function. The result of this function will be sorted using the - * `<`, `=`, `>` operator. + * `<`, `===`, `>` operator. * - `string`: An Angular expression. The result of this expression is used to compare elements * (for example `name` to sort by a property called `name` or `name.substr(0, 3)` to sort by * 3 first characters of a property called `name`). The result of a constant expression @@ -18664,11 +18797,11 @@ function FormController(element, attrs, $scope, $animate, $interpolate) { <form name="myForm" ng-controller="FormController" class="my-form"> userType: <input name="input" ng-model="userType" required> <span class="error" ng-show="myForm.input.$error.required">Required!</span><br> - <tt>userType = {{userType}}</tt><br> - <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br> - <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br> - <tt>myForm.$valid = {{myForm.$valid}}</tt><br> - <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br> + <code>userType = {{userType}}</code><br> + <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br> + <code>myForm.input.$error = {{myForm.input.$error}}</code><br> + <code>myForm.$valid = {{myForm |