Microformats and Firefox 3 (for Developers)

So let's talk about what Firefox 3 will hopefully offer for developers. The goal is that extension authors will have an API to access microformatted data directly without worrying about parsing. In addition, there will be a model for adding additional microformats, as well as adding semantic actions (more about that in a minute). Here's what the API looks like right now.

Any microformat can be instantiated from a DOM Node:

var hcard = new hCard(DOMNode);

Once the microformat has been instantiated, members can be accessed directly, like hcard.fn. If the property is defined as an array in the microformat specification, it is an array in the newly created object. A pointer to the original DOM node is also stored in this object if you want to do anything to the microformat node on the glass.

Microformat objects can be queried from a document:

var hCards = Microformats.get(document, "hCard");

I need a better name for this one I think. Given a document and a microformat type, this API returns an array of objects that represent each microformat in the document. I'm not sure if this should go through all the child frames and return every microformat in every sub document. I have to think about that.

If you have DOM Nodes, you might need some information about them. The scenario here is what if you have a DOM Node and you don't know if it is a microformat or not? What APIs could help you?

Microformats.isMicroformat(DOMNode)

This function tells you if the specific DOM Node you passed in is a microformat. It returns a boolean.

Microformats.getParentMicroformatNode(DOMNode)

This function gets the first microformat that is a parent of this node. If you pass in a microformat, it still gets the parent. This is important for finding nested microformats.

Microformats.getMicroformatNamesFromNode(DOMNode)

This function returns an array of the microformat types that this node represent.

So here's how you might use those three functions, for instance when a context menu is displayed on a given node:

  if (Microformat.isMicroformatNode(node)) {
    mfNode = node;
  } else {
    mfNode = Microformats.getParentMicroformatNode(node);
  }
  while (mfNode) {
    var mfNames = Microformats.getMicroformatNamesFromNode(mfNode);
    /* enumerate through names and do something */
    mfNode = Microformats.getParentMicroformatNode(mfNode);
  }

I mentioned semantic actions earlier. I'm still working on how I can create an action model that is easily extensible. In an earlier post, I suggested that actions be implemented like this:

semanticActions.actions.youtube_search_tags = {
  description: "Find videos on YouTube",
  icon: "http://youtube.com/favicon.ico",
  scope: {
    semantic: {
      "tag" : "tag"
    }
  },
  doAction: function(semanticObject, semanticObjectType) {
    if (semanticObject.tag) {
      return("http://youtube.com/results?search_query=" + encodeURIComponent(semanticObject.tag));
    }
  }
};

I'm now trying to decide if I should use a function method, something like:

semanticActions.addAction("youtube_search_tags", youtube_object);

There will be much more on that later.

Anyway, I'm primarily looking for feedback from people. Are these APIs sufficient? Did I miss something obvious? Thanks for the input.

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 *

5 thoughts on “Microformats and Firefox 3 (for Developers)

  1. I would say yes.

    The difference for you in setting up the JS is negligible, especially if you've already "staked out" the Microformats "package" for defining other functions. Furthermore, I don't think it makes the API any harder to understand, so even if the benefit is mostly theoretical, that seems like reason enough to do it.

    After all, someone out there must have written some custom uF handling javascript already that includes an "hCard" object. Doing this avoids breaking their existing work.

    Similarly, I do suspect that you should implement the action handlers using function objects and an "interface" (not a concept frequently uttered around JavaScript, but you can design it that way). You could probably even simplify the "signature" so that you just pass in an object without specifying what actions it takes.

    That is, instead of
    semanticActions.addAction("youtube_search_tags", youtube_object);
    you would just have
    semanticActions.addAction(youtube_object);

    And then one of the methods on the object would be
    function canHandleSemanticAction(str);

    btw, I don't have any great ideas at the moment, but I'm not too keen on the use of "semantic". Maybe something like Microformats.registerHandler(obj)

    When would these actions be invoked? Is the idea that after the page loads, the browser then finds all the uF nodes and tells each action about it? What about an AJAX-y page that may "load" new uF nodes later?