Sergio and the sigil

Oh, no. My TortoiseSVN overlays are missing

Posted by Sergio on 2010-01-05

It's a matter of time. Good were the days when almost no application knew how to put overlays on your file icons in Explorer. These days it seems this is the coolest thing ever and virtually all file system type of utilities want to add their own.

Sooner or later you will install some utility and not notice anything different. But after the next reboot, poof, your TortoiseSVN overlays are gone. And, depending on how much time elapsed between the utility installation and that reboot, you may not have the slightest clue of what happened. Reinstalling TSVN won't fix it

TFS Power tools, Dropbox, Mozy, stop breaking my TSVN overlays

I should not blame these applications for a Windows shell limitation. To be fair, TSVN is the greater offender of them all.

It seems that the shell only supports 15 different icon overlays and TSVN creates 9 of those. After 15 the shell starts ignoring the extra ones. The trick is that Windows chooses the first 15 alphabetically from their entries in the system registry.

I love simple fixes

The fix is rather obvious; just make sure the overlays you want to be active are registered alphabetically before the ones you can live without.

Open the registry editor and go to HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers and look at all the child keys in there. It will be obvious that, if you want to preserve the TSVN overlays like me, you need to keep the ones starting with Tortoise* before the other ones.

If you look at the image below you'll see that I changed my entries by prefixing the undesirable ones with z_, following someone else's suggestion.

After that change you just need to kill and restart explorer.exe using Task Manager (or logoff or reboot the machine depending on your tolerance to pain.)

I believe this is a common problem so I hope this tip helps somebody.

IE6 still haunts me

Posted by Sergio on 2009-10-21

Oh, the woes of supporting IE6 (or, better put, IE666 — the browser of the beast.)

Halloween is definitely upon us. Today I spent a good chunk of time trying to identify the source of a problem in my application. Right now I'm in the process of jQuery-fying some legacy JavaScript, which includes Ajax calls and error handling logic.

At some point I needed to pop-up a DIV that was supposed to look like a modal message box, reporting some error that happened during the Ajax call. That was not hard at all. I used the SimpleModal plugin and got the message box up in not time at all.

Not so fast, you have IE6 users

As with many web developers out there, I don't have the luxury of ignoring IE6 users because they are upwards of 60% of our user base (corporate users that for some reason can't easily upgrade their browsers.)

I thought it wouldn't be a problem because the SimpleModal plugin handles a number of IE6 issues, including the insertion of an IFrame to overcome the bleedthrough of Select tags. But of course it couldn't be that easy right?

In some of my tests IE6 was simply crashing when I tried to open the "modal" message. After a lot or hair pulling, I saw this suspicious HTML in one of my messages:

<table style="font-size: expression(parentnode.currentstyle.fontsize);" >
    <!-- rest of the table is normal -->
</table>

Sure enough, moving that hack to a proper CSS rule in the external .css file made the error go away. We shouldn't be using dynamic CSS expressions anyway, since they were removed from IE8, so I went ahead and ditched that kind of usage wherever I could find it.

This is just to keep us on our toes regarding IE6 support. Even though the modern JavaScript libraries go to great lengths to support IE6 and make our coding transparent, nothing substitutes good old manual testing to make sure IE6 doesn't play pranks on us in production.

JavaScript and its love for zeroes

Posted by Sergio on 2009-09-19
This post is part of a series called JavaScript Demystified.

Answer quick. Do you know what date is being created here?

var year = '2009', month = '09', day = '01';
var date = new Date( 
             parseInt(year),
			 parseInt(month),
			 parseInt(day)
			 );	

At first glance, it wouldn't surprising that someone guesseed September 1st 2009. However, I'd not be writing this post if that was the correct answer, right?

There's an interesting and tricky thing with the JavaScript parseInt function: it can parse strings with a numeric value in the decimal radix, but also in other radices. See the following examples.

//passing the radix explicitly
parseInt('1011', 10); // ==> 1011
parseInt('1011',  2); // ==> 11
parseInt('1011',  8); // ==> 521
parseInt('1011', 16); // ==> 4113

Maybe you thought that if you didn't pass the radix, then it would default to 10 because it's the obvious behavior. Well, no. In JavaScript the default behavior is to try to identify one of the literal formats and interpret that. So here's that in action:

//leaving JavaScript on its own
parseInt('1011'); // ==> 1011 (decimal literal)
parseInt('0x12'); // ==> 18   (hexadecimal literal)
parseInt('0511'); // ==> 329  (octal literal)
parseInt('0182'); // ==> 1    (whaaaa?!?!)

If you are familiar with the literal notation for integer numbers in JavaScript, and after I explained the default behavior of parseInt, then you probaly understood the results shown above. Well, maybe the last one deserves some comments.

