JavaScript Variable Declarations

This one is for the JavaScript nerds. No suspense as I’ve included the answer below the question.

NOTE: This is lame-ass, test code. Anyone who codes like this should be shot, or at least have your eyes taped open and be forced to watch Gigli three times.

But I wanted to remind myself how variable declaration, definition, and (non-)block level scoping worked in a basic JavaScript function.

Ready, set, go:

// What strings will be displayed in the 4 alert statements?
//
// This is designed to be a test, not a trick.
function test() {
    i = 20;

    alert(i);
    alert(window.i);

    if (true) {
        var i = {};
    }

    alert(i);
}
test();
alert(window.i);

Answers for the impatient:

  1. 20
  2. undefined
  3. [object Object]
  4. undefined

My JavaScript reminders:

If anyone is a JavaScript nerd and you happen to stumble in on this post, please feel free to post anything I forgot.

Help from my friends and random people on IE8 Dynamic CSS?

To my five fans (to those reading that aren’t part of the fan 5 crew, my 5 fans are also good friends):

I have a bit of a dilemma in some web coding.

Problem: I need to be able to dynamically inject some CSS rules into a web page through JavaScript. (Long story why, I just do.) In all of my target browsers, various methods would work to inject CSS into a web page via JavaScript. IE8 does not like any of these previous methods. The only way I’ve found so far to get this to work in IE8 is the following hacktastic solution:

    function hacktasticSolutionToDynamicCSSInjectionInIE8() {
        var myCSS = "<style>.redText{color:#ff0000}</style>";
        document.getElementsByTagName("body")[0].innerHTML += myCSS;
    }

Using the method above to inject a stylesheet into the body tag via innerHTML so makes me want to gouge my eyes out. But it’s the only thing that seems to work in IE8?

Other things I’ve tried that have failed:

Anyone reading this who knows of a better solution than what I’ve done in the hacktastic function above?

Edit: 7/3/2009
Turns out in all my tests, Internet Explorer tends to provide a “free” stylesheet by default. The following code did what I wanted on all IEs, and everywhere else.

    if ( document.styleSheets[0] && document.styleSheets[0].cssText ) {
        document.styleSheets[0].cssText += cssString;
    } else {
        var style = document.createElement("style");
        style.appendChild(document.createTextNode(cssString));
        document.getElementsByTagName("head")[0].appendChild(style);
    }

Does anyone have mad linux April Fools skills?

I know, I’m a day late, but a mix of Boston Legal and messing around with linux lead me to this question:

Anyone know how to make the ‘whoami’ command spit out:

Denny Crane

when used as root, without just rewriting the whoami binary?

The spam bots are getting smarter

This was a spam comment at the top of my spam list yesterday:

Submitted on 2009/03/31 at 9:18am
You’re a good but lazy blogger.
bathrooms@racecare.info
bathroom accessories
spam
Approve | Delete | Edit | Quick Edit

How to get that Web Inspector, Java Script Console, DOM Explorer up in Safari on Windows

This has been written before, but it’s just not propagated enough. After spending a day and a bit chasing down really esoteric browser incompatibilities, I’d like to drop another bit of information into the ether for those 0.00005% of people who just might appreciate it. Other people have reported on this, but most posts are ancient and not currently useful.

Problem: I want to work on Safari 3.1 in Windows XP Service Pack 3, not the WebKit nightly builds. The tardtastic Developer Safari FAQ neglects to tell me how to open the JavaScript console on Windows.

Solution: To turn on your JavaScript console in the set-up listed above:

  1. Find your Safari WebKitPreferences.plist file. If your setup is like mine, it should be located in:
  2. C:\Documents and Settings\INSERT_YOUR_USER_NAME_HERE\Application Data\Apple Computer\Safari

  3. Input these two lines between the <dict>...</dict> tags
  4. <key>WebKitDeveloperExtras</key>
    <true/>

  5. Restart Safari, if it’s running.
  6. After opening a page, right click on the page to bring up the context menu
  7. Click on the “Inspect Elements” menu option

Viola, Web Inspector.

And remember, it is “Love your pet rock” week starting tomorrow.

Mozilla and other open source customer service better than I expected

