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

fix($compile): support merging special attribute names in replace d… #13318

Closed
wants to merge 9 commits into from
20 changes: 19 additions & 1 deletion src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse,
$controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) {

var SIMPLE_ATTR_NAME = /^\w/;
var specialAttrHolder = document.createElement('div');
var Attributes = function(element, attributesToCopy) {
if (attributesToCopy) {
var keys = Object.keys(attributesToCopy);
Expand Down Expand Up @@ -1168,7 +1170,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
if (value === null || isUndefined(value)) {
this.$$element.removeAttr(attrName);
} else {
this.$$element.attr(attrName, value);
if (SIMPLE_ATTR_NAME.test(attrName)) {
this.$$element.attr(attrName, value);
} else {
setSpecialAttr(this.$$element[0], attrName, value);
}
}
}

Expand Down Expand Up @@ -1221,6 +1227,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
};

function setSpecialAttr(element, attrName, value) {
// Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`
// so we have to jump through some hoops to get such an attribute
// https://github.com/angular/angular.js/pull/13318
specialAttrHolder.innerHTML = "<span " + attrName + ">";
var attributes = specialAttrHolder.firstChild.attributes;
var attribute = attributes[0];
// We have to remove the attribute from its container element before we can add it to the destination element
attributes.removeNamedItem(attribute.name);
attribute.value = value;
element.attributes.setNamedItem(attribute);
}

function safeAddClass($element, className) {
try {
Expand Down
11 changes: 11 additions & 0 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,17 @@ describe('$compile', function() {
expect(div.attr('id')).toEqual('myid');
}));


it('should correctly merge attributes that contain special characters', inject(function($compile, $rootScope) {
element = $compile(
'<div><div replace (click)="doSomething()" [value]="someExpression" ω="omega"></div><div>')($rootScope);
var div = element.find('div');
expect(div.attr('(click)')).toEqual('doSomething()');
expect(div.attr('[value]')).toEqual('someExpression');
expect(div.attr('ω')).toEqual('omega');
}));


it('should prevent multiple templates per element', inject(function($compile) {
try {
$compile('<div><span replace class="replace"></span></div>');
Expand Down