summaryrefslogtreecommitdiffstats
path: root/js/vendor/angular
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-09-23 09:12:24 +0200
committerBernhard Posselt <dev@bernhard-posselt.com>2014-09-23 09:46:18 +0200
commit1c872d3d501b2f9894510dac27b284409b555df1 (patch)
treeb67f692dda9833a14df386bf1a8cd8f5cbdb9c70 /js/vendor/angular
parent4dda6575be15e4f8dba0eca4ab6024705f7147a9 (diff)
update angular
Diffstat (limited to 'js/vendor/angular')
-rw-r--r--js/vendor/angular/.bower.json8
-rw-r--r--js/vendor/angular/angular.js475
-rw-r--r--js/vendor/angular/angular.min.js466
-rw-r--r--js/vendor/angular/angular.min.js.gzipbin43132 -> 39789 bytes
-rw-r--r--js/vendor/angular/angular.min.js.map6
-rw-r--r--js/vendor/angular/bower.json2
6 files changed, 591 insertions, 366 deletions
diff --git a/js/vendor/angular/.bower.json b/js/vendor/angular/.bower.json
index 716ec4e9b..6cb135a42 100644
--- a/js/vendor/angular/.bower.json
+++ b/js/vendor/angular/.bower.json
@@ -1,14 +1,14 @@
{
"name": "angular",
- "version": "1.3.0-rc.1",
+ "version": "1.3.0-rc.2",
"main": "./angular.js",
"dependencies": {},
"homepage": "https://github.com/angular/bower-angular",
- "_release": "1.3.0-rc.1",
+ "_release": "1.3.0-rc.2",
"_resolution": {
"type": "version",
- "tag": "v1.3.0-rc.1",
- "commit": "c7bdad874c48aa3cf83a8baca35a03eeba7a2cf7"
+ "tag": "v1.3.0-rc.2",
+ "commit": "dbe57c6c9495752c3d1cf3a75fc5aa624ff3ba06"
},
"_source": "git://github.com/angular/bower-angular.git",
"_target": "~1.3.*",
diff --git a/js/vendor/angular/angular.js b/js/vendor/angular/angular.js
index bdc97abb0..a3527e899 100644
--- a/js/vendor/angular/angular.js
+++ b/js/vendor/angular/angular.js
@@ -1,5 +1,5 @@
/**
- * @license AngularJS v1.3.0-rc.1
+ * @license AngularJS v1.3.0-rc.2
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -71,7 +71,7 @@ function minErr(module, ErrorConstructor) {
return match;
});
- message = message + '\nhttp://errors.angularjs.org/1.3.0-rc.1/' +
+ message = message + '\nhttp://errors.angularjs.org/1.3.0-rc.2/' +
(module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1535,7 +1535,7 @@ function reloadWithDebugInfo() {
window.location.reload();
}
-/*
+/**
* @name angular.getTestability
* @module ng
* @description
@@ -2122,11 +2122,11 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.3.0-rc.1', // all of these placeholder strings will be replaced by grunt's
+ full: '1.3.0-rc.2', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 3,
dot: 0,
- codeName: 'backyard-atomicity'
+ codeName: 'tactile-perception'
};
@@ -2957,7 +2957,6 @@ forEach({
function createEventHandler(element, events) {
var eventHandler = function (event, type) {
-
// jQuery specific api
event.isDefaultPrevented = function() {
return event.defaultPrevented;
@@ -2968,13 +2967,34 @@ function createEventHandler(element, events) {
if (!eventFnsLength) return;
+ if (isUndefined(event.immediatePropagationStopped)) {
+ var originalStopImmediatePropagation = event.stopImmediatePropagation;
+ event.stopImmediatePropagation = function() {
+ event.immediatePropagationStopped = true;
+
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
+ if (originalStopImmediatePropagation) {
+ originalStopImmediatePropagation.call(event);
+ }
+ };
+ }
+
+ event.isImmediatePropagationStopped = function() {
+ return event.immediatePropagationStopped === true;
+ };
+
// Copy event handlers in case event handlers array is modified during execution.
if ((eventFnsLength > 1)) {
eventFns = shallowCopy(eventFns);
}
for (var i = 0; i < eventFnsLength; i++) {
- eventFns[i].call(element, event);
+ if (!event.isImmediatePropagationStopped()) {
+ eventFns[i].call(element, event);
+ }
}
};
@@ -3175,11 +3195,12 @@ forEach({
var eventFns = events && events[eventName];
if (eventFns) {
-
// Create a dummy event to pass to the handlers
dummyEvent = {
preventDefault: function() { this.defaultPrevented = true; },
isDefaultPrevented: function() { return this.defaultPrevented === true; },
+ stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },
+ isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },
stopPropagation: noop,
type: eventName,
target: element
@@ -3195,9 +3216,10 @@ forEach({
handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
forEach(eventFnsCopy, function(fn) {
- fn.apply(element, handlerArgs);
+ if (!dummyEvent.isImmediatePropagationStopped()) {
+ fn.apply(element, handlerArgs);
+ }
});
-
}
}
}, function(fn, name){
@@ -5845,6 +5867,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// 'on' and be composed of only English letters.
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
+ function parseIsolateBindings(scope, directiveName) {
+ var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
+
+ var bindings = {};
+
+ forEach(scope, function(definition, scopeName) {
+ var match = definition.match(LOCAL_REGEXP);
+
+ if (!match) {
+ throw $compileMinErr('iscp',
+ "Invalid isolate scope definition for directive '{0}'." +
+ " Definition: {... {1}: '{2}' ...}",
+ directiveName, scopeName, definition);
+ }
+
+ bindings[scopeName] = {
+ attrName: match[3] || scopeName,
+ mode: match[1],
+ optional: match[2] === '?'
+ };
+ });
+
+ return bindings;
+ }
+
/**
* @ngdoc method
* @name $compileProvider#directive
@@ -5882,6 +5929,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
directive.name = directive.name || name;
directive.require = directive.require || (directive.controller && directive.name);
directive.restrict = directive.restrict || 'EA';
+ if (isObject(directive.scope)) {
+ directive.$$isolateBindings = parseIsolateBindings(directive.scope, directive.name);
+ }
directives.push(directive);
} catch (e) {
$exceptionHandler(e);
@@ -6928,21 +6978,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
newIsolateScopeDirective.bindToController === true) {
isolateBindingContext = isolateScopeController.instance;
}
- forEach(newIsolateScopeDirective.scope, function(definition, scopeName) {
- var match = definition.match(LOCAL_REGEXP) || [],
- attrName = match[3] || scopeName,
- optional = (match[2] == '?'),
- mode = match[1], // @, =, or &
+
+ forEach(isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, function(definition, scopeName) {
+ var attrName = definition.attrName,
+ optional = definition.optional,
+ mode = definition.mode, // @, =, or &
lastValue,
parentGet, parentSet, compare;
- isolateScope.$$isolateBindings[scopeName] = mode + attrName;
-
switch (mode) {
case '@':
attrs.$observe(attrName, function(value) {
- isolateScope[scopeName] = value;
+ isolateBindingContext[scopeName] = value;
});
attrs.$$observers[attrName].$$scope = scope;
if( attrs[attrName] ) {
@@ -6970,7 +7018,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
attrs[attrName], newIsolateScopeDirective.name);
};
lastValue = isolateBindingContext[scopeName] = parentGet(scope);
- var unwatch = scope.$watch($parse(attrs[attrName], function parentValueWatch(parentValue) {
+ var parentValueWatch = function parentValueWatch(parentValue) {
if (!compare(parentValue, isolateBindingContext[scopeName])) {
// we are out of sync and need to copy
if (!compare(parentValue, lastValue)) {
@@ -6982,7 +7030,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
}
return lastValue = parentValue;
- }), null, parentGet.literal);
+ };
+ parentValueWatch.$stateful = true;
+ var unwatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
isolateScope.$on('$destroy', unwatch);
break;
@@ -6992,12 +7042,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
return parentGet(scope, locals);
};
break;
-
- default:
- throw $compileMinErr('iscp',
- "Invalid isolate scope definition for directive '{0}'." +
- " Definition: {... {1}: '{2}' ...}",
- newIsolateScopeDirective.name, scopeName, definition);
}
});
}
@@ -10749,7 +10793,6 @@ var OPERATORS = extend(createMap(), {
'/':function(self, locals, a,b){return a(self, locals)/b(self, locals);},
'%':function(self, locals, a,b){return a(self, locals)%b(self, locals);},
'^':function(self, locals, a,b){return a(self, locals)^b(self, locals);},
- '=':noop,
'===':function(self, locals, a, b){return a(self, locals)===b(self, locals);},
'!==':function(self, locals, a, b){return a(self, locals)!==b(self, locals);},
'==':function(self, locals, a,b){return a(self, locals)==b(self, locals);},
@@ -10761,9 +10804,11 @@ var OPERATORS = extend(createMap(), {
'&&':function(self, locals, a,b){return a(self, locals)&&b(self, locals);},
'||':function(self, locals, a,b){return a(self, locals)||b(self, locals);},
'&':function(self, locals, a,b){return a(self, locals)&b(self, locals);},
-// '|':function(self, locals, a,b){return a|b;},
- '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));},
- '!':function(self, locals, a){return !a(self, locals);}
+ '!':function(self, locals, a){return !a(self, locals);},
+
+ //Tokenized as operators but parsed as assignment/filters
+ '=':true,
+ '|':true
});
/* jshint bitwise: true */
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
@@ -11012,6 +11057,10 @@ Lexer.prototype = {
};
+function isConstant(exp) {
+ return exp.constant;
+}
+
/**
* @constructor
*/
@@ -11126,26 +11175,20 @@ Parser.prototype = {
},
unaryFn: function(fn, right) {
- return extend(function(self, locals) {
+ return extend(function $parseUnaryFn(self, locals) {
return fn(self, locals, right);
}, {
- constant:right.constant
- });
- },
-
- ternaryFn: function(left, middle, right){
- return extend(function(self, locals){
- return left(self, locals) ? middle(self, locals) : right(self, locals);
- }, {
- constant: left.constant && middle.constant && right.constant
+ constant:right.constant,
+ inputs: [right]
});
},
- binaryFn: function(left, fn, right) {
- return extend(function(self, locals) {
+ binaryFn: function(left, fn, right, isBranching) {
+ return extend(function $parseBinaryFn(self, locals) {
return fn(self, locals, left, right);
}, {
- constant:left.constant && right.constant
+ constant: left.constant && right.constant,
+ inputs: !isBranching && [left, right]
});
},
@@ -11174,12 +11217,12 @@ Parser.prototype = {
var left = this.expression();
var token;
while ((token = this.expect('|'))) {
- left = this.binaryFn(left, token.fn, this.filter());
+ left = this.filter(left);
}
return left;
},
- filter: function() {
+ filter: function(inputFn) {
var token = this.expect();
var fn = this.$filter(token.text);
var argsFn;
@@ -11193,7 +11236,10 @@ Parser.prototype = {
}
}
- return valueFn(function $parseFilter(self, locals, input) {
+ var inputs = [inputFn].concat(argsFn || []);
+
+ return extend(function $parseFilter(self, locals) {
+ var input = inputFn(self, locals);
if (args) {
args[0] = input;
@@ -11206,6 +11252,9 @@ Parser.prototype = {
}
return fn(input);
+ }, {
+ constant: !fn.$stateful && inputs.every(isConstant),
+ inputs: !fn.$stateful && inputs
});
},
@@ -11223,9 +11272,11 @@ Parser.prototype = {
this.text.substring(0, token.index) + '] can not be assigned to', token);
}
right = this.ternary();
- return function $parseAssignment(scope, locals) {
+ return extend(function $parseAssignment(scope, locals) {
return left.assign(scope, right(scope, locals), locals);
- };
+ }, {
+ inputs: [left, right]
+ });
}
return left;
},
@@ -11237,20 +11288,27 @@ Parser.prototype = {
if ((token = this.expect('?'))) {
middle = this.assignment();
if ((token = this.expect(':'))) {
- return this.ternaryFn(left, middle, this.assignment());
+ var right = this.assignment();
+
+ return extend(function $parseTernary(self, locals){
+ return left(self, locals) ? middle(self, locals) : right(self, locals);
+ }, {
+ constant: left.constant && middle.constant && right.constant
+ });
+
} else {
this.throwError('expected :', token);
}
- } else {
- return left;
}
+
+ return left;
},
logicalOR: function() {
var left = this.logicalAND();
var token;
while ((token = this.expect('||'))) {
- left = this.binaryFn(left, token.fn, this.logicalAND());
+ left = this.binaryFn(left, token.fn, this.logicalAND(), true);
}
return left;
},
@@ -11259,7 +11317,7 @@ Parser.prototype = {
var left = this.equality();
var token;
if ((token = this.expect('&&'))) {
- left = this.binaryFn(left, token.fn, this.logicalAND());
+ left = this.binaryFn(left, token.fn, this.logicalAND(), true);
}
return left;
},
@@ -11394,7 +11452,6 @@ Parser.prototype = {
// This is used with json array declaration
arrayDeclaration: function () {
var elementFns = [];
- var allConstant = true;
if (this.peekToken().text !== ']') {
do {
if (this.peek(']')) {
@@ -11403,9 +11460,6 @@ Parser.prototype = {
}
var elementFn = this.expression();
elementFns.push(elementFn);
- if (!elementFn.constant) {
- allConstant = false;
- }
} while (this.expect(','));
}
this.consume(']');
@@ -11418,41 +11472,38 @@ Parser.prototype = {
return array;
}, {
literal: true,
- constant: allConstant
+ constant: elementFns.every(isConstant),
+ inputs: elementFns
});
},
object: function () {
- var keyValues = [];
- var allConstant = true;
+ var keys = [], valueFns = [];
if (this.peekToken().text !== '}') {
do {
if (this.peek('}')) {
// Support trailing commas per ES5.1.
break;
}
- var token = this.expect(),
- key = token.string || token.text;
+ var token = this.expect();
+ keys.push(token.string || token.text);
this.consume(':');
var value = this.expression();
- keyValues.push({key: key, value: value});
- if (!value.constant) {
- allConstant = false;
- }
+ valueFns.push(value);
} while (this.expect(','));
}
this.consume('}');
return extend(function $parseObjectLiteral(self, locals) {
var object = {};
- for (var i = 0, ii = keyValues.length; i < ii; i++) {
- var keyValue = keyValues[i];
- object[keyValue.key] = keyValue.value(self, locals);
+ for (var i = 0, ii = valueFns.length; i < ii; i++) {
+ object[keys[i]] = valueFns[i](self, locals);
}
return object;
}, {
literal: true,
- constant: allConstant
+ constant: valueFns.every(isConstant),
+ inputs: valueFns
});
}
};
@@ -11534,7 +11585,7 @@ function getterFn(path, options, fullExp) {
if (pathKeysLength < 6) {
fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp);
} else {
- fn = function(scope, locals) {
+ fn = function cspSafeGetter(scope, locals) {
var i = 0, val;
do {
val = cspSafeGetterFn(pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++],
@@ -11563,14 +11614,14 @@ function getterFn(path, options, fullExp) {
var evaledFnGetter = new Function('s', 'l', code); // s=scope, l=locals
/* jshint +W054 */
evaledFnGetter.toString = valueFn(code);
- evaledFnGetter.assign = function(self, value) {
- return setter(self, path, value, path);
- };
fn = evaledFnGetter;
}
fn.sharedGetter = true;
+ fn.assign = function(self, value) {
+ return setter(self, path, value, path);
+ };
getterFnCache[path] = fn;
return fn;
}
@@ -11679,6 +11730,8 @@ function $ParseProvider() {
parsedExpression = wrapSharedExpression(parsedExpression);
parsedExpression.$$watchDelegate = parsedExpression.literal ?
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
+ } else if (parsedExpression.inputs) {
+ parsedExpression.$$watchDelegate = inputsWatchDelegate;
}
cache[cacheKey] = parsedExpression;
@@ -11693,6 +11746,88 @@ function $ParseProvider() {
}
};
+ function collectExpressionInputs(inputs, list) {
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ var input = inputs[i];
+ if (!input.constant) {
+ if (input.inputs) {
+ collectExpressionInputs(input.inputs, list);
+ } else if (list.indexOf(input) === -1) { // TODO(perf) can we do better?
+ list.push(input);
+ }
+ }
+ }
+
+ return list;
+ }
+
+ function expressionInputDirtyCheck(newValue, oldValueOfValue) {
+
+ if (newValue == null || oldValueOfValue == null) { // null/undefined
+ return newValue === oldValueOfValue;
+ }
+
+ if (typeof newValue === 'object') {
+
+ // attempt to convert the value to a primitive type
+ // TODO(docs): add a note to docs that by implementing valueOf even objects and arrays can
+ // be cheaply dirty-checked
+ newValue = newValue.valueOf();
+
+ if (typeof newValue === 'object') {
+ // objects/arrays are not supported - deep-watching them would be too expensive
+ return false;
+ }
+
+ // fall-through to the primitive equality check
+ }
+
+ //Primitive or NaN
+ return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);
+ }
+
+ function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression) {
+ var inputExpressions = parsedExpression.$$inputs ||
+ (parsedExpression.$$inputs = collectExpressionInputs(parsedExpression.inputs, []));
+
+ var lastResult;
+
+ if (inputExpressions.length === 1) {
+ var oldInputValue = expressionInputDirtyCheck; // init to something unique so that equals check fails
+ inputExpressions = inputExpressions[0];
+ return scope.$watch(function expressionInputWatch(scope) {
+ var newInputValue = inputExpressions(scope);
+ if (!expressionInputDirtyCheck(newInputValue, oldInputValue)) {
+ lastResult = parsedExpression(scope);
+ oldInputValue = newInputValue && newInputValue.valueOf();
+ }
+ return lastResult;
+ }, listener, objectEquality);
+ }
+
+ var oldInputValueOfValues = [];
+ for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
+ oldInputValueOfValues[i] = expressionInputDirtyCheck; // init to something unique so that equals check fails
+ }
+
+ return scope.$watch(function expressionInputsWatch(scope) {
+ var changed = false;
+
+ for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
+ var newInputValue = inputExpressions[i](scope);
+ if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) {
+ oldInputValueOfValues[i] = newInputValue && newInputValue.valueOf();
+ }
+ }
+
+ if (changed) {
+ lastResult = parsedExpression(scope);
+ }
+
+ return lastResult;
+ }, listener, objectEquality);
+ }
+
function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression) {
var unwatch, lastValue;
return unwatch = scope.$watch(function oneTimeWatch(scope) {
@@ -11758,7 +11893,18 @@ function $ParseProvider() {
// initial value is defined (for bind-once)
return isDefined(value) ? result : value;
};
- fn.$$watchDelegate = parsedExpression.$$watchDelegate;
+
+ // Propagate $$watchDelegates other then inputsWatchDelegate
+ if (parsedExpression.$$watchDelegate &&
+ parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
+ fn.$$watchDelegate = parsedExpression.$$watchDelegate;
+ } else if (!interceptorFn.$stateful) {
+ // If there is an interceptor, but no watchDelegate then treat the interceptor like
+ // we treat filters - it is assumed to be a pure function unless flagged with $stateful
+ fn.$$watchDelegate = inputsWatchDelegate;
+ fn.inputs = [parsedExpression];
+ }
+
return fn;
}
}];
@@ -12496,7 +12642,7 @@ function $RootScopeProvider(){
this.$$postDigestQueue = [];
this.$$listeners = {};
this.$$listenerCount = {};
- this.$$isolateBindings = {};
+ this.$$isolateBindings = null;
this.$$applyAsyncQueue = [];
}
@@ -12877,6 +13023,8 @@ function $RootScopeProvider(){
* de-registration function is executed, the internal watch operation is terminated.
*/
$watchCollection: function(obj, listener) {
+ $watchCollectionInterceptor.$stateful = true;
+
var self = this;
// the current value, updated on each dirty-check run
var newValue;
@@ -16199,10 +16347,11 @@ var uppercaseFilter = valueFn(uppercase);
*
* @description
* Creates a new array or string containing only a specified number of elements. The elements
- * are taken from either the beginning or the end of the source array or string, as specified by
- * the value and sign (positive or negative) of `limit`.
+ * are taken from either the beginning or the end of the source array, string or number, as specified by
+ * the value and sign (positive or negative) of `limit`. If a number is used as input, it is
+ * converted to a string.
*
- * @param {Array|string} input Source array or string to be limited.
+ * @param {Array|string|number} input Source array, string or number to be limited.
* @param {string|number} limit The length of the returned array or string. If the `limit` number
* is positive, `limit` number of items from the beginning of the source array/string are copied.
* If the number is negative, `limit` number of items from the end of the source array/string
@@ -16218,8 +16367,10 @@ var uppercaseFilter = valueFn(uppercase);
.controller('ExampleController', ['$scope', function($scope) {
$scope.numbers = [1,2,3,4,5,6,7,8,9];
$scope.letters = "abcdefghi";
+ $scope.longNumber = 2345432342;
$scope.numLimit = 3;
$scope.letterLimit = 3;
+ $scope.longNumberLimit = 3;
}]);
</script>
<div ng-controller="ExampleController">
@@ -16227,19 +16378,25 @@ var uppercaseFilter = valueFn(uppercase);
<p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
Limit {{letters}} to: <input type="integer" ng-model="letterLimit">
<p>Output letters: {{ letters | limitTo:letterLimit }}</p>
+ Limit {{longNumber}} to: <input type="integer" ng-model="longNumberLimit">
+ <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>
</div>
</file>
<file name="protractor.js" type="protractor">
var numLimitInput = element(by.model('numLimit'));
var letterLimitInput = element(by.model('letterLimit'));
+ var longNumberLimitInput = element(by.model('longNumberLimit'));
var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
+ var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));
it('should limit the number array to first three items', function() {
expect(numLimitInput.getAttribute('value')).toBe('3');
expect(letterLimitInput.getAttribute('value')).toBe('3');
+ expect(longNumberLimitInput.getAttribute('value')).toBe('3');
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
expect(limitedLetters.getText()).toEqual('Output letters: abc');
+ expect(limitedLongNumber.getText()).toEqual('Output long number: 234');
});
it('should update the output when -3 is entered', function() {
@@ -16247,8 +16404,11 @@ var uppercaseFilter = valueFn(uppercase);
numLimitInput.sendKeys('-3');
letterLimitInput.clear();
letterLimitInput.sendKeys('-3');
+ longNumberLimitInput.clear();
+ longNumberLimitInput.sendKeys('-3');
expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
expect(limitedLetters.getText()).toEqual('Output letters: ghi');
+ expect(limitedLongNumber.getText()).toEqual('Output long number: 342');
});
it('should not exceed the maximum size of input array', function() {
@@ -16256,14 +16416,18 @@ var uppercaseFilter = valueFn(uppercase);
numLimitInput.sendKeys('100');
letterLimitInput.clear();
letterLimitInput.sendKeys('100');
+ longNumberLimitInput.clear();
+ longNumberLimitInput.sendKeys('100');
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
+ expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');
});
</file>
</example>
*/
function limitToFilter(){
return function(input, limit) {
+ if (isNumber(input)) input = input.toString();
if (!isArray(input) && !isString(input)) return input;
if (Math.abs(Number(limit)) === Infinity) {
@@ -18436,11 +18600,11 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
element.on('change', listener);
ctrl.$render = function() {
- element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
+ element.val(ctrl.$isEmpty(ctrl.$modelValue) ? '' : ctrl.$viewValue);
};
}
-function weekParser(isoWeek) {
+function weekParser(isoWeek, existingDate) {
if (isDate(isoWeek)) {
return isoWeek;
}
@@ -18451,9 +18615,21 @@ function weekParser(isoWeek) {
if (parts) {
var year = +parts[1],
week = +parts[2],
+ hours = 0,
+ minutes = 0,
+ seconds = 0,
+ milliseconds = 0,
firstThurs = getFirstThursdayOfYear(year),
addDays = (week - 1) * 7;
- return new Date(year, 0, firstThurs.getDate() + addDays);
+
+ if (existingDate) {
+ hours = existingDate.getHours();
+ minutes = existingDate.getMinutes();
+ seconds = existingDate.getSeconds();
+ milliseconds = existingDate.getMilliseconds();
+ }
+
+ return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);
}
}
@@ -18461,7 +18637,7 @@ function weekParser(isoWeek) {
}
function createDateParser(regexp, mapping) {
- return function(iso) {
+ return function(iso, date) {
var parts, map;
if (isDate(iso)) {
@@ -18483,14 +18659,26 @@ function createDateParser(regexp, mapping) {
if (parts) {
parts.shift();
- map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0 };
+ if (date) {
+ map = {
+ yyyy: date.getFullYear(),
+ MM: date.getMonth() + 1,
+ dd: date.getDate(),
+ HH: date.getHours(),
+ mm: date.getMinutes(),
+ ss: date.getSeconds(),
+ sss: date.getMilliseconds()
+ };
+ } else {
+ map = { yyyy: 1970, MM: 1, dd: 1, HH: 0, mm: 0, ss: 0, sss: 0 };
+ }
forEach(parts, function(part, index) {
if (index < mapping.length) {
map[mapping[index]] = +part;
}
});
- return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0);
+ return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss || 0);
}
}
@@ -18508,7 +18696,12 @@ function createDateInputType(type, regexp, parseDate, format) {
ctrl.$parsers.push(function(value) {
if (ctrl.$isEmpty(value)) return null;
if (regexp.test(value)) {
- var parsedDate = parseDate(value);
+ var previousDate = ctrl.$modelValue;
+ if (previousDate && timezone === 'UTC') {
+ var timezoneOffset = 60000 * previousDate.getTimezoneOffset();
+ previousDate = new Date(previousDate.getTime() + timezoneOffset);
+ }
+ var parsedDate = parseDate(value, previousDate);
if (timezone === 'UTC') {
parsedDate.setMinutes(parsedDate.getMinutes() - parsedDate.getTimezoneOffset());
}
@@ -18628,8 +18821,7 @@ function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
stringBasedInputType(ctrl);
ctrl.$$parserName = 'url';
- ctrl.$validators.url = function(modelValue, viewValue) {
- var value = modelValue || viewValue;
+ ctrl.$validators.url = function(value) {
return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
};
}
@@ -18641,8 +18833,7 @@ function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
stringBasedInputType(ctrl);
ctrl.$$parserName = 'email';
- ctrl.$validators.email = function(modelValue, viewValue) {
- var value = modelValue || viewValue;
+ ctrl.$validators.email = function(value) {
return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
};
}
@@ -18696,7 +18887,7 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
element[0].checked = ctrl.$viewValue;
};
- // Override the standard `$isEmpty` because a value of `false` means empty in a checkbox.
+ // Override the standard `$isEmpty` because an empty checkbox is never equal to the trueValue
ctrl.$isEmpty = function(value) {
return value !== trueValue;
};
@@ -19155,7 +19346,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
* default. The `checkboxInputType` directive does this because in its case a value of `false`
* implies empty.
*
- * @param {*} value Reference to check.
+ * @param {*} value Model value to check.
* @returns {boolean} True if `value` is empty.
*/
this.$isEmpty = function(value) {
@@ -19342,9 +19533,11 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
// check parser error
if (!processParseErrors(parseValid)) {
+ validationDone(false);
return;
}
if (!processSyncValidators()) {
+ validationDone(false);
return;
}
processAsyncValidators();
@@ -19362,7 +19555,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
forEach(ctrl.$asyncValidators, function(v, name) {
setValidity(name, null);
});
- validationDone();
return false;
}
}
@@ -19380,7 +19572,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
forEach(ctrl.$asyncValidators, function(v, name) {
setValidity(name, null);
});
- validationDone();
return false;
}
return true;
@@ -19388,6 +19579,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
function processAsyncValidators() {
var validatorPromises = [];
+ var allValid = true;
forEach(ctrl.$asyncValidators, function(validator, name) {
var promise = validator(modelValue, viewValue);
if (!isPromiseLike(promise)) {
@@ -19398,13 +19590,16 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
validatorPromises.push(promise.then(function() {
setValidity(name, true);
}, function(error) {
+ allValid = false;
setValidity(name, false);</