Creating a Microformat Action User Script (Advanced)

We've already discussed creating a microformat action user script for Operator. Let's discuss some more advanced techniques.

We're going to cover three topics: creating an action that works on all microformats in a page, dynamically changing the name of an action and updating existing installed actions to support new microformats.

Creating an action for all microformats on a page

Similar to the "doAction" function we talked about earlier, there is a "doActionAll" function that you can implement in your action:


doActionAll: function(semanticArrays, semanticObjectType)
{
...
}

Let's talk about semanticObjectType first since this might be a little confusing. There are two ways that your action can be invoked based on how Operator is being used. If the user is in the "data types" view, the action will only happen on a particular microformat type. If this is the case, semanticObjectType will be set to that microformat. If Operator is in the "actions" view, then semanticObjectType will be empty. The reason this happens is because in the "actions" view, the action might be acting on more than one semanticObjectType. For instance, the "Google Maps" action acts on both the adr microformat and the geo microformat.

In practice, the semanticObjectType will probably never be used, because most actions (especially "all" actions) are associated with one microformat. So in your action, you'll probably just hard code the microformat you are handling.

The semanticArrays parameter contains arrays that represent ALL microformats in the document. You only need to be concerned with the microformat you are handling. So for instance, if you want to handle all the geos on a page, you can get them by accessing:

semanticArrays['geo'];

This will be an array of all the geo objects in the document, and they can be handled individually as semantic objects.

To add a description for your "all action," just add a new parameter "descriptionAll" to the structure at the top.

Note that semantic scope is used to determine when your "all action" is displayed.

Customizing the action name on the fly

When we first talked about creating actions, we indicated that there was a parameter called "propertyIndex" that was passed to doAction. This indicated what instance of a particular object was being passed to that action. This creates a problem. If we have an hCard, for instance, that has five URLs, wouldn't there simply be five actions that say "Open URL?" How do we differentiate between the different URLs? The answer is the getActionName function.


getActionName: function(semanticObject, semanticObjectType, propertyIndex) {
...
}

The getActionName function allows us to change the name of our action based on the current object we are working with. So for instance, we could change the name of an "Open URL" action to contain the web address in parentheses. We can also use the getActionName function to cause an action not to display at all. For instance, if we wanted to create an action that worked with AOL instance messenger, it could check URLs to see if they contain the aim protocol, and if not, don't display them. This can be accomplished by simply returning undefined when asked for an action name. Note that if you return an empty string, we display the "default."

If you want to see this in action, check out the "Go to web page" action.

Incidentally, this function is called for every action, so you can experiment with using it to have actions that display based on other criteria than what is specified in semantic scope.

Attaching to existing actions

Sometimes there is already an action that already does what you want, but you want to add additional function to it or you might have created a new microformat and want to attach it to an existing action. For example, the hResume microformat adds itself to the "Bookmark with Firefox" action as well as the "Search Google" and "Search Yahoo!" actions. Let's take a look at how to do that. If we look at hResume.js, we'll see this code at the end:


var hresume_firefox_bookmark = {
scope: { semantic: { "hResume" : "hResume", } } }; var hresume_google_search = { scope: { semantic: { "hResume" : "contact.fn" } } }; var hresume_yahoo_search = { scope: { semantic: { "hResume" : "contact.fn" } } }; SemanticActions.add("firefox_bookmark", hresume_firefox_bookmark); SemanticActions.add("google_search", hresume_google_search); SemanticActions.add("yahoo_search", hresume_yahoo_search);

What you'll notice here is that all we've done is created objects that define additional semantic scope and then we attach those objects to existing actions. Because those actions use the data in semantic scope to decide what to act on, this is all that is required.

In some cases, you'll actually need to create a new doAction function that handles your new microformat. We actually chain doAction calls together, so all you need to do in your doAction is check for your new microformat as the semanticObjecType, and if it is there, handle it and return true to indicate that you have handled it. Otherwise return false.

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 “Creating a Microformat Action User Script (Advanced)

  1. would be really nice if you could provide or point me to a list of all available (existing) Semanticaction objects...
    a quick pointer using the existing del.icio.us bookmarking actions, etc...