mark nottingham

Thoughts on Declarative Ajax

Thursday, 19 October 2006

HTTP

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.


7 Comments

Asbjørn Ulsberg said:

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

Aniket said:

There is a workaround for this, for that you must declare a namespace in the root element like so:

<html xmlns=”https://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 == “https://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

Aniket said:

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

Aniket said:

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 AM