<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>
Element and attribute namespaces (HTML)
</title>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<script language="javascript" type="text/javascript">
var elem;
var attr;
var resultText = "";
var passes = 0;
var failures = 0;
var errors = 0;
var currentTest = '';
function shouldBe(_a,_b) {
var _av = eval(_a);
var _bv = eval(_b);
if (_av == _bv) {
resultText += "PASS: " + currentTest + ": " + _a + " is " + _b + "\n";
passes++;
}
else {
resultText += "FAIL: " + currentTest + ": " + _a + " should be " + _b + ", was " + _av + "\n";
failures++;
}
}
function output(msg) {
resultText += msg + "\n";
}
// Element/Attribute creation
function testCreateHTMLElementLower() {
// Create a normal HTML element in a HTML document
// We pass in a lowercase name here, but it should be mapped to uppercase
// since this is a HTML document
elem = document.createElement("input");
shouldBe("elem.nodeName","'INPUT'");
shouldBe("elem.namespaceURI","null");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","null");
shouldBe("elem.tagName","'INPUT'");
// Verify that this is actually a HTMLInputElement
shouldBe("(elem.blur != undefined)","true");
}
function testCreateHTMLElementUpper() {
// Create a normal HTML element in a HTML document
elem = document.createElement("INPUT");
shouldBe("elem.nodeName","'INPUT'");
shouldBe("elem.namespaceURI","null");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","null");
shouldBe("elem.tagName","'INPUT'");
// Verify that this is actually a HTMLInputElement
shouldBe("(elem.blur != undefined)","true");
}
function testCreateXHTMLElement() {
// Create a HTML element in the XHTML namespace. This should have the namespaceURI
// and localName set, and the tag name should remain in lowercase
elem = document.createElementNS("http://www.w3.org/1999/xhtml","input");
shouldBe("elem.nodeName","'input'");
shouldBe("elem.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","'input'");
shouldBe("elem.tagName","'input'");
// Verify that this is actually a HTMLInputElement
shouldBe("(elem.blur != undefined)","true");
}
function testCreateNonHTMLElementInXHTMLNamespace() {
// Create an element in the XHTML namespace. This is not a HTML element however,
// since we're passing the name in as (partial) uppercase, and XHTML elements are lowercase only
elem = document.createElementNS("http://www.w3.org/1999/xhtml","InPuT");
shouldBe("elem.nodeName","'InPuT'");
shouldBe("elem.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","'InPuT'");
shouldBe("elem.tagName","'InPuT'");
// Verify that this is _not_ a HTMLInputElement
shouldBe("elem.blur","undefined");
}
function testCreateNonHTMLElementInXHTMLNamespace2() {
// Create an element in the XHTML namespace but using a non-HTML name
elem = document.createElementNS("http://www.w3.org/1999/xhtml","other");
shouldBe("elem.nodeName","'other'");
shouldBe("elem.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","'other'");
shouldBe("elem.tagName","'other'");
}
function testCreateXHTMLElementWithPrefix() {
// Create a HTML element in the XHTML namespace with a prefix. This should have the namespaceURI,
// prefix and localName set, and the tag name should remain in lowercase
elem = document.createElementNS("http://www.w3.org/1999/xhtml","testprefix:input");
shouldBe("elem.nodeName","'testprefix:input'");
shouldBe("elem.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("elem.prefix","'testprefix'");
shouldBe("elem.localName","'input'");
shouldBe("elem.tagName","'testprefix:input'");
// Verify that this is actually a HTMLInputElement
shouldBe("(elem.blur != undefined)","true");
}
function testCreateNonHTMLElementInXHTMLNamespaceWithPrefix() {
// Create an element in the XHTML namespace with a prefix. This is not a HTML element however,
// since we're passing the name in as (partial) uppercase, and XHTML elements are lowercase only
elem = document.createElementNS("http://www.w3.org/1999/xhtml","testprefix:InPuT");
shouldBe("elem.nodeName","'testprefix:InPuT'");
shouldBe("elem.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("elem.prefix","'testprefix'");
shouldBe("elem.localName","'InPuT'");
shouldBe("elem.tagName","'testprefix:InPuT'");
// Verify that this is _not_ a HTMLInputElement
shouldBe("elem.blur","undefined");
}
function testCreateNonHTMLElementInXHTMLNamespaceWithPrefix2() {
// Create an element in the XHTML namespace with a prefix but using a non-HTML name
elem = document.createElementNS("http://www.w3.org/1999/xhtml","testprefix:other");
shouldBe("elem.nodeName","'testprefix:other'");
shouldBe("elem.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("elem.prefix","'testprefix'");
shouldBe("elem.localName","'other'");
shouldBe("elem.tagName","'testprefix:other'");
}
function testCreateNonHTMLElement() {
// Create an non-html element with no namespace. Since this is a HTML document, the
// name should be mapped to uppercase, even though it's not actually a HTML element
elem = document.createElement("TestElement");
shouldBe("elem.nodeName","'TESTELEMENT'");
shouldBe("elem.namespaceURI","null");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","null");
shouldBe("elem.tagName","'TESTELEMENT'");
}
function testCreateElementNS() {
// Create an element in a different namespace. Even though this is a HTML document,
// the case should be preserved in this case since the spec only mentions uppercasing
// element names for createElement(), not createElementNS().
// The returned element should have both namespaceURI and localName set.
elem = document.createElementNS("http://www.test.com","TestElement");
shouldBe("elem.nodeName","'TestElement'");
shouldBe("elem.namespaceURI","'http://www.test.com'");
shouldBe("elem.prefix","null");
shouldBe("elem.localName","'TestElement'");
shouldBe("elem.tagName","'TestElement'");
}
function testCreateElementNSWithPrefix() {
// Create an element in a different namespace with a prefix. Even though this is a
// HTML document, the case should be preserved in this case since the spec only
// mentions uppercasing element names for createElement(), not createElementNS().
// The returned element should have namespaceURI, prefix and localName set.
elem = document.createElementNS("http://www.test.com","TestPrefix:TestElement");
shouldBe("elem.nodeName","'TestPrefix:TestElement'");
shouldBe("elem.namespaceURI","'http://www.test.com'");
shouldBe("elem.prefix","'TestPrefix'");
shouldBe("elem.localName","'TestElement'");
shouldBe("elem.tagName","'TestPrefix:TestElement'");
}
function testParsingHTML() {
// A bit different, but still related to element tagName: test how we store
// the name of elements during parsing. This is an HTML-compat document,
// so they should be uppercase.
elem = document.getElementById('output');
shouldBe("elem.nodeName","'PRE'");
shouldBe("elem.namespaceURI",null);
shouldBe("elem.prefix",null);
shouldBe("elem.localName",null);
shouldBe("elem.tagName","'PRE'");
}
function testCreateAttribute() {
// Create a normal HTML attribute. The name should be transformed to lowercase.
// Note that in XML documents we preserve the case.
attr = document.createAttribute("src");
shouldBe("attr.nodeName","'src'");
shouldBe("attr.namespaceURI","null");
shouldBe("attr.prefix","null");
shouldBe("attr.localName","null");
shouldBe("attr.name","'src'");
shouldBe("attr.value","''");
}
function testCreateAttributeUppercase() {
// Create a normal HTML attribute. The name should be transformed to lowercase.
attr = document.createAttribute("SRC");
shouldBe("attr.nodeName","'src'");
shouldBe("attr.namespaceURI","null");
shouldBe("attr.prefix","null");
shouldBe("attr.localName","null");
shouldBe("attr.name","'src'");
shouldBe("attr.value","''");
}
// Referencing nodes using both namespace aware and namspace unaware methods
function testSetAttribute() {
// After using setAttribute() to create an attribute node and assign it to an
// element, the attribute node can be retrieved using getAttributeNode(), and
// has all of the expected values
// The attribute name should be lowercased.
// Although section 1.3 of
// DOM Level 2 HTML says: "element and attribute names are exposed as all uppercase
// (for consistency) when used on an HTML document", DOM Core is much less affirmative.
// W3C members have expressed remorse on this statement, and
// concerns about undermining the ongoing standardization on lowercase attributes
// amongst major web browsers.
elem = document.createElement("p");
elem.setAttribute("class","test");
attr = elem.getAttributeNode("class");
shouldBe("attr.nodeName","'class'");
shouldBe("attr.namespaceURI","null");
shouldBe("attr.prefix","null");
shouldBe("attr.localName","null");
shouldBe("attr.name","'class'");
shouldBe("attr.value","'test'");
shouldBe("attr.nodeValue","'test'");
shouldBe("elem.getAttribute('class')","'test'");
shouldBe("elem.getAttribute('ClAsS')","'test'");
shouldBe("elem.getAttribute('CLASS')","'test'");
shouldBe("elem.getAttributeNode('class')","attr");
shouldBe("elem.getAttributeNode('ClAsS')","attr");
shouldBe("elem.getAttributeNode('CLASS')","attr");
shouldBe("attr.ownerElement","elem");
shouldBe("attr.specified","true");
shouldBe("elem.attributes.getNamedItem('class')","attr");
shouldBe("elem.attributes.getNamedItem('ClAsS')","attr");
shouldBe("elem.attributes.getNamedItem('CLASS')","attr");
// getAttributeNodeNS() and getAttributeNS() should fail here, as they match based on the
// namespaceURI and localName. But since the attribute was created in a non-namespace aware
// context, it's localName is null.
shouldBe("elem.getAttributeNodeNS(null,'CLASS')","null");
shouldBe("elem.getAttributeNS(null,'CLASS')","''");
shouldBe("elem.attributes.getNamedItemNS(null,'CLASS')","null");
// If an attribute with that name is already present in the element, its value is
// changed to be that of the value parameter
elem.setAttribute("class","newvalue");
shouldBe("elem.getAttributeNode('class')","attr");
shouldBe("elem.attributes.getNamedItem('class')","attr");
shouldBe("elem.getAttribute('class')","'newvalue'");
shouldBe("attr.value","'newvalue'");
shouldBe("attr.nodeValue","'newvalue'");
}
function testSetAttributeNS() {
// After using setAttributeNS() to create an attribute node and assign it to an
// element, the attribute node can be retrieved using getAttributeNodeNS(), and
// has all of the expected values
// the behaviour with regard to compatibility mode is the same than createElementNS
elem = document.createElement("p");
elem.setAttributeNS("http://www.test.com","myattr","test");
attr = elem.getAttributeNodeNS("http://www.test.com","myattr");
shouldBe("attr.nodeName","'myattr'");
shouldBe("attr.namespaceURI","'http://www.test.com'");
shouldBe("attr.prefix","null");
shouldBe("attr.localName","'myattr'");
shouldBe("attr.name","'myattr'");
shouldBe("attr.value","'test'");
shouldBe("attr.nodeValue","'test'");
shouldBe("elem.getAttribute('myattr')","'test'");
shouldBe("elem.getAttribute('MyAtTr')","'test'");
shouldBe("elem.getAttribute('MYATTR')","'test'");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'test'");
shouldBe("elem.getAttributeNode('myattr')","attr");
shouldBe("elem.getAttributeNode('MyAtTr')","attr");
shouldBe("elem.getAttributeNode('MYATTR')","attr");
shouldBe("attr.ownerElement","elem");
shouldBe("attr.specified","true");
shouldBe("elem.attributes.getNamedItem('myattr')","attr");
shouldBe("elem.attributes.getNamedItem('MyAtTr')","attr");
shouldBe("elem.attributes.getNamedItem('MYATTR')","attr");
shouldBe("elem.getAttributeNodeNS('http://www.test.com','myattr')","attr");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'test'");
shouldBe("elem.attributes.getNamedItemNS('http://www.test.com','myattr')","attr");
// If an attribute with that name is already present in the element, its value is
// changed to be that of the value parameter
elem.setAttribute("myattr","newvalue");
shouldBe("elem.getAttributeNode('myattr')","attr");
shouldBe("elem.getAttributeNodeNS('http://www.test.com','myattr')","attr");
shouldBe("elem.attributes.getNamedItem('myattr')","attr");
shouldBe("elem.attributes.getNamedItemNS('http://www.test.com','myattr')","attr");
shouldBe("elem.getAttribute('myattr')","'newvalue'");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'newvalue'");
shouldBe("attr.value","'newvalue'");
shouldBe("attr.nodeValue","'newvalue'");
elem.setAttributeNS("http://www.test.com","myattr","othervalue");
shouldBe("elem.getAttributeNode('myattr')","attr");
shouldBe("elem.getAttributeNodeNS('http://www.test.com','myattr')","attr");
shouldBe("elem.attributes.getNamedItem('myattr')","attr");
shouldBe("elem.attributes.getNamedItemNS('http://www.test.com','myattr')","attr");
shouldBe("elem.getAttribute('myattr')","'othervalue'");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'othervalue'");
shouldBe("attr.value","'othervalue'");
shouldBe("attr.nodeValue","'othervalue'");
}
function testSetAttributeNSInXHTMLNamespace() {
// After using setAttributeNS() to create an attribute node and assign it to an
// element, the attribute node can be retrieved using getAttributeNodeNS(), and
// has all of the expected values
// the behaviour with regard to compatibility mode is the same than createElementNS
elem = document.createElement("p");
elem.setAttributeNS("http://www.w3.org/1999/xhtml", "OtherAttr", "aValue");
attr = elem.getAttributeNode("OtherAttr");
shouldBe("elem.getAttributeNodeNS('http://www.w3.org/1999/xhtml','OtherAttr')","attr");
shouldBe("attr.nodeName","'OtherAttr'");
shouldBe("attr.namespaceURI","'http://www.w3.org/1999/xhtml'");
shouldBe("attr.prefix","null");
shouldBe("attr.localName","'OtherAttr'");
shouldBe("attr.name","'OtherAttr'");
shouldBe("attr.value","'aValue'");
shouldBe("attr.nodeValue","'aValue'");
}
function testSetAttributeNSWithPrefix() {
// After using setAttributeNS() to create an attribute node and assign it to an
// element, the attribute node can be retrieved using getAttributeNodeNS(), and
// has all of the expected values
// the behaviour with regard to compatibility mode is the same than createElementNS
elem = document.createElement("p");
elem.setAttributeNS("http://www.test.com","myprefix:myattr","test");
attr = elem.getAttributeNodeNS("http://www.test.com","myattr");
shouldBe("attr.nodeName","'myprefix:myattr'");
shouldBe("attr.namespaceURI","'http://www.test.com'");
shouldBe("attr.prefix","'myprefix'");
shouldBe("attr.localName","'myattr'");
shouldBe("attr.name","'myprefix:myattr'");
shouldBe("attr.value","'test'");
shouldBe("attr.nodeValue","'test'");
shouldBe("elem.getAttribute('myprefix:myattr')","'test'");
shouldBe("elem.getAttribute('myprefix:MyAtTr')","'test'");
shouldBe("elem.getAttribute('myprefix:MYATTR')","'test'");
shouldBe("elem.getAttribute('MyPrefix:myattr')","'test'");
shouldBe("elem.getAttribute('MYPREFIX:myattr')","'test'");
shouldBe("elem.getAttribute('myattr')","''");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'test'");
shouldBe("elem.getAttributeNS('http://www.test.com','myprefix:myattr')","''");
shouldBe("elem.getAttributeNode('myprefix:myattr')","attr");
shouldBe("elem.getAttributeNode('myprefix:MyAtTr')","attr");
shouldBe("elem.getAttributeNode('myprefix:MYATTR')","attr");
shouldBe("elem.getAttributeNode('MyPrefix:myattr')","attr");
shouldBe("elem.getAttributeNode('MYPREFIX:myattr')","attr");
shouldBe("elem.getAttributeNode('myattr')","null");
shouldBe("attr.ownerElement","elem");
shouldBe("attr.specified","true");
shouldBe("elem.attributes.getNamedItem('myattr')","null");
shouldBe("elem.attributes.getNamedItem('myprefix:myattr')","attr");
shouldBe("elem.attributes.getNamedItem('myprefix:MyAtTr')","attr");
shouldBe("elem.attributes.getNamedItem('myprefix:MYATTR')","attr");
shouldBe("elem.attributes.getNamedItem('MyPrefix:myattr')","attr");
shouldBe("elem.attributes.getNamedItem('MYPREFIX:myattr')","attr");
shouldBe("elem.getAttributeNodeNS('http://www.test.com','myattr')","attr");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'test'");
shouldBe("elem.attributes.getNamedItemNS('http://www.test.com','myattr')","attr");
// If an attribute with that name is already present in the element, its value is
// changed to be that of the value parameter
elem.setAttribute("myprefix:myattr","newvalue");
shouldBe("elem.getAttributeNode('myprefix:myattr')","attr");
shouldBe("elem.getAttributeNodeNS('http://www.test.com','myattr')","attr");
shouldBe("elem.attributes.getNamedItem('myprefix:myattr')","attr");
shouldBe("elem.attributes.getNamedItemNS('http://www.test.com','myattr')","attr");
shouldBe("elem.getAttribute('myprefix:myattr')","'newvalue'");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'newvalue'");
shouldBe("attr.value","'newvalue'");
shouldBe("attr.nodeValue","'newvalue'");
elem.setAttributeNS("http://www.test.com","myattr","othervalue");
shouldBe("elem.getAttributeNode('myprefix:myattr')","attr");
shouldBe("elem.getAttributeNodeNS('http://www.test.com','myattr')","attr");
shouldBe("elem.attributes.getNamedItem('myprefix:myattr')","attr");
shouldBe("elem.attributes.getNamedItemNS('http://www.test.com','myattr')","attr");
shouldBe("elem.getAttribute('myprefix:myattr')","'othervalue'");
shouldBe("elem.getAttributeNS('http://www.test.com','myattr')","'othervalue'");
shouldBe("attr.value","'othervalue'");
shouldBe("attr.nodeValue","'othervalue'");
}
function runTest(testName,func) {
currentTest = testName;
try {
func();
}
catch (e) {
output("ERROR: " + testName + ": " + e);
errors++;
}
currentTest = '';
}
function runTests() {
// Element/Attribute creation
runTest("createElement() with a lowercase html element name",
testCreateHTMLElementLower);
runTest("createElement() with a upper html element name",
testCreateHTMLElementUpper);
runTest("createElementNS() in the xhtml namespace",
testCreateXHTMLElement);
runTest("createElementNS() with a html element name but different case in the xhtml namespace",
testCreateNonHTMLElementInXHTMLNamespace);
runTest("createElementNS() with a non-HTML element in the xhtml namespace",
testCreateNonHTMLElementInXHTMLNamespace2);
runTest("createElementNS() in the xhtml namespace with a prefix",
testCreateXHTMLElementWithPrefix);
runTest("createElementNS() with a html element name & prefix but different case in the xhtml namespace",
testCreateNonHTMLElementInXHTMLNamespaceWithPrefix);
runTest("createElementNS() with a non-HTML element & prefix in the xhtml namespace",
testCreateNonHTMLElementInXHTMLNamespaceWithPrefix2);
runTest("createElement() with a non-html element name",
testCreateNonHTMLElement);
runTest("createElementNS()",
testCreateElementNS);
runTest("createElementNS() with prefix",
testCreateElementNSWithPrefix);
runTest("parsing html compat elements",
testParsingHTML);
runTest("createAttribute()",testCreateAttribute);
runTest("createAttribute() with an uppercase name",testCreateAttributeUppercase);
// Referencing nodes using both namespace aware and namespace unaware methods
runTest("setAttribute()",testSetAttribute);
runTest("setAttributeNS()",testSetAttributeNS);
runTest("setAttributeNS() in XHTML namespace", testSetAttributeNSInXHTMLNamespace);
runTest("setAttributeNS() with prefix",testSetAttributeNSWithPrefix);
showResults();
}
function showResults() {
var str = resultText +
"Passes: " + passes +
"\nFailures: " + failures +
"\nErrors: " + errors;
document.getElementById("output").appendChild(document.createTextNode(str));
}
</script>
</head>
<body>
<h1>
Element and attribute namespaces (HTML)
</h1>
<p>
Results should be displayed below.
</p>
<pre id="output"></pre>
<script language="javascript" type="text/javascript">
runTests();
</script>
</body>
</html>