Seeking Ubiquity

By Kurt Cagle
September 9, 2008 | Comments: 1

The command line is perhaps the most fundamental of all user interfaces - at a terminal, a prompt character appears that you can type in a command with zero or more arguments, then press the Return key to evaluate that command. As an interface it has some serious limitations - there are typically few indications about what specifically can be typed into that interface, or the action that will ensue once you do enter the line, but for programmers in particular, the command line is also the foundation on which every other user interface ultimately rests.

The web of course has its own command-line: the navigator control where you type in your URL. By using query string parameters, it is even possible to invoke a passable "web application" that's not that dissimilar from a typical Unix, Linux, Apple or Windows command line - indeed, much of the development in web services over the last decade has ultimately been devoted to the creation of exactly such as "command-line", along with the associated pipes and messaging structures that make for the more complex applications.

However, suppose that your goal was not to communicate with the web, but rather to communicate with the browser. This is subtly different, but in some respects an even more profound task. Most web browsers in this day and age are effectively either extensions of the underlying operating system (such as Internet Explorer) or are themselves "virtual machine" operating systems that provide graphical, multimedia, messaging, security, communications, persistence and system services for the activities within the browser. The idea of a command line that can communicate directly with that operating system, invoking (and more importantly defining) appropriate commands for such as browser operating system, makes perfect sense, though until recently, such an idea existed (in very rough form) only in applications such as GreaseMonkey.


Ubiquity, the open source add-on currently in alpha and being produced by the Mozilla team for Firefox, is intended to make such a command line possible. The idea behind ubiquity is to take advantage of both the internal storage capability and online communications in order to let users both create local "scripts" written in JavaScript that can be invoked to perform certain actions and to create a centralized (and vetted) library of such scripts online that people can load to accomplish nearly any task.

book coverbook coverbook cover
For a complete list of JavaScript books, visit the
JavasScript topic page in the O'Reilly Store.

Once the Ubiquity add-on is loaded from https://wiki.mozilla.org/Labs/Ubiquity , pressing Ctrl-Space will bring up a "terminal" in the upper-left-hand corner of the browser. This terminal will let you type in a command that is then interpreted by the Ubiquity engine. If the results of this command involve jumping to a different page, then the current tab window will jump to that page. Otherwise, it will display the results of the operation in a pop-up window (using the same notification that's used to indicate completed downloads and available plugins, in the lower-right portion of the browser page).

At an absolute minimum, this can be used to reduce the need to use a mouse. For instance, suppose that you wanted to perform a search on Google News for "mozilla ubiquity". You can open up the command window, then type in "google-news mozilla ubiquity". Even before pressing enter, a preview of several articles about ubiquity will show up in a summary drop-down in the command window. You can either click on one of these or press return to pull up the Google News page for this entry.

Suppose that instead I wanted to know the current weather conditions locally. By typing in weather Victoria, BC the preview window will show me the current temperature and weather condition (a balmy 17° C and clear). Instead, if you wanted to find the definition of the word "ubiquity", you'd type in the command define ubiquity, which will drop down a preview in the form:

ubiquity n : the state of being everywhere at once (or seeming to be everywhere at once)

