“Design depends largely on constraints.” — Charles Eames
Thursday, 19 October 2006
Dave Johnson writes up a nice summary of the issues of adding new elements to HTML for declarative Ajax, something that I ran into when doing HInclude.
Basically, IE doesn’t give you access to any non-HTML element that’s not in a namespace, and you have to access it by the full QName, so your hands are tied somewhat (e.g., the user can’t swap in a different prefix), but it’s doable. E.g.,
var includes = document.getElementsByTagName("hx:include");
if (includes.length == 0) { // remove ns for IE
includes = document.getElementsByTagName("include");
}
I’ve also received some grief about HInclude making HTML invalid, and therefore being a Bad Thing. I disagree — HTML has to be able to evolve, and Declarative Javascript is a nice way to do it. As Mark says, it’s a pendulum.
Filed under: Web
It's a pendulum indeed and the crying about validity is usually just hogwash, but it's still important that extensions are carefully designed and where it is possible, don't break (X)HTML compliance. XHTML's and XML's support for DTD's is what's problematic here, since DTD's don't have any notion for XML Namespaces.
Let's see what the new HTML initative from Tim BL will lead to. Perhaps we'll see a more extensible (X)HTML in the future. At least I hope we will.
Monday, October 30 2006 at 3:22 AM +10:00
Yes, definitely. When I was doing HInclude, I tried to do it using an XHTML Module, but it's so Byzantine as to be unworkable, so I gave up and just broke validity.
I really hope the next effort makes extensibility more usable, while assuring that extensions don't create too much fragmentation. Using Javascript to implement them at first is a really nice lever.
Monday, October 30 2006 at 7:36 AM +10:00
There is a workaround for this, for that you must declare a namespace in the root element like so:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xh="urn:some-name">
then use this function:
function getElementsByTagNameNS(domElem, strNsURI, lName) {
if(domElem.getElementsByTagNameNS) {
return domElem.getElementsByTagNameNS(strNsURI, lName);
}else {
// for IE ns is stored in tagUrn property
// ugh!! ugly hack for IE which does not understand default namespace
if(strNsURI == "http://www.w3.org/1999/xhtml") {
strNsURI = "";
}
var arrElems = domElem.getElementsByTagName(lName);
var allElems = new Array();
for(var i = 0, len = arrElems.length; i < len; i++) {
var elem = arrElems[i];
if(elem.tagUrn == strNsURI) {
allElems.push(elem);
}
}
return allElems;
}
};// call
getElementsByTagNameNS(document, "urn:some-name", "include")
Tuesday, November 7 2006 at 3:47 AM +10:00
I am sorry, the call should have been like so:
getElementsByTagNameNS(document.documentElement, "urn:some-name", "include")
Tuesday, November 7 2006 at 3:55 AM +10:00
Hi Aniket,
I'm not sure what you're referring to there... HInclude already accounts for the differences in namespace handling in IE and other browsers.
Tuesday, November 7 2006 at 9:11 AM +10:00
Hi Mark,
What i was referring to was is that you can swap a different namespace prefix for the element and still be able to get those elements using the function above.What hinclude does is this:
var includes = document.getElementsByTagName("hx:include");
if (includes.length == 0) { // remove ns for IE
includes = document.getElementsByTagName("include");
}But with the function above, you can use any ns prefix, you only need to know the namespace URI and you can still get the element by the function no matter what the ns prefix
getElementsByTagNameNS(document.documentElement, "http://purl.org/NET/hinclude", "include")
if there are two prefixes like this:
<html xmlns:h="http://purl.org/NET/hinclude" xmlns:xh="http://purl.org/NET/hinclude">
calling the function above will return both the elements:
"h:include" and "xh:include".I think this is what Dave Johnson talks about??
-Aniket
Tuesday, November 7 2006 at 9:58 PM +10:00
Ah, OK! I'll give that a try next time around. Thanks!
Wednesday, November 8 2006 at 4:04 PM +10:00