diff --git a/src/binding/defaultBindings/attr.js b/src/binding/defaultBindings/attr.js index a6b3961e5..e39c2ad82 100755 --- a/src/binding/defaultBindings/attr.js +++ b/src/binding/defaultBindings/attr.js @@ -5,12 +5,21 @@ ko.bindingHandlers['attr'] = { ko.utils.objectForEach(value, function(attrName, attrValue) { attrValue = ko.utils.unwrapObservable(attrValue); + // Find the namespace of this attribute, if any. + // Defaulting to `null` should be ok, as + // + // element.setAttributeNS( null, name, value ) ~ element.setAttribute( name, value ) + // element.removetAttributeNS( null, name ) ~ element.removeAttribute( name ) + // + var prefixLen = attrName.indexOf(':'); + var namespace = prefixLen < 0 ? null : element.lookupNamespaceURI( attrName.substr(0, prefixLen) ); + // To cover cases like "attr: { checked:someProp }", we want to remove the attribute entirely // when someProp is a "no value"-like value (strictly null, false, or undefined) // (because the absence of the "checked" attr is how to mark an element as not checked, etc.) var toRemove = (attrValue === false) || (attrValue === null) || (attrValue === undefined); if (toRemove) - element.removeAttribute(attrName); + element.removeAttributeNS(namespace, attrName); // In IE <= 7 and IE8 Quirks Mode, you have to use the Javascript property name instead of the // HTML attribute name for certain attributes. IE8 Standards Mode supports the correct behavior, @@ -23,7 +32,7 @@ ko.bindingHandlers['attr'] = { else element[attrName] = attrValue; } else if (!toRemove) { - element.setAttribute(attrName, attrValue.toString()); + element.setAttributeNS(namespace, attrName, attrValue.toString()); } // Treat "name" specially - although you can think of it as an attribute, it also needs