node.appendChild( <img src="url" />
).Me, I'm 100% in agreement that this kind of thing is a definite oversight, but when one considers that the DOM API is governed by the W3C while E4X and ECMAScript are both ECMA standards, one could charitably understand why ECMA didn't want to tread on a fellow standards body's toes. Or, more cynically, promote the use of competing specs.
Anyway. This becomes one more hurdle at the presentation level, which I can live with. After having written DOM-driven SAX event drivers and DOM-constructing SAX event handlers, not even touching XMLPull etc., why not add another to the mix? Bring the noise.
Which brings me to my next point, which is that I can rarely resist using JS code that I haven't fiddled with. The functions in the above links are functionally perfect, but I don't get why the XMLNS is hard-coded and not passed as an argument, since FF can grok SVG and MathML now. Conversely, the mime type of "text/xml" is a static constant, when, for the purposes of the parser, it will never change. Additionally, having a Java background means I instinctively namespace my code, meaning I don't have to assign anything to the function properties.
My purely aesthetic revision:
lib.util.e4x2dom = function(xmlObj, xmlObjNs, doc) {Here's hoping that blogspot doesn't mangle my escaped & formatted characters.
if(!doc) doc = document;
if(!xmlObjNs) xmlObjNs = NS_HTML;
var xmlRootObj = <root xmlns={xmlObjNs} />;
if(!lib.util.e4x2dom.parser) lib.util.e4x2dom.parser = new DOMParser(); //one time initialisation
xmlRootObj.firstChild=xmlObj;
var domTree=lib.util.e4x2dom.parser.parseFromString(xmlRootObj.toXMLString(), "text/xml");
var importMe=domTree.documentElement.firstChild;
while(importMe && importMe.nodeType!=1) {
importMe=importMe.nextSibling;
}
return (importMe) ? doc.importNode(importMe,true):null;
}
HAVING SAID THAT,
A second consequence of the unwanted duality is (joy!) complete lack of access to DOM-specific functions. In HTML this isn't such a big deal, but in SVG when you construct text elements, the getComputedTextLength() method is invaluable and is often used during the construction of the element, i.e. in my case when it's still in E4X and not in DOM.
So this is what I'm left with:
var text = "foo bar";
var textDOM = document.createElement("text");
textDOM.appendChild(document.createTextNode(text));
var textE4X = <text y="0" x={textDOM.getComputedTextLength()}>{text}</text>;
Which is a nasty hack, to put it nicely. No code that touches the real world will ever be perfect.
Addendum: the above snippet doesn't work. The text has to be rendered before FF can give me a length. Foo.