Archive

Archive for April, 2009

Gigantic Javascript WTF: DispHTMLElementCollection

April 22nd, 2009 blakeyrat No comments

I don’t normally post about boring work topics, but I wanted to talk about this because it’s a gigantic WTF, and because it might come in handy for someone else who’s stuck on a Javascript project.

It turns out that the thing getElementsByName and getElementsByTagName returns isn’t actually an array. It looks like an array, it walks like an array, and it quacks like a duck, but it’s not actually an array at all. It’s actually a “dispHTMLElementCollection”.

I’ve been doing tons and tons of Javascript work for years, and I’ve actually never come up against this particular quirk before. The only reason I figured it out is that I tried to push() an element into a dispHTMLElementCollection, and it turns out that dispHTMLElementCollections don’t have a push() method. Why doesn’t it have a push() method? Who knows.

Oh, and to make it worse: it’s not documented. Anywhere. This forum post is all MSDN (Microsoft’s developer site, maker of the most popular web browser on Earth) has. Mozilla (makers of the second-most popular web browser on Earth) has absolutely nothing on it, or at least nothing Google’s indexed. Nor does w3.org, the maintainers of the DOM standards (most relevant to this issue.)

What. The. Fuck.

Here’s a test page to demonstrate the issue:

<html> <head> <title>Test</title> </head> <body> <p>h</p> <p>e</p> <hr /> <p>l</p> <p>l</p> <hr /> <p>o</p> <script type="text/javascript"> // Call the "broken" version of CombinedElementList // This function fails in both IE and Firefox, even // though at first glance it looks fine. Reason? // getElementsByTagName *doesn't* return an array, // instead it returns a "dispHTMLElementCollection" // which looks and acts exactly like an array, but // has no .push() method. //var combo = CombinedElementListBroken(); // The "fixed" version uses a Javascript array to // store the results of the two // getElementsByTagName calls. var combo = CombinedElementListWorks(); alert(combo.length); // Expect: 7 function CombinedElementListBroken() { // Create two "arrays" of HTML elements var paras = document.getElementsByTagName('P'); var hrs = document.getElementsByTagName('HR'); // Attempt to combine the two using a simple FOR loop for (var i = 0; i < hrs.length; i++) { // IE: Object doesn't support this property or method // Firefox: paras.push is not a function paras.push(hrs[i]); } return (paras); } function CombinedElementListWorks() { // Create two "arrays" of HTML elements var paras = document.getElementsByTagName('P'); var hrs = document.getElementsByTagName('HR'); // Create a third, blank, array to store the combined list var combinedArr = new Array(); // Puts elements from the first "array" into the combined array for (var i = 0; i < paras.length; i++) { combinedArr.push(paras[i]); } // And the second for (var i = 0; i < hrs.length; i++) { combinedArr.push(hrs[i]); } return (combinedArr); } </script> </body> </html>


Ok, so I posted this to TheDailyWTF, thinking it’d be a laugh: it’s not. Don’t do that, ever. You’d never know it from the frontpage, but the WTF forums are full, apparently, of programmers with psychic or telekinetic powers. To them, it’s my own fault that I couldn’t tell with only my mind that a dispHTMLElementCollection is actually the same thing as a NodeList as documented in the DOM2 standards.

Read the thread if you like.

One useful piece of information I did glean from this, though, the reason that getElementsByTagName (and similar functions) return something other than an array: the list they return is “live”, meaning they can update as elements are added or removed from the page. I don’t see this as being particularly useful, but, hey, at least it explains why it’s not an array.

Several non-useful pieces of information I received: link after link after link to documentation that doesn’t have the terms “dispHTMLElementCollection” and “NodeList” on the same page, and thus have absolutely nothing to do with the WTF I reported.

Apparently, to the WTF posters, this is all “common knowledge” that I should have gotten based on vague comments in a Javascript library I don’t even use. Or I was supposed to look up getElementsByTagName in the DOM, then assume that the type returned (NodeList) just happens to be the same thing as a dispHTMLElementCollection even though there’s nothing to indicate that that is the case.

To the WTF posters, writing a simple page on either Mozilla or Microsoft’s site saying, “oh BTW, dispHTMLElementCollection is the interface we use to DOM2’s NodeList, here’s a link” is a horrible burden that should be never be inflicted on anybody.

BTW, kudos to tgape who not only agrees with me that the lack of documentation is a WTF, but who wasn’t a jerk about it.

