vendor/assets/javascripts/angular.js in rails-angularjs-1.4.1 vs vendor/assets/javascripts/angular.js in rails-angularjs-1.4.2

- old
+ new

@@ -1,7 +1,7 @@ /** - * @license AngularJS v1.4.1 + * @license AngularJS v1.4.2 * (c) 2010-2015 Google, Inc. http://angularjs.org * License: MIT */ (function(window, document, undefined) {'use strict'; @@ -55,11 +55,11 @@ } return match; }); - message += '\nhttp://errors.angularjs.org/1.4.1/' + + message += '\nhttp://errors.angularjs.org/1.4.2/' + (module ? module + '/' : '') + code; for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' + encodeURIComponent(toDebugString(templateArgs[i])); @@ -419,12 +419,16 @@ for (var j = 0, jj = keys.length; j < jj; j++) { var key = keys[j]; var src = obj[key]; if (deep && isObject(src)) { - if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {}; - baseExtend(dst[key], [src], true); + if (isDate(src)) { + dst[key] = new Date(src.valueOf()); + } else { + if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {}; + baseExtend(dst[key], [src], true); + } } else { dst[key] = src; } } } @@ -531,10 +535,15 @@ identity.$inject = []; function valueFn(value) {return function() {return value;};} +function hasCustomToString(obj) { + return isFunction(obj.toString) && obj.toString !== Object.prototype.toString; +} + + /** * @ngdoc function * @name angular.isUndefined * @module ng * @kind function @@ -2339,15 +2348,15 @@ * - `minor` – `{number}` – Minor version number, such as "9". * - `dot` – `{number}` – Dot version number, such as "18". * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.4.1', // all of these placeholder strings will be replaced by grunt's + full: '1.4.2', // all of these placeholder strings will be replaced by grunt's major: 1, // package task minor: 4, - dot: 1, - codeName: 'hyperionic-illumination' + dot: 2, + codeName: 'nebular-readjustment' }; function publishExternalAPI(angular) { extend(angular, { @@ -5399,11 +5408,11 @@ } } function getHash(url) { var index = url.indexOf('#'); - return index === -1 ? '' : url.substr(index + 1); + return index === -1 ? '' : url.substr(index); } /** * @private * Note: this method is used only by scenario runner @@ -7744,11 +7753,11 @@ jqCollection, originalReplaceDirective, preLinkFns, postLinkFns, previousCompileContext) { previousCompileContext = previousCompileContext || {}; var terminalPriority = -Number.MAX_VALUE, - newScopeDirective, + newScopeDirective = previousCompileContext.newScopeDirective, controllerDirectives = previousCompileContext.controllerDirectives, newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective, templateDirective = previousCompileContext.templateDirective, nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, hasTranscludeDirective = false, @@ -7910,10 +7919,11 @@ } nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, { controllerDirectives: controllerDirectives, + newScopeDirective: (newScopeDirective !== directive) && newScopeDirective, newIsolateScopeDirective: newIsolateScopeDirective, templateDirective: templateDirective, nonTlbTranscludeDirective: nonTlbTranscludeDirective }); ii = directives.length; @@ -8294,11 +8304,11 @@ : origAsyncDirective.templateUrl, templateNamespace = origAsyncDirective.templateNamespace; $compileNode.empty(); - $templateRequest($sce.getTrustedResourceUrl(templateUrl)) + $templateRequest(templateUrl) .then(function(content) { var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn; content = denormalizeTemplate(content); @@ -9354,11 +9364,11 @@ * * 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 `default.cache = false` then only requests that specify their own custom + * 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.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token. * Defaults value is `'XSRF-TOKEN'`. * @@ -9887,11 +9897,11 @@ * that should abort the request when resolved. * - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the * XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials) * for more information. * - **responseType** - `{string}` - see - * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType). + * [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype). * * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the * standard `then` method and two http specific methods: `success` and `error`. The `then` * method takes two arguments a success and an error callback which will be called with a * response object. The `success` and `error` methods take a single argument - a function that @@ -11370,11 +11380,11 @@ */ this.$$parse = function(url) { 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 withoutHashUrl = beginsWith(hashPrefix, withoutBaseUrl); if (isUndefined(withoutHashUrl)) { @@ -11384,11 +11394,19 @@ } else { // 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); this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase); @@ -17455,27 +17473,38 @@ /** * @ngdoc service * @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). + * 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} tpl The HTTP request template URL + * @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} a promise for the HTTP response data of the given URL. * * @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)) { transformResponse = transformResponse.filter(function(transformer) { return transformer !== defaultHttpResponseTransform; @@ -18249,14 +18278,10 @@ return Array.prototype.filter.call(array, predicateFn); }; } -function hasCustomToString(obj) { - return isFunction(obj.toString) && obj.toString !== Object.prototype.toString; -} - // Helper functions for `filterFilter` function createPredicateFn(expression, comparator, matchAgainstAnyProp) { var shouldMatchPrimitives = isObject(expression) && ('$' in expression); var predicateFn; @@ -19225,94 +19250,120 @@ </example> */ orderByFilter.$inject = ['$parse']; function orderByFilter($parse) { return function(array, sortPredicate, reverseOrder) { + if (!(isArrayLike(array))) return array; - sortPredicate = isArray(sortPredicate) ? sortPredicate : [sortPredicate]; + + if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; } if (sortPredicate.length === 0) { sortPredicate = ['+']; } - sortPredicate = sortPredicate.map(function(predicate) { - var descending = false, get = predicate || identity; - if (isString(predicate)) { + + var predicates = processPredicates(sortPredicate, reverseOrder); + + // The next three lines are a version of a Swartzian Transform idiom from Perl + // (sometimes called the Decorate-Sort-Undecorate idiom) + // See https://en.wikipedia.org/wiki/Schwartzian_transform + var compareValues = Array.prototype.map.call(array, getComparisonObject); + compareValues.sort(doComparison); + array = compareValues.map(function(item) { return item.value; }); + + return array; + + function getComparisonObject(value, index) { + return { + value: value, + predicateValues: predicates.map(function(predicate) { + return getPredicateValue(predicate.get(value), index); + }) + }; + } + + function doComparison(v1, v2) { + var result = 0; + for (var index=0, length = predicates.length; index < length; ++index) { + result = compare(v1.predicateValues[index], v2.predicateValues[index]) * predicates[index].descending; + if (result) break; + } + return result; + } + }; + + function processPredicates(sortPredicate, reverseOrder) { + reverseOrder = reverseOrder ? -1 : 1; + return sortPredicate.map(function(predicate) { + var descending = 1, get = identity; + + if (isFunction(predicate)) { + get = predicate; + } else if (isString(predicate)) { if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) { - descending = predicate.charAt(0) == '-'; + descending = predicate.charAt(0) == '-' ? -1 : 1; predicate = predicate.substring(1); } - if (predicate === '') { - // Effectively no predicate was passed so we compare identity - return reverseComparator(compare, descending); + if (predicate !== '') { + get = $parse(predicate); + if (get.constant) { + var key = get(); + get = function(value) { return value[key]; }; + } } - get = $parse(predicate); - if (get.constant) { - var key = get(); - return reverseComparator(function(a, b) { - return compare(a[key], b[key]); - }, descending); - } } - return reverseComparator(function(a, b) { - return compare(get(a),get(b)); - }, descending); + return { get: get, descending: descending * reverseOrder }; }); - return slice.call(array).sort(reverseComparator(comparator, reverseOrder)); + } - function comparator(o1, o2) { - for (var i = 0; i < sortPredicate.length; i++) { - var comp = sortPredicate[i](o1, o2); - if (comp !== 0) return comp; - } - return 0; + function isPrimitive(value) { + switch (typeof value) { + case 'number': /* falls through */ + case 'boolean': /* falls through */ + case 'string': + return true; + default: + return false; } - function reverseComparator(comp, descending) { - return descending - ? function(a, b) {return comp(b,a);} - : comp; - } + } - function isPrimitive(value) { - switch (typeof value) { - case 'number': /* falls through */ - case 'boolean': /* falls through */ - case 'string': - return true; - default: - return false; - } + function objectValue(value, index) { + // If `valueOf` is a valid function use that + if (typeof value.valueOf === 'function') { + value = value.valueOf(); + if (isPrimitive(value)) return value; } + // If `toString` is a valid function and not the one from `Object.prototype` use that + if (hasCustomToString(value)) { + value = value.toString(); + if (isPrimitive(value)) return value; + } + // We have a basic object so we use the position of the object in the collection + return index; + } - function objectToString(value) { - if (value === null) return 'null'; - if (typeof value.valueOf === 'function') { - value = value.valueOf(); - if (isPrimitive(value)) return value; - } - if (typeof value.toString === 'function') { - value = value.toString(); - if (isPrimitive(value)) return value; - } - return ''; + function getPredicateValue(value, index) { + var type = typeof value; + if (value === null) { + type = 'string'; + value = 'null'; + } else if (type === 'string') { + value = value.toLowerCase(); + } else if (type === 'object') { + value = objectValue(value, index); } + return { value: value, type: type }; + } - function compare(v1, v2) { - var t1 = typeof v1; - var t2 = typeof v2; - if (t1 === t2 && t1 === "object") { - v1 = objectToString(v1); - v2 = objectToString(v2); + function compare(v1, v2) { + var result = 0; + if (v1.type === v2.type) { + if (v1.value !== v2.value) { + result = v1.value < v2.value ? -1 : 1; } - if (t1 === t2) { - if (t1 === "string") { - v1 = v1.toLowerCase(); - v2 = v2.toLowerCase(); - } - if (v1 === v2) return 0; - return v1 < v2 ? -1 : 1; - } else { - return t1 < t2 ? -1 : 1; - } + } else { + result = v1.type < v2.type ? -1 : 1; } - }; + return result; + } } function ngDirective(directive) { if (isFunction(directive)) { directive = { @@ -19562,10 +19613,17 @@ * @name ngChecked * @restrict A * @priority 100 * * @description + * Sets the `checked` attribute on the element, if the expression inside `ngChecked` is truthy. + * + * Note that this directive should not be used together with {@link ngModel `ngModel`}, + * as this can lead to unexpected behavior. + * + * ### Why do we need `ngChecked`? + * * The HTML specification does not require browsers to preserve the values of boolean attributes * such as checked. (Their presence means true and their absence means false.) * If we put an Angular interpolation expression into such an attribute then the * binding information would be lost when the browser removes the attribute. * The `ngChecked` directive solves this problem for the `checked` attribute. @@ -19586,11 +19644,11 @@ </file> </example> * * @element INPUT * @param {expression} ngChecked If the {@link guide/expression expression} is truthy, - * then special attribute "checked" will be set on the element + * then the `checked` attribute will be set on the element */ /** * @ngdoc directive @@ -21228,16 +21286,19 @@ * * @description * HTML radio button. * * @param {string} ngModel Assignable angular expression to data-bind to. - * @param {string} value The value to which the expression should be set when selected. + * @param {string} value The value to which the `ngModel` expression should be set when selected. + * Note that `value` only supports `string` values, i.e. the scope model needs to be a string, + * too. Use `ngValue` if you need complex models (`number`, `object`, ...). * @param {string=} name Property name of the form under which the control is published. * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. - * @param {string} ngValue Angular expression which sets the value to which the expression should - * be set when selected. + * @param {string} ngValue Angular expression to which `ngModel` will be be set when the radio + * is selected. Should be used instead of the `value` attribute if you need + * a non-string `ngModel` (`boolean`, `array`, ...). * * @example <example name="radio-input-directive" module="radioExample"> <file name="index.html"> <script> @@ -23661,10 +23722,11 @@ /** * @ngdoc directive * @name ngIf * @restrict A + * @multiElement * * @description * The `ngIf` directive removes or recreates a portion of the DOM tree based on an * {expression}. If the expression assigned to `ngIf` evaluates to a false * value then the element is removed from the DOM, otherwise a clone of the @@ -23959,12 +24021,12 @@ * Emitted when a template HTTP request yields an erroneous response (status < 200 || status > 299) * * @param {Object} angularEvent Synthetic event object. * @param {String} src URL of content to load. */ -var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', '$sce', - function($templateRequest, $anchorScroll, $animate, $sce) { +var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate', + function($templateRequest, $anchorScroll, $animate) { return { restrict: 'ECA', priority: 400, terminal: true, transclude: 'element', @@ -23996,11 +24058,11 @@ previousElement = currentElement; currentElement = null; } }; - scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) { + scope.$watch(srcExp, function ngIncludeWatchAction(src) { var afterAnimation = function() { if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { $anchorScroll(); } }; @@ -25951,24 +26013,45 @@ this.label = label; this.group = group; this.disabled = disabled; } + function getOptionValuesKeys(optionValues) { + var optionValuesKeys; + + if (!keyName && isArrayLike(optionValues)) { + optionValuesKeys = optionValues; + } else { + // if object, extract keys, in enumeration order, unsorted + optionValuesKeys = []; + for (var itemKey in optionValues) { + if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') { + optionValuesKeys.push(itemKey); + } + } + } + return optionValuesKeys; + } + return { trackBy: trackBy, getTrackByValue: getTrackByValue, - getWatchables: $parse(valuesFn, function(values) { + getWatchables: $parse(valuesFn, function(optionValues) { // Create a collection of things that we would like to watch (watchedArray) // so that they can all be watched using a single $watchCollection // that only runs the handler once if anything changes var watchedArray = []; - values = values || []; + optionValues = optionValues || []; - Object.keys(values).forEach(function getWatchable(key) { - if (key.charAt(0) === '$') return; - var locals = getLocals(values[key], key); - var selectValue = getTrackByValueFn(values[key], locals); + var optionValuesKeys = getOptionValuesKeys(optionValues); + var optionValuesLength = optionValuesKeys.length; + for (var index = 0; index < optionValuesLength; index++) { + var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index]; + var value = optionValues[key]; + + var locals = getLocals(optionValues[key], key); + var selectValue = getTrackByValueFn(optionValues[key], locals); watchedArray.push(selectValue); // Only need to watch the displayFn if there is a specific label expression if (match[2] || match[1]) { var label = displayFn(scope, locals); @@ -25978,11 +26061,11 @@ // Only need to watch the disableWhenFn if there is a specific disable expression if (match[4]) { var disableWhen = disableWhenFn(scope, locals); watchedArray.push(disableWhen); } - }); + } return watchedArray; }), getOptions: function() { @@ -25990,25 +26073,11 @@ var selectValueMap = {}; // The option values were already computed in the `getWatchables` fn, // which must have been called to trigger `getOptions` var optionValues = valuesFn(scope) || []; - var optionValuesKeys; - - - if (!keyName && isArrayLike(optionValues)) { - optionValuesKeys = optionValues; - } else { - // if object, extract keys, in enumeration order, unsorted - optionValuesKeys = []; - for (var itemKey in optionValues) { - if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') { - optionValuesKeys.push(itemKey); - } - } - } - + var optionValuesKeys = getOptionValuesKeys(optionValues); var optionValuesLength = optionValuesKeys.length; for (var index = 0; index < optionValuesLength; index++) { var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index]; var value = optionValues[key]; @@ -26620,10 +26689,11 @@ }]; /** * @ngdoc directive * @name ngRepeat + * @multiElement * * @description * The `ngRepeat` directive instantiates a template once per item from a collection. Each template * instance gets its own scope, where the given loop variable is set to the current collection item, * and `$index` is set to the item index or key. @@ -27149,10 +27219,11 @@ var NG_HIDE_CLASS = 'ng-hide'; var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate'; /** * @ngdoc directive * @name ngShow + * @multiElement * * @description * The `ngShow` directive shows or hides the given HTML element based on the expression * provided to the `ngShow` attribute. The element is shown or hidden by removing or adding * the `.ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined @@ -27324,9 +27395,10 @@ /** * @ngdoc directive * @name ngHide + * @multiElement * * @description * The `ngHide` directive shows or hides the given HTML element based on the expression * provided to the `ngHide` attribute. The element is shown or hidden by removing or adding * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined \ No newline at end of file