View Full Version : avoiding eval w/ E4X?

rnd me
12-14-2007, 03:14 AM
i am using the following E4X code to search directories on a server.
the problem is that only firefox supports E4X at the moment.

E4X uses a special operator: ".." to find descendants of nodes without regard to their parent.

trouble is, that ".." raises a syntax error in other browsers, not be a valid statement as far as they are concered.

i would like to keep the E4X code in the same file as other functions, my main module, used by all browsers.

i have it coded as below, and this works ok i guess:

function harvestE4X(ina){ //e4x version
eval( " qaa = { name:ina..displayname.toString(), \
path: ina..href.toString(), \
size: (ina..getcontentlength.toString().toInt() || 0), \
date: (parseDate(ina..getlastmodified.toString())) } ")//end eval hide
return qaa;
}//end e4x harvest

function harvestDOM(ina){ //DOM version
var tname=(obValsl( a.getElementsByTagName("displayname"))[0][TEXT].toString() || "untitled" );
var tpath=(obValsl( a.getElementsByTagName("href"))[0][TEXT].toString() || "nopath" );
var tsize=(obValsl( a.getElementsByTagName("getcontentlength"))[0][TEXT].toString() || 0 );
var tdate=(obValsl( a.getElementsByTagName("getlastmodified"))[0][TEXT].toString() || now() );

var qaa={ name: tname,
path: tpath,
size: tsize,
date: tdate }

return qaa;
}//end harvest DOM

if (!! window.XML ){ harvest=harvestE4X } else { harvest=harvestDOM }

Is there anyway around having to eval the firefox code to hide it from other browsers? (i don't like to use eval)

12-14-2007, 03:26 AM
I'm not sure I understand. Why not skip E4X, and just use the DOM? I believe DOM methods work with XML, but I might be wrong.

Also, does understanding obValsl() make any difference for us spectators?

rnd me
12-14-2007, 03:57 AM
does understanding obValsl() make any difference for us spectators?
obValsl returns an array of the values in the collection passed to it.

DOM methods do work fine.
I think E4X is faster and simpler to code.
this is not the only E4X code like this i have.
In other functions, i use it to do a lot more complicated things than the code above.

i just need a way to safely conceal it from non-E4X browsers.

12-14-2007, 06:16 AM
I see. Just one more question: What does obValsl stand for? IMO a weird name :D. Just as another way to do the same thing, this is what I've done in the past for converting element collections. (Not that it is necessarily better though.)

//for loser IE
try {
Array.prototype.slice.call(document.childNodes, 0, 0);
catch(e) {
Array.prototype.slice = function(i, n) {
if(n === undefined || n < 0)
n = (n || 0) + this.length;
for(var r = []; i < n; ++i)
return r;

//example use
Array.prototype.slice.call(document.getElementsByTagName("div"), 0);

I've been trying to do what you want, but so far to no avail. If you can bear it, conditionally load the script based on XML support, but I got the impression that you didn't want that. I'll play with it a little longer and try to find another solution, and if I do, I'll post it.

As a side note, if you could get around to it, could you look at:
Just a follow-up on the Array.prototype.reduce thing you mentioned with variable names.

I read your edit in that linked thread and saw this:

this doesn't seem to be nearly as big a problem as i thought.
i should examine the diff between apply and call more in depth.
for some reason, this code seems to be better than my earlier replacements.
From experience, knowing how to use call and apply is one of THE key things to learn to use to code better Javascript. Others include first-class functions, closures, and prototypes. But I think you already have a solid understanding of those.

Also, in harvestE4X, you're qaa does not have the var keyword. Bad news.

12-14-2007, 08:06 AM
I give up. There probably isn't a way to make IE ignore the .. unless it is in a string or a regex.

Here's what I wrote

var harvest = window.XML
? eval( 'function(el) { \
return { \
name: el..displayname.toString(), \
path: el..href.toString() || "nopath", \
size: el..getcontentlength.toString() - 0 || 0, \
date: parseDate(el..getlastmodified.toString()) || now() \
}; \
} ')
: function(el) {
var f = harvest.getDescendantValue;
return {
name: f(el, "displayname") || "untitled",
path: f(el, "href") || "nopath",
size: f(el, "getcontentlength") - 0 || 0,
date: parseDate(f(el, "getlastmodified")) || now()

if(!window.XML) {
harvest.getDescendantValue = function(el, s) {
return el.getElementsByTagName(s)[0][TEXT].toString();

But my best advise is to probably scrap the limited .. support; you're going to have to code the DOM version anyway. Plus less code === less bugs and maintenance.