Anyway, some good came out of all of this: the next person to search for this completely undocumented class (or interface, or whatever the hell it is) will find either the WTF post or this one, and hopefully won’t waste as much time and energy on it as I have.


It brings up a question, though, that I’m too lazy to test on a Sunday morning (but maybe I will tomorrow): Since the DOM NodeList can be a different class in a different browser, how the holy hell are you supposed to use typeof(x) to find whether something is a NodeList in a cross-browser way? Alternatively, if it’s represented internally to IE as a dispHTMLElementCollection, but typeof(x) returns NodeList (which is what I suspect happens), then why the holy hell would the debugger show dispHTMLElementCollection instead of NodeList?

There’s WTFs all around.

Categories: Tech, Web Tags:

Database Collations Piss Me Off

April 15th, 2009 blakeyrat No comments

I just moved this blog onto another host, and of course in the process you have to move your database to another host. Of course, this couldn’t be an easy task:

  • First, MySQL changed the default collation on their database server installs from latin1 to UTF8. UTF8 is by far a superior choice, but it’s the change that causes the pain since all older databases are latin1.
  • To make things worse, it turns out WordPress (the software running this blog) shoves UTF8 into the database regardless of what the database collation is set to. Christ.
  • To make things more worse, when you have a latin1 database table with UTF8 in it, phpmyadmin can’t export it without filling in those UTF8 entries with junk characters.
  • And just to top it off, I have a whole blog posting based around the word “piƱata.”

Anyway, after database export after export after export, and with the help of a WordPress plug-in designed specifically to fix this dumbness, I think I have it all finally straightened-out. Everything’s moved over to the new host, and working exactly how it did on the old host. (With one exception: the backup plug-in I was using isn’t compatible with Windows servers because it uses hard-coded path separators.)

Joy.

If you see any problems with anything, please let me know in the comments. Unless comments aren’t working, then send me a singing telegram.

Categories: Tech, Web Tags:

Mini Superhero Movie Reviews: Jumper

April 12th, 2009 blakeyrat No comments

Jumper

It’s really hard to like this movie. It’s not that it’s not well-made or interesting; it’s that the “heroes” of this movie are such complete and total jackasses. Who, in fact, almost certainly cause more death and destruction than the “bad guys.” Including at least three out-right murders, one of them cold-blooded.

The story follows Anakin Skywalker- er, David Rice- as he unnecessarily narrates how he discovered his ability to teleport. Apparently, a tiny fraction of people are born with the ability to teleport themselves and objects they’re touching (up to a certain size) anywhere in the world instantly. At least if they come from broken homes, all the jumpers seem to have. Naturally, Anakin uses his gifts to rob banks, go on constant trips to tropical vacation spots, and ignore people who he could potentially save if he wasn’t such a self-absorbed jackass.

Samuel L Jackson plays Roland, an NSA agent who is also in a secret society of “Paladins” who hunt jumpers and also the most likeable character in the movie. After investigating one of Anakin’s bank robberies, Roland manages to track him down and hit him with an industrial-strength taser, which inhibits his ability to jump. Unless it’s important to the plot. Unfortunately for us, Anakin manages to escape, thus making the movie longer than half an hour.

Now knowing that he’s being pursued by the secret society, Anakin decides to lay low by going back to his home-town and the only people in the entire world who can positively ID him. Brilliant thinking there, buddy. Meeting up with his ex-girlfriend, Millie, he takes her to Rome. The conventional, airliner, way. Apparently he pays for the trip using a huge wad of cash in his backpack, and buys the tickets the day of the flight, which proves the TSA is as effective in the movie world is about the same as the real world.

In Rome, Anakin encounters another jumper, Griffin, who proceeds to murder several government agents before explaining to Anakin that the paladins have been hunting jumpers for thousands of years. How hunting down a person who can teleport anywhere on Earth instantly, and can only be stopped by tasers, was accomplished long before satellite communications was invented is not explained.

When Anakin’s carelessness leads the paladins to Griffin’s hideout, and they subsequently kidnap Millie, he must find a way to get her back and prevent Griffin from setting off a bomb… blah, blah, blah it’s really not that interesting.

But enough of the plot and plot holes. The movie is well-produced, has good special effects (especially during the world-spanning fights sequences), and the acting is passable. If you can get past the fact that every single character in it is a complete asshole, and the ending that is nothing but 5 minutes of setup for the sequel, give this one a rent. But you’re not missing much if you don’t.

Categories: Movies Tags: