Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 724273a

Browse files
committed
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
1 parent f3377da commit 724273a

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

src/ng/compile.js

+16-12
Original file line numberDiff line numberDiff line change
@@ -2761,18 +2761,22 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
27612761

27622762
// copy the new attributes on the old attrs object
27632763
forEach(src, function(value, key) {
2764-
if (key === 'class') {
2765-
safeAddClass($element, value);
2766-
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
2767-
} else if (key === 'style') {
2768-
$element.attr('style', $element.attr('style') + ';' + value);
2769-
dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
2770-
// `dst` will never contain hasOwnProperty as DOM parser won't let it.
2771-
// You will get an "InvalidCharacterError: DOM Exception 5" error if you
2772-
// have an attribute like "has-own-property" or "data-has-own-property", etc.
2773-
} else if (key.charAt(0) !== '$' && !dst.hasOwnProperty(key)) {
2774-
dst[key] = value;
2775-
dstAttr[key] = srcAttr[key];
2764+
// Check if we already set this attribute in the loop above
2765+
if (!dst[key]) {
2766+
2767+
if (key === 'class') {
2768+
safeAddClass($element, value);
2769+
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
2770+
} else if (key === 'style') {
2771+
$element.attr('style', $element.attr('style') + ';' + value);
2772+
dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
2773+
// `dst` will never contain hasOwnProperty as DOM parser won't let it.
2774+
// You will get an "InvalidCharacterError: DOM Exception 5" error if you
2775+
// have an attribute like "has-own-property" or "data-has-own-property", etc.
2776+
} else if (key.charAt(0) !== '$' && !dst.hasOwnProperty(key)) {
2777+
dst[key] = value;
2778+
dstAttr[key] = srcAttr[key];
2779+
}
27762780
}
27772781
});
27782782
}

test/ng/compileSpec.js

+23
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,29 @@ describe('$compile', function() {
980980
}));
981981

982982

983+
it('should not set merged attributes twice in $attrs', function() {
984+
var attrs;
985+
986+
module(function() {
987+
directive('logAttrs', function() {
988+
return {
989+
link: function($scope, $element, $attrs) {
990+
attrs = $attrs;
991+
}
992+
}
993+
})
994+
});
995+
996+
inject(function($compile, $rootScope) {
997+
element = $compile(
998+
'<div><div log-attrs replace class="myLog"></div><div>')($rootScope);
999+
var div = element.find('div');
1000+
expect(div.attr('class')).toBe('myLog log');
1001+
expect(attrs.class).toBe('myLog log');
1002+
});
1003+
});
1004+
1005+
9831006
it('should prevent multiple templates per element', inject(function($compile) {
9841007
try {
9851008
$compile('<div><span replace class="replace"></span></div>');

0 commit comments

Comments
 (0)