I'm Aza Raskin @azaaza. I make shiny things. I simplify.

I am the cofounder of Massive Health.

 

A New Way of Writing Ubiquity Commands: Feedback Needed

In Mozilla Labs, one of our mantras when creating news was to write browser functionality is the “five minute rule”. If we can’t write a “hello world” example in five minutes — to get to that gratification of seeing the results of your work — then we’re probably on the wrong path.

Ubiquity passes with flying colors. Writing a hello world command can be done in under a minute. But only for a certain types of commands — as soon as they start requiring a lot of presentation, they become a bit unwieldy. In fact, we haven’t really updated the “map” command because its complexity sort of scares us.

We’ve been working on a new way of writing Ubiquity features which has three major advantages:

(1) It’s much more “webby”.
(2) It’s much easier to debug.
(3) It’s secure.

The goal of this blog post isn’t to announce what we’ve got, but rather to get feedback. We need your feedback before we make it a standard part of Ubiquity.

How it looks

By the end of this “tutorial” we’ll recreate most of the map command. The hard work for the map command is in creating the preview, so we’ll leave that for last.

Here’s the code the defines the command “new-map”. It looks remarkably like the old way of defining a command, but now it’s done inside a something that looks like a webpage. This lets you include complex HTML without the gross anti-pattern of building HTML with Javascript string concatenation.

<html>
<script src="ubiquity.js"></script>
<script>
Ubiquity.defineVerb({
  name: "new-map",
  takes: "address",
  previewUrl: "map-preview.html",
  execute: function(address) {
    window.open("http://maps.google.com/?q=" + address.text);
  }
});
</script>
</html>

There are two fancy things going on here.

The first is the inclusion of ubiquity.js. This is the shim that implements all of the low-level talk between the web-page style command and the Ubiquity extension (which is implemented using the secure event passing model). The cool thing here is that we can mock out ubiquity.js, so that any normal web page can also be a host to Ubiquity commands without requiring an extension (Bespin, anyone?). Notice that we can just use the webby window.open, instead of learning a new API like was required for the current way of writing a Ubiquity command.

The second fancy thing is that the preview is being handled by the external file “map-preview.html”. Let’s dive into that:

<html>
<head>
  <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false"type="text/javascript"></script>
  <script type="text/javascript">
    function initialize() {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas"));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        geocoder = new GClientGeocoder();
      }
    }

    // addAddressToMap() is called when the geocoder returns an
    // answer.  It adds a marker to the map with an open info window
    // showing the nicely formatted version of the address and the country code.
    function addAddressToMap(response) {
      map.clearOverlays();
      if (!response || response.Status.code != 200) {
        // Do nothing
      } else {
         place = response.Placemark[0];
         point = new GLatLng(place.Point.coordinates[1],
                             place.Point.coordinates[0]);
         marker = new GMarker(point);
         map.setCenter(point, 13);
         map.addOverlay(marker);
      }
    }

    </script>

    <style>
      body{ width: 500px; height: 500px; overflow: hidden; color: white;}
    </style>
</head>

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width: 460px; height: 400px"></div>
<script src="ubiquity.js"></script>
<script>
Ubiquity.registerPreview(
  function(cmdName, address) {
    geocoder.getLocations(address.html, addAddressToMap);
  });
</script>
</html>

It’s just a simple web page mostly taken from the Google Maps API documentation! In fact, you can run it exactly like a normal web page, debug it using Firebug, and bring in any 3rd party library you like. Because any privileged interaction happens through the Ubiquity object, which is locked down, there’s no worry about security leaks. It makes it a joy to write complex and secure previews.

The only other magic is the Ubiquity.registerPreview function, which is the glue between what the user has typed into Ubiquity and the preview updating. Instead of reloading the entire preview on every keystroke (as was done before), the preview can update itself incrementally.

If you have the latest beta of Ubiquity, you can try try out the command.

Questions

What do you like? What do you dislike? What kinds of things do you want to be able to more easily do in the current way of writing Ubiquity commands? What’s hard to do right now? What do you hate?

