talideon.com

Blackout Ireland

Entries for March 2005

March 6, 2005 at 11:04PM Comments rights on this site

Spurred by this post on Ned’s blog, I think I’d better outline my attitude towards comment copyright on this site.

Bryan Price posted up a link to his site disclaimer in one of the comments. He pretty much sums up my own views on it, but I’d better phrase it in my own language:

  1. This is my site, and any content on it is mine: quote away, link all you like, just attribute me.
  2. If somebody posts something, that belongs to them. However, by posting here, you implicitly give me the right to archive and display what you posted.
  3. It’s a good idea to supply email addresses when you comment because if you ever want me to remove something I’ll only accept the request if your email address and the address of the comment match. Otherwise, tough.
  4. I reserve the right to remove any comments. I may even edit your comment if I’ve very good reason, but any edits will be completely transparent and annoted. I try to suck as little as possible, but this is, after all, my personal dictatorship.
  5. Spam and nonsense will be deleted. Don’t even bother. Particularly, spamming comments with links to crap won’t work here. Why? I’ve the site set up so that search engines ignore any outgoing links on any pages with comments on them. Oh, the joy of nofollow!

And there you go. That’s surely fair enough, isn’t it?

Comments, by the way, rock my world, so don’t be afraid to post them. [wink]

March 15, 2005 at 10:30PM Using to get nicer URLs

Here’s another one of those things that sits at the back of your head, gnawing at your attention until you think to yourself, “bugger it, I have to take a look”. And I did.

I think it might be possible to use the CFERROR tag to give this site nicer URLs. Despite my protests that a decently-written URL rewriter wouldn’t have all that much impact on the overall speed of the server, the lads have refused to let me write one and install it. So be it.

But I can get around that. With CFERROR, I can catch any bad requests and frob about with the URL to find out what exactly to display. Oh frabjous day!

Fun stuff coming as soon as I can be bothered to implement it.

Update: ok, maybe not. Apparently, in CF5 at least (which I’m stuck with on this server for now), a page set up as a request error handler can’t include CFML tags, and is wrapped in an implicit CFOUTPUT tag. Grr! So much for my fiendish plans.

March 15, 2005 at 11:00PM Fixing JavaScript memory leaks for good.

I’m a fan of unobtrusive JavaScript and I’ve strove to make my JavaScript code as unobtrusive as possible for years now.

However, I discovered something about IE a while ago when I was reading through the comp.lang.JavaScript FAQ: IE leaks memory like a sieve when you use closures with any kind of COM object (including DOM elements, which are implemented using COM). That kinda sucks. Firefox and other browsers apparently have the same problem only to a lesser extent. Damned multiple garbage collectors!

I’ve run into the whole memory leak problem before, but it never occurred to me that was the cause. But last weekend, I decided to fix it once and for all.

So I present to you my very own all-singing, all-dancing EventManager!

/*
 * EventManager.js
 * by Keith Gaughan
 *
 * This allows event handlers to be registered unobtrusively, and cleans
 * them up on unload to prevent memory leaks.
 *
 * Copyright (c) Keith Gaughan, 2005.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * (CPL) which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/cpl.php
 *
 * This software is covered by a modified version of the Common Public License
 * (CPL), where Keith Gaughan is the Agreement Steward, and the licensing
 * agreement is covered by the laws of the Republic of Ireland.
 */

// For implementations that don't include the push() methods for arrays.
if (!Array.prototype.push) {
    Array.prototype.push = function(elem) {
        this[this.length] = elem;
    }
}

var EventManager = {
    _registry: null,

    Initialise: function() {
        if (this._registry == null) {
            this._registry = [];

            // Register the cleanup handler on page unload.
            EventManager.Add(window, "unload", this.CleanUp);
        }
    },

    /**
     * Registers an event and handler with the manager.
     *
     * @param  obj         Object handler will be attached to.
     * @param  type        Name of event handler responds to.
     * @param  fn          Handler function.
     * @param  useCapture  Use event capture. False by default.
     *                     If you don't understand this, ignore it.
     *
     * @return True if handler registered, else false.
     */
    Add: function(obj, type, fn, useCapture) {
        this.Initialise();

        // If a string was passed in, it's an id.
        if (typeof obj == "string") {
            obj = document.getElementById(obj);
        }
        if (obj == null || fn == null) {
            return false;
        }

        // Mozilla/W3C listeners?
        if (obj.addEventListener) {
            obj.addEventListener(type, fn, useCapture);
            this._registry.push({obj: obj, type: type, fn: fn, useCapture: useCapture});
            return true;
        }

        // IE-style listeners?
        if (obj.attachEvent && obj.attachEvent("on" + type, fn)) {
            this._registry.push({obj: obj, type: type, fn: fn, useCapture: false});
            return true;
        }

        return false;
    },

    /**
     * Cleans up all the registered event handlers.
     */
    CleanUp: function() {
        for (var i = 0; i < EventManager._registry.length; i++) {
            with (EventManager._registry[i]) {
                // Mozilla/W3C listeners?
                if (obj.removeEventListener) {
                    obj.removeEventListener(type, fn, useCapture);
                }
                // IE-style listeners?
                else if (obj.detachEvent) {
                    obj.detachEvent("on" + type, fn);
                }
            }
        }

        // Kill off the registry itself to get rid of the last remaining
        // references.
        EventManager._registry = null;
    }
};

Download EventManager.js, and be happy.

Update (2005-06-07): I put the updated version that supports event capture and fixes the bug where it wasn’t deregistering handlers in browsers that support addEventHandler() and removeEventListener(). Those who want this code to work on older browsers should peruse this blog entry.

Update (2007-10-25): It’s over two years since I wrote this, and I’m pretty sure I can do a much better job of it. I think I’ll hack on the code and post something up tomorrow.

March 17, 2005 at 11:01PM The Slow Creeping of Totalitarianism

So naïve and otherworldly was the great logician that Einstein felt obliged to help look after the practical aspects of his life. One much retailed story concerns Gödel’s decision after the war to become an American citizen. The character witnesses at his hearing were to be Einstein and Oskar Morgenstern, one of the founders of game theory. Gödel took the matter of citizenship with great solemnity, preparing for the exam by making a close study of the United States Constitution. On the eve of the hearing, he called Morgenstern in an agitated state, saying he had found an “inconsistency” in the Constitution, one that could allow a dictatorship to arise. Morgenstern was amused, but he realized that Gödel was serious and urged him not to mention it to the judge, fearing that it would jeopardize Gödel’s citizenship bid. On the short drive to Trenton the next day, with Morgenstern serving as chauffeur, Einstein tried to distract Gödel with jokes. When they arrived at the courthouse, the judge was impressed by Gödel’s eminent witnesses, and he invited the trio into his chambers. After some small talk, he said to Gödel, “Up to now you have held German citizenship.”

No, Gödel corrected, Austrian.

“In any case, it was under an evil dictatorship,” the judge continued. “Fortunately that’s not possible in America.”

“On the contrary, I can prove it is possible!” Gödel exclaimed, and he began describing the constitutional loophole he had descried. But the judge told the examinee that “he needn’t go into that,” and Einstein and Morgenstern succeeded in quieting him down. A few months later, Gödel took his oath of citizenship.

Gödel may have been half mad, but that is not to say he was wrong.

March 24, 2005 at 10:22PM Why do people still use GreyMatter?

This really puzzles me. I’ve came across a few sites, sites still being updated, that run GreyMatter. Now, I’ve nothing against Noah Grey: I used to read his weblog and he always came across to me as a good and decent human being, and a fine photographer. But that doesn’t stop me from wondering why in the name of all that’s good and holy people are still using the blogging code he wrote.

GreyMatter has a lot of problems. And I do mean a lot. It’s full of redundancies, global variables (and oddly named ones too, such as FUNNYFEETSCRATCH: wtf?!), the gm-library.cgi file alone is about 600kB, at least eight to ten times bigger than it should be considering what the program does, &c. The codebase just just one giant WTF. Now, this would be fine except for the fact that so many people ended up using it in the earlier days of blogging. This is not a good thing.

So, is there any equivalent of the project to replace the Matt’s Scripting Archive scripts with something written properly for GreyMatter? Not that I can see. In fact, there appears to have been an update to the existing codebase recently, but no effort to refactor it into some kind of shape, and it doesn’t even use CGI.pm! Though, in fairness, at least the guys working with it now agree.

It’s enough to make a man rewrite the thing from scratch, I tell you!