aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng
diff options
context:
space:
mode:
Diffstat (limited to 'src/ng')
-rw-r--r--src/ng/compile.js4
-rw-r--r--src/ng/controller.js1
-rw-r--r--src/ng/directive/form.js5
-rw-r--r--src/ng/directive/ngRepeat.js2
-rw-r--r--src/ng/directive/select.js4
-rw-r--r--src/ng/parse.js22
6 files changed, 34 insertions, 4 deletions
diff --git a/src/ng/compile.js b/src/ng/compile.js
index fce6f34e..55de18ec 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -178,6 +178,7 @@ function $CompileProvider($provide) {
* @returns {ng.$compileProvider} Self for chaining.
*/
this.directive = function registerDirective(name, directiveFactory) {
+ assertNotHasOwnProperty(name, 'directive');
if (isString(name)) {
assertArg(directiveFactory, 'directiveFactory');
if (!hasDirectives.hasOwnProperty(name)) {
@@ -1175,6 +1176,9 @@ function $CompileProvider($provide) {
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
} else if (key == 'style') {
$element.attr('style', $element.attr('style') + ';' + value);
+ // `dst` will never contain hasOwnProperty as DOM parser won't let it.
+ // You will get an "InvalidCharacterError: DOM Exception 5" error if you
+ // have an attribute like "has-own-property" or "data-has-own-property", etc.
} else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) {
dst[key] = value;
dstAttr[key] = srcAttr[key];
diff --git a/src/ng/controller.js b/src/ng/controller.js
index 2203c698..dc291c8c 100644
--- a/src/ng/controller.js
+++ b/src/ng/controller.js
@@ -25,6 +25,7 @@ function $ControllerProvider() {
* annotations in the array notation).
*/
this.register = function(name, constructor) {
+ assertNotHasOwnProperty(name, 'controller');
if (isObject(name)) {
extend(controllers, name)
} else {
diff --git a/src/ng/directive/form.js b/src/ng/directive/form.js
index ed9d7052..455ad15f 100644
--- a/src/ng/directive/form.js
+++ b/src/ng/directive/form.js
@@ -73,9 +73,12 @@ function FormController(element, attrs) {
* Input elements using ngModelController do this automatically when they are linked.
*/
form.$addControl = function(control) {
+ // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
+ // and not added to the scope. Now we throw an error.
+ assertNotHasOwnProperty(control.$name, 'input');
controls.push(control);
- if (control.$name && !form.hasOwnProperty(control.$name)) {
+ if (control.$name) {
form[control.$name] = control;
}
};
diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js
index 16a810ef..78b054ff 100644
--- a/src/ng/directive/ngRepeat.js
+++ b/src/ng/directive/ngRepeat.js
@@ -305,6 +305,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
key = (collection === collectionKeys) ? index : collectionKeys[index];
value = collection[key];
trackById = trackByIdFn(key, value, index);
+ assertNotHasOwnProperty(trackById, '`track by` id');
if(lastBlockMap.hasOwnProperty(trackById)) {
block = lastBlockMap[trackById]
delete lastBlockMap[trackById];
@@ -327,6 +328,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
// remove existing items
for (key in lastBlockMap) {
+ // lastBlockMap is our own object so we don't need to use special hasOwnPropertyFn
if (lastBlockMap.hasOwnProperty(key)) {
block = lastBlockMap[key];
$animate.leave(block.elements);
diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js
index 0b6288c1..fb03e0ca 100644
--- a/src/ng/directive/select.js
+++ b/src/ng/directive/select.js
@@ -1,5 +1,6 @@
'use strict';
+var ngOptionsMinErr = minErr('ngOptions');
/**
* @ngdoc directive
* @name ng.directive:select
@@ -152,6 +153,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
self.addOption = function(value) {
+ assertNotHasOwnProperty(value, '"option value"');
optionsMap[value] = true;
if (ngModelCtrl.$viewValue == value) {
@@ -300,7 +302,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
var match;
if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
- throw minErr('ngOptions')('iexp',
+ throw ngOptionsMinErr('iexp',
"Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}",
optionsExp, startingTag(selectElement));
}
diff --git a/src/ng/parse.js b/src/ng/parse.js
index 4a1921fc..682b497b 100644
--- a/src/ng/parse.js
+++ b/src/ng/parse.js
@@ -290,6 +290,7 @@ Lexer.prototype = {
text: ident
};
+ // OPERATORS is our own object so we don't need to use special hasOwnPropertyFn
if (OPERATORS.hasOwnProperty(ident)) {
token.fn = OPERATORS[ident];
token.json = OPERATORS[ident];
@@ -938,6 +939,9 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp) {
}
function getterFn(path, csp, fullExp) {
+ // Check whether the cache has this getter already.
+ // We can use hasOwnProperty directly on the cache because we ensure,
+ // see below, that the cache never stores a path called 'hasOwnProperty'
if (getterFnCache.hasOwnProperty(path)) {
return getterFnCache[path];
}
@@ -986,7 +990,12 @@ function getterFn(path, csp, fullExp) {
fn.toString = function() { return code; };
}
- return getterFnCache[path] = fn;
+ // Only cache the value if it's not going to mess up the cache object
+ // This is more performant that using Object.prototype.hasOwnProperty.call
+ if (path !== 'hasOwnProperty') {
+ getterFnCache[path] = fn;
+ }
+ return fn;
}
///////////////////////////////////
@@ -1036,6 +1045,7 @@ function $ParseProvider() {
return function(exp) {
var lexer = new Lexer($sniffer.csp);
var parser = new Parser(lexer, $filter, $sniffer.csp);
+ var parsedExpression;
switch (typeof exp) {
case 'string':
@@ -1043,7 +1053,15 @@ function $ParseProvider() {
return cache[exp];
}
- return cache[exp] = parser.parse(exp, false);
+ parsedExpression = parser.parse(exp, false);
+
+ if (exp !== 'hasOwnProperty') {
+ // Only cache the value if it's not going to mess up the cache object
+ // This is more performant that using Object.prototype.hasOwnProperty.call
+ cache[exp] = parsedExpression;
+ }
+
+ return parsedExpression;
case 'function':
return exp;