From 40c7d904c328179782745e8452be2a596d29c521 Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Tue, 1 May 2012 23:10:36 -0400 Subject: bump angular to rc7 --- alias-angular/app/lib/angular/angular.js | 427 ++++++++++++++++++++------- alias-angular/app/lib/angular/angular.min.js | 303 ++++++++++--------- 2 files changed, 471 insertions(+), 259 deletions(-) (limited to 'alias-angular/app/lib') diff --git a/alias-angular/app/lib/angular/angular.js b/alias-angular/app/lib/angular/angular.js index b621c96..dca7169 100644 --- a/alias-angular/app/lib/angular/angular.js +++ b/alias-angular/app/lib/angular/angular.js @@ -1,6 +1,6 @@ /** - * @license AngularJS v1.0.0rc5 - * (c) 2010-2012 AngularJS http://angularjs.org + * @license AngularJS v1.0.0rc7 + * (c) 2010-2012 Google, Inc. http://angularjs.org * License: MIT */ (function(window, document, undefined) { @@ -8,9 +8,6 @@ //////////////////////////////////// -if (typeof document.getAttribute == 'undefined') - document.getAttribute = function() {}; - /** * @ngdoc function * @name angular.lowercase @@ -1246,11 +1243,11 @@ function setupModuleLoader(window) { * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.0.0rc5', // all of these placeholder strings will be replaced by rake's + full: '1.0.0rc7', // all of these placeholder strings will be replaced by rake's major: 1, // compile task minor: 0, dot: 0, - codeName: 'reality-distortion' + codeName: 'rc-generation' }; @@ -1308,6 +1305,7 @@ function publishExternalAPI(angular){ ngClass: ngClassDirective, ngClassEven: ngClassEvenDirective, ngClassOdd: ngClassOddDirective, + ngCsp: ngCspDirective, ngCloak: ngCloakDirective, ngController: ngControllerDirective, ngForm: ngFormDirective, @@ -1876,8 +1874,8 @@ function createEventHandler(element) { // Remove monkey-patched methods (IE), // as they would cause memory leaks in IE8. - if (msie < 8) { - // IE7 does not allow to delete property on native object + if (msie <= 8) { + // IE7/8 does not allow to delete property on native object event.preventDefault = null; event.stopPropagation = null; event.isDefaultPrevented = null; @@ -1921,14 +1919,12 @@ forEach({ bindFn(element, 'mouseover', function(event) { counter++; if (counter == 1) { - event.type = 'mouseenter'; mouseenter(event); } }); bindFn(element, 'mouseout', function(event) { counter --; if (counter == 0) { - event.type = 'mouseleave'; mouseleave(event); } }); @@ -3365,7 +3361,7 @@ function $TemplateCacheProvider() { * Calling the linking function returns the element of the template. It is either the original element * passed in, or the clone of the element if the `cloneAttachFn` is provided. * - * After linking the view is not updateh until after a call to $digest which typically is done by + * After linking the view is not updated until after a call to $digest which typically is done by * Angular automatically. * * If you need access to the bound view, there are two ways to do it: @@ -3742,12 +3738,17 @@ function $CompileProvider($provide) { addTextInterpolateDirective(directives, node.nodeValue); break; case 8: /* Comment */ - match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue); - if (match) { - nName = directiveNormalize(match[1]); - if (addDirective(directives, nName, 'M', maxPriority)) { - attrs[nName] = trim(match[2]); + try { + match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue); + if (match) { + nName = directiveNormalize(match[1]); + if (addDirective(directives, nName, 'M', maxPriority)) { + attrs[nName] = trim(match[2]); + } } + } catch (e) { + // turns out that under some circumstances IE9 throws errors when one attempts to read comment's node value. + // Just ignore it and continue. (Can't seem to reproduce in test case.) } break; } @@ -5275,7 +5276,7 @@ var OPERATORS = { }; var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; -function lex(text){ +function lex(text, csp){ var tokens = [], token, index = 0, @@ -5435,7 +5436,7 @@ function lex(text){ if (OPERATORS.hasOwnProperty(ident)) { token.fn = token.json = OPERATORS[ident]; } else { - var getter = getterFn(ident); + var getter = getterFn(ident, csp); token.fn = extend(function(self, locals) { return (getter(self, locals)); }, { @@ -5509,10 +5510,10 @@ function lex(text){ ///////////////////////////////////////// -function parser(text, json, $filter){ +function parser(text, json, $filter, csp){ var ZERO = valueFn(0), value, - tokens = lex(text), + tokens = lex(text, csp), assignment = _assignment, functionCall = _functionCall, fieldAccess = _fieldAccess, @@ -5780,7 +5781,7 @@ function parser(text, json, $filter){ function _fieldAccess(object) { var field = expect().text; - var getter = getterFn(field); + var getter = getterFn(field, csp); return extend( function(self, locals) { return getter(object(self, locals), locals); @@ -5933,32 +5934,119 @@ function getter(obj, path, bindFnToScope) { var getterFnCache = {}; -function getterFn(path) { +/** + * Implementation of the "Black Hole" variant from: + * - http://jsperf.com/angularjs-parse-getter/4 + * - http://jsperf.com/path-evaluation-simplified/7 + */ +function cspSafeGetterFn(key0, key1, key2, key3, key4) { + return function(scope, locals) { + var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope, + promise; + + if (!pathVal) return pathVal; + + pathVal = pathVal[key0]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key1 || !pathVal) return pathVal; + + pathVal = pathVal[key1]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key2 || !pathVal) return pathVal; + + pathVal = pathVal[key2]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key3 || !pathVal) return pathVal; + + pathVal = pathVal[key3]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + if (!key4 || !pathVal) return pathVal; + + pathVal = pathVal[key4]; + if (pathVal && pathVal.then) { + if (!("$$v" in pathVal)) { + promise = pathVal; + promise.$$v = undefined; + promise.then(function(val) { promise.$$v = val; }); + } + pathVal = pathVal.$$v; + } + return pathVal; + }; +}; + +function getterFn(path, csp) { if (getterFnCache.hasOwnProperty(path)) { return getterFnCache[path]; } - var fn, code = 'var l, fn, p;\n'; - forEach(path.split('.'), function(key, index) { - code += 'if(!s) return s;\n' + - 'l=s;\n' + - 's='+ (index - // we simply direference 's' on any .dot notation - ? 's' - // but if we are first then we check locals firs, and if so read it first - : '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' + - 'if (s && s.then) {\n' + - ' if (!("$$v" in s)) {\n' + - ' p=s;\n' + - ' p.$$v = undefined;\n' + - ' p.then(function(v) {p.$$v=v;});\n' + - '}\n' + - ' s=s.$$v\n' + - '}\n'; - }); - code += 'return s;'; - fn = Function('s', 'k', code); - fn.toString = function() { return code; }; + var pathKeys = path.split('.'), + pathKeysLength = pathKeys.length, + fn; + + if (csp) { + fn = (pathKeysLength < 6) + ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4]) + : function(scope, locals) { + var i = 0, val; + do { + val = cspSafeGetterFn( + pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++] + )(scope, locals); + locals = undefined; // clear after first iteration + } while (i < pathKeysLength); + }; + } else { + var code = 'var l, fn, p;\n'; + forEach(pathKeys, function(key, index) { + code += 'if(!s) return s;\n' + + 'l=s;\n' + + 's='+ (index + // we simply dereference 's' on any .dot notation + ? 's' + // but if we are first then we check locals first, and if so read it first + : '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' + + 'if (s && s.then) {\n' + + ' if (!("$$v" in s)) {\n' + + ' p=s;\n' + + ' p.$$v = undefined;\n' + + ' p.then(function(v) {p.$$v=v;});\n' + + '}\n' + + ' s=s.$$v\n' + + '}\n'; + }); + code += 'return s;'; + fn = Function('s', 'k', code); // s=scope, k=locals + fn.toString = function() { return code; }; + } return getterFnCache[path] = fn; } @@ -5967,13 +6055,13 @@ function getterFn(path) { function $ParseProvider() { var cache = {}; - this.$get = ['$filter', function($filter) { + this.$get = ['$filter', '$sniffer', function($filter, $sniffer) { return function(exp) { switch(typeof exp) { case 'string': return cache.hasOwnProperty(exp) ? cache[exp] - : cache[exp] = parser(exp, false, $filter); + : cache[exp] = parser(exp, false, $filter, $sniffer.csp); case 'function': return exp; default: @@ -7549,7 +7637,9 @@ function $SnifferProvider() { } return eventSupport[event]; - } + }, + // TODO(i): currently there is no way to feature detect CSP without triggering alerts + csp: false }; }]; } @@ -11264,7 +11354,7 @@ var ngValueDirective = [function() { * * Once scenario in which the use of `ngBind` is prefered over `{{ expression }}` binding is when * it's desirable to put bindings into template that is momentarily displayed by the browser in its - * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes make the + * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the * bindings invisible to the user while the page is loading. * * An alternative solution to this problem would be using the @@ -11371,10 +11461,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) { * @description * Creates a binding that will innerHTML the result of evaluating the `expression` into the current * element. *The innerHTML-ed content will not be sanitized!* You should use this directive only if - * {@link angular.module.ng.$compileProvider.directive.ngBindHtml ngBindHtml} directive is too + * {@link angular.module.ngSanitize.directive.ngBindHtml ngBindHtml} directive is too * restrictive and when you absolutely trust the source of the content you are binding to. * - * See {@link angular.module.ng.$sanitize $sanitize} docs for examples. + * See {@link angular.module.ngSanitize.$sanitize $sanitize} docs for examples. * * @element ANY * @param {expression} ngBindHtmlUnsafe {@link guide/dev_guide.expressions Expression} to evaluate. @@ -11692,6 +11782,32 @@ var ngControllerDirective = [function() { }; }]; +/** + * @ngdoc directive + * @name angular.module.ng.$compileProvider.directive.ngCsp + * @priority 1000 + * + * @description + * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support. + * This directive should be used on the root element of the application (typically the `` + * element or other element with the {@link angular.module.ng.$compileProvider.directive.ngApp ngApp} + * directive). + * + * If enabled the performance of template expression evaluator will suffer slightly, so don't enable + * this mode unless you need it. + * + * @element html + */ + +var ngCspDirective = ['$sniffer', function($sniffer) { + return { + priority: 1000, + compile: function() { + $sniffer.csp = true; + } + }; +}]; + /** * @ngdoc directive * @name angular.module.ng.$compileProvider.directive.ngClick @@ -12982,8 +13098,11 @@ var scriptDirective = ['$templateCache', function($templateCache) { terminal: true, compile: function(element, attr) { if (attr.type == 'text/ng-template') { - var templateUrl = attr.id; - $templateCache.put(templateUrl, element.text()); + var templateUrl = attr.id, + // IE is not consistent, in scripts we have to read .text but in other nodes we have to read .textContent + text = element[0].text; + + $templateCache.put(templateUrl, text); } } }; @@ -13011,16 +13130,10 @@ var scriptDirective = ['$templateCache', function($templateCache) { * be nested into the `
Color (null allowed): -
+ -

+
Color grouped by shade: and IE barfs otherwise. + optionTemplate = jqLite(document.createElement('option')), + optGroupTemplate =jqLite(document.createElement('optgroup')), + unknownOption = optionTemplate.clone(); + + // find "null" option + for(var i = 0, children = element.children(), ii = children.length; i < ii; i++) { + if (children[i].value == '') { + emptyOption = nullOption = children.eq(i); + break; + } + } + + selectCtrl.init(ngModelCtrl, nullOption, unknownOption); // required validator if (multiple && (attr.required || attr.ngRequired)) { var requiredValidator = function(value) { - ctrl.$setValidity('required', !attr.required || (value && value.length)); + ngModelCtrl.$setValidity('required', !attr.required || (value && value.length)); return value; }; - ctrl.$parsers.push(requiredValidator); - ctrl.$formatters.unshift(requiredValidator); + ngModelCtrl.$parsers.push(requiredValidator); + ngModelCtrl.$formatters.unshift(requiredValidator); attr.$observe('required', function() { - requiredValidator(ctrl.$viewValue); + requiredValidator(ngModelCtrl.$viewValue); }); } - if (optionsExp) Options(scope, element, ctrl); - else if (multiple) Multiple(scope, element, ctrl); - else Single(scope, element, ctrl); + if (optionsExp) Options(scope, element, ngModelCtrl); + else if (multiple) Multiple(scope, element, ngModelCtrl); + else Single(scope, element, ngModelCtrl, selectCtrl); //////////////////////////// - function Single(scope, selectElement, ctrl) { - ctrl.$render = function() { - selectElement.val(ctrl.$viewValue); + function Single(scope, selectElement, ngModelCtrl, selectCtrl) { + ngModelCtrl.$render = function() { + var viewValue = ngModelCtrl.$viewValue; + + if (selectCtrl.hasOption(viewValue)) { + if (unknownOption.parent()) unknownOption.remove(); + selectElement.val(viewValue); + if (viewValue === '') emptyOption.prop('selected', true); // to make IE9 happy + } else { + if (isUndefined(viewValue) && emptyOption) { + selectElement.val(''); + } else { + selectCtrl.renderUnknownOption(viewValue); + } + } }; selectElement.bind('change', function() { scope.$apply(function() { - ctrl.$setViewValue(selectElement.val()); + if (unknownOption.parent()) unknownOption.remove(); + ngModelCtrl.$setViewValue(selectElement.val()); }); }); } @@ -13208,26 +13408,26 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { groupByFn = $parse(match[3] || ''), valueFn = $parse(match[2] ? match[1] : valueName), valuesFn = $parse(match[7]), - // we can't just jqLite('