RT @azaaza A New Way of Writing Ubiquity Commands: Feedback Needed | Follow @azaaza on Twitter | All blog posts

Tags: ,

View all 30 comments


Unfortunately, Bespin doesn’t work like that. Only you can see the preview file, so we can’t test it using that link.

Now, I haven’t looked into how Ubiquity currently defines its commands, but I’m not sure I like the empty HTML file to do it. Could you explain why a simple JS file can’t work? Perhaps I’m missing something….


Great news and stuff! But…

Do we need pre14? Because it have been missing something…



Dao

I’m not sure mimicing window.open makes sense there. Looks more like alert, as it takes a string, although I suppose it’s async.



Rodrigo Messias

This is MUCH better then the old way.



Aza Raskin

@Dao Oops. That was me putting in the wrong sample code!
@Gordon: Also mea cupla. I’ve moved to hosting the sample code on my own server.



Zaki Manian

I find the ability to use firebug to debug your ubiquity script really appealing. It was very painful the old way.



Harry Wincup

I like where this is going…seems much easier than the current way.

I like the idea of creating a separate html file for your preview so you can make it look nice with ease.. but what’s the purpose of having the actual command as a html file too?

I’m not sure if this is what Gordon was talking about above. Can the actual command simply be a js file that can then be included on any html page in a project?

Also, how will this preview html react within various ubiquity skins …



RichB

Why does the second example have a but the first doesn’t? I can see the validity from a tag soup perspective, but is that the proper way to do it?



RichB

The missing word in the previous paragraph is ‘<head>’


Aza, 3 questions:

as part of what domain would the preview page run? Would a script running on that page be able to execute HTTP request on any URL?

How would you share JS code between JS logic embedded in the preview page and JS code embedded into the execute function?

If the preview page needs to listen to updates from the command and refresh itself, it would still need to have some dynamic templating to refresh its HTML representation. No?


I dislike the fact that it still looks like code.

Perhaps it’s a much bigger project to make development just as user-friendly as what you’re developing for, but it’s something you should keep in mind. If the code for a Ubiquity command cannot, in theory, be generated by a hypothetical WYSIWYG graphical command editor, then the structure should probably be reconsidered.


“any normal web page can also be a host to Ubiquity commands without requiring an extension”?

Does this mean that Ubiquity in this format would also work on other browsers? I’m thinking of WebKit derivatives, I would love to have Ubiquity in Adobe AIR.



Chris

Doesn’t this turn Ubiquity into a better way of implementing generic Firefox extensions? Which is sorely needed, IMHO. All you need to add is a javascript API into browser features, similar to FUEL perhaps.



waqas

I like the new way much better, for the reasons you stated. Thanks for all the great work.

I do wish Ubiquity allowed me to preview command information, and allowed me to try them *before* I subscribe to a feed.

Thinking along those lines, Ubiquity could allow web authors to extend their pages with Ubiquity. This being the same as subscribing to feeds, but working automatically, and only on those pages. Kind of like greasemonkey scripts, but with focus on context sensitive commands and previews.



Nippotam

When will we have ubiquity on other platforms (ie8, Chrome, Safari, Opera…) ?

thanks in advance


whenever I try to use new-map I get a dialog that says:

“The Google Maps API key used on this web site was registered for a different web site. You can generate a new key for this web site at http://code.google.com/apis/maps/.



Tim

Why is the command an HTML page with JS on it instead of a simple JS file like it is currently? Why have the preview code happen on a separate page? You can still have the preview defined in the same place as the rest of the command, right?
“What kinds of things do you want to be able to more easily do in the current way of writing Ubiquity commands?”
Creating a simple search command is too complex for how simple it ought to be. Some easy command and/or option in the context menu to create a command to search that box should be there. It should automatically fill in the favicon, have a simple preview/description (just telling you what it does), and of course when executed search that field. For an example of what a simple one could look like (could be minus the author info if desired), see the sc2pod-wiki in my link below. It might have to ask the user for some info like the title of the site with capitalization.
“What’s hard to do right now?”
I think that getting info from a web page and doing what you want with it is too complex. For example, see the preview and execution of the tniv-bible command at this URL: (I made all the commands there)
http://gist.github.com/47422
Surely there could be an easier way than the long jQuery.ajax command and confusing “something.substr”, “startBlock”, and “endBlock” things.



