From dae416b8c8fafd8f7563169aae5c659440eba728 Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Tue, 15 Sep 2015 13:54:02 -0700 Subject: Update Angular to 1.3.18 from 1.3.7 Change-Id: Ieab642e1b6bac7514ab743fe59ddaa1cec560a2b --- xstatic/pkg/angular/__init__.py | 2 +- xstatic/pkg/angular/data/angular-animate.js | 33 +- xstatic/pkg/angular/data/angular-aria.js | 207 +- xstatic/pkg/angular/data/angular-cookies.js | 9 +- xstatic/pkg/angular/data/angular-loader.js | 13 +- xstatic/pkg/angular/data/angular-messages.js | 9 +- xstatic/pkg/angular/data/angular-mocks.js | 137 +- xstatic/pkg/angular/data/angular-resource.js | 3 +- xstatic/pkg/angular/data/angular-route.js | 27 +- xstatic/pkg/angular/data/angular-sanitize.js | 57 +- xstatic/pkg/angular/data/angular-scenario.js | 7625 ++++++++++++++------------ xstatic/pkg/angular/data/angular-touch.js | 37 +- xstatic/pkg/angular/data/angular.js | 7545 +++++++++++++------------ xstatic/pkg/angular/data/errors.json | 2 +- xstatic/pkg/angular/data/version.json | 2 +- xstatic/pkg/angular/data/version.txt | 2 +- 16 files changed, 8350 insertions(+), 7360 deletions(-) diff --git a/xstatic/pkg/angular/__init__.py b/xstatic/pkg/angular/__init__.py index 518b856..1eec0a1 100644 --- a/xstatic/pkg/angular/__init__.py +++ b/xstatic/pkg/angular/__init__.py @@ -11,7 +11,7 @@ NAME = __name__.split('.')[-1] # package name (e.g. 'foo' or 'foo_bar') # please use a all-lowercase valid python # package name -VERSION = '1.3.7' # version of the packaged files, please use the upstream +VERSION = '1.3.18' # version of the packaged files, please use the upstream # version number BUILD = '1' # our package build number, so we can release new builds # with fixes for xstatic stuff. diff --git a/xstatic/pkg/angular/data/angular-animate.js b/xstatic/pkg/angular/data/angular-animate.js index 7d09d78..cd835d0 100644 --- a/xstatic/pkg/angular/data/angular-animate.js +++ b/xstatic/pkg/angular/data/angular-animate.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -438,9 +438,11 @@ angular.module('ngAnimate', ['ng']) //so that all the animated elements within the animation frame //will be properly updated and drawn on screen. This is //required to perform multi-class CSS based animations with - //Firefox. DO NOT REMOVE THIS LINE. - var a = bod.offsetWidth + 1; - fn(); + //Firefox. DO NOT REMOVE THIS LINE. DO NOT OPTIMIZE THIS LINE. + //THE MINIFIER WILL REMOVE IT OTHERWISE WHICH WILL RESULT IN AN + //UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND WILL + //TAKE YEARS AWAY FROM YOUR LIFE! + fn(bod.offsetWidth); }); }; }]) @@ -839,7 +841,8 @@ angular.module('ngAnimate', ['ng']) * promise that was returned when the animation was started. * * ```js - * var promise = $animate.addClass(element, 'super-long-animation').then(function() { + * var promise = $animate.addClass(element, 'super-long-animation'); + * promise.then(function() { * //this will still be called even if cancelled * }); * @@ -1197,18 +1200,21 @@ angular.module('ngAnimate', ['ng']) } return cache.promise = runAnimationPostDigest(function(done) { - var parentElement = element.parent(); - var elementNode = extractElementNode(element); - var parentNode = elementNode.parentNode; + var cache, parentNode, parentElement, elementNode = extractElementNode(element); + if (elementNode) { + cache = element.data(STORAGE_KEY); + element.removeData(STORAGE_KEY); + + parentElement = element.parent(); + parentNode = elementNode.parentNode; + } + // TODO(matsko): move this code into the animationsDisabled() function once #8092 is fixed if (!parentNode || parentNode['$$NG_REMOVED'] || elementNode['$$NG_REMOVED']) { done(); return; } - var cache = element.data(STORAGE_KEY); - element.removeData(STORAGE_KEY); - var state = element.data(NG_ANIMATE_STATE) || {}; var classes = resolveElementClasses(element, cache, state.active); return !classes @@ -1332,8 +1338,7 @@ angular.module('ngAnimate', ['ng']) } else if (lastAnimation.event == 'setClass') { animationsToCancel.push(lastAnimation); cleanup(element, className); - } - else if (runningAnimations[className]) { + } else if (runningAnimations[className]) { var current = runningAnimations[className]; if (current.event == animationEvent) { skipAnimation = true; @@ -1874,7 +1879,7 @@ angular.module('ngAnimate', ['ng']) return; } - if (!staggerTime && styles) { + if (!staggerTime && styles && Object.keys(styles).length > 0) { if (!timings.transitionDuration) { element.css('transition', timings.animationDuration + 's linear all'); appliedStyles.push('transition'); diff --git a/xstatic/pkg/angular/data/angular-aria.js b/xstatic/pkg/angular/data/angular-aria.js index 197b9c8..19bcbb6 100644 --- a/xstatic/pkg/angular/data/angular-aria.js +++ b/xstatic/pkg/angular/data/angular-aria.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -27,13 +27,13 @@ * * | Directive | Supported Attributes | * |---------------------------------------------|----------------------------------------------------------------------------------------| - * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required | * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled | * | {@link ng.directive:ngShow ngShow} | aria-hidden | * | {@link ng.directive:ngHide ngHide} | aria-hidden | - * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event | * | {@link ng.directive:ngDblclick ngDblclick} | tabindex | * | {@link module:ngMessages ngMessages} | aria-live | + * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles | + * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role | * * Find out more information about each directive by reading the * {@link guide/accessibility ngAria Developer Guide}. @@ -105,7 +105,8 @@ function $AriaProvider() { * - **ariaMultiline** – `{boolean}` – Enables/disables aria-multiline tags * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags * - **tabindex** – `{boolean}` – Enables/disables tabindex tags - * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on ng-click + * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `<div>` and + * `<li>` elements with ng-click * * @description * Enables/disables various ARIA attributes @@ -133,6 +134,7 @@ function $AriaProvider() { * @name $aria * * @description + * @priority 200 * * The $aria service contains helper methods for applying common * [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives. @@ -196,6 +198,10 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { return $aria.config(normalizedAttr) && !elem.attr(attr); } + function shouldAttachRole(role, elem) { + return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT'); + } + function getShape(attr, elem) { var type = attr.type, role = attr.role; @@ -209,82 +215,102 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { return { restrict: 'A', require: '?ngModel', - link: function(scope, elem, attr, ngModel) { + priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value + compile: function(elem, attr) { var shape = getShape(attr, elem); - var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem); - - function ngAriaWatchModelValue() { - return ngModel.$modelValue; - } - - function getRadioReaction() { - if (needsTabIndex) { - needsTabIndex = false; - return function ngAriaRadioReaction(newVal) { - var boolVal = newVal === attr.value; - elem.attr('aria-checked', boolVal); - elem.attr('tabindex', 0 - !boolVal); - }; - } else { - return function ngAriaRadioReaction(newVal) { - elem.attr('aria-checked', newVal === attr.value); - }; - } - } - function ngAriaCheckboxReaction(newVal) { - elem.attr('aria-checked', !!newVal); - } + return { + pre: function(scope, elem, attr, ngModel) { + if (shape === 'checkbox' && attr.type !== 'checkbox') { + //Use the input[checkbox] $isEmpty implementation for elements with checkbox roles + ngModel.$isEmpty = function(value) { + return value === false; + }; + } + }, + post: function(scope, elem, attr, ngModel) { + var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem); - switch (shape) { - case 'radio': - case 'checkbox': - if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) { - scope.$watch(ngAriaWatchModelValue, shape === 'radio' ? - getRadioReaction() : ngAriaCheckboxReaction); + function ngAriaWatchModelValue() { + return ngModel.$modelValue; } - break; - case 'range': - if ($aria.config('ariaValue')) { - if (attr.min && !elem.attr('aria-valuemin')) { - elem.attr('aria-valuemin', attr.min); - } - if (attr.max && !elem.attr('aria-valuemax')) { - elem.attr('aria-valuemax', attr.max); - } - if (!elem.attr('aria-valuenow')) { - scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) { - elem.attr('aria-valuenow', newVal); - }); + + function getRadioReaction() { + if (needsTabIndex) { + needsTabIndex = false; + return function ngAriaRadioReaction(newVal) { + var boolVal = (attr.value == ngModel.$viewValue); + elem.attr('aria-checked', boolVal); + elem.attr('tabindex', 0 - !boolVal); + }; + } else { + return function ngAriaRadioReaction(newVal) { + elem.attr('aria-checked', (attr.value == ngModel.$viewValue)); + }; } } - break; - case 'multiline': - if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) { - elem.attr('aria-multiline', true); + + function ngAriaCheckboxReaction() { + elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue)); } - break; - } - if (needsTabIndex) { - elem.attr('tabindex', 0); - } + switch (shape) { + case 'radio': + case 'checkbox': + if (shouldAttachRole(shape, elem)) { + elem.attr('role', shape); + } + if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) { + scope.$watch(ngAriaWatchModelValue, shape === 'radio' ? + getRadioReaction() : ngAriaCheckboxReaction); + } + break; + case 'range': + if (shouldAttachRole(shape, elem)) { + elem.attr('role', 'slider'); + } + if ($aria.config('ariaValue')) { + if (attr.min && !elem.attr('aria-valuemin')) { + elem.attr('aria-valuemin', attr.min); + } + if (attr.max && !elem.attr('aria-valuemax')) { + elem.attr('aria-valuemax', attr.max); + } + if (!elem.attr('aria-valuenow')) { + scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) { + elem.attr('aria-valuenow', newVal); + }); + } + } + break; + case 'multiline': + if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) { + elem.attr('aria-multiline', true); + } + break; + } - if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) { - scope.$watch(function ngAriaRequiredWatch() { - return ngModel.$error.required; - }, function ngAriaRequiredReaction(newVal) { - elem.attr('aria-required', !!newVal); - }); - } + if (needsTabIndex) { + elem.attr('tabindex', 0); + } - if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) { - scope.$watch(function ngAriaInvalidWatch() { - return ngModel.$invalid; - }, function ngAriaInvalidReaction(newVal) { - elem.attr('aria-invalid', !!newVal); - }); - } + if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) { + scope.$watch(function ngAriaRequiredWatch() { + return ngModel.$error.required; + }, function ngAriaRequiredReaction(newVal) { + elem.attr('aria-required', !!newVal); + }); + } + + if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) { + scope.$watch(function ngAriaInvalidWatch() { + return ngModel.$invalid; + }, function ngAriaInvalidReaction(newVal) { + elem.attr('aria-invalid', !!newVal); + }); + } + } + }; } }; }]) @@ -302,21 +328,40 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) { } }; }) -.directive('ngClick',['$aria', function($aria) { +.directive('ngClick',['$aria', '$parse', function($aria, $parse) { return { restrict: 'A', - link: function(scope, elem, attr) { - if ($aria.config('tabindex') && !elem.attr('tabindex')) { - elem.attr('tabindex', 0); - } + compile: function(elem, attr) { + var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true); + return function(scope, elem, attr) { + + var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA']; - if ($aria.config('bindKeypress') && !elem.attr('ng-keypress')) { - elem.on('keypress', function(event) { - if (event.keyCode === 32 || event.keyCode === 13) { - scope.$eval(attr.ngClick); + function isNodeOneOf(elem, nodeTypeArray) { + if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) { + return true; } - }); - } + } + if (!elem.attr('role') && !isNodeOneOf(elem, nodeBlackList)) { + elem.attr('role', 'button'); + } + + if ($aria.config('tabindex') && !elem.attr('tabindex')) { + elem.attr('tabindex', 0); + } + + if ($aria.config('bindKeypress') && !attr.ngKeypress && !isNodeOneOf(elem, nodeBlackList)) { + elem.on('keypress', function(event) { + if (event.keyCode === 32 || event.keyCode === 13) { + scope.$apply(callback); + } + + function callback() { + fn(scope, { $event: event }); + } + }); + } + }; } }; }]) diff --git a/xstatic/pkg/angular/data/angular-cookies.js b/xstatic/pkg/angular/data/angular-cookies.js index d80d9d9..495d3ba 100644 --- a/xstatic/pkg/angular/data/angular-cookies.js +++ b/xstatic/pkg/angular/data/angular-cookies.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -91,6 +91,7 @@ angular.module('ngCookies', ['ng']). for (name in lastCookies) { if (isUndefined(cookies[name])) { $browser.cookies(name, undefined); + delete lastCookies[name]; } } @@ -103,13 +104,13 @@ angular.module('ngCookies', ['ng']). } if (value !== lastCookies[name]) { $browser.cookies(name, value); + lastCookies[name] = value; updated = true; } } //verify what was actually stored if (updated) { - updated = false; browserCookies = $browser.cookies(); for (name in cookies) { @@ -117,10 +118,10 @@ angular.module('ngCookies', ['ng']). //delete or reset all cookies that the browser dropped from $cookies if (isUndefined(browserCookies[name])) { delete cookies[name]; + delete lastCookies[name]; } else { - cookies[name] = browserCookies[name]; + cookies[name] = lastCookies[name] = browserCookies[name]; } - updated = true; } } } diff --git a/xstatic/pkg/angular/data/angular-loader.js b/xstatic/pkg/angular/data/angular-loader.js index 2ef986c..fd9b2a1 100644 --- a/xstatic/pkg/angular/data/angular-loader.js +++ b/xstatic/pkg/angular/data/angular-loader.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -55,7 +55,7 @@ function minErr(module, ErrorConstructor) { return match; }); - message = message + '\nhttp://errors.angularjs.org/1.3.7/' + + message = message + '\nhttp://errors.angularjs.org/1.3.18/' + (module ? module + '/' : '') + code; for (i = 2; i < arguments.length; i++) { message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' + @@ -296,10 +296,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()}. + * + *
+ * **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`). + *
*/ filter: invokeLater('$filterProvider', 'register'), diff --git a/xstatic/pkg/angular/data/angular-messages.js b/xstatic/pkg/angular/data/angular-messages.js index b9cfedb..6d32f5c 100644 --- a/xstatic/pkg/angular/data/angular-messages.js +++ b/xstatic/pkg/angular/data/angular-messages.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -178,7 +178,7 @@ angular.module('ngMessages', []) * at a time and this depends on the prioritization of the messages within the template. (This can * be changed by using the ng-messages-multiple on the directive container.) * - * A remote template can also be used to promote message reuseability and messages can also be + * A remote template can also be used to promote message reusability and messages can also be * overridden. * * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. @@ -331,6 +331,9 @@ angular.module('ngMessages', []) * must be situated since it determines which messages are visible based on the state * of the provided key/value map that `ngMessages` listens on. * + * More information about using `ngMessage` can be found in the + * {@link module:ngMessages `ngMessages` module documentation}. + * * @usage * ```html * @@ -348,8 +351,6 @@ angular.module('ngMessages', []) * * ``` * - * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`. - * * @param {string} ngMessage a string value corresponding to the message key. */ .directive('ngMessage', ['$animate', function($animate) { diff --git a/xstatic/pkg/angular/data/angular-mocks.js b/xstatic/pkg/angular/data/angular-mocks.js index 3430bb7..dbfd1df 100644 --- a/xstatic/pkg/angular/data/angular-mocks.js +++ b/xstatic/pkg/angular/data/angular-mocks.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -250,31 +250,31 @@ angular.mock.$ExceptionHandlerProvider = function() { * * @param {string} mode Mode of operation, defaults to `rethrow`. * - * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there - * is a bug in the application or test, so this mock will make these tests fail. * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` * mode stores an array of errors in `$exceptionHandler.errors`, to allow later * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and * {@link ngMock.$log#reset reset()} + * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there + * is a bug in the application or test, so this mock will make these tests fail. + * For any implementations that expect exceptions to be thrown, the `rethrow` mode + * will also maintain a log of thrown errors. */ this.mode = function(mode) { + switch (mode) { - case 'rethrow': - handler = function(e) { - throw e; - }; - break; case 'log': + case 'rethrow': var errors = []; - handler = function(e) { if (arguments.length == 1) { errors.push(e); } else { errors.push([].slice.call(arguments, 0)); } + if (mode === "rethrow") { + throw e; + } }; - handler.errors = errors; break; default: @@ -1283,7 +1283,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1297,7 +1297,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1311,7 +1311,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1327,7 +1327,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives * data string and returns true if the data is as expected. * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1343,7 +1343,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives * data string and returns true if the data is as expected. * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1356,7 +1356,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1377,7 +1377,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * is in JSON format. * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header * object and returns true if the headers match the current expectation. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. * @@ -1412,7 +1412,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. See #expect for more info. */ @@ -1426,7 +1426,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1440,7 +1440,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1457,7 +1457,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * receives data string and returns true if the data is as expected, or Object if request body * is in JSON format. * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1474,7 +1474,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * receives data string and returns true if the data is as expected, or Object if request body * is in JSON format. * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1491,7 +1491,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * receives data string and returns true if the data is as expected, or Object if request body * is in JSON format. * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1504,7 +1504,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { * * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. - * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched * request is handled. You can save this object for later use and invoke `respond` again in * order to change how a matched request is handled. */ @@ -1809,6 +1809,77 @@ angular.mock.$RootElementProvider = function() { }; }; +/** + * @ngdoc service + * @name $controller + * @description + * A decorator for {@link ng.$controller} with additional `bindings` parameter, useful when testing + * controllers of directives that use {@link $compile#-bindtocontroller- `bindToController`}. + * + * + * ## Example + * + * ```js + * + * // Directive definition ... + * + * myMod.directive('myDirective', { + * controller: 'MyDirectiveController', + * bindToController: { + * name: '@' + * } + * }); + * + * + * // Controller definition ... + * + * myMod.controller('MyDirectiveController', ['log', function($log) { + * $log.info(this.name); + * })]; + * + * + * // In a test ... + * + * describe('myDirectiveController', function() { + * it('should write the bound name to the log', inject(function($controller, $log) { + * var ctrl = $controller('MyDirective', { /* no locals */ }, { name: 'Clark Kent' }); + * expect(ctrl.name).toEqual('Clark Kent'); + * expect($log.info.logs).toEqual(['Clark Kent']); + * }); + * }); + * + * ``` + * + * @param {Function|string} constructor If called with a function then it's considered to be the + * controller constructor function. Otherwise it's considered to be a string which is used + * to retrieve the controller constructor using the following steps: + * + * * check if a controller with given name is registered via `$controllerProvider` + * * check if evaluating the string on the current scope returns a constructor + * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global + * `window` object (not recommended) + * + * The string can use the `controller as property` syntax, where the controller instance is published + * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this + * to work correctly. + * + * @param {Object} locals Injection locals for Controller. + * @param {Object=} bindings Properties to add to the controller before invoking the constructor. This is used + * to simulate the `bindToController` feature and simplify certain kinds of tests. + * @return {Object} Instance of given controller. + */ +angular.mock.$ControllerDecorator = ['$delegate', function($delegate) { + return function(expression, locals, later, ident) { + if (later && typeof later === 'object') { + var create = $delegate(expression, locals, true, ident); + angular.extend(create.instance, later); + return create(); + } + return $delegate(expression, locals, later, ident); + }; +}]; + + /** * @ngdoc module * @name ngMock @@ -1837,6 +1908,7 @@ angular.module('ngMock', ['ng']).provider({ $provide.decorator('$$rAF', angular.mock.$RAFDecorator); $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator); $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator); + $provide.decorator('$controller', angular.mock.$ControllerDecorator); }]); /** @@ -2134,18 +2206,32 @@ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) { if (window.jasmine || window.mocha) { var currentSpec = null, + annotatedFunctions = [], isSpecRunning = function() { return !!currentSpec; }; + angular.mock.$$annotate = angular.injector.$$annotate; + angular.injector.$$annotate = function(fn) { + if (typeof fn === 'function' && !fn.$inject) { + annotatedFunctions.push(fn); + } + return angular.mock.$$annotate.apply(this, arguments); + }; + (window.beforeEach || window.setup)(function() { + annotatedFunctions = []; currentSpec = this; }); (window.afterEach || window.teardown)(function() { var injector = currentSpec.$injector; + annotatedFunctions.forEach(function(fn) { + delete fn.$inject; + }); + angular.forEach(currentSpec.$modules, function(module) { if (module && module.$$hashKey) { module.$$hashKey = undefined; @@ -2158,7 +2244,8 @@ if (window.jasmine || window.mocha) { if (injector) { injector.get('$rootElement').off(); - injector.get('$browser').pollFns.length = 0; + var $browser = injector.get('$browser'); + if ($browser.pollFns) $browser.pollFns.length = 0; } // clean up jquery's fragment cache diff --git a/xstatic/pkg/angular/data/angular-resource.js b/xstatic/pkg/angular/data/angular-resource.js index 7a5eac2..27dc6dc 100644 --- a/xstatic/pkg/angular/data/angular-resource.js +++ b/xstatic/pkg/angular/data/angular-resource.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -213,6 +213,7 @@ function shallowClearAndCopy(src, dst) { * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` * - non-GET instance actions: `instance.$action([parameters], [success], [error])` * + * * Success callback is called with (value, responseHeaders) arguments. Error callback is called * with (httpResponse) argument. * diff --git a/xstatic/pkg/angular/data/angular-route.js b/xstatic/pkg/angular/data/angular-route.js index 834429b..6b54cb6 100644 --- a/xstatic/pkg/angular/data/angular-route.js +++ b/xstatic/pkg/angular/data/angular-route.js @@ -1,5 +1,5 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ @@ -412,7 +412,9 @@ function $RouteProvider() { * @name $route#$routeChangeSuccess * @eventType broadcast on root scope * @description - * Broadcasted after a route dependencies are resolved. + * Broadcasted after a route change has happened successfully. + * The `resolve` dependencies are now available in the `current.locals` property. + * * {@link ngRoute.directive:ngView ngView} listens for the directive * to instantiate the controller and render the view. * @@ -440,9 +442,11 @@ function $RouteProvider() { * @name $route#$routeUpdate * @eventType broadcast on root scope * @description - * * The `reloadOnSearch` property has been set to false, and we are reusing the same * instance of the Controller. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current/previous route information. */ var forceReload = false, @@ -482,21 +486,15 @@ function $RouteProvider() { * definitions will be interpolated into the location's path, while * remaining properties will be treated as query params. * - * @param {Object} newParams mapping of URL parameter names to values + * @param {!Object} newParams mapping of URL parameter names to values */ updateParams: function(newParams) { if (this.current && this.current.$$route) { - var searchParams = {}, self=this; - - angular.forEach(Object.keys(newParams), function(key) { - if (!self.current.pathParams[key]) searchParams[key] = newParams[key]; - }); - newParams = angular.extend({}, this.current.params, newParams); $location.path(interpolate(this.current.$$route.originalPath, newParams)); - $location.search(angular.extend({}, $location.search(), searchParams)); - } - else { + // interpolate modifies newParams, only query params are left + $location.search(newParams); + } else { throw $routeMinErr('norout', 'Tried updating route when with no current route'); } } @@ -600,9 +598,8 @@ function $RouteProvider() { if (angular.isFunction(templateUrl)) { templateUrl = templateUrl(nextRoute.params); } - templateUrl = $sce.getTrustedResourceUrl(templateUrl); if (angular.isDefined(templateUrl)) { - nextRoute.loadedTemplateUrl = templateUrl; + nextRoute.loadedTemplateUrl = $sce.valueOf(templateUrl); template = $templateRequest(templateUrl); } } diff --git a/xstatic/pkg/angular/data/angular-sanitize.js b/xstatic/pkg/angular/data/angular-sanitize.js index 4b0edac..e128391 100644 --- a/xstatic/pkg/angular/data/angular-sanitize.js +++ b/xstatic/pkg/angular/data/angular-sanitize.js @@ -1,10 +1,21 @@ /** - * @license AngularJS v1.3.7 + * @license AngularJS v1.3.18 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ (function(window, angular, undefined) {'use strict'; +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Any commits to this file should be reviewed with security in mind. * + * Changes to this file can potentially create security vulnerabilities. * + * An approval from 2 Core members with history of modifying * + * this file is required. * + * * + * Does the change somehow allow for arbitrary javascript to be executed? * + * Or allows for someone to change the prototype of built-in objects? * + * Or gives undesired access to variables likes document or window? * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + var $sanitizeMinErr = angular.$$minErr('$sanitize'); /** @@ -276,14 +287,14 @@ function htmlParser(html, handler) { } } var index, chars, match, stack = [], last = html, text; - stack.last = function() { return stack[ stack.length - 1 ]; }; + stack.last = function() { return stack[stack.length - 1]; }; while (html) { text = ''; chars = true; // Make sure we're not in a script or style element - if (!stack.last() || !specialElements[ stack.last() ]) { + if (!stack.last() || !specialElements[stack.last()]) { // Comment if (html.indexOf(" + *
+ * *
* ``` * - * The HTML specification does not require browsers to preserve the values of boolean attributes - * such as disabled. (Their presence means true and their absence means false.) + * This is because the HTML specification does not require browsers to preserve the values of + * boolean attributes such as `disabled` (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 `ngDisabled` directive solves this problem for the `disabled` attribute. - * This complementary directive is not removed by the browser and so provides - * a permanent reliable place to store the binding information. * * @example @@ -27071,7 +27325,7 @@ var htmlAnchorDirective = valueFn({ * * @element INPUT * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy, - * then special attribute "disabled" will be set on the element + * then the `disabled` attribute will be set on the element */ @@ -27466,6 +27720,9 @@ function FormController(element, attrs, $scope, $animate, $interpolate) { forEach(form.$error, function(value, name) { form.$setValidity(name, null, control); }); + forEach(form.$$success, function(value, name) { + form.$setValidity(name, null, control); + }); arrayRemove(controls, control); }; @@ -27483,23 +27740,23 @@ function FormController(element, attrs, $scope, $animate, $interpolate) { addSetValidityMethod({ ctrl: this, $element: element, - set: function(object, property, control) { + set: function(object, property, controller) { var list = object[property]; if (!list) { - object[property] = [control]; + object[property] = [controller]; } else { - var index = list.indexOf(control); + var index = list.indexOf(controller); if (index === -1) { - list.push(control); + list.push(controller); } } }, - unset: function(object, property, control) { + unset: function(object, property, controller) { var list = object[property]; if (!list) { return; } - arrayRemove(list, control); + arrayRemove(list, controller); if (list.length === 0) { delete object[property]; } @@ -27616,7 +27873,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) { * * # Alias: {@link ng.directive:ngForm `ngForm`} * - * In Angular forms can be nested. This means that the outer form is valid when all of the child + * In Angular, forms can be nested. This means that the outer form is valid when all of the child * forms are valid as well. However, browsers do not allow nesting of `
` elements, so * Angular provides the {@link ng.directive:ngForm `ngForm`} directive which behaves identically to * `` but can be nested. This allows you to have nested forms, which is very useful when @@ -27715,11 +27972,11 @@ function FormController(element, attrs, $scope, $animate, $interpolate) { userType: Required!
- userType = {{userType}}
- myForm.input.$valid = {{myForm.input.$valid}}
- myForm.input.$error = {{myForm.input.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
+ userType = {{userType}}
+ myForm.input.$valid = {{myForm.input.$valid}}
+ myForm.input.$error = {{myForm.input.$error}}
+ myForm.$valid = {{myForm.$valid}}
+ myForm.$error.required = {{!!myForm.$error.required}}
@@ -27754,10 +28011,12 @@ var formDirectiveFactory = function(isNgForm) { name: 'form', restrict: isNgForm ? 'EAC' : 'E', controller: FormController, - compile: function ngFormCompile(formElement) { + compile: function ngFormCompile(formElement, attr) { // Setup initial state of the control formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS); + var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false); + return { pre: function ngFormPreLink(scope, formElement, attr, controller) { // if `action` attr is not present on the form, prevent the default action (submission) @@ -27788,23 +28047,21 @@ var formDirectiveFactory = function(isNgForm) { }); } - var parentFormCtrl = controller.$$parentForm, - alias = controller.$name; - - if (alias) { - setter(scope, alias, controller, alias); - attr.$observe(attr.name ? 'name' : 'ngForm', function(newValue) { - if (alias === newValue) return; - setter(scope, alias, undefined, alias); - alias = newValue; - setter(scope, alias, controller, alias); - parentFormCtrl.$$renameControl(controller, alias); + var parentFormCtrl = controller.$$parentForm; + + if (nameAttr) { + setter(scope, null, controller.$name, controller, controller.$name); + attr.$observe(nameAttr, function(newValue) { + if (controller.$name === newValue) return; + setter(scope, null, controller.$name, undefined, controller.$name); + parentFormCtrl.$$renameControl(controller, newValue); + setter(scope, null, controller.$name, controller, controller.$name); }); } formElement.on('$destroy', function() { parentFormCtrl.$removeControl(controller); - if (alias) { - setter(scope, alias, undefined, alias); + if (nameAttr) { + setter(scope, null, attr[nameAttr], undefined, controller.$name); } extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards }); @@ -27820,12 +28077,13 @@ var formDirectiveFactory = function(isNgForm) { var formDirective = formDirectiveFactory(); var ngFormDirective = formDirectiveFactory(true); -/* global VALID_CLASS: true, - INVALID_CLASS: true, - PRISTINE_CLASS: true, - DIRTY_CLASS: true, - UNTOUCHED_CLASS: true, - TOUCHED_CLASS: true, +/* global VALID_CLASS: false, + INVALID_CLASS: false, + PRISTINE_CLASS: false, + DIRTY_CLASS: false, + UNTOUCHED_CLASS: false, + TOUCHED_CLASS: false, + ngModelMinErr: false, */ // Regex code is obtained from SO: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 @@ -27838,9 +28096,6 @@ var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{ 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 DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/; - -var $ngModelMinErr = new minErr('ngModel'); var inputType = { @@ -27883,19 +28138,21 @@ var inputType = {
- Single word: + Single word: Required! Single word only! - text = {{text}}
+ text = {{example.text}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -27903,9 +28160,9 @@ var inputType = {
- var text = element(by.binding('text')); + var text = element(by.binding('example.text')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('text')); + var input = element(by.model('example.text')); it('should initialize to model', function() { expect(text.getText()).toContain('guest'); @@ -27967,18 +28224,20 @@ var inputType = {
Pick a date in 2013: - Required! Not a valid date! - value = {{value | date: "yyyy-MM-dd"}}
+ value = {{example.value | date: "yyyy-MM-dd"}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -27986,9 +28245,9 @@ var inputType = {
- var value = element(by.binding('value | date: "yyyy-MM-dd"')); + var value = element(by.binding('example.value | date: "yyyy-MM-dd"')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('value')); + var input = element(by.model('example.value')); // currently protractor/webdriver does not support // sending keys to all known HTML5 input controls @@ -28058,18 +28317,20 @@ var inputType = {
Pick a date between in 2013: - Required! Not a valid date! - value = {{value | date: "yyyy-MM-ddTHH:mm:ss"}}
+ value = {{example.value | date: "yyyy-MM-ddTHH:mm:ss"}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28077,9 +28338,9 @@ var inputType = {
- var value = element(by.binding('value | date: "yyyy-MM-ddTHH:mm:ss"')); + var value = element(by.binding('example.value | date: "yyyy-MM-ddTHH:mm:ss"')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('value')); + var input = element(by.model('example.value')); // currently protractor/webdriver does not support // sending keys to all known HTML5 input controls @@ -28150,18 +28411,20 @@ var inputType = {
Pick a between 8am and 5pm: - Required! Not a valid date! - value = {{value | date: "HH:mm:ss"}}
+ value = {{example.value | date: "HH:mm:ss"}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28169,9 +28432,9 @@ var inputType = {
- var value = element(by.binding('value | date: "HH:mm:ss"')); + var value = element(by.binding('example.value | date: "HH:mm:ss"')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('value')); + var input = element(by.model('example.value')); // currently protractor/webdriver does not support // sending keys to all known HTML5 input controls @@ -28241,18 +28504,20 @@ var inputType = {
Pick a date between in 2013: - Required! Not a valid date! - value = {{value | date: "yyyy-Www"}}
+ value = {{example.value | date: "yyyy-Www"}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28260,9 +28525,9 @@ var inputType = {
- var value = element(by.binding('value | date: "yyyy-Www"')); + var value = element(by.binding('example.value | date: "yyyy-Www"')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('value')); + var input = element(by.model('example.value')); // currently protractor/webdriver does not support // sending keys to all known HTML5 input controls @@ -28332,18 +28597,20 @@ var inputType = {
- Pick a month int 2013: - Required! Not a valid month! - value = {{value | date: "yyyy-MM"}}
+ value = {{example.value | date: "yyyy-MM"}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28351,9 +28618,9 @@ var inputType = {
- var value = element(by.binding('value | date: "yyyy-MM"')); + var value = element(by.binding('example.value | date: "yyyy-MM"')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('value')); + var input = element(by.model('example.value')); // currently protractor/webdriver does not support // sending keys to all known HTML5 input controls @@ -28397,7 +28664,11 @@ var inputType = { * Text input with number validation and transformation. Sets the `number` validation * error if not a valid number. * - * The model must always be a number, otherwise Angular will throw an error. + *
+ * The model must always be of type `number` otherwise Angular will throw an error. + * Be aware that a string containing a number is not enough. See the {@link ngModel:numfmt} + * error docs for more information and an example of how to convert your model if necessary. + *
* * @param {string} ngModel Assignable angular expression to data-bind to. * @param {string=} name Property name of the form under which the control is published. @@ -28429,17 +28700,19 @@ var inputType = {
- Number: Required! Not valid number! - value = {{value}}
+ value = {{example.value}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28447,9 +28720,9 @@ var inputType = {
- var value = element(by.binding('value')); + var value = element(by.binding('example.value')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('value')); + var input = element(by.model('example.value')); it('should initialize to model', function() { expect(value.getText()).toContain('12'); @@ -28517,16 +28790,18 @@ var inputType = {
- URL: + URL: Required! Not valid url! - text = {{text}}
+ text = {{url.text}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28535,9 +28810,9 @@ var inputType = {
- var text = element(by.binding('text')); + var text = element(by.binding('url.text')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('text')); + var input = element(by.model('url.text')); it('should initialize to model', function() { expect(text.getText()).toContain('http://google.com'); @@ -28606,16 +28881,18 @@ var inputType = {
- Email: + Email: Required! Not valid email! - text = {{text}}
+ text = {{email.text}}
myForm.input.$valid = {{myForm.input.$valid}}
myForm.input.$error = {{myForm.input.$error}}
myForm.$valid = {{myForm.$valid}}
@@ -28624,9 +28901,9 @@ var inputType = {
- var text = element(by.binding('text')); + var text = element(by.binding('email.text')); var valid = element(by.binding('myForm.input.$valid')); - var input = element(by.model('text')); + var input = element(by.model('email.text')); it('should initialize to model', function() { expect(text.getText()).toContain('me@example.com'); @@ -28673,7 +28950,9 @@ var inputType = {
- Red
- Green
- Blue
- color = {{color | json}}
+ Red
+ Green
+ Blue
+ color = {{color.name | json}}
Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
it('should change state', function() { - var color = element(by.binding('color')); + var color = element(by.binding('color.name')); expect(color.getText()).toContain('blue'); - element.all(by.model('color')).get(0).click(); + element.all(by.model('color.name')).get(0).click(); expect(color.getText()).toContain('red'); }); @@ -28724,28 +29003,30 @@ var inputType = {
- Value1:
- Value2:
+ Value2:
- value1 = {{value1}}
- value2 = {{value2}}
+ value1 = {{checkboxModel.value1}}
+ value2 = {{checkboxModel.value2}}
it('should change state', function() { - var value1 = element(by.binding('value1')); - var value2 = element(by.binding('value2')); + var value1 = element(by.binding('checkboxModel.value1')); + var value2 = element(by.binding('checkboxModel.value2')); expect(value1.getText()).toContain('true'); expect(value2.getText()).toContain('YES'); - element(by.model('value1')).click(); - element(by.model('value2')).click(); + element(by.model('checkboxModel.value1')).click(); + element(by.model('checkboxModel.value2')).click(); expect(value1.getText()).toContain('false'); expect(value2.getText()).toContain('NO'); @@ -28966,7 +29247,7 @@ function createDateInputType(type, regexp, parseDate, format) { ctrl.$formatters.push(function(value) { if (value && !isDate(value)) { - throw $ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value); + throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value); } if (isValidDate(value)) { previousDate = value; @@ -29043,14 +29324,14 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { ctrl.$formatters.push(function(value) { if (!ctrl.$isEmpty(value)) { if (!isNumber(value)) { - throw $ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value); + throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value); } value = value.toString(); } return value; }); - if (attr.min || attr.ngMin) { + if (isDefined(attr.min) || attr.ngMin) { var minVal; ctrl.$validators.min = function(value) { return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; @@ -29066,7 +29347,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { }); } - if (attr.max || attr.ngMax) { + if (isDefined(attr.max) || attr.ngMax) { var maxVal; ctrl.$validators.max = function(value) { return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; @@ -29136,7 +29417,7 @@ function parseConstantExpr($parse, context, name, expression, fallback) { if (isDefined(expression)) { parseFn = $parse(expression); if (!parseFn.constant) { - throw minErr('ngModel')('constexpr', 'Expected constant expression for `{0}`, but saw ' + + throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' + '`{1}`.', name, expression); } return parseFn(context); @@ -29342,3700 +29623,3627 @@ var inputDirective = ['$browser', '$sniffer', '$filter', '$parse', }; }]; -var VALID_CLASS = 'ng-valid', - INVALID_CLASS = 'ng-invalid', - PRISTINE_CLASS = 'ng-pristine', - DIRTY_CLASS = 'ng-dirty', - UNTOUCHED_CLASS = 'ng-untouched', - TOUCHED_CLASS = 'ng-touched', - PENDING_CLASS = 'ng-pending'; - -/** - * @ngdoc type - * @name ngModel.NgModelController - * - * @property {string} $viewValue Actual string value in the view. - * @property {*} $modelValue The value in the model that the control is bound to. - * @property {Array.} $parsers Array of functions to execute, as a pipeline, whenever - the control reads value from the DOM. The functions are called in array order, each passing - its return value through to the next. The last return value is forwarded to the - {@link ngModel.NgModelController#$validators `$validators`} collection. - -Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue -`$viewValue`}. -Returning `undefined` from a parser means a parse error occurred. In that case, -no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel` -will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`} -is set to `true`. The parse error is stored in `ngModel.$error.parse`. +var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; +/** + * @ngdoc directive + * @name ngValue * - * @property {Array.} $formatters Array of functions to execute, as a pipeline, whenever - the model value changes. The functions are called in reverse array order, each passing the value through to the - next. The last return value is used as the actual DOM value. - Used to format / convert values for display in the control. - * ```js - * function formatter(value) { - * if (value) { - * return value.toUpperCase(); - * } - * } - * ngModel.$formatters.push(formatter); - * ``` - * - * @property {Object.} $validators A collection of validators that are applied - * whenever the model value changes. The key value within the object refers to the name of the - * validator while the function refers to the validation operation. The validation operation is - * provided with the model value as an argument and must return a true or false value depending - * on the response of that validation. - * - * ```js - * ngModel.$validators.validCharacters = function(modelValue, viewValue) { - * var value = modelValue || viewValue; - * return /[0-9]+/.test(value) && - * /[a-z]+/.test(value) && - * /[A-Z]+/.test(value) && - * /\W+/.test(value); - * }; - * ``` + * @description + * Binds the given expression to the value of `