From 0b575f8153a5ba81b9165349aa11daca29a65c58 Mon Sep 17 00:00:00 2001 From: Noah Luck Easterly Date: Wed, 7 Aug 2013 15:06:18 -0400 Subject: [PATCH] Implement support for namespaces in attr binding. The DOM provides a way to lookup which namespace an attribute name belongs to given the element the attribute will be bound to, Node.lookupNamespaceURI (http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI). Given the namespace, it's simple to add/remove the desired attribute with the correct namespace using the Node.setElementNS and Node.removeAttributeNS. --- src/binding/defaultBindings/attr.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) 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