2006-06-16

User script clashes

Aditya Mukherjee noticed that my Blogger post tagger/publish helper recently failed to link Del.icio.us from the "posted" page in his setup, and some debugging later, we found it was a clash between that script and Stephen's Blogger trackback script.

Collisions like these are inherent to the stigmergy model of user scripts, where multiple scripts affect the environments of one another. It takes a bit of attention to defensive coding practices to avoid problems like these. Especially considering that invocation order might make the combination of two scripts sharing environment work with the one script installed prior to the other (which, at least in Greasemonkey, is what decides the script invocation order), but not the other way around. Apply Murphy, and users will encounter trouble, even if you made sure one of the combinations worked. (This gets increasingly unwieldy if you widen scope from two scripts to three scripts, or indeed seventeen.)

It took us a bit of debugging to weed out what went wrong and why, but Aditya found me on a good day with a bit of time on my hands, and we dug into the problem, sprinkling alert()s and try{ ... }catch(e){alert(e)} statements all over the place until we had it down to where what happened and didn't, and before long it was aparrent that it was some other script that tripped mine, and Aditya homed it in to Stephen's, which in turn was based on mine.

In-bred scripts that try to do very many things, for various reasons, are more likely to suffer this condition than others. I often make whole little applications in user script form, rather than separating each feature into a user script of its own, and this script was no exception; it made links out of plaintext paths, added some useful links Blogger does not, and so on, and Stephen's adopted version of the script did many (if not most) of the things the original did, so when they both tried to, one was doomed to fail, and uncharted chaos ensue.

The more assumptions a script makes about its environment, the more likely it is to break. Picking up some script to use as a base for another script is a practice I rather like, and encourage; this lowers the bar for many a scriptwright to achieving results, which is of course good. The point I try to make here is that you should try to strip off as much of the cruft of the base as you possibly can before doing what you want with it, refactoring it to avoid as many side effects as you can that are not what your script sets out to achieve.

Similarly (and this goes just as much for me), it is a healthy practice not to add a busload of side effect featurities to a scipt, if you can stay away from it, as every assumption made adds potential conflicts to integration with other scripts. As user script authors, we deal with an unryly fauna of cooperating or competing scripts that all try to live their lives, and we do not have the luxuries of memory protection and similar safe-guards which applications developers have; indeed the whole point of the user script is to tamper with the bits of others.

Occasionally, it is unfortunately necessary to marry wildly different features into a single script for doing cross-script configuration data sharing, to have them instead share a local storage namespace. (As some scripts depend on the same set of configuration data to do their job and to work in concert.)

Otherwise, my tip is to avoid the temptation of bundling up everything under the same hood while you are at it, at least if you write your scripts, intending to share them with a wider audience.

2006-06-12

Better than Ajaxian on web dev

I mention little of what online reading I consume, but for the part of my readership that swim in the deep end of the pool, I'd like to recommend a really good read in Hedger Wang's blog, appropriately subtitled "The more you know about WebDev, the more you you find here". This post is a small tribute and / or love story about it.

Superficially and at first glance, it looks a bit like just another Yahoo 360 blog among the masses, much like this blog is just another *.blogspot.com blog, or like some run-of-the-mill opt-in community blog on MySpace, LiveJournal et al; same kind of visual furnishing and jump-the-hoops-to-access-visitor-commentary functionality. But there is startlingly little, if any, narration in the actual blog.

In reality, it's really more of a raw feed of applied web research and development, condensed to absolutely minimum commentary about purpose, when especially difficult to situate into a usefulness context. It's the kind of blog you read as much in below-surface "view source" mode as in surface rendered HTML mode. It does one thing, very well, per post, often outlining portability scope, and it's rather written in the universal language of code than in English, rarely wasting any of the reader's time at all with words. It's a growing repository of reference knowledge.

To get a complete list of all 150+ posts from the last year, visit www.hedgerwow.com. That takes a while to load, as each post gets pulled in to the page from the Yahoo 360 back-end via asynchronous proxied XMLHttpRequest fetches. So the 360 surface is mostly a front; Hedger really uses Yahoo as a storage/persistence/feed backend for his writing, perhaps as a way of focusing on content rather than ephemeral surface and presentation.

At least that's my take on it; when I went back to blogging after a few years' worth of non-blogging, I specifically picked a blog provider that would not let me tweak the server side, so I'd spend more time blogging than hacking the blog framework itself.

In hind-sight, I sort of failed, instead spending time polishing up solutions to work the same kind of magic client side, even in the limited confines of a Blogger blog. (I left Advogato for its total absence of visitor commentary functionality.) Blogger's template customizability just offered enough of an open but limited environmental confinement to allow creativity to expand on it, unleashing and flexing all the new-found powers that HTML, CSS and javascript have gained in recent years, and end up again with the kind of unwieldy rusting blog I had in the nineties. :-) But enough about me.

Reading Hedger's posts has something of the same kind of thrill as diving into either of the Myst / Riven / Exile saga games, not in a visual or musical setting, but in unraveling things, finding what logically goes where and discovering the mechanics, purpose and possibilities of things. It offers ingenious tricks and new takes on things, tracking the technical web development front and how to trick web browsers we are stuck with today to perform the tricks we expect them to but which web standards typically do not yet address.

It's not for everyone, but it's a gold mine for its target audience. I keep coming back to things like his neat PNG transparency in Internet Explorer 5.5+ hacks when I need them. (And by the looks of things, I won't remain for very long in a line of work where I do now.)

2006-06-01

Firefox 1.5.0.3 E4X bug and work-around

For those of you who have been happily running Mark My Links and noticed that its configuration page stopped working on upgrading from Firefox 1.5.0.2 to 1.5.0.3 recently, I tracked down the regression today and found a work-around. The script has been updated now.

It boils down to the slight E4X shortcoming of not really supporting (I believe -- corrections warmly welcome) a way of writing a tag literal with a dynamically decided presence of some attribute -- as you want to do when generating a checkbox tag that either is checked or not (<input type="checkbox" checked="yes"/> vs <input type="checkbox"/>).

To do this, I kludged a solution that adds a harmless unchecked="yes" attribute when not checked, and this broke in 1.5.0.3 under particular conditions. Reordering the attributes to feature the dynamically named attribute last kludged the kludge to work again.

More exact technicalities in the bugzilla ticket.