fix($compile): don't add merged attributes twice to $attrs
In replace directives, attribute values from the template are added twice to the replaced element when both the replaced element and the template element have the attribute. This does not affect the DOM, as it normalizes duplicate values. The values are however duplicated in the $attrs object that is available to directive link functions. Fixes #8159 Closes #14737
This commit is contained in:
committed by
Peter Bacon Darwin
parent
78a23ccea2
commit
3ba29c464d
+9
-11
@@ -2761,18 +2761,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
|
||||
// copy the new attributes on the old attrs object
|
||||
forEach(src, function(value, key) {
|
||||
if (key === 'class') {
|
||||
safeAddClass($element, value);
|
||||
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
|
||||
} else if (key === 'style') {
|
||||
$element.attr('style', $element.attr('style') + ';' + value);
|
||||
dst['style'] = (dst['style'] ? dst['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)) {
|
||||
// Check if we already set this attribute in the loop above.
|
||||
// `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.
|
||||
if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') {
|
||||
dst[key] = value;
|
||||
dstAttr[key] = srcAttr[key];
|
||||
|
||||
if (key !== 'class' && key !== 'style') {
|
||||
dstAttr[key] = srcAttr[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -980,6 +980,29 @@ describe('$compile', function() {
|
||||
}));
|
||||
|
||||
|
||||
it('should not set merged attributes twice in $attrs', function() {
|
||||
var attrs;
|
||||
|
||||
module(function() {
|
||||
directive('logAttrs', function() {
|
||||
return {
|
||||
link: function($scope, $element, $attrs) {
|
||||
attrs = $attrs;
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
inject(function($compile, $rootScope) {
|
||||
element = $compile(
|
||||
'<div><div log-attrs replace class="myLog"></div><div>')($rootScope);
|
||||
var div = element.find('div');
|
||||
expect(div.attr('class')).toBe('myLog log');
|
||||
expect(attrs.class).toBe('myLog log');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should prevent multiple templates per element', inject(function($compile) {
|
||||
try {
|
||||
$compile('<div><span replace class="replace"></span></div>');
|
||||
|
||||
Reference in New Issue
Block a user