There are a couple of dozen such terms defined as part of the "core" ubiquity package, including searches of Wikipedia, Google, Yahoo, eBay and others, commands to add to (Google) calendar entries or list those that are currently available, a basic calculator, a twitter command and more. Other commands can work upon selected text within a web page, such as a word-count mechanism, highlighter, translator, syntax highlighting of code (very cool if you're editing a blog account), tinyURL generator and more. Finally, a few commands even let you set the edit flag of the current document on or off, making it possible for you to go to a certain section, switch to edit mode, change content within that section, then save the changes as an annotation.

These capabilities by themselves are intriguing, and can dramatically reduce the amount of typing and browsing that you have to do, but these are all just part of the built-in script library. The idea behind Ubiquity is that it is a command line interface for building potentially sophisticated applications - just as with add-ins, you can load in Ubiquity scripts by going to such places as The Herd (https://labs.toolness.com/ubiquity-herd/all-feeds/), which provides a place for (vetted) third party Ubiquity scripts.

Ultimately the intent is to provide a mechanism akin to the download button for Add-ins, though in my experiences, the feeds to enable this worked about half of the time (probably due to the rapid developmental changes to the core application). For instance, one of the applications available from within the Herd was the forecast script, which, when given a city and state (or province) will provide the seven day weather outlook for that particular city.

When you go to the Forecast page, a permissions banner with a button will appear asking whether you wish to download the script (the banner is essentially identical to that used by Add-ins). Once you indicate your assent, Ubiquity shows you a second review page that displays the JavaScript before letting you complete the submission process. If you choose to accept the script, then it will automatically load in - unlike add-ins, you do not need to restart the browser in order to run the application. Once loaded, the forecast script is available for use in the command line,

While not yet implemented, it is likely that a future version of ubiquity will provide ways of binding such scripts to tab-bar buttons and menus, possibly with dialogs making it possible to pass parameters into the scripts themselves - meaning that ubiquity has the potential to significantly simplify the development of "extensions" to the Mozilla browser (more about this point later in this article). At this stage, you can access Ubiquity commands via the context menu on a web page, typically when you have created a selection on the page to indicate what the particular command is supposed to work on.

Creating Ubiquity Scripts

One of the most intriguing aspects of Ubiquity is that you can not only invoke previously defined functions, you can also write your own using JavaScript through a simple "command-editor" chrome page (one of several such pages in the Ubiquity control center, a set of chrome generated pages).

For instance, my youngest daughter is crazy about playing Sims, and has become (somewhat alarmingly) proficient in speaking Simlish, an artificial language created specifically so that the Sim characters could have conversations with one another without the need to actually have these conversations have any actual meaning (and thus avoid repetitiveness). Grant Harding of MIT wrote a Lorem Ipsum generator as part of the Herd scripts (see below) that created random strings from pseudo-Latin text, useful for Greeking content for page layout.

Taking that idea, I expanded upon it, using the Sims "Dictionary" on the Sims 2 site (Tiny URL of http://tinyurl.com/6dk7lu) to create a Simlish command that will generate paragraphs of Simlish. Opening up the editor at chrome://ubiquity/content/editor.html (this is live only if you have Ubiquity installs), I copied the Lorem script and modified it to create the Simlish script:

CmdUtils.CreateCommand({
        name: "simlish",
        homepage: "http://grantrules.com/ubiquity/lorem.html",
        author: { name: "Kurt Cagle", email: "kurt@oreilly.com"},
        contributors: ["Grant Harding","Kurt Cagle"],
        license: "MIT",
        description: "Insert some Simlish filler text, based on the Grant Harding Lorem Ipsum generator",
        help: "Inserts simlish filler text",
        takes: {"number of words": noun_arb_text},
        
//      preview: "Generate simlish filler text",
        preview: function (pb, floop) {
                var res = this._simlish(floop);
                pb.innerHTML = res;
        },


        execute: function(floop) {
                var res = this._simlish(floop);
                CmdUtils.setSelection(res);
        },

        _simlish: function(floop) {
                var _uc = function(str) { return str.substr(0,1).toUpperCase() + str.substr(1,str.length); }
                var num = parseInt(floop.text, 10);
                if (num == 'NaN') { num = 15;}
                var str;
                var words = ['ahhhh','molombia','arriba','chandler','ah','van','vesua','cummuns','nala','abbi anar','araganda','ah fweegah fwaa','awoba','awasa poa','atohteh','bum bum','bloo bagoo','balinda macoy','boo pna','baba','boobasnot','cuh teek a loo','cayoo','coman schnala','chum cha','deepwa spanewash deepla blah','degg degg','dustin aey ball','dis wompf','es fredesche','elicanto','fleny fleny','frabbit','fuzzy buckles','flart','flort','flarn','fro','goo scavony','go spogando','grin','iguoanas','fluing','indie skie','geelfrob','garnar frash','grouw','harva sol labaga','alon wid hava','so lawnumg','hotty baba','alon','wid','hotty ba','huree','hallo hallo','hora','hurdy furdy sarl','de-baggy','yesh','hooba noobie','jowlenin','jamoo','kooj','kashooti','le la la cula','lickenarf','mogey mogey mogey','menukonya',' malenka',' mychuno','nicloske','ga','gloope','nockanova','bunadda','nooboo','nash-na-poof','nuk nuk','nib','nurfver','oh moratic','oo krem letich','ooh shaboo','ooo shanga day','o mee pooba','ole like emjoel','ooh tashuconana','o vwa vwaf', 'sna','paba','plicka','robalubi','khan', 'radashay', 'ravasheen','stoonce','sisaroom','seflia way','sheb sheb abfladaah','shoo flee','shoota tooda',' fableeen','shoobatidaa','toodit','soy llaman','soodle soodle','shoandish geegway','tag tag','uh-uh','ummmm naeum','uh',' licht nar','veena fredishay','wing zing dog','whoo hoo','wing ding sessel','wee bow','wetash','wich ta ribbit',' yucky','heroosh lika toh','da deee','tacola tavoba', 'pucchi','kashalamibow','vla donn','krach','lamoo','lakajo','tuben','kachee','yakon talafun', 'pregenta','shabadoo','yakatuba','noobie','ranuti','racho','ya micko', 'krafuncha', 'yatoo', 'kracho','hrowla','toop la','kunachu','da kuda','now schkluskla','vach','shabada'];
                var wrds = [];
                if (num < 0) { wrds = wrds.splice(0,num); }
                var uc = false;
                var t = false;
                for (var i = 0; i < num; i++) {
                        wrds.push((uc && !(uc = false) ? _uc(words[Math.floor(Math.random()*words.length)]) : words[Math.floor(Math.random()*words.length)]) + (Math.floor(Math.random()*15) == 1 && i+1 != num ? (Math.floor(Math.random()*2) == 1 ? ',' : (uc = true ? '.<br/>' : '')) : ''));
                }
                var phrase = wrds.join(' ') + '.';
                var phrase = phrase.substr(0,1).toUpperCase()+phrase.substr(1,phrase.length);
                return phrase;
        },
});

The preview function generates the content that you will see in the preview drop-down part of the Ubiquity command line when you type in simlish N where N is the number of words to use in the sample. The execute function, on the other hand, will replace a selection in a web page (regardless of whether that web page is read only or read-write, with the Simlish text. The primary assumption is that the selected content is likely in an editable region (such as a text area block) but this doesn't have to be the case.

One thing to note here is that this makes fairly extensive use of the notion of internal methods and JSON-type objects. Ultimately, all of the scripts defined within Ubiquity share the same address space, so keeping methods local to the command generators is definitely a good design decision.

More complex scripts are the rule rather than the exception, especially since it is possible to build scripts that will automatically be invoked when a document is loaded rather than from a command line interface, as well as scripts that can be invoked via callbacks. Most significantly, these commands are performed in the underlying XUL context rather than the web page context, meaning that at least some (and perhaps most) of the underlying XUL functionality - including communication with the XML libraries, image processing routines, dialogs and access to the SQLLite data-store - are all done within a privileged context. While this opens up all kinds of things that can't necessarily be done in a web page, it also means that ultimately the Ubiquity layer is going to need some serious secure sandboxing.

Implications

Ubiquity is about to create a whole new class of extensions to Firefox. A typical XPI add-on usually consists of a package consisting of one or more XUL layouts, CSS pages, JavaScript pages and XBL documents, along with image or similar resources. In the case of Ubiquity, however, what you have instead is considerably lighter weight, consisting primarily of the script itself. However, this actually describes a use-case for a number of scenarios where full add-ins are overkill.

If resources are already available on the web, it makes comparatively little sense to load them internally to an XPI (except for speed of access). Moreover, Ubiquity scripts have few reasons to access XUL resources - they can emulate them quite effectively with XHTML and SVG if necessary, as the explosion of AJAX "widgets" has proven repeatedly.

Additionally, given the sometimes arduous cycle of development necessary to build and test an XPI, especially for a reasonably complex add-in, the introduction of Ubiquity scripts is something of a god-send. With an XPI, you generally have to make changes to scripts, stylesheets, and structural elements, zip these, upload them, download the XPI (perhaps after clearing a cache and restarting Firefox), and test it out. With an Ubiquity script, you can modify the script (and not even bother about saving it, as the Ubiquity component saves the scripts automatically) and open the prompt to test it right then - this means that debugging and development can occur very, very quickly.

For all that, it would also be a mistake to look upon Ubiquity as simply another mechanism for building Firefox extensions. When you create an ubiquity script, you are essentially adding a new command to the Ubiquity language, just as you would with most other computer languages. Thus means that you can create an ubiquity script that performs a certain task (such as filling a web page with generated test data), then can create another script command that repeatedly calls the first in order to build unit testing for web applications.

This has an interesting implication for document management as well. Because it is possible to set up a command so that it is invoked on document load rather than needing to be specifically invoked from the command line, you can write document filters that will parse an incoming document and modify it in some way. For instance, (in an example Jeni Tennison pointed out here at O'Reilly), an Ubiquity script could parse a document for RDFa tags and generate both links from and highlight the corresponding tags as pop-ups.

In a more extreme example, downloading a DocBook document could trigger an Ubiquity script that would run an XSLT transformation on the document to convert it into HTML, either loading the transformations onto the client or posting the document to a web service via XMLHttpRequest to perform the necessary changes on the server, then rendering the output back to the browser.

Given that Ubiquity can also easily toggle the editable state of the browser, another possibility that opens up is the concept of completely transparent editing - the whole page is the editable plane, which means that one person can start up a wiki-like blank page and fill in content, saving upon leaving using XMLHttpRequest, a second person (possibly with a permission check) can then alter the content and add his or her two cents worth, and so forth.

Perhaps one of the most intriguing aspects of this is the position of Ubiquity as being a Mozilla project. If, as I suspect will happen, Mozilla decides to integrate Ubiquity into the browser in Firefox 3.1, this means that Ubiquity scripts will become ... well, ubiquitous. Greasemonkey (which is the obvious intellectual progenitor of Ubiquity) suffers from the fact that it is itself an add-on that must be downloaded, and as such the ability to build applications around Greasemonkey is sorely limited. A universal "command line", on the other hand, makes such applications not only fairly trivial but also insures that versioning within Ubiquity can provide appropriate fallbacks for outdated scripts.

All of these points should be raising alarm bells, however - because it's reasonably obvious that that downside to Ubiquity is the potential that it has for even inadvertent accidents, let-alone outright mischief. For instance, it takes comparatively little imagination to envision how you would write up script for zombifying other machines and then use them as a mechanism for denial of service attacks. The comparative freedom that such Ubiquity scripts offer for modifying web pages also make them perfect for phishing sites and the like.

Mozilla has, in general, been good at identifying security holes and ways that the browser can be misused, so given the scope and potential that this type of application has, I also suspect that they have someone on the Ubiquity team whose primary purpose is to hack it, in order to see where the vulnerabilities are, and I am hoping in the near term future to discuss this particular point with the team in depth.

I do have some doubts about the command model itself - as Ubiquity itself becomes more common, the number of terms in the Ubiquity herd namespace is going to reach a saturation point, and I think that the notion of working with either an OOP structure or a namespace mechanism (the former being more likely) is going to prove key. The ability to make a call like google:mail vs. yahoo:mail makes some sense to me, (or perhaps the standardization of the using keyword - mail this using google to kurt@oreilly.com, for instance, could provide a convenient way to differentiate between Gmail and Yahoo Mail, while still allowing the mail keyword its full rein.

My suspicion as well is that if Ubiquity turns into the level of success that I think it might, its something that the other browser vendors may very well examine as well. At this stage its perhaps too much to hope for an ubiquitous standard for command line interfaces, though interestingly enough what it does do is highlight the fact that the idea of browser as platform is becoming increasingly viable - you will end up seeing the IE platform, the WebKit platform (Safari, Chrome, Konqueror, et al.), the Mozilla platform (Firefox, Flock, Songbird, etc.), the Opera platform, the Flash platform and so on. With the exception of IE, these all work on all of the primary desktops (and all are increasingly working on mobile platforms), to the extent that, especially for consumer facing applications, the notion that you design your applications to work on the web first becomes a hard one to turn down.

There are certain aspects of Ubiquity that need to be worked out - namespaces, security, user interface and the like being some of them - but the concept itself is intriguing and already useful. I'm especially intrigued to see what happens when you marry Ubiquity to the hyper-charged trace tree parsing improvements that will be part and parcel of Firefox 3.1.

Yet overall, Ubiquity is a logical move for Mozilla, and I suspect it will be a game-changer, the next step to making the browser as platform a reality. What's up on the Herd already is intriguing, though for the most part still tied into Ubiquity as a convenient "shorthand" mechanism for navigation, as is typical of brand new apps. Longer term, Ubiquity will likely end up creating a whole new class of applications that are unlike anything we've seen to date. Should make for an interesting salvo on Browser Wars II.

Kurt Cagle is Online Editor for O'Reilly Media, focusing on XML and Web Development. You can subscribe (via Atom) to his most recent posts here. He lives in Victoria, British Columbia, and spends entirely too much time drinking lattes at Starbucks.


You might also be interested in:

1 Comment

Hey, hows it going? I'm attempting to surf the web and find a variety of Ubiquity coders. I'm noticing allot of people are sharing there scripts. If anyone would like to they are welcome to use our site at www.cipherhive.org . You can upload your javascript to folder and then put the link in a html block. That way when someone wants to install your script they can just view your page and opt to install it. We are fairly new so we are starting with what ever coders we can find to build the site up. Let me know what you think if you check it out. here is the Ubiquity tutorial...

http://www.cipherhive.org/course/view.php?id=19

Make sure to briefly review the Course Making Tutorial First just to learn how to add html blocks. It a no brainer and uses a simple gui.

http://www.cipherhive.org/course/view.php?id=11

V/r
Jason Mansfield

P.S. O'REILLY ROCKS!

News Topics

Recommended for You

Got a Question?