I have used lots of open source software, but I have not been a good bug submitter. I have rarely submitted bugs to the developers, mainly because I never thought people would pay attention to them, nor did I think the developers actually cared. Odd to admit my arrogance, since when I write code I genuinely care about it, and I should assume others do, too.

Recently I bit the bullet and submitted a (small) handful of bugs to different projects, and have been 100% happy and surprised with the responses. The most recent bug I submitted was to Mozilla, in regards to what I thought might have been a problem with their implementation of the JavaScript delete operator. The bug was submitted on January 12th, 2009. The first day the bug was passed around to real people given the real sounding email addresses. Commentary about the bug appeared in my inbox in real time. You can check out the progress here. Commentary continues to this day. [The bug was confirmed as a real bug while I wrote this.]

What’s different is most likely my expectations given the situation. I expect commercial corporations, like banks, phone companies, rental car companies, cable companies, to treat people appropriately and handle our complaints with interest and genuine care. I expect to deal with real people who I could potentially talk to again and again, and not just be shuttled around the system with a “complaint identification number.” After all, if they show they care, they might just get more money from me. Sadly, that seems to rarely be the case anymore, as even my wife has gotten into corporate customer service bashing on her blog.

Of course the Mozilla Foundation is not exactly a poor, garage shop operation, but they are non-profit and they’ve never seen a cent of my money. They haven’t jumped up and down, patted me on the back and said, “Good boy! Good boy! Find that bug! Yay!” but that isn’t what I wanted them to do. I wanted them to take a genuine interest in the problem I had, and assign resources to investigate. They seem to have done exactly the right thing.

Are we at the point where commercial corporations could learn a thing or two from non-profits and open source projects? Or perhaps are we now experiencing the difference between dealing with people who genuinely care and have a stake in something — open source projects for example — and people who don’t give a shit except about clocking in the hours for their next pay check — aka. customer service employees at for profit corporations?

I don’t know the answer to those questions. I do know that I’m more open to submitting bugs to open source software projects, and that’s a nice change.

The delete operator blows on Firefox 3.0

My friend Brent and I have been refactoring for the next release of the JavaScript API we work on. One of our mini projects made me happy because I knew I would finally have a reason to use JSLitmus. One of the tests we did I believe is worth blogging about.

The scenario is that we currently use a JavaScript Array object to hold a dictionary of callback functions. We index the function in the array with the raw number used to id the request, where the raw number is a random integer from 0 to fucking-gigantic. When the server responds to our request, if there is a callback function associated with the id of the response, then we call the function and null out it’s position in the array.

Essentially:

/* initialize shit */
_callbackArray = [];
/* store shit for later */
_callbackArray[requestId] = functionToCallLater;
/* tell shit to happen */
/* shit happens */
/* catch shit, here responseId === requestId */
if ( _callbackArray[responseId] ) {
_callbackArray[responseId]();
_callbackArray[responseId] = null;
}

Brent and I were curious about:

I decided to test out the second item first. I whipped up a test on JSLitmus to check the speed of our proposed solutions:

What was interesting was how Firefox 3.0.5 on Windows choked like an amateur fluffer when executing a massive number of delete operations. JSLitmus produces cool charts, and I include them for shock value. The graphs are normalized, make sure to pay attention to the numbers (ops per second).

JS Litmus tests of the delete operator on Safari 3.1

JS Litmus tests of the delete operator on Opera 9.5

JS Litmus tests of the delete operator on IE 7

JS Litmus tests of the delete operator on Firefox 3.0

74 deletes per second on Firefox 3.0? It’s like JSLitmus said, “I haz failed ur deletes.” It makes me cry when IE does something better. [Ed: Opera and] Safari are majorly fucking fast, no surprise there. For thoroughness, Brent did some tests on Chrome, and while I didn’t grab the chart off his computer, it appears Chrome is just as handicapable as Firefox when it comes to running delete operations.

Grain of salt: just how many people really need to run tens of thousands of delete ops at a time? No matter the validity of this test, I think the surprise is worthy enough to file a bug with the browsers.

Memories of the Logo Turtle

I’ve been messing around a lot with Canvas and I keep adding the penUp method into my code. Firebug then quickly reminds me that Canvas is not equal to Logo. (I should preface my posts nowadays with a nerd alert….)

