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

Commit ebbaa4a

Browse files
Narretzpetebacondarwin
authored andcommitted
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 6171372 commit ebbaa4a

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

src/ng/compile.js

+9-11
Original file line numberDiff line numberDiff line change
@@ -2774,18 +2774,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
27742774

27752775
// copy the new attributes on the old attrs object
27762776
forEach(src, function(value, key) {
2777-
if (key == 'class') {
2778-
safeAddClass($element, value);
2779-
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
2780-
} else if (key == 'style') {
2781-
$element.attr('style', $element.attr('style') + ';' + value);
2782-
dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
2783-
// `dst` will never contain hasOwnProperty as DOM parser won't let it.
2784-
// You will get an "InvalidCharacterError: DOM Exception 5" error if you
2785-
// have an attribute like "has-own-property" or "data-has-own-property", etc.
2786-
} else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) {
2777+
// Check if we already set this attribute in the loop above.
2778+
// `dst` will never contain hasOwnProperty as DOM parser won't let it.
2779+
// You will get an "InvalidCharacterError: DOM Exception 5" error if you
2780+
// have an attribute like "has-own-property" or "data-has-own-property", etc.
2781+
if (!dst.hasOwnProperty(key) && key.charAt(0) !== '$') {
27872782
dst[key] = value;
2788-
dstAttr[key] = srcAttr[key];
2783+
2784+
if (key !== 'class' && key !== 'style') {
2785+
dstAttr[key] = srcAttr[key];
2786+
}
27892787
}
27902788
});
27912789
}

test/ng/compileSpec.js

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

981981

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

0 commit comments

Comments
 (0)