When JavaScript is parsing the string, if it finds a digit (number or alpha) that is invalid in the chosen radix, it stops right there and parses only the portion of the string that comes before that digit. So, since we started '0182' with a leading zero, the octal radix is assumed. Then, because 8 is not a valid octal digit, only '01' will be parsed, which becomes 1.

Tip #1: If there's any chance the string value you plan to parse into an integer number has a leading zero (or a less likely 0x,) then be safe and pass the radix parameter to your parseInt call. If you're extra paranoid, then always pass the radix.

Back to our original question

Armed with the clarification made above, we can expand our example like this:

//given:
var year = '2009', month = '09', day = '01';
// then the following statement:
var date = new Date( 
         parseInt(year),
         parseInt(month),
         parseInt(day)
         );	
//...is equivalent to:
var date = new Date( 
         2009,
         0,  // ===> oopsie
         1
         );	

Hmmm, a zero in the month parameter. Will we have an error here? No, here comes the second potential surprise of this post.

Tip #2: When creating a new date using new Date(year, month, day), the month parameter, and only the month parameter is zero-based (0 to 11).

So, in case the tips and the picture in this text were not enough to help you guessing the date being created, here goes another completely gratuitous one with the answer.

Taming Firebug with Profiles

Posted by Sergio on 2009-09-01

This is a tip for anyone using Firefox and Firebug for web development that is not leveraging the Profiles feature of that browser.

Recent versions of Firebug (after v1.3 I think) removed the ability to enable Firebug panes on a per-domain basis. Now it's kind of all or nothing. And you know that you don't want to have Firebug enabled when using Ajax-intensive applications like GMail, for example.

The end result is that you are stuck in this annoying dance of of enabling/disabling, open/close Firebug when switching tabs.

There are some workarounds for that but I think the best solution for this problem is through Profiles, which is also a very nice approach for web development overall.

Firefox Profiles

Firefox stores all your preferences (add-ons, state, saved passwords, history, etc) inside profile directories. It installs a default profile and that's perfectly enough for the casual browser user. Web developers, add-on developers, and power users in general, on the other hand, can find handy uses for extra profiles.

You can see your profile directories in %APPDATA%\Mozilla\Firefox\Profiles (or, on the Mac, ~/Library/Application Support/Firefox/Profiles).

Development profile

The suggestion I'm giving is to create a separate profile just to be used during web development work. That way you can exclude some of the add-ons (like ad blockers, bookmarking extensions like Delicious, and any other non development-related extensions.) The opposite applies to your default profile — you can now remove all the development stuff from that profile and keep your browser a little lighter. In addition to that I use a different skin/theme in each profile, just to make it screaming obvious which one I'm looking at.

Here's how we create a new profile. First close all your Firefox windows and make sure there's no Firefox process running in the background. Now go to the command line and enter this:

(on Windows)
%ProgramFiles%\Mozilla Firefox\firefox.exe -ProfileManager
(or on the Mac)
/Applications/Firefox.app/Contents/MacOS/firefox -ProfileManager

This will bring up the Profile Manager, where you can easily create a new profile. Create one named Development and start it.

Once started, you'll notice that Firefox will open looking just like it did the first time you installed it. You can now install your favorite extensions for web development (like Firebug, YSlow, Web Developer Toolbar, User Agent Switcher, etc)

To launch Firefox using the the Development profile you can create a shortcut that passes some arguments to Firefox, like firefox.exe -P Development -no-remote. For example, I added that shortcut to my Desktop, Quick Launch, and Launchy. (Firefox will remember which profile you started last using the Profile Manager, and use that one next time you start Firefox without explicitly choosing a profile. You may want to leave the default profile selected in the Profile Manager.)

More uses for Profiles

Besides creating a profile dedicated to web development work, I can very well see myself eventually creating extra ones for different activities, like a Presentation profile and a NoAddons profile, for example.

Circular Refactoring

Posted by Sergio on 2009-08-14

One of these days I was chatting with Derik and we were talking about refactoring and when to stop refactoring. We thought it was funny (and embarrassing) how sometimes, after a few consecutive refactorings, we are back at the starting point.

This type of Circular Refactoring is a real productivity enemy. In our genuine desire to improve the code, and wishing to dive into an interesting task, we sometimes lose sight of the code history and the real need for this change. It reminds me a lot of this funny comment (second part).

How do you tell when you're being a victim of this variation of the premature optimization monster? Well, here's a start:

Top 10 signs you've fallen into circular refactoring

9 - Code gets eerily familiar by the minute.
8 - Your git repository doesn't seem to grow.
7 - Work feels too much fun to be real.
6 - Your code metrics trending charts look like Bart Simpson's hair.
5 - You're never breaking any of your unit tests after each change.
4 - You've created macros in the IDE to help with almost all the steps.
3 - You're refactoring your macros.
2 - Clippy is asking if you've heard about the "svn merge" command.
1 - TFS, on the other hand, still can't offer you much help.
0 - Your Find/Replace drop-downs seem to read your mind.