Anyone else remember Logo? When the nostalgia hit hard on Sunday I searched for a web version. It’s good to know the Logo Turtle is still alive and well.

See my pretty star that I drew (with the help of the cheat sheet at the bottom of the Logo page).

The old Logo Turtle

My coding mistakes: Time to stop using the escape function in JavaScript

Mistake: Just because the JavaScript escape function has worked well for my American- and European-centric tests doesn’t mean it works for Chinese characters.

Yep, after I figured out the French character problem along comes a problem with Chinese requests. Not really surprising: the code I inherited was well designed, but it was only ever really tested in the US, somewhat in Europe, and never really tested in Chinese applications.

I didn’t have any problem finding a test case. I just grabbed what I thought looked like a cool character from my test examples:

I don’t speak Chinese, hell I almost didn’t make it to the Airport in Shanghai when I braved a taxi ride on my own, but Google found me a great site that had a load of Chinese characters along with their Unicode and UTF-8 character encodings at http://www.ansell-uebersetzungen.com/gbuni.html.

This one was a lot easier to figure out. The character:

Should have been translated into the following hex codes:

%E9%BB%84

But nope, it was being translated into the string of the Unicode index:

%u9EC4

If I wanted a straight Unicode lookup, this would have been great, but the server expected UTF-8 encoding. The Mozilla Developer Guide says that escape shouldn’t be used. Well, escape worked just fine until we introduced Chinese characters, and since we needed to support Firefox usage, escape had to go. Looks like escape only works correctly for 1-byte (ASCII) and 2-byte UTF-8 characters, but breaks on 3-byte and larger characters.

Conclusion:
Use encodeURI or encodeURIComponent in modern browser code instead of escape. For a good comparison of these two functions, please see this article.

My coding mistakes: UTF-8 character encoding can’t be assumed

Sometimes I make mistakes that I know I shouldn’t. Rather than hide them, I will share them (when I find time to do so) in the hopes that others might learn from them.

Mistake: Assuming that all characters on a web page in a UTF-8 configurd browser are treated as UTF-8

Let’s start with the instigator of the problem, found in a French test word, the small e acute:

é

Damn French characters. My distilled process that recreated the problem:

I got lucky and guessed the category of the problem correctly immediately: Character Encoding. But wasn’t everything supposed to be in UTF-8 these days? Damnit, how can I be sure?

I followed this path to figure out what was going on:

The idea of character encoding, or the storage of (usually) visual and human understandable glyphs by a (usually) computer system, is not magic.

I see the letter on my computer screen as:

é

Assuming UTF-8, the computer sees the following string of bits, from left to right:

11000011 10101001

Something was happening in the transfer between my web page to the backend server, that’s all that I could figure out. A little more investigation and I stumbled onto the second layer of the problem: what I thought was going on and what was really going on.

I see the letter on my computer screen as:

é

In UTF-8, the bits of this letter are:

11000011 10101001

But I wasn’t actually sending bits as bits, I was sending the bits as a hex string in a URL, encoded as follows:

%C3%A9

I looked closer at the results I should have been getting from the server and the results I was actually getting. The results were entirely fubared, totally and completely. I mean, the server was returning results, but it was as if I was asking a question in French and getting an answer back in Esperanto.

I could only guess that my original UTF-8 character, the small e acute, while seemingly being translated as a double-byte UTF-8 encoded character might actually be decoded on the server as two characters. It would be weird, but it would explain the most bizarre results I was getting back.

Take the:

é

That I sent to the server as:

%C3%A9

And what if the server was decoding it differently, say as part of the ISO-8859-1 extended set:

é

With fuzzy matching doing it’s magic on the server side, I guessed the resulting single byte characters might have led to the crappy results that were being returned. The server was supposed to work with UTF-8, but what if I was somehow signaling the server to treat my requests as Latin-1. Didn’t make a lot of sense, but I wasn’t in charge of the server.

Browsing around on the internet, I learned that the following element should be inserted into the head element of web pages to signal that everything should be dealt with as UTF-8:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

After I made this setting to everyone of my web pages the requests in French returned results that made sense and the results I was expecting.

Conclusion:
On the web, don’t assume things are in UTF-8, or any encoding for that matter. Explicitly set the encoding on the web page.

Next Page →