Microformat Objects in JavaScript

Unfortunately for everyone out there, when I discover new things in JavaScript, it means I rewrite some parts of Operator, and I am in the middle of that right now. The thing that I discovered is the ability to have custom getters for objects in JavaScript.

One of the things I have wrestled with in the past is that my current model for accessing a microformat in JavaScript is clunky. You have two choices – you can either create the microformat in its entirety:

var hcard = createMicroformat(node, "hCard");

and access the properties like this:

alert(hcard.fn);
alert(hcard.adr.region);

or you can access an individual property like this:

var fn = getMicroformatProperty(node, "hCard", "fn");

The problem with the first approach is that you do a lot of work if you only want part of the microformat, and the problem with the second approach is that there is no caching of the data.

Enter custom getters:

var hcard = new hCard(node);
alert(hcard.fn);

and hcard.fn is not queried until you access it the first time and it is cached.

What I do now is that when the hCard is instantiated, I set the getter for each property to be a function that queries the property and then sets it (getMicroformatPropertyGenerator):

object.__defineGetter__(property, ufJSParser.getMicroformatPropertyGenerator(node, microformat, property, object));

getMicroformatPropertyGenerator looks like this:

getMicroformatPropertyGenerator: function(node, name, property, microformat)
  return function() {
    var result = ufJSParser.getMicroformatProperty(node, name, property);
    if (result) {
      microformat.__defineGetter__(property, function() {return result});
      return result;
    }
  };
}

The result allows for much cleaner code in an action, because the actions are now going to receive the microformat data object directly so they don’t have to worry about DOM nodes and things like that. All an action has to do is access the individual properties. This will also allow for actions that aren’t so dependent on microformats.

I’ll still keep the old way around if people want to use the microformat parser in web pages. If anyone knows of a cross browser way to do what I am doing, or even a better way to do it, please let me know.

Please note: I reserve the right to delete comments that are offensive or off-topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

4 thoughts on “Microformat Objects in JavaScript

  1. If you don’t want the getter to be live but rather to just be a lazy-construct mechanism, as you demonstrate here, you don’t need the new getter — just remove the old one using delete and use the normal property mechanism:

    getMicroformatPropertyGenerator: function(node, name, property, microformat)
    return function() {
    var result = ufJSParser.getMicroformatProperty(node, name, property);
    if (result) {
    delete microformat[property]; // removes getter
    return microformat[property] = result;
    }
    };
    }

  2. Jeff:

    sweet. That’s even cooler. Here’s what I ended up with:

    getMicroformatPropertyGenerator: function(node, name, property, microformat)
    {
     return function() {
      var result = ufJSParser.getMicroformatProperty(node, name, property);
      delete microformat[property];
      if (result) {
       microformat[property] = result;
       return result;
      }
     };
    },