aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2012-03-13 14:42:26 -0700
committerMisko Hevery2012-03-13 16:59:03 -0700
commitde9464c1431906883bdf180fb00615e6fa371577 (patch)
tree5002990279d089cae2577ab98468217258455dec
parent31cd5803102ba93f8b93cd5304aea4ade50f96ab (diff)
downloadangular.js-de9464c1431906883bdf180fb00615e6fa371577.tar.bz2
f(compile): boolean attributes too agresive
- compiler would rewrite boolean attributes on all elements. This is too aggressive and interferes with some third-party frameworks
-rw-r--r--src/jqLite.js8
-rw-r--r--src/service/compiler.js10
-rw-r--r--test/directive/ngNonBindableSpec.js2
-rw-r--r--test/service/compilerSpec.js49
4 files changed, 39 insertions, 30 deletions
diff --git a/src/jqLite.js b/src/jqLite.js
index dd793ab2..96dda112 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -310,6 +310,14 @@ var BOOLEAN_ATTR = {};
forEach('multiple,selected,checked,disabled,readOnly,required'.split(','), function(value) {
BOOLEAN_ATTR[lowercase(value)] = value;
});
+var BOOLEAN_ELEMENTS = {};
+forEach('input,select,option,textarea,button'.split(','), function(value) {
+ BOOLEAN_ELEMENTS[uppercase(value)] = true;
+});
+
+function isBooleanAttr(element, name) {
+ return BOOLEAN_ELEMENTS[element.nodeName] && BOOLEAN_ATTR[name.toLowerCase()];
+}
forEach({
data: JQLiteData,
diff --git a/src/service/compiler.js b/src/service/compiler.js
index cefc2d81..8aba28e4 100644
--- a/src/service/compiler.js
+++ b/src/service/compiler.js
@@ -381,10 +381,10 @@ function $CompileProvider($provide) {
attrs[nName] = value = trim((msie && name == 'href')
? decodeURIComponent(node.getAttribute(name, 2))
: attr.value);
- if (BOOLEAN_ATTR[nName]) {
+ if (isBooleanAttr(node, nName)) {
attrs[nName] = true; // presence means true
}
- addAttrInterpolateDirective(directives, value, nName)
+ addAttrInterpolateDirective(node, directives, value, nName)
addDirective(directives, nName, 'A', maxPriority);
}
@@ -852,11 +852,11 @@ function $CompileProvider($provide) {
}
- function addAttrInterpolateDirective(directives, value, name) {
+ function addAttrInterpolateDirective(node, directives, value, name) {
var interpolateFn = $interpolate(value, true);
if (SIDE_EFFECT_ATTRS[name]) {
name = SIDE_EFFECT_ATTRS[name];
- if (BOOLEAN_ATTR[name]) {
+ if (isBooleanAttr(node, name)) {
value = true;
}
} else if (!interpolateFn) {
@@ -921,7 +921,7 @@ function $CompileProvider($provide) {
* @param {string=} attrName Optional none normalized name. Defaults to key.
*/
function attrSetter(key, value, attrName) {
- var booleanKey = BOOLEAN_ATTR[key.toLowerCase()];
+ var booleanKey = isBooleanAttr(this.$element[0], key.toLowerCase());
if (booleanKey) {
value = toBoolean(value);
diff --git a/test/directive/ngNonBindableSpec.js b/test/directive/ngNonBindableSpec.js
index 4f69528b..1f7bf25d 100644
--- a/test/directive/ngNonBindableSpec.js
+++ b/test/directive/ngNonBindableSpec.js
@@ -10,7 +10,7 @@ describe('ng-non-bindable', function() {
});
- iit('should prevent compilation of the owning element and its children',
+ it('should prevent compilation of the owning element and its children',
inject(function($rootScope, $compile) {
element = $compile('<div ng-non-bindable text="{{name}}"><span ng-bind="name"></span></div>')($rootScope);
$rootScope.name = 'misko';
diff --git a/test/service/compilerSpec.js b/test/service/compilerSpec.js
index b42b871a..28c91492 100644
--- a/test/service/compilerSpec.js
+++ b/test/service/compilerSpec.js
@@ -1226,20 +1226,39 @@ describe('$compile', function() {
});
- it('should read boolean attributes as boolean', function() {
+ it('should read boolean attributes as boolean only on control elements', function() {
+ var value;
+ module(function($compileProvider) {
+ $compileProvider.directive({
+ input: valueFn({
+ restrict: 'ECA',
+ link:function(scope, element, attr) {
+ value = attr.required;
+ }
+ })
+ });
+ });
+ inject(function($rootScope, $compile) {
+ element = $compile('<input required></input>')($rootScope);
+ expect(value).toEqual(true);
+ });
+ });
+
+ it('should read boolean attributes as text on non-controll elements', function() {
+ var value;
module(function($compileProvider) {
$compileProvider.directive({
div: valueFn({
restrict: 'ECA',
link:function(scope, element, attr) {
- element.text(attr.required);
+ value = attr.required;
}
})
});
});
inject(function($rootScope, $compile) {
- element = $compile('<div required></div>')($rootScope);
- expect(element.text()).toEqual('true');
+ element = $compile('<div required="some text"></div>')($rootScope);
+ expect(value).toEqual('some text');
});
});
@@ -1262,24 +1281,6 @@ describe('$compile', function() {
});
- it('should read boolean attributes as boolean', function() {
- module(function($compileProvider) {
- $compileProvider.directive({
- div: valueFn({
- restrict: 'ECA',
- link: function(scope, element, attr) {
- element.text(attr.required);
- }
- })
- });
- });
- inject(function($rootScope, $compile) {
- element = $compile('<div required></div>')($rootScope);
- expect(element.text()).toEqual('true');
- });
- });
-
-
it('should create new instance of attr for each template stamping', function() {
module(function($compileProvider, $provide) {
var state = { first: [], second: [] };
@@ -1335,7 +1336,7 @@ describe('$compile', function() {
var attr;
beforeEach(function(){
module(function($compileProvider) {
- $compileProvider.directive('div', valueFn({
+ $compileProvider.directive('input', valueFn({
restrict: 'ECA',
link: function(scope, element, attr) {
scope.attr = attr;
@@ -1343,7 +1344,7 @@ describe('$compile', function() {
}));
});
inject(function($compile, $rootScope) {
- element = $compile('<div></div>')($rootScope);
+ element = $compile('<input></input>')($rootScope);
attr = $rootScope.attr;
expect(attr).toBeDefined();
});