Skip to content

Commit

Permalink
Implement support for namespaces in attr binding.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rampion committed Aug 7, 2013
1 parent 6d3d744 commit 0b575f8
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/binding/defaultBindings/attr.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down

0 comments on commit 0b575f8

Please sign in to comment.