Radu

Aza – you have mentioned that one can debug Ubiquity scripts. That would be so helpful to me – bu I still have not been able to use it in my case below. Can you provide a more descriptive sequence of steps on debugging Ubiquity.

I am new to Ubiquity and having a difficult time with a simple task – ajax get xml from the same domain. It works fine using html + jquery, but it fails in ubiiquity … :( The only thing I am able to do is to displayMessage inside the error: method.

TIA,
Radu


@Radu: Your problem is exactly the kind of thing that the web page feeds will make much, much easier. Basically, if you can do something in a web page, it’ll be super easy to include in a command, because turning a web page into a command feed will just be a matter of including another JS file and calling a few functions to talk to Ubiquity. Help is on the way!


Here is my feed. I really like this idea. Trying to see if we can push this idea further: http://blog.feedly.com/2009/03/04/ubiquity-commands-as-html-pages-response-to-aza/



nka

Using Minefield 3.2alpre and can’t get some ubiquity cmds to work properly. When I type email to and type the name of someone in my Gmail contacts list it doesn’t appear to be finding my contacts. For example Email this to chris, and I do have a contact named chris in my contacts, produces no results.

In the email command after selecting a portion of the webpage and typing email to xyz@gmail.com ubiquity launches a new compose window but doesn’t paste in the content that I selected. It pastes in a link to the page where the contact that I selected is located. Furthermore, it didn’t insert xyz@gmail.com into the to field.

Lastly using the map cmd and clicking on insert this, doesn’t insert the map into the gmail compose window that I have open. Instead, it inserted the address that I asked ubiquity to map.

Why aren’t these commands working like they are supposed to?



nka

After posting I highlighted my own post and accessed ubiquity using this cmd: email this to xyz@gmail.com. Ubiquity launched a compose window and inserted this into the subject: ‘Aza’s Thoughts » A New Way of Writing Ubiquity Commands: Feedback Needed’ and this into the body: From the page Aza’s Thoughts » A New Way of Writing Ubiquity Commands: Feedback Needed:

Why is this happening? Please email me if you have any ideas, thanks!


Now, I haven’t looked into how Ubiquity currently defines its commands, but I’m not sure I like the empty HTML file to do it. Could you explain why a simple JS file can’t work? Perhaps I’m missing something….


Why is this happening? Please email me if you have any ideas, thanks!



Sex

Unfortunately, Bespin doesn’t work like that. Only you can see the preview file, so we can’t test it using that link.


In Mozilla Labs, one of our mantras when creating news was to write browser functionality is the “five minute rule”. If we can’t write a “hello world” example in five minutes — to get to that gratification of seeing the results of your work — then we’re probably on the wrong path.


It should automatically fill in the favicon, have a simple preview/description (just telling you what it does), and of course when executed search that field. For an example of what a simple one could look like (could be minus the author info if desired), see the sc2pod-wiki in my link below. It might have to ask the user for some info like the title of the site with capitalization.


I wanted to post you that little word in order to say thank you as before for those remarkable tricks you’ve featured on this site. It is surprisingly open-handed with you to convey openly what some people could have marketed as an e book to help with making some money on their own, especially since you could possibly have done it if you decided. These guidelines as well served as the fantastic way to realize that other people online have a similar keenness like my personal own to find out a little more around this condition. I am sure there are thousands of more pleasurable situations in the future for many who view your blog post.


I would like to thnkx for the efforts you’ve put in writing this web site. I’m hoping the same high-grade site post from you in the upcoming as well. In fact your creative writing skills has inspired me to get my own web site now. Actually the blogging is spreading its wings fast. Your write up is a good example of it.


Leave a Comment