Commit 5a53ef13 authored by Pascal Hartig's avatar Pascal Hartig

Angular: Update to 1.2.19

parent 36e2ffa2
......@@ -2,11 +2,11 @@
"name": "todomvc-angular",
"version": "0.0.0",
"dependencies": {
"angular": "1.2.18",
"angular": "1.2.19",
"todomvc-common": "~0.1.4"
},
"devDependencies": {
"angular-mocks": "1.2.18",
"angular-route": "1.2.18"
"angular-mocks": "1.2.19",
"angular-route": "1.2.19"
}
}
/**
* @license AngularJS v1.2.18
* @license AngularJS v1.2.19
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
......
/**
* @license AngularJS v1.2.18
* @license AngularJS v1.2.19
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
......@@ -68,7 +68,7 @@ function minErr(module) {
return match;
});
message = message + '\nhttp://errors.angularjs.org/1.2.18/' +
message = message + '\nhttp://errors.angularjs.org/1.2.19/' +
(module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
......@@ -92,6 +92,7 @@ function minErr(module) {
-angularModule,
-nodeName_,
-uid,
-VALIDITY_STATE_PROPERTY,
-lowercase,
-uppercase,
......@@ -181,6 +182,10 @@ function minErr(module) {
* <div doc-module-components="ng"></div>
*/
// The name of a form control's ValidityState property.
// This is used so that it's possible for internal tests to create mock ValidityStates.
var VALIDITY_STATE_PROPERTY = 'validity';
/**
* @ngdoc function
* @name angular.lowercase
......@@ -1483,7 +1488,7 @@ function assertArgFn(arg, name, acceptArrayAnnotation) {
}
assertArg(isFunction(arg), name, 'not a function, got ' +
(arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg));
(arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
return arg;
}
......@@ -1953,11 +1958,11 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
full: '1.2.18', // all of these placeholder strings will be replaced by grunt's
full: '1.2.19', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 2,
dot: 18,
codeName: 'ear-extendability'
dot: 19,
codeName: 'precognitive-flashbacks'
};
......@@ -2179,8 +2184,9 @@ function publishExternalAPI(angular){
* @returns {Object} jQuery object.
*/
JQLite.expando = 'ng339';
var jqCache = JQLite.cache = {},
jqName = JQLite.expando = 'ng' + new Date().getTime(),
jqId = 1,
addEventListenerFn = (window.document.addEventListener
? function(element, type, fn) {element.addEventListener(type, fn, false);}
......@@ -2390,7 +2396,7 @@ function jqLiteOff(element, type, fn, unsupported) {
}
function jqLiteRemoveData(element, name) {
var expandoId = element[jqName],
var expandoId = element.ng339,
expandoStore = jqCache[expandoId];
if (expandoStore) {
......@@ -2404,17 +2410,17 @@ function jqLiteRemoveData(element, name) {
jqLiteOff(element);
}
delete jqCache[expandoId];
element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
}
}
function jqLiteExpandoStore(element, key, value) {
var expandoId = element[jqName],
var expandoId = element.ng339,
expandoStore = jqCache[expandoId || -1];
if (isDefined(value)) {
if (!expandoStore) {
element[jqName] = expandoId = jqNextId();
element.ng339 = expandoId = jqNextId();
expandoStore = jqCache[expandoId] = {};
}
expandoStore[key] = value;
......@@ -3081,16 +3087,16 @@ forEach({
* @returns {string} hash string such that the same input will have the same hash string.
* The resulting string key is in 'type:hashKey' format.
*/
function hashKey(obj) {
function hashKey(obj, nextUidFn) {
var objType = typeof obj,
key;
if (objType == 'object' && obj !== null) {
if (objType == 'function' || (objType == 'object' && obj !== null)) {
if (typeof (key = obj.$$hashKey) == 'function') {
// must invoke on object to keep the right this
key = obj.$$hashKey();
} else if (key === undefined) {
key = obj.$$hashKey = nextUid();
key = obj.$$hashKey = (nextUidFn || nextUid)();
}
} else {
key = obj;
......@@ -3102,7 +3108,13 @@ function hashKey(obj) {
/**
* HashMap which can use objects as keys
*/
function HashMap(array){
function HashMap(array, isolatedUid) {
if (isolatedUid) {
var uid = 0;
this.nextUid = function() {
return ++uid;
};
}
forEach(array, this.put, this);
}
HashMap.prototype = {
......@@ -3112,7 +3124,7 @@ HashMap.prototype = {
* @param value value to store can be any type
*/
put: function(key, value) {
this[hashKey(key)] = value;
this[hashKey(key, this.nextUid)] = value;
},
/**
......@@ -3120,7 +3132,7 @@ HashMap.prototype = {
* @returns {Object} the value for the key
*/
get: function(key) {
return this[hashKey(key)];
return this[hashKey(key, this.nextUid)];
},
/**
......@@ -3128,7 +3140,7 @@ HashMap.prototype = {
* @param key
*/
remove: function(key) {
var value = this[key = hashKey(key)];
var value = this[key = hashKey(key, this.nextUid)];
delete this[key];
return value;
}
......@@ -3206,7 +3218,7 @@ function annotate(fn) {
argDecl,
last;
if (typeof fn == 'function') {
if (typeof fn === 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
......@@ -3419,7 +3431,7 @@ function annotate(fn) {
/**
* @ngdoc object
* @ngdoc service
* @name $provide
*
* @description
......@@ -3725,7 +3737,7 @@ function createInjector(modulesToLoad) {
var INSTANTIATING = {},
providerSuffix = 'Provider',
path = [],
loadedModules = new HashMap(),
loadedModules = new HashMap([], true),
providerCache = {
$provide: {
provider: supportObject(provider),
......@@ -3896,8 +3908,7 @@ function createInjector(modulesToLoad) {
: getService(key)
);
}
if (!fn.$inject) {
// this means that we must be an array.
if (isArray(fn)) {
fn = fn[length];
}
......@@ -6078,7 +6089,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective);
// iterate over the attributes
for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes,
for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
var attrStartName = false;
var attrEndName = false;
......@@ -6086,9 +6097,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
attr = nAttrs[j];
if (!msie || msie >= 8 || attr.specified) {
name = attr.name;
value = trim(attr.value);
// support ngAttr attribute binding
ngAttrName = directiveNormalize(name);
if (NG_ATTR_BINDING.test(ngAttrName)) {
if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) {
name = snake_case(ngAttrName.substr(6), '-');
}
......@@ -6101,10 +6114,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
nName = directiveNormalize(name.toLowerCase());
attrsMap[nName] = name;
attrs[nName] = value = trim(attr.value);
if (isNgAttr || !attrs.hasOwnProperty(nName)) {
attrs[nName] = value;
if (getBooleanAttrName(node, nName)) {
attrs[nName] = true; // presence means true
}
}
addAttrInterpolateDirective(node, directives, value, nName);
addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,
attrEndName);
......@@ -7201,7 +7216,7 @@ function $ControllerProvider() {
instance = $injector.instantiate(expression, locals);
if (identifier) {
if (!(locals && typeof locals.$scope == 'object')) {
if (!(locals && typeof locals.$scope === 'object')) {
throw minErr('$controller')('noscp',
"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.",
constructor || expression.name, identifier);
......@@ -8403,7 +8418,8 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
// Safari respectively.
if (xhr && xhr.readyState == 4) {
var responseHeaders = null,
response = null;
response = null,
statusText = '';
if(status !== ABORTED) {
responseHeaders = xhr.getAllResponseHeaders();
......@@ -8413,11 +8429,17 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
response = ('response' in xhr) ? xhr.response : xhr.responseText;
}
// Accessing statusText on an aborted xhr object will
// throw an 'c00c023f error' in IE9 and lower, don't touch it.
if (!(status === ABORTED && msie < 10)) {
statusText = xhr.statusText;
}
completeRequest(callback,
status || xhr.status,
response,
responseHeaders,
xhr.statusText || '');
statusText);
}
};
......@@ -8951,7 +8973,7 @@ function $IntervalProvider() {
interval.cancel = function(promise) {
if (promise && promise.$$intervalId in intervals) {
intervals[promise.$$intervalId].reject('canceled');
clearInterval(promise.$$intervalId);
$window.clearInterval(promise.$$intervalId);
delete intervals[promise.$$intervalId];
return true;
}
......@@ -9585,7 +9607,7 @@ function $LocationProvider(){
html5Mode = false;
/**
* @ngdoc property
* @ngdoc method
* @name $locationProvider#hashPrefix
* @description
* @param {string=} prefix Prefix for hash part (containing path and search)
......@@ -9601,7 +9623,7 @@ function $LocationProvider(){
};
/**
* @ngdoc property
* @ngdoc method
* @name $locationProvider#html5Mode
* @description
* @param {boolean=} mode Use HTML5 strategy if available.
......@@ -9959,14 +9981,7 @@ var promiseWarning;
//
// As an example, consider the following Angular expression:
//
// {}.toString.constructor(alert("evil JS code"))
//
// We want to prevent this type of access. For the sake of performance, during the lexing phase we
// disallow any "dotted" access to any member named "constructor".
//
// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor
// while evaluating the expression, which is a stronger but more expensive test. Since reflective
// calls are expensive anyway, this is not such a big deal compared to static dereferencing.
// {}.toString.constructor('alert("evil JS code")')
//
// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
// against the expression language, but not to prevent exploits that were enabled by exposing
......@@ -9974,17 +9989,19 @@ var promiseWarning;
// practice and therefore we are not even trying to protect against interaction with an object
// explicitly exposed in this way.
//
// A developer could foil the name check by aliasing the Function constructor under a different
// name on the scope.
//
// In general, it is not possible to access a Window object from an angular expression unless a
// window or some DOM object that has a reference to window is published onto a Scope.
// Similarly we prevent invocations of function known to be dangerous, as well as assignments to
// native objects.
function ensureSafeMemberName(name, fullExpression) {
if (name === "constructor") {
if (name === "__defineGetter__" || name === "__defineSetter__"
|| name === "__lookupGetter__" || name === "__lookupSetter__"
|| name === "__proto__") {
throw $parseMinErr('isecfld',
'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}',
fullExpression);
'Attempting to access a disallowed field in Angular expressions! '
+'Expression: {0}', fullExpression);
}
return name;
}
......@@ -10006,11 +10023,34 @@ function ensureSafeObject(obj, fullExpression) {
throw $parseMinErr('isecdom',
'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}',
fullExpression);
} else if (// block Object so that we can't get hold of dangerous Object.* methods
obj === Object) {
throw $parseMinErr('isecobj',
'Referencing Object in Angular expressions is disallowed! Expression: {0}',
fullExpression);
}
}
return obj;
}
var CALL = Function.prototype.call;
var APPLY = Function.prototype.apply;
var BIND = Function.prototype.bind;
function ensureSafeFunction(obj, fullExpression) {
if (obj) {
if (obj.constructor === obj) {
throw $parseMinErr('isecfn',
'Referencing Function in Angular expressions is disallowed! Expression: {0}',
fullExpression);
} else if (obj === CALL || obj === APPLY || (BIND && obj === BIND)) {
throw $parseMinErr('isecff',
'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}',
fullExpression);
}
}
}
var OPERATORS = {
/* jshint bitwise : false */
'null':function(){return null;},
......@@ -10645,6 +10685,7 @@ Parser.prototype = {
i = indexFn(self, locals),
v, p;
ensureSafeMemberName(i, parser.text);
if (!o) return undefined;
v = ensureSafeObject(o[i], parser.text);
if (v && v.then && parser.options.unwrapPromises) {
......@@ -10687,7 +10728,7 @@ Parser.prototype = {
var fnPtr = fn(scope, locals, context) || noop;
ensureSafeObject(context, parser.text);
ensureSafeObject(fnPtr, parser.text);
ensureSafeFunction(fnPtr, parser.text);
// IE stupidity! (IE doesn't have apply for some native functions)
var v = fnPtr.apply
......@@ -10796,6 +10837,8 @@ function setter(obj, path, setValue, fullExp, options) {
}
}
key = ensureSafeMemberName(element.shift(), fullExp);
ensureSafeObject(obj, fullExp);
ensureSafeObject(obj[key], fullExp);
obj[key] = setValue;
return setValue;
}
......@@ -11215,9 +11258,6 @@ function $ParseProvider() {
* var deferred = $q.defer();
*
* setTimeout(function() {
* // since this fn executes async in a future turn of the event loop, we need to wrap
* // our code into an $apply call so that the model changes are properly observed.
* scope.$apply(function() {
* deferred.notify('About to greet ' + name + '.');
*
* if (okToGreet(name)) {
......@@ -11225,7 +11265,6 @@ function $ParseProvider() {
* } else {
* deferred.reject('Greeting ' + name + ' is not allowed.');
* }
* });
* }, 1000);
*
* return deferred.promise;
......@@ -12387,7 +12426,7 @@ function $RootScopeProvider(){
if ((value = watch.get(current)) !== (last = watch.last) &&
!(watch.eq
? equals(value, last)
: (typeof value == 'number' && typeof last == 'number'
: (typeof value === 'number' && typeof last === 'number'
&& isNaN(value) && isNaN(last)))) {
dirty = true;
lastDirtyWatch = watch;
......@@ -13732,7 +13771,7 @@ function $SceProvider() {
/**
* @ngdoc method
* @name $sce#parse
* @name $sce#parseAs
*
* @description
* Converts Angular {@link guide/expression expression} into a function. This is like {@link
......@@ -14688,7 +14727,7 @@ function filterFilter() {
// jshint +W086
for (var key in expression) {
(function(path) {
if (typeof expression[path] == 'undefined') return;
if (typeof expression[path] === 'undefined') return;
predicates.push(function(value) {
return search(path == '$' ? value : (value && value[path]), expression[path]);
});
......@@ -14843,6 +14882,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
if (match && match[2] == '-' && match[3] > fractionSize + 1) {
numStr = '0';
number = 0;
} else {
formatedText = numStr;
hasExponent = true;
......@@ -14857,8 +14897,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac);
}
var pow = Math.pow(10, fractionSize + 1);
number = Math.floor(number * pow + 5) / pow;
// safely round numbers in JS without hitting imprecisions of floating-point arithmetics
// inspired by:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);
var fraction = ('' + number).split(DECIMAL_SEP);
var whole = fraction[0];
fraction = fraction[1] || '';
......@@ -16360,7 +16403,7 @@ var ngFormDirective = formDirectiveFactory(true);
*/
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
var inputType = {
......@@ -16786,15 +16829,29 @@ function validate(ctrl, validatorName, validity, value){
return validity ? value : undefined;
}
function testFlags(validity, flags) {
var i, flag;
if (flags) {
for (i=0; i<flags.length; ++i) {
flag = flags[i];
if (validity[flag]) {
return true;
}
}
}
return false;
}
function addNativeHtml5Validators(ctrl, validatorName, element) {
var validity = element.prop('validity');
// Pass validity so that behaviour can be mocked easier.
function addNativeHtml5Validators(ctrl, validatorName, badFlags, ignoreFlags, validity) {
if (isObject(validity)) {
ctrl.$$hasNativeValidators = true;
var validator = function(value) {
// Don't overwrite previous validation, don't consider valueMissing to apply (ng-required can
// perform the required validation)
if (!ctrl.$error[validatorName] && (validity.badInput || validity.customError ||
validity.typeMismatch) && !validity.valueMissing) {
if (!ctrl.$error[validatorName] &&
!testFlags(validity, ignoreFlags) &&
testFlags(validity, badFlags)) {
ctrl.$setValidity(validatorName, false);
return;
}
......@@ -16805,8 +16862,9 @@ function addNativeHtml5Validators(ctrl, validatorName, element) {
}
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
var validity = element.prop('validity');
var validity = element.prop(VALIDITY_STATE_PROPERTY);
var placeholder = element[0].placeholder, noevent = {};
ctrl.$$validityState = validity;
// In composition mode, users are still inputing intermediate text buffer,
// hold the listener until composition is done.
......@@ -16844,11 +16902,11 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
value = trim(value);
}
if (ctrl.$viewValue !== value ||
// If the value is still empty/falsy, and there is no `required` error, run validators
// again. This enables HTML5 constraint validation errors to affect Angular validation
// even when the first character entered causes an error.
(validity && value === '' && !validity.valueMissing)) {
// If a control is suffering from bad input, browsers discard its value, so it may be
// necessary to revalidate even if the control's value is the same empty value twice in
// a row.
var revalidate = validity && ctrl.$$hasNativeValidators;
if (ctrl.$viewValue !== value || (value === '' && revalidate)) {
if (scope.$$phase) {
ctrl.$setViewValue(value);
} else {
......@@ -16954,6 +17012,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
}
}
var numberBadFlags = ['badInput'];
function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
......@@ -16968,7 +17028,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
}
});
addNativeHtml5Validators(ctrl, 'number', element);
addNativeHtml5Validators(ctrl, 'number', numberBadFlags, null, ctrl.$$validityState);
ctrl.$formatters.push(function(value) {
return ctrl.$isEmpty(value) ? '' : '' + value;
......@@ -17450,7 +17510,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
* This method should be called by validators - i.e. the parser or formatter functions.
*
* @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign
* to `$error[validationErrorKey]=isValid` so that it is available for data-binding.
* to `$error[validationErrorKey]=!isValid` so that it is available for data-binding.
* The `validationErrorKey` should be in camelCase and will get converted into dash-case
* for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
* class and can be bound to as `{{someForm.someControl.$error.myError}}` .
......@@ -19834,7 +19894,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
* When one person, perhaps John, views the document, "John is viewing" will be shown.
* When three people view the document, no explicit number rule is found, so
* an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
* In this case, plural category 'one' is matched and "John, Marry and one other person are viewing"
* In this case, plural category 'one' is matched and "John, Mary and one other person are viewing"
* is shown.
*
* Note that when you specify offsets, you must provide explicit number rules for
......@@ -20716,7 +20776,7 @@ var ngHideDirective = ['$animate', function($animate) {
<file name="protractor.js" type="protractor">
var colorSpan = element(by.css('span'));
iit('should check ng-style', function() {
it('should check ng-style', function() {
expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
element(by.css('input[value=\'set color\']')).click();
expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
......@@ -21609,7 +21669,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
// rather then the element.
(element = optionTemplate.clone())
.val(option.id)
.attr('selected', option.selected)
.prop('selected', option.selected)
.text(option.label);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment