If it ain’t broke…

Or, “The eighteen steps of stupidity.”

You know what they say about fixing things that ain’t broke?

Well, I spent most of today chasing an elusive Safari 2 bug (I thought it was a bug anyway). My text resizer tool setup scripts were failing and taking the rest of my onload scripts with them. It was the final day of testing and I really wasn’t happy to have an otherwise compatible site breaking in such a common browser.

Of course, my install of Safari 2 was the default version that came with OSX 10.4. I’d recently had to reinstall OSX, as the previous install was doing some funky things which I didn’t like, such as randomly resetting the password used to access the login account every now and then.

So Step 1 was to try my page out in some slightly newer versions of Safari. I downloaded Michel Fortin’s self contained versions of Safari 2.02, 2.03 and 2.04 from his Multi-Safari page, and loaded ‘em up .. but was still having issues. Plus, I couldn’t launch 2.04 because my version of OSX was too old.

By a stroke of luck, the Mac’s updater box burst into life, informing me that there was an OS upgrade available. I upgraded from 10.4 to 10.4.10 (Step 2), and after a restart Safari 2.04 launched fine. But, I was still having issues.

After a bit of cursing, I headed on over to Apple’s site to download the beta of Safari 3. Interestingly this is now also available for Windows, but, as someone wise commented: “Do we really need another browser [for Windows]?”

I know the answer to that question, and if you don’t then I’d suggest that you head on down to evolt.org and check out the plethora of browser wannabes sometime.

Now, hate is such a strong word, so I’ll simply say that I dislike beta browser releases, just as I dislike the people who download beta browser releases and then visit sites that I build and expect them to work flawlessly in their version x beta browser release. If it has the tag ‘beta‘ officially appended to its title, then that should tell us that it’s not a final release, and it’s probably in beta for a reason.

But, I was stuck – if it was a version issue, and my code was going to work in a newer version, there was only one way to find out. So I did the deed, and after a restart, and with Safari 3 beta installed, I was still having the same trouble.

Now, to be honest, at this point, I really didn’t have any idea what was going on, so Step 3 was to enlist the help of Safari’s helpfully hidden Javascript debugger tool, the ‘Debug’ menu. Thanks Apple.

Once I got that up and running, I knew right away what the problem was. It was a case of the ol’ DOM Exception 8. Hang on. The what? I turned to Google for help (Step 4), but all Google gave me was links to forum posts containing knowledgeable comments like: “..a wonderfully usless error message..” and “..try not to raise DOM Exception 8, whatever the f**k that is.”

Having nearly exhausted all three pages of results for the (exact) search phrase “dom exception 8″ I finally found a link to blech’s del.icio.us ‘error’ bookmark (Step 5) for Webkist (Step 6), only that link was broken, so back to Google (Step 7), then via the ErrorZilla add-on (Steps 8 and 9), and shortly thereafter to the wayback machine (Step 10).

As a side note, I love it how the current AJAX craze hit NZ in 2006/2007 but this old, deleted, forgotten post, was from way back in ’05…

Anyway, after congratulating myself on my small search victory, I quickly realised that the Webkist post, while helpful, really wasn’t all that helpful as it wasn’t actually the same issue as I was having after all. But, it was a lead of sorts.

And then, at some point, a light went on and I discovered that Safari’s ‘DOM Exception 8′ was one and the same thing as Firefox’s Node was not found” code: “8 (Step 11). Given the importance of this discovery it’s a real shame that I can’t actually remember exactly where I got this from. Perhaps my brain started working at this point, but it’s unlikely. Anyway, although it seemed like the-key-to-everything at the time, it later eventuated that it was actually the-key-to-nothing. Well, not quite, but read on for more stupidity..

So, armed with my newfound knowledge, I set up a local test page (Step 12), to test appendChild() and removeChild(). My theory was that my text resizer node couldn’t be removed because I was trying to remove it from its DOM grandparent rather than its immediate parent {insert wisecrack about grandparents and grandkids..}.

My grandparent vs parent tests worked as I had hoped, and I validated my findings after reading this helpful post here which lead me to the relevant docs here and here (Steps 13, 14, and 15). In due course I resolved the bug by using removeChild() to remove my text resizer element from its immediate parent, div#tools (Step 16).

And then I realised.. that my removeChild() issue was just a red herring. Lo and behold, the script proceeded to fail at line 146. Woo hoo.

Line 146 was the cookie test. Now, in the past I have had problems with this particular cookie script, in particular it has appeared to fail in my Safari and IE5 test browsers, and I often wondered if the reason was that said test browsers were perhaps somehow somewhat less than fully functional. But this time I looked to the code for salvation.

Now, I didn’t write the particular cookie script in question, rather I did what any good developer worth his salt would do – I ripped it off Quirksmode. Unlike me, the author of Quirksmode, ‘PPK’, is a proper Javascript developer, and he capably writes his own scripts from the ground up, rather than chopping together others’ snippets with snippets of his own. On the other hand, like me, PPK likes to test very throughly. And I respect a man that takes the time to test his assumptions. Believe me, not everyone does..

I doubted very much that the trustworthy PPK was to blame. And so, in Step 17, I compared PPK’s scripts with my own scripts, aka PPK’s scripts. Now, even though I am an evil guy, in that I take more scripts than I make for others to take, I still like to understand how the scripts I am taking actually work. And, once these scripts are integrated into my scripts, I like them to look the same, ie they have the same formatting, the same style of commenting, etc. This way everything is readable, or not, depending on whether you like a(n) (un)healthy amount of white space in your javascript, like me, or not.

So, back to Step 17, and comparing the code. At a glance everything seemed in order. But, I did notice a little extra whitespace in my cookie script, aka PPK’s reformatted cookie script. Surely this could not be the culprit?

I removed the whitespace, and uploaded the script to test in Safari, (Step 18).

Problem solved, Safari happy, Dan happy, Project Manager probably happy, and I’m pretty sure this will resolve my IE5 cookie issues too.

Lesson learned.

CSS: Position

It’s true, I *am* a mental patient =P. For some unknown reason my lobotomised brain thought that once you set position:relative; on an element you couldn’t override it. Overuse of position:relative can create tricky aneurysm-causing IE5 and 6 bugs, but now, thanks to my new found knowledge (courtesy of css-discuss and w3 schools) that in fact position actually has a possible, nay default value of ‘static’, I can finally override position:relative when I need to :)

View source

I often use View Source in Firefox to view the page source after all Javascripts have run: CONTROL+A → Right-Click → View Selection Source.

As I work remotely and my two testing computers aren’t set up to do the VPN connection, I often use this technique to save out a copy of a page for viewing and debugging in IE7 and Safari.

Something to be aware of is that this generated source omits the page Doctype, which can mean funky rendering in IE7. Replacing the Doctype after pasting the generated code fixes this problem and creates one less diversion when developing cross-browser scripting and styling.

Update 11.08.2007: It also looks like source code viewed in this way is also converted to HTML markup, regardless or whether it was authored as XHTML or not.