<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.mozilla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Endolith</id>
	<title>MozillaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mozilla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Endolith"/>
	<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/Special:Contributions/Endolith"/>
	<updated>2026-04-17T23:01:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.10</generator>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Firefox/Feature_Brainstorming:Form_handling_and_text_areas&amp;diff=213831</id>
		<title>Firefox/Feature Brainstorming:Form handling and text areas</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Firefox/Feature_Brainstorming:Form_handling_and_text_areas&amp;diff=213831"/>
		<updated>2010-04-06T21:33:25Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Automatically restore form with text values filled in if submit fails */ grrrrrrrrrrrrrrrr &amp;gt;:(&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FeatureBrainstorming}}&lt;br /&gt;
== Text input field navigation improvements  ==&lt;br /&gt;
&lt;br /&gt;
*Allow {TAB}-key navigating &#039;through input fields only&#039;. Pressing the {TAB}-key lets today&#039;s Firefox annoyingly jump to the next hyperlink (!) and option button (!), too, so that it often takes very long to select the next text input field (including the web adress bar and search bar). Hyperlinks and option buttons etc. can be used easier by mouseclicking, but input form fields could be selected faster by {TAB} and {SHIFT}-{TAB}. - [[User:Gutzndaifi|Gutzndaifi]] 09:14, 25 October 2007 (PDT) &lt;br /&gt;
*Maybe this can be integrated into an add-on like &#039;Highlight Focus&#039; by Rudolf Noe, located at [https://addons.mozilla.org/en-US/firefox/addon/1310] etc., but it would be much better to implement it &#039;as standard&#039;. - [[User:Gutzndaifi|Gutzndaifi]] 09:14, 25 October 2007 (PDT) &lt;br /&gt;
*On Firefox for the Mac, allow (TAB)-key navigating between other types of objects in a form. Currently, pressing TAB only navigates between text fields. Please add the ability to navigate to combo boxes, check boxes, radio buttons, buttons, etc. -JK 30 March, 2008 &lt;br /&gt;
*I love the idea of separate tab queues for forms, links, images, i dunno what else. Forms and links are the two biggies IMHO. This is the only feature the keeps Opera installed on my box. Please Please Please may we have it?&amp;amp;nbsp;:) -CD 23 May, 2008 &lt;br /&gt;
*Many pages will automatically place the text cursor in a particular text box only after a given percentage of the page has loaded (for example, Gmail places the cursor in the username field). However, one can manually begin information in whatever field before this occurs by clicking on that field. It is frustrating when, in the middle of typing something, the cursor is automatically relocated. Mozilla should include a feature whereby the manual placement of the cursor overrides the auto-placement.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Caution User when about to lose form data to the back button&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*When the back button is pressed (or backspace on the keyboard accidentaly pressed), and some form element on the page has been edited but not submitted, display a dialog telling the user they are about to lose what they typed. The dialog could of course have a checkbox marked do not show this message again.&lt;br /&gt;
&lt;br /&gt;
There is nothing more aggravating than losing a long post because you thought that a text field had focus. This way, &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Web Forms 2.0 implementation ==&lt;br /&gt;
* Allow using of the extended forms. See the standard made by whatwg, which is located at [http://www.whatwg.org/specs/web-forms/current-work]&lt;br /&gt;
* Opera browser partially supports it, you can see how useful it can be in FireFox&lt;br /&gt;
&lt;br /&gt;
== External editing of text boxes ==&lt;br /&gt;
* Allow an external editor (vim, emacs, textpad, etc) to edit text in form text boxes&lt;br /&gt;
* Currently supported by plug-ins, but only on some platforms; should be available everywhere&lt;br /&gt;
* Make it embedded in the place of the textarea, without opening another window.  Otherwise it would be cumbersome and confusing to keep track of.&lt;br /&gt;
* As more and more apps move towards web services, the ability to effectively edit large blocks of text (wikis, blogs, forums, webmail) becomes more and more critical.&lt;br /&gt;
* Include ability to save/restore the text box contents.&lt;br /&gt;
* Provide a key binding and also bind to right-click/Edit in text areas.&lt;br /&gt;
**No, this should be in the form of plugins because it isn&#039;t possible to make firefox recognize every text-editing program by default. --[[User:Armaetin|Armaetin]] 15:49, 13 February 2007 (PST)&lt;br /&gt;
; References&lt;br /&gt;
* [https://bugzilla.mozilla.org/show_bug.cgi?id=103767 bug 103767]&lt;br /&gt;
* [https://bugzilla.mozilla.org/show_bug.cgi?id=13474 bug 13474]&lt;br /&gt;
&lt;br /&gt;
== Full featured editing of text areas==&lt;br /&gt;
Much writing nowadays is done in text areas: wikis, blogs, forums, webmail. Text areas need full featured editing support:&lt;br /&gt;
* Unlimited undo/redo.&lt;br /&gt;
* Regular expression search and replace.&lt;br /&gt;
* Improve spell checking by switching from MySpell to the far-superior HunSpell (this is a direct descendant of MySpell and is the spell checking system now used by new versions of Open Office). There&#039;s a list of all the improvements in [https://bugzilla.mozilla.org/show_bug.cgi?id=319778 bug 319778]. This may also allow us to ship some dictionaries other than En-US in our localized builds (e.g. Hungarian).&lt;br /&gt;
* Grammar checking functionality similar to Spell checking (Grammar mistakes is just as prolific an bad spelling)&lt;br /&gt;
* The ability of checking multiple languages in a textarea simultaneously. &lt;br /&gt;
* Configurable shortcuts and macros.&lt;br /&gt;
* Allow easy saving of text area contents on the local machine.&lt;br /&gt;
* Automatic safety saves, so that the contents of a text area are never lost.&lt;br /&gt;
* Allow resizing of text areas, and splitting into two views.&lt;br /&gt;
&lt;br /&gt;
;See also: [http://ifindkarma.typepad.com/relax/2005/01/life_in_a_texta.html Life in a TEXTAREA] by Adam Rifkin&lt;br /&gt;
&lt;br /&gt;
== WYSIWYG Text Area ==&lt;br /&gt;
Enhanced the TEXTAREA tag to provide a WYSIWYG editor that generates HTML code.  How many different Javascript, ActiveX, Applet and AJAX solutions exist for this problem?  How many of them &amp;lt;u&amp;gt;actually work&amp;lt;/u&amp;gt;?  None.  Let&#039;s fix this problem once and do it right.  Imagine:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;TEXTAREA NAME=&amp;quot;foo&amp;quot; TYPE=&amp;quot;wysiwyg&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The user would see a text box with WYSIWYG editing controls.  When the form submits, the field would contain HTML code for the user&#039;s content.  Other browsers would ignore the new flag and display a standard TEXTAREA.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;EVERYONE&amp;lt;/u&amp;gt; needs this, including this Wiki.&lt;br /&gt;
:However we would be breaking the standards, wouldn&#039;t we? And i think we shouldn&#039;t be trying to do W3C&#039;s job.&lt;br /&gt;
&lt;br /&gt;
== Use mouse wheel to modify the values ==&lt;br /&gt;
&lt;br /&gt;
When I&#039;m hovering textarea with number/date and scroll my mouse up/down it should increase/decrease the value.&lt;br /&gt;
*This should be optional for those who don&#039;t want to accidentally change values when scrolling up or down a page. --[[User:Armaetin|Armaetin]] 15:49, 13 February 2007 (PST)&lt;br /&gt;
* This is not usable, because the scroll wheel is used for scrolling the page, as the previous reply said. -[[User:Pgan002|Pgan002]] 18:20, 27 March 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Automatically restore form with text values filled in if submit fails ==&lt;br /&gt;
After filling in a long email, blog entry etc. and submitting the form, if the subsequent page fails to load (eg because the Internet connection was lost when you were typing, or because of a temporary problem with page), instead of just showing an error message Firefox should give the user the option to either:&lt;br /&gt;
* attempt to submit the data again &lt;br /&gt;
or &lt;br /&gt;
* return to the previous page with all form items filled in (loaded from offline cache in case Internet connection is still down)&lt;br /&gt;
or&lt;br /&gt;
* provide a separate page or a tab in Page info where the contents of forms that are sent last are shown.&lt;br /&gt;
&lt;br /&gt;
There should definitely be some way to recover data that has been typed into a form and then lost.  Cache everything typed into forms, make it available on an about:textareas page or something, so we can recover our ten minutes of typing even if the page crashes, changes, gets logged out, etc. and Firefox can&#039;t figure out how to re-fill it.&lt;br /&gt;
&lt;br /&gt;
== Autofill forms ==&lt;br /&gt;
&lt;br /&gt;
* Like Opera&#039;s Wand or Google&#039;s Autofill in the Google Toolbar.&lt;br /&gt;
* Have an option to fill in your name, address and other information necessary for many websites into Firefox so that when filling out forms you can click a button that &#039;autofills&#039; them for you.&lt;br /&gt;
* Like Internet Explorer - it is best way.&lt;br /&gt;
* With Firefox 2, login form fields are only filled in with the login information stored in password manager after loading of the entire page has completed. However, form fields (in particular for login) should be rendered before any other elements on a page, because often all you want to do on a login page is ... to log in. But instead, rendering of a login page often hangs because billions of annoying ad servers take forever to reply to client requests. Rendering (login) forms and filling in the login information first would allow for immediate login, without having to wait until rendering of the whole page is complete -- also contributing to save bandwith, as requests to the billions of annoying ad servers would not be send, or at least cancelled immediately.&lt;br /&gt;
* Allow for check boxes to be filled based on the box being highlighted. So that if 10 check boxes are highlighted, you can fill them all in in one task not ten individual button clicks.&lt;br /&gt;
&lt;br /&gt;
== User-created spell check blacklist ==&lt;br /&gt;
&lt;br /&gt;
* Allow users to specify sites that should not have their text areas spell checked (i.e. sites with HTML editing text areas)&lt;br /&gt;
&lt;br /&gt;
== Submit form to new tab/window ==&lt;br /&gt;
&lt;br /&gt;
* Allow users to submit form buttons to a new tab/window&lt;br /&gt;
* [https://addons.mozilla.org/en-US/firefox/addon/483 Submit To Tab] Extension by nrlz&lt;br /&gt;
* [https://bugzilla.mozilla.org/show_bug.cgi?id=17754 Bug17754] Ability to submit form in a new window / tab&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;Minor&#039; Edit made; [[User:Nu(-)Ne(Ø)|_(-)(Ø)_]] 21:44, 29 December 2007 (PST)▼&lt;br /&gt;
&amp;lt;br&amp;gt;Apparently, context Menu Items like these aren&#039;t a big deal; at least not to the developers who are supposed to implement them, to my awareness thereof. Which is probably Why the Context Menu Item &amp;quot;View Image in New Tab&amp;quot; Option(amongst many other context menu Items mind you) is, Strangely, absent from the context Menu of Images(and to other respective/relevant objects as well) :O. That, or they just forgot about conveniences like that and need to be, reminded ;), ;).&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
But I second the notion you&#039;ve stated for a &amp;quot;Submit in New Window&amp;quot; and &amp;quot;Submit in New Tab&amp;quot; Context menu Item to be added to form like JavaScript based(?) Buttons as I to feel that it was, shall I say, &amp;quot;Left to be desired&amp;quot; :).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Please remove my input herein, if need be so.&lt;br /&gt;
▲&lt;br /&gt;
&lt;br /&gt;
== Change the way the spell checker highlights the misspelled words ==&lt;br /&gt;
&lt;br /&gt;
User interface consistency is important. I think misspelled words should be underlined with a red zigzag line, much like it&#039;s done on all modern text processors, instead of the current dotted line.&lt;br /&gt;
&lt;br /&gt;
[added:stk 10-mar-07]&lt;br /&gt;
I concur that changing the way the spell checker highlights misspelled words would be a good thing.  (Been trying to hack a way, but unsuccessful, so far).&lt;br /&gt;
&lt;br /&gt;
1px dotted red is just a tad too difficult for these old (48ish) eyes to see.  Been looking for a way to change text color (magenta, like google-spell does) ... or bg color ... SOMETHING more prominent.&lt;br /&gt;
&lt;br /&gt;
Which leads to another idea - make such behaviors user-set-able in some advanced behaviors tab (including option to point to other user-defined, specialty dictionaries - e.g., Word custom.dic, etc.)?&lt;br /&gt;
* I also agree that the spellchecker&#039;s highlighting should be changed, although that isn&#039;t as high of a priority as many of the other excellent features Firefox still needs. I also agree that the spellchecker&#039;s color should be changed to the will of the user, even though I already like red because it parallels with that of MS Word&#039;s. By the way, stk, advanced user preferences can be accessed by typing about:config in the address bar, and dictionaries are &amp;quot;stored&amp;quot; in a file named persdict.dat. --[[User:Armaetin|Armaetin]] 11:39, 10 March 2007 (PST)&lt;br /&gt;
&lt;br /&gt;
== Automatically pad text area with blank lines ==&lt;br /&gt;
&lt;br /&gt;
When I am reading a long article, paging down, it is annoying to reach the last page only to find that it is shorter than all the other pages and now my place is lost somewhere in the middle of the screen. I have to hunt for where I left off. I could solve this using the mouse to scroll, and sometimes I do, but I find that more burdensome than just hitting page down. This behavior has existed since the earliest days of the web. It seems to me the easiest way to fix it is for the browser to position the last line of the current page as the first line of the next, no matter what, and fill the rest of the window as needed with blank space. Since I spend most of my web time reading text, consistent text positioning would be a major usability enhancement for me.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;minor&#039; edit made; [[User:Nu(-)Ne(Ø)|_(-)(Ø)_]] 21:57, 29 December 2007 (PST)▼&lt;br /&gt;
You know what&#039;d be a sweet Idea?&lt;br /&gt;
&amp;lt;br&amp;gt;# 13 of my list: Memory Markers of some sorts that you can &amp;quot;place&amp;quot; on the page so that when you go down or up the page, right click off the scrollbar and input a # or something, it would send you to the corresponding part of the page. Maybe a Context Menu Item that states something along the lines of &amp;quot;Place memory marker on this currently displayed position&amp;quot; with extra Context Items added to the list and set as Numbers so you can seamlessly scroll anywhere on the current page. I haven&#039;t fully gone into the details of its implementation but I&#039;ll work on it when I get the proper inspiration.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Thanks however for your proposal as I often wondered if anyone else had the same Idea ;).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Please remove my input herein, if need be so. ▲&lt;br /&gt;
&lt;br /&gt;
== Drag and dropping files into textboxes ==&lt;br /&gt;
&lt;br /&gt;
* Allow users to drag and drop a local text/HTML file into a text box to insert the content of the file instead of its path.&lt;br /&gt;
&lt;br /&gt;
== Thesaurus and Form Information Spell Check ==&lt;br /&gt;
There should be a submenu (similarly to the &amp;quot;Language&amp;quot; submenu) that lists the synonym of the right-clicked word.&lt;br /&gt;
*A submenu for antonyms, as per the synonyms in the previous bullet.&lt;br /&gt;
*An easier way to edit and update Firefox&#039;s dictionary without manually going into persdict.dat.&lt;br /&gt;
*Grammar Check&lt;br /&gt;
&lt;br /&gt;
== Clipboard: A Modified Copy/Paste Functionality ==&lt;br /&gt;
What a clipboard would do:&lt;br /&gt;
* Firefox should add all objects we copy into a clipboard.&lt;br /&gt;
* The clipboard is accessible via a sidebar.&lt;br /&gt;
* Double-clicking an entry on the clipboard pastes the item, if appropriate.&lt;br /&gt;
* The clipboard is cleared after every session.&lt;br /&gt;
* A user can &amp;quot;merge&amp;quot; items on the clipboard. What this means is that a user can select multiple items on the clipboard (the same way multiple icons are selected on a desktop: using the Ctrl/Cmd key) and consolidate them into one item. This is for simplicity purposes, ie a user wants to paste everything on Firefox&#039;s clipboard into an external application.&lt;br /&gt;
Notes:&lt;br /&gt;
* Ideally, a clipboard should hold as many entries as possible.&lt;br /&gt;
* Unlike the floating clipboard in Microsoft Office programs, the clipboard should behave as a sidebar or toolbar.&lt;br /&gt;
* The clipboard does not affect copy and paste in any way. It merely pastes all instances of copying into its memory. Pasting an item from the clipboard merely copies the item from the history and pastes it, as if the user did it manually.&lt;br /&gt;
* The order of the items on a clipboard can be sorted via up/down buttons.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;Minor edit&#039; made [[User:Nu(-)Ne(Ø)|_(-)(Ø)_]] 22:13, 29 December 2007 (PST)▼&lt;br /&gt;
You know, on KDE we have this thing called Klipper. It is shear Awesomeness! It is, or can be, almost as your description depicts. Except, its a Tray Icon instead of a sidebar. I don&#039;t think a sidebar would be very, space friendly, you know? Floating clipboard provide ease of access and is space considerate. I think the problem would be, as I am assuming, that it would get in the way of the cursor sometimes. I don&#039;t see why we can&#039;t have it as, a Sidebar, Toolbar, and Float. Just Position it to the right or left pane for sidebar preference, Up near the top for Toolbar preferences, and anywhere in between for floating preferences with context options for displaying said clipboard as such.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Still that would be a good thing to have when you want to download many specific things from a page while Browsing using Firefox :).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Please remove my input herein, if need be so.▲&lt;br /&gt;
&lt;br /&gt;
== Allow specified textareas to expand with the size of the window ==&lt;br /&gt;
When editing large text, such as email, wiki, code and others, it is convenient to have the as large as possible an area to view it through.  But when the browser window itself is too small, you end up with two horizontal and/or two vertical scrollbars.  It wold be great if some specified text areas and text boxes could expand and contract with the size of the window.&lt;br /&gt;
*I agree, and I also think Firefox should give users the option of having the ability to manually set how large certain fields are. --[[User:Armaetin|Armaetin]] 22:57, 22 January 2007 (PST)&lt;br /&gt;
&lt;br /&gt;
== Auto-Correction ==&lt;br /&gt;
Microsoft Word automatically corrects commonly misspelled words (ie, changing &amp;quot;teh&amp;quot; to &amp;quot;the&amp;quot;). Perhaps Firefox should do the same:&lt;br /&gt;
*The undo command (Ctrl+Z) would undo an auto-correct, if the user had intended to spell the word incorrectly.&lt;br /&gt;
*There would be an auto-correction dictionary (separate from the current dictionary) in which users can place their own entries on what Firefox auto-corrects and remove some of Firefox&#039;s default auto-correction entries (if, for example, &amp;quot;teh&amp;quot; was actually a word in that user&#039;s regular vocabulary and that user does not like how Firefox keeps changing &amp;quot;teh&amp;quot; into &amp;quot;the&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Record and Play Macros ==&lt;br /&gt;
Some forms require clicking a series of routine &amp;quot;submit&amp;quot; buttons.  Some of the button-clicking has to do with accepting security certificates.  It&#039;s good that Firefox can remember the user IDs and passwords.  It&#039;d be better if Firefox allows us to &amp;quot;record&amp;quot; the sequence of button clicking as a macro files, and allows us (end users, not Web masters) to replay those macro files with a single click of a button.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
--[[User:Paulmackinlay|Paulmackinlay]] 04:42, 25 May 2007 (PDT)&lt;br /&gt;
This feature would be very useful and can be extended further to be even more useful. If the macros could be saved, categorised, edited this could form the basis of a powerful web testing suite. Firefox has always had great web-app developer aids and this would be certainly one of the most useful since it could be used to generate test suites which would be fully automated functional tests. It would ensure the web-app it behaving as expected with the current version of gecko and rhino.&lt;br /&gt;
&lt;br /&gt;
Assertions would need to be made available, which would indicate if a test passes or fails. It would also be useful to modify parameters such as domain name and port so that the same tests can be executed on more than one environment.&lt;br /&gt;
&lt;br /&gt;
Actually, there is a great piece of software called Badboy[http://www.badboy.com.au/] which does something similar, it has a lot of excellent features. Unfortunately it is only available for a specific OS and becuase it is not portable I can&#039;t use it. I appreciate that web-app testing is probably beyond the scope of core Firefox but maybe a seperate component/plug that does this could be considered.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[User:Glest|Glest]] 03:19, 19 February 2008 (PST)&lt;br /&gt;
I don&#039;t really like the idea of building a macro system in a browser. It would make it very easy to spam forms. I know it&#039;s already easy, but atleast there is no standard browser function called &amp;quot;Spam form&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Searchable button labels ==&lt;br /&gt;
Make button labels searchable, so that you can text search (for example) this page for &amp;quot;Search&amp;quot; and have the cursor on the &amp;quot;Search&amp;quot; button at the top.  This would help with navigation, especially in large webpages.  First, like text search in general, it allows the focus to be positioned directly without using a pointing device, which is often faster.  Second, there is often a specific button or function (such as search) which users want to use and have to scroll through the page and look for it manually. -[[User:Pgan002|Pgan002]] 15:07, 8 May 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Easy clearing of bad completions ==&lt;br /&gt;
Add an &amp;quot;X&amp;quot; button to the end of each line in the completion list that removes the entry.  This would allow you to get rid of accidental typos in previous forms that will pop up (without having to clear ALL the form completion data.)  -[[User:EricBayer|EricBayer]] 22:10, 3 July 2007&lt;br /&gt;
* I think this should be optional because it might be aesthetically displeasing to some. I am assuming Mr. EricBayer is unaware that he can get rid of saved form entries using Shift+Delete? --[[User:Armaetin|Armaetin]] 22:48, 3 July 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Remember chosen language for every text area on every page ==&lt;br /&gt;
For polyglot users, the Spell Checker loses much of its appeal, because you must manually switch the language every time you switch between languages.&lt;br /&gt;
&lt;br /&gt;
If the checker simply remembered the language I chose for each web page and on a second level for each text area on that web page (probably hard to impossible), it would greatly simplify writing for polyglot users. So, if I write on English wikipedia it first checks which language header the web site sent and if I don&#039;t agree with that setting, I can choose my own - maybe British English, even though Wikipedia sends US-English headers - and the checker will remember my choice, when I revisit the page.&lt;br /&gt;
&lt;br /&gt;
Another idea would be auto-recognition and multiple languages, but that&#039;s not too easy I guess, especially if the detection is based on the users misspellings.&lt;br /&gt;
I don&#039;t know whether there already is some sort of JS-Handler, but if web sites could tamper with Firefoxes Spell checker, they could suggest the right language right away - and annoy users a lot if they have bad intentions, of course.&lt;br /&gt;
--[[User:Rubenarslan|Rubenarslan]] 09:11, 4 November 2007 (PST)&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Parser_2_API_Conversion_Tutorial&amp;diff=156180</id>
		<title>Labs/Ubiquity/Parser 2 API Conversion Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Parser_2_API_Conversion_Tutorial&amp;diff=156180"/>
		<updated>2009-07-19T00:02:33Z</updated>

		<summary type="html">&lt;p&gt;Endolith: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Intro ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity 0.5 introduces an updated command API, reflecting the changes in [[Labs/Ubiquity/Parser_2|the parser]] as well as the new [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|ability to localize (some) commands]]. This tutorial will walk you through some of the key changes you will need to make. If you are interested in writing a new Ubiquity command from scratch, please refer to the [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|updated Command Authoring Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== A note on (backwards) compatibility ==&lt;br /&gt;
&lt;br /&gt;
Please note that Ubiquity 0.5 by default uses Parser 2 and Parser 1 (and the Parser 1 API) will be deprecated in the future. For the time being, however, it is possible to use Parser 1 in Ubiquity 0.5 by going to the Ubiquity settings page and turning off &amp;quot;use Parser 2&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Parser 1 API commands in Parser 2 ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Ubiquity_Old_API_badge.png|right]]&lt;br /&gt;
&lt;br /&gt;
All commands in the previous style (Parser 1 API) will be marked with an Old API badge in the Ubiquity command list, as seen on the right. Of these commands, those which do not take any arguments (no modifiers and no direct objects, in the Parser 1 API lingo) will be automatically converted and made to work with Parser 2, but all others will be ignored by Parser 2.&lt;br /&gt;
&lt;br /&gt;
=== Parser 2 API commands in Parser 1 ===&lt;br /&gt;
&lt;br /&gt;
While Parser 2 commands were built with some backwards compatibility in mind, there are some notable limitations. With Ubiquity 0.5 in Parser 1 mode (the &amp;quot;Use Parser 2&amp;quot; setting turned off), Parser 2 commands should be usable but they will only respond to specific prepositions. For example, a command which expects a &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; will only work with the preposition &amp;quot;near&amp;quot; rather than &amp;quot;near,&amp;quot; &amp;quot;on,&amp;quot; and &amp;quot;at,&amp;quot; which all work for this argument with Parser 2 (see below for more information on semantic roles). In addition, commands will only work in English and localization does not work in Parser 1 mode.&lt;br /&gt;
&lt;br /&gt;
Note, however, that Parser 2-style commands will &#039;&#039;not&#039;&#039; work at all in Ubiquity 0.1.x installs.&lt;br /&gt;
&lt;br /&gt;
We strongly encourage that all community commands be rewritten in Parser 2 format to take advantage of new (and upcoming) features.&lt;br /&gt;
&lt;br /&gt;
=== Supporting both Parser 1 and Parser 2 in Your Command Feed ===&lt;br /&gt;
&lt;br /&gt;
There is a property added to the Command API that allows you to present different commands to clients running Parser 1 and Parser 2, called CmdUtils.parserVersion.  A command can provide different options to CmdUtils.CreateCommand() and behave differently depending on this value, allowing a single command feed to cater to whatever parser the user is using. &lt;br /&gt;
&lt;br /&gt;
  if (CmdUtils.parserVersion == 2) {&lt;br /&gt;
    //parser 2 command here&lt;br /&gt;
  } else {&lt;br /&gt;
    //parser 1 command here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Converting your command ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;names&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Where Parser 1 expected a single default verb name in the property &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; and possible synonyms in an optional &amp;lt;code&amp;gt;synonyms&amp;lt;/code&amp;gt; property, Parser 2 requires that there be a single &amp;lt;code&amp;gt;names&amp;lt;/code&amp;gt; property with an array of possible verb names.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 1 (old) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    name: &#039;find&#039;,&lt;br /&gt;
    synonyms: [&#039;look-for&#039;, &#039;search&#039;],&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 2 (new) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    names: [&#039;find&#039;, &#039;look for&#039;, &#039;search&#039;],&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
Note also that command names may now include spaces. (Hurray!)&lt;br /&gt;
&lt;br /&gt;
=== Specifying semantic roles ===&lt;br /&gt;
&lt;br /&gt;
The biggest change in the Parser 2 API is that arguments are now specified using abstract &#039;&#039;semantic roles&#039;&#039; instead of language-specific markers. (See [[Labs/Ubiquity/Parser_2/Semantic_Roles|Semantic roles in Parser 2]] for further explanation of semantic roles and the rationale for this change.) Arguments which previously were specified in &amp;lt;code&amp;gt;takes&amp;lt;/code&amp;gt;, direct objects, use the role &amp;quot;object&amp;quot;. Arguments which were specified in &amp;lt;code&amp;gt;modifiers&amp;lt;/code&amp;gt; are specified using different semantic roles, based on the grammatical function of the argument, instead of by its English preposition. For example, an argument introduced by &amp;quot;to&amp;quot; would now be marked with the role &amp;lt;code&amp;gt;goal&amp;lt;/code&amp;gt;, and an argument introduced by &amp;quot;using&amp;quot; would be encoded as &amp;lt;code&amp;gt;instrument&amp;lt;/code&amp;gt;. These arguments are then all specified together with their nountypes in an array as property &amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 1 (old) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    takes: {query: noun_arb_text}&lt;br /&gt;
    modifiers: {&#039;using&#039;: noun_type_searchengine}&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 2 (new) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    arguments: [ {role: &#039;object&#039;, nountype: noun_arb_text, label: &#039;query&#039;},&lt;br /&gt;
                 {role: &#039;instrument&#039;, nountype: noun_type_searchengine} ],&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
Please refer to [[Labs/Ubiquity/Parser_2/Semantic_Roles|Semantic roles in Parser 2]] for a list of supported semantic roles with examples of their use. Note that the &amp;lt;code&amp;gt;label&amp;lt;/code&amp;gt; parameter (used in specifying the &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; argument above) is optional.&lt;br /&gt;
&lt;br /&gt;
In addition, the old-style (but rare) &amp;lt;code&amp;gt;DOType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;DOLabel&amp;lt;/code&amp;gt; specifications are also no longer supported.&lt;br /&gt;
&lt;br /&gt;
=== Using semantic roles in &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
As arguments are specified using semantic roles, arguments are then passed to the &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; methods based on their arguments as well. Both methods are handed an object with the semantic roles as the keys, and the argument data as the values, e.g.&lt;br /&gt;
&lt;br /&gt;
  { object:     { text: &#039;chicken&#039;,&lt;br /&gt;
                  data: &#039;chicken&#039;,&lt;br /&gt;
                  ... },&lt;br /&gt;
    instrument: { text: &#039;goo&#039;,&lt;br /&gt;
                  data: &#039;Google&#039;,&lt;br /&gt;
                  ... }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Note that the structure of the argument data itself (with requisite properties &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;html&amp;lt;/code&amp;gt;) is the same as with the Parser 1 API.&lt;br /&gt;
&lt;br /&gt;
Instead of handing the direct object&#039;s data and the other arguments&#039; data separately to &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt;, Parser 2 hands it to them together as one argument:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 1 (old) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    preview: function(pblock, object, modifiers) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = object.text;&lt;br /&gt;
      data.engine = modifiers.using.text;&lt;br /&gt;
      pblock.innerHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                           &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                           data );&lt;br /&gt;
    },&lt;br /&gt;
    execute: function(object, modifiers) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = object.text;&lt;br /&gt;
      data.engine = modifiers.using.text;&lt;br /&gt;
      displayMessage(CmdUtils.renderTemplate(&lt;br /&gt;
                      &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                      data );&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 2 (new) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    preview: function(pblock, args) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = args.object.text;&lt;br /&gt;
      data.engine = args.instrument.text;&lt;br /&gt;
      pblock.innerHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                           &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                           data );&lt;br /&gt;
    },&lt;br /&gt;
    execute: function(args) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = args.object.text;&lt;br /&gt;
      data.engine = args.instrument.text;&lt;br /&gt;
      displayMessage(CmdUtils.renderTemplate(&lt;br /&gt;
                      &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                       data );&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
As always, it is best to first check whether the requisite arguments were filled in the parser before using it.&lt;br /&gt;
&lt;br /&gt;
=== Making your command localizable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;More detailed information on making commands localizable can be found in the tutorial [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making Commands Localizable]].&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t yet support the localization of commands which are not bundled with Ubiquity itself. However, the localization of community commands is being planned, so making your command localizable now will future-proof your command and will later open your command up to a much wider target audience.&lt;br /&gt;
&lt;br /&gt;
In addition to the Parser 2 API changes listed above, the main change to be made is to wrap any localizable strings in your &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; methods with the function &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt;. This &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; command (familiar to anyone with prior experience with [http://en.wikipedia.org/wiki/Gettext Gettext]) handles the localization by finding the appropriate matching localized string on preview or execution.&lt;br /&gt;
&lt;br /&gt;
  displayMessage(_(&#039;No results were found.&#039;));&lt;br /&gt;
&lt;br /&gt;
In the case above, &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; will then take care of finding appropriate localizations of the string &amp;quot;No results were found&amp;quot; for your command and, if available, display that string instead.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; function also handles [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates &amp;lt;code&amp;gt;renderTemplate&amp;lt;/code&amp;gt;ing] if you also give it an object with replacement variables. For examples, you can write the following:&lt;br /&gt;
&lt;br /&gt;
  displayMessage(_(&amp;quot;${number} results found.&amp;quot;, {number: numOfResults}))&lt;br /&gt;
&lt;br /&gt;
By default, this will display, for example, &amp;quot;3 results found.&amp;quot; if &amp;lt;code&amp;gt;numOfResults == 3&amp;lt;/code&amp;gt; and something like &amp;quot;Il y a 3 résultats&amp;quot; given a French localization of &amp;quot;Il y a ${number} résultats&amp;quot;. This templating can also be used to handle pluralization—please refer to [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making Commands Localizable]] for more information.&lt;br /&gt;
&lt;br /&gt;
There is no need to wrap any properties of the commands (&amp;lt;code&amp;gt;names&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;help&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;, etc.) in &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt;, nor do you need to wrap string previews in &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt;, in order for the command to be localizable. These direct properties of the command are automatically localizable as long as they are set in the original command.&lt;br /&gt;
&lt;br /&gt;
More tips on making strings localizable can be found in [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making Commands Localizable]].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|The updated Command Authoring Tutorial]]&lt;br /&gt;
* [[Labs/Ubiquity/Parser_2/Semantic_Roles|Semantic roles in Parser 2]]: a list of supported semantic roles with explanations and examples&lt;br /&gt;
* [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making your command localizable]]&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Parser_2_API_Conversion_Tutorial&amp;diff=156179</id>
		<title>Labs/Ubiquity/Parser 2 API Conversion Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Parser_2_API_Conversion_Tutorial&amp;diff=156179"/>
		<updated>2009-07-18T23:23:27Z</updated>

		<summary type="html">&lt;p&gt;Endolith: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Intro ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity 0.5 introduces an updated command API, reflecting the changes in [[Labs/Ubiquity/Parser_2|the parser]] as well as the new [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|ability to localize (some) commands]]. This tutorial will walk you through some of the key changes you will need to make. If you are interested in writing a new Ubiquity command from scratch, please refer to the [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|updated Command Authoring Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== A note on (backwards) compatibility ==&lt;br /&gt;
&lt;br /&gt;
Please note that Ubiquity 0.5 by default uses Parser 2 and Parser 1 (and the Parser 1 API) will be deprecated in the future. For the time being, however, it is possible to use Parser 1 in Ubiquity 0.5 by going to the Ubiquity settings page and turning off &amp;quot;use Parser 2&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Parser 1 API commands in Parser 2 ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Ubiquity_Old_API_badge.png|right]]&lt;br /&gt;
&lt;br /&gt;
All commands in the previous style (Parser 1 API) will be marked with an Old API badge in the Ubiquity command list, as seen on the right. Of these commands, those which do not take any arguments (no modifiers and no direct objects, in the Parser 1 API lingo) will be automatically converted and made to work with Parser 2, but all others will be ignored by Parser 2.&lt;br /&gt;
&lt;br /&gt;
=== Parser 2 API commands in Parser 1 ===&lt;br /&gt;
&lt;br /&gt;
While Parser 2 commands were built with some backwards compatibility in mind, there are some notable limitations. With Ubiquity 0.5 in Parser 1 mode (the &amp;quot;Use Parser 2&amp;quot; setting turned off), Parser 2 commands should be usable but they will only respond to specific prepositions. For example, a command which expects a &amp;lt;code&amp;gt;location&amp;lt;/code&amp;gt; will only work with the preposition &amp;quot;near&amp;quot; rather than &amp;quot;near,&amp;quot; &amp;quot;on,&amp;quot; and &amp;quot;at,&amp;quot; which all work for this argument with Parser 2 (see below for more information on semantic roles). In addition, commands will only work in English and localization does not work in Parser 1 mode.&lt;br /&gt;
&lt;br /&gt;
Note, however, that Parser 2-style commands will &#039;&#039;not&#039;&#039; work at all in Ubiquity 0.1.x installs.&lt;br /&gt;
&lt;br /&gt;
We strongly encourage that all community commands be rewritten in Parser 2 format to take advantage of new (and upcoming) features.&lt;br /&gt;
&lt;br /&gt;
=== Supporting both Parser 1 and Parser 2 in Your Command Feed ===&lt;br /&gt;
&lt;br /&gt;
There is a property added to the Command API that allows you to present different commands to clients running Parser 1 and Parser 2, called CmdUtils.parserVersion.  A command can provide different options to CmdUtils.CreateCommand() and behave differently depending on this value, allowing a single command feed to cater to whatever parser the user is using. &lt;br /&gt;
&lt;br /&gt;
  if (CmdUtils.parserVersion == 2) {&lt;br /&gt;
    //parser 2 command here&lt;br /&gt;
  } else {&lt;br /&gt;
    //parser 1 command here&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Converting your command ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;names&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Where Parser 1 expected a single default verb name in the property &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; and possible synonyms in an optional &amp;lt;code&amp;gt;synonyms&amp;lt;/code&amp;gt; property, Parser 2 requires that there be a single &amp;lt;code&amp;gt;names&amp;lt;/code&amp;gt; property with an array of possible verb names.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 1 (old) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    name: &#039;find&#039;,&lt;br /&gt;
    synonyms: [&#039;look-for&#039;, &#039;search&#039;],&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 2 (new) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    names: [&#039;find&#039;, &#039;look for&#039;, &#039;search&#039;],&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
Note also that command names may now include spaces. (Hurray!)&lt;br /&gt;
&lt;br /&gt;
=== Specifying semantic roles ===&lt;br /&gt;
&lt;br /&gt;
The biggest change in the Parser 2 API is that arguments are now specified using abstract &#039;&#039;semantic roles&#039;&#039; instead of language-specific markers. (See [[Labs/Ubiquity/Parser_2/Semantic_Roles|Semantic roles in Parser 2]] for further explanation of semantic roles and the rationale for this change.) Arguments which previously were specified in &amp;lt;code&amp;gt;takes&amp;lt;/code&amp;gt;, direct objects, use the role &amp;quot;object&amp;quot;. Arguments which were specified in &amp;lt;code&amp;gt;modifiers&amp;lt;/code&amp;gt; are specified using different semantic roles, based on the grammatical function of the argument, instead of by its English preposition. For example, an argument introduced by &amp;quot;to&amp;quot; would now be marked with the role &amp;lt;code&amp;gt;goal&amp;lt;/code&amp;gt;, and an argument introduced by &amp;quot;using&amp;quot; would be encoded as &amp;lt;code&amp;gt;instrument&amp;lt;/code&amp;gt;. These arguments are then all specified together with their nountypes in an array as property &amp;lt;code&amp;gt;arguments&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 1 (old) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    takes: {query: noun_arb_text}&lt;br /&gt;
    modifiers: {&#039;using&#039;: noun_type_searchengine}&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 2 (new) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    arguments: [ {role: &#039;object&#039;, nountype: noun_arb_text, label: &#039;query&#039;},&lt;br /&gt;
                 {role: &#039;instrument&#039;, nountype: noun_type_searchengine} ],&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
Please refer to [[Labs/Ubiquity/Parser_2/Semantic_Roles|Semantic roles in Parser 2]] for a list of supported semantic roles with examples of their use. Note that the &amp;lt;code&amp;gt;label&amp;lt;/code&amp;gt; parameter (used in specifying the &amp;lt;code&amp;gt;object&amp;lt;/code&amp;gt; argument above) is optional.&lt;br /&gt;
&lt;br /&gt;
In addition, the old-style (but rare) &amp;lt;code&amp;gt;DOType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;DOLabel&amp;lt;/code&amp;gt; specifications are also no longer supported.&lt;br /&gt;
&lt;br /&gt;
=== Using semantic roles in &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
As arguments are specified using semantic roles, arguments are then passed to the &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; methods based on their arguments as well. Both methods are handed an object with the semantic roles as the keys, and the argument data as the values, e.g.&lt;br /&gt;
&lt;br /&gt;
  { object:     { text: &#039;chicken&#039;,&lt;br /&gt;
                  data: &#039;chicken&#039;,&lt;br /&gt;
                  ... },&lt;br /&gt;
    instrument: { text: &#039;goo&#039;,&lt;br /&gt;
                  data: &#039;Google&#039;,&lt;br /&gt;
                  ... }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Note that the structure of the argument data itself (with requisite properties &amp;lt;code&amp;gt;text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;html&amp;lt;/code&amp;gt;) is the same as with the Parser 1 API.&lt;br /&gt;
&lt;br /&gt;
Instead of handing the direct object&#039;s data and the other arguments&#039; data separately to &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt;, Parser 2 hands it to them together as one argument:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 1 (old) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    preview: function(pblock, object, modifiers) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = object.text;&lt;br /&gt;
      data.engine = modifiers.using.text;&lt;br /&gt;
      pblock.innerHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                           &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                           data );&lt;br /&gt;
    },&lt;br /&gt;
    execute: function(object, modifiers) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = object.text;&lt;br /&gt;
      data.engine = modifiers.using.text;&lt;br /&gt;
      displayMessage(CmdUtils.renderTemplate(&lt;br /&gt;
                      &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                      data );&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Parser 2 (new) API:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  CmdUtils.CreateCommand({&lt;br /&gt;
    ...&lt;br /&gt;
    preview: function(pblock, args) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = args.object.text;&lt;br /&gt;
      data.engine = args.instrument.text;&lt;br /&gt;
      pblock.innerHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                           &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                           data );&lt;br /&gt;
    },&lt;br /&gt;
    execute: function(args) {&lt;br /&gt;
      var data = {};&lt;br /&gt;
      data.query = args.object.text;&lt;br /&gt;
      data.engine = args.instrument.text;&lt;br /&gt;
      displayMessage(CmdUtils.renderTemplate(&lt;br /&gt;
                      &amp;quot;Searching for ${query} using ${engine}.&amp;quot;,&lt;br /&gt;
                       data );&lt;br /&gt;
    },&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
As always, it is best to first check whether the requisite arguments were filled in the parse before using it.&lt;br /&gt;
&lt;br /&gt;
=== Making your command localizable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;More detailed information on making commands localizable can be found in the tutorial [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making Commands Localizable]].&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t yet support the localization of commands which are not bundled with Ubiquity itself. However, the localization of community commands is being planned, so making your command localizable now will future-proof your command and will later open your command up to a much wider target audience.&lt;br /&gt;
&lt;br /&gt;
In addition to the Parser 2 API changes listed above, the main change to be made is to wrap any localizable strings in your &amp;lt;code&amp;gt;preview&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute&amp;lt;/code&amp;gt; methods with the function &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt;. This &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; command (familiar to anyone with prior experience with [http://en.wikipedia.org/wiki/Gettext Gettext]) handles the localization by finding the appropriate matching localized string on preview or execution.&lt;br /&gt;
&lt;br /&gt;
  displayMessage(_(&#039;No results were found.&#039;));&lt;br /&gt;
&lt;br /&gt;
In the case above, &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; will then take care of finding appropriate localizations of the string &amp;quot;No results were found&amp;quot; for your command and, if available, display that string instead.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; function also handles [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates &amp;lt;code&amp;gt;renderTemplate&amp;lt;/code&amp;gt;ing] if you also give it an object with replacement variables. For examples, you can write the following:&lt;br /&gt;
&lt;br /&gt;
  displayMessage(_(&amp;quot;${number} results found.&amp;quot;, {number: numOfResults}))&lt;br /&gt;
&lt;br /&gt;
By default, this will display, for example, &amp;quot;3 results found.&amp;quot; if &amp;lt;code&amp;gt;numOfResults == 3&amp;lt;/code&amp;gt; and something like &amp;quot;Il y a 3 résultats&amp;quot; given a French localization of &amp;quot;Il y a ${number} résultats&amp;quot;. This templating can also be used to handle pluralization—please refer to [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making Commands Localizable]] for more information.&lt;br /&gt;
&lt;br /&gt;
There is no need to wrap any properties of the commands (&amp;lt;code&amp;gt;names&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;help&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;author&amp;lt;/code&amp;gt;, etc.) in &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt;, nor do you need to wrap string previews in &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt;, in order for the command to be localizable. These direct properties of the command are automatically localizable as long as they are set in the original command.&lt;br /&gt;
&lt;br /&gt;
More tips on making strings localizable can be found in [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making Commands Localizable]].&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|The updated Command Authoring Tutorial]]&lt;br /&gt;
* [[Labs/Ubiquity/Parser_2/Semantic_Roles|Semantic roles in Parser 2]]: a list of supported semantic roles with explanations and examples&lt;br /&gt;
* [[Labs/Ubiquity/Ubiquity_0.5_Making_Commands_Localizable|Making your command localizable]]&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.5_Author_Tutorial&amp;diff=154582</id>
		<title>Labs/Ubiquity/Ubiquity 0.5 Author Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.5_Author_Tutorial&amp;diff=154582"/>
		<updated>2009-07-11T00:28:07Z</updated>

		<summary type="html">&lt;p&gt;Endolith: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
Author: Aza Raskin, Blair McBride, Abimanyu Raja, Jono DiCarlo, Atul Varma&lt;br /&gt;
&lt;br /&gt;
= The Ubiquity version 0.5 Command Tutorial =&lt;br /&gt;
&lt;br /&gt;
The great power of Ubiquity&amp;amp;mdash;from a developer standpoint&amp;amp;mdash;is how easy it is to create commands. With only a couple of lines of Javascript, Ubiquity enables even casual web developers to drastically enhance the features of the browser. From an 8-line command to insert a contact&#039;s email address in any text field, to a 50-line Twitter integration, this tutorial walks you through the process of being generative with Ubiquity.&lt;br /&gt;
&lt;br /&gt;
The rest of this page documents the command developer API as it stands frozen in version 0.5.&lt;br /&gt;
&lt;br /&gt;
If you want the bleeding-edge command developer API (which includes any new features that may have been added to the Ubiquity source code in HG but not yet included in a release), then that&#039;s [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|here]].&lt;br /&gt;
&lt;br /&gt;
If you want the old command developer API, as it stood in Ubiquity 0.1 (not recommended), that&#039;s [[Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial|here]].&lt;br /&gt;
&lt;br /&gt;
== Real Time Development ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t require you to restart Firefox as you develop. Restarting is a drastic measure, and we want none of it. Instead, Ubiquity reloads the commands every time it is summoned. When you are using the built-in editor then you don&#039;t even need to save!&lt;br /&gt;
&lt;br /&gt;
To open the Ubiquity command editor, summon Ubiquity (control/alt + space) and use the &amp;quot;open command editor&amp;quot; command. Throughout this tutorial, when we want you to run a command in Ubiquity, we&#039;ll say &#039;&#039;&#039;Ubiq&#039;&#039;&#039; it. For instance, to open the editor, just Ubiq &amp;quot;open command editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the following examples, just type in this editor. Updates happen the next time you summon Ubiquity.&lt;br /&gt;
&lt;br /&gt;
== Choices, Choices... ==&lt;br /&gt;
&lt;br /&gt;
You may notice a drop-down menu mentioning something about a &amp;quot;feed type&amp;quot; just above the editing field in the command editor:&lt;br /&gt;
&lt;br /&gt;
http://www.toolness.com/images/20090318121423.jpg&lt;br /&gt;
&lt;br /&gt;
For now, just make sure this drop-down is set to &amp;quot;Regular&amp;quot;.  We&#039;ll tell you more about what this means later.&lt;br /&gt;
&lt;br /&gt;
= Hello World: The First Command =&lt;br /&gt;
&lt;br /&gt;
== Just a Message: As Simple as it Gets ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s start with the standard programing trope: printing &amp;quot;Hello, World!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the command editor type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now try Ubiq-ing &amp;quot;say hello&amp;quot;. You&#039;ll see that &amp;quot;Hello, World!&amp;quot; is immediately displayed on the screen. If you are on Mac OSX with [http://en.wikipedia.org/wiki/Growl_(software) Growl] installed the message will appear as a Growl notification. If you are on Windows, then it will appears as a standard &amp;quot;toaster&amp;quot; notification in the bottom right-hand corner of the screen.&lt;br /&gt;
&lt;br /&gt;
http://farm3.static.flickr.com/2479/3651542339_022e4aa4c4.jpg&lt;br /&gt;
&lt;br /&gt;
http://img517.imageshack.us/img517/7726/picture2vx2.png&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 8.04 (Hardy Heron) this appears thus:&lt;br /&gt;
&lt;br /&gt;
http://img293.imageshack.us/img293/7746/ubiqubuntuhelloworldeq9.png&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have Growl installed on OSX, or aren&#039;t on a Windows XP/Vista or Ubuntu Hardy, then you won&#039;t get any sort of notification. That&#039;s something to be [http://labs.toolness.com/trac/ticket/19 worked on] in future releases of Ubiquity.&lt;br /&gt;
&lt;br /&gt;
=== CmdUtils.CreateCommand ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CmdUtils&amp;lt;/code&amp;gt; is a namespace which contains all the functions you need to create commands.  Commands are created by making an object and passing it to &amp;lt;code&amp;gt;CmdUtils.CreateCommand&amp;lt;/code&amp;gt;.  In Javascript, inline curly braces mean &amp;quot;new object&amp;quot;, so this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
   names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
   execute: function() { //etc }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
means &amp;quot;Make an object with two attributes, &#039;names&#039; and &#039;execute&#039;.&amp;quot;  This object is then passed as the argument to &amp;lt;code&amp;gt;CmdUtils.CreateCommand&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== names ===&lt;br /&gt;
&lt;br /&gt;
&#039;names&#039; and &#039;execute&#039; are the only two mandatory attributes for your command object.  &#039;names&#039; specifies what the command is called, and &#039;execute&#039; specifies what it does.  There are plenty of other attributes that you can specify, but they are all optional.&lt;br /&gt;
&lt;br /&gt;
&#039;names&#039; is always an array (thus the square brackets).  In the case of this command we provided only one name, &amp;quot;hello world&amp;quot;.  But we could have provided as many names as we wanted.  For instance, if we had said:&lt;br /&gt;
&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
then &amp;quot;say hello&amp;quot; would be the normal name of the command, but Ubiquity would also recognize &amp;quot;greet&amp;quot; as a synonym or alias for the command.&lt;br /&gt;
&lt;br /&gt;
=== execute ===&lt;br /&gt;
&lt;br /&gt;
&#039;execute&#039; is always a function.  When the user executes your command, this is the function that will be run.  It can do pretty much anything you want -- or at least, anything you know how to write in JavaScript.&lt;br /&gt;
&lt;br /&gt;
In the example above, we simply call &amp;lt;code&amp;gt;displayMessage()&amp;lt;/code&amp;gt;, which displays the given message in whichever way the operating system can.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are a number of other useful functions in the &amp;lt;code&amp;gt;CmdUtils&amp;lt;/code&amp;gt; namespace. We don&#039;t yet have full documentation for these commands, but you&#039;ll get a sense of the useful ones in this tutorial. For more detailed information, take a look at [http://hg.toolness.com/ubiquity-firefox/file/9a6c9935da9f/ubiquity/chrome/content/cmdutils.js cmdutils.js].&lt;br /&gt;
&lt;br /&gt;
=== Making sure your command is localizable ===&lt;br /&gt;
&lt;br /&gt;
Ubiquity now supports multiple languages.  That means that hopefully someday someone will be translating your commands to the other languages that Ubiquity supports.  Making your command localizable is easy, and a good habit to get into!  You just have to locate all strings that appear in your &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; methods, that are intended for display to humans, and wrap them with:&lt;br /&gt;
&lt;br /&gt;
 _()&lt;br /&gt;
&lt;br /&gt;
This may look odd, but what it does is quite important: it makes your strings appear in the template files that localizers will be using.  So let&#039;s make our &amp;quot;Hello world!&amp;quot; command localizable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( _(&amp;quot;Hello, World!&amp;quot;) );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This makes it so that when a localization template is generated from your command feed, &amp;quot;Hello, World!&amp;quot; will be listed among the strings to be translated.&lt;br /&gt;
&lt;br /&gt;
Note that we don&#039;t need to wrap the names, or other strings that appear in the command metadata -- these are automatically wrapped for us.  We only need to wrap strings that appear inside the functions.&lt;br /&gt;
&lt;br /&gt;
== Adding a Preview ==&lt;br /&gt;
&lt;br /&gt;
http://img352.imageshack.us/img352/1002/picture3ex0.png&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a preview to our new command. Previews give the user feedback about what a command does before it&#039;s executed. Previews are great for providing rich visual feedback like displaying a graphical representation of atmospheric conditions when using the weather command as shown above. Previews have the full expressive power of HTML, including animations, so there&#039;s a lot you can do with them.&lt;br /&gt;
&lt;br /&gt;
One point of design: Preview code should never have side-effects. That is, a preview should never (without user interaction) change the state of the system.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;say hello&amp;quot; command, we don&#039;t need anything fancy: just some help text that is more descriptive than the default &amp;quot;Executes the say hello command.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;],&lt;br /&gt;
  preview: &amp;quot;Displays a &amp;lt;i&amp;gt;salutary&amp;lt;/i&amp;gt; greeting to the planet.&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( _(&amp;quot;Hello, World!&amp;quot;) );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the preview is an HTML-formatted string. The preview can also be a function. We&#039;ll get to that in the next section.&lt;br /&gt;
&lt;br /&gt;
= The Date Command: The Second Command =&lt;br /&gt;
&lt;br /&gt;
= Setting the Selection =&lt;br /&gt;
&lt;br /&gt;
I often forget what day it is. That may be because I need to go outside more often, but, like any programmer, I generally solve my problem&#039;s symptoms with technology rather then addressing the root cause. My solution is to create a command that inserts the date at the location of the cursor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    CmdUtils.setSelection( date.toLocaleDateString() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new function here is &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt;. This inserts the passed-in text onto the page at the location of the cursor. If the cursor is in an editable text or rich-text fields, the text gets dumped there. If the cursor isn&#039;t in an editable area, &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt; will still be able to insert the date. (Even when it isn&#039;t displayed, Firefox always keeps track of a cursor position. To see it, type F7.) Try going to a page, selecting some non-mutable text, and using the command. See, it works! This is particularly useful for commands like &amp;quot;translate&amp;quot;, where you want to replace non-editable text with its translation.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;toLocalDateString()&amp;lt;/code&amp;gt; function is native to Javascript, so if you&#039;re not familiar with it check out the documentation for the Javascript [http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date Date object].&lt;br /&gt;
&lt;br /&gt;
== A Better Preview ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s time to add a better preview to the date command. Let&#039;s have the preview show the date, so that the user will know what to expect when they execute the command. (As a side benefit the user doesn&#039;t even need to execute the command to do a quick check of the day.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  &lt;br /&gt;
  _date: function(){&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    return date.toLocaleDateString();&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = _(&#039;Inserts today&#039;s date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;);&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function() {&lt;br /&gt;
    CmdUtils.setSelection( this._date() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&#039;ve done three things here. The first was to factor out the code for getting the date into the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt; function. This way we don&#039;t break [http://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY] by repeating code across the preview and execute functions. Notice that to access the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt;, we use the &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
&lt;br /&gt;
The second thing we&#039;ve done is to add a preview function. The first argument is the DOM element that gets displayed as the preview for your command. Modify &amp;lt;code&amp;gt;pblock&amp;lt;/code&amp;gt; and you modify the preview. In this case, we set the &amp;lt;code&amp;gt;innerHTML&amp;lt;/code&amp;gt; of the preview block to be the message we want.&lt;br /&gt;
&lt;br /&gt;
The third thing we&#039;ve done is to do some string formatting using the &amp;lt;code&amp;gt;renderTemplate()&amp;lt;/code&amp;gt; function. This takes a template string and performs the appropriate substitution given the passed-in JSON object. Templates can handle a wide range of functionality, as we are currently using TrimPath&#039;s [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates JavascriptTemplates]. You should read their site for more documentation. Although JavascriptTemplates has some nice properties, we are contemplating moving to [http://mjtemplate.org/ MJT] sometime soon.&lt;br /&gt;
&lt;br /&gt;
=== A shortcut for localization and rendering templates ===&lt;br /&gt;
&lt;br /&gt;
Note how in the code above, we used the localization wrapper &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; before passing the string to renderTemplate.  Because this is such a very common combination when displaying strings, we have a shortcut for it.  Calling _() with a JSON object as the second argument will automatically trigger &amp;lt;code&amp;gt;CmdUtils.renderTemplate()&amp;lt;/code&amp;gt; on the post-localization string.  So the above preview method could be rewritten more simply as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &#039;Inserts today&#039;s date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
    pblock.innerHTML = _( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Networking calls and placeholder previews ===&lt;br /&gt;
&lt;br /&gt;
Previews display something meaningful to the user immediately. If you have a preview that requires an AJAX request&amp;amp;mdash;say, to fetch some search results&amp;amp;mdash;that call might take a while to return. In the meantime, your command should display a placeholder preview giving the user feedback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    pblock.innerHTML = _(&amp;quot;This will show until the AJAX request returns&amp;quot;);&lt;br /&gt;
    // AJAX request&lt;br /&gt;
    pblock.innerHTML = getFromServer();&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the future, we may work on streamlining this process.&lt;br /&gt;
&lt;br /&gt;
== Documentation and Metadata ==&lt;br /&gt;
&lt;br /&gt;
Before you share your command with the world, you should consider adding some attributions to the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you should &amp;lt;em&amp;gt;definitely&amp;lt;/em&amp;gt; add some documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Inserts today&#039;s date.&amp;quot;,&lt;br /&gt;
  help: &amp;quot;If you&#039;re in an editable text area, inserts today&#039;s date, formatted for the current locale.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.description&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.help&amp;lt;/code&amp;gt; attributes are both automatically displayed alongside your command&#039;s name on the command-list page.  (The user can get to this page at any time by issuing the &amp;quot;list ubiquity commands&amp;quot; command.)  HTML tags can be used in both of these strings.&lt;br /&gt;
&lt;br /&gt;
Description is a one-line summary of what the command does, while Help is a longer description that can include examples, caveats, and so on. If your command is simple enough that all you have to say about it fits in one line, it&#039;s OK to use a description alone and leave out the help.&lt;br /&gt;
&lt;br /&gt;
== Sharing it with the World ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our awesome new &amp;quot;date&amp;quot; command, let&#039;s share it with the world. All you have to do is put it the javascript file on the web somewhere, and make an html page linking to it with &amp;quot;link rel&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;pre&amp;gt;&amp;lt;link rel=&amp;quot;commands&amp;quot; href=&amp;quot;http://path-to-js&amp;quot; name=&amp;quot;Title Goes Here&amp;quot; /&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anyone with Ubiquity who visits will get a message offering them the choice of subscribing to your command.&lt;br /&gt;
&lt;br /&gt;
[[Image:Subscribe.png]]&lt;br /&gt;
&lt;br /&gt;
If the user chooses to subscribe to a Regular command feed from an untrusted source, they will get a security warning message before they can install the command.  Because Regular Ubiquity command feeds can execute arbitrary javascript with chrome privileges, subscribing to a command from a website means allowing that site full access to do whatever it wants to your browser.  We want to make sure people understand the dangers before subscribing to commands, so we made the warning page pretty scary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Warning.PNG]]&lt;br /&gt;
&lt;br /&gt;
=== Feed Types ===&lt;br /&gt;
&lt;br /&gt;
Recall that back near the beginning of the tutorial, you set the &amp;quot;feed type&amp;quot; to &amp;quot;Regular&amp;quot;.  As you may have guessed, there&#039;s actually more than one way to write a command feed.  The advantage of Regular feeds is that they let you do whatever you want, so it&#039;s really easy to innovate, but the disadvantages lie in subscribing to misbehaving or malicious code.  You can alternatively write what&#039;s called a &#039;&#039;Locked-Down Feed&#039;&#039;, which is much safer and doesn&#039;t raise a warning page when a user subscribes to it&amp;amp;mdash;but the consequences are that you have less freedom of implementation as a command author.  If you&#039;re interested in learning more about Locked-Down Feeds, check out the [[Labs/Ubiquity/Locked-Down_Feed_Tutorial|Locked-Down Feed Tutorial]].&lt;br /&gt;
&lt;br /&gt;
=== Trust Networks ===&lt;br /&gt;
&lt;br /&gt;
In the future, we&#039;re going to have something set up that we call a &amp;quot;[[Labs/Ubiquity/TrustNetwork|trust network]]&amp;quot;.  When you try out a Ubiquity command from a website, and determine that the command is safe (or unsafe), you&#039;ll be able to leave an approval (or a warning).  When your friends with Ubiquity installed visit the same site, they&#039;ll see the approval or the warning that you left.  In this way, users will be able to rely on the judgement of other people they already know and trust in order to help them make decisions about whether a command is safe to install or not.&lt;br /&gt;
&lt;br /&gt;
By the way, the reason we call it &amp;quot;subscribing&amp;quot; to a command, rather than &amp;quot;installing&amp;quot; a command, is that if the javascript file changes -- if the site owner adds new commands, removes old commands, or updates existing commands -- all users subscribed to that URL will automatically get the updates.  This will be very convenient for both users and developers, but it will also introduce another type of security risk: just because you decided a command was safe at one point in time doesn&#039;t mean that the command will always remain safe.  For this reason, we&#039;ll need to make sure that the trust network keeps track of when commands have been modified, and notifies users of changes that may make a command unsafe.&lt;br /&gt;
&lt;br /&gt;
== Map Me! Location, Snapshots, and Inserting HTML ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;map&amp;quot; command that comes with Ubiquity is fairly powerful. It&#039;s also fairly complicated&amp;amp;mdash;well, comparatively. It&#039;s still only a couple hundred lines of code. The command, though, can get even more useful. Imagine being able to select some houses on Craigslist, or a list of restaurant names, and Ubiq &amp;quot;map these&amp;quot; to get just the map you want. The concept of &amp;quot;these&amp;quot; puts the power of mashups into the users hands. But I digress. Let&#039;s make a simple command that inserts a map of your current location.&lt;br /&gt;
&lt;br /&gt;
In this command, we use the Google [http://code.google.com/apis/maps/documentation/staticmaps/ static map API] and the Ubiquity function &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; to insert a map of your current location. Ubiquity currently uses the [http://www.maxmind.com/app/api MaxMind] API for trying to guess your location from your IP. That will probably change in the future.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll call this command &amp;lt;code&amp;gt;&amp;quot;map me&amp;quot;&amp;lt;/code&amp;gt; so that it won&#039;t be confused with the standard &amp;lt;code&amp;gt;&amp;quot;map&amp;quot;&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;map me&amp;quot;],&lt;br /&gt;
  &lt;br /&gt;
  _getMapUrl: function() {&lt;br /&gt;
    var loc = CmdUtils.getGeoLocation();&lt;br /&gt;
    var mapUrl = &amp;quot;http://maps.google.com/staticmap?&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    var params = {&lt;br /&gt;
      center: loc.lat + &amp;quot;,&amp;quot; + loc.long,&lt;br /&gt;
      size: &amp;quot;500x400&amp;quot;,&lt;br /&gt;
      zoom: 14,&lt;br /&gt;
      key: &amp;quot;ABQIAAAAGZ11mh1LzgQ8-8LRW3wEShQeSuJunOpTb3RsLsk00-MAdzxmXhQoiCd940lo0KlfQM5PeNYEPLW-3w&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    return mapUrl + jQuery.param( params );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &amp;quot;Inserts a map of your current location: &amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
              &amp;quot;&amp;lt;img src=&#039;${url}&#039;/&amp;gt;&amp;quot;;&lt;br /&gt;
    pblock.innerHTML = _(msg, {url: this._getMapUrl()});&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( ) {&lt;br /&gt;
    CmdUtils.getImageSnapshot( this._getMapUrl(), function(imgData) {&lt;br /&gt;
      CmdUtils.setSelection( &amp;quot;&amp;lt;img src=&#039;&amp;quot; + imgData +&amp;quot;&#039;/&amp;gt;&amp;quot;);&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are three new things here: &amp;lt;code&amp;gt;CmdUtils.setSelection&amp;lt;/code&amp;gt; to set HTML (yep, it can do that); the use of &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt;; and using &amp;lt;code&amp;gt;CmdUtils.snapshotImage()&amp;lt;/code&amp;gt; to capture the bits for the image.&lt;br /&gt;
&lt;br /&gt;
I find getting the location&amp;amp;mdash;as imprecise as IP-based location can be&amp;amp;mdash;useful for doing sensible defaults for location-based commands, like Yelp. &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; returns an object which has the following properties: city, state, country, lat, and long.&lt;br /&gt;
&lt;br /&gt;
Why do we need to use &amp;lt;code&amp;gt;CmdUtils.snapshotImage()&amp;lt;/code&amp;gt;? Because the Google Maps API requires a key that is tied to a particular URL. If we naively inject the image tag into a random web page, the image won&#039;t load because the key doesn&#039;t match that random web page&#039;s URL. Thus, we use the &amp;lt;code&amp;gt;snapshotImage()&amp;lt;/code&amp;gt; function to convert the image into a [http://en.wikipedia.org/wiki/Data:_URI_scheme data url].&lt;br /&gt;
&lt;br /&gt;
There&#039;s also a &amp;lt;code&amp;gt;CmdUtils.snapshotWindow&amp;lt;/code&amp;gt; function, which allows you to get the image data for any tab/window. The function takes a window as the first paramater, and a callback for the second.&lt;br /&gt;
&lt;br /&gt;
= Commands with Arguments =&lt;br /&gt;
&lt;br /&gt;
== Echo ==&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be working towards making some fun and useful commands&amp;amp;mdash;commands that let you control the seething tendrils of the internet with your little pinky. But, let&#039;s start by making a simple command to echo back whatever you type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;echo&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_arb_text,&lt;br /&gt;
               label: &amp;quot;your shout&amp;quot;}],&lt;br /&gt;
  preview: function( pblock, arguments ) {&lt;br /&gt;
    pblock.innerHTML = _(&amp;quot;Will echo: &amp;quot;) + arguments.object.text;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var msg = arguments.object.text + &amp;quot;... &amp;quot; + arguments.object.text + &amp;quot;......&amp;quot;;&lt;br /&gt;
    displayMessage( msg );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This says that the command &amp;quot;echo&amp;quot; takes one argument which is arbitrary text. Whatever text the user enters will get wrapped in an input object and passed into both the preview and execute function.&lt;br /&gt;
&lt;br /&gt;
Try it!  Ubiq &amp;quot;echo hellooooo&amp;quot; and watch what happens.&lt;br /&gt;
&lt;br /&gt;
Ubiquity takes care of parsing the user&#039;s input, so you don&#039;t need to worry about handling prounoun substitution or any of the other natural-language-like features of the Ubiquity parser. Try selecting some text on a page, and Ubiq &amp;quot;echo this&amp;quot;. Ubiquity should now echo the selected text.  &lt;br /&gt;
&lt;br /&gt;
Note that we gave three pieces of information when defining our argument:  its role, its nountype, and its label.  The label is the easiest part: It&#039;s just whatever text you want to have appear in the Ubiquity interface as a prompt for the user.  E.g, if you ubiq &amp;quot;echo&amp;quot;, you will see the label for the argument:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  echo (your shout)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The roles and the nountypes require some more explanation.  We&#039;ll cover each of them in detail next.&lt;br /&gt;
&lt;br /&gt;
=== Argument Roles ===&lt;br /&gt;
&lt;br /&gt;
Your command can take multiple arguments.  Each one is identified by a &amp;quot;role&amp;quot;.  To understand roles, it helps to think of your command name as a verb, and each argument as a noun.  Remember that Ubiquity&#039;s command line is a pseudo-natural-language environment, so it attempts to be as close to natural language grammar as possible.&lt;br /&gt;
&lt;br /&gt;
For example, if you&#039;ve ever used the &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; command, you know that it takes up to two arguments: a message and a person.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  email message&lt;br /&gt;
  email to person&lt;br /&gt;
  email message to person&lt;br /&gt;
  email to person message&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In grammatical terms, the message argument is the &amp;quot;direct object&amp;quot; of the verb &amp;quot;email&amp;quot;.  The person argument is an indirect object.  We call it the &amp;quot;goal&amp;quot; of the verb.  So if we were writing the email command, we&#039;d define the arguments like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_arb_text,&lt;br /&gt;
               label: &amp;quot;message&amp;quot;},&lt;br /&gt;
              {role: &amp;quot;goal&amp;quot;,&lt;br /&gt;
               nountype: noun_type_contact,&lt;br /&gt;
               label: &amp;quot;recipient&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we give the recipient argument the &amp;quot;goal&amp;quot; role, the Ubiquity parser knows to expect the user to type the word &amp;quot;to&amp;quot;.  When the user enters &amp;quot;email hello to Aza&amp;quot;, the parser knows that the word following &amp;quot;to&amp;quot; -- that is, &amp;quot;Aza&amp;quot; -- should be assigned to the recipient argument.&lt;br /&gt;
&lt;br /&gt;
In our simple &amp;quot;echo&amp;quot; command, we expect the user to type &amp;quot;echo hellooooo&amp;quot; or something like that.  The &amp;quot;hellooooo&amp;quot; is the direct object of the verb &amp;quot;echo&amp;quot;, so we give it the &amp;quot;object&amp;quot; role.  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Object&amp;quot; is the most common role.  If a command takes only one argument, that argument is usually an &amp;quot;object&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== What Roles Can I Use? ====&lt;br /&gt;
&lt;br /&gt;
* object   (in &amp;quot;echo helloooo&amp;quot;, hello is the object.)&lt;br /&gt;
* goal    (in &amp;quot;email this to brandon&amp;quot;, brandon is the goal.)&lt;br /&gt;
* source   (in &amp;quot;translate this from spanish&amp;quot;, spanish is the source.)&lt;br /&gt;
* location    (in &amp;quot;yelp pizza near boston&amp;quot;, boston is the location.)&lt;br /&gt;
* time    (in &amp;quot;book a flight on thursday&amp;quot;, thursday is the time.)&lt;br /&gt;
* instrument  (in &amp;quot;search monkeys with google&amp;quot;, google is the instrument.)&lt;br /&gt;
* format   (in &amp;quot;check weather in celsius&amp;quot;, celsius is the format.)&lt;br /&gt;
* modifier  (in &amp;quot;get email address for chris&amp;quot;, chris is the modifier.)&lt;br /&gt;
* alias   (in &amp;quot;twitter this as jono&amp;quot;, jono is the alias.)&lt;br /&gt;
&lt;br /&gt;
[https://wiki.mozilla.org/Labs/Ubiquity/Parser_2/Semantic_Roles More information about these roles].&lt;br /&gt;
&lt;br /&gt;
=== The Arguments Object ===&lt;br /&gt;
&lt;br /&gt;
When your execute method is called, it is passed a single object that encapsulates the values for all arguments.&lt;br /&gt;
&lt;br /&gt;
When your preview method is called, it is passed this object, too.&lt;br /&gt;
&lt;br /&gt;
The object has one attribute corresponding to each role.  In our example above, the command accepts only an object-role argument, so the preview and execute methods get passed an argument with an &amp;quot;arguments.object&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
If we made a command, like email, that takes an object-role argument and a goal-role argument, its preview and execute methods would get passed an argument with &amp;quot;arguments.object&amp;quot; and &amp;quot;arguments.goal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
arguments.object (or arguments.goal) has several attributes of its own:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments.object.text  // a string of the input in plain text, without formatting&lt;br /&gt;
  arguments.object.html  // a string of the input in formatted html, including tags&lt;br /&gt;
  arguments.object.data  // for non-text input types, an arbitrary data object&lt;br /&gt;
  arguments.object.summary // for very long inputs, an abbreviated display string&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our example command only cares about the &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; attribute of the input, because it simply wants plain text.  Often, when the user invokes your command by typing a few short words into the input box, &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.html&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; will all have exactly the same value, and &amp;lt;code&amp;gt;.data&amp;lt;/code&amp;gt; will be null.  Many, if not most, commands that you write will only care about the text value.  Nevertheless, the other versions of the input data are provided to you in case they differ from &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; and in case your command has a use for them.&lt;br /&gt;
&lt;br /&gt;
== Introduction to Noun Types ==&lt;br /&gt;
&lt;br /&gt;
Noun types specify what &#039;&#039;kind&#039;&#039; of input your command can accept for each one of its arguments.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;echo&amp;quot; command, we wanted the object-role argument to accept any text whatsoever, so for its nountype we passed in the predefined &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; object.  This object accepts any arbitrary text as a valid argument and passes it to the command unchanged.&lt;br /&gt;
&lt;br /&gt;
This is OK for very simple commands, like echoing back the user&#039;s input.  But for commands that take structured data, you will want to use more specific nountypes.&lt;br /&gt;
&lt;br /&gt;
For example, if a command can take a date (like the &amp;quot;check calendar&amp;quot; command), you would want to use &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; as the nountype of the argument.  &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; provides several benefits to your command:  it does all of the date parsing for you; it suggests dates that the user might want to enter (for instance, it defaults to today&#039;s date).  And, it lets the parser know that your command takes a date.  This is useful because when the user selects a date on a page and invokes Ubiquity, your command -- along with &amp;quot;check calendar&amp;quot; -- will be one of the top suggestions.&lt;br /&gt;
&lt;br /&gt;
You can write your own noun types -- we&#039;ll get into that later.  For now, let&#039;s take a look at the built-in nountypes that your command can use.  These include:&lt;br /&gt;
&lt;br /&gt;
* noun_arb_text (Arbitrary text)&lt;br /&gt;
* noun_type_language (Name of a human language, e.g. &amp;quot;English&amp;quot;, &amp;quot;Japanese&amp;quot;)&lt;br /&gt;
* noun_type_url (A URL)&lt;br /&gt;
* noun_type_contact (An email address from your address book)&lt;br /&gt;
* noun_type_date (A date, in any format, or a word like &amp;quot;tomorrow&amp;quot;)&lt;br /&gt;
* noun_type_time (A time, in any format)&lt;br /&gt;
* noun_type_percentage&lt;br /&gt;
* noun_type_address&lt;br /&gt;
* noun_type_tab&lt;br /&gt;
* noun_type_searchengine&lt;br /&gt;
* noun_type_tag&lt;br /&gt;
* noun_type_geolocation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with writing commands, you should check out the [http://hg.toolness.com/ubiquity-firefox/file/6caa9d66b3bb/ubiquity/chrome/content/nlparser/en/nountypes.js nountypes.js], which has the implementation for most of the noun-types.  You can see what noun types are already available for your commands to use, what still needs to be written, and where the existing implementations could use improvement &amp;amp;mdash; and then come [[Labs/Ubiquity#Participation|get involved]] to help us improve them.&lt;br /&gt;
&lt;br /&gt;
=== Regexps as Noun Types ===&lt;br /&gt;
&lt;br /&gt;
If none of the nountypes above is what you&#039;re looking for, there are several ways to define your own.  The simplest is to use a regular expression.  Suppose that (for whatever odd reason) you wanted your command to accept only arguments that begin with the letter N.  The following regexp matches words that start with N:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /^[nN]/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You could use it as a noun type, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: /^[nN]/,&lt;br /&gt;
               label: &amp;quot;word that starts with n&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note that you do &#039;&#039;not&#039;&#039; put quotes around the regexp.)&lt;br /&gt;
&lt;br /&gt;
A regexp nountype will reject input that doesn&#039;t match, but it doesn&#039;t know how to help the user by suggesting appropriate input.&lt;br /&gt;
&lt;br /&gt;
=== Lists as Noun Types ===&lt;br /&gt;
&lt;br /&gt;
Suppose you&#039;re writing a command that takes a color as an argument (perhaps it outputs a hexadecimal RGB representation of that color.)  To make a nountype that accepts colors, you can simply pass in an array of strings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  names: [&amp;quot;convert color&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: [&amp;quot;red&amp;quot;, &amp;quot;orange&amp;quot;, &amp;quot;yellow&amp;quot;, &amp;quot;green&amp;quot;, &lt;br /&gt;
                          &amp;quot;blue&amp;quot;, &amp;quot;violet&amp;quot;, &amp;quot;black&amp;quot;, &amp;quot;white&amp;quot;,&lt;br /&gt;
                          &amp;quot;grey&amp;quot;, &amp;quot;brown&amp;quot;, &amp;quot;beige&amp;quot;, &amp;quot;magenta&amp;quot;,&lt;br /&gt;
                          &amp;quot;cerulean&amp;quot;, &amp;quot;puce&amp;quot;],&lt;br /&gt;
               label: &amp;quot;color to convert&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One benefit of using a list is that the parser can use it offer the user suggestions.   If the user enters &amp;quot;get-color bl&amp;quot;, for instance, Ubiquity will be able to suggest &amp;quot;black&amp;quot; and &amp;quot;blue&amp;quot; as the two valid completions based on the input.  This makes list-based nountypes very useful for any command that can accept only a finite set of values.&lt;br /&gt;
&lt;br /&gt;
=== Writing a Noun Type Object ===&lt;br /&gt;
&lt;br /&gt;
Of course, not every type of noun you&#039;d be interested in can be represented&lt;br /&gt;
as a finite list or as a regexp.  If you want to be able to accept or reject input based on some algorithmic test, you can do so by writing a custom JavaScript object that implements a &amp;lt;code&amp;gt;suggest()&amp;lt;/code&amp;gt; method (and, optionally, a &amp;lt;code&amp;gt;default()&amp;lt;/code&amp;gt; method.)&lt;br /&gt;
&lt;br /&gt;
There is an example of how to do this in the section on the tab commands, below.&lt;br /&gt;
&lt;br /&gt;
== Insert Email: the Contact noun type ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s take a look at one of the built-in noun-types: &amp;lt;code&amp;gt;noun_type_contact&amp;lt;/code&amp;gt;. This lets Ubiquity know to expect a person (either by name or email address). By using the noun-type, Ubiquity will also autocomplete to known people while the user is entering the command. This is what the built-in Ubiquity command &amp;quot;email&amp;quot; uses.&lt;br /&gt;
&lt;br /&gt;
At the moment, Ubiquity figures out what people you know through reading your Gmail contacts. In this prototyped version, you&#039;ll need to use Gmail and be logged in for for Ubiquity to know who you know. Eventually, we&#039;d like to be able to interface with all major web-mail sites, as well as desktop software like Thunderbird.&lt;br /&gt;
&lt;br /&gt;
Enough rambling. It&#039;s time for a command. I constantly find that I need to fetch someone&#039;s email address to paste into a text field because I don&#039;t know it off-hand. This command solves that by letting you insert someone&#039;s email address using autocomplete.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert email&amp;quot;],&lt;br /&gt;
  arguments: {modifier: noun_type_contact},&lt;br /&gt;
  preview: &amp;quot;Inserts someone&#039;s email address by name.&amp;quot;,&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    CmdUtils.setSelection( arguments.modifier.text );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To try this out, Ubiq &amp;quot;insert email for &amp;quot; and then the first few letters of someone you email often.&lt;br /&gt;
&lt;br /&gt;
=== Shorter Argument Declarations ===&lt;br /&gt;
&lt;br /&gt;
Notice that we used a shortcut for declaring the arguments.  In the long form, we would have had to say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;modifier&amp;quot;,&lt;br /&gt;
               nountype: noun_type_contact,&lt;br /&gt;
               label: &amp;quot;contact&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
but if we don&#039;t care about specifying a label for the argument, we can get away with using a single object for &amp;quot;arguments&amp;quot;, with the roles as the property names, and the nountypes as the property values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: {modifier: noun_type_contact}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we had several arguments, and none of them needed labels, we could say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: {object: noun_arb_text, modifier: noun_type_contact}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and so on.&lt;br /&gt;
&lt;br /&gt;
Aza writes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
This one command sums up what I love about Ubiquity. In 8 lines of code, I can &lt;br /&gt;
fundamentally enhance the browser&#039;s functionality. Doing the same thing using &lt;br /&gt;
a normal Firefox extension methodology takes pages and pages of code&amp;amp;mdash;and  the interface would take more thought still. Doing the same thing using a bookmarklet would require a server-side component (to get around cross-site Ajax request ban) as well as forcing the user to give up their email password.&lt;br /&gt;
&lt;br /&gt;
Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TinyURL: Network Calls and jQuery (and the URL noun type)==&lt;br /&gt;
&lt;br /&gt;
Often while writing emails, I&#039;ll discover that I&#039;ve pasted in a URL long enough to be used for unfortunate analogies. I&#039;d like to be able to quickly turn that into a [http://en.wikipedia.org/wiki/Tinyurl TinyURL]&amp;amp;mdash;but the process of making a TinyURL involves lots of fiddly steps. Ubiquity to the rescue.&lt;br /&gt;
&lt;br /&gt;
Because we include [http://en.wikipedia.org/wiki/jQuery jQuery] with Ubiquity, it is simple to perform Ajax calls as well as parse returning data. TinyUrl.com provides an easy to use RESTful API where you pass a URL and it returns its shortened form. We use that API in this command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;tinyurl&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_type_url,&lt;br /&gt;
               label: &amp;quot;url to shorten&amp;quot;}],&lt;br /&gt;
  preview: &amp;quot;Replaces the selected URL with a TinyUrl.&amp;quot;,&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var baseUrl = &amp;quot;http://tinyurl.com/api-create.php&amp;quot;;&lt;br /&gt;
    var params = {url: arguments.object.text};&lt;br /&gt;
    jQuery.get( baseUrl, params, function( tinyUrl ) {&lt;br /&gt;
      CmdUtils.setSelection( tinyUrl );&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;noun_type_url&amp;lt;/code&amp;gt; is a useful nountype because it defaults to the URL of the page that you are currently on.  If that is in fact the URL that the user wants, then they don&#039;t have to type it or even select it.&lt;br /&gt;
&lt;br /&gt;
jQuery is a powerful tool. With it, you can fairly effortlessly cherry-pick the data you need from RSS feeds, XML, and all sorts of other data formats. It also makes doing in-preview animations a breeze.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Twitter: Putting It All Together =&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now covered everything we need to cover in order to write a command that allows us to [http://en.wikipedia.org/wiki/Twitter Twitter] from Ubiquity.  The code below is the actual source code of the Twitter command as it appears in Ubiquity 0.5.&lt;br /&gt;
&lt;br /&gt;
Many thanks to [http://theunfocused.net/moz/ubiquity/verbs/ Blair McBride] for writing this command.  The source code is a bit more intricate than anything we&#039;ve seen so far, but it&#039;s built using exactly the same basic pieces -- and demonstrates nearly all of those pieces in action.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const TWITTER_STATUS_MAXLEN = 140;&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;twitter&amp;quot;, &amp;quot;tweet&amp;quot;, &amp;quot;share using twitter&amp;quot;],&lt;br /&gt;
  arguments: [&lt;br /&gt;
    {role: &amp;quot;object&amp;quot;, label: &#039;status&#039;, nountype: noun_arb_text},&lt;br /&gt;
    {role: &amp;quot;alias&amp;quot;, nountype: noun_type_twitter_user}&lt;br /&gt;
  ],&lt;br /&gt;
  icon: &amp;quot;http://twitter.com/favicon.ico&amp;quot;,&lt;br /&gt;
  description:&lt;br /&gt;
  &amp;quot;Sets your Twitter status to a message of at most 160 characters.&amp;quot;,&lt;br /&gt;
  help: (&amp;quot;You&#039;ll need a &amp;lt;a href=\&amp;quot;http://twitter.com\&amp;quot;&amp;gt;Twitter account&amp;lt;/a&amp;gt;,&amp;quot; +&lt;br /&gt;
         &amp;quot; obviously.  If you&#039;re not already logged in&amp;quot; +&lt;br /&gt;
         &amp;quot; you&#039;ll be asked to log in.&amp;quot;),&lt;br /&gt;
  preview: function(previewBlock, args) {&lt;br /&gt;
    var statusText = (args.object ? args.object.text : &#039;&#039;);&lt;br /&gt;
    var usernameText = &amp;quot;&amp;quot;;&lt;br /&gt;
    if (args.alias) {&lt;br /&gt;
      usernameText = args.alias.text;&lt;br /&gt;
    } else if (args.as) {&lt;br /&gt;
      usernameText = args.as.text;&lt;br /&gt;
    }&lt;br /&gt;
    var previewTemplate = (&lt;br /&gt;
      &amp;quot;&amp;lt;div class=&#039;twitter&#039;&amp;gt;&amp;quot;+_(&amp;quot;Updates your Twitter status ${username} to:&amp;quot;)+&amp;quot;&amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
      &amp;quot;&amp;lt;b class=&#039;status&#039;&amp;gt;${status}&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
      _(&amp;quot;Characters remaining: &amp;lt;b&amp;gt;${chars}&amp;lt;/b&amp;gt;&amp;quot;) +&lt;br /&gt;
      &amp;quot;&amp;lt;p&amp;gt;&amp;lt;small&amp;gt;&amp;quot;+_(&amp;quot;tip: tweet @mozillaubiquity for help&amp;quot;)+&amp;quot;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
    var truncateTemplate = (&lt;br /&gt;
      &amp;quot;&amp;lt;strong&amp;gt;&amp;quot;+_(&amp;quot;The last &amp;lt;b&amp;gt;${truncate}&amp;lt;/b&amp;gt; characters will be truncated!&amp;quot;)+&amp;quot;&amp;lt;/strong&amp;gt;&amp;quot;);&lt;br /&gt;
    var previewData = {&lt;br /&gt;
      status: &amp;lt;&amp;gt;{statusText}&amp;lt;/&amp;gt;.toXMLString(),&lt;br /&gt;
      username: usernameText &amp;amp;&amp;amp; _(&amp;quot;(For user &amp;lt;b&amp;gt;${usernameText}&amp;lt;/b&amp;gt;)&amp;quot;),&lt;br /&gt;
      chars: TWITTER_STATUS_MAXLEN - statusText.length&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var previewHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                        CmdUtils.renderTemplate(previewTemplate, previewData),&lt;br /&gt;
                        {usernameText:usernameText});&lt;br /&gt;
&lt;br /&gt;
    if (previewData.chars &amp;lt; 0) {&lt;br /&gt;
      var truncateData = {&lt;br /&gt;
        truncate: 0 - previewData.chars&lt;br /&gt;
      };&lt;br /&gt;
&lt;br /&gt;
      previewHTML += CmdUtils.renderTemplate(truncateTemplate, truncateData);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    previewBlock.innerHTML = previewHTML;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(args) {&lt;br /&gt;
    var statusText = args.object.text;&lt;br /&gt;
    if(statusText.length &amp;lt; 1) {&lt;br /&gt;
      this._show(_(&amp;quot;requires a status to be entered&amp;quot;));&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var updateUrl = &amp;quot;https://twitter.com/statuses/update.json&amp;quot;;&lt;br /&gt;
    var updateParams = {&lt;br /&gt;
      source: &amp;quot;ubiquity&amp;quot;,&lt;br /&gt;
      status: statusText&lt;br /&gt;
      //dont cut the input since sometimes, the user selects a big url,&lt;br /&gt;
      //and the total lenght is more than 140, but tinyurl takes care of that&lt;br /&gt;
    };&lt;br /&gt;
    var me = this;&lt;br /&gt;
&lt;br /&gt;
    function sendMessage() {&lt;br /&gt;
      jQuery.ajax({&lt;br /&gt;
        type: &amp;quot;POST&amp;quot;,&lt;br /&gt;
        url: updateUrl,&lt;br /&gt;
        data: updateParams,&lt;br /&gt;
        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
        error: function() {&lt;br /&gt;
          me._show(_(&amp;quot;error - status not updated&amp;quot;));&lt;br /&gt;
        },&lt;br /&gt;
        success: function() {&lt;br /&gt;
          me._show(/^d /.test(statusText)&lt;br /&gt;
                   ? _(&amp;quot;direct message sent&amp;quot;)&lt;br /&gt;
                   : _(&amp;quot;status updated&amp;quot;));&lt;br /&gt;
        },&lt;br /&gt;
        username: login.username,&lt;br /&gt;
        password: login.password&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var login;&lt;br /&gt;
    var alias = args.alias;&lt;br /&gt;
    if (alias &amp;amp;&amp;amp; alias.text &amp;amp;&amp;amp; alias.data) {&lt;br /&gt;
      login = alias.data;&lt;br /&gt;
      sendMessage();&lt;br /&gt;
    } else {&lt;br /&gt;
      login = {username: null,&lt;br /&gt;
               password: null};&lt;br /&gt;
      if (alias &amp;amp;&amp;amp; alias.text)&lt;br /&gt;
        login.username = alias.text;&lt;br /&gt;
      sendMessage();&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  _show: function(txt){&lt;br /&gt;
    displayMessage({icon: this.icon, title: this.name, text: txt});&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Switching Tabs =&lt;br /&gt;
&lt;br /&gt;
The final command in this tutorial is for switching between tabs. The end goal is this: type a few keys to that matches the title of an open tab (in any window), hit return, and you&#039;ve switched to that tab.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll write this command in two steps. The first step is creating a tab noun-type. The second step is using that noun-type to create the tab-switching command.&lt;br /&gt;
&lt;br /&gt;
== Switching: Writing your own Noun-Types ==&lt;br /&gt;
&lt;br /&gt;
A noun-type needs to only have two things: A &amp;lt;code&amp;gt;label&amp;lt;/code&amp;gt; and a &amp;lt;code&amp;gt;suggest()&amp;lt;/code&amp;gt; function.  It can optionally also have a &amp;lt;code&amp;gt;default()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
The label is what shows up when the command prompts for input. Suggest returns a list of input objects, each one containing the name of a matching tab. We&#039;re using [http://developer.mozilla.org/en/docs/FUEL FUEL] to interact with the browser, which is where the &amp;quot;Application&amp;quot; variable comes from.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_tab = {&lt;br /&gt;
  label: &amp;quot;tab name&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  // Returns all tabs from all windows.&lt;br /&gt;
  getTabs: function(){&lt;br /&gt;
    var tabs = {};&lt;br /&gt;
&lt;br /&gt;
    for( var j=0; j &amp;lt; Application.windows.length; j++ ) {&lt;br /&gt;
      var window = Application.windows[j];&lt;br /&gt;
      for (var i = 0; i &amp;lt; window.tabs.length; i++) {&lt;br /&gt;
        var tab = window.tabs[i];&lt;br /&gt;
        tabs[tab.document.title] = tab;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return tabs;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  suggest: function( text, html, callback ) {&lt;br /&gt;
    &lt;br /&gt;
    var suggestions  = [];&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
&lt;br /&gt;
    //TODO: implement a better match algorithm&lt;br /&gt;
    for ( var tabName in tabs ) {&lt;br /&gt;
      if (tabName.match(text, &amp;quot;i&amp;quot;))&lt;br /&gt;
	 suggestions.push( CmdUtils.makeSugg(tabName) );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Return a list of input objects, limited to at most five:&lt;br /&gt;
    return suggestions.splice(0, 5);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The suggest method of a noun type always gets passed both text and html.  If the input is coming from a part of a web page that the user has selected, these&lt;br /&gt;
values can be different: they are both strings, but the html value contains markup tags while the text value does not. The Tab noun type only cares about the plain text of the tab name, so we ignore the value of html.&lt;br /&gt;
&lt;br /&gt;
The callback argument is for use by nountypes that need to run asynchronously, i.e. becaus they need to do network calls to generate suggestions.  The callback is a function; instead of returning a list of suggestions right away, an asynchronous noun type can call the callback with each suggestion it generates.  More on this later; the tab noun type generates all its suggestions right away, so it just returns them instead of using the callback.&lt;br /&gt;
&lt;br /&gt;
We use the convenience function &amp;lt;code&amp;gt;CmdUtils.makeSugg()&amp;lt;/code&amp;gt; to generate an&lt;br /&gt;
input object of the type that the Ubiquity parser expects.  The full signature of this function is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.makeSugg( text, html, data );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
but html and data are optional and need be provided only if they differ from text.&lt;br /&gt;
&lt;br /&gt;
If the text or html input is very long, &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; generates a summary for us, and puts it in the &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; attribute of the input object.&lt;br /&gt;
&lt;br /&gt;
We could have accomplished mostly the same thing without calling &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; by returning a list of anonymous objects like these:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ text: tabName,&lt;br /&gt;
  html: tabName,&lt;br /&gt;
  data: null,&lt;br /&gt;
  summary: tabName };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The input objects that our &amp;lt;code&amp;gt;.suggest()&amp;lt;/code&amp;gt; method generates are the same objects that will eventually get passed in to the &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; methods of any commands that use this noun type.&lt;br /&gt;
&lt;br /&gt;
== Switching Tabs: The Command ==&lt;br /&gt;
&lt;br /&gt;
Now that we are armed with the tab noun-type, it is easy to make the tab-switching command. Again, we use FUEL to focus the selected tab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;tab&amp;quot;],&lt;br /&gt;
  arguments: {object: noun_type_tab},&lt;br /&gt;
&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var tabName = arguments.object.text;&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
    tabs[tabName]._window.focus();&lt;br /&gt;
    tabs[tabName].focus();&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  preview: function( pblock, arguments ) {&lt;br /&gt;
    var tabName = arguments.object.text;&lt;br /&gt;
    if( tabName.length &amp;gt; 1 ){&lt;br /&gt;
        var msg = &amp;quot;Changes to &amp;lt;b style=\&amp;quot;color:yellow\&amp;quot;&amp;gt;${tab}&amp;lt;/b&amp;gt; tab.&amp;quot;;&lt;br /&gt;
        pblock.innerHTML = _(msg, {tab: tabName});&lt;br /&gt;
     }&lt;br /&gt;
    else&lt;br /&gt;
      pblock.innerHTML = _(&amp;quot;Switch to a tab by name.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Development Hints =&lt;br /&gt;
&lt;br /&gt;
You now know all you need to know to get started developing useful Ubiquity commands of your own.&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous tips that didn&#039;t fit elsewhere on this page, that may make development easier for you.&lt;br /&gt;
&lt;br /&gt;
== The Source Code of Built-In Commands ==&lt;br /&gt;
&lt;br /&gt;
Looking at the source code of built-in commands and built-in noun types can be a very useful aid to development.  If you have the source checkout of Ubiquity (see [Labs/Ubiquity/Ubiquity_0.1_Development_Tutorial | the development tutorial] to find out how to get this), the source code can be found in the files:&lt;br /&gt;
&lt;br /&gt;
 ubiquity/standard-feeds/&lt;br /&gt;
 ubiquity/builtin-feeds/en/builtincmds.js&lt;br /&gt;
 ubiquity/modules/nountypes.js&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a checkout of the source code, you can view the latest version on the web here:&lt;br /&gt;
&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/standard-feeds/ standard-feeds]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/builtin-feeds/en/builtincmds.js builtincmds.js]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/modules/nountypes.js nountypes.js]&lt;br /&gt;
&lt;br /&gt;
== Interacting with Other Extensions ==&lt;br /&gt;
&lt;br /&gt;
http://img363.imageshack.us/img363/1906/picture7cm5.png&lt;br /&gt;
&lt;br /&gt;
There isn&#039;t much to say here besides that it&#039;s easy. For example, here&#039;s a command (thanks to [http://foyrek.com/lyrics.html Abimanyu Raja] for writing this code) that finds the lyrics for a song. You can simply Ubiq something like &amp;quot;get lyrics for wild international&amp;quot; but the command will also interface with the FoxyTunes extension (if it is installed) and add the currently playing song to the suggestion list. Interfacing with other extensions, too, is easy because you can view the source code for every Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_song = {&lt;br /&gt;
  label: &amp;quot;song name&amp;quot;,&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    var suggestions  = [CmdUtils.makeSugg(text)];&lt;br /&gt;
    if(window.foxytunesGetCurrentTrackTitle){&lt;br /&gt;
   suggestions.push(CmdUtils.makeSugg(window.foxytunesGetCurrentTrackTitle()));&lt;br /&gt;
  	}&lt;br /&gt;
    return suggestions;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;get lyrics&amp;quot;],&lt;br /&gt;
  arguments: {modifier: noun_type_song},&lt;br /&gt;
  preview: function(pblock, arguments) {&lt;br /&gt;
    &lt;br /&gt;
    searchText = jQuery.trim(arguments.modifier.text);&lt;br /&gt;
    if(searchText.length &amp;lt; 1) {&lt;br /&gt;
      pblock.innerHTML = _(&amp;quot;Searches for lyrics of the song&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var previewTemplate = &amp;quot;Searches for the lyrics of &amp;lt;b&amp;gt;${query}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    pblock.innerHTML = _(previewTemplate, {query: searchText});&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(arguments) {&lt;br /&gt;
    var url = &amp;quot;http://www.google.com/search?q={QUERY}&amp;quot;&lt;br /&gt;
    var query = arguments.object.text + _(&amp;quot; lyrics&amp;quot;);&lt;br /&gt;
    var urlString = url.replace(&amp;quot;{QUERY}&amp;quot;, query);&lt;br /&gt;
    Utils.openUrlInBrowser(urlString);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementing Asynchronous Noun Suggestions ==&lt;br /&gt;
&lt;br /&gt;
The noun types we&#039;ve seen so far in this tutorial have all worked synchronously, returning their suggestions right away. However, Ubiquity also supports asynchronous noun suggestions. These are useful for when a noun type needs to do some potentially time-consuming work before it can make suggestions &amp;amp;mdash; most commonly when it needs to call an external service.&lt;br /&gt;
&lt;br /&gt;
Implementing asynchronous suggestions is simple. Whenever the Ubiquity parser calls a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function, it includes a callback function that may be used to send suggestions back to the parser as they become available. In the most typical case, the noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function makes an AJAX request, invoking the parser&#039;s callback function from within the callback function for the AJAX request.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example: a noun type that suggests [http://www.freebase.com/ Freebase] topics based on the text the user has typed or selected, and a barebones &amp;lt;code&amp;gt;freebase-lookup&amp;lt;/code&amp;gt; command that uses the noun type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_freebase_topic = {&lt;br /&gt;
  name: &amp;quot;Freebase topic&amp;quot;,&lt;br /&gt;
  label: &amp;quot;topic&amp;quot;,&lt;br /&gt;
  suggest: function freebase_topic_suggest(text, html, callback) {&lt;br /&gt;
    return [&lt;br /&gt;
      CmdUtils.makeSugg(text),&lt;br /&gt;
      $.ajax({&lt;br /&gt;
        url: &amp;quot;http://www.freebase.com/api/service/search&amp;quot;,&lt;br /&gt;
        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
        data: {prefix: text, limit: 5},&lt;br /&gt;
        success: function suggestTopics(response) {&lt;br /&gt;
          if (response.status === &amp;quot;200 OK&amp;quot;)&lt;br /&gt;
            callback([CmdUtils.makeSugg(result.name, result.name, result)&lt;br /&gt;
                      for each (result in response.result)]);&lt;br /&gt;
        },&lt;br /&gt;
      })];&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;lookup on freebase&amp;quot;],&lt;br /&gt;
  arguments: {object: noun_type_freebase_topic},&lt;br /&gt;
  preview: function preview(pblock, args) {&lt;br /&gt;
    pblock.innerHTML = _((&amp;quot;Go to the Freebase topic page for &amp;quot; +&lt;br /&gt;
                          &amp;quot;{if text}${text}{else}any topic{/if}.&amp;quot;),&lt;br /&gt;
                         args.object);&lt;br /&gt;
  },&lt;br /&gt;
  execute: function goToFreebase({object: {text, data}}) {&lt;br /&gt;
    Utils.openUrlInBrowser(&lt;br /&gt;
      text&lt;br /&gt;
      ? (data&lt;br /&gt;
         ? &amp;quot;http://www.freebase.com/view&amp;quot; + data.id&lt;br /&gt;
         : (&amp;quot;http://www.freebase.com/search?query=&amp;quot; +&lt;br /&gt;
            encodeURIComponent(text)))&lt;br /&gt;
      : &amp;quot;http://www.freebase.com/&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A few notes:&lt;br /&gt;
&lt;br /&gt;
* The parser&#039;s callback function expects only one suggestion (not an array of suggestions), so it must be called one time for each suggestion, even if the noun type has multiple suggestions available at the same time (as in the Freebase example above). This is a bit different from the synchronous case, in which the &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function is expected to return an array.&lt;br /&gt;
* A noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function typically returns an empty array when it intends to make asynchronous suggestions, but it can return one or more suggestions synchronously if it has them available.&lt;br /&gt;
* Because the work being done to generate asynchronous suggestions is generally somewhat expensive, and because a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function may be called for every keystroke the user makes, you should probably consider implementing a delay before starting the work and/or caching the work at some level. Ubiquity currently leaves this up to each noun type individually.&lt;br /&gt;
* A much more robust implementation of Freebase-derived noun types can be found [http://graynorton.com/ubiquity/freebase-nouns.html here].&lt;br /&gt;
&lt;br /&gt;
== Running on page load and startup ==&lt;br /&gt;
&lt;br /&gt;
Commands aren&#039;t the only thing you can put in a command feed.  You can also include functions you want to be run automatically at page-load time and at Firefox startup time.&lt;br /&gt;
&lt;br /&gt;
In order to run some code on page load, you simply have to prefix your function with &amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;. For example, if you want to say &amp;quot;Hi&amp;quot; every time a page is loaded, your code would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function pageLoad_hi(){&lt;br /&gt;
 displayMessage(&amp;quot;hi&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you modify the function and want to see the changes, remember to first invoke Ubiquity. Although your function like above, might not be a Ubiquity command, this is necessary to refresh the cached code.&lt;br /&gt;
&lt;br /&gt;
Similarly, if you want to run some code everytime Firefox starts up, you just have to prefix the function with &amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
The awesome thing about these functions is the ability to develop whole Firefox extensions (that require minimal UI) as Ubiquity plugins in lesser lines of code. You don&#039;t need to worry about chrome.manifest or install.rdf. Another added benefit is that you never have to restart your Firefox during development unless of course, you are running code on Firefox startup.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;http://img388.imageshack.us/img388/3086/picture5eo9.png&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code for [http://foyrek.com/keyscape.js Keyscape] which is a Ubiquity command that makes use of &amp;lt;code&amp;gt;pageLoad&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;startup&amp;lt;/code&amp;gt; to recreate the functionality of the [https://addons.mozilla.org/en-US/firefox/addon/339 Search Keys extension] by Jesse Ruderman. In line with Ubiquity&#039;s aim to let you do things quicker using your keyboard, this command lets you go to search results on Google by just pressing a number. It&#039;ll add hints to show the number of each link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//A lot of this code is borrowed from the Search Keys extension&lt;br /&gt;
//Many thanks to Jeese Ruderman&lt;br /&gt;
&lt;br /&gt;
function startup_keyscape() {&lt;br /&gt;
  window.addEventListener(&amp;quot;keydown&amp;quot;, keyscape_down, true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function pageLoad_keyscape(doc){&lt;br /&gt;
&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
  //If we are on about: or chrome://, just return&lt;br /&gt;
  if(uri.scheme != &amp;quot;http&amp;quot;)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  //Check if the page we are on is google&lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	      		    &lt;br /&gt;
    for(var num=1; num&amp;lt;=10; num++){&lt;br /&gt;
&lt;br /&gt;
      var link = jQuery(doc.body).find(&#039;a.l&#039;)[num-1];&lt;br /&gt;
      &lt;br /&gt;
      if( link ){&lt;br /&gt;
&lt;br /&gt;
        var hint = doc.createElementNS(&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;, &amp;quot;span&amp;quot;);&lt;br /&gt;
        hint.style.color = &amp;quot;blue&amp;quot;;&lt;br /&gt;
        hint.style.background = &amp;quot;white&amp;quot;;&lt;br /&gt;
        hint.style.padding = &amp;quot;1px 2px 1px 2px&amp;quot;;&lt;br /&gt;
        hint.style.marginLeft = &amp;quot;.5em&amp;quot;;&lt;br /&gt;
        hint.appendChild(doc.createTextNode(num == 10 ? 0 : num));&lt;br /&gt;
        link.parentNode.insertBefore(hint, link.nextSibling);&lt;br /&gt;
      }  		&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_isGoogle(uri){&lt;br /&gt;
  return uri.host.indexOf(&amp;quot;google&amp;quot;) != -1 &lt;br /&gt;
	 &amp;amp;&amp;amp; (uri.path.substr(0,8) == &amp;quot;/search?&amp;quot; &lt;br /&gt;
         || uri.path.substr(0,8) == &amp;quot;/custom?&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_down(event){&lt;br /&gt;
&lt;br /&gt;
  var doc =  Application.activeWindow.activeTab.document;	&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
 &lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	&lt;br /&gt;
   var key = parseInt(event.keyCode || event.charCode);	&lt;br /&gt;
   var num;&lt;br /&gt;
	&lt;br /&gt;
   if(48 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 57) //number keys&lt;br /&gt;
     num = key - 48;&lt;br /&gt;
   else if(96 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 105) //numeric keypad with numlock on&lt;br /&gt;
     num = key - 96;&lt;br /&gt;
   else&lt;br /&gt;
     return;&lt;br /&gt;
&lt;br /&gt;
   //Don&#039;t do anything if we are in a textbox&lt;br /&gt;
   //or some other related elements&lt;br /&gt;
   var elt = window.document.commandDispatcher.focusedElement;&lt;br /&gt;
   &lt;br /&gt;
   if (elt) {&lt;br /&gt;
     var ln = new String(elt.localName).toLowerCase();&lt;br /&gt;
     if (ln == &amp;quot;input&amp;quot; || ln == &amp;quot;textarea&amp;quot; || ln == &amp;quot;select&amp;quot; || ln == &amp;quot;isindex&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
   //Get the link url from the search results page&lt;br /&gt;
   var url_dest = jQuery(doc.body).find(&#039;a.l&#039;).eq(num-1).attr(&#039;href&#039;);&lt;br /&gt;
   &lt;br /&gt;
   if(event.altKey){&lt;br /&gt;
     //Open in new tab&lt;br /&gt;
     Application.activeWindow.open(Utils.url(url_dest));&lt;br /&gt;
   }else{&lt;br /&gt;
     //Open in same tab&lt;br /&gt;
     doc.location.href = url_dest;&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If Ubiquity does indeed become ubiquitous, a lot of extensions can be re-written as Ubiquity commands. This is much nicer for the end-user, as well, because the Ubiquity command installation process is a lot easier.&lt;br /&gt;
&lt;br /&gt;
In the future, Ubiquity is also likely to have the ability to convert your Ubiquity commands into proper Firefox extensions. Look [http://labs.toolness.com/trac/ticket/3 here] to check on the progress of this functionality.&lt;br /&gt;
&lt;br /&gt;
== Firebug ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity automatically enables Chrome Errors and Warnings on startup so that errors in your code appear in the Firebug console. Just use &amp;lt;tt&amp;gt;CmdUtils.log()&amp;lt;/tt&amp;gt; rather than &amp;lt;tt&amp;gt;console.log()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Where To Go From Here =&lt;br /&gt;
&lt;br /&gt;
Take a look at Ubiquity&#039;s reference documentation for the &amp;lt;tt&amp;gt;[https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html#modules/utils.js Utils]&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;[https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html#modules/cmdutils.js CmdUtils]&amp;lt;/tt&amp;gt; namespaces.&lt;br /&gt;
&lt;br /&gt;
If you have any questions or comments, feel free to join us on IRC at &amp;lt;tt&amp;gt;#ubiquity&amp;lt;/tt&amp;gt; on &amp;lt;tt&amp;gt;irc.mozilla.org&amp;lt;/tt&amp;gt;, as well as the [http://groups.google.com/group/ubiquity-firefox Ubiquity Google Group].&lt;br /&gt;
&lt;br /&gt;
= Conclusion =&lt;br /&gt;
&lt;br /&gt;
To reiterate a point I made before: Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web. You are one of those agents.&lt;br /&gt;
&lt;br /&gt;
Now, go forth and create.&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.5_Author_Tutorial&amp;diff=154568</id>
		<title>Labs/Ubiquity/Ubiquity 0.5 Author Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.5_Author_Tutorial&amp;diff=154568"/>
		<updated>2009-07-10T23:14:13Z</updated>

		<summary type="html">&lt;p&gt;Endolith: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
Author: Aza Raskin, Blair McBride, Abimanyu Raja, Jono DiCarlo, Atul Varma&lt;br /&gt;
&lt;br /&gt;
= The Ubiquity version 0.5 Command Tutorial =&lt;br /&gt;
&lt;br /&gt;
The great power of Ubiquity&amp;amp;mdash;from a developer standpoint&amp;amp;mdash;is how easy it is to create commands. With only a couple of lines of Javascript, Ubiquity enables even casual web developers to drastically enhance the features of the browser. From an 8-line command to insert a contact&#039;s email address in any text field, to a 50-line Twitter integration, this tutorial walks you through the process of being generative with Ubiquity.&lt;br /&gt;
&lt;br /&gt;
The rest of this page documents the command developer API as it stands frozen in version 0.5.&lt;br /&gt;
&lt;br /&gt;
If you want the bleeding-edge command developer API (which includes any new features that may have been added to the Ubiquity source code in HG but not yet included in a release), then that&#039;s [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|here]].&lt;br /&gt;
&lt;br /&gt;
If you want the old command developer API, as it stood in Ubiquity 0.1 (not recommended), that&#039;s [[Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial|here]].&lt;br /&gt;
&lt;br /&gt;
== Real Time Development ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t require you to restart Firefox as you develop. Restarting is a drastic measure, and we want none of it. Instead, Ubiquity reloads the commands every time it is summoned. When you are using the built-in editor then you don&#039;t even need to save!&lt;br /&gt;
&lt;br /&gt;
To open the Ubiquity command editor, summon Ubiquity (control/alt + space) and use the &amp;quot;open command editor&amp;quot; command. Throughout this tutorial, when we want you to run a command in Ubiquity, we&#039;ll say &#039;&#039;&#039;Ubiq&#039;&#039;&#039; it. For instance, to open the editor, just Ubiq &amp;quot;open command editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the following examples, just type in this editor. Updates happen the next time you summon Ubiquity.&lt;br /&gt;
&lt;br /&gt;
== Choices, Choices... ==&lt;br /&gt;
&lt;br /&gt;
You may notice a drop-down menu mentioning something about a &amp;quot;feed type&amp;quot; just above the editing field in the command editor:&lt;br /&gt;
&lt;br /&gt;
http://www.toolness.com/images/20090318121423.jpg&lt;br /&gt;
&lt;br /&gt;
For now, just make sure this drop-down is set to &amp;quot;Regular&amp;quot;.  We&#039;ll tell you more about what this means later.&lt;br /&gt;
&lt;br /&gt;
= Hello World: The First Command =&lt;br /&gt;
&lt;br /&gt;
== Just a Message: As Simple as it Gets ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s start with the standard programing trope: printing &amp;quot;Hello, World!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the command editor type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now try Ubiq-ing &amp;quot;say hello&amp;quot;. You&#039;ll see that &amp;quot;Hello, World!&amp;quot; is immediately displayed on the screen. If you are on Mac OSX with [http://en.wikipedia.org/wiki/Growl_(software) Growl] installed the message will appear as a Growl notification. If you are on Windows, then it will appears as a standard &amp;quot;toaster&amp;quot; notification in the bottom right-hand corner of the screen.&lt;br /&gt;
&lt;br /&gt;
http://farm3.static.flickr.com/2479/3651542339_022e4aa4c4.jpg&lt;br /&gt;
&lt;br /&gt;
http://img517.imageshack.us/img517/7726/picture2vx2.png&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 8.04 (Hardy Heron) this appears thus:&lt;br /&gt;
&lt;br /&gt;
http://img293.imageshack.us/img293/7746/ubiqubuntuhelloworldeq9.png&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have Growl installed on OSX, or aren&#039;t on a Windows XP/Vista or Ubuntu Hardy, then you won&#039;t get any sort of notification. That&#039;s something to be [http://labs.toolness.com/trac/ticket/19 worked on] in future releases of Ubiquity.&lt;br /&gt;
&lt;br /&gt;
=== CmdUtils.CreateCommand ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CmdUtils&amp;lt;/code&amp;gt; is a namespace which contains all the functions you need to create commands.  Commands are created by making an object and passing it to &amp;lt;code&amp;gt;CmdUtils.CreateCommand&amp;lt;/code&amp;gt;.  In Javascript, inline curly braces mean &amp;quot;new object&amp;quot;, so this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
   names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
   execute: function() { //etc }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
means &amp;quot;Make an object with two attributes, &#039;names&#039; and &#039;execute&#039;.&amp;quot;  This object is then passed as the argument to &amp;lt;code&amp;gt;CmdUtils.CreateCommand&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== names ===&lt;br /&gt;
&lt;br /&gt;
&#039;names&#039; and &#039;execute&#039; are the only two mandatory attributes for your command object.  &#039;names&#039; specifies what the command is called, and &#039;execute&#039; specifies what it does.  There are plenty of other attributes that you can specify, but they are all optional.&lt;br /&gt;
&lt;br /&gt;
&#039;names&#039; is always an array (thus the square brackets).  In the case of this command we provided only one name, &amp;quot;hello world&amp;quot;.  But we could have provided as many names as we wanted.  For instance, if we had said:&lt;br /&gt;
&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
then &amp;quot;say hello&amp;quot; would be the normal name of the command, but Ubiquity would also recognize &amp;quot;greet&amp;quot; as a synonym or alias for the command.&lt;br /&gt;
&lt;br /&gt;
=== execute ===&lt;br /&gt;
&lt;br /&gt;
&#039;execute&#039; is always a function.  When the user executes your command, this is the function that will be run.  It can do pretty much anything you want -- or at least, anything you know how to write in JavaScript.&lt;br /&gt;
&lt;br /&gt;
In the example above, we simply call &amp;lt;code&amp;gt;displayMessage()&amp;lt;/code&amp;gt;, which displays the given message in whichever way the operating system can.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are a number of other useful functions in the &amp;lt;code&amp;gt;CmdUtils&amp;lt;/code&amp;gt; namespace. We don&#039;t yet have full documentation for these commands, but you&#039;ll get a sense of the useful ones in this tutorial. For more detailed information, take a look at [http://hg.toolness.com/ubiquity-firefox/file/9a6c9935da9f/ubiquity/chrome/content/cmdutils.js cmdutils.js].&lt;br /&gt;
&lt;br /&gt;
=== Making sure your command is localizable ===&lt;br /&gt;
&lt;br /&gt;
Ubiquity now supports multiple languages.  That means that hopefully someday someone will be translating your commands to the other languages that Ubiquity supports.  Making your command localizable is easy, and a good habit to get into!  You just have to locate all strings that appear in your &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; methods, that are intended for display to humans, and wrap them with:&lt;br /&gt;
&lt;br /&gt;
 _()&lt;br /&gt;
&lt;br /&gt;
This may look odd, but what it does is quite important: it makes your strings appear in the template files that localizers will be using.  So let&#039;s make our &amp;quot;Hello world!&amp;quot; command localizable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( _(&amp;quot;Hello, World!&amp;quot;) );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This makes it so that when a localization template is generated from your command feed, &amp;quot;Hello, World!&amp;quot; will be listed among the strings to be translated.&lt;br /&gt;
&lt;br /&gt;
Note that we don&#039;t need to wrap the names, or other strings that appear in the command metadata -- these are automatically wrapped for us.  We only need to wrap strings that appear inside the functions.&lt;br /&gt;
&lt;br /&gt;
== Adding a Preview ==&lt;br /&gt;
&lt;br /&gt;
http://img352.imageshack.us/img352/1002/picture3ex0.png&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a preview to our new command. Previews give the user feedback about what a command does before it&#039;s executed. Previews are great for providing rich visual feedback like displaying a graphical representation of atmospheric conditions when using the weather command as shown above. Previews have the full expressive power of HTML, including animations, so there&#039;s a lot you can do with them.&lt;br /&gt;
&lt;br /&gt;
One point of design: Preview code should never have side-effects. That is, a preview should never (without user interaction) change the state of the system.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;say hello&amp;quot; command, we don&#039;t need anything fancy: just some help text that is more descriptive than the default &amp;quot;Executes the say hello command.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;],&lt;br /&gt;
  preview: &amp;quot;Displays a &amp;lt;i&amp;gt;salutary&amp;lt;/i&amp;gt; greeting to the planet.&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( _(&amp;quot;Hello, World!&amp;quot;) );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the preview is an HTML-formatted string. The preview can also be a function. We&#039;ll get to that in the next section.&lt;br /&gt;
&lt;br /&gt;
= The Date Command: The Second Command =&lt;br /&gt;
&lt;br /&gt;
= Setting the Selection =&lt;br /&gt;
&lt;br /&gt;
I often forget what day it is. That may be because I need to go outside more often, but, like any programmer, I generally solve my problem&#039;s symptoms with technology rather then addressing the root cause. My solution is to create a command that inserts the date at the location of the cursor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    CmdUtils.setSelection( date.toLocaleDateString() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new function here is &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt;. This inserts the passed-in text onto the page at the location of the cursor. If the cursor is in an editable text or rich-text fields, the text gets dumped there. If the cursor isn&#039;t in an editable area, &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt; will still be able to insert the date. (Even when it isn&#039;t displayed, Firefox always keeps track of a cursor position. To see it, type F7.) Try going to a page, selecting some non-mutable text, and using the command. See, it works! This is particularly useful for commands like &amp;quot;translate&amp;quot;, where you want to replace non-editable text with its translation.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;toLocalDateString()&amp;lt;/code&amp;gt; function is native to Javascript, so if you&#039;re not familiar with it check out the documentation for the Javascript [http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date Date object].&lt;br /&gt;
&lt;br /&gt;
== A Better Preview ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s time to add a better preview to the date command. Let&#039;s have the preview show the date, so that the user will know what to expect when they execute the command. (As a side benefit the user doesn&#039;t even need to execute the command to do a quick check of the day.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  &lt;br /&gt;
  _date: function(){&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    return date.toLocaleDateString();&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = _(&#039;Inserts todays date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;);&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function() {&lt;br /&gt;
    CmdUtils.setSelection( this._date() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&#039;ve done two things here. The first was to factor out the code for getting the date into the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt; function. This way we don&#039;t break [http://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY] by repeating code across the preview and execute functions. Notice that to access the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt;, we use the &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
&lt;br /&gt;
The second thing we&#039;ve done is to add a preview function. The first argument is the DOM element that gets displayed as the preview for your command. Modify &amp;lt;code&amp;gt;pblock&amp;lt;/code&amp;gt; and you modify the preview. In this case, we set the &amp;lt;code&amp;gt;innerHTML&amp;lt;/code&amp;gt; of the preview block to be the message we want.&lt;br /&gt;
&lt;br /&gt;
The other thing I&#039;ve done is to do some string formatting using the &amp;lt;code&amp;gt;renderTemplate()&amp;lt;/code&amp;gt; function. This takes a template string and performs the appropriate substitution given the passed-in JSON object. Templates can handle a wide range of functionality, as we are currently using TrimPath&#039;s [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates JavascriptTemplates]. You should read their site for more documentation. Although JavascriptTemplates has some nice properties, we are contemplating moving to [http://mjtemplate.org/ MJT] sometime soon.&lt;br /&gt;
&lt;br /&gt;
=== A shortcut for localization and rendering templates ===&lt;br /&gt;
&lt;br /&gt;
Note how in the code above, we used the localization wrapper &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; before passing the string to renderTemplate.  Because this is such a very common combination when displaying strings, we have a shortcut for it.  Calling _() with a JSON object as the second argument will automatically trigger &amp;lt;code&amp;gt;CmdUtils.renderTemplate()&amp;lt;/code&amp;gt; on the post-localization string.  So the above preview method could be rewritten more simply as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &#039;Inserts todays date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
    pblock.innerHTML = _( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Networking calls and placeholder previews ===&lt;br /&gt;
&lt;br /&gt;
Previews display something meaningful to the user immediately. If you have a preview that requires an AJAX request&amp;amp;mdash;say, to fetch some search results&amp;amp;mdash;that call might take a while to return. In the meantime, your command should display a placeholder preview giving the user feedback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    pblock.innerHTML = _(&amp;quot;This will show until the AJAX request returns&amp;quot;);&lt;br /&gt;
    // AJAX request&lt;br /&gt;
    pblock.innerHTML = getFromServer();&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the future, we may work on streamlining this process.&lt;br /&gt;
&lt;br /&gt;
== Documentation and Metadata ==&lt;br /&gt;
&lt;br /&gt;
Before you share your command with the world, you should consider adding some attributions to the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you should &amp;lt;em&amp;gt;definitely&amp;lt;/em&amp;gt; add some documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Inserts today&#039;s date.&amp;quot;,&lt;br /&gt;
  help: &amp;quot;If you&#039;re in an editable text area, inserts today&#039;s date, formatted for the current locale.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.description&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.help&amp;lt;/code&amp;gt; attributes are both automatically displayed alongside your command&#039;s name on the command-list page.  (The user can get to this page at any time by issuing the &amp;quot;list ubiquity commands&amp;quot; command.)  HTML tags can be used in both of these strings.&lt;br /&gt;
&lt;br /&gt;
Description is a one-line summary of what the command does, while Help is a longer description that can include examples, caveats, and so on. If your command is simple enough that all you have to say about it fits in one line, it&#039;s OK to use a description alone and leave out the help.&lt;br /&gt;
&lt;br /&gt;
== Sharing it with the World ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our awesome new &amp;quot;date&amp;quot; command, let&#039;s share it with the world. All you have to do is put it the javascript file on the web somewhere, and make an html page linking to it with &amp;quot;link rel&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;pre&amp;gt;&amp;lt;link rel=&amp;quot;commands&amp;quot; href=&amp;quot;http://path-to-js&amp;quot; name=&amp;quot;Title Goes Here&amp;quot; /&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anyone with Ubiquity who visits will get a message offering them the choice of subscribing to your command.&lt;br /&gt;
&lt;br /&gt;
[[Image:Subscribe.png]]&lt;br /&gt;
&lt;br /&gt;
If the user chooses to subscribe to a Regular command feed from an untrusted source, they will get a security warning message before they can install the command.  Because Regular Ubiquity command feeds can execute arbitrary javascript with chrome privileges, subscribing to a command from a website means allowing that site full access to do whatever it wants to your browser.  We want to make sure people understand the dangers before subscribing to commands, so we made the warning page pretty scary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Warning.PNG]]&lt;br /&gt;
&lt;br /&gt;
=== Feed Types ===&lt;br /&gt;
&lt;br /&gt;
Recall that back near the beginning of the tutorial, you set the &amp;quot;feed type&amp;quot; to &amp;quot;Regular&amp;quot;.  As you may have guessed, there&#039;s actually more than one way to write a command feed.  The advantage of Regular feeds is that they let you do whatever you want, so it&#039;s really easy to innovate, but the disadvantages lie in subscribing to misbehaving or malicious code.  You can alternatively write what&#039;s called a &#039;&#039;Locked-Down Feed&#039;&#039;, which is much safer and doesn&#039;t raise a warning page when a user subscribes to it&amp;amp;mdash;but the consequences are that you have less freedom of implementation as a command author.  If you&#039;re interested in learning more about Locked-Down Feeds, check out the [[Labs/Ubiquity/Locked-Down_Feed_Tutorial|Locked-Down Feed Tutorial]].&lt;br /&gt;
&lt;br /&gt;
=== Trust Networks ===&lt;br /&gt;
&lt;br /&gt;
In the future, we&#039;re going to have something set up that we call a &amp;quot;trust network&amp;quot;.  When you try out a Ubiquity command from a website, and determine that the command is safe (or unsafe), you&#039;ll be able to leave an approval (or a warning).  When your friends with Ubiquity installed visit the same site, they&#039;ll see the approval or the warning that you left.  In this way, users will be able to rely on the judgement of other people they already know and trust in order to help them make decisions about whether a command is safe to install or not.&lt;br /&gt;
&lt;br /&gt;
By the way, the reason we call it &amp;quot;subscribing&amp;quot; to a command, rather than &amp;quot;installing&amp;quot; a command, is that if the javascript file changes -- if the site owner adds new commands, removes old commands, or updates existing commands -- all users subscribed to that URL will automatically get the updates.  This will be very convenient for both users and developers, but it will also introduce another type of security risk: just because you decided a command was safe at one point in time doesn&#039;t mean that the command will always remain safe.  For this reason, we&#039;ll need to make sure that the trust network keeps track of when commands have been modified, and notifies users of changes that may make a command unsafe.&lt;br /&gt;
&lt;br /&gt;
== Map Me! Location, Snapshots, and Inserting HTML ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;map&amp;quot; command that comes with Ubiquity is fairly powerful. It&#039;s also fairly complicated&amp;amp;mdash;well, comparatively. It&#039;s still only a couple hundred lines of code. The command, though, can get even more useful. Imagine being able to select some houses on Craigslist, or a list of restaurant names, and Ubiq &amp;quot;map these&amp;quot; to get just the map you want. The concept of &amp;quot;these&amp;quot; puts the power of mashups into the users hands. But I digress. Let&#039;s make a simple command that inserts a map of your current location.&lt;br /&gt;
&lt;br /&gt;
In this command, we use the Google [http://code.google.com/apis/maps/documentation/staticmaps/ static map API] and the Ubiquity function &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; to insert a map of your current location. Ubiquity currently uses the [http://www.maxmind.com/app/api MaxMind] API for trying to guess your location from your IP. That will probably change in the future.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll call this command &amp;lt;code&amp;gt;&amp;quot;map me&amp;quot;&amp;lt;/code&amp;gt; so that it won&#039;t be confused with the standard &amp;lt;code&amp;gt;&amp;quot;map&amp;quot;&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;map me&amp;quot;],&lt;br /&gt;
  &lt;br /&gt;
  _getMapUrl: function() {&lt;br /&gt;
    var loc = CmdUtils.getGeoLocation();&lt;br /&gt;
    var mapUrl = &amp;quot;http://maps.google.com/staticmap?&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    var params = {&lt;br /&gt;
      center: loc.lat + &amp;quot;,&amp;quot; + loc.long,&lt;br /&gt;
      size: &amp;quot;500x400&amp;quot;,&lt;br /&gt;
      zoom: 14,&lt;br /&gt;
      key: &amp;quot;ABQIAAAAGZ11mh1LzgQ8-8LRW3wEShQeSuJunOpTb3RsLsk00-MAdzxmXhQoiCd940lo0KlfQM5PeNYEPLW-3w&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    return mapUrl + jQuery.param( params );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &amp;quot;Inserts a map of your current location: &amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
              &amp;quot;&amp;lt;img src=&#039;${url}&#039;/&amp;gt;&amp;quot;;&lt;br /&gt;
    pblock.innerHTML = _(msg, {url: this._getMapUrl()});&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( ) {&lt;br /&gt;
    CmdUtils.getImageSnapshot( this._getMapUrl(), function(imgData) {&lt;br /&gt;
      CmdUtils.setSelection( &amp;quot;&amp;lt;img src=&#039;&amp;quot; + imgData +&amp;quot;&#039;/&amp;gt;&amp;quot;);&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are three new things here: &amp;lt;code&amp;gt;CmdUtils.setSelection&amp;lt;/code&amp;gt; to set HTML (yep, it can do that); the use of &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt;; and using &amp;lt;code&amp;gt;CmdUtils.snapshotImage()&amp;lt;/code&amp;gt; to capture the bits for the image.&lt;br /&gt;
&lt;br /&gt;
I find getting the location&amp;amp;mdash;as imprecise as IP-based location can be&amp;amp;mdash;useful for doing sensible defaults for location-based commands, like Yelp. &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; returns an object which has the following properties: city, state, country, lat, and long.&lt;br /&gt;
&lt;br /&gt;
Why do we need to use &amp;lt;code&amp;gt;CmdUtils.snapshotImage()&amp;lt;/code&amp;gt;? Because the Google Maps API requires a key that is tied to a particular URL. If we naively inject the image tag into a random web page, the image won&#039;t load because the key doesn&#039;t match that random web page&#039;s URL. Thus, we use the &amp;lt;code&amp;gt;snapshotImage()&amp;lt;/code&amp;gt; function to convert the image into a [http://en.wikipedia.org/wiki/Data:_URI_scheme data url].&lt;br /&gt;
&lt;br /&gt;
There&#039;s also a &amp;lt;code&amp;gt;CmdUtils.snapshotWindow&amp;lt;/code&amp;gt; function, which allows you to get the image data for any tab/window. The function takes a window as the first paramater, and a callback for the second.&lt;br /&gt;
&lt;br /&gt;
= Commands with Arguments =&lt;br /&gt;
&lt;br /&gt;
== Echo ==&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be working towards making some fun and useful commands&amp;amp;mdash;commands that let you control the seething tendrils of the internet with your little pinky. But, let&#039;s start by making a simple command to echo back whatever you type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;echo&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_arb_text,&lt;br /&gt;
               label: &amp;quot;your shout&amp;quot;}],&lt;br /&gt;
  preview: function( pblock, arguments ) {&lt;br /&gt;
    pblock.innerHTML = _(&amp;quot;Will echo: &amp;quot;) + arguments.object.text;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var msg = arguments.object.text + &amp;quot;... &amp;quot; + arguments.object.text + &amp;quot;......&amp;quot;;&lt;br /&gt;
    displayMessage( msg );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This says that the command &amp;quot;echo&amp;quot; takes one argument which is arbitrary text. Whatever text the user enters will get wrapped in an input object and passed into both the preview and execute function.&lt;br /&gt;
&lt;br /&gt;
Try it!  Ubiq &amp;quot;echo hellooooo&amp;quot; and watch what happens.&lt;br /&gt;
&lt;br /&gt;
Ubiquity takes care of parsing the user&#039;s input, so you don&#039;t need to worry about handling prounoun substitution or any of the other natural-language-like features of the Ubiquity parser. Try selecting some text on a page, and Ubiq &amp;quot;echo this&amp;quot;. Ubiquity should now echo the selected text.  &lt;br /&gt;
&lt;br /&gt;
Note that we gave three pieces of information when defining our argument:  its role, its nountype, and its label.  The label is the easiest part: It&#039;s just whatever text you want to have appear in the Ubiquity interface as a prompt for the user.  E.g, if you ubiq &amp;quot;echo&amp;quot;, you will see the label for the argument:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  echo (your shout)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The roles and the nountypes require some more explanation.  We&#039;ll cover each of them in detail next.&lt;br /&gt;
&lt;br /&gt;
=== Argument Roles ===&lt;br /&gt;
&lt;br /&gt;
Your command can take multiple arguments.  Each one is identified by a &amp;quot;role&amp;quot;.  To understand roles, it helps to think of your command name as a verb, and each argument as a noun.  Remember that Ubiquity&#039;s command line is a pseudo-natural-language environment, so it attempts to be as close to natural language grammar as possible.&lt;br /&gt;
&lt;br /&gt;
For example, if you&#039;ve ever used the &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; command, you know that it takes up to two arguments: a message and a person.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  email message&lt;br /&gt;
  email to person&lt;br /&gt;
  email message to person&lt;br /&gt;
  email to person message&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In grammatical terms, the message argument is the &amp;quot;direct object&amp;quot; of the verb &amp;quot;email&amp;quot;.  The person argument is an indirect object.  We call it the &amp;quot;goal&amp;quot; of the verb.  So if we were writing the email command, we&#039;d define the arguments like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_arb_text,&lt;br /&gt;
               label: &amp;quot;message&amp;quot;},&lt;br /&gt;
              {role: &amp;quot;goal&amp;quot;,&lt;br /&gt;
               nountype: noun_type_contact,&lt;br /&gt;
               label: &amp;quot;recipient&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we give the recipient argument the &amp;quot;goal&amp;quot; role, the Ubiquity parser knows to expect the user to type the word &amp;quot;to&amp;quot;.  When the user enters &amp;quot;email hello to Aza&amp;quot;, the parser knows that the word following &amp;quot;to&amp;quot; -- that is, &amp;quot;Aza&amp;quot; -- should be assigned to the recipient argument.&lt;br /&gt;
&lt;br /&gt;
In our simple &amp;quot;echo&amp;quot; command, we expect the user to type &amp;quot;echo hellooooo&amp;quot; or something like that.  The &amp;quot;hellooooo&amp;quot; is the direct object of the verb &amp;quot;echo&amp;quot;, so we give it the &amp;quot;object&amp;quot; role.  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Object&amp;quot; is the most common role.  If a command takes only one argument, that argument is usually an &amp;quot;object&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== What Roles Can I Use? ====&lt;br /&gt;
&lt;br /&gt;
* object   (in &amp;quot;echo helloooo&amp;quot;, hello is the object.)&lt;br /&gt;
* goal    (in &amp;quot;email this to brandon&amp;quot;, brandon is the goal.)&lt;br /&gt;
* source   (in &amp;quot;translate this from spanish&amp;quot;, spanish is the source.)&lt;br /&gt;
* location    (in &amp;quot;yelp pizza near boston&amp;quot;, boston is the location.)&lt;br /&gt;
* time    (in &amp;quot;book a flight on thursday&amp;quot;, thursday is the time.)&lt;br /&gt;
* instrument  (in &amp;quot;search monkeys with google&amp;quot;, google is the instrument.)&lt;br /&gt;
* format   (in &amp;quot;check weather in celsius&amp;quot;, celsius is the format.)&lt;br /&gt;
* modifier  (in &amp;quot;get email address for chris&amp;quot;, chris is the modifier.)&lt;br /&gt;
* alias   (in &amp;quot;twitter this as jono&amp;quot;, jono is the alias.)&lt;br /&gt;
&lt;br /&gt;
[https://wiki.mozilla.org/Labs/Ubiquity/Parser_2/Semantic_Roles More information about these roles].&lt;br /&gt;
&lt;br /&gt;
=== The Arguments Object ===&lt;br /&gt;
&lt;br /&gt;
When your execute method is called, it is passed a single object that encapsulates the values for all arguments.&lt;br /&gt;
&lt;br /&gt;
When your preview method is called, it is passed this object, too.&lt;br /&gt;
&lt;br /&gt;
The object has one attribute corresponding to each role.  In our example above, the command accepts only an object-role argument, so the preview and execute methods get passed an argument with an &amp;quot;arguments.object&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
If we made a command, like email, that takes an object-role argument and a goal-role argument, its preview and execute methods would get passed an argument with &amp;quot;arguments.object&amp;quot; and &amp;quot;arguments.goal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
arguments.object (or arguments.goal) has several attributes of its own:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments.object.text  // a string of the input in plain text, without formatting&lt;br /&gt;
  arguments.object.html  // a string of the input in formatted html, including tags&lt;br /&gt;
  arguments.object.data  // for non-text input types, an arbitrary data object&lt;br /&gt;
  arguments.object.summary // for very long inputs, an abbreviated display string&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our example command only cares about the &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; attribute of the input, because it simply wants plain text.  Often, when the user invokes your command by typing a few short words into the input box, &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.html&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; will all have exactly the same value, and &amp;lt;code&amp;gt;.data&amp;lt;/code&amp;gt; will be null.  Many, if not most, commands that you write will only care about the text value.  Nevertheless, the other versions of the input data are provided to you in case they differ from &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; and in case your command has a use for them.&lt;br /&gt;
&lt;br /&gt;
== Introduction to Noun Types ==&lt;br /&gt;
&lt;br /&gt;
Noun types specify what &#039;&#039;kind&#039;&#039; of input your command can accept for each one of its arguments.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;echo&amp;quot; command, we wanted the object-role argument to accept any text whatsoever, so for its nountype we passed in the predefined &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; object.  This object accepts any arbitrary text as a valid argument and passes it to the command unchanged.&lt;br /&gt;
&lt;br /&gt;
This is OK for very simple commands, like echoing back the user&#039;s input.  But for commands that take structured data, you will want to use more specific nountypes.&lt;br /&gt;
&lt;br /&gt;
For example, if a command can take a date (like the &amp;quot;check calendar&amp;quot; command), you would want to use &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; as the nountype of the argument.  &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; provides several benefits to your command:  it does all of the date parsing for you; it suggests dates that the user might want to enter (for instance, it defaults to today&#039;s date).  And, it lets the parser know that your command takes a date.  This is useful because when the user selects a date on a page and invokes Ubiquity, your command -- along with &amp;quot;check calendar&amp;quot; -- will be one of the top suggestions.&lt;br /&gt;
&lt;br /&gt;
You can write your own noun types -- we&#039;ll get into that later.  For now, let&#039;s take a look at the built-in nountypes that your command can use.  These include:&lt;br /&gt;
&lt;br /&gt;
* noun_arb_text (Arbitrary text)&lt;br /&gt;
* noun_type_language (Name of a human language, e.g. &amp;quot;English&amp;quot;, &amp;quot;Japanese&amp;quot;)&lt;br /&gt;
* noun_type_url (A URL)&lt;br /&gt;
* noun_type_contact (An email address from your address book)&lt;br /&gt;
* noun_type_date (A date, in any format, or a word like &amp;quot;tomorrow&amp;quot;)&lt;br /&gt;
* noun_type_time (A time, in any format)&lt;br /&gt;
* noun_type_percentage&lt;br /&gt;
* noun_type_address&lt;br /&gt;
* noun_type_tab&lt;br /&gt;
* noun_type_searchengine&lt;br /&gt;
* noun_type_tag&lt;br /&gt;
* noun_type_geolocation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with writing commands, you should check out the [http://hg.toolness.com/ubiquity-firefox/file/6caa9d66b3bb/ubiquity/chrome/content/nlparser/en/nountypes.js nountypes.js], which has the implementation for most of the noun-types.  You can see what noun types are already available for your commands to use, what still needs to be written, and where the existing implementations could use improvement &amp;amp;mdash; and then come [[Labs/Ubiquity#Participation|get involved]] to help us improve them.&lt;br /&gt;
&lt;br /&gt;
=== Regexps as Noun Types ===&lt;br /&gt;
&lt;br /&gt;
If none of the nountypes above is what you&#039;re looking for, there are several ways to define your own.  The simplest is to use a regular expression.  Suppose that (for whatever odd reason) you wanted your command to accept only arguments that begin with the letter N.  The following regexp matches words that start with N:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /^[nN]/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You could use it as a noun type, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: /^[nN]/,&lt;br /&gt;
               label: &amp;quot;word that starts with n&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note that you do &#039;&#039;not&#039;&#039; put quotes around the regexp.)&lt;br /&gt;
&lt;br /&gt;
A regexp nountype will reject input that doesn&#039;t match, but it doesn&#039;t know how to help the user by suggesting appropriate input.&lt;br /&gt;
&lt;br /&gt;
=== Lists as Noun Types ===&lt;br /&gt;
&lt;br /&gt;
Suppose you&#039;re writing a command that takes a color as an argument (perhaps it outputs a hexadecimal RGB representation of that color.)  To make a nountype that accepts colors, you can simply pass in an array of strings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  names: [&amp;quot;convert color&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: [&amp;quot;red&amp;quot;, &amp;quot;orange&amp;quot;, &amp;quot;yellow&amp;quot;, &amp;quot;green&amp;quot;, &lt;br /&gt;
                          &amp;quot;blue&amp;quot;, &amp;quot;violet&amp;quot;, &amp;quot;black&amp;quot;, &amp;quot;white&amp;quot;,&lt;br /&gt;
                          &amp;quot;grey&amp;quot;, &amp;quot;brown&amp;quot;, &amp;quot;beige&amp;quot;, &amp;quot;magenta&amp;quot;,&lt;br /&gt;
                          &amp;quot;cerulean&amp;quot;, &amp;quot;puce&amp;quot;],&lt;br /&gt;
               label: &amp;quot;color to convert&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One benefit of using a list is that the parser can use it offer the user suggestions.   If the user enters &amp;quot;get-color bl&amp;quot;, for instance, Ubiquity will be able to suggest &amp;quot;black&amp;quot; and &amp;quot;blue&amp;quot; as the two valid completions based on the input.  This makes list-based nountypes very useful for any command that can accept only a finite set of values.&lt;br /&gt;
&lt;br /&gt;
=== Writing a Noun Type Object ===&lt;br /&gt;
&lt;br /&gt;
Of course, not every type of noun you&#039;d be interested in can be represented&lt;br /&gt;
as a finite list or as a regexp.  If you want to be able to accept or reject input based on some algorithmic test, you can do so by writing a custom JavaScript object that implements a &amp;lt;code&amp;gt;suggest()&amp;lt;/code&amp;gt; method (and, optionally, a &amp;lt;code&amp;gt;default()&amp;lt;/code&amp;gt; method.)&lt;br /&gt;
&lt;br /&gt;
There is an example of how to do this in the section on the tab commands, below.&lt;br /&gt;
&lt;br /&gt;
== Insert Email: the Contact noun type ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s take a look at one of the built-in noun-types: &amp;lt;code&amp;gt;noun_type_contact&amp;lt;/code&amp;gt;. This lets Ubiquity know to expect a person (either by name or email address). By using the noun-type, Ubiquity will also autocomplete to known people while the user is entering the command. This is what the built-in Ubiquity command &amp;quot;email&amp;quot; uses.&lt;br /&gt;
&lt;br /&gt;
At the moment, Ubiquity figures out what people you know through reading your Gmail contacts. In this prototyped version, you&#039;ll need to use Gmail and be logged in for for Ubiquity to know who you know. Eventually, we&#039;d like to be able to interface with all major web-mail sites, as well as desktop software like Thunderbird.&lt;br /&gt;
&lt;br /&gt;
Enough rambling. It&#039;s time for a command. I constantly find that I need to fetch someone&#039;s email address to paste into a text field because I don&#039;t know it off-hand. This command solves that by letting you insert someone&#039;s email address using autocomplete.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert email&amp;quot;],&lt;br /&gt;
  arguments: {modifier: noun_type_contact},&lt;br /&gt;
  preview: &amp;quot;Inserts someone&#039;s email address by name.&amp;quot;,&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    CmdUtils.setSelection( arguments.modifier.text );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To try this out, Ubiq &amp;quot;insert email for &amp;quot; and then the first few letters of someone you email often.&lt;br /&gt;
&lt;br /&gt;
=== Shorter Argument Declarations ===&lt;br /&gt;
&lt;br /&gt;
Notice that we used a shortcut for declaring the arguments.  In the long form, we would have had to say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;modifier&amp;quot;,&lt;br /&gt;
               nountype: noun_type_contact,&lt;br /&gt;
               label: &amp;quot;contact&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
but if we don&#039;t care about specifying a label for the argument, we can get away with using a single object for &amp;quot;arguments&amp;quot;, with the roles as the property names, and the nountypes as the property values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: {modifier: noun_type_contact}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we had several arguments, and none of them needed labels, we could say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: {object: noun_arb_text, modifier: noun_type_contact}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and so on.&lt;br /&gt;
&lt;br /&gt;
Aza writes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
This one command sums up what I love about Ubiquity. In 8 lines of code, I can &lt;br /&gt;
fundamentally enhance the browser&#039;s functionality. Doing the same thing using &lt;br /&gt;
a normal Firefox extension methodology takes pages and pages of code&amp;amp;mdash;and  the interface would take more thought still. Doing the same thing using a bookmarklet would require a server-side component (to get around cross-site Ajax request ban) as well as forcing the user to give up their email password.&lt;br /&gt;
&lt;br /&gt;
Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TinyURL: Network Calls and jQuery (and the URL noun type)==&lt;br /&gt;
&lt;br /&gt;
Often while writing emails, I&#039;ll discover that I&#039;ve pasted in a URL long enough to be used for unfortunate analogies. I&#039;d like to be able to quickly turn that into a [http://en.wikipedia.org/wiki/Tinyurl TinyURL]&amp;amp;mdash;but the process of making a TinyURL involves lots of fiddly steps. Ubiquity to the rescue.&lt;br /&gt;
&lt;br /&gt;
Because we include [http://en.wikipedia.org/wiki/jQuery jQuery] with Ubiquity, it is simple to perform Ajax calls as well as parse returning data. TinyUrl.com provides an easy to use RESTful API where you pass a URL and it returns its shortened form. We use that API in this command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;tinyurl&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_type_url,&lt;br /&gt;
               label: &amp;quot;url to shorten&amp;quot;}],&lt;br /&gt;
  preview: &amp;quot;Replaces the selected URL with a TinyUrl.&amp;quot;,&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var baseUrl = &amp;quot;http://tinyurl.com/api-create.php&amp;quot;;&lt;br /&gt;
    var params = {url: arguments.object.text};&lt;br /&gt;
    jQuery.get( baseUrl, params, function( tinyUrl ) {&lt;br /&gt;
      CmdUtils.setSelection( tinyUrl );&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;noun_type_url&amp;lt;/code&amp;gt; is a useful nountype because it defaults to the URL of the page that you are currently on.  If that is in fact the URL that the user wants, then they don&#039;t have to type it or even select it.&lt;br /&gt;
&lt;br /&gt;
jQuery is a powerful tool. With it, you can fairly effortlessly cherry-pick the data you need from RSS feeds, XML, and all sorts of other data formats. It also makes doing in-preview animations a breeze.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Twitter: Putting It All Together =&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now covered everything we need to cover in order to write a command that allows us to [http://en.wikipedia.org/wiki/Twitter Twitter] from Ubiquity.  The code below is the actual source code of the Twitter command as it appears in Ubiquity 0.5.&lt;br /&gt;
&lt;br /&gt;
Many thanks to [http://theunfocused.net/moz/ubiquity/verbs/ Blair McBride] for writing this command.  The source code is a bit more intricate than anything we&#039;ve seen so far, but it&#039;s built using exactly the same basic pieces -- and demonstrates nearly all of those pieces in action.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const TWITTER_STATUS_MAXLEN = 140;&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;twitter&amp;quot;, &amp;quot;tweet&amp;quot;, &amp;quot;share using twitter&amp;quot;],&lt;br /&gt;
  arguments: [&lt;br /&gt;
    {role: &amp;quot;object&amp;quot;, label: &#039;status&#039;, nountype: noun_arb_text},&lt;br /&gt;
    {role: &amp;quot;alias&amp;quot;, nountype: noun_type_twitter_user}&lt;br /&gt;
  ],&lt;br /&gt;
  icon: &amp;quot;http://twitter.com/favicon.ico&amp;quot;,&lt;br /&gt;
  description:&lt;br /&gt;
  &amp;quot;Sets your Twitter status to a message of at most 160 characters.&amp;quot;,&lt;br /&gt;
  help: (&amp;quot;You&#039;ll need a &amp;lt;a href=\&amp;quot;http://twitter.com\&amp;quot;&amp;gt;Twitter account&amp;lt;/a&amp;gt;,&amp;quot; +&lt;br /&gt;
         &amp;quot; obviously.  If you&#039;re not already logged in&amp;quot; +&lt;br /&gt;
         &amp;quot; you&#039;ll be asked to log in.&amp;quot;),&lt;br /&gt;
  preview: function(previewBlock, args) {&lt;br /&gt;
    var statusText = (args.object ? args.object.text : &#039;&#039;);&lt;br /&gt;
    var usernameText = &amp;quot;&amp;quot;;&lt;br /&gt;
    if (args.alias) {&lt;br /&gt;
      usernameText = args.alias.text;&lt;br /&gt;
    } else if (args.as) {&lt;br /&gt;
      usernameText = args.as.text;&lt;br /&gt;
    }&lt;br /&gt;
    var previewTemplate = (&lt;br /&gt;
      &amp;quot;&amp;lt;div class=&#039;twitter&#039;&amp;gt;&amp;quot;+_(&amp;quot;Updates your Twitter status ${username} to:&amp;quot;)+&amp;quot;&amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
      &amp;quot;&amp;lt;b class=&#039;status&#039;&amp;gt;${status}&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
      _(&amp;quot;Characters remaining: &amp;lt;b&amp;gt;${chars}&amp;lt;/b&amp;gt;&amp;quot;) +&lt;br /&gt;
      &amp;quot;&amp;lt;p&amp;gt;&amp;lt;small&amp;gt;&amp;quot;+_(&amp;quot;tip: tweet @mozillaubiquity for help&amp;quot;)+&amp;quot;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
    var truncateTemplate = (&lt;br /&gt;
      &amp;quot;&amp;lt;strong&amp;gt;&amp;quot;+_(&amp;quot;The last &amp;lt;b&amp;gt;${truncate}&amp;lt;/b&amp;gt; characters will be truncated!&amp;quot;)+&amp;quot;&amp;lt;/strong&amp;gt;&amp;quot;);&lt;br /&gt;
    var previewData = {&lt;br /&gt;
      status: &amp;lt;&amp;gt;{statusText}&amp;lt;/&amp;gt;.toXMLString(),&lt;br /&gt;
      username: usernameText &amp;amp;&amp;amp; _(&amp;quot;(For user &amp;lt;b&amp;gt;${usernameText}&amp;lt;/b&amp;gt;)&amp;quot;),&lt;br /&gt;
      chars: TWITTER_STATUS_MAXLEN - statusText.length&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var previewHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                        CmdUtils.renderTemplate(previewTemplate, previewData),&lt;br /&gt;
                        {usernameText:usernameText});&lt;br /&gt;
&lt;br /&gt;
    if (previewData.chars &amp;lt; 0) {&lt;br /&gt;
      var truncateData = {&lt;br /&gt;
        truncate: 0 - previewData.chars&lt;br /&gt;
      };&lt;br /&gt;
&lt;br /&gt;
      previewHTML += CmdUtils.renderTemplate(truncateTemplate, truncateData);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    previewBlock.innerHTML = previewHTML;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(args) {&lt;br /&gt;
    var statusText = args.object.text;&lt;br /&gt;
    if(statusText.length &amp;lt; 1) {&lt;br /&gt;
      this._show(_(&amp;quot;requires a status to be entered&amp;quot;));&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var updateUrl = &amp;quot;https://twitter.com/statuses/update.json&amp;quot;;&lt;br /&gt;
    var updateParams = {&lt;br /&gt;
      source: &amp;quot;ubiquity&amp;quot;,&lt;br /&gt;
      status: statusText&lt;br /&gt;
      //dont cut the input since sometimes, the user selects a big url,&lt;br /&gt;
      //and the total lenght is more than 140, but tinyurl takes care of that&lt;br /&gt;
    };&lt;br /&gt;
    var me = this;&lt;br /&gt;
&lt;br /&gt;
    function sendMessage() {&lt;br /&gt;
      jQuery.ajax({&lt;br /&gt;
        type: &amp;quot;POST&amp;quot;,&lt;br /&gt;
        url: updateUrl,&lt;br /&gt;
        data: updateParams,&lt;br /&gt;
        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
        error: function() {&lt;br /&gt;
          me._show(_(&amp;quot;error - status not updated&amp;quot;));&lt;br /&gt;
        },&lt;br /&gt;
        success: function() {&lt;br /&gt;
          me._show(/^d /.test(statusText)&lt;br /&gt;
                   ? _(&amp;quot;direct message sent&amp;quot;)&lt;br /&gt;
                   : _(&amp;quot;status updated&amp;quot;));&lt;br /&gt;
        },&lt;br /&gt;
        username: login.username,&lt;br /&gt;
        password: login.password&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var login;&lt;br /&gt;
    var alias = args.alias;&lt;br /&gt;
    if (alias &amp;amp;&amp;amp; alias.text &amp;amp;&amp;amp; alias.data) {&lt;br /&gt;
      login = alias.data;&lt;br /&gt;
      sendMessage();&lt;br /&gt;
    } else {&lt;br /&gt;
      login = {username: null,&lt;br /&gt;
               password: null};&lt;br /&gt;
      if (alias &amp;amp;&amp;amp; alias.text)&lt;br /&gt;
        login.username = alias.text;&lt;br /&gt;
      sendMessage();&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  _show: function(txt){&lt;br /&gt;
    displayMessage({icon: this.icon, title: this.name, text: txt});&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Switching Tabs =&lt;br /&gt;
&lt;br /&gt;
The final command in this tutorial is for switching between tabs. The end goal is this: type a few keys to that matches the title of an open tab (in any window), hit return, and you&#039;ve switched to that tab.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll write this command in two steps. The first step is creating a tab noun-type. The second step is using that noun-type to create the tab-switching command.&lt;br /&gt;
&lt;br /&gt;
== Switching: Writing your own Noun-Types ==&lt;br /&gt;
&lt;br /&gt;
A noun-type needs to only have two things: A &amp;lt;code&amp;gt;label&amp;lt;/code&amp;gt; and a &amp;lt;code&amp;gt;suggest()&amp;lt;/code&amp;gt; function.  It can optionally also have a &amp;lt;code&amp;gt;default()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
The label is what shows up when the command prompts for input. Suggest returns a list of input objects, each one containing the name of a matching tab. We&#039;re using [http://developer.mozilla.org/en/docs/FUEL FUEL] to interact with the browser, which is where the &amp;quot;Application&amp;quot; variable comes from.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_tab = {&lt;br /&gt;
  label: &amp;quot;tab name&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  // Returns all tabs from all windows.&lt;br /&gt;
  getTabs: function(){&lt;br /&gt;
    var tabs = {};&lt;br /&gt;
&lt;br /&gt;
    for( var j=0; j &amp;lt; Application.windows.length; j++ ) {&lt;br /&gt;
      var window = Application.windows[j];&lt;br /&gt;
      for (var i = 0; i &amp;lt; window.tabs.length; i++) {&lt;br /&gt;
        var tab = window.tabs[i];&lt;br /&gt;
        tabs[tab.document.title] = tab;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return tabs;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  suggest: function( text, html, callback ) {&lt;br /&gt;
    &lt;br /&gt;
    var suggestions  = [];&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
&lt;br /&gt;
    //TODO: implement a better match algorithm&lt;br /&gt;
    for ( var tabName in tabs ) {&lt;br /&gt;
      if (tabName.match(text, &amp;quot;i&amp;quot;))&lt;br /&gt;
	 suggestions.push( CmdUtils.makeSugg(tabName) );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Return a list of input objects, limited to at most five:&lt;br /&gt;
    return suggestions.splice(0, 5);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The suggest method of a noun type always gets passed both text and html.  If the input is coming from a part of a web page that the user has selected, these&lt;br /&gt;
values can be different: they are both strings, but the html value contains markup tags while the text value does not. The Tab noun type only cares about the plain text of the tab name, so we ignore the value of html.&lt;br /&gt;
&lt;br /&gt;
The callback argument is for use by nountypes that need to run asynchronously, i.e. becaus they need to do network calls to generate suggestions.  The callback is a function; instead of returning a list of suggestions right away, an asynchronous noun type can call the callback with each suggestion it generates.  More on this later; the tab noun type generates all its suggestions right away, so it just returns them instead of using the callback.&lt;br /&gt;
&lt;br /&gt;
We use the convenience function &amp;lt;code&amp;gt;CmdUtils.makeSugg()&amp;lt;/code&amp;gt; to generate an&lt;br /&gt;
input object of the type that the Ubiquity parser expects.  The full signature of this function is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.makeSugg( text, html, data );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
but html and data are optional and need be provided only if they differ from text.&lt;br /&gt;
&lt;br /&gt;
If the text or html input is very long, &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; generates a summary for us, and puts it in the &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; attribute of the input object.&lt;br /&gt;
&lt;br /&gt;
We could have accomplished mostly the same thing without calling &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; by returning a list of anonymous objects like these:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ text: tabName,&lt;br /&gt;
  html: tabName,&lt;br /&gt;
  data: null,&lt;br /&gt;
  summary: tabName };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The input objects that our &amp;lt;code&amp;gt;.suggest()&amp;lt;/code&amp;gt; method generates are the same objects that will eventually get passed in to the &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; methods of any commands that use this noun type.&lt;br /&gt;
&lt;br /&gt;
== Switching Tabs: The Command ==&lt;br /&gt;
&lt;br /&gt;
Now that we are armed with the tab noun-type, it is easy to make the tab-switching command. Again, we use FUEL to focus the selected tab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;tab&amp;quot;],&lt;br /&gt;
  arguments: {object: noun_type_tab},&lt;br /&gt;
&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var tabName = arguments.object.text;&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
    tabs[tabName]._window.focus();&lt;br /&gt;
    tabs[tabName].focus();&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  preview: function( pblock, arguments ) {&lt;br /&gt;
    var tabName = arguments.object.text;&lt;br /&gt;
    if( tabName.length &amp;gt; 1 ){&lt;br /&gt;
        var msg = &amp;quot;Changes to &amp;lt;b style=\&amp;quot;color:yellow\&amp;quot;&amp;gt;${tab}&amp;lt;/b&amp;gt; tab.&amp;quot;;&lt;br /&gt;
        pblock.innerHTML = _(msg, {tab: tabName});&lt;br /&gt;
     }&lt;br /&gt;
    else&lt;br /&gt;
      pblock.innerHTML = _(&amp;quot;Switch to a tab by name.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Development Hints =&lt;br /&gt;
&lt;br /&gt;
You now know all you need to know to get started developing useful Ubiquity commands of your own.&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous tips that didn&#039;t fit elsewhere on this page, that may make development easier for you.&lt;br /&gt;
&lt;br /&gt;
== The Source Code of Built-In Commands ==&lt;br /&gt;
&lt;br /&gt;
Looking at the source code of built-in commands and built-in noun types can be a very useful aid to development.  If you have the source checkout of Ubiquity (see [Labs/Ubiquity/Ubiquity_0.1_Development_Tutorial | the development tutorial] to find out how to get this), the source code can be found in the files:&lt;br /&gt;
&lt;br /&gt;
 ubiquity/standard-feeds/&lt;br /&gt;
 ubiquity/builtin-feeds/en/builtincmds.js&lt;br /&gt;
 ubiquity/modules/nountypes.js&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a checkout of the source code, you can view the latest version on the web here:&lt;br /&gt;
&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/standard-feeds/ standard-feeds]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/builtin-feeds/en/builtincmds.js builtincmds.js]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/modules/nountypes.js nountypes.js]&lt;br /&gt;
&lt;br /&gt;
== Interacting with Other Extensions ==&lt;br /&gt;
&lt;br /&gt;
http://img363.imageshack.us/img363/1906/picture7cm5.png&lt;br /&gt;
&lt;br /&gt;
There isn&#039;t much to say here besides that it&#039;s easy. For example, here&#039;s a command (thanks to [http://foyrek.com/lyrics.html Abimanyu Raja] for writing this code) that finds the lyrics for a song. You can simply Ubiq something like &amp;quot;get lyrics for wild international&amp;quot; but the command will also interface with the FoxyTunes extension (if it is installed) and add the currently playing song to the suggestion list. Interfacing with other extensions, too, is easy because you can view the source code for every Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_song = {&lt;br /&gt;
  label: &amp;quot;song name&amp;quot;,&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    var suggestions  = [CmdUtils.makeSugg(text)];&lt;br /&gt;
    if(window.foxytunesGetCurrentTrackTitle){&lt;br /&gt;
   suggestions.push(CmdUtils.makeSugg(window.foxytunesGetCurrentTrackTitle()));&lt;br /&gt;
  	}&lt;br /&gt;
    return suggestions;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;get lyrics&amp;quot;],&lt;br /&gt;
  arguments: {modifier: noun_type_song},&lt;br /&gt;
  preview: function(pblock, arguments) {&lt;br /&gt;
    &lt;br /&gt;
    searchText = jQuery.trim(arguments.modifier.text);&lt;br /&gt;
    if(searchText.length &amp;lt; 1) {&lt;br /&gt;
      pblock.innerHTML = _(&amp;quot;Searches for lyrics of the song&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var previewTemplate = &amp;quot;Searches for the lyrics of &amp;lt;b&amp;gt;${query}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    pblock.innerHTML = _(previewTemplate, {query: searchText});&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(arguments) {&lt;br /&gt;
    var url = &amp;quot;http://www.google.com/search?q={QUERY}&amp;quot;&lt;br /&gt;
    var query = arguments.object.text + _(&amp;quot; lyrics&amp;quot;);&lt;br /&gt;
    var urlString = url.replace(&amp;quot;{QUERY}&amp;quot;, query);&lt;br /&gt;
    Utils.openUrlInBrowser(urlString);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementing Asynchronous Noun Suggestions ==&lt;br /&gt;
&lt;br /&gt;
The noun types we&#039;ve seen so far in this tutorial have all worked synchronously, returning their suggestions right away. However, Ubiquity also supports asynchronous noun suggestions. These are useful for when a noun type needs to do some potentially time-consuming work before it can make suggestions &amp;amp;mdash; most commonly when it needs to call an external service.&lt;br /&gt;
&lt;br /&gt;
Implementing asynchronous suggestions is simple. Whenever the Ubiquity parser calls a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function, it includes a callback function that may be used to send suggestions back to the parser as they become available. In the most typical case, the noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function makes an AJAX request, invoking the parser&#039;s callback function from within the callback function for the AJAX request.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example: a noun type that suggests [http://www.freebase.com/ Freebase] topics based on the text the user has typed or selected, and a barebones &amp;lt;code&amp;gt;freebase-lookup&amp;lt;/code&amp;gt; command that uses the noun type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_freebase_topic = {&lt;br /&gt;
  name: &amp;quot;Freebase topic&amp;quot;,&lt;br /&gt;
  label: &amp;quot;topic&amp;quot;,&lt;br /&gt;
  suggest: function freebase_topic_suggest(text, html, callback) {&lt;br /&gt;
    return [&lt;br /&gt;
      CmdUtils.makeSugg(text),&lt;br /&gt;
      $.ajax({&lt;br /&gt;
        url: &amp;quot;http://www.freebase.com/api/service/search&amp;quot;,&lt;br /&gt;
        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
        data: {prefix: text, limit: 5},&lt;br /&gt;
        success: function suggestTopics(response) {&lt;br /&gt;
          if (response.status === &amp;quot;200 OK&amp;quot;)&lt;br /&gt;
            callback([CmdUtils.makeSugg(result.name, result.name, result)&lt;br /&gt;
                      for each (result in response.result)]);&lt;br /&gt;
        },&lt;br /&gt;
      })];&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;lookup on freebase&amp;quot;],&lt;br /&gt;
  arguments: {object: noun_type_freebase_topic},&lt;br /&gt;
  preview: function preview(pblock, args) {&lt;br /&gt;
    pblock.innerHTML = _((&amp;quot;Go to the Freebase topic page for &amp;quot; +&lt;br /&gt;
                          &amp;quot;{if text}${text}{else}any topic{/if}.&amp;quot;),&lt;br /&gt;
                         args.object);&lt;br /&gt;
  },&lt;br /&gt;
  execute: function goToFreebase({object: {text, data}}) {&lt;br /&gt;
    Utils.openUrlInBrowser(&lt;br /&gt;
      text&lt;br /&gt;
      ? (data&lt;br /&gt;
         ? &amp;quot;http://www.freebase.com/view&amp;quot; + data.id&lt;br /&gt;
         : (&amp;quot;http://www.freebase.com/search?query=&amp;quot; +&lt;br /&gt;
            encodeURIComponent(text)))&lt;br /&gt;
      : &amp;quot;http://www.freebase.com/&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A few notes:&lt;br /&gt;
&lt;br /&gt;
* The parser&#039;s callback function expects only one suggestion (not an array of suggestions), so it must be called one time for each suggestion, even if the noun type has multiple suggestions available at the same time (as in the Freebase example above). This is a bit different from the synchronous case, in which the &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function is expected to return an array.&lt;br /&gt;
* A noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function typically returns an empty array when it intends to make asynchronous suggestions, but it can return one or more suggestions synchronously if it has them available.&lt;br /&gt;
* Because the work being done to generate asynchronous suggestions is generally somewhat expensive, and because a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function may be called for every keystroke the user makes, you should probably consider implementing a delay before starting the work and/or caching the work at some level. Ubiquity currently leaves this up to each noun type individually.&lt;br /&gt;
* A much more robust implementation of Freebase-derived noun types can be found [http://graynorton.com/ubiquity/freebase-nouns.html here].&lt;br /&gt;
&lt;br /&gt;
== Running on page load and startup ==&lt;br /&gt;
&lt;br /&gt;
Commands aren&#039;t the only thing you can put in a command feed.  You can also include functions you want to be run automatically at page-load time and at Firefox startup time.&lt;br /&gt;
&lt;br /&gt;
In order to run some code on page load, you simply have to prefix your function with &amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;. For example, if you want to say &amp;quot;Hi&amp;quot; every time a page is loaded, your code would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function pageLoad_hi(){&lt;br /&gt;
 displayMessage(&amp;quot;hi&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you modify the function and want to see the changes, remember to first invoke Ubiquity. Although your function like above, might not be a Ubiquity command, this is necessary to refresh the cached code.&lt;br /&gt;
&lt;br /&gt;
Similarly, if you want to run some code everytime Firefox starts up, you just have to prefix the function with &amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
The awesome thing about these functions is the ability to develop whole Firefox extensions (that require minimal UI) as Ubiquity plugins in lesser lines of code. You don&#039;t need to worry about chrome.manifest or install.rdf. Another added benefit is that you never have to restart your Firefox during development unless of course, you are running code on Firefox startup.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;http://img388.imageshack.us/img388/3086/picture5eo9.png&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code for [http://foyrek.com/keyscape.js Keyscape] which is a Ubiquity command that makes use of &amp;lt;code&amp;gt;pageLoad&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;startup&amp;lt;/code&amp;gt; to recreate the functionality of the [https://addons.mozilla.org/en-US/firefox/addon/339 Search Keys extension] by Jesse Ruderman. In line with Ubiquity&#039;s aim to let you do things quicker using your keyboard, this command lets you go to search results on Google by just pressing a number. It&#039;ll add hints to show the number of each link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//A lot of this code is borrowed from the Search Keys extension&lt;br /&gt;
//Many thanks to Jeese Ruderman&lt;br /&gt;
&lt;br /&gt;
function startup_keyscape() {&lt;br /&gt;
  window.addEventListener(&amp;quot;keydown&amp;quot;, keyscape_down, true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function pageLoad_keyscape(doc){&lt;br /&gt;
&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
  //If we are on about: or chrome://, just return&lt;br /&gt;
  if(uri.scheme != &amp;quot;http&amp;quot;)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  //Check if the page we are on is google&lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	      		    &lt;br /&gt;
    for(var num=1; num&amp;lt;=10; num++){&lt;br /&gt;
&lt;br /&gt;
      var link = jQuery(doc.body).find(&#039;a.l&#039;)[num-1];&lt;br /&gt;
      &lt;br /&gt;
      if( link ){&lt;br /&gt;
&lt;br /&gt;
        var hint = doc.createElementNS(&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;, &amp;quot;span&amp;quot;);&lt;br /&gt;
        hint.style.color = &amp;quot;blue&amp;quot;;&lt;br /&gt;
        hint.style.background = &amp;quot;white&amp;quot;;&lt;br /&gt;
        hint.style.padding = &amp;quot;1px 2px 1px 2px&amp;quot;;&lt;br /&gt;
        hint.style.marginLeft = &amp;quot;.5em&amp;quot;;&lt;br /&gt;
        hint.appendChild(doc.createTextNode(num == 10 ? 0 : num));&lt;br /&gt;
        link.parentNode.insertBefore(hint, link.nextSibling);&lt;br /&gt;
      }  		&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_isGoogle(uri){&lt;br /&gt;
  return uri.host.indexOf(&amp;quot;google&amp;quot;) != -1 &lt;br /&gt;
	 &amp;amp;&amp;amp; (uri.path.substr(0,8) == &amp;quot;/search?&amp;quot; &lt;br /&gt;
         || uri.path.substr(0,8) == &amp;quot;/custom?&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_down(event){&lt;br /&gt;
&lt;br /&gt;
  var doc =  Application.activeWindow.activeTab.document;	&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
 &lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	&lt;br /&gt;
   var key = parseInt(event.keyCode || event.charCode);	&lt;br /&gt;
   var num;&lt;br /&gt;
	&lt;br /&gt;
   if(48 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 57) //number keys&lt;br /&gt;
     num = key - 48;&lt;br /&gt;
   else if(96 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 105) //numeric keypad with numlock on&lt;br /&gt;
     num = key - 96;&lt;br /&gt;
   else&lt;br /&gt;
     return;&lt;br /&gt;
&lt;br /&gt;
   //Don&#039;t do anything if we are in a textbox&lt;br /&gt;
   //or some other related elements&lt;br /&gt;
   var elt = window.document.commandDispatcher.focusedElement;&lt;br /&gt;
   &lt;br /&gt;
   if (elt) {&lt;br /&gt;
     var ln = new String(elt.localName).toLowerCase();&lt;br /&gt;
     if (ln == &amp;quot;input&amp;quot; || ln == &amp;quot;textarea&amp;quot; || ln == &amp;quot;select&amp;quot; || ln == &amp;quot;isindex&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
   //Get the link url from the search results page&lt;br /&gt;
   var url_dest = jQuery(doc.body).find(&#039;a.l&#039;).eq(num-1).attr(&#039;href&#039;);&lt;br /&gt;
   &lt;br /&gt;
   if(event.altKey){&lt;br /&gt;
     //Open in new tab&lt;br /&gt;
     Application.activeWindow.open(Utils.url(url_dest));&lt;br /&gt;
   }else{&lt;br /&gt;
     //Open in same tab&lt;br /&gt;
     doc.location.href = url_dest;&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If Ubiquity does indeed become ubiquitous, a lot of extensions can be re-written as Ubiquity commands. This is much nicer for the end-user, as well, because the Ubiquity command installation process is a lot easier.&lt;br /&gt;
&lt;br /&gt;
In the future, Ubiquity is also likely to have the ability to convert your Ubiquity commands into proper Firefox extensions. Look [http://labs.toolness.com/trac/ticket/3 here] to check on the progress of this functionality.&lt;br /&gt;
&lt;br /&gt;
== Firebug ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity automatically enables Chrome Errors and Warnings on startup so that errors in your code appear in the Firebug console. Just use &amp;lt;tt&amp;gt;CmdUtils.log()&amp;lt;/tt&amp;gt; rather than &amp;lt;tt&amp;gt;console.log()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Where To Go From Here =&lt;br /&gt;
&lt;br /&gt;
Take a look at Ubiquity&#039;s reference documentation for the &amp;lt;tt&amp;gt;[https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html#modules/utils.js Utils]&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;[https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html#modules/cmdutils.js CmdUtils]&amp;lt;/tt&amp;gt; namespaces.&lt;br /&gt;
&lt;br /&gt;
If you have any questions or comments, feel free to join us on IRC at &amp;lt;tt&amp;gt;#ubiquity&amp;lt;/tt&amp;gt; on &amp;lt;tt&amp;gt;irc.mozilla.org&amp;lt;/tt&amp;gt;, as well as the [http://groups.google.com/group/ubiquity-firefox Ubiquity Google Group].&lt;br /&gt;
&lt;br /&gt;
= Conclusion =&lt;br /&gt;
&lt;br /&gt;
To reiterate a point I made before: Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web. You are one of those agents.&lt;br /&gt;
&lt;br /&gt;
Now, go forth and create.&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.5_Author_Tutorial&amp;diff=154566</id>
		<title>Labs/Ubiquity/Ubiquity 0.5 Author Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.5_Author_Tutorial&amp;diff=154566"/>
		<updated>2009-07-10T23:10:28Z</updated>

		<summary type="html">&lt;p&gt;Endolith: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
Author: Aza Raskin, Blair McBride, Abimanyu Raja, Jono DiCarlo, Atul Varma&lt;br /&gt;
&lt;br /&gt;
= The Ubiquity version 0.5 Command Tutorial =&lt;br /&gt;
&lt;br /&gt;
The great power of Ubiquity&amp;amp;mdash;from a developer standpoint&amp;amp;mdash;is how easy it is to create commands. With only a couple of lines of Javascript, Ubiquity enables even casual web developers to drastically enhance the features of the browser. From an 8-line command to insert a contact&#039;s email address in any text field, to a 50-line Twitter integration, this tutorial walks you through the process of being generative with Ubiquity.&lt;br /&gt;
&lt;br /&gt;
The rest of this page documents the command developer API as it stands frozen in version 0.5.&lt;br /&gt;
&lt;br /&gt;
If you want the bleeding-edge command developer API (which includes any new features that may have been added to the Ubiquity source code in HG but not yet included in a release), then that&#039;s [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|here]].&lt;br /&gt;
&lt;br /&gt;
If you want the old command developer API, as it stood in Ubiquity 0.1 (not recommended), that&#039;s [[Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial|here]].&lt;br /&gt;
&lt;br /&gt;
== Real Time Development ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t require you to restart Firefox as you develop. Restarting is a drastic measure, and we want none of it. Instead, Ubiquity reloads the commands every time it is summoned. When you are using the built-in editor then you don&#039;t even need to save!&lt;br /&gt;
&lt;br /&gt;
To open the Ubiquity command editor, summon Ubiquity (control/alt + space) and use the &amp;quot;open command editor&amp;quot; command. Throughout this tutorial, when we want you to run a command in Ubiquity, we&#039;ll say &#039;&#039;&#039;Ubiq&#039;&#039;&#039; it. For instance, to open the editor, just Ubiq &amp;quot;open command editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the following examples, just type in this editor. Updates happen the next time you summon Ubiquity.&lt;br /&gt;
&lt;br /&gt;
== Choices, Choices... ==&lt;br /&gt;
&lt;br /&gt;
You may notice a drop-down menu mentioning something about a &amp;quot;feed type&amp;quot; just above the editing field in the command editor:&lt;br /&gt;
&lt;br /&gt;
http://www.toolness.com/images/20090318121423.jpg&lt;br /&gt;
&lt;br /&gt;
For now, just make sure this drop-down is set to &amp;quot;Regular&amp;quot;.  We&#039;ll tell you more about what this means later.&lt;br /&gt;
&lt;br /&gt;
= Hello World: The First Command =&lt;br /&gt;
&lt;br /&gt;
== Just a Message: As Simple as it Gets ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s start with the standard programing trope: printing &amp;quot;Hello, World!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the command editor type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now try Ubiq-ing &amp;quot;say hello&amp;quot;. You&#039;ll see that &amp;quot;Hello, World!&amp;quot; is immediately displayed on the screen. If you are on Mac OSX with [http://en.wikipedia.org/wiki/Growl_(software) Growl] installed the message will appear as a Growl notification. If you are on Windows, then it will appears as a standard &amp;quot;toaster&amp;quot; notification in the bottom right-hand corner of the screen.&lt;br /&gt;
&lt;br /&gt;
http://farm3.static.flickr.com/2479/3651542339_022e4aa4c4.jpg&lt;br /&gt;
&lt;br /&gt;
http://img517.imageshack.us/img517/7726/picture2vx2.png&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 8.04 (Hardy Heron) this appears thus:&lt;br /&gt;
&lt;br /&gt;
http://img293.imageshack.us/img293/7746/ubiqubuntuhelloworldeq9.png&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have Growl installed on OSX, or aren&#039;t on a Windows XP/Vista or Ubuntu Hardy, then you won&#039;t get any sort of notification. That&#039;s something to be [http://labs.toolness.com/trac/ticket/19 worked on] in future releases of Ubiquity.&lt;br /&gt;
&lt;br /&gt;
=== CmdUtils.CreateCommand ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CmdUtils&amp;lt;/code&amp;gt; is a namespace which contains all the functions you need to create commands.  Commands are created by making an object and passing it to &amp;lt;code&amp;gt;CmdUtils.CreateCommand&amp;lt;/code&amp;gt;.  In Javascript, inline curly braces mean &amp;quot;new object&amp;quot;, so this code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
   names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
   execute: function() { //etc }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
means &amp;quot;Make an object with two attributes, &#039;names&#039; and &#039;execute&#039;.&amp;quot;  This object is then passed as the argument to &amp;lt;code&amp;gt;CmdUtils.CreateCommand&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== names ===&lt;br /&gt;
&lt;br /&gt;
&#039;names&#039; and &#039;execute&#039; are the only two mandatory attributes for your command object.  &#039;names&#039; specifies what the command is called, and &#039;execute&#039; specifies what it does.  There are plenty of other attributes that you can specify, but they are all optional.&lt;br /&gt;
&lt;br /&gt;
&#039;names&#039; is always an array (thus the square brackets).  In the case of this command we provided only one name, &amp;quot;hello world&amp;quot;.  But we could have provided as many names as we wanted.  For instance, if we had said:&lt;br /&gt;
&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
then &amp;quot;say hello&amp;quot; would be the normal name of the command, but Ubiquity would also recognize &amp;quot;greet&amp;quot; as a synonym or alias for the command.&lt;br /&gt;
&lt;br /&gt;
=== execute ===&lt;br /&gt;
&lt;br /&gt;
&#039;execute&#039; is always a function.  When the user executes your command, this is the function that will be run.  It can do pretty much anything you want -- or at least, anything you know how to write in JavaScript.&lt;br /&gt;
&lt;br /&gt;
In the example above, we simply call &amp;lt;code&amp;gt;displayMessage()&amp;lt;/code&amp;gt;, which displays the given message in whichever way the operating system can.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are a number of other useful functions in the &amp;lt;code&amp;gt;CmdUtils&amp;lt;/code&amp;gt; namespace. We don&#039;t yet have full documentation for these commands, but you&#039;ll get a sense of the useful ones in this tutorial. For more detailed information, take a look at [http://hg.toolness.com/ubiquity-firefox/file/9a6c9935da9f/ubiquity/chrome/content/cmdutils.js cmdutils.js].&lt;br /&gt;
&lt;br /&gt;
=== Making sure your command is localizable ===&lt;br /&gt;
&lt;br /&gt;
Ubiquity now supports multiple languages.  That means that hopefully someday someone will be translating your commands to the other languages that Ubiquity supports.  Making your command localizable is easy, and a good habit to get into!  You just have to locate all strings that appear in your &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; methods, that are intended for display to humans, and wrap them with:&lt;br /&gt;
&lt;br /&gt;
 _()&lt;br /&gt;
&lt;br /&gt;
This may look odd, but what it does is quite important: it makes your strings appear in the template files that localizers will be using.  So let&#039;s make our &amp;quot;Hello world!&amp;quot; command localizable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( _(&amp;quot;Hello, World!&amp;quot;) );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This makes it so that when a localization template is generated from your command feed, &amp;quot;Hello, World!&amp;quot; will be listed among the strings to be translated.&lt;br /&gt;
&lt;br /&gt;
Note that we don&#039;t need to wrap the names, or other strings that appear in the command metadata -- these are automatically wrapped for us.  We only need to wrap strings that appear inside the functions.&lt;br /&gt;
&lt;br /&gt;
== Adding a Preview ==&lt;br /&gt;
&lt;br /&gt;
http://img352.imageshack.us/img352/1002/picture3ex0.png&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a preview to our new command. Previews give the user feedback about what a command does before it&#039;s executed. Previews are great for providing rich visual feedback like displaying a graphical representation of atmospheric conditions when using the weather command as shown above. Previews have the full expressive power of HTML, including animations, so there&#039;s a lot you can do with them.&lt;br /&gt;
&lt;br /&gt;
One point of design: Preview code should never have side-effects. That is, a preview should never (without user interaction) change the state of the system.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;say hello&amp;quot; command, we don&#039;t need anything fancy: just some help text that is more descriptive than the default &amp;quot;Executes the say hello command.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;say hello&amp;quot;, &amp;quot;greet&amp;quot;],&lt;br /&gt;
  preview: &amp;quot;Displays a &amp;lt;i&amp;gt;salutary&amp;lt;/i&amp;gt; greeting to the planet.&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( _(&amp;quot;Hello, World!&amp;quot;) );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the preview is an HTML-formatted string. The preview can also be a function. We&#039;ll get to that in the next section.&lt;br /&gt;
&lt;br /&gt;
= The Date Command: The Second Command =&lt;br /&gt;
&lt;br /&gt;
= Setting the Selection =&lt;br /&gt;
&lt;br /&gt;
I often forget what day it is. That may be because I need to go outside more often, but, like any programmer, I generally solve my problem&#039;s symptoms with technology rather then addressing the root cause. My solution is to create a command that inserts the date at the location of the cursor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    CmdUtils.setSelection( date.toLocaleDateString() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new function here is &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt;. This inserts the passed-in text onto the page at the location of the cursor. If the cursor is in an editable text or rich-text fields, the text gets dumped there. If the cursor isn&#039;t in an editable area, &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt; will still be able to insert the date. (Even when it isn&#039;t displayed, Firefox always keeps track of a cursor position. To see it, type F7.) Try going to a page, selecting some non-mutable text, and using the command. See, it works! This is particularly useful for commands like &amp;quot;translate&amp;quot;, where you want to replace non-editable text with its translation.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;toLocalDateString()&amp;lt;/code&amp;gt; function is native to Javascript, so if you&#039;re not familiar with it check out the documentation for the Javascript [http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date Date object].&lt;br /&gt;
&lt;br /&gt;
== A Better Preview ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s time to add a better preview to the date command. Let&#039;s have the preview show the date, so that the user will know what to expect when they execute the command. (As a side benefit the user doesn&#039;t even need to execute the command to do a quick check of the day.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  &lt;br /&gt;
  _date: function(){&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    return date.toLocaleDateString();&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = _(&#039;Inserts todays date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;);&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function() {&lt;br /&gt;
    CmdUtils.setSelection( this._date() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&#039;ve done two things here. The first was to factor out the code for getting the date into the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt; function. This way we don&#039;t break [http://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY] by repeating code across the preview and execute functions. Notice that to access the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt;, we use the &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
&lt;br /&gt;
The second thing we&#039;ve done is to add a preview function. The first argument is the DOM element that gets displayed as the preview for your command. Modify &amp;lt;code&amp;gt;pblock&amp;lt;/code&amp;gt; and you modify the preview. In this case, we set the &amp;lt;code&amp;gt;innerHTML&amp;lt;/code&amp;gt; of the preview block to be the message we want.&lt;br /&gt;
&lt;br /&gt;
The other thing I&#039;ve done is to do some string formatting using the &amp;lt;code&amp;gt;renderTemplate()&amp;lt;/code&amp;gt; function. This takes a template string and performs the appropriate substitution given the passed-in JSON object. Templates can handle a wide range of functionality, as we are currently using TrimPath&#039;s [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates JavascriptTemplates]. You should read their site for more documentation. Although JavascriptTemplates has some nice properties, we are contemplating moving to [http://mjtemplate.org/ MJT] sometime soon.&lt;br /&gt;
&lt;br /&gt;
=== A shortcut for localization and rendering templates ===&lt;br /&gt;
&lt;br /&gt;
Note how in the code above, we used the localization wrapper &amp;lt;code&amp;gt;_()&amp;lt;/code&amp;gt; before passing the string to renderTemplate.  Because this is such a very common combination when displaying strings, we have a shortcut for it.  Calling _() with a JSON object as the second argument will automatically trigger &amp;lt;code&amp;gt;CmdUtils.renderTemplate()&amp;lt;/code&amp;gt; on the post-localization string.  So the above preview method could be rewritten more simply as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &#039;Inserts todays date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
    pblock.innerHTML = _( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Networking calls and placeholder previews ===&lt;br /&gt;
&lt;br /&gt;
Previews display something meaningful to the user immediately. If you have a preview that requires an AJAX request&amp;amp;mdash;say, to fetch some search results&amp;amp;mdash;that call might take a while to return. In the meantime, your command should display a placeholder preview giving the user feedback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    pblock.innerHTML = _(&amp;quot;This will show until the AJAX request returns&amp;quot;);&lt;br /&gt;
    // AJAX request&lt;br /&gt;
    pblock.innerHTML = getFromServer();&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the future, we may work on streamlining this process.&lt;br /&gt;
&lt;br /&gt;
== Documentation and Metadata ==&lt;br /&gt;
&lt;br /&gt;
Before you share your command with the world, you should consider adding some attributions to the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you should &amp;lt;em&amp;gt;definitely&amp;lt;/em&amp;gt; add some documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert date&amp;quot;],&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Inserts today&#039;s date.&amp;quot;,&lt;br /&gt;
  help: &amp;quot;If you&#039;re in an editable text area, inserts today&#039;s date, formatted for the current locale.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.description&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.help&amp;lt;/code&amp;gt; attributes are both automatically displayed alongside your command&#039;s name on the command-list page.  (The user can get to this page at any time by issuing the &amp;quot;list ubiquity commands&amp;quot; command.)  HTML tags can be used in both of these strings.&lt;br /&gt;
&lt;br /&gt;
Description is a one-line summary of what the command does, while Help is a longer description that can include examples, caveats, and so on. If your command is simple enough that all you have to say about it fits in one line, it&#039;s OK to use a description alone and leave out the help.&lt;br /&gt;
&lt;br /&gt;
== Sharing it with the World ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our awesome new &amp;quot;date&amp;quot; command, let&#039;s share it with the world. All you have to do is put it the javascript file on the web somewhere, and make an html page linking to it with &amp;quot;link rel&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;pre&amp;gt;&amp;lt;link rel=&amp;quot;commands&amp;quot; href=&amp;quot;http://path-to-js&amp;quot; name=&amp;quot;Title Goes Here&amp;quot; /&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anyone with Ubiquity who visits will get a message offering them the choice of subscribing to your command.&lt;br /&gt;
&lt;br /&gt;
[[Image:Subscribe.png]]&lt;br /&gt;
&lt;br /&gt;
If the user chooses to subscribe to a Regular command feed from an untrusted source, they will get a security warning message before they can install the command.  Because Regular Ubiquity command feeds can execute arbitrary javascript with chrome privileges, subscribing to a command from a website means allowing that site full access to do whatever it wants to your browser.  We want to make sure people understand the dangers before subscribing to commands, so we made the warning page pretty scary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Warning.PNG]]&lt;br /&gt;
&lt;br /&gt;
=== Feed Types ===&lt;br /&gt;
&lt;br /&gt;
Recall that back near the beginning of the tutorial, you set the &amp;quot;feed type&amp;quot; to &amp;quot;Regular&amp;quot;.  As you may have guessed, there&#039;s actually more than one way to write a command feed.  The advantage of Regular feeds is that they let you do whatever you want, so it&#039;s really easy to innovate, but the disadvantages lie in subscribing to misbehaving or malicious code.  You can alternatively write what&#039;s called a &#039;&#039;Locked-Down Feed&#039;&#039;, which is much safer and doesn&#039;t raise a warning page when a user subscribes to it&amp;amp;mdash;but the consequences are that you have less freedom of implementation as a command author.  If you&#039;re interested in learning more about Locked-Down Feeds, check out the [[Labs/Ubiquity/Locked-Down_Feed_Tutorial|Locked-Down Feed Tutorial]].&lt;br /&gt;
&lt;br /&gt;
=== Trust Networks ===&lt;br /&gt;
&lt;br /&gt;
In the future, we&#039;re going to have something set up that we call a &amp;quot;trust network&amp;quot;.  When you try out a Ubiquity command from a website, and determine that the command is safe (or unsafe), you&#039;ll be able to leave an approval (or a warning).  When your friends with Ubiquity installed visit the same site, they&#039;ll see the approval or the warning that you left.  In this way, users will be able to rely on the judgement of other people they already know and trust in order to help them make decisions about whether a command is safe to install or not.&lt;br /&gt;
&lt;br /&gt;
By the way, the reason we call it &amp;quot;subscribing&amp;quot; to a command, rather than &amp;quot;installing&amp;quot; a command, is that if the javascript file changes -- if the site owner adds new commands, removes old commands, or updates existing commands -- all users subscribed to that URL will automatically get the updates.  This will be very convenient for both users and developers, but it will also introduce another type of security risk: just because you decided a command was safe at one point in time doesn&#039;t mean that the command will always remain safe.  For this reason, we&#039;ll need to make sure that the trust network keeps track of when commands have been modified, and notifies users of changes that may make a command unsafe.&lt;br /&gt;
&lt;br /&gt;
== Map Me! Location, Snapshots, and Inserting HTML ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;map&amp;quot; command that comes with Ubiquity is fairly powerful. It&#039;s also fairly complicated&amp;amp;mdash;well, comparatively. It&#039;s still only a couple hundred lines of code. The command, though, can get even more useful. Imagine being able to select some houses on Craigslist, or a list of restaurant names, and Ubiq &amp;quot;map these&amp;quot; to get just the map you want. The concept of &amp;quot;these&amp;quot; puts the power of mashups into the users hands. But I digress. Let&#039;s make a simple command that inserts a map of your current location.&lt;br /&gt;
&lt;br /&gt;
In this command, we use the Google [http://code.google.com/apis/maps/documentation/staticmaps/ static map API] and the Ubiquity function &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; to insert a map of your current location. Ubiquity currently uses the [http://www.maxmind.com/app/api MaxMind] API for trying to guess your location from your IP. That will probably change in the future.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll call this command &amp;lt;code&amp;gt;&amp;quot;map me&amp;quot;&amp;lt;/code&amp;gt; so that it won&#039;t be confused with the standard &amp;lt;code&amp;gt;&amp;quot;map&amp;quot;&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;map me&amp;quot;],&lt;br /&gt;
  &lt;br /&gt;
  _getMapUrl: function() {&lt;br /&gt;
    var loc = CmdUtils.getGeoLocation();&lt;br /&gt;
    var mapUrl = &amp;quot;http://maps.google.com/staticmap?&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    var params = {&lt;br /&gt;
      center: loc.lat + &amp;quot;,&amp;quot; + loc.long,&lt;br /&gt;
      size: &amp;quot;500x400&amp;quot;,&lt;br /&gt;
      zoom: 14,&lt;br /&gt;
      key: &amp;quot;ABQIAAAAGZ11mh1LzgQ8-8LRW3wEShQeSuJunOpTb3RsLsk00-MAdzxmXhQoiCd940lo0KlfQM5PeNYEPLW-3w&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    return mapUrl + jQuery.param( params );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &amp;quot;Inserts a map of your current location: &amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
              &amp;quot;&amp;lt;img src=&#039;${url}&#039;/&amp;gt;&amp;quot;;&lt;br /&gt;
    pblock.innerHTML = _(msg, {url: this._getMapUrl()});&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( ) {&lt;br /&gt;
    CmdUtils.getImageSnapshot( this._getMapUrl(), function(imgData) {&lt;br /&gt;
      CmdUtils.setSelection( &amp;quot;&amp;lt;img src=&#039;&amp;quot; + imgData +&amp;quot;&#039;/&amp;gt;&amp;quot;);&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are three new things here: &amp;lt;code&amp;gt;CmdUtils.setSelection&amp;lt;/code&amp;gt; to set HTML (yep, it can do that); the use of &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt;; and using &amp;lt;code&amp;gt;CmdUtils.snapshotImage()&amp;lt;/code&amp;gt; to capture the bits for the image.&lt;br /&gt;
&lt;br /&gt;
I find getting the location&amp;amp;mdash;as imprecise as IP-based location can be&amp;amp;mdash;useful for doing sensible defaults for location-based commands, like Yelp. &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; returns an object which has the following properties: city, state, country, lat, and long.&lt;br /&gt;
&lt;br /&gt;
Why do we need to use &amp;lt;code&amp;gt;CmdUtils.snapshotImage()&amp;lt;/code&amp;gt;? Because the Google Maps API requires a key that is tied to a particular URL. If we naively inject the image tag into a random web page, the image won&#039;t load because the key doesn&#039;t match that random web page&#039;s URL. Thus, we use the &amp;lt;code&amp;gt;snapshotImage()&amp;lt;/code&amp;gt; function to convert the image into a [http://en.wikipedia.org/wiki/Data:_URI_scheme data url].&lt;br /&gt;
&lt;br /&gt;
There&#039;s also a &amp;lt;code&amp;gt;CmdUtils.snapshotWindow&amp;lt;/code&amp;gt; function, which allows you to get the image data for any tab/window. The function takes a window as the first paramater, and a callback for the second.&lt;br /&gt;
&lt;br /&gt;
= Commands with Arguments =&lt;br /&gt;
&lt;br /&gt;
== Echo ==&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be working towards making some fun and useful commands&amp;amp;mdash;commands that let you control the seething tendrils of the internet with your little pinky. But, let&#039;s start by making a simple command to echo back whatever you type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;echo&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_arb_text,&lt;br /&gt;
               label: &amp;quot;your shout&amp;quot;}],&lt;br /&gt;
  preview: function( pblock, arguments ) {&lt;br /&gt;
    pblock.innerHTML = _(&amp;quot;Will echo: &amp;quot;) + arguments.object.text;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var msg = arguments.object.text + &amp;quot;... &amp;quot; + arguments.object.text + &amp;quot;......&amp;quot;;&lt;br /&gt;
    displayMessage( msg );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This says that the command &amp;quot;echo&amp;quot; takes one argument which is arbitrary text. Whatever text the user enters will get wrapped in an input object and passed into both the preview and execute function.&lt;br /&gt;
&lt;br /&gt;
Try it!  Ubiq &amp;quot;echo hellooooo&amp;quot; and watch what happens.&lt;br /&gt;
&lt;br /&gt;
Ubiquity takes care of parsing the user&#039;s input, so you don&#039;t need to worry about handling prounoun substitution or any of the other natural-language-like features of the Ubiquity parser. Try selecting some text on a page, and Ubiq &amp;quot;echo this&amp;quot;. Ubiquity should now echo the selected text.  &lt;br /&gt;
&lt;br /&gt;
Note that we gave three pieces of information when defining our argument:  its role, its nountype, and its label.  The label is the easiest part: It&#039;s just whatever text you want to have appear in the Ubiquity interface as a prompt for the user.  E.g, if you ubiq &amp;quot;echo&amp;quot;, you will see the label for the argument:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  echo (your shout)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The roles and the nountypes require some more explanation.  We&#039;ll cover each of them in detail next.&lt;br /&gt;
&lt;br /&gt;
=== Argument Roles ===&lt;br /&gt;
&lt;br /&gt;
Your command can take multiple arguments.  Each one is identified by a &amp;quot;role&amp;quot;.  To understand roles, it helps to think of your command name as a verb, and each argument as a noun.  Remember that Ubiquity&#039;s command line is a pseudo-natural-language environment, so it attempts to be as close to natural language grammar as possible.&lt;br /&gt;
&lt;br /&gt;
For example, if you&#039;ve ever used the &amp;lt;code&amp;gt;email&amp;lt;/code&amp;gt; command, you know that it takes up to two arguments: a message and a person.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  email message&lt;br /&gt;
  email to person&lt;br /&gt;
  email message to person&lt;br /&gt;
  email to person message&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In grammatical terms, the message argument is the &amp;quot;direct object&amp;quot; of the verb &amp;quot;email&amp;quot;.  The person argument is an indirect object.  We call it the &amp;quot;goal&amp;quot; of the verb.  So if we were writing the email command, we&#039;d define the arguments like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_arb_text,&lt;br /&gt;
               label: &amp;quot;message&amp;quot;},&lt;br /&gt;
              {role: &amp;quot;goal&amp;quot;,&lt;br /&gt;
               nountype: noun_type_contact,&lt;br /&gt;
               label: &amp;quot;recipient&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because we give the recipient argument the &amp;quot;goal&amp;quot; role, the Ubiquity parser knows to expect the user to type the word &amp;quot;to&amp;quot;.  When the user enters &amp;quot;email hello to Aza&amp;quot;, the parser knows that the word following &amp;quot;to&amp;quot; -- that is, &amp;quot;Aza&amp;quot; -- should be assigned to the recipient argument.&lt;br /&gt;
&lt;br /&gt;
In our simple &amp;quot;echo&amp;quot; command, we expect the user to type &amp;quot;echo hellooooo&amp;quot; or something like that.  The &amp;quot;hellooooo&amp;quot; is the direct object of the verb &amp;quot;echo&amp;quot;, so we give it the &amp;quot;object&amp;quot; role.  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Object&amp;quot; is the most common role.  If a command takes only one argument, that argument is usually an &amp;quot;object&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== What Roles Can I Use? ====&lt;br /&gt;
&lt;br /&gt;
* object   (in &amp;quot;echo helloooo&amp;quot;, hello is the object.)&lt;br /&gt;
* goal    (in &amp;quot;email this to brandon&amp;quot;, brandon is the goal.)&lt;br /&gt;
* source   (in &amp;quot;translate this from spanish&amp;quot;, spanish is the source.)&lt;br /&gt;
* location    (in &amp;quot;yelp pizza near boston&amp;quot;, boston is the location.)&lt;br /&gt;
* time    (in &amp;quot;book a flight on thursday&amp;quot;, thursday is the time.)&lt;br /&gt;
* instrument  (in &amp;quot;search monkeys with google&amp;quot;, google is the instrument.)&lt;br /&gt;
* format   (in &amp;quot;check weather in celsius&amp;quot;, celsius is the format.)&lt;br /&gt;
* modifier  (in &amp;quot;get email address for chris&amp;quot;, chris is the modifier.)&lt;br /&gt;
* alias   (in &amp;quot;twitter this as jono&amp;quot;, jono is the alias.)&lt;br /&gt;
&lt;br /&gt;
[https://wiki.mozilla.org/Labs/Ubiquity/Parser_2/Semantic_Roles More information about these roles].&lt;br /&gt;
&lt;br /&gt;
=== The Arguments Object ===&lt;br /&gt;
&lt;br /&gt;
When your execute method is called, it is passed a single object that encapsulates the values for all arguments.&lt;br /&gt;
&lt;br /&gt;
When your preview method is called, it is passed this object, too.&lt;br /&gt;
&lt;br /&gt;
The object has one attribute corresponding to each role.  In our example above, the command accepts only an object-role argument, so the preview and execute methods get passed an argument with an &amp;quot;arguments.object&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
If we made a command, like email, that takes an object-role argument and a goal-role argument, its preview and execute methods would get passed an argument with &amp;quot;arguments.object&amp;quot; and &amp;quot;arguments.goal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
arguments.object (or arguments.goal) has several attributes of its own:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments.object.text  // a string of the input in plain text, without formatting&lt;br /&gt;
  arguments.object.html  // a string of the input in formatted html, including tags&lt;br /&gt;
  arguments.object.data  // for non-text input types, an arbitrary data object&lt;br /&gt;
  arguments.object.summary // for very long inputs, an abbreviated display string&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our example command only cares about the &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; attribute of the input, because it simply wants plain text.  Often, when the user invokes your command by typing a few short words into the input box, &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.html&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; will all have exactly the same value, and &amp;lt;code&amp;gt;.data&amp;lt;/code&amp;gt; will be null.  Many, if not most, commands that you write will only care about the text value.  Nevertheless, the other versions of the input data are provided to you in case they differ from &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; and in case your command has a use for them.&lt;br /&gt;
&lt;br /&gt;
== Introduction to Noun Types ==&lt;br /&gt;
&lt;br /&gt;
Noun types specify what &#039;&#039;kind&#039;&#039; of input your command can accept for each one of its arguments.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;echo&amp;quot; command, we wanted the object-role argument to accept any text whatsoever, so for its nountype we passed in the predefined &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; object.  This object accepts any arbitrary text as a valid argument and passes it to the command unchanged.&lt;br /&gt;
&lt;br /&gt;
This is OK for very simple commands, like echoing back the user&#039;s input.  But for commands that take structured data, you will want to use more specific nountypes.&lt;br /&gt;
&lt;br /&gt;
For example, if a command can take a date (like the &amp;quot;check calendar&amp;quot; command), you would want to use &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; as the nountype of the argument.  &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; provides several benefits to your command:  it does all of the date parsing for you; it suggests dates that the user might want to enter (for instance, it defaults to today&#039;s date).  And, it lets the parser know that your command takes a date.  This is useful because when the user selects a date on a page and invokes Ubiquity, your command -- along with &amp;quot;check calendar&amp;quot; -- will be one of the top suggestions.&lt;br /&gt;
&lt;br /&gt;
You can write your own noun types -- we&#039;ll get into that later.  For now, let&#039;s take a look at the built-in nountypes that your command can use.  These include:&lt;br /&gt;
&lt;br /&gt;
* noun_arb_text (Arbitrary text)&lt;br /&gt;
* noun_type_language (Name of a human language, e.g. &amp;quot;English&amp;quot;, &amp;quot;Japanese&amp;quot;)&lt;br /&gt;
* noun_type_url (A URL)&lt;br /&gt;
* noun_type_contact (An email address from your address book)&lt;br /&gt;
* noun_type_date (A date, in any format, or a word like &amp;quot;tomorrow&amp;quot;)&lt;br /&gt;
* noun_type_time (A time, in any format)&lt;br /&gt;
* noun_type_percentage&lt;br /&gt;
* noun_type_address&lt;br /&gt;
* noun_type_tab&lt;br /&gt;
* noun_type_searchengine&lt;br /&gt;
* noun_type_tag&lt;br /&gt;
* noun_type_geolocation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with writing commands, you should check out the [http://hg.toolness.com/ubiquity-firefox/file/6caa9d66b3bb/ubiquity/chrome/content/nlparser/en/nountypes.js nountypes.js], which has the implementation for most of the noun-types.  You can see what noun types are already available for your commands to use, what still needs to be written, and where the existing implementations could use improvement &amp;amp;mdash; and then come [[Labs/Ubiquity#Participation|get involved]] to help us improve them.&lt;br /&gt;
&lt;br /&gt;
=== Regexps as Noun Types ===&lt;br /&gt;
&lt;br /&gt;
If none of the nountypes above is what you&#039;re looking for, there are several ways to define your own.  The simplest is to use a regular expression.  Suppose that (for whatever odd reason) you wanted your command to accept only arguments that begin with the letter N.  The following regexp matches words that start with N:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  /^[nN]/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You could use it as a noun type, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: /^[nN]/,&lt;br /&gt;
               label: &amp;quot;word that starts with n&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note that you do &#039;&#039;not&#039;&#039; put quotes around the regexp.)&lt;br /&gt;
&lt;br /&gt;
A regexp nountype will reject input that doesn&#039;t match, but it doesn&#039;t know how to help the user by suggesting appropriate input.&lt;br /&gt;
&lt;br /&gt;
=== Lists as Noun Types ===&lt;br /&gt;
&lt;br /&gt;
Suppose you&#039;re writing a command that takes a color as an argument (perhaps it outputs a hexadecimal RGB representation of that color.)  To make a nountype that accepts colors, you can simply pass in an array of strings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  names: [&amp;quot;convert color&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: [&amp;quot;red&amp;quot;, &amp;quot;orange&amp;quot;, &amp;quot;yellow&amp;quot;, &amp;quot;green&amp;quot;, &lt;br /&gt;
                          &amp;quot;blue&amp;quot;, &amp;quot;violet&amp;quot;, &amp;quot;black&amp;quot;, &amp;quot;white&amp;quot;,&lt;br /&gt;
                          &amp;quot;grey&amp;quot;, &amp;quot;brown&amp;quot;, &amp;quot;beige&amp;quot;, &amp;quot;magenta&amp;quot;,&lt;br /&gt;
                          &amp;quot;cerulean&amp;quot;, &amp;quot;puce&amp;quot;],&lt;br /&gt;
               label: &amp;quot;color to convert&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One benefit of using a list is that the parser can use it offer the user suggestions.   If the user enters &amp;quot;get-color bl&amp;quot;, for instance, Ubiquity will be able to suggest &amp;quot;black&amp;quot; and &amp;quot;blue&amp;quot; as the two valid completions based on the input.  This makes list-based nountypes very useful for any command that can accept only a finite set of values.&lt;br /&gt;
&lt;br /&gt;
=== Writing a Noun Type Object ===&lt;br /&gt;
&lt;br /&gt;
Of course, not every type of noun you&#039;d be interested in can be represented&lt;br /&gt;
as a finite list or as a regexp.  If you want to be able to accept or reject input based on some algorithmic test, you can do so by writing a custom JavaScript object that implements a &amp;lt;code&amp;gt;suggest()&amp;lt;/code&amp;gt; method (and, optionally, a &amp;lt;code&amp;gt;default()&amp;lt;/code&amp;gt; method.)&lt;br /&gt;
&lt;br /&gt;
There is an example of how to do this in the section on the tab commands, below.&lt;br /&gt;
&lt;br /&gt;
== Insert Email: the Contact noun type ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s take a look at one of the built-in noun-types: &amp;lt;code&amp;gt;noun_type_contact&amp;lt;/code&amp;gt;. This lets Ubiquity know to expect a person (either by name or email address). By using the noun-type, Ubiquity will also autocomplete to known people while the user is entering the command. This is what the built-in Ubiquity command &amp;quot;email&amp;quot; uses.&lt;br /&gt;
&lt;br /&gt;
At the moment, Ubiquity figures out what people you know through reading your Gmail contacts. In this prototyped version, you&#039;ll need to use Gmail and be logged in for for Ubiquity to know who you know. Eventually, we&#039;d like to be able to interface with all major web-mail sites, as well as desktop software like Thunderbird.&lt;br /&gt;
&lt;br /&gt;
Enough rambling. It&#039;s time for a command. I constantly find that I need to fetch someone&#039;s email address to paste into a text field because I don&#039;t know it off-hand. This command solves that by letting you insert someone&#039;s email address using autocomplete.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;insert email&amp;quot;],&lt;br /&gt;
  arguments: {modifier: noun_type_contact},&lt;br /&gt;
  preview: &amp;quot;Inserts someone&#039;s email address by name.&amp;quot;,&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    CmdUtils.setSelection( arguments.modifier.text );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To try this out, Ubiq &amp;quot;insert email for &amp;quot; and then the first few letters of someone you email often.&lt;br /&gt;
&lt;br /&gt;
=== Shorter Argument Declarations ===&lt;br /&gt;
&lt;br /&gt;
Notice that we used a shortcut for declaring the arguments.  In the long form, we would have had to say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: [{role: &amp;quot;modifier&amp;quot;,&lt;br /&gt;
               nountype: noun_type_contact,&lt;br /&gt;
               label: &amp;quot;contact&amp;quot;}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
but if we don&#039;t care about specifying a label for the argument, we can get away with using a single object for &amp;quot;arguments&amp;quot;, with the roles as the property names, and the nountypes as the property values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: {modifier: noun_type_contact}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we had several arguments, and none of them needed labels, we could say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  arguments: {object: noun_arb_text, modifier: noun_type_contact}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and so on.&lt;br /&gt;
&lt;br /&gt;
Aza writes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
This one command sums up what I love about Ubiquity. In 8 lines of code, I can &lt;br /&gt;
fundamentally enhance the browser&#039;s functionality. Doing the same thing using &lt;br /&gt;
a normal Firefox extension methodology takes pages and pages of code&amp;amp;mdash;and  the interface would take more thought still. Doing the same thing using a bookmarklet would require a server-side component (to get around cross-site Ajax request ban) as well as forcing the user to give up their email password.&lt;br /&gt;
&lt;br /&gt;
Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== TinyURL: Network Calls and jQuery (and the URL noun type)==&lt;br /&gt;
&lt;br /&gt;
Often while writing emails, I&#039;ll discover that I&#039;ve pasted in a URL long enough to be used for unfortunate analogies. I&#039;d like to be able to quickly turn that into a [http://en.wikipedia.org/wiki/Tinyurl TinyURL]&amp;amp;mdash;but the process of making a TinyURL involves lots of fiddly steps. Ubiquity to the rescue.&lt;br /&gt;
&lt;br /&gt;
Because we include [http://en.wikipedia.org/wiki/jQuery jQuery] with Ubiquity, it is simple to perform Ajax calls as well as parse returning data. TinyUrl.com provides an easy to use RESTful API where you pass a URL and it returns its shortened form. We use that API in this command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;tinyurl&amp;quot;],&lt;br /&gt;
  arguments: [{role: &amp;quot;object&amp;quot;,&lt;br /&gt;
               nountype: noun_type_url,&lt;br /&gt;
               label: &amp;quot;url to shorten&amp;quot;}],&lt;br /&gt;
  preview: &amp;quot;Replaces the selected URL with a TinyUrl.&amp;quot;,&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var baseUrl = &amp;quot;http://tinyurl.com/api-create.php&amp;quot;;&lt;br /&gt;
    var params = {url: arguments.object.text};&lt;br /&gt;
    jQuery.get( baseUrl, params, function( tinyUrl ) {&lt;br /&gt;
      CmdUtils.setSelection( tinyUrl );&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;noun_type_url&amp;lt;/code&amp;gt; is a useful nountype because it defaults to the URL of the page that you are currently on.  If that is in fact the URL that the user wants, then they don&#039;t have to type it or even select it.&lt;br /&gt;
&lt;br /&gt;
jQuery is a powerful tool. With it, you can fairly effortlessly cherry-pick the data you need from RSS feeds, XML, and all sorts of other data formats. It also makes doing in-preview animations a breeze.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Twitter: Putting It All Together =&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now covered everything we need to cover in order to write a command that allows us to [http://en.wikipedia.org/wiki/Twitter Twitter] from Ubiquity.  The code below is the actual source code of the Twitter command as it appears in Ubiquity 0.5.&lt;br /&gt;
&lt;br /&gt;
Many thanks to [http://theunfocused.net/moz/ubiquity/verbs/ Blair McBride] for writing this command.  The source code is a bit more intricate than anything we&#039;ve seen so far, but it&#039;s built using exactly the same basic pieces -- and demonstrates nearly all of those pieces in action.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const TWITTER_STATUS_MAXLEN = 140;&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;twitter&amp;quot;, &amp;quot;tweet&amp;quot;, &amp;quot;share using twitter&amp;quot;],&lt;br /&gt;
  arguments: [&lt;br /&gt;
    {role: &amp;quot;object&amp;quot;, label: &#039;status&#039;, nountype: noun_arb_text},&lt;br /&gt;
    {role: &amp;quot;alias&amp;quot;, nountype: noun_type_twitter_user}&lt;br /&gt;
  ],&lt;br /&gt;
  icon: &amp;quot;http://twitter.com/favicon.ico&amp;quot;,&lt;br /&gt;
  description:&lt;br /&gt;
  &amp;quot;Sets your Twitter status to a message of at most 160 characters.&amp;quot;,&lt;br /&gt;
  help: (&amp;quot;You&#039;ll need a &amp;lt;a href=\&amp;quot;http://twitter.com\&amp;quot;&amp;gt;Twitter account&amp;lt;/a&amp;gt;,&amp;quot; +&lt;br /&gt;
         &amp;quot; obviously.  If you&#039;re not already logged in&amp;quot; +&lt;br /&gt;
         &amp;quot; you&#039;ll be asked to log in.&amp;quot;),&lt;br /&gt;
  preview: function(previewBlock, args) {&lt;br /&gt;
    var statusText = (args.object ? args.object.text : &#039;&#039;);&lt;br /&gt;
    var usernameText = &amp;quot;&amp;quot;;&lt;br /&gt;
    if (args.alias) {&lt;br /&gt;
      usernameText = args.alias.text;&lt;br /&gt;
    } else if (args.as) {&lt;br /&gt;
      usernameText = args.as.text;&lt;br /&gt;
    }&lt;br /&gt;
    var previewTemplate = (&lt;br /&gt;
      &amp;quot;&amp;lt;div class=&#039;twitter&#039;&amp;gt;&amp;quot;+_(&amp;quot;Updates your Twitter status ${username} to:&amp;quot;)+&amp;quot;&amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
      &amp;quot;&amp;lt;b class=&#039;status&#039;&amp;gt;${status}&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;quot; +&lt;br /&gt;
      _(&amp;quot;Characters remaining: &amp;lt;b&amp;gt;${chars}&amp;lt;/b&amp;gt;&amp;quot;) +&lt;br /&gt;
      &amp;quot;&amp;lt;p&amp;gt;&amp;lt;small&amp;gt;&amp;quot;+_(&amp;quot;tip: tweet @mozillaubiquity for help&amp;quot;)+&amp;quot;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;);&lt;br /&gt;
    var truncateTemplate = (&lt;br /&gt;
      &amp;quot;&amp;lt;strong&amp;gt;&amp;quot;+_(&amp;quot;The last &amp;lt;b&amp;gt;${truncate}&amp;lt;/b&amp;gt; characters will be truncated!&amp;quot;)+&amp;quot;&amp;lt;/strong&amp;gt;&amp;quot;);&lt;br /&gt;
    var previewData = {&lt;br /&gt;
      status: &amp;lt;&amp;gt;{statusText}&amp;lt;/&amp;gt;.toXMLString(),&lt;br /&gt;
      username: usernameText &amp;amp;&amp;amp; _(&amp;quot;(For user &amp;lt;b&amp;gt;${usernameText}&amp;lt;/b&amp;gt;)&amp;quot;),&lt;br /&gt;
      chars: TWITTER_STATUS_MAXLEN - statusText.length&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var previewHTML = CmdUtils.renderTemplate(&lt;br /&gt;
                        CmdUtils.renderTemplate(previewTemplate, previewData),&lt;br /&gt;
                        {usernameText:usernameText});&lt;br /&gt;
&lt;br /&gt;
    if (previewData.chars &amp;lt; 0) {&lt;br /&gt;
      var truncateData = {&lt;br /&gt;
        truncate: 0 - previewData.chars&lt;br /&gt;
      };&lt;br /&gt;
&lt;br /&gt;
      previewHTML += CmdUtils.renderTemplate(truncateTemplate, truncateData);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    previewBlock.innerHTML = previewHTML;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(args) {&lt;br /&gt;
    var statusText = args.object.text;&lt;br /&gt;
    if(statusText.length &amp;lt; 1) {&lt;br /&gt;
      this._show(_(&amp;quot;requires a status to be entered&amp;quot;));&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var updateUrl = &amp;quot;https://twitter.com/statuses/update.json&amp;quot;;&lt;br /&gt;
    var updateParams = {&lt;br /&gt;
      source: &amp;quot;ubiquity&amp;quot;,&lt;br /&gt;
      status: statusText&lt;br /&gt;
      //dont cut the input since sometimes, the user selects a big url,&lt;br /&gt;
      //and the total lenght is more than 140, but tinyurl takes care of that&lt;br /&gt;
    };&lt;br /&gt;
    var me = this;&lt;br /&gt;
&lt;br /&gt;
    function sendMessage() {&lt;br /&gt;
      jQuery.ajax({&lt;br /&gt;
        type: &amp;quot;POST&amp;quot;,&lt;br /&gt;
        url: updateUrl,&lt;br /&gt;
        data: updateParams,&lt;br /&gt;
        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
        error: function() {&lt;br /&gt;
          me._show(_(&amp;quot;error - status not updated&amp;quot;));&lt;br /&gt;
        },&lt;br /&gt;
        success: function() {&lt;br /&gt;
          me._show(/^d /.test(statusText)&lt;br /&gt;
                   ? _(&amp;quot;direct message sent&amp;quot;)&lt;br /&gt;
                   : _(&amp;quot;status updated&amp;quot;));&lt;br /&gt;
        },&lt;br /&gt;
        username: login.username,&lt;br /&gt;
        password: login.password&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var login;&lt;br /&gt;
    var alias = args.alias;&lt;br /&gt;
    if (alias &amp;amp;&amp;amp; alias.text &amp;amp;&amp;amp; alias.data) {&lt;br /&gt;
      login = alias.data;&lt;br /&gt;
      sendMessage();&lt;br /&gt;
    } else {&lt;br /&gt;
      login = {username: null,&lt;br /&gt;
               password: null};&lt;br /&gt;
      if (alias &amp;amp;&amp;amp; alias.text)&lt;br /&gt;
        login.username = alias.text;&lt;br /&gt;
      sendMessage();&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  _show: function(txt){&lt;br /&gt;
    displayMessage({icon: this.icon, title: this.name, text: txt});&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Switching Tabs =&lt;br /&gt;
&lt;br /&gt;
The final command in this tutorial is for switching between tabs. The end goal is this: type a few keys to that matches the title of an open tab (in any window), hit return, and you&#039;ve switched to that tab.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll write this command in two steps. The first step is creating a tab noun-type. The second step is using that noun-type to create the tab-switching command.&lt;br /&gt;
&lt;br /&gt;
== Switching: Writing your own Noun-Types ==&lt;br /&gt;
&lt;br /&gt;
A noun-type needs to only have two things: A &amp;lt;code&amp;gt;label&amp;lt;/code&amp;gt; and a &amp;lt;code&amp;gt;suggest()&amp;lt;/code&amp;gt; function.  It can optionally also have a &amp;lt;code&amp;gt;default()&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
The label is what shows up when the command prompts for input. Suggest returns a list of input objects, each one containing the name of a matching tab. We&#039;re using [http://developer.mozilla.org/en/docs/FUEL FUEL] to interact with the browser, which is where the &amp;quot;Application&amp;quot; variable comes from.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_tab = {&lt;br /&gt;
  label: &amp;quot;tab name&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  // Returns all tabs from all windows.&lt;br /&gt;
  getTabs: function(){&lt;br /&gt;
    var tabs = {};&lt;br /&gt;
&lt;br /&gt;
    for( var j=0; j &amp;lt; Application.windows.length; j++ ) {&lt;br /&gt;
      var window = Application.windows[j];&lt;br /&gt;
      for (var i = 0; i &amp;lt; window.tabs.length; i++) {&lt;br /&gt;
        var tab = window.tabs[i];&lt;br /&gt;
        tabs[tab.document.title] = tab;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return tabs;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  suggest: function( text, html, callback ) {&lt;br /&gt;
    &lt;br /&gt;
    var suggestions  = [];&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
&lt;br /&gt;
    //TODO: implement a better match algorithm&lt;br /&gt;
    for ( var tabName in tabs ) {&lt;br /&gt;
      if (tabName.match(text, &amp;quot;i&amp;quot;))&lt;br /&gt;
	 suggestions.push( CmdUtils.makeSugg(tabName) );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Return a list of input objects, limited to at most five:&lt;br /&gt;
    return suggestions.splice(0, 5);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The suggest method of a noun type always gets passed both text and html.  If the input is coming from a part of a web page that the user has selected, these&lt;br /&gt;
values can be different: they are both strings, but the html value contains markup tags while the text value does not. The Tab noun type only cares about the plain text of the tab name, so we ignore the value of html.&lt;br /&gt;
&lt;br /&gt;
The callback argument is for use by nountypes that need to run asynchronously, i.e. becaus they need to do network calls to generate suggestions.  The callback is a function; instead of returning a list of suggestions right away, an asynchronous noun type can call the callback with each suggestion it generates.  More on this later; the tab noun type generates all its suggestions right away, so it just returns them instead of using the callback.&lt;br /&gt;
&lt;br /&gt;
We use the convenience function &amp;lt;code&amp;gt;CmdUtils.makeSugg()&amp;lt;/code&amp;gt; to generate an&lt;br /&gt;
input object of the type that the Ubiquity parser expects.  The full signature of this function is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.makeSugg( text, html, data );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
but html and data are optional and need be provided only if they differ from text.&lt;br /&gt;
&lt;br /&gt;
If the text or html input is very long, &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; generates a summary for us, and puts it in the &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; attribute of the input object.&lt;br /&gt;
&lt;br /&gt;
We could have accomplished mostly the same thing without calling &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; by returning a list of anonymous objects like these:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ text: tabName,&lt;br /&gt;
  html: tabName,&lt;br /&gt;
  data: null,&lt;br /&gt;
  summary: tabName };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The input objects that our &amp;lt;code&amp;gt;.suggest()&amp;lt;/code&amp;gt; method generates are the same objects that will eventually get passed in to the &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; methods of any commands that use this noun type.&lt;br /&gt;
&lt;br /&gt;
== Switching Tabs: The Command ==&lt;br /&gt;
&lt;br /&gt;
Now that we are armed with the tab noun-type, it is easy to make the tab-switching command. Again, we use FUEL to focus the selected tab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;tab&amp;quot;],&lt;br /&gt;
  arguments: {object: noun_type_tab},&lt;br /&gt;
&lt;br /&gt;
  execute: function( arguments ) {&lt;br /&gt;
    var tabName = arguments.object.text;&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
    tabs[tabName]._window.focus();&lt;br /&gt;
    tabs[tabName].focus();&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  preview: function( pblock, arguments ) {&lt;br /&gt;
    var tabName = arguments.object.text;&lt;br /&gt;
    if( tabName.length &amp;gt; 1 ){&lt;br /&gt;
        var msg = &amp;quot;Changes to &amp;lt;b style=\&amp;quot;color:yellow\&amp;quot;&amp;gt;${tab}&amp;lt;/b&amp;gt; tab.&amp;quot;;&lt;br /&gt;
        pblock.innerHTML = _(msg, {tab: tabName});&lt;br /&gt;
     }&lt;br /&gt;
    else&lt;br /&gt;
      pblock.innerHTML = _(&amp;quot;Switch to a tab by name.&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Development Hints =&lt;br /&gt;
&lt;br /&gt;
You now know all you need to know to get started developing useful Ubiquity commands of your own.&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous tips that didn&#039;t fit elsewhere on this page, that may make development easier for you.&lt;br /&gt;
&lt;br /&gt;
== The Source Code of Built-In Commands ==&lt;br /&gt;
&lt;br /&gt;
Looking at the source code of built-in commands and built-in noun types can be a very useful aid to development.  If you have the source checkout of Ubiquity (see [Labs/Ubiquity/Ubiquity_0.1_Development_Tutorial | the development tutorial] to find out how to get this), the source code can be found in the files:&lt;br /&gt;
&lt;br /&gt;
 ubiquity/standard-feeds/&lt;br /&gt;
 ubiquity/builtin-feeds/en/builtincmds.js&lt;br /&gt;
 ubiquity/modules/nountypes.js&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a checkout of the source code, you can view the latest version on the web here:&lt;br /&gt;
&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/standard-feeds/ standard-feeds]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/builtin-feeds/en/builtincmds.js builtincmds.js]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/modules/nountypes.js nountypes.js]&lt;br /&gt;
&lt;br /&gt;
== Interacting with Other Extensions ==&lt;br /&gt;
&lt;br /&gt;
http://img363.imageshack.us/img363/1906/picture7cm5.png&lt;br /&gt;
&lt;br /&gt;
There isn&#039;t much to say here besides that it&#039;s easy. For example, here&#039;s a command (thanks to [http://foyrek.com/lyrics.html Abimanyu Raja] for writing this code) that finds the lyrics for a song. You can simply Ubiq something like &amp;quot;get lyrics for wild international&amp;quot; but the command will also interface with the FoxyTunes extension (if it is installed) and add the currently playing song to the suggestion list. Interfacing with other extensions, too, is easy because you can view the source code for every Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_song = {&lt;br /&gt;
  label: &amp;quot;song name&amp;quot;,&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    var suggestions  = [CmdUtils.makeSugg(text)];&lt;br /&gt;
    if(window.foxytunesGetCurrentTrackTitle){&lt;br /&gt;
   suggestions.push(CmdUtils.makeSugg(window.foxytunesGetCurrentTrackTitle()));&lt;br /&gt;
  	}&lt;br /&gt;
    return suggestions;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;get lyrics&amp;quot;],&lt;br /&gt;
  arguments: {modifier: noun_type_song},&lt;br /&gt;
  preview: function(pblock, arguments) {&lt;br /&gt;
    &lt;br /&gt;
    searchText = jQuery.trim(arguments.modifier.text);&lt;br /&gt;
    if(searchText.length &amp;lt; 1) {&lt;br /&gt;
      pblock.innerHTML = _(&amp;quot;Searches for lyrics of the song&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var previewTemplate = &amp;quot;Searches for the lyrics of &amp;lt;b&amp;gt;${query}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    pblock.innerHTML = _(previewTemplate, {query: searchText});&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(arguments) {&lt;br /&gt;
    var url = &amp;quot;http://www.google.com/search?q={QUERY}&amp;quot;&lt;br /&gt;
    var query = arguments.object.text + _(&amp;quot; lyrics&amp;quot;);&lt;br /&gt;
    var urlString = url.replace(&amp;quot;{QUERY}&amp;quot;, query);&lt;br /&gt;
    Utils.openUrlInBrowser(urlString);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementing Asynchronous Noun Suggestions ==&lt;br /&gt;
&lt;br /&gt;
The noun types we&#039;ve seen so far in this tutorial have all worked synchronously, returning their suggestions right away. However, Ubiquity also supports asynchronous noun suggestions. These are useful for when a noun type needs to do some potentially time-consuming work before it can make suggestions &amp;amp;mdash; most commonly when it needs to call an external service.&lt;br /&gt;
&lt;br /&gt;
Implementing asynchronous suggestions is simple. Whenever the Ubiquity parser calls a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function, it includes a callback function that may be used to send suggestions back to the parser as they become available. In the most typical case, the noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function makes an AJAX request, invoking the parser&#039;s callback function from within the callback function for the AJAX request.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example: a noun type that suggests [http://www.freebase.com/ Freebase] topics based on the text the user has typed or selected, and a barebones &amp;lt;code&amp;gt;freebase-lookup&amp;lt;/code&amp;gt; command that uses the noun type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_freebase_topic = {&lt;br /&gt;
  name: &amp;quot;Freebase topic&amp;quot;,&lt;br /&gt;
  label: &amp;quot;topic&amp;quot;,&lt;br /&gt;
  suggest: function freebase_topic_suggest(text, html, callback) {&lt;br /&gt;
    return [&lt;br /&gt;
      CmdUtils.makeSugg(text),&lt;br /&gt;
      $.ajax({&lt;br /&gt;
        url: &amp;quot;http://www.freebase.com/api/service/search&amp;quot;,&lt;br /&gt;
        dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
        data: {prefix: text, limit: 5},&lt;br /&gt;
        success: function suggestTopics(response) {&lt;br /&gt;
          if (response.status === &amp;quot;200 OK&amp;quot;)&lt;br /&gt;
            callback([CmdUtils.makeSugg(result.name, result.name, result)&lt;br /&gt;
                      for each (result in response.result)]);&lt;br /&gt;
        },&lt;br /&gt;
      })];&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  names: [&amp;quot;lookup on freebase&amp;quot;],&lt;br /&gt;
  arguments: {object: noun_type_freebase_topic},&lt;br /&gt;
  preview: function preview(pblock, args) {&lt;br /&gt;
    pblock.innerHTML = _((&amp;quot;Go to the Freebase topic page for &amp;quot; +&lt;br /&gt;
                          &amp;quot;{if text}${text}{else}any topic{/if}.&amp;quot;),&lt;br /&gt;
                         args.object);&lt;br /&gt;
  },&lt;br /&gt;
  execute: function goToFreebase({object: {text, data}}) {&lt;br /&gt;
    Utils.openUrlInBrowser(&lt;br /&gt;
      text&lt;br /&gt;
      ? (data&lt;br /&gt;
         ? &amp;quot;http://www.freebase.com/view&amp;quot; + data.id&lt;br /&gt;
         : (&amp;quot;http://www.freebase.com/search?query=&amp;quot; +&lt;br /&gt;
            encodeURIComponent(text)))&lt;br /&gt;
      : &amp;quot;http://www.freebase.com/&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A few notes:&lt;br /&gt;
&lt;br /&gt;
* The parser&#039;s callback function expects only one suggestion (not an array of suggestions), so it must be called one time for each suggestion, even if the noun type has multiple suggestions available at the same time (as in the Freebase example above). This is a bit different from the synchronous case, in which the &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function is expected to return an array.&lt;br /&gt;
* A noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function typically returns an empty array when it intends to make asynchronous suggestions, but it can return one or more suggestions synchronously if it has them available.&lt;br /&gt;
* Because the work being done to generate asynchronous suggestions is generally somewhat expensive, and because a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function may be called for every keystroke the user makes, you should probably consider implementing a delay before starting the work and/or caching the work at some level. Ubiquity currently leaves this up to each noun type individually.&lt;br /&gt;
* A much more robust implementation of Freebase-derived noun types can be found [http://graynorton.com/ubiquity/freebase-nouns.html here].&lt;br /&gt;
&lt;br /&gt;
== Running on page load and startup ==&lt;br /&gt;
&lt;br /&gt;
Commands aren&#039;t the only thing you can put in a command feed.  You can also include functions you want to be run automatically at page-load time and at Firefox startup time.&lt;br /&gt;
&lt;br /&gt;
In order to run some code on page load, you simply have to prefix your function with &amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;. For example, if you want to say &amp;quot;Hi&amp;quot; every time a page is loaded, your code would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function pageLoad_hi(){&lt;br /&gt;
 displayMessage(&amp;quot;hi&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you modify the function and want to see the changes, remember to first invoke Ubiquity. Although your function like above, might not be a Ubiquity command, this is necessary to refresh the cached code.&lt;br /&gt;
&lt;br /&gt;
Similarly, if you want to run some code everytime Firefox starts up, you just have to prefix the function with &amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
The awesome thing about these functions is the ability to develop whole Firefox extensions (that require minimal UI) as Ubiquity plugins in lesser lines of code. You don&#039;t need to worry about chrome.manifest or install.rdf. Another added benefit is that you never have to restart your Firefox during development unless of course, you are running code on Firefox startup.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;http://img388.imageshack.us/img388/3086/picture5eo9.png&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code for [http://foyrek.com/keyscape.js Keyscape] which is a Ubiquity command that makes use of &amp;lt;code&amp;gt;pageLoad&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;startup&amp;lt;/code&amp;gt; to recreate the functionality of the [https://addons.mozilla.org/en-US/firefox/addon/339 Search Keys extension] by Jesse Ruderman. In line with Ubiquity&#039;s aim to let you do things quicker using your keyboard, this command lets you go to search results on Google by just pressing a number. It&#039;ll add hints to show the number of each link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//A lot of this code is borrowed from the Search Keys extension&lt;br /&gt;
//Many thanks to Jeese Ruderman&lt;br /&gt;
&lt;br /&gt;
function startup_keyscape() {&lt;br /&gt;
  window.addEventListener(&amp;quot;keydown&amp;quot;, keyscape_down, true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function pageLoad_keyscape(doc){&lt;br /&gt;
&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
  //If we are on about: or chrome://, just return&lt;br /&gt;
  if(uri.scheme != &amp;quot;http&amp;quot;)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  //Check if the page we are on is google&lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	      		    &lt;br /&gt;
    for(var num=1; num&amp;lt;=10; num++){&lt;br /&gt;
&lt;br /&gt;
      var link = jQuery(doc.body).find(&#039;a.l&#039;)[num-1];&lt;br /&gt;
      &lt;br /&gt;
      if( link ){&lt;br /&gt;
&lt;br /&gt;
        var hint = doc.createElementNS(&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;, &amp;quot;span&amp;quot;);&lt;br /&gt;
        hint.style.color = &amp;quot;blue&amp;quot;;&lt;br /&gt;
        hint.style.background = &amp;quot;white&amp;quot;;&lt;br /&gt;
        hint.style.padding = &amp;quot;1px 2px 1px 2px&amp;quot;;&lt;br /&gt;
        hint.style.marginLeft = &amp;quot;.5em&amp;quot;;&lt;br /&gt;
        hint.appendChild(doc.createTextNode(num == 10 ? 0 : num));&lt;br /&gt;
        link.parentNode.insertBefore(hint, link.nextSibling);&lt;br /&gt;
      }  		&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_isGoogle(uri){&lt;br /&gt;
  return uri.host.indexOf(&amp;quot;google&amp;quot;) != -1 &lt;br /&gt;
	 &amp;amp;&amp;amp; (uri.path.substr(0,8) == &amp;quot;/search?&amp;quot; &lt;br /&gt;
         || uri.path.substr(0,8) == &amp;quot;/custom?&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_down(event){&lt;br /&gt;
&lt;br /&gt;
  var doc =  Application.activeWindow.activeTab.document;	&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
 &lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	&lt;br /&gt;
   var key = parseInt(event.keyCode || event.charCode);	&lt;br /&gt;
   var num;&lt;br /&gt;
	&lt;br /&gt;
   if(48 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 57) //number keys&lt;br /&gt;
     num = key - 48;&lt;br /&gt;
   else if(96 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 105) //numeric keypad with numlock on&lt;br /&gt;
     num = key - 96;&lt;br /&gt;
   else&lt;br /&gt;
     return;&lt;br /&gt;
&lt;br /&gt;
   //Don&#039;t do anything if we are in a textbox&lt;br /&gt;
   //or some other related elements&lt;br /&gt;
   var elt = window.document.commandDispatcher.focusedElement;&lt;br /&gt;
   &lt;br /&gt;
   if (elt) {&lt;br /&gt;
     var ln = new String(elt.localName).toLowerCase();&lt;br /&gt;
     if (ln == &amp;quot;input&amp;quot; || ln == &amp;quot;textarea&amp;quot; || ln == &amp;quot;select&amp;quot; || ln == &amp;quot;isindex&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
   //Get the link url from the search results page&lt;br /&gt;
   var url_dest = jQuery(doc.body).find(&#039;a.l&#039;).eq(num-1).attr(&#039;href&#039;);&lt;br /&gt;
   &lt;br /&gt;
   if(event.altKey){&lt;br /&gt;
     //Open in new tab&lt;br /&gt;
     Application.activeWindow.open(Utils.url(url_dest));&lt;br /&gt;
   }else{&lt;br /&gt;
     //Open in same tab&lt;br /&gt;
     doc.location.href = url_dest;&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If Ubiquity does indeed become ubiquitous, a lot of extensions can be re-written as Ubiquity commands. This is much nicer for the end-user, as well, because the Ubiquity command installation process is a lot easier.&lt;br /&gt;
&lt;br /&gt;
In the future, Ubiquity is also likely to have the ability to convert your Ubiquity commands into proper Firefox extensions. Look [http://labs.toolness.com/trac/ticket/3 here] to check on the progress of this functionality.&lt;br /&gt;
&lt;br /&gt;
== Firebug ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity automatically enables Chrome Errors and Warnings on startup so that errors in your code appear in the Firebug console. Just use &amp;lt;tt&amp;gt;CmdUtils.log()&amp;lt;/tt&amp;gt; rather than &amp;lt;tt&amp;gt;console.log()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Where To Go From Here =&lt;br /&gt;
&lt;br /&gt;
Take a look at Ubiquity&#039;s reference documentation for the &amp;lt;tt&amp;gt;[https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html#modules/utils.js Utils]&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;[https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html#modules/cmdutils.js CmdUtils]&amp;lt;/tt&amp;gt; namespaces.&lt;br /&gt;
&lt;br /&gt;
If you have any questions or comments, feel free to join us on IRC at &amp;lt;tt&amp;gt;#ubiquity&amp;lt;/tt&amp;gt; on &amp;lt;tt&amp;gt;irc.mozilla.org&amp;lt;/tt&amp;gt;, as well as the [http://groups.google.com/group/ubiquity-firefox Ubiquity Google Group].&lt;br /&gt;
&lt;br /&gt;
= Conclusion =&lt;br /&gt;
&lt;br /&gt;
To reiterate a point I made before: Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web. You are one of those agents.&lt;br /&gt;
&lt;br /&gt;
Now, go forth and create.&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Roadmap&amp;diff=151900</id>
		<title>Labs/Ubiquity/Roadmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Roadmap&amp;diff=151900"/>
		<updated>2009-06-25T18:37:31Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Ubiquity 0.7: The Web-of-Trust Security Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= The Purpose of the Ubiquity experiment =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ubiquity is really two experiments in one.&lt;br /&gt;
&lt;br /&gt;
== Pseudo-Natural Language ==&lt;br /&gt;
&lt;br /&gt;
The first is an attempt to build a practical, learnable, efficient user-interface using pseudo-natural-language parsing.  Parsing and understanding the semantics of natural language in the general case is extremely difficult, maybe even impossible, and IMHO best left to academic A.I. researchers.  But maybe it&#039;s possible to make an interface which is similar enough to a limited subset of natural language that the user&#039;s linguistic instincts will make it easier to learn and use.  That&#039;s what we&#039;re exploring.&lt;br /&gt;
&lt;br /&gt;
== Verbing the web ==&lt;br /&gt;
&lt;br /&gt;
The second experiment has to do with the &amp;quot;verbification&amp;quot; of the web.  Traditionally the web has been made of &amp;quot;locations&amp;quot;, i.e. pages, that you &amp;quot;go&amp;quot; to using a browser.  But as more and more of those locations become interactive and offer useful services, maybe it makes more sense to treat those services as things you can &amp;quot;pick up&amp;quot; and &amp;quot;take with you&amp;quot; to use elsewhere, instead of treating them as locations.  These chunks of code become &#039;&#039;&#039;commands&#039;&#039;&#039;, the &amp;quot;verbs&amp;quot; of the web, as opposed to the &amp;quot;nouns&amp;quot; that are content-oriented websites.&lt;br /&gt;
&lt;br /&gt;
=== Security plus generativity ===&lt;br /&gt;
&lt;br /&gt;
To make this work, we need to solve the problems of how discrete chunks of code can be written and shared (as easily as web pages can) in a way that offers protection from malicious code without sacrificing generativity.  Security and generativity are often at odds (c.f. &amp;quot;The Future of the Internet and How to Stop It&amp;quot; by Jonathan Zittrain) so to resolve the paradox we explore new and untested security models such as the proposed &amp;quot;web of trust&amp;quot;.  If we can find something that works, it could be applied to many other projects as well.&lt;br /&gt;
&lt;br /&gt;
== The benefit for the user is efficiency ==&lt;br /&gt;
&lt;br /&gt;
Natural language and generativity are of interest mainly to developers.  For the end-user, the benefit of installing Ubiquity is that it gives a faster way to do common web tasks.  With the appropriate command installed, you can accomplish something by simply selecting text on a page and invoking a command, as opposed to copying text, going to a different website, pasting it into a form, etc.  For all of the complexity going on under the surface, this efficiency boost is the reason people use Ubiquity.  To drive more uptake, we should look for more opportunities to write commands that streamline repetitive tasks.&lt;br /&gt;
&lt;br /&gt;
Although there are a nearly infinite number of cool new features that can be proposed for Ubiquity, we should try to stay focused on these three areas: natural language interface, verbifying the web, and increasing the efficiency of the user&#039;s internet tasks.  Things that aren&#039;t closely related to one of these should be considered out-of-scope for the project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Planned Upcoming Releases =&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.5: The New Parser ==&lt;br /&gt;
&lt;br /&gt;
The big news here is the new parser, which supports internationalization.  We took everything we learned from writing the original parser and used it to create a much more robust and expandable basis for future development of multiple-language pseudo-natural-language input.&lt;br /&gt;
&lt;br /&gt;
Second biggest news is the new interactive tutorial.  User testing showed we had a desperate need for a better first-run experience, so we created a walkthrough that takes new users by the hand and teaches them the basic concepts along with a handful of the most useful commands.&lt;br /&gt;
&lt;br /&gt;
Release date:  June 22 (or 23rd if we&#039;re following the tuesday-publicity theory), timed to coincide with release of Firefox 3.5.  (Update:  We released 0.5pre, a still-buggy preview edition, on June 22.  We will release 0.5 for real, with no new features but lots of bug fixes, on June 30.)&lt;br /&gt;
&lt;br /&gt;
Must support both Firefox 3.0 and 3.5.&lt;br /&gt;
&lt;br /&gt;
Major new features:&lt;br /&gt;
&lt;br /&gt;
* Parser version 2, which supports internationalization&lt;br /&gt;
* More consistent naming of standard feed commands, with no more hyphens&lt;br /&gt;
* New interactive tutorial&lt;br /&gt;
* better organized web/help content&lt;br /&gt;
* improved asynchronous noun suggestions&lt;br /&gt;
* Supports multiple languages:  English, Japanese, and Danish at launch; more later.&lt;br /&gt;
&lt;br /&gt;
=== Community building after 0.5: ===&lt;br /&gt;
&lt;br /&gt;
* New command developer documentation&lt;br /&gt;
* Series of videos promoting new features that 0.5 offers to command developers and encouraging command developers to update their feeds to the new format.&lt;br /&gt;
* Educate command developers on locked-down feeds, encourage them to use locked-down feeds whenever possible and standard feeds only when absolutely neccessary.&lt;br /&gt;
* Human interface guidelines for command developers, to encourage consistency of interface between commands.&lt;br /&gt;
* Outreach to localization community, to solicit the help of localizers to get Ubiquity working in more languages.&lt;br /&gt;
&lt;br /&gt;
== Server-Side Improvements ==&lt;br /&gt;
&lt;br /&gt;
There are three server side components to Ubiquity:&lt;br /&gt;
&lt;br /&gt;
# The command search engine (&amp;quot;The Herd&amp;quot;)&lt;br /&gt;
# The bug-reporting system&lt;br /&gt;
# The developer support infrastructure, e.g. Hg and Trac, that run on ubiquity.mozilla.com.&lt;br /&gt;
&lt;br /&gt;
All three of these have been experiencing major availability and/or performance problems.  The lack of usable uptime is really starting to hold us back.  As soon as 0.5 is released, we need to focus on making all three of these server-side components stable and reliable enough to support our plans for growth of the user and developer communities.&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.5.1 ==&lt;br /&gt;
&lt;br /&gt;
Beginning of Q3, 2009&lt;br /&gt;
&lt;br /&gt;
A few features that didn&#039;t make it into 0.5, along with fixes for whatever the biggest bugs are that we discover after 0.5.  Notable features (which are almost done, but didn&#039;t get in to 0.5 before feature freeze) are:&lt;br /&gt;
&lt;br /&gt;
* Provider plugin arguments&lt;br /&gt;
* Suggestion memory in parser 2&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.6: Push for more End-User Benefits ==&lt;br /&gt;
&lt;br /&gt;
Mid Q3, 2009&lt;br /&gt;
&lt;br /&gt;
After the deep infrastructure work of 0.5, we need to focus on turning the new power of the platform into tangible benefits for the end-user.  That means improving the implementation of the standard feed commands for better stability and functionality, plus expanding the range of commands available, and attempting to expand the size of our user base.&lt;br /&gt;
&lt;br /&gt;
Around this time, the Test Pilot project will have produced a usable set of policy guidelines for collecting data without compromising user privacy.  These guidelines will be implemented in 0.6 so that we can start collecting usage data that we can use to scientifically improve the usability of Ubiquity from here on.&lt;br /&gt;
&lt;br /&gt;
* Instrument Ubiquity for data collection according to Test Pilot standards.&lt;br /&gt;
* Improvements to standard feed commands and their documentation; more new commands.&lt;br /&gt;
* New and better default skin; Better graphics for user interface.&lt;br /&gt;
* Localization gets wider and deeper: More locales supported; make nountypes localizable; look into distributing localization so that a command feed can be localized independently from its creator.&lt;br /&gt;
* Suggestion memory improved to cover noun suggestions&lt;br /&gt;
* Experiment with doing noun recognition in the cloud&lt;br /&gt;
&lt;br /&gt;
=== Community Building after 0.6 ===&lt;br /&gt;
&lt;br /&gt;
We should come up with metrics to estimate the size of our user base, and set targets for the number of users we would like to have.  With the higher quality of the standard commands that will be emphasized in 0.6, it will be easier to reach new users.&lt;br /&gt;
&lt;br /&gt;
Increasing our user base will increase our command developer base as well as our command subscriber base, and allow us to make more realistic explorations of the scaling effects that start to affect security and trust when the network grows past critical mass.  For instance, I am not aware of anyone having yet attempted to write a malicious Ubiquity command.  I&#039;m sure this is mostly because the user base is too small to be worth targeting.  As the user base grows, it becomes inevitable that someone will attempt to attack our users using a malicious command.  Thus, growing the community is an opportunity to test out the web-of-trust security model.&lt;br /&gt;
&lt;br /&gt;
We should take a hint from the &amp;quot;Extend Firefox&amp;quot; contests and run a contest to write the best Ubiquity command -- the most useful, most innovative, and best implemented commands that conform to our security and human interface guidelines will be rewarded with publicity and swag.&lt;br /&gt;
&lt;br /&gt;
Separately from any contests, we should also have a spot on the Herd / command-search front page for &amp;quot;Featured Commands&amp;quot;.  This can be a short, rotating list of commands that we have reviewed for security and usability and found highly useful and worthy of recommendation.&lt;br /&gt;
&lt;br /&gt;
The Herd ought to offer a feature where users can give thumbs-up or thumbs-down to commands, and then view commands ranked by number of thumbs.&lt;br /&gt;
&lt;br /&gt;
Good, popular third-party commands can also be considered for inclusion into future versions of the standard feeds.  (But inclusion in standard feeds will never be offered as a prize for any contest; that goes against Mozilla&#039;s policies.)&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.6.1 ==&lt;br /&gt;
&lt;br /&gt;
A few features that didn&#039;t make it into 0.6, along with fixes for whatever the biggest bugs are that we discover after 0.6.&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.7: The Web-of-Trust Security Model ==&lt;br /&gt;
&lt;br /&gt;
Late Q3, 2009&lt;br /&gt;
&lt;br /&gt;
Because of the growing user population, this release will need to focus on security.  With the growing user population, sooner or later someone will start writing malicious Ubiquity commands.  We will try to combat this by using the power of networked users for good instead of evil.  Our longstanding plans for a &amp;quot;[[Labs/Ubiquity/TrustNetwork|web of trust]]&amp;quot; security model will require several improvements to the infrastructure of command subscription.  First, Ubiquity will need to know who your friends are, so that it can see what commands your friends have recommended subscribing to, and what commands they&#039;ve recommended avoiding.&lt;br /&gt;
&lt;br /&gt;
Second, commands will no longer be able to have direct access to third-party servers through XHRs, or to the XPCOM components in the Mozilla platform.  Instead, they will have to make API calls through a security layer.  This security layer will identify exactly what permissions a command is requesting, so that when a user subscribes to it, Ubiquity can tell that user in a plain, human-readable way exactly what is being requested:  &amp;quot;This command wants permission to write to your filesystem&amp;quot;, for instance, or &amp;quot;This command wants to contact the site www.sendmealotofspam.com.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The security layer will make it so that users know what questions are being asked of them by a command install (which will be a big step up from the scary red screen with javascript source code); the web of trust, with recommendations from your friends, will help users decide sensible answers to these questions.&lt;br /&gt;
&lt;br /&gt;
* The web-of trust: Ubiquity becomes aware of your friends and includes a system for giving feedback on commands.&lt;br /&gt;
* The security layer: commands get access to third-party XHRs, XPCOM components, etc. only through security-aware proxy object.&lt;br /&gt;
* User-defined command aliases&lt;br /&gt;
* More locales supported, more and better built-in commands&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.7.1 ==&lt;br /&gt;
&lt;br /&gt;
A few features that didn&#039;t make it into 0.7, along with fixes for whatever the biggest bugs are that we discover after 0.7.&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 0.8: User-interface experimentation ==&lt;br /&gt;
&lt;br /&gt;
Q4, 2009&lt;br /&gt;
&lt;br /&gt;
This release will focus on opening up the Ubiquity user-interface to more experimentation.&lt;br /&gt;
&lt;br /&gt;
By rebuilding Ubiquity on top of Jetpack, so that Ubiquity and Jetpack share a common runtime, we will not only make debugging of Ubiquity much easier; we will also be able to expose the library of installed Ubiquity commands through a Jetpack API, so that others can write new interfaces to take advantage of these commands.&lt;br /&gt;
&lt;br /&gt;
* Ubiquity built to run on Jetpack&lt;br /&gt;
* Commands exposed through Jetpack&lt;br /&gt;
* Experimentation with different UI, such as always-on input field, or mouse-based UI.&lt;br /&gt;
* Command chaining, AKA pipes between commands&lt;br /&gt;
* Solve whatever are the most pressing usability problems discovered through Test Pilot data collection&lt;br /&gt;
* More locales supported, more and better built-in commands&lt;br /&gt;
&lt;br /&gt;
== Ubiquity 1.0: A product ready for mainstream use ==&lt;br /&gt;
&lt;br /&gt;
Q1, 2010&lt;br /&gt;
&lt;br /&gt;
This release will focus on polish.  It will not have any major new features beyond 0.8, but before a release is worthy of being called 1.0 it must be much more solid than any release we have made thus far.  The built-in commands and nountypes, the security model, the user interface, and the parser must all be clean and reliable, and all remaining major bugs must be fixed.&lt;br /&gt;
&lt;br /&gt;
== Beyond 1.0: ==&lt;br /&gt;
&lt;br /&gt;
Experiments in these areas can be done beyond 1.0 if there are sufficient developer resources, but they are outside the core project goals.&lt;br /&gt;
&lt;br /&gt;
* Weave integration&lt;br /&gt;
* Thunderbird integration&lt;br /&gt;
* Bespin integration&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Talk:Labs/Ubiquity/TrustNetwork&amp;diff=147704</id>
		<title>Talk:Labs/Ubiquity/TrustNetwork</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Talk:Labs/Ubiquity/TrustNetwork&amp;diff=147704"/>
		<updated>2009-06-08T14:48:20Z</updated>

		<summary type="html">&lt;p&gt;Endolith: Created page with &amp;#039;Is this for trusting the reliability/functionality of the script, or the malicious intentions of the author?  Does it make sense to have metrics for both reliability/quality and ...&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Is this for trusting the reliability/functionality of the script, or the malicious intentions of the author?  Does it make sense to have metrics for both reliability/quality and lack of maliciousness?&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Talk:Labs/Ubiquity/The_Great_Renaming&amp;diff=146358</id>
		<title>Talk:Labs/Ubiquity/The Great Renaming</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Talk:Labs/Ubiquity/The_Great_Renaming&amp;diff=146358"/>
		<updated>2009-05-30T04:42:58Z</updated>

		<summary type="html">&lt;p&gt;Endolith: Created page with &amp;#039;I sure hope we don&amp;#039;t actually have to type out &amp;quot;search for something with google&amp;quot; in order to search google.  I want to type &amp;quot;go[Tab]something[Enter]&amp;quot; like I currently do.&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I sure hope we don&#039;t actually have to type out &amp;quot;search for something with google&amp;quot; in order to search google.  I want to type &amp;quot;go[Tab]something[Enter]&amp;quot; like I currently do.&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Commands_In_The_Wild&amp;diff=131162</id>
		<title>Labs/Ubiquity/Commands In The Wild</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Commands_In_The_Wild&amp;diff=131162"/>
		<updated>2009-03-01T16:57:14Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* extensions of the core commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LEGAL NOTICE: Mozilla is providing links to these third-party Ubiquity commands as a courtesy, and makes no representations regarding the commands or any information related there to. Any questions, complaints or claims regarding the commands must be directed to the appropriate developer or software vendor.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Commands in the Wild &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please note that the main way we&#039;d like commands to be distributed and shared in the future is via [http://ubiquity.mozilla.com/herd/ The Ubiquity Herd].  Right now there isn&#039;t any social functionality on the Herd, though, which is why we&#039;re using this page to allow for user-contributed commentary and discussion.  At some point in the near future we&#039;ll be adding this kind of functionality to the Herd and will migrate the content on this page there.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; There Be Dragons Here &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pioneering can be crazy fun, but also a bit dangerous. The commands referenced here have not been reviewed by Mozilla. They may contain malicious code, so use them only at your own risk. Until Ubiquity becomes more mature, we recommend only adding commands that come from people you trust, or if you&#039;ve read the code and know that they are safe.&lt;br /&gt;
&lt;br /&gt;
Beware that even if you review the code before subscribing, the code may be subject to change from the publisher, and your copy will automatically update on firefox restart. This problem will be remedied in later versions of Ubiquity.&lt;br /&gt;
&lt;br /&gt;
=Country specific Commands=&lt;br /&gt;
==AT==&lt;br /&gt;
*[http://gist.github.com/25096 gist.github.com/25096]: ÖBB Railway time table search&lt;br /&gt;
&lt;br /&gt;
==BR==&lt;br /&gt;
*[http://minhavidaorientadaaobjetos.blogspot.com/2009/01/buscap-ubiquity-compare-produtos.html Buscape Command]: Compare products quickly in Buscapé&lt;br /&gt;
*[http://minhavidaorientadaaobjetos.blogspot.com/2009/01/americanascom-para-ubiquity-facilitando.html Americanas.com Command]: Search for products at Americanas.com&lt;br /&gt;
*[http://gist.github.com/65907 lyrics a.k.a. letras]: Search for lyrics at letras.mus.br&lt;br /&gt;
*[http://gist.github.com/65903 whois-br]: Whois search for brazilian hosts (registro.br)&lt;br /&gt;
&lt;br /&gt;
==CA==&lt;br /&gt;
* [http://mricon.com/ubi/ Montréal Transit]: Look up STM bus and AMT train schedules&lt;br /&gt;
&lt;br /&gt;
==CH==&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;SBB CFF FFS&#039;&#039;&#039;]: Swiss Railway time table search for [http://www.sbb.ch SBB CFF FFS]. You can find some screen shot [http://frigi.ch/index.php/ubiquity/screenshot here].&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Tel.Search.ch&#039;&#039;&#039;]: Swiss Phone Book search from [http://tel.search.ch tel.search.ch]&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Swiss Teletext&#039;&#039;&#039;]: Swiss Teletext page browser. You can find some screen shot [http://frigi.ch/index.php/ubiquity/screenshot here].&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Rete 3&#039;&#039;&#039;]: visualizza le ultime canzoni in onda su [http://rete3.rtsi.ch/ Rete 3]. Puoi trovare degli screen shot [http://frigi.ch/index.php/ubiquity/screenshot qui].&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Meteo-local&#039;&#039;&#039;]: show the calculated meteo for a location. Information from [http://www.meteosvizzera.admin.ch Federal Office of Meteorology and Climatology]. You can find some screen shot [http://frigi.ch/index.php/ubiquity/screenshot here].&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Meteo-radar&#039;&#039;&#039;]: show the last radar image from [http://www.meteosvizzera.admin.ch Federal Office of Meteorology and Climatology]. You can find some screen shot [http://frigi.ch/index.php/ubiquity/screenshot here].&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Slf&#039;&#039;&#039;]: show the latest avalanche bulletin from [http://www.slf.ch Institute for Snow and Avalanche Research SLF]. You can find some screen shot [http://frigi.ch/index.php/ubiquity/screenshot here].&lt;br /&gt;
*[http://www.frigi.ch/index.php/ubiquity &#039;&#039;&#039;Swisswebcams&#039;&#039;&#039;]: show a random webcam image from the site [http://www.swisswebcams.ch Swisswebcams]. You can find some screen shot [http://frigi.ch/index.php/ubiquity/screenshot here].&lt;br /&gt;
&lt;br /&gt;
==CN==&lt;br /&gt;
* [http://gist.github.com/51784 jiwai]: Command for posting to jiwai.de, a microblogging service in China. For information [http://damienh.org/2009/01/25/ubiquity%e5%8f%bd%e6%ad%aa%e5%91%bd%e4%bb%a4%e5%8a%a0%e5%bc%ba%e7%89%88/ check here].&lt;br /&gt;
*[http://ubidu.sourceforge.net/ ubidu]: Search Baidu.com, the No.1 search engine in China.&lt;br /&gt;
* [http://17th.name/wp-content/uploads/2008/09/fanfou.html Fanfou Command] - post to Fanfou.com (??)&lt;br /&gt;
* [http://www.utblog.com/tools/ubiquity/yodao-dict.htm Youdao or Yodao Dict Search Command] - Translate english to chinese and vice versa through dict.yodao.com service.&lt;br /&gt;
* [http://gist.github.com/25703 Translate word with dict.cn ] - Translate word with dict.cn, both English to Chinese or Chinese to English.&lt;br /&gt;
* [http://gist.github.com/31480 Search in douban] - Search douban items for movie/music/book/generic. With live preview of search results. See a screen shot [http://desktable.blogbus.com/logs/32090698.html here].&lt;br /&gt;
* [http://gist.github.com/49305 Search in Jukuu] - Retrive a word’s pronounce and example sentences from www.jukuu.com, supports English-Chinese and Chinese-English translations. See a screen shot [http://sealence.x10hosting.com/wordpress/?p=61 here].&lt;br /&gt;
* [http://gist.github.com/49422 Recite word everyday on iciba.com] - Retrieving 5 words from the every day recite word lists from www.iciba.com. None input for today’s word, input date string like “2009-1-19″ to retrieve previous day. See a screen shot [http://sealence.x10hosting.com/wordpress/?p=63 here].&lt;br /&gt;
&lt;br /&gt;
==CZ==&lt;br /&gt;
* [http://ubiquity.wegguy.cz/idos/ idos]: Search Czech public transport connections&lt;br /&gt;
&lt;br /&gt;
==DE==&lt;br /&gt;
* [http://daniel.lomm.es/projects/ubiquity-vrr vrr]: Search for timetables for trains, trams and buses in the Rhein-Ruhr region.&lt;br /&gt;
&lt;br /&gt;
==DK==&lt;br /&gt;
* [http://u.ter.dk/mitkbh mitkbh]: search locations and reviews in Copenhagen&lt;br /&gt;
* [http://u.ter.dk/tv tv]: Danish tv guide&lt;br /&gt;
&lt;br /&gt;
==FI==&lt;br /&gt;
*[http://www.juhamakkonen.com/ubiquity/commands/finland/horeca/eat/ eat]: twelve city specific (e.g. eat-helsinki) finnish restaurant searches from eat.fi&lt;br /&gt;
*[http://www.juhamakkonen.com/ubiquity/commands/finland/horeca/vapaa-aikavirasto/vapaa-aikavirasto.htm vapaa-aikavirasto]: fi-nationwide restaurant/bar search from vapaa-aikavirasto.com&lt;br /&gt;
*[http://www.juhamakkonen.com/ubiquity/commands/finland/horeca/viini/viini.htm viini]: wine review search from viiniweb.net&lt;br /&gt;
*[http://www.juhamakkonen.com/ubiquity/commands/finland/jalkapallo/suomencup.htm suomencup]: search material related to finnish cup football from suomencup.net wiki &lt;br /&gt;
*[http://www.juhamakkonen.com/ubiquity/commands/finland/jalkapallo/veikkausliiga.htm veikkausliiga]: rss news feeds from veikkausliiga football teams&lt;br /&gt;
&lt;br /&gt;
==KR==&lt;br /&gt;
*[http://dotnet.pe.kr/ubiquity/me2day_ubiquity.html me2day] - Enables ubiquity to send posts to me2DAY(http://me2day.net) a Korean microblogging site. setme2daykey command sets the username and userkey that is required for posting.&lt;br /&gt;
*[http://sites.google.com/site/coosgadgets/east-asian-language-romanization korean] - Romanization of Korean language (Hangul)&lt;br /&gt;
&lt;br /&gt;
==IT==&lt;br /&gt;
*[http://gstefanoni.netsons.org/ubiquity/treni-from.html treni-from] - Searches for the next available train on the selected route on the Trenitalia network&lt;br /&gt;
==JA==&lt;br /&gt;
*[http://gist.github.com/8346 eijiro] - Japanese &amp;lt;=&amp;gt; English&lt;br /&gt;
*[http://sites.google.com/site/coosgadgets/east-asian-language-romanization japanese] - Japanese &amp;lt;=&amp;gt; English with Romaji&lt;br /&gt;
&lt;br /&gt;
==NO==&lt;br /&gt;
* [http://skogvoldconsulting.no/ubiquity/1881/ 1881.no]: Norwegian phone book online.&lt;br /&gt;
* [http://skogvoldconsulting.no/ubiquity/posten/ Sporing p&amp;amp;aring; posten.no]: Norwegian mail tracking&lt;br /&gt;
&lt;br /&gt;
==NL==&lt;br /&gt;
* [http://gist.github.com/35909 vandale]: For looking up words in the free online version of the leading Dutch dictionary: Van Dale.&lt;br /&gt;
* [http://gist.github.com/59840 hyves-zoek]: For looking for people on the social networking site Hyves.&lt;br /&gt;
&lt;br /&gt;
==NZ==&lt;br /&gt;
* [http://tommo39.com/trademe.html trademe]: Searches trademe.co.nz for whatever item you are looking for.&lt;br /&gt;
&lt;br /&gt;
==PT==&lt;br /&gt;
*[http://gist.github.com/19991 priberam] - Looks up a word in the Priberam Portuguese dictionary [http://priberam.pt/dlpo/ Priberam] (Homepage [http://sites.google.com/site/edgargoncalves/work/software/ubiquity here])&lt;br /&gt;
&lt;br /&gt;
==RO==&lt;br /&gt;
* [http://avatars.postiton.net/ avatars] - Search Avatars in English and add to your emails [http://avatars.postiton.net/ avatars.postiton.net]&lt;br /&gt;
* [http://avatare.afisatepe.net/ avatar] - Search Avatar in Romanian and add to your emails [http://avatare.afisatepe.net/ avatare.afisatepe.net]&lt;br /&gt;
&lt;br /&gt;
==RS==&lt;br /&gt;
* [http://gist.github.com/11398 sr-map] - Search maps of major Serbian cities using [http://mape.b92.net mape.b92.net]&lt;br /&gt;
&lt;br /&gt;
==SE==&lt;br /&gt;
* [http://raymond.bergmark.googlepages.com/hitta.htm Hitta.se]: Swedish phone book online.&lt;br /&gt;
&lt;br /&gt;
==TR==&lt;br /&gt;
* [http://burakcelebi.googlepages.com/ubiquity-eksisozluk.html EksiSozluk Commands] - Commands for http://sozluk.sourtimes.org&lt;br /&gt;
&lt;br /&gt;
* [http://www.deniz.web.tr/ubiquity cevir] - Turkish - English translation command.&lt;br /&gt;
&lt;br /&gt;
* [http://www.azizce.com/wp-content/ubiquity/tdk.html Turk Dil Kurumu &#039;nda Arama] - Fast search command for [http://www.tdk.gov.tr/ Official TDK Website].&lt;br /&gt;
&lt;br /&gt;
* [http://www.verisux.com/ubi-seslisozluk.html seslisozluk] - Integration with seslisozluk.com for quick enlish/german/turkish translations&lt;br /&gt;
&lt;br /&gt;
==TW==&lt;br /&gt;
*[http://linlichangjen.googlepages.com/ubiquity ydic]: Translate English word to Tratitional Chinese&lt;br /&gt;
&lt;br /&gt;
*[http://fortelin.net78.net/ubiquity/2r 2r, another extended version of twitter command]: with url shortened and edit dialogue function, enjoy it ^^&lt;br /&gt;
&lt;br /&gt;
*[http://fortelin.net78.net/ubiquity/soso soso Command for Ubiquity]:another extended, tabbed version of the google command.&lt;br /&gt;
&lt;br /&gt;
==UK==&lt;br /&gt;
*[http://mskadu.googlepages.com/ubiquityscripts yell]: Search Yell.com for businesses in the UK&lt;br /&gt;
&lt;br /&gt;
*[http://www.red-eyed.org.uk/ubiquity.html amazonuk]: Search Amazon.co.uk for any item. A version of amazon-search-all customised for the UK version of the Amazon site.&lt;br /&gt;
&lt;br /&gt;
*[http://tevp.net/projects/ubiquity/ journey]: Searches the TfL journeyplanner for a destination. Currently has hardcoded start point and walking speed.&lt;br /&gt;
&lt;br /&gt;
*[http://www.socialanimal.com/pubs/ubiquity.htm pubfinder]: Looks for pubs in the specified place or postcode.&lt;br /&gt;
&lt;br /&gt;
*[http://choffee.co.uk/Ubiquity trainuk]: Simple interface to search for train times in the UK.&lt;br /&gt;
&lt;br /&gt;
*[http://github.com/elson/ubiquity-bbc-iplayer/wikis/command-feed BBC iPlayer]: Watch or listen to recent programmes on BBC iPlayer&lt;br /&gt;
&lt;br /&gt;
==Multiple Countries==&lt;br /&gt;
*[http://garyhodgson.com/ubiquity/amazon.html amazon-locale]: Perform a &#039;Blended&#039; search on Amazon Germany, UK, USA, Japan or Canada.&lt;br /&gt;
&lt;br /&gt;
= Directory Search =&lt;br /&gt;
*[http://mskadu.googlepages.com/ubiquityscripts yell]: Search Yell.com for businesses in the UK&lt;br /&gt;
* [http://gist.github.com/65093 Cambridge English Advanced Learner&#039;s Dictionary Definition Lookup with preview ]: English (Cambridge). See a screen shot [http://sealence.x10hosting.com/wordpress/?p=66 here].&lt;br /&gt;
&lt;br /&gt;
= Web Search =&lt;br /&gt;
&lt;br /&gt;
* OneLook Reverse Lookup - http://icecreamfactory.freehostia.com/ubiquity/reverse-lookup.html&lt;br /&gt;
&lt;br /&gt;
== Site-specific Search ==&lt;br /&gt;
&lt;br /&gt;
* Agentarius User-Agent-Info - http://www.agentarius.net&lt;br /&gt;
* All Music Guide - http://a9ej32w.googlepages.com/allmusic&lt;br /&gt;
* Allrecipes.com - http://www.javajill.com/ubiquity/recipe.html&lt;br /&gt;
* AltLaw - http://www.keysquaremedia.com/&lt;br /&gt;
* Archive.org - http://ubiquity.washing-up.co.uk/archive.html&lt;br /&gt;
* Aspectweb - http://annoq.aspectweb.org/uq.html&lt;br /&gt;
* Avatars - http://avatars.postiton.net&lt;br /&gt;
* Babylon - http://www.geocities.com/ubiquities1&lt;br /&gt;
* Beat Goes On - http://***.pixelcore.ca/bgo_ubiquity/ (Used CDs DVDs &amp;amp; Video Games)&lt;br /&gt;
* BibleGateway - http://www.zenorsoft.com/ubiquity.php (Looks up Bible Verses)&lt;br /&gt;
* BoardGameGeek - http://www.hunterandlori.com/ubiquity/&lt;br /&gt;
* Brainstorm #9 - http://www.brainstorm9.com.br&lt;br /&gt;
* Cambridge - http://sealence.x10hosting.com/wordpress/?p=66&lt;br /&gt;
* CharlieRose.com - http://erikvold.com/tools/ubiquity/charlierose/charlierose.cfm&lt;br /&gt;
* Common Lisp Hyperspec - http://common-lisp.net/project/lifp/ubiquity/clhs.htm&lt;br /&gt;
* Coxa Creme (Brazil) - http://gist.github.com/10795&lt;br /&gt;
* craigslist - http://labs.vunite.com/vubiqs/verbs.php&lt;br /&gt;
* Deal Extreme - http://skogvoldconsulting.no/ubiquity/dealextreme&lt;br /&gt;
* Demonoid - http://www.thecompgeek.info/ubiquity/demonoid.html&lt;br /&gt;
* Deezer - http://jacquin.pascal.free.fr/ubiquity/ (Search&amp;amp;listen music online)&lt;br /&gt;
* Digg - http://captspify.is-a-geek.com/scripts/Home/Ubiquity (Searches Digg)&lt;br /&gt;
* dinehere.ca - http://dairong.googlepages.com/ubiquity.html&lt;br /&gt;
* Discogs - http://a9ej32w.googlepages.com/discogs&lt;br /&gt;
* eBay (geodetects your location and searches accordingly) - http://mskadu.googlepages.com/ebaysearch2&lt;br /&gt;
* EmacsWiki - http://ubiquity.chrononaut.net/emacswiki.html&lt;br /&gt;
* eMule - http://gist.github.com/16364&lt;br /&gt;
* Fileshunt - http://avid.me/ubi/fileshunt.html&lt;br /&gt;
* Filmweb.pl - http://gist.github.com/19735&lt;br /&gt;
* Firefox add-ons - http://www.rakudave.ch/?q=node/20&lt;br /&gt;
* Freebase - http://hamstersoup.com/freebase/ubiquity/&lt;br /&gt;
* Futureshop.ca - http://dairong.googlepages.com/ubiquity.html&lt;br /&gt;
* GitHub - http://ubiquity.chrononaut.net/github.html&lt;br /&gt;
* Google Finance - http://www.hoffstein.net/ubiquity/stock-quote.html&lt;br /&gt;
* Google Image (with preview) - http://gist.github.com/10704&lt;br /&gt;
* Google Image Search (preview, links, embedding) - http://www.jimmy2k.it/getimagescommand&lt;br /&gt;
* Google Trends (with preview) - http://gist.github.com/10706&lt;br /&gt;
* Google Scholar - http://static.isnotworking.com/scholar-search.html&lt;br /&gt;
* Google Books - http://www.radiantweb.net/ubiquity/&lt;br /&gt;
* Hoogle - http://www.randomhacks.net/git/ubiquity/hoogle/&lt;br /&gt;
* Hulu - http://gist.github.com/51468&lt;br /&gt;
* Imdb (with preview) - http://gist.github.com/59109&lt;br /&gt;
* Iciba.com(irecite) - http://sealence.x10hosting.com/wordpress/?p=63&lt;br /&gt;
* Jaiku - http://jonasnockert.com/2008/08/ubiquity-code-for-jaiku-search/&lt;br /&gt;
* Jiwa - http://jacquin.pascal.free.fr/ubiquity/ (Search&amp;amp;listen music online)&lt;br /&gt;
* Jukuu - http://sealence.x10hosting.com/wordpress/?p=61&lt;br /&gt;
* Kewego.fr - http://ht.ubiquity.googlepages.com/ubiquity-kewego.html&lt;br /&gt;
* Last.FM - http://static.isnotworking.com/lastfm-search.html&lt;br /&gt;
* Last.fm &amp;quot;advanced&amp;quot; - http://www.satf.se/page/ubiquity-advanced-last-fm-search&lt;br /&gt;
* Last.fm Artist Lookup - http://gist.github.com/50505&lt;br /&gt;
* leo.org dictionary - http://www.geocities.com/ubiquities1&lt;br /&gt;
* LibraryThing - http://www.quicksilverillness.com/ubiquity/librarything_searches.html&lt;br /&gt;
*Lifehacker.com search - http://gist.github.com/47455&lt;br /&gt;
* Lifehacking tagcloud search - http://lifehacking.nl/web20/ubiquity-verbindt-het-web-weer/ (Dutch only!)&lt;br /&gt;
* Live - http://www.powerset.com&lt;br /&gt;
* LolCats latest image - http://members.optusnet.com.au/~crazyjane13/lolcats.html&lt;br /&gt;
* LoveFilm - http://dave.org.uk/ubiquity/lovefilm.html&lt;br /&gt;
* metacritic.com - http://dairong.googlepages.com/ubiquity.html&lt;br /&gt;
* metal-archives.com - http://people.iola.dk/arj/2008/09/02/adding-some-metal-to-ubiquity/&lt;br /&gt;
* Mozilla Add-ons - http://projects.fligtar.com/ubiquity/add-on.php&lt;br /&gt;
* Mozilla Add-ons (by folarb) - http://gist.github.com/34678&lt;br /&gt;
* MusicBrainz - http://a9ej32w.googlepages.com/musicbrainz&lt;br /&gt;
* NCIX.com - http://dairong.googlepages.com/ubiquity.html&lt;br /&gt;
* netflix - http://radria.sqlfusion.com/ubiquity.php&lt;br /&gt;
* NewAdvent.org - http://gist.github.com/54249&lt;br /&gt;
* Newegg - http://test.fathomthat.org/ubiquity/newegg.html&lt;br /&gt;
* Newzbin - http://www.quicksilverillness.com/newzbin_search.html&lt;br /&gt;
* Orkut User Search - http://avid.me/ubi/orkut.html&lt;br /&gt;
* PubMed - http://code.google.com/p/tl-ubiquity-commands/source/browse/trunk/pubmed/search-pubmed.js&lt;br /&gt;
* Powerset - http://www.powerset.com&lt;br /&gt;
* Questionable Content MediaFire Thread - http://bluesuncorp.co.uk/bbq/mfsearch.htm&lt;br /&gt;
* Reddit - http://captspify.is-a-geek.com/scripts/Home/Ubiquity/&lt;br /&gt;
* RetailMeNot - http://www.quicksilverillness.com/ubiquity/retailmenot.html&lt;br /&gt;
* REVU - http://revu.ubuntuwire.com/ubiquity-plugin.py&lt;br /&gt;
* Ruhr-University Bochum OPAC - http://bibliolabs.ub.rub.de/ubiquity&lt;br /&gt;
* Shoutcast Search&lt;br /&gt;
* SearchMe - http://www.thecompgeek.info/ubiquity/searchme.html&lt;br /&gt;
* Skweezer - http://unplugd.com/enblogd&lt;br /&gt;
* Smelly Cat - http://www.smellycat.com.br&lt;br /&gt;
* Snow Report - http://www.freewebs.com/wwprograms/ubiquity.htm&lt;br /&gt;
* Social Actions - http://www.crankreport.org/junkdrawer/js/ubiq_social_actions_page.html&lt;br /&gt;
* stock.xchng / sxc.hu - http://www.juhamakkonen.com/ubiquity/commands/images/sxc.hu/sxc.htm&lt;br /&gt;
* Subscene - http://avid.me/ubi/subscene.html&lt;br /&gt;
* suggest-experts -  [http://gist.github.com/15544 subscribe], [http://code.google.com/p/tl-ubiquity-commands/source/browse/trunk/pubmed/suggest-experts.js project at google code]&lt;br /&gt;
* Thesaurus - Used to search thesaurus.reference.com http://www.zacharyspencer.com/2008/09/my-first-ubiquity-command/ &lt;br /&gt;
* Thottbot - http://topthis.tv/ubiquity/&lt;br /&gt;
* Tonight.eu - http://www.tonight.eu/ubiquity/&lt;br /&gt;
* Ubuntu brainstorm - http://www.rakudave.ch/?q=node/21&lt;br /&gt;
* Ultimate Guitar (supports grabbing FoxyTunes track info) - http://propus.lunarpages.com/~thefo2/ug.htm&lt;br /&gt;
* Update or Die (Brazil) - http://gist.github.com/10788&lt;br /&gt;
* Urban Dictionary - http://common-lisp.net/project/lifp/ubiquity/urban-dictionary.htm (now with preview!)&lt;br /&gt;
* Urban Dictionary, alternate version - http://gist.github.com/47363&lt;br /&gt;
* Vimeo - http://gist.github.com/72179&lt;br /&gt;
* Viu Isso? (Brazil) - http://gist.github.com/10791&lt;br /&gt;
* YTMND.com - http://gist.github.com/21802&lt;br /&gt;
* Wapedia Search - http://unplugd.com/enblogd&lt;br /&gt;
* The Wayback Machine - http://www.yardensachs.com/ubiquity/&lt;br /&gt;
* Webmd search - http://predator101.webng.com/ubiquity/webmd.html&lt;br /&gt;
* Websource.It - http://www.briandgoad.com/blog/ubiquity-commands/websourceit/&lt;br /&gt;
* What.CD - http://corevette.googlepages.com/whatcdubiquity.html&lt;br /&gt;
* WhitePages.com - http://charlesconnell.com/ubiquity.html&lt;br /&gt;
* Wikiquote - http://www.geocities.com/ubiquities1&lt;br /&gt;
* Wordnik – http://jonasnockert.com/2008/10/ubiquity-wordnik/&lt;br /&gt;
* WorldCat - http://bibliolabs.ub.rub.de/ubiquity&lt;br /&gt;
* WTFCalls.com - http://wtfcalls.com/search/&lt;br /&gt;
* WTSBooks.com - http://www.nerdlets.org/2009/01/14/ubiquity-command-for-the-westminster-bookstore/&lt;br /&gt;
* xkcd - http://ieng6.ucsd.edu/~rjc002/&lt;br /&gt;
*[http://mskadu.googlepages.com/ubiquityscripts yell]: Search Yell.com for businesses in the UK&lt;br /&gt;
* Yahoo! Finance http://www.matthias-schuetz.eu/yfin-ubiquity.html Quickly review stock quotes and charts&lt;br /&gt;
* Yahoo! Finance http://proplus.aptanacloud.com/ubiquity/yahoo-graph.html Tiny Year To Date ticker chart&lt;br /&gt;
* dict.youdao.com / dict.yodao.com - http://www.utblog.com/tools/ubiquity/yodao-dict.htm&lt;br /&gt;
* Zappos - http://topthis.tv/ubiquity/&lt;br /&gt;
* Zipzoomfly - http://test.fathomthat.org/ubiquity/zipzoomfly.html&lt;br /&gt;
* Zootool - http://zootool.com/blog/2008/08/27/zootool-and-ubiquity/&lt;br /&gt;
&lt;br /&gt;
== Web Lookup ==&lt;br /&gt;
[http://www.starwarsdatapad.741.com/ubiq.htm whois]: Performs a whois on selected or typed URL/IP.&lt;br /&gt;
&lt;br /&gt;
[http://www.starwarsdatapad.741.com/ubiq.htm ping]: Pings the selected or typed URL/IP&lt;br /&gt;
&lt;br /&gt;
[http://www.starwarsdatapad.741.com/ubiq.htm lookup]: Performs a lookup on selected or typed URL/IP.&lt;br /&gt;
&lt;br /&gt;
[http://www.starwarsdatapad.741.com/ubiq.htm tracert]: Performs a tracert on selected or typed URL/IP.&lt;br /&gt;
&lt;br /&gt;
[http://www.rakudave.ch/?q=node/25 just-ping]: Pings the selected or typed URL/IP from 32 checkpoints worldwide.&lt;br /&gt;
&lt;br /&gt;
[http://www.starwarsdatapad.741.com/ubiq.htm isdown]: Takes selected or typed URL and determines if it is working using the downforeveryoneorjustme.com tool.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/9285 Whats-My-IP]: Gets your IP address and displays it in the preview.  Copies IP to clipboard on execute.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10700 Search-Domain-Name]: Checks the availability of com/org/net TLD domain names.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10707 Traffic]: Get Compete traffic charts for the given site.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10703 Host]: Checks the Web Host of the given site.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10702 Site-Down]: Checks if the site is down.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10249 Gmane]: Look up gmane group&lt;br /&gt;
&lt;br /&gt;
==Google==&lt;br /&gt;
&lt;br /&gt;
===extensions of the core commands===&lt;br /&gt;
* [http://mytechieself.blogspot.com/2008/08/writing-ubiquity-commands.html Google Scholar and Google Patent Searches]&lt;br /&gt;
* [http://www.radiantweb.net/ubiquity/ Google Book Search]&lt;br /&gt;
* [http://www.radiantweb.net/ubiquity/ Google News Search]&lt;br /&gt;
* [http://hondje.mine.nu/ubiquity/ Google Search within current domain]&lt;br /&gt;
** [http://www.endolith.com/ubiquity_commands.html Version that lets you specify which domain]&lt;br /&gt;
* [http://pynej.blogspot.com/2008/10/ubiquity-command-search-google-web.html Google Web History Search]&lt;br /&gt;
* [http://www.anod1.free.fr/pdf.html pdf] is a command that search pdf files with google.&lt;br /&gt;
*[http://threepipeproblem.com/ubiquity/gmine_ubiquity.html Gmine] searches Gmail, Google Calendar, and GDocs for your search term.&lt;br /&gt;
&lt;br /&gt;
===Google Feeling Lucky ===&lt;br /&gt;
* [http://gist.github.com/16507 Quicky] not only runs your input through I&#039;m Feeling Lucky, but lets you preview the page also. A quick, dirty splice up of &#039;go&#039; and &#039;goto&#039;.&lt;br /&gt;
* [http://point.pt/~guillaume/ubiquity/feeling-lucky.html Feeling-lucky] is a simple command that looks up the first result and displays it on the preview, and upon hitting enter, it executes by opening that particular web-page.&lt;br /&gt;
* [http://point.pt/~guillaume/ubiquity/feeling-lucky.html Link-to-feeling-lucky] is a command that is similar to &#039;&#039;link-to-wikipedia&#039;&#039;: upon execution it injects a link to google&#039;s first result on the rich text-editing field. Quite handy when linking to companies websites while blogging.&lt;br /&gt;
&#039;&#039;[[User:Griflet|Griflet]]: I renamed these commands with their natural names. The old commands with their original names can still be found [http://point.pt/~guillaume/ubiquity/myCows.html here]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===google hacks===&lt;br /&gt;
* [http://www.anod1.free.fr/music.html music] is a command that use google hacks in order to find mp3 or ogg music. &lt;br /&gt;
* [http://www.anod1.free.fr/video.html video] is a command that use google hacks in order to find video.&lt;br /&gt;
* [http://icecreamfactory.freehostia.com/ubiquity/googlism.html googlism] shows what google.com thinks of you, your friends or anything&lt;br /&gt;
* [http://icecreamfactory.freehostia.com/ubiquity/directions.php directions] shows how to go from location-a to location-b on google maps&lt;br /&gt;
&lt;br /&gt;
==Multiple site search==&lt;br /&gt;
&lt;br /&gt;
* [http://math-www.uni-paderborn.de/~axel/ubiquity_search.html multi-search]: Searches Google, Yahoo, MSN Live and Ask.com simultaneously, in different tabs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Let Me Google That For You==&lt;br /&gt;
&lt;br /&gt;
* [http://gist.github.com/45201 lmgtfy]: create a link to a (not so?) subtle suggestion for someone who asks you, via a computer, about something that Google might be able to answer. Courtesy of [[LetMeGoogleThatForYou.com]].&lt;br /&gt;
&lt;br /&gt;
==Picitup Visual Search==&lt;br /&gt;
&lt;br /&gt;
[http://www.picitup.com]: 2 commands:&lt;br /&gt;
* shop - Executes a shopping search with visual similarity and shopping compariosn - [http://www.picitup.com/picitup/picShop.jsp]&lt;br /&gt;
* picitup - Executes a visual search query agianst, Yahoo, Flikcr and Picasa image search engines [http://www.picitup.com]&lt;br /&gt;
&lt;br /&gt;
== Legal Citation Search ==&lt;br /&gt;
*[http://www.keysquaremedia.com legal-cite]: Executes search of AltLaw for U.S. Code (federal statutes) and some federal case law (i.e., Supreme Court Opinions and federal appeals court opinions that were reported by West) &lt;br /&gt;
&lt;br /&gt;
== Oracle ==&lt;br /&gt;
*[http://www.pythian.com/blogs/1187/ubiquity-and-tahiti-together-at-last Tahiti]: Executes search of Oracle documentation from their repository at http://tahiti.oracle.com.  Can search all docs or version-specific docs.&lt;br /&gt;
*[http://mskadu.googlepages.com/ubiquityscripts search-oracle-docs:  Search through the Oracle Documentation on] [http://www.oracle.com/technology/documentation/index.html Oracle Documentation website]&lt;br /&gt;
&lt;br /&gt;
== Torrent Search ==&lt;br /&gt;
* [http://slackers.se/projects/ubiquity-hdbits HDBits]: Search for torrents on HDBits.&lt;br /&gt;
* [http://entvibes.com/torrents.htm torrent]: Search for torrents on ALL the big trackers at once (uses Torrent Vortex and Torrent-Finder)&lt;br /&gt;
* [http://www.furey.com.au/stuff/ubiquity/mininova/ mininova]: Search for torrents on [http://Mininova.org Mininova]. Refine your search using categories (&amp;quot;in&amp;quot;) and sort types (&amp;quot;by&amp;quot;).&lt;br /&gt;
* [http://garyhodgson.com/ubiquity/torrent.html mininova]: Performs a search for the selected text on [http://Mininova.org Mininova].  Optionally, a category can be defined, e.g. Books, Anime, etc.)&lt;br /&gt;
* [http://garyhodgson.com/ubiquity/torrent.html mininova-imdb]: Performs a search on Mininova.org for a given IMDB code (with or without the &#039;tt&#039;-prefix).&lt;br /&gt;
* [http://gist.github.com/53950 imdbt]: Accurately search for movie torrents on mininova. Type movie keywords and specify desired movie with the &amp;quot;with&amp;quot; mod phrase using the movie&#039;s imdb code shown in the preview (start typing &amp;quot;with t&amp;quot; and choose from autocomplete suggestions). Search will be done using imdb code if available or keywords otherwise.&lt;br /&gt;
* [http://gist.github.com/57852 thePirateBay]: Performs a search for (a) given word(s) on [http://ThePirateBay.org ThePirateBay].  The result will be display directly on the ubiquity preview window, you can start downloading without opening a new tab.&lt;br /&gt;
* [http://gist.github.com/64552 piratebay]: Search for a torrent on Pirate Bay, with the option of specifying a category (Audio/Video/Software/Games/Other) and/or a sort (Type/Name/Uploaded/Size/Seeds).&lt;br /&gt;
* [http://garyhodgson.com/ubiquity/torrent.html piratebay]: Performs a search for the selected text on [http://ThePirateBay.org ThePirateBay].  Optionally, a category can be defined, e.g. Audio, Video, etc.)&lt;br /&gt;
* [http://mskadu.googlepages.com/ubiquityscripts search-torrentz: Search for torrents] on [http://www.torrentz.com Torrentz.com]&lt;br /&gt;
* [http://math-www.uni-paderborn.de/~axel/ubiquity_torrent.html torrent-search]: Searches on PirateBay, Isohunt and Torrentz simultaneously, in different tabs.&lt;br /&gt;
* [http://knightar.artician.com/blog/2008/09/TokyoToshocom-Search-Addon-for-Ubiquity/ tokyotosho]: Searches and lists TokyoTosho.com torrents. (Optionally, a category can be defined, e.g. Anime, Manga, Drama, Raws, etc.)&lt;br /&gt;
* [http://www.thecompgeek.info/ubiquity/demonoid.html Demonoid]: Searches for the predetermined set of keywords on Demonoid.com. Plain and simple.&lt;br /&gt;
* [http://avid.me/ubi/speckly.html Speckly]: Searches for keywords on Speckly.com - Searches 10 torrent sites&lt;br /&gt;
* [http://www.dca.fee.unicamp.br/~tatai/ubiquity btjunkie-search]: Searches for torrents on BTJunkie&lt;br /&gt;
&lt;br /&gt;
= Natural Languages =&lt;br /&gt;
* [http://developer.swekee.com/ubiquity/ David Álvaro &amp;lt;&amp;gt; Diccionario de la lengua de la Real Academia Española ]: Español / Spanish (D-RAE)&lt;br /&gt;
* [http://yardensachs.com/ubiquity/ Yarden&#039;s Hebrew&amp;lt;&amp;gt;English Morfix dictionary lookup ]: morfix&lt;br /&gt;
*[http://yardensachs.com/ubiquity/ Yarden&#039;s Hebrish&amp;lt;&amp;gt;Engrew convert - between Hebrew char&#039;s and English char&#039;s with QWERTY layout ]: hetoen / entohe&lt;br /&gt;
* [http://halcy.de/past/2008/8/27/mozilla_ubiquity_beolingus_germanenglish_dictionary/ German&amp;lt;&amp;gt;English dictionary lookup ]: beo&lt;br /&gt;
* [http://www.satf.se/page/ubiquity-japanese-english-romaji-dictionary pihl&#039;s Japanese&amp;lt;&amp;gt;English romaji dictionary lookup ]: jaen&lt;br /&gt;
* [http://radheef.com/ubiquity/ Dhivehi Radheef (dictionary) lookup ]: jaa&lt;br /&gt;
* [http://olobolger.blogspot.com/2008/08/mozilla-ubiquity.html RAE Spanish dictionary definition lookup]: rae&lt;br /&gt;
* [http://pnxk.freehostia.com/ubiquity/cambridge_dictionary.html Cambridge English Advanced Learner&#039;s Dictionary Definition Lookup ]: English (Cambridge)&lt;br /&gt;
* [http://gist.github.com/65093 Cambridge English Advanced Learner&#039;s Dictionary Definition Lookup with preview ]: English (Cambridge). See a screen shot [http://sealence.x10hosting.com/wordpress/?p=66 here].&lt;br /&gt;
* [http://pnxk.freehostia.com/ubiquity/rae_dictionary.html Real Academia Española Diccionário/Dictionary Definition Lookup ]: Español / Spanish (RAE)&lt;br /&gt;
*[http://www.geocities.com/baloo_rch/rae_ubiquity.html Real Academia Española Diccionário/Dictionary Definition Lookup (with preview) ]: definir&lt;br /&gt;
*[http://www.heartsmagic.net/ubi.html Seslisozluk, Zargan English &amp;lt;-&amp;gt; Turkish look up] English &amp;lt;-&amp;gt; Turkish&lt;br /&gt;
*[http://www.verdsveven.com/ubiquity/nn_nb_dict.html Nynorskordboka og Bokmålsordboka]: Norwegian dictionaries&lt;br /&gt;
* [http://www.jpemartin.com/ubiq/calc2.html calc2] - natural language calculator&lt;br /&gt;
* [http://jarfil.net/ubiquity/dict.html dict.org lookup]: dict&lt;br /&gt;
* [http://gist.github.com/60377 dizionario]: - Italian dictonary (Hoepli)&lt;br /&gt;
* [http://gist.github.com/70871 De Mauro]: - Search Italian Dictionary De Mauro Paravia&lt;br /&gt;
&lt;br /&gt;
=Programming Languages=&lt;br /&gt;
== Asterisk ==&lt;br /&gt;
[[Labs/Ubiquity/dial]]: Configure your Asterisk PBX to use the &#039;dial&#039; command for Ubiquity.&lt;br /&gt;
&lt;br /&gt;
== Common Lisp ==&lt;br /&gt;
* [http://common-lisp.net/project/lifp/ubiquity/clhs.htm Search Common Lisp Hyperspec]&lt;br /&gt;
&lt;br /&gt;
== C++ ==&lt;br /&gt;
[http://abauchu.net/ubiquity/search-cpp.html search-c++] Searches a term on [http://www.cplusplus.com cplusplus.com].&lt;br /&gt;
&lt;br /&gt;
== jQuery ==&lt;br /&gt;
# [http://erikvold.com/tools/ubiquity/jquery/jquery.cfm jquery]: Searches the jQuery documentation.&lt;br /&gt;
&lt;br /&gt;
== PHP ==&lt;br /&gt;
[http://taukon.de/ubiquity-php-function.php php]&lt;br /&gt;
search PHP function documentation&lt;br /&gt;
example: php join()&lt;br /&gt;
&lt;br /&gt;
[http://taukon.de/ubiquity-php-function-doc.php phpd]&lt;br /&gt;
search PHP documentation &lt;br /&gt;
example: phpd class&lt;br /&gt;
&lt;br /&gt;
== Perl ==&lt;br /&gt;
[http://www.grok.in/ubiquity/perl.html perldoc, cpan, monks]: Three commands, one each to search perldocs, CPAN and perlmonks.org&lt;br /&gt;
&lt;br /&gt;
== Rails ==&lt;br /&gt;
[http://gist.github.com/43619 rails]&lt;br /&gt;
search rails documentation&lt;br /&gt;
example: rails link_to&lt;br /&gt;
&lt;br /&gt;
== ActionScript ==&lt;br /&gt;
[http://anirudhs.chaosnet.org/blog/2008.09.04.html as3livedocs, as3desc, as3package]: Three commands, one to open up livedocs page given a class, one to give the description of an actionscript class and another to give the package to which a class belongs to.&lt;br /&gt;
&lt;br /&gt;
== Coldfusion ==&lt;br /&gt;
[http://erikvold.com/tools/ubiquity/coldfusion/coldfusion.cfm coldfusion]: Search the Coldfusion 8 LiveDocs.&lt;br /&gt;
&lt;br /&gt;
== MySQL ==&lt;br /&gt;
[http://erikvold.com/tools/ubiquity/mysql/mysql.cfm mysql]&lt;br /&gt;
&lt;br /&gt;
* mysql: Search all of the MySQL documentation.&lt;br /&gt;
* mysql5: Search the MySQL 5.0 reference manual.&lt;br /&gt;
* mysql5.1: Search the MySQL 5.1 reference manual.&lt;br /&gt;
* mysql6: Search the MySQL 6.0 reference manual.&lt;br /&gt;
* mysql-admin: Search the MySQL administrator reference manual.&lt;br /&gt;
* mysql-query-browser: Search the MySQL query browser reference manual&lt;br /&gt;
* mysql-migration-toolkit: Search the MySQL migration toolkit reference manual.&lt;br /&gt;
* mysql-workbench: Search the MySQL workbench reference manual.&lt;br /&gt;
&lt;br /&gt;
[http://mitcho.com/code/select select] - select gives you read access to your MySQL databases right from Ubiquity, with smart suggestions of your table and column names.&lt;br /&gt;
&lt;br /&gt;
== Postgres ==&lt;br /&gt;
[http://gist.github.com/44867 postgres]&lt;br /&gt;
&lt;br /&gt;
* postgres: Search all of the Postgress documentation.&lt;br /&gt;
* postgres83: Search the Postgress 8.3 reference manual.&lt;br /&gt;
* postgres82: Search the Postgress 8.2 reference manual.&lt;br /&gt;
* postgres81: Search the Postgress 8.1 reference manual.&lt;br /&gt;
* postgres80: Search the Postgress 8.0 reference manual.&lt;br /&gt;
* postgres74: Search the Postgress 7.4 reference manual&lt;br /&gt;
&lt;br /&gt;
== Java ==&lt;br /&gt;
[http://www.cse.ucsd.edu/users/jnguy/java.html Java API] - Wraps a google search pointing to the java API&lt;br /&gt;
&lt;br /&gt;
== Javascript ==&lt;br /&gt;
[http://blog.monstuff.com/archives/000341.html Beautify-JS] - Let&#039;s you nicely reformat any selected javascript code. Handy for Ubiquity verb authors.&lt;br /&gt;
&lt;br /&gt;
== HTML/CSS Reference ==&lt;br /&gt;
[http://gist.github.com/62697 W3Schools Search] uses google to search W3Schools&#039;  documentation on HTML, javascript, CSS, and other web technologies.&lt;br /&gt;
&lt;br /&gt;
== HTML Validation ==&lt;br /&gt;
[http://joshhuckabee.com/w3c-validator-ubiquity-plugin W3C Validator Ubiquity Plugin] Submits the current page to the W3C&#039;s markup validator. Enter the command &amp;quot;validate&amp;quot; on any publicly available web page and hit enter.&lt;br /&gt;
&lt;br /&gt;
== Wordpress ==&lt;br /&gt;
[http://avid.me/ubi/wordpress.html Wordpress] Searches the terms in Documentation &amp;amp; Forums on Wordpress.com&lt;br /&gt;
&lt;br /&gt;
== Drupal API ==&lt;br /&gt;
[http://joshhuckabee.com/drupal-api-ubiquity-plugin Drupal API Ubiquity Plugin] Lookup functions, files, constants, etc. in Drupal&#039;s API. Enter the command &amp;quot;drupal&amp;quot; followed by what you wish to lookup.  Hit enter to be taken to that item in the API.&lt;br /&gt;
&lt;br /&gt;
==Python==&lt;br /&gt;
[http://www.vwelch.com/ubiquity/pydoc.html Pydoc] Lookup any Python terms via http://starship.python.net/crew/theller/pyhelp.cgi. Enter &amp;quot;pydoc&amp;quot; followed by the search term.&lt;br /&gt;
&lt;br /&gt;
=URL Tools=&lt;br /&gt;
&lt;br /&gt;
* goto: Simply navigate to any URL - http://gist.github.com/72189&lt;br /&gt;
&lt;br /&gt;
==mac==&lt;br /&gt;
https://wiki.mozilla.org/Mac&lt;br /&gt;
search for manifacturer with last octet of mac adress&lt;br /&gt;
&lt;br /&gt;
==is.gd==&lt;br /&gt;
[http://arunstechcorner.blogspot.com/2009/02/shorten-urls-in-ubiquity-with-isgd.html is.gd] Shorten and replace the selected URL with is.gd service. The shortened URL is also copied to the clipboard&lt;br /&gt;
== Inlinks ==&lt;br /&gt;
[http://erikvold.com/tools/ubiquity/inlinks/inlinks.cfm Inlinks] Find the number of external inlinks to a provided url (yahoo.com only).&lt;br /&gt;
&lt;br /&gt;
== BuiltWith ==&lt;br /&gt;
[http://builtwith.com BuiltWith] Find out what technologies the URL is using.&lt;br /&gt;
&lt;br /&gt;
== Text2Link ==&lt;br /&gt;
&lt;br /&gt;
[http://text2link.jeffreyjmorgan.com/ubiquity/ Text2Link] opens URLs and sends emails to addresses not marked up as HTML links with the A tag. This is the Ubiquity version of the [https://addons.mozilla.org/en-US/firefox/addon/6003 Text2Link Firefox Extension].&lt;br /&gt;
&lt;br /&gt;
== shortText.com ==&lt;br /&gt;
&lt;br /&gt;
2 commands:&lt;br /&gt;
&lt;br /&gt;
* [http://shortText.com/ shorttext]: Creates a shortText URL for any selected text&lt;br /&gt;
* [http://shortText.com/ longtext]: Select any shortText URL on any site and it will replace the URL with the actual content&lt;br /&gt;
&lt;br /&gt;
== Bit.ly ==&lt;br /&gt;
&lt;br /&gt;
* [http://mskadu.googlepages.com/bitly bitly] - Shortens the selected url using [http://bit.ly Bit.ly]. Pretty much the same as the built-in tinyurl.&lt;br /&gt;
* Shorten URL and copy to clipboard using bit.ly service: http://bit.ly/18Fsn2&lt;br /&gt;
* Shorten and replace selected URL in a Rich Text Field or reverse an already shortened bit.ly URL: http://bit.ly/315THd&lt;br /&gt;
&lt;br /&gt;
== LongURL ==&lt;br /&gt;
&lt;br /&gt;
[http://longurl.org/tools expand-short-url] Uses the LongURL service to expand URLs shortened with any shortening service (TinyURL.com, Bit.ly, etc.)&lt;br /&gt;
&lt;br /&gt;
== Tr.im ==&lt;br /&gt;
[http://almaer.com/firefox/commands/ trimurl] Uses the tr.im service to shorten a URL and put it in your clipboard if successful&lt;br /&gt;
&lt;br /&gt;
== Hurl.ws ==&lt;br /&gt;
&lt;br /&gt;
Shorten a URL using hurl.  &lt;br /&gt;
Simply navigate to [http://www.hurl.ws  hurl.ws] to install using firefox.&lt;br /&gt;
Use the command &amp;quot;hurl&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== a.longreply.com ==&lt;br /&gt;
&lt;br /&gt;
Use a.longereply.com to convert any section of text into a URL so you can then send this link via IM, Twitter, email?  Can send very large peices of text.&lt;br /&gt;
Use the command &amp;quot;longreply&amp;quot;.  To install it [http://a.longreply.com a.longreply.com]&lt;br /&gt;
&lt;br /&gt;
== shorten ==&lt;br /&gt;
&lt;br /&gt;
The all in one URL shortner: [http://labs.vunite.com/vubiqs/verbs.php vunite&#039;s commands]&lt;br /&gt;
Usage: shorten [url] using [tinyurl|isgd|bitly|hurl|snipurl]&lt;br /&gt;
&lt;br /&gt;
== kissa.be ==&lt;br /&gt;
&lt;br /&gt;
A new [http://www.yalazi.org/ubiquity/list.html kissalt, url shortening service], kissalt means &amp;quot;shorten&amp;quot; in Turkish (original word: kisalt)&lt;br /&gt;
&lt;br /&gt;
== lincr ==&lt;br /&gt;
&lt;br /&gt;
[http://sathyasays.com/2008/09/21/my-first-ubiquity-command-lincr-it/ Lincr ] is a URL shortening service. The [http://lin.cr homepage] also shows a list of recently Lincr&#039;d URLs and a RSS feed of the same.&lt;br /&gt;
&lt;br /&gt;
== Other URL manipulation==&lt;br /&gt;
* [http://projects.fligtar.com/ubiquity/url.php URL Tool] - Converts selected URLs to links or lets you choose which one to open in a new tab.&lt;br /&gt;
* [http://nevermind85.net63.net/Ubiquity/try.html ToLink] - Converts the selected text link in a real clickable link.&lt;br /&gt;
* [http://blog.monstuff.com/archives/000343.html insert-link] - Search for a link in your history and insert it.&lt;br /&gt;
* [http://earth2marsh.com/ubiquity/ Percent Encoding Tools] Commands to percent encode as well as decode (aka &amp;quot;URI encoding&amp;quot;) selected text. Provides preview and/or replaces selected text.&lt;br /&gt;
* [http://kollektive.com/ubiquity/ links] - converts non-marked up text/html which contains urls and email addresses into proper anchor tags. Works within html pages, and in rich text editing fields (eg. rich text editing in GMAIL)&lt;br /&gt;
[[Media:Example.ogg]]&lt;br /&gt;
&lt;br /&gt;
= Web 2.0 (Social networks, blogs, recommenders, etc) = &lt;br /&gt;
&lt;br /&gt;
== BackType ==&lt;br /&gt;
# [http://erikvold.com/tools/ubiquity/backtype/backtype.cfm backtype]: Starts a search of BackType, which allows you to do a search for a person&#039;s comments on blogs and other sites. &lt;br /&gt;
&lt;br /&gt;
==CipherHive==&lt;br /&gt;
A Global search of Moodle Based Courses, Forums, Wiki&#039;s, Blogs, Users, Posts, Authors, etc.&lt;br /&gt;
&lt;br /&gt;
Script: http://www.cipherhive.org/course/view.php?id=19&lt;br /&gt;
&lt;br /&gt;
To use, just type cipher + the word you wish to search.&lt;br /&gt;
&lt;br /&gt;
== Digg ==&lt;br /&gt;
&lt;br /&gt;
Submit a selected, or manually typed URL, or simply type digg to submit the current tab&#039;s URL to digg...&lt;br /&gt;
... will be extended shortly with options to include title, description, category and preview image ... possibly even skip the digg &amp;quot;new entry&amp;quot; page ...&lt;br /&gt;
&lt;br /&gt;
Script: http://www.wgbox.de/ubiquity/digg.html&lt;br /&gt;
&lt;br /&gt;
== Del.icio.us ==&lt;br /&gt;
&lt;br /&gt;
=== Add a page to your delicious bookmarks ===&lt;br /&gt;
&lt;br /&gt;
Script: http://gist.github.com/7516&lt;br /&gt;
&lt;br /&gt;
To use, just type delicious + your tags.&lt;br /&gt;
&lt;br /&gt;
Another Command: http://decafbad.com/UbiquityCommands/&lt;br /&gt;
&lt;br /&gt;
Highlight some text on the page for notes, activate Ubiquity, enter command share-on-delicious.  You can also enter your own notes, assign tags to the bookmark with the &amp;quot;tagged&amp;quot; modifier, and alter the bookmark default page title with the &amp;quot;entitled&amp;quot; modifier.  Note that you must also already be logged in at delicious.com to use this command.&lt;br /&gt;
&lt;br /&gt;
Another Command: http://gist.github.com/9499&lt;br /&gt;
&lt;br /&gt;
Emulates the Delicious.com bookmarklet. Highlight some text on the page for notes, activate Ubiquity, enter command delicious. It will pop up a new window where you can select tags other people have used for the URL.&lt;br /&gt;
&lt;br /&gt;
=== View a users delicious tags ===&lt;br /&gt;
Script: http://parentno.de/ubiquity/?command=get-delicious&lt;br /&gt;
&lt;br /&gt;
Shows del.icio.us bookmarks from this user {username} tagged with {tagname}&lt;br /&gt;
To use, type get-delicious {username} tag {tagname}&lt;br /&gt;
&lt;br /&gt;
=== View the 10 most recent/popular bookmarks in delicious ===&lt;br /&gt;
Script: http://201.238.211.147/~yinocl/ubiquity.html&lt;br /&gt;
&lt;br /&gt;
Shows the 10 most recent/popular del.icio.us bookmarks.&lt;br /&gt;
To use, type recent-delicious or popular-delicious.&lt;br /&gt;
A basic save-delicious is included as well.&lt;br /&gt;
&lt;br /&gt;
== Evernote ==&lt;br /&gt;
*[http://gist.github.com/50974 clip to Evernote] Clip the current web page selection to Evernote&lt;br /&gt;
&lt;br /&gt;
== Facebook ==&lt;br /&gt;
&lt;br /&gt;
Lets you update your status and go quickly to a friend&#039;s profile.&lt;br /&gt;
&lt;br /&gt;
[[http://grantrules.com/ubiquity/facebook.html script]] with two commands:&lt;br /&gt;
* &#039;facebook-status (your status)&#039; - Updates your status, doesn&#039;t add &amp;quot;is&amp;quot;!&lt;br /&gt;
* &#039;facebook-friend (your friend)&#039; - Locate a friend. You have to type whole words, though (if searching for Amy Jones, you can&#039;t type Amy Jon; it must be one of: amy, jones, amy jones!)&lt;br /&gt;
&lt;br /&gt;
=== Share on Facebook ===&lt;br /&gt;
Shares the the page in the current tab on Facebook. I parsed the bookmarklet provided by Facebook so you get the nice little pop-up window rather than a whole new tab.&lt;br /&gt;
&lt;br /&gt;
Script: http://jallen7usa.com/ubiquity/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Search Facebook ===&lt;br /&gt;
&lt;br /&gt;
Look anything up in Facebook, contacts, groups and it even works whether you are logged in or not.&lt;br /&gt;
&lt;br /&gt;
script here&lt;br /&gt;
http://myfirstscript.blogspot.com/2008/10/ubiquity-is-awesome_06.html&lt;br /&gt;
&lt;br /&gt;
== Ffffound it! ==&lt;br /&gt;
&lt;br /&gt;
Adds images to the Ffffound! image repository site. You must have a Ffffound! account to be able to use.&lt;br /&gt;
Simply navigate to [http://www.lantern.co.nz/ubiquity/ffffound.html  lantern.co.nz/ubiquity/ffffound.html] to install using firefox.&lt;br /&gt;
Use the command &amp;quot;ffffound it&amp;quot; on a page which has the image you want to save.&lt;br /&gt;
&lt;br /&gt;
== Friendfeed ==&lt;br /&gt;
*[http://gist.github.com/51007 share-on-friendfeed] Simple bookmarklet command to share the current page on friendfeed.&lt;br /&gt;
&lt;br /&gt;
== Hatena ==&lt;br /&gt;
&lt;br /&gt;
*[http://gist.github.com/8351 hatebu]&lt;br /&gt;
*[http://gist.github.com/8575 hotentry]&lt;br /&gt;
&lt;br /&gt;
== Identi.ca ==&lt;br /&gt;
&lt;br /&gt;
Script: [[http://bobbo.me.uk/code/ubiquity/]] Allows you to post to Identi.ca from Mozilla Ubiquity. To use, install from link, open Ubiquity and type &amp;quot;identi.ca&amp;quot; followed by your status message.&lt;br /&gt;
&lt;br /&gt;
== Mixx==&lt;br /&gt;
# [http://erikvold.com/tools/ubiquity/mixx/mixx.cfm mixx]: Mixx the typed/pasted url, or highlighted url, or otherwise the current page. Also get the mixx count of the url in the preview.&lt;br /&gt;
&lt;br /&gt;
== myExperiment ==&lt;br /&gt;
&lt;br /&gt;
Script: [http://www.myexperiment.org/files/151/download/myexperiment_search.js myExperiment basic search command] Basic search plugin for myExperiment, an online comunity for scientists.&lt;br /&gt;
&lt;br /&gt;
== MySpace.com ==&lt;br /&gt;
&lt;br /&gt;
Four tools to update and interact with your MySpace account.&lt;br /&gt;
&lt;br /&gt;
- Comment&lt;br /&gt;
- Send Message&lt;br /&gt;
- Post Bulletin&lt;br /&gt;
- Create Blog Entry&lt;br /&gt;
&lt;br /&gt;
[http://devstatus.com/ MySpace Command Collection] Quick and easy way to use the contextual information from Ubiquity on MySpace. Read syntax and examples on related pages.&lt;br /&gt;
&lt;br /&gt;
== Pawst.com ==&lt;br /&gt;
&lt;br /&gt;
Search social bookmarking websites using pawst.com&amp;lt;br&amp;gt;&lt;br /&gt;
Simply type &#039;pawst topic&#039; i.e &#039;pawst funny pics&#039;&lt;br /&gt;
&lt;br /&gt;
by [http://shmuel.ahdut.com Shmuel Ahdut] - licensed as MPL&lt;br /&gt;
&lt;br /&gt;
Subscribe: http://pawst.com (You&#039;ll get Ubiquity&#039;s subscribe popline)&amp;lt;br&amp;gt;&lt;br /&gt;
Script: http://pawst.com/javascripts/ubiquity.js&lt;br /&gt;
&lt;br /&gt;
== Sphinn ==&lt;br /&gt;
# [http://erikvold.com/tools/ubiquity/sphinn/sphinn.cfm sphinn]: Sphinns the typed url, or highlighted url, or otherwise the current page. Also get the sphinn count of the url in the preview.&lt;br /&gt;
&lt;br /&gt;
== Jaiku ==&lt;br /&gt;
Script: http://ubiquity.pastebin.com/f495c6d62&lt;br /&gt;
To add your username and api key use the command:&lt;br /&gt;
jaiku-setuserandkey &amp;lt;username&amp;gt; api &amp;lt;apikey&amp;gt; -- you can get your api key on http://api.jaiku.com&lt;br /&gt;
(inspired by http://trodrigues.net/ubiquity/pingfm/)&lt;br /&gt;
to post:&lt;br /&gt;
jaiku &amp;lt;you presence&amp;gt; at &amp;lt;location&amp;gt; : The location is optional, if you don&#039;t pass, the script will try to guess it using CmdUtils.getGeoLocation().&lt;br /&gt;
&lt;br /&gt;
== Idiquity ==&lt;br /&gt;
[http://geekmatters.com/Ubiquity/Idiquity.html Idiquity]allows updating and checking your timeline from Ubiquity. More functionality is to come; details are at the site. It is compatible with any Laconi.ca based site (or any site with a Twitter compatible API).&lt;br /&gt;
&lt;br /&gt;
== News and Feed Readers ==&lt;br /&gt;
&lt;br /&gt;
[http://i8news.appspot.com/ubiquity/nytimes.html NYTimes recent Headlines]: autosuggest recent headlines when you are typing; and if no matching, just hit enter, you will go to NYTimes.com search page. &lt;br /&gt;
&lt;br /&gt;
[http://www.bennysheerin.com/ubiquity.html Simple news feed]: Returns latest headlines from various vendors such as bbc, cnn and digg.&lt;br /&gt;
&lt;br /&gt;
[http://www.planetaki.com/ubiquity Planetaki Commands]: Add the website you&#039;re visiting to your Planet&lt;br /&gt;
&lt;br /&gt;
[http://cokeeffe.wordpress.com/get-news-for-ubiquity/ get-news]: Enables you to search Google News for news titles.&lt;br /&gt;
&lt;br /&gt;
== Nexopia ==&lt;br /&gt;
&lt;br /&gt;
=== Go to user profile ===&lt;br /&gt;
&lt;br /&gt;
Type &amp;quot;nexopia&amp;quot; and the user&#039;s name and it will take you directly to that user&#039;s profile on Nexopia.com.&lt;br /&gt;
&lt;br /&gt;
Script: http://jodyheavener.com/ubiquity/nexopia/&lt;br /&gt;
&lt;br /&gt;
== People Search ==&lt;br /&gt;
* [http://www.123people.com 123people]: Let&#039;s you search people meta data from around the world via Ubiquity.&lt;br /&gt;
* [http://avid.me/ubi/pipl.html pipl]: Searches for People&#039;s name on pipl.com&lt;br /&gt;
* [http://avid.me/ubi/chickipedia.html Chickipedia]: Searchs for Chickipedia, the world’s largest web-based, women-based, wiki-based database of hot chicks.&lt;br /&gt;
&lt;br /&gt;
== Serchilo ==&lt;br /&gt;
[http://wiki.serchilo.net/Serchilo:Ubiquity Serchilo in Ubiquity] allows using [http://serchilo.net Serchilo] commands in Ubiquity.&lt;br /&gt;
&lt;br /&gt;
== Slashdot ==&lt;br /&gt;
* [http://blipo.ath.cx/chkslashdot.html Check Slashdot]&lt;br /&gt;
&lt;br /&gt;
== Ping.fm ==&lt;br /&gt;
&lt;br /&gt;
Allows you to post messages via the ping.fm service.&lt;br /&gt;
&lt;br /&gt;
Script: http://ubiquity.washing-up.co.uk/pingfm.html&lt;br /&gt;
&lt;br /&gt;
The first time it is used, you must provide it with your ping.fm app key by typing &amp;quot;ping-set-key &amp;lt;your app key&amp;gt;&amp;quot;  Once it has stored your app key, you do not need to provide it again, and can just type &amp;quot;ping &amp;lt;message&amp;gt;&amp;quot;  Your app key can be found at [http://ping.fm/key http://ping.fm/key]&lt;br /&gt;
&lt;br /&gt;
== Tonight.eu ==&lt;br /&gt;
&lt;br /&gt;
Lets you to search venues, restaurants and events in some big european cities.&lt;br /&gt;
&lt;br /&gt;
Script: http://www.tonight.eu/ubiquity/&lt;br /&gt;
&lt;br /&gt;
== Bugmenot ==&lt;br /&gt;
&lt;br /&gt;
A password database site for general public&lt;br /&gt;
&lt;br /&gt;
[http://www.yalazi.org/ubiquity/list.html bugmenot, username password retrieving from bugmenot]&lt;br /&gt;
&lt;br /&gt;
== Google Bookmark ==&lt;br /&gt;
Adds the current page to your Google bookmarks with the title you give it. Still rather rough - not robust against invalid inputs.&lt;br /&gt;
http://www.cs.washington.edu/homes/butaud/ubiquity.html&lt;br /&gt;
&lt;br /&gt;
== Google Reader (shared items) ==&lt;br /&gt;
Adds the current selection to your Google Reader Shared Items page&lt;br /&gt;
and allows you to add a note to it.&lt;br /&gt;
[http://abauchu.net/ubiquity/share-on-reader.html share-on-reader command]&lt;br /&gt;
&lt;br /&gt;
Alternate Command: [http://pynej.blogspot.com/2008/10/ubiquity-command-note-in-reader.html Note in Reader]&lt;br /&gt;
&lt;br /&gt;
==Gmail==&lt;br /&gt;
&lt;br /&gt;
* [http://fettig.net/playground/ubiquity/ Gmail Status Message] Update your Google Talk status message in Gmail&lt;br /&gt;
* [http://www.jpemartin.com/ubiq/smiley.html Smiley] Insert smileys into your email message (also works with other email or blog)&lt;br /&gt;
* [http://www.geocities.com/skyhopper88/GmailEdit.html GMail Edit] Edit of an old Ubiquity script to work with latest version (.1.1). Opens Gmail in a new tab, as well as showing you the last couple of new messages in the preivew.&lt;br /&gt;
* [http://www.strangeblackhole.com/sign-it/ Sign It] Now you can sign your message, blog post and other with HTML code.&lt;br /&gt;
&lt;br /&gt;
== Reddit ==&lt;br /&gt;
&lt;br /&gt;
[http://urdna.org/ubiquity Urdna&#039;s &#039;Reddit-This&#039; command]&lt;br /&gt;
&lt;br /&gt;
== Social Graph (FOAF/XFN etc) ==&lt;br /&gt;
&lt;br /&gt;
[http://danbri.org/2008/ubisg/ DanBri&#039;s &#039;foaf&#039; command] (calls Google SGAPI)&lt;br /&gt;
&lt;br /&gt;
== Stickam ==&lt;br /&gt;
&lt;br /&gt;
http://stickhacks.googlepages.com - Watch someone&#039;s live Stickam stream without going to their profile&lt;br /&gt;
&lt;br /&gt;
== mYoUvies.com ==&lt;br /&gt;
[http://myouvies.com/ubiquity/ movieshare]: Allows for simple posting to the social movie news website [http://myouvies.com mYoUvies.com]&lt;br /&gt;
&lt;br /&gt;
== Soup.io ==&lt;br /&gt;
[http://static.al3x.net/ubiquity.html soup] - replicates the functionality of the bookmarklet for the Soup.io tumblelogging service&lt;br /&gt;
&lt;br /&gt;
== Open Contacts ==&lt;br /&gt;
&lt;br /&gt;
Create, search, list or sign [http://annoq.aspectweb.org/uq.html commands] for [http://annoq.aspectweb.org/softLink.html#openq openqx.org] experimental project. Associates freely accessible contact information (such person name, telephone number, email, etc.) with regular web domains. Web API and flexible query language included. Ubiquity commands: &lt;br /&gt;
* openq-search (cross domain searching)&lt;br /&gt;
* openq-list (lists contacts for contextual domain)&lt;br /&gt;
* openq-create (adds new contact to the contextual domain)&lt;br /&gt;
* openq-sign (sign documents with your Open Contact data)&lt;br /&gt;
* openq-to (fill address fields by querying Open Contacts)&lt;br /&gt;
&lt;br /&gt;
== Form Data Templates ==&lt;br /&gt;
&lt;br /&gt;
Create data templates by saving form content (ubiquity form-save). Password fields are left out for security reasons. Once persisted, the data becomes available to anyone (ubiquity form-load). [http://annoq.aspectweb.org/fuq.html commands]. The functionality is similar to what you already know from wire transfer templates but &#039;&#039;&#039;please avoid experimenting with sensitive data&#039;&#039;&#039;. (eg. go to Bugzilla  graphical [https://bugzilla.mozilla.org/query.cgi?format=report-graph report generation page] and issue form-load [Enter])&lt;br /&gt;
&lt;br /&gt;
== Web Annotations &amp;amp; User Links ==&lt;br /&gt;
&lt;br /&gt;
Yet another [http://aspectweb.org aspectweb.org] project. Social service commands to create, embed or search comments or custom links for any regular web page.  [http://annoq.aspectweb.org/sq.html commands] (eg.: goto Jean Gebser wiki [http://en.wikipedia.org/wiki/Jean_Gebser page] and type &#039;&#039;&#039;slink-list&#039;&#039;&#039; to list current user links or &#039;&#039;&#039;annoq-list&#039;&#039;&#039; for related annotations)&lt;br /&gt;
* [http://www.strangeblackhole.com/sign-it/ Sign It] Now you can sign your message, blog post and other with HTML code.&lt;br /&gt;
&lt;br /&gt;
== shortText ==&lt;br /&gt;
&lt;br /&gt;
2 commands:&lt;br /&gt;
&lt;br /&gt;
* [http://shortText.com/ shorttext]: Creates a URL for any selected text&lt;br /&gt;
* [http://shortText.com/ longtext]: Select any shortText URL on any site and it will replace the URL with the actual content&lt;br /&gt;
&lt;br /&gt;
==Twitter==&lt;br /&gt;
* [http://benatkin.com/ubiquity/tweet/ Ben&#039;s tweet command]: post to twitter (with URL shortener)&lt;br /&gt;
* [http://geekmum.com/ubiquity twittersearch]&lt;br /&gt;
* [http://www.matthias-schuetz.eu/twitter-ubiquity.html twitter]With timeline and auto completion for contacts&#039; names.&lt;br /&gt;
* [http://sites.google.com/site/coosgadgets/2ii 2ii], based on matthias&#039; work. Add current url replacement and shorten, hyperlink in the preview etc.&lt;br /&gt;
* [http://gist.github.com/52797 twtplus] Forked from 2ii. Cleared out &amp;quot;ugly hacks&amp;quot; and refactored a lot. New features include shortening all urls in a post, d message with friend username autocompletion, and posting as specified user account.&lt;br /&gt;
* [http://gist.github.com/20044 otw] I can&#039;t type such a long username.&lt;br /&gt;
* [http://gist.github.com/38698 wtw] Twitter viewer.&lt;br /&gt;
&lt;br /&gt;
==Tumblr==&lt;br /&gt;
* [http://gist.github.com/48778 ptm] You can post to Tumblr. But please pay attention to L3 and L4 - email and password.&lt;br /&gt;
&lt;br /&gt;
= Web 3.0 (Web Of Data, Semantic Web, etc) =&lt;br /&gt;
Commands allowing the access or manipulation Web 3.0 content, that is [http://www.w3.org/RDF/ RDF]-based datasets such as [http://linkeddata.org linked data].&lt;br /&gt;
&lt;br /&gt;
* [http://srv.buzzword.org.uk/ Cognition] microformat/RDF/RDFa/eRDF/GRDDL parser.&lt;br /&gt;
*# &amp;lt;code&amp;gt;cognify&amp;lt;/code&amp;gt;&lt;br /&gt;
*[http://jowl.ontologyonline.org/Ubiquity.html jOWL Ubiquity command], Visualize and query on OWL-DL files with [http://jowl.ontologyonline.org jOWL]&lt;br /&gt;
*# &amp;lt;code&amp;gt;view_ontology&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Microformats ==&lt;br /&gt;
* Microformats Extraction commands available at http://transformr.co.uk/&lt;br /&gt;
*#commands: &lt;br /&gt;
*#* &amp;lt;code&amp;gt;get-atom&amp;lt;/code&amp;gt; from [http://microformats.org/wiki/hatom hAtom] &lt;br /&gt;
*#* &amp;lt;code&amp;gt;get-vcard&amp;lt;/code&amp;gt; from [http://microformats.org/wiki/hcard hCard] &lt;br /&gt;
*#* &amp;lt;code&amp;gt;get-webcal&amp;lt;/code&amp;gt; from [http://microformats.org/wiki/hcalendar hCalendar]&lt;br /&gt;
*#* &amp;lt;code&amp;gt;get-podcast&amp;lt;/code&amp;gt; from [http://microformats.org/wiki/haudio hAudio] &lt;br /&gt;
*#* &amp;lt;code&amp;gt;get-rdf&amp;lt;/code&amp;gt; from [http://www.w3.org/TR/xhtml-rdfa-primer/ RDFa]&lt;br /&gt;
&lt;br /&gt;
* Search the [http://microformats.org/wiki/ Microformats Wiki] available at http://weborganics.co.uk/&lt;br /&gt;
*#command: &lt;br /&gt;
*#* &amp;lt;code&amp;gt;uf-search&amp;lt;/code&amp;gt; (search term)&lt;br /&gt;
&lt;br /&gt;
== WoD ==&lt;br /&gt;
[[User:MichaelHausenblas|Michael Hausenblas]] has put together a [http://sw.joanneum.at/ubiq/ collection of WoD commands]. Currently three commands are available:&lt;br /&gt;
* query the semantic indexer [http://sindice.com Sindice] for a term&lt;br /&gt;
* lookup [http://dbpedia.org/About DBpedia] resources [http://gist.github.com/59915 lookupNdbpedia]&lt;br /&gt;
* lookup [http://dbpedia.org/About DBpedia] for things in a certain category&lt;br /&gt;
* perform a [http://curl.haxx.se/ curl] HEAD for a URI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Crunchbase ==&lt;br /&gt;
[http://bnode.org/about Benjamin Nowack] has written the [http://cb.semsol.org/ubiquity cb command] allowing to do [http://www.crunchbase.com/ CrunchBase] lookups for companies, products or people.&lt;br /&gt;
&lt;br /&gt;
== Twine ==&lt;br /&gt;
[http://static.isnotworking.com/add-to-twine.html add-to-twine]: &lt;br /&gt;
Brings up the dialog for posting the current page to [http://twine.com Twine].&lt;br /&gt;
&lt;br /&gt;
== Linked Data Exploration ==&lt;br /&gt;
[http://demo.openlinksw.com/ubiq OpenLink Web Resource Description Commands] - Commands for obtaining structured descriptions of Web Resources. Uses [http://virtuoso.openlinksw.com/ Openlink Virtuoso]&#039;s in-built RDFization Middleware (&amp;quot;Sponger&amp;quot;) and Linked Data Deployment technology.&lt;br /&gt;
&lt;br /&gt;
== Link lookup and insertion ==&lt;br /&gt;
[http://demo.monrai.com summon command] - look up a link representing the keywords or phrase you enter, and inserts it into the page. Good for quickly inserting links into emails, blog, blog comments, twitter, etc.&lt;br /&gt;
&lt;br /&gt;
== headup ==&lt;br /&gt;
[http://www.headup.com/ubiquity.html headup]: Connect the artist / city / person / company / movie / book / etc - with  relevant and personalized information, using the headup Firefox addon - [http://www.headup.com Get headup].&lt;br /&gt;
&lt;br /&gt;
= Visualization =&lt;br /&gt;
* [http://code.google.com/p/tl-ubiquity-commands/source/browse/trunk/visualization/word-cloud.js word-cloud] generates a &#039;word cloud&#039; from the selected text.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Clocks =&lt;br /&gt;
* analog clock - http://www.jpemartin.com/ubiq/time.html (also allows you to specify a timezone)&lt;br /&gt;
* minute-minder: show the time on page-load - http://individual.utoronto.ca/duez/cw.html&lt;br /&gt;
* MJD to UTC and UTC to MJD converters: [http://www.storybookdachshunds.com/surlyfritter/  mjd2utc and utc2mjd]&lt;br /&gt;
see also swies&#039;s commands, below&lt;br /&gt;
* [http://swapoff.org/files/ubiquity_time/ An international clock (plus flags!)] This looks pretty cool but say, Moscow time is off by one hour! Looks like the problem with EarthTools, maybe use something else?&lt;br /&gt;
&lt;br /&gt;
= Travel =&lt;br /&gt;
* [http://widgets.bootsnall.com/ubiquity/flight.html flight search]&lt;br /&gt;
* [http://blog.mikelorengo.com/2008/09/ubiquitizing-jenn-for-flight.html fly-alaskaair]. Shops for flights on Alaska Airlines and Horizon Airlines  &amp;quot;fly-alaskaair (cmd)&amp;quot; where (cmd) can be free form text. Examples include:&lt;br /&gt;
** fly-alaskaair sea lih 02/11/2009 return 02/25/2009&lt;br /&gt;
** fly-alaskaair sea lax next thursday return sunday&lt;br /&gt;
** fly-alaskaair sea sjd next wednesday one way&lt;br /&gt;
* [http://widgets.bootsnall.com/ubiquity/hotel.html hotel search]&lt;br /&gt;
* [http://widgets.bootsnall.com/ubiquity/vacation.htmlvacation package search] (flight+hotel together)  &lt;br /&gt;
* [http://widgets.bootsnall.com/ubiquity/car.html car rental search]&lt;br /&gt;
&lt;br /&gt;
= Maths = &lt;br /&gt;
* Converts selected amount to foreign currency (currently supports over 60 currencies) http://users.tpg.com.au/tbchris&lt;br /&gt;
* [http://www.verdsveven.com/ubiquity/metric.html metric]: Converts numbers to metric units. Can recognize numbers in the selection and replace them.&lt;br /&gt;
* [http://samespirit.net/ricky/dev/ubiquity/chart.html  chart]: Draws a chart using the Google Charts API based on the selected table row.&lt;br /&gt;
* temperature converter - http://www.jpemartin.com/ubiq/temp.html&lt;br /&gt;
* base64 decode / encode - http://taukon.de/ubiquity-base64.php&lt;br /&gt;
* Integrate - http://tat.wright.name/ubiquity/integrate.html&lt;br /&gt;
* gcalc (interface to Google&#039;s calculator; converts units and currencies, knows constants of nature etc.) - http://math-www.uni-paderborn.de/~axel/ubiquity_gcalc.html&lt;br /&gt;
* calculate2 (a good calculator) - http://www.jpemartin.com/ubiq/calc2.html&lt;br /&gt;
&lt;br /&gt;
= Programming / development tools =&lt;br /&gt;
&lt;br /&gt;
* [http://www.ewitk.com/char-count.html char-count] is a command to count the number of characters in a block of selected text.&lt;br /&gt;
* [http://www.dahius.com/projects/ubiquity/pwgen/ pwgen] is a password generator service (http://pwgen.net)&lt;br /&gt;
* Whatismyip - http://www.srobbin.com/ubiquity-commands/whatismyip/&lt;br /&gt;
* [http://gist.github.com/10371 comments]: Display html comments on the page as css roll-over popups&lt;br /&gt;
* [http://mitcho.com/code/select select] - select gives you read access to your MySQL databases right from Ubiquity, with smart suggestions of your table and column names.&lt;br /&gt;
&lt;br /&gt;
= Random tools =&lt;br /&gt;
* [http://jasonwilsondesign.com/development-locker/ubiquity-commands/BBFlickr.php BBFlickr]: Quickly translates Flickr&#039;s generated HTML links to BBCode in your clipboard.&lt;br /&gt;
* [http://www.bennysheerin.com/ubiquity_open.html  open]: Allows you to quickly open your favourite web sites.&lt;br /&gt;
* open-in-tab - http://bergius.org/ubiquity/?open-in-tab&lt;br /&gt;
* Twurl shorten URL - http://xolotl.org/ubiquity&lt;br /&gt;
* xkcd (shows latest xkcd comic in preview pane) - http://alexsydell.com/applications/ubiquity/xkcd/&lt;br /&gt;
* flags of the world - http://www.jpemartin.com/ubiq/flag.html&lt;br /&gt;
* forecast - http://dothejustice.com/forecast/&lt;br /&gt;
* images (shows only the images on a page) - http://kloudsolutions.com&lt;br /&gt;
* [http://erikvold.com/tools/ubiquity/comicstrip/comicstrip.cfm  comicstrip]: Allows you to view a comicstrip and drop the image into an area selected (such as a gmail email). So far the command supports bc, bornloser, dilbert, garfield, getfuzzy, herman, monty, peanuts, penny-arcade, offthemark, opus, userfriendly, workingitout, and xkcd.&lt;br /&gt;
* [http://members.optusnet.com.au/~crazyjane13/lolcats.html lolcats]:  Retrieves the latest LOLCAT in the preview, jumps to page on execute - by Brett Dalton&lt;br /&gt;
*[http://members.optusnet.com.au/~crazyjane13/roll.html roll]:  Dice rolling verb, rolls single, multiple dice of any size with option for variable dificulty exploding dice pool (as per World of Darkness) - by Brett Dalton&lt;br /&gt;
*[http://student.dei.uc.pt/~rmramos/ubiquity/lorem.html lorem]: Allows you to copy any given number of words or paragraphs of the &amp;quot;Lorem Ipsum&amp;quot; placeholder text onto your Clipboard, useful if you want to paste it in some other application afterward. Use: lorem [num] nice [words||paragraphs]&lt;br /&gt;
* nofollow  - Preview counts no-follow links and execute highlights them. [[http://surfmind.com/lab/mozilla/ubiquity/nofollow.html Install Page]], [[http://surfmind.com/lab/mozilla/ubiquity/nofollow.js Script:]], [[http://flickr.com/photos/andyed/2767130077/in/photostream/ Preview]]&lt;br /&gt;
* [http://www.rakudave.ch/?q=node/26 Rhyme] a word&lt;br /&gt;
* [http://common-lisp.net/project/lifp/ubiquity/sharebee.htm sharebee-download] Sharebee &lt;br /&gt;
* [http://insideoutsites.com/ubiquity/ xbl] - displays your xbox live friends list in the preview window&lt;br /&gt;
* [http://www.nt7s.com/blog/ubiquity-qrz/ qrz] - Lookup amateur radio callsigns on the QRZ.com server.&lt;br /&gt;
* [http://www.briandgoad.com/blog/ubiquity-commands/websourceit/ websource] - Compares the popularity on the internet of two (or more) terms using Websource.It&lt;br /&gt;
* [http://www.developerfriendly.com/ubiquity/roll.php UbiquityRoll] - get your roll on demand, currently supports rickroll duckroll and hoodroll&lt;br /&gt;
* [http://www.nasser.me/ubiquity/rapidsharecom-link-checker/ rscheck] - check selected links on rapidshare.com link checker.&lt;br /&gt;
* [http://f.resourcehog.net/has-swearing.php has-swearing] - check to see if the selected text has any swearing in it; highlights any instances of swearing.&lt;br /&gt;
* [http://www.dib0.nl/ubiquity.html open-all-bookmarks-in-tabs] - opens all bookmarks filed under the given folder in new tabs. It is also possible to open bookmarks with a specific tag.&lt;br /&gt;
* [http://www.geocities.com/ubiquities1 reverse-telephone] - reverse lookup on a german telephone number via das-oertliche.de&lt;br /&gt;
* [http://www.watersheep.org/~markh/screengrab.html screengrab] - takes a screen grab of the current page.&lt;br /&gt;
* [http://stuarthendren.net/printwyl printwyl] - opens current page in [http://www.printwhatyoulike.com PrintWhayYouLike.com] so you can create a better print out of the information you need.&lt;br /&gt;
* [http://yonen.ca/ubiquity2.html qr_code] - Generates QR Code images.&lt;br /&gt;
* [http://gist.github.com/21311 notepad] - Opens Notepad on Windows&lt;br /&gt;
* [http://gist.github.com/21319 paint] - Opens MS Paint on Windows&lt;br /&gt;
* [http://mike.thedt.net/ubiquity/note/note.php note] - The purpose of this command is to quickly save the inputted text (can be selected text or your own text) to a file on your disk without having to launch a text editor.&lt;br /&gt;
* [http://boardraider-ubiquity-commands.googlecode.com/svn/trunk/fx-update-scanner.html fx-update-scanner] - Update checks for restricted user accounts&lt;br /&gt;
* [http://boardraider-ubiquity-commands.googlecode.com/svn/trunk/gd-upload.html gd-upload] - Uploads a document to Google Docs via URL&lt;br /&gt;
* [http://boardraider-ubiquity-commands.googlecode.com/svn/trunk/vacuum-places.html vacuum-places] - Executes the VACUUM statement on your places.sqlite&lt;br /&gt;
* [http://gist.github.com/62707 d20] - Searches d20srd.org.&lt;br /&gt;
* [http://kilianvalkhof.com/uploads/ubiquity-binary Binary tools] - Convert text to binary, and the other way around.&lt;br /&gt;
* [http://kilianvalkhof.com/uploads/ubiquity-yoda Yoda speak] - Convert text to how master Yoda would say it.&lt;br /&gt;
* [http://gist.github.com/70761 lyric]: Lookup song lyrics from lyrics.astraweb.com&lt;br /&gt;
* [http://gist.github.com/69722 muni]: Grab San Francisco, CA muni bus arrival information from nextmuni.com.  &#039;&#039;example: muni 24 at Divis and Fulton&#039;&#039;&lt;br /&gt;
==Flip==&lt;br /&gt;
* [http://www.michaeltheweissman.com/flip flip]: Flips text uʍop ǝpısdn&lt;br /&gt;
&lt;br /&gt;
=Development Tools=&lt;br /&gt;
== Gecko Development ==&lt;br /&gt;
* [http://sites.google.com/site/cgranade/projects/ubiquity-scripts xpc-interfaces]: Queries a list of interfaces supported by a given XPCOM contract ID.&lt;br /&gt;
&lt;br /&gt;
=Other Web Applications=&lt;br /&gt;
== Woot ==&lt;br /&gt;
[http://gist.github.com/41227 Woot Checker] - Previews the current Woot item and takes you to the &amp;quot;Want One&amp;quot; page.&lt;br /&gt;
&lt;br /&gt;
== ESV bible ==&lt;br /&gt;
[http://www.duncanandmeg.org/projects/ubiquity-esv-insert.php esv-insert, esv-insert-plain, esv-search] - Replaces the current selection with verses from the ESV Bible, or searches by passage or phrase.&lt;br /&gt;
&lt;br /&gt;
== Amazon ==&lt;br /&gt;
=== Wish List ===&lt;br /&gt;
[http://jplorenti.googlepages.com/ubiquity-wishamazon WishAmazon] - Allows adding any product page on the web to your Amazon Wish List. Similar functionality to the Amazon Universal Wish List bookmarklet.&lt;br /&gt;
&lt;br /&gt;
[http://avid.me/ubi/skreemr.html Skreemr] - Searches Skreemr.com for downloading Mp3&#039;s&lt;br /&gt;
&lt;br /&gt;
== BookMooch ==&lt;br /&gt;
[http://www.sillybean.net/downloads/ubiquity-commands.html mooch] - Search [http://bookmooch.com/ BookMooch] for the term you provide.&lt;br /&gt;
&lt;br /&gt;
== Finances ==&lt;br /&gt;
=== Buxfer ===&lt;br /&gt;
[http://gist.github.com/66959 buxfer-spend, buxfer-receive] - Adds a transaction to www.buxfer.com using its remote API, spending or receiving a given amount. (Homepage [http://sites.google.com/site/edgargoncalves/work/software/ubiquity here]).&lt;br /&gt;
&lt;br /&gt;
[http://dl.getdropbox.com/u/103378/projects/buxferubiquity/buxferubiquity.html twixfer] - Adds a transaction to www.buxfer.com, using the Twitter API (obsolete - use buxfer-spend and buxfer-receive instead) (Homepage [http://sites.google.com/site/edgargoncalves/work/software/twixfer here]).&lt;br /&gt;
&lt;br /&gt;
== GTD ==&lt;br /&gt;
=== gtd-php ===&lt;br /&gt;
[http://www.gtd-php.com/Developers/Ubiquity gtdphp] - &amp;lt;tt&amp;gt;gtdin&amp;lt;/tt&amp;gt; adds an inbox item, and &amp;lt;tt&amp;gt;gtdref&amp;lt;/tt&amp;gt; creates a reference to the current page, as a child of a specific project&lt;br /&gt;
=== Remember The Milk ===&lt;br /&gt;
* [http://garyhodgson.com/ubiquity/rtm-api.html rtm-*] - Commands to manage your Remember The Milk task lists.  Add, postpone, prioritise, complete, move and view commands are available.&lt;br /&gt;
* [http://garyhodgson.com/ubiquity/rtm.html rtm (bookmarklet)] - Opens the RTM [http://www.rememberthemilk.com/help/answers/quickadd/ quick-add bookmarklet].&lt;br /&gt;
&lt;br /&gt;
=== Gubb ===&lt;br /&gt;
[http://ivancho.awardspace.com/ubiquity/gubb.html gubb-*] - Interface to [http://gubb.net Gubb], with adding items and inserting lists/contents functionality.&lt;br /&gt;
&lt;br /&gt;
=== Nozbe ===&lt;br /&gt;
[http://svd.at.tut.by/nozbe.html nozbe-*] - commands to manage tasks in Nozbe.&lt;br /&gt;
&lt;br /&gt;
== Science ==&lt;br /&gt;
=== NCBI ===&lt;br /&gt;
[http://gist.github.com/67266] - Very preliminary attempt to access NCBI and other genomic resources - currently only Pubmed&lt;br /&gt;
&lt;br /&gt;
== Wikis ==&lt;br /&gt;
=== TiddlyWiki ===&lt;br /&gt;
[http://garyhodgson.com/ubiquity/tiddlywiki.html tw-*] - Allows you to Create, Open, or Search for keywords within, Tiddlers from your [http://www.tiddlywiki.com/ TiddlyWiki]&lt;br /&gt;
&lt;br /&gt;
== Temporary Email Address ==&lt;br /&gt;
=== Jetable.org ===&lt;br /&gt;
Script: http://gist.github.com/11261&lt;br /&gt;
&lt;br /&gt;
Creates a temporary Jetable email address for a given life span (one hour, one day, one week, one month).&lt;br /&gt;
=== Mailinator.com ===&lt;br /&gt;
mailinator - http://gist.github.com/16415&lt;br /&gt;
&lt;br /&gt;
Opens the mailinator inbox of the typed name.&lt;br /&gt;
=== Spambox.us ===&lt;br /&gt;
http://gist.github.com/41634&lt;br /&gt;
&lt;br /&gt;
Creates a temporary Spambox.us email address for a given life span (half hour, hour, half day, day, week, month, half year, year).&lt;br /&gt;
&lt;br /&gt;
== TheSixtyOne.com ==&lt;br /&gt;
[http://www.jpemartin.com/ubiq/pause-TSO.html pause-TSO] pause and resume music playback.&lt;br /&gt;
&lt;br /&gt;
== World of Warcraft ==&lt;br /&gt;
* Gryffyn&#039;s Basic Allakhazam Lookup w/Preview: http://www.gryffyndevelopment.com/ubiquity/alla.html&lt;br /&gt;
* Zenwolf&#039;s WoW Armory Command: [http://www.annieandmatt.com/ubiquity/wowarmory.html Subscribe/View code here]&lt;br /&gt;
* Amosh&#039;s Wowhead Database Search [http://gist.github.com/19910]&lt;br /&gt;
&lt;br /&gt;
== instapaper.com bookmarklet ==&lt;br /&gt;
&lt;br /&gt;
[http://www.duncanandmeg.org/projects/ubiquity-instapaper.php instapaper]: Saves current page to read later on [http://www.instapaper.com/ Instapaper]. If you select some text from the page, it will be stored as the summary. This command will store your instapaper login and password in the browser password manager. Uses the new [http://blog.instapaper.com/post/73123968/read-later-api instapaper API].&lt;br /&gt;
&lt;br /&gt;
[http://static.al3x.net/ubiquity.html later]: an alternate implementation that mimics the instapaper.com bookmarklet (requires your bookmarklet hash key). Might be a dead link now???&lt;br /&gt;
&lt;br /&gt;
== laterloop.com Bookmarklet/RSS ==&lt;br /&gt;
[http://gist.github.com/10172 laterloop-this]: Mimics functionality of the [http://www.laterloop.com laterloop] bookmarklet.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10172 laterloop]: Shows items you have saved for later in your preview.  Allows for paging and can open a specific item through use of an &amp;quot;open #&amp;quot; modifier.&lt;br /&gt;
&lt;br /&gt;
[http://gist.github.com/10172 laterloop-clear]: Utility command to clear out preference values stored when initially setting up the laterloop and laterloop-this commands.&lt;br /&gt;
&lt;br /&gt;
== Shoutcast Search ==&lt;br /&gt;
http://myfirstscript.blogspot.com/2008/10/ubiquity-is-awesome_06.html&lt;br /&gt;
Search for anything in Shoutcast, artist, song, genre. use it everytime you wanna hear that one great song!.&lt;br /&gt;
&lt;br /&gt;
== ROT13 ==&lt;br /&gt;
[http://www.randomloci.com/dev/ubiquity/rot13.php ROT13]: Translate selected text using the ROT13 algorithm. Background [http://www.randomloci.com/dev/ubiquity/index.php here].&lt;br /&gt;
&lt;br /&gt;
= Command collections =&lt;br /&gt;
&lt;br /&gt;
[http://devstatus.com/ MySpace command collection]: MySpace Command Collection&lt;br /&gt;
&lt;br /&gt;
[http://ianj.appspot.com/insert Insert words using a keyword]: insert and learn-to-insert&lt;br /&gt;
&lt;br /&gt;
[http://jorgensen.ian.googlepages.com/size.html Screen Resolution commands]: size and resize&lt;br /&gt;
&lt;br /&gt;
[http://liketribe.com/liketribe/lktrb-ubiquity.html liketribe]: chat with an intelligent assistant bot to get recommendations, directions, weather, connect with friends, or just ramble on aimlessly.&lt;br /&gt;
&lt;br /&gt;
[http://www.tonight.eu/ubiquity/ Tonight]: searches for venues, restaurants and events in your city, near a specific location.&lt;br /&gt;
&lt;br /&gt;
[http://www.bennysheerin.com/ubiquity.html news command]: simple news command.&lt;br /&gt;
&lt;br /&gt;
[http://www.rakudave.ch/?q=node/18 rakudave&#039;s commands]: firefox add-ons, ubuntu brainstorm, just-ping, rhyme&lt;br /&gt;
&lt;br /&gt;
[http://widgets.bootsnall.com/ubiquity/everystockphoto.html Everystockphoto.com]: Search for images at everystockphoto.com&lt;br /&gt;
&lt;br /&gt;
[http://widgets.bootsnall.com/ubiquity/shopping-search.html Shopping.com]: Search for products and compare prices at Shopping.com&lt;br /&gt;
&lt;br /&gt;
[http://mika.lepisto.com/ubiquity-commands-160.html Ubiquity Commands by Mika]: Random commands including Everystockphoto.com and Shopping.com referenced above.&lt;br /&gt;
&lt;br /&gt;
[http://www.ubiqcmds.co.nr issi_noho&#039;s (and others) commands]: torrentz.com and more soon. Submit your command here.&lt;br /&gt;
&lt;br /&gt;
[http://www.thecompgeek.info/ubiquity/ CyberPrime&#039;s Commands]: SearchMe.Com, demonoid, about:commands and much more to come&lt;br /&gt;
&lt;br /&gt;
[http://enobrev.info/ enobrev&#039;s commands]: php and html (with auto-completion)&lt;br /&gt;
&lt;br /&gt;
[http://swieskowski.net/verbs/ swies&#039;s commands]: dog, clock, msdn&lt;br /&gt;
&lt;br /&gt;
[http://foyrek.com/ubi.html Abi&#039;s commands]&lt;br /&gt;
&lt;br /&gt;
[http://erikvold.com/tools/ubiquity/index.cfm Erik Vold&#039;s Commands]&lt;br /&gt;
&lt;br /&gt;
[http://dietrich.ganx4.com/mozilla/ubiquity.html Dietrich&#039;s commands]&lt;br /&gt;
&lt;br /&gt;
[http://www.gilbertpellegrom.co.uk/2008/08/27/my-ubiquity-commands/ Gilbert&#039;s commands]: date, time-12, time-24&lt;br /&gt;
&lt;br /&gt;
[http://www.bjtitus.net/ubiquity/ Brandon&#039;s Commands]: FriendFeed&lt;br /&gt;
&lt;br /&gt;
[http://www.fuzzhead.com/ubiquity.html Fuzzhead&#039;s Commands]: What&#039;s My IP?&lt;br /&gt;
&lt;br /&gt;
[http://lokonline.com/ip/ubiq.html Improved IP address retrieval] Should work for ipv6 too.&lt;br /&gt;
&lt;br /&gt;
[http://sites.google.com/site/ubiquitycommands/ Whatthechuck&#039;s commands]: validate (W3C markup validator), vimeo&lt;br /&gt;
&lt;br /&gt;
[http://npattison.com/ubiquity/ Nickworks&#039;s commands]: Seeqpod, PHP.net&lt;br /&gt;
&lt;br /&gt;
[http://aufrank.net/ubiquity/ aufrank&#039;s commands]:  gfl, urej&lt;br /&gt;
&lt;br /&gt;
[http://mysite.verizon.net/zaduma/ calhoun_ftw&#039;s commands]: Embiggen TinyURL replacer adaption, newegg, pirate bay, many more, releasing new always.&lt;br /&gt;
&lt;br /&gt;
[http://www.mzzt.net/ubiq.html mzzt.net commands]: remove/replace selection, detach tab to new window, open chromeless window&lt;br /&gt;
&lt;br /&gt;
[http://ubiquity.skumleren.net FreakCERS&#039;s commands]: latex&lt;br /&gt;
&lt;br /&gt;
[http://www.satf.se/page/ubiquity-satf-se-s-commands-for-you pihl&#039;s commands]: &amp;lt;blink&amp;gt;, jaen, fix-all-problems, last.fm&lt;br /&gt;
&lt;br /&gt;
[http://web.me.com/yaztromo/rot13-ubiq.html Yaz&#039;s Commands]: rot13&lt;br /&gt;
&lt;br /&gt;
[http://hoffstein.net/ubiquity hoffstein&#039;s commands]: stock-quote, stock-chart&lt;br /&gt;
&lt;br /&gt;
[http://nocturne.net.nz/verbs Bayard&#039;s commands]: WoWhead, WoW Armoury, BBCode&lt;br /&gt;
&lt;br /&gt;
[http://grantrules.com/ubiquity Grant&#039;s commands]: Facebook, Lorem Ipsum generator, MD5/Sha1 hashes, Penis flood, What.cd artist/torrent search, UPS/USPS/FedEx tracking&lt;br /&gt;
&lt;br /&gt;
[http://www.gfx-fr.com/ubiquity/ Setsuna666&#039;s commands]: Amazon Canada &lt;br /&gt;
&lt;br /&gt;
[http://www.yalazi.org/ubiquity/list.html Onur Yalaz?&#039;s commands]: kissalt, bugmenot  &lt;br /&gt;
&lt;br /&gt;
[http://labs.vunite.com/vubiqs/verbs.php vunite&#039;s commands]: goto, shorten, craigslist&lt;br /&gt;
&lt;br /&gt;
[http://common-lisp.net/project/lifp/ubiquity/ Timofei Shatrov&#039;s commands]: clhs, myip, urban-dictionary-search, sharebee-download&lt;br /&gt;
&lt;br /&gt;
[http://jimmahdigital.com/ubiq/ Jim&#039;s commands]: add-to-reader&lt;br /&gt;
&lt;br /&gt;
[http://www.phoque.de/projekte/ubiquity/ phoque.de]: Add marked text to your blog&lt;br /&gt;
&lt;br /&gt;
[http://www.srobbin.com/ubiquity-commands/ srobbin.com]: whatismyip&lt;br /&gt;
&lt;br /&gt;
[http://tim.sorbera.googlepages.com/ubiquity.html Mini-Geek&#039;s commands]: homestar-runner-wiki, starcraft-wiki, tniv-bible-passage, tniv-bible-word, webster-dictionary, webster-thesaurus, open-url, ign, and fileshack&lt;br /&gt;
&lt;br /&gt;
[http://www.geero.net Geero&#039;s commands]: Last.fm track search, Bible Gateway ESV URL builder&lt;br /&gt;
&lt;br /&gt;
[http://www.jasonsmith.ca/articles/ubiquity_by_mozilla_labs amazon-search-all]: Search all items on [http://www.amazon.com Amazon.com]&lt;br /&gt;
&lt;br /&gt;
[http://www.mikedeboer.nl Mike&#039;s commands]: mail (uses mailto: urls)&lt;br /&gt;
&lt;br /&gt;
[http://www.bpeers.com/ubiq/ bpeers.com]: ticker (preview or paste a stock quote and its change); bling (currency conversion in google syntax)&lt;br /&gt;
&lt;br /&gt;
[http://static.al3x.net/ubquity.html]: bit.ly, Instapaper, Soup.io, Google Reader subscribe, Twitter Search, Yep, zap CSS&lt;br /&gt;
&lt;br /&gt;
[http://kollektive.com/ubiquity/ kollektive]: links - converts non-marked up text/html which contains urls and email addresses into proper anchor tags. Works within html pages, and in rich text editing fields (eg. rich text editing in GMAIL)&lt;br /&gt;
&lt;br /&gt;
[http://www.cse.cuhk.edu.hk/~gli/ubiquity.html Xatan&#039;s ubiquity commands]: google scholar, xunlei(??), baidu(??), douban(??), verycd, google news, dict.cn(??), mininova, dictionary.hm (detailed english explanation)&lt;br /&gt;
&lt;br /&gt;
[http://www.acarlos.com.br/ubiquity/ TV Globo Video Search]: searches for TV Globo and GloboSat videos (Brazil).&lt;br /&gt;
&lt;br /&gt;
[http://v0xel.ubuntusrbija.org/2008/08/31/mozilla-ubiquity-i-b92-mape-srbije/ sr-map]: Searches for street names and shows them on a map. Works for couple of cities in Serbia. &lt;br /&gt;
&lt;br /&gt;
[http://www.geocities.com/skyhopper88/ Skyhopper88&#039;s Commands] Several Search Commands, edit of Gmail script below for .1.1&lt;br /&gt;
&lt;br /&gt;
[http://17th.name/wp-content/uploads/2008/09/fanfou.html Alex&#039;s fanfou command]: post to fanfou (??)&lt;br /&gt;
&lt;br /&gt;
[http://unplugd.com/enblogd Samps&#039;s command collection]: eBay-Au, Ubuntu-WiKi, Skweezer, Wapedia, PHP function search&lt;br /&gt;
&lt;br /&gt;
[http://test.fathomthat.org/ubiquity/evav.html Evilavatar]: Search Evilavatar for new posts containing your search term&lt;br /&gt;
&lt;br /&gt;
[http://icecreamfactory.freehostia.com/ubiquity/ I.C.E.C.R.E.A.M COMMANDS]: directions, reverse-lookup, googlism&lt;br /&gt;
&lt;br /&gt;
[http://www.geocities.com/ubiquities1 Sieglinde&#039;s commands]: babylon,leo,quote,reverse-telephone&lt;br /&gt;
&lt;br /&gt;
[http://www.objectforward.com/ubiquity/ objectforward&#039;s commands]:&lt;br /&gt;
dictionary - simple command to use dictionary.reference.com for word look up.&lt;br /&gt;
thesaurus - uses thesaurus.reference.com for similar word look up.&lt;br /&gt;
I just like this better than the default &#039;define&#039; command. Enjoy!&lt;br /&gt;
&lt;br /&gt;
[http://updates.versionone.com/ubiquity/ VersionOne]: A command set for users of the VersionOne agile project management suite.&lt;br /&gt;
&lt;br /&gt;
[http://craxy.bplaced.de/prog/ubiquity/ find commands]: Commands to control the firefox search (ctrl+f)&lt;br /&gt;
&lt;br /&gt;
= Pre 0.1 Style Commands (Now Broken) =&lt;br /&gt;
&lt;br /&gt;
# Quote text for BB-style forums. [http://www.gialloporpora.netsons.org/ubiquity/index.php?command=quotebb Quotebb.js]&lt;br /&gt;
# Quotes HTML entities in your selection. [http://www.gialloporpora.netsons.org/ubiquity/index.php?command=quotehtml quotehtml.js]&lt;br /&gt;
# Opens Gmail in a new tab, as well as showing you the last couple of new messages in the preivew. [http://ubiquity-firefox.googlegroups.com/web/ubiquity_gmail.js?gda=gHCQx0IAAAD_mC6ocghADlnwgKtOZarHy0pz4L1zdfNBZQ-WVQEtDWG1qiJ7UbTIup-M2XPURDThhrjtatuGnhW3da2gcLyrMQ4HhOIVlic7wv2V2HiqYg Gmail.js]&lt;br /&gt;
#Let&#039;s you Twitter from anywhere. This command has been moved into Ubiquity core. [http://theunfocused.net/moz/ubiquity/verbs/twitter.js Twitter.js]&lt;br /&gt;
#Another micro-blogging service like Twitter/Pounce/etc., but open source Essentially identical code to Twitter+Ubiquity above, except for renaming of constants and web addresses [http://ubiquity-firefox.googlegroups.com/web/identica%20(2).js?gda=4oc_PEkAAACqaO7Aax4IB5JX_WYSl8iOrBnsuQS45ejhBtvVuEfs-xpD7Q4I70bg7A2QUTeiVCyg9p4rhRQ_Rj874eUFNZ-HhAioEG5q2hncZWbpWmJ7IQ identica(2).js]&lt;br /&gt;
#[http://www.gialloporpora.netsons.org/ubiquity/diggthis.js DiggThis.js]&lt;br /&gt;
# Converts your selection to lower case. [http://www.gialloporpora.netsons.org/ubiquity/index.php?command=tolower tolower.js]&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131036</id>
		<title>Labs/Ubiquity/Ubiquity Command Suggestions</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131036"/>
		<updated>2009-02-27T17:35:44Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Finished Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the commands suggested on this page have already been implemented, either by us or by third parties.  Please take a look at [https://labs.toolness.com/ubiquity-herd/all-feeds/ | The Herd&#039;s command feed index] to see what commands other people have implemented.  You may find what you&#039;re looking for there!&lt;br /&gt;
&lt;br /&gt;
Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
==Interesting Commands ==&lt;br /&gt;
&lt;br /&gt;
These commands are either extremely useful to everyone (likely to be included as a builtin command) or they push the boundaries of what Ubiquity can do.&lt;br /&gt;
&lt;br /&gt;
* Search the Herd for new Ubiquity commands directly using Ubiquity without having to physically navigate to the site. &lt;br /&gt;
* Commands for all of the menu items (so that I never have to reach for the mouse to menu again). Sandro mentioned this recently. &lt;br /&gt;
* Program launcher (When in Chrome, JS can launch other applications)&lt;br /&gt;
* &amp;quot;cmd&amp;quot; command to pass selected text to the command line, i.e. &amp;quot;cmd wget&amp;quot; would pass the selected text to the wget function via the cli.&lt;br /&gt;
* Upload code to pastebin (useful for sharing commands from the command-editor)&lt;br /&gt;
* Integration with webchuck extension (with the ability to view webchunks in the preview).&lt;br /&gt;
* BlueOrganizer (be inspired by this addon and it&#039;s somewhat semantic knowledge)&lt;br /&gt;
* Graphing data (currently, only sparklines are supported). Would be nice to plot bar graphs and pie charts of things like countries by GDP from Wikipedia or browser usage on my website. There&#039;s a lot to think about here but this could potentially become one of the best features of Ubiquity.&lt;br /&gt;
* Task-specific tab grouping. Allow for opening and closing a set of tabs all at once. The key question here is how to add tabs to groups using Ubiquity.&lt;br /&gt;
&lt;br /&gt;
==Search Commands==&lt;br /&gt;
*Creative Commons: Find something in CC&lt;br /&gt;
*Wikipedia in spanish: (or use it in another languages)&lt;br /&gt;
*Bookmarklet command; execute any bookmarklet via the keyboard.(This could include normal bookmarks something like quick dial with the keyboard)&lt;br /&gt;
*Map contact command, a command to get the location(s) of a contact from your contact list.( map-contact (name) )&lt;br /&gt;
* Google site search multiple urls in selection.  You would select a block of text containing multiple urls, and be able to search them all simultaneously for any given text.&lt;br /&gt;
** Is this even possible?  What is the format?  &amp;quot;site:mozilla.org,wikipedia.org test&amp;quot;?  &amp;quot;site:mozilla.org site:wikipedia.org test&amp;quot;?&lt;br /&gt;
* Flickr search (a [http://194.95.111.244/%7Ecountzero/scripts/_myImageFlow/ coverflow-like preview] would be awesome)&lt;br /&gt;
* last.fm search with preview (a first attempt has been made [http://www.geero.net/ here])&lt;br /&gt;
* Google Image Search with preview&lt;br /&gt;
** Built-in image-search command does this, no?&lt;br /&gt;
* Google Sets (part of Google labs) to give related terms based on user input&lt;br /&gt;
* More specific Google searches, like google video search on &#039;video&#039;, and google definition search type &amp;quot;define:mozilla&amp;quot; into google.&lt;br /&gt;
* A search for the Gawker sites eg: Gizmodo, Lifehacker, etc...&lt;br /&gt;
* a command to find the largest number in a given tab/present page&lt;br /&gt;
* A search for books by ISBN number for availability in libraries of your choice. Use the [http://en.wikipedia.org/wiki/Special:BookSources/ &#039;Book sources&#039;] by wikipedia to find it. To find the book with ISBN number 1871890306 in SF, you Ubiq &amp;quot;ISBN 1871890306 in San Francisco&amp;quot;, or if you are in San Francisco, you can type &amp;quot;ISBN 1871890306 here&amp;quot;, using your geo-location by ip attached to the [http://labs.toolness.com/trac/ticket/179 magic word &#039;here&#039;], which I believe will be part of Ubiq 0.2. Integration with maps in a later stage? Discuss [http://getsatisfaction.com/mozilla/topics/book_source_your_isbn_numbers_through_ubiquity here]. &lt;br /&gt;
* One command should be able to launch several searches on different sites in different tabs. It worked before, with several Utils.openUrlInBrowser&#039;s, but 0.1.1 broke it.&lt;br /&gt;
* Froogle search ([http://stanford.edu/~marce110/verbs/froogle-search.html This] works pretty well for now, but it&#039;s messy and would break if Google changed the format of the search results.)&lt;br /&gt;
* search google calendar&lt;br /&gt;
* taking the name of a television show, search for the show&#039;s schedule and add that schedule to google calendar&lt;br /&gt;
* A command that searches the web for a picture similar to one selected. using similar pixel arraignment to find pictures of better resolution or less cropped than one you might find roaming randomly.&lt;br /&gt;
** [http://blogs.msdn.com/livesearch/archive/2008/12/01/using-images-to-find-other-images.aspx Microsoft Live Search can do this]&lt;br /&gt;
* A image cover flow or even just something as simple as a image viewer. Also it should be able to add images into e-mails like the maps.&lt;br /&gt;
* Would love to see a search function for Calorie King to look up Nutrition Fact tables for foods ([http://is.gd/euXv like this one]).&lt;br /&gt;
* A search function for XHTML entities (maybe looking like [http://www.digitalmediaminute.com/reference/entity/index.php this]?) would be awesome. Not sure what auto-complete would look like for this....&lt;br /&gt;
* A function where you can highlight a text and then add additional text to that in ubiquity. For example I highlight a bands name on wiki then open Ubiquity and add a song name and then search on youtube.&lt;br /&gt;
*A search function for custom search command adding.&lt;br /&gt;
For example, allowing a user to search [input] using www.ffxiclopedia.org&#039;s main search [input] by setting &amp;quot;ffxi&amp;quot; command to it.&lt;br /&gt;
&lt;br /&gt;
==Program Integration==&lt;br /&gt;
* Goto command for navigating the web quick and easy but I want it in the core.&lt;br /&gt;
* Search command (allows you to search for text in any open tab, and then navigate you there)&lt;br /&gt;
* Flock stuff (be inspired by whatever seems to be actually useful in Flock)&lt;br /&gt;
** Especially nice if it could integrate with existing application launchers (ie: Quicksilver, Launchy, etc)&lt;br /&gt;
* Ability to take snapshots of the current window&lt;br /&gt;
* Queries for places datastores, rendering in plain html blue links (Beltzer showed me a little js console script that is a fine starting point).&lt;br /&gt;
** tag:(hci gestuers)&lt;br /&gt;
** site:google date:yesterday show:clicks&lt;br /&gt;
** starred intitle:Concept&lt;br /&gt;
* Integrate with Thunderbird, Sunbird, Songbird and other Mozilla software&lt;br /&gt;
* Allow for commands to be treated as content/arguments for other commands ie: email {map Washington DC} to myfriend@gmail.com would open up an email box to friend1 with a map of DC in the content pane&lt;br /&gt;
* clone of email command for Gajim/Pidgin/Psi/Adium...&lt;br /&gt;
* Integration with Instant Messenger clients (AIM, Pidgin, Trillion, etc) to allow inserting content into a message for a particular contact ie &#039;IM this to John&#039;&lt;br /&gt;
* Idea:: have a very, very small program run on start up, that detects when the key combination is pressed and will launch Ubiquity. After Ubiquity is dismissed, it will return to its original state.&lt;br /&gt;
* In Firefox, &amp;quot;Bookmark this&amp;quot; &amp;amp; &amp;quot;Create bookmark folder &amp;lt;data&amp;gt;&amp;quot;&lt;br /&gt;
* For Linux, allow users and other commands to be sent to the terminal...eg. IF you had selected text and wanted to open in gedit, ubiquity would tell the terminal to open gedit then paste in text..etc&lt;br /&gt;
* Ability to select the address-bar. I.e. &amp;quot;Select-address&amp;quot; would jump to the address-bar and highlight it.&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
* Annotate web pages and then share those annotations (perhaps using google notebook?)&lt;br /&gt;
* Close unrelated tabs: similar to close all related tabs&lt;br /&gt;
* Download manager - A text based download manager like wget on linux&lt;br /&gt;
* Related articles and images, possibly using Zemanta like [https://addons.mozilla.org/en-US/firefox/addon/7571 this plugin].&lt;br /&gt;
* Replace words in selected text (optional: regular expressions)&lt;br /&gt;
* Save current site into a PDF file&lt;br /&gt;
** &amp;quot;convert&amp;quot; command already does this&lt;br /&gt;
* Save page as... &amp;quot;Web Page, complete&amp;quot; to a pre-specified folder&lt;br /&gt;
* Save selection/highlighted text to a file in a pre-specified location&lt;br /&gt;
* Spell checker - any text, not just form fields&lt;br /&gt;
* Related to spell checker - take highlighted text, pass it through any number of online dictionaries, and let user select which word to use as replacement.&lt;br /&gt;
* Status message editor - Easily modify status and/or status message on popular IM protocols&lt;br /&gt;
* Perhaps &amp;quot;convert 8pm australian time to my time&amp;quot; where my timezone could automatically be obtained from CmdUtils.getLocation()&lt;br /&gt;
* &#039;Tag&#039; function:&lt;br /&gt;
** Auto-complete from current tags list would be excellent&lt;br /&gt;
** Needs to handle multiple, comma-separated tags, better.  Currently adds the comma to the tag name (eg. &#039;tag snacks, quick-meals&#039; creates a new tag called &amp;quot;snacks,&amp;quot;)&lt;br /&gt;
* &#039;Undo&#039; function should work on in-page replacements (eg. translating highlighted text or inserting a map into page)&lt;br /&gt;
* Upload selected image to [http://tinypic.com tinypic] or the like&lt;br /&gt;
* Disable &amp;quot;window.print()&amp;quot; API for all pages, or replace it with a less intrusive variant (toast notification?)&lt;br /&gt;
* Command Creator From Forms: Kind of like how you can create keyword searches by right clicking any search box, but you would be able to right-click any form from any search or web publish forms and select &amp;quot;Create Ubiquity Command...&amp;quot; which pops a box where you say the the command keyword&lt;br /&gt;
* Add a domain (current domain as default) to cookie whitelist&lt;br /&gt;
* Add a thesaurus search function&lt;br /&gt;
** http://www.zacharyspencer.com/2008/09/my-first-ubiquity-command/&lt;br /&gt;
* Restart Firefox&lt;br /&gt;
** Built-in &amp;quot;restart&amp;quot; command does this&lt;br /&gt;
* Download instead of opening URL&lt;br /&gt;
* The ability to Edit existing/installed commands. I.E. &amp;quot;edit-command define&amp;quot; would search for an installed &amp;quot;define&amp;quot; command and open the source in the command-editor.&lt;br /&gt;
* The ability to bookmark a page and bypass the [ok/cancel] dialog box so that you can bookmark related tabs all at once.&lt;br /&gt;
&lt;br /&gt;
==Site Integration==&lt;br /&gt;
*Forum (BBCode) formatting&lt;br /&gt;
*Youtube: Highlight a youtube link and embed the video. Could be used with other sites as well.&lt;br /&gt;
* Blogger:&lt;br /&gt;
** &#039;blog&#039; function, to create a new blog post from selected text&lt;br /&gt;
*Command for [http://www.mytextfile.com MyTextFile] such as, &amp;quot;note/textfile (text).&amp;quot; It should auto-save so you never leave Ubiquity, unless, opening a new tab is necessary. Very similar to how email works now.&lt;br /&gt;
* Google Calendar: &lt;br /&gt;
**ability to add more information to a calendar appointment such as location (perhaps signaled by @ ), calendar choice ( [ ] ), improved date parsing (you could say next Wednesday, and it could figure it out, maybe like [http://www.datejs.com/ DateJS]).&lt;br /&gt;
**ability to get a preview of my next 10 calendar entries.&lt;br /&gt;
** access HTTPS version of calendar, perhaps with &#039;add-to-scalendar&#039; and &#039;check-scalendar&#039;&lt;br /&gt;
* Gmail:&lt;br /&gt;
** Add contact, from a selected text to your contact list in gmail.&lt;br /&gt;
*** Add a contact group (and contacts if needed) from the emails list in a received email (all cc&#039;ed people, including the sender, excluding yourself), or from a list of email address&#039;.&lt;br /&gt;
** Gmail labels, alphabetical lookup from available labels.  Code possibly similar to the greasemonkey script [http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html macros] for gmail.&lt;br /&gt;
* Google Maps - &lt;br /&gt;
** when a google map image is inserted into a form, the image should have a link to the map on the google map site. e.g.: http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Budapest,+Hungary&amp;amp;ie=UTF8&amp;amp;z=11&amp;amp;iwloc=addr&lt;br /&gt;
** Google Directions search, perhaps separating locations with a semicolon if Ubiquity doesn&#039;t understand multiple word arguments.&lt;br /&gt;
** Route information&lt;br /&gt;
* Internationalisation (google.co.uk, ebay.co.uk. etc) &lt;br /&gt;
** weather command in Celsius&lt;br /&gt;
** localize verbs (and their parameters: 01/09 = 1st September in some country)&lt;br /&gt;
** &amp;quot;map&amp;quot; command needs to be country-specific (maps.google.com.xx)&lt;br /&gt;
* Flickr integration (ability to inject pictures/slideshows and post found images to Flickr) &lt;br /&gt;
* More advanced twitter integration (a command to view last x messages from a specific friend and another to view your recent friends timeline)&lt;br /&gt;
* Blog integration (select a chunk of text or an image and then blog about it in your favorite blog software)&lt;br /&gt;
* Fly command (possibly using [http://tripeedo.com/ Tripeedo]&#039;s built-in natural language search and the site&#039;s preview or the Kayak API) to make booking flights easier&lt;br /&gt;
* Digg (see Sandro&#039;s [http://ubiquity-firefox.googlegroups.com/web/diggthis.js diggthis command])&lt;br /&gt;
* Reddit/Mixx&lt;br /&gt;
* Del.icio.us (e.g. &amp;quot;delic this&amp;quot; or &amp;quot;delic this with tag1 tag2 tag3&amp;quot;)&lt;br /&gt;
* Turn referencing friend feed comments and tweets on a page (defaulted to the current page) into page annotations via command &amp;quot;show conversations&amp;quot;&lt;br /&gt;
* Integration with Jaiku, Plurk, Pownce, and other microblogging services (not only with Twitter)&lt;br /&gt;
* Integration with Google Docs and Google Notebook&lt;br /&gt;
* Command to send selected text to tinypaste.com and/or &amp;lt;strike&amp;gt;shorttext.com&amp;lt;/strike&amp;gt; (&amp;lt;i&amp;gt;[http://shortText.com/ Commands &#039;shorttext&#039;, &#039;longtext&#039;] now available&amp;lt;/i&amp;gt;), pastebin.com, cl1p.net etc.&lt;br /&gt;
* Subscribe to current site&#039;s feed via Google Reader or other RSS reader&lt;br /&gt;
* Add to Google Bookmarks&lt;br /&gt;
* Easily control [http://www.bitlet.org BitLet.org]&lt;br /&gt;
* Add torrents with [http://www.azureuswiki.com/index.php/HTML_WebUI Azureus&#039; HTML WebUI]. =&amp;gt; this can be done with Greasemonkey already&lt;br /&gt;
* Geotag flickr photos easily (see [http://labs.sumaato.net/tools/flickr_geocode_bookmarklet/ Localize Bookmarklet])&lt;br /&gt;
* Take highlighted thread, and paste it in a forum.  Because of the amount of forums, it might be better to just have a template for each forum type.&lt;br /&gt;
* Evernote command (post this page/text to evernote) suggested by Ben [http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/68d7f5d7f817c4d5?hl=en here]&lt;br /&gt;
* Adobe Buzzword integration&lt;br /&gt;
* tempomail / jetable (temp mail address) integration. Implemented. See [http://gist.github.com/11261 Jetable]&lt;br /&gt;
* Horde email/calendar&lt;br /&gt;
* SMS Messaging. Text-message content to a contact or phone number. Could integrate with an existing service such as: http://smseverywhere.com/send.htm&lt;br /&gt;
* Set tv recording. For those people using mythtv / myth* or a TiVo with a web front-end, if you saw a show on some web site, like tvrage or any channel that shows tv-listings, highlight the show, and say &#039;record this&#039;. This would probably be very dependent on your specific web front-end / TVR hardware.&lt;br /&gt;
*integrate into MySpace. command such as &amp;quot;send this to (myspace contact): (selected text or image, maybe even if your on youtube, it will automatically imbed.)&amp;quot; Another could be &amp;quot;set headline as (selected text or input)&amp;quot;&lt;br /&gt;
* Integrate with [http://www.squirrelmail.org/ SqirrelMail]&lt;br /&gt;
* Integrate with [http://roundcube.net/ RoundCube Mail]&lt;br /&gt;
* Integrate with [http://sourceforge.net/projects/scuttle/ Scuttle Bookmarks]&lt;br /&gt;
* Integrate with [http://webcalendar.sourceforge.net/ WebCalendar]&lt;br /&gt;
* Integrate with [http://www.rememberthemilk.com/ Remember The Milk]. Add tasks, get list of tasks, mark tasks as completed, etc. They have a really rich API. (Adding tasks is done: [http://garyhodgson.com/ubiquity/rtm.html here], with a more advanced version [http://garyhodgson.com/ubiquity/rtm-wip.html in progress].)&lt;br /&gt;
* Integrate with [http://www.toodledo.com/ Toodledo] in a similar way to that described for RTM&lt;br /&gt;
* [http://www.facebook.com Facebook] status setting-resetting integration. Ping.fm has been implemented but there are users (like me) that prefer to use only one social networking site, hence they don&#039;t need a ping.fm account. (already done [http://home.comcast.net/~captainbeah/ubiquity/facebook/ here])&lt;br /&gt;
* Integrate with [http://www.me.com/ MobileMe] to allow similar email and calendar editing integration as for the Google equivalents (GMail etc.)&lt;br /&gt;
* Integrate with [http://www.ryanair.com/ Ryanair] to allow searching for flights using Ubiquity.&lt;br /&gt;
* Subscribe with Bloglines&lt;br /&gt;
* Integrate with Google Apps (Gmail, Calendar) [http://www.google.com/apps/] to allow using the standard commands&lt;br /&gt;
&lt;br /&gt;
==Extension Integration==&lt;br /&gt;
* PasswordMaker: http://passwordmaker.org/&lt;br /&gt;
* BlueOrganizer (be inspired by [https://addons.mozilla.org/en-US/firefox/addon/3481 this addon] and it&#039;s somewhat semantic knowledge)  &lt;br /&gt;
* Take inspiration from [https://addons.mozilla.org/en-US/firefox/addon/1407  Clipmarks]&lt;br /&gt;
* Firebug integration, inspect DOM-Reference, show firebug net panel&lt;br /&gt;
* Media player control similar to [https://addons.mozilla.org/en-US/firefox/addon/219 FoxyTunes]&lt;br /&gt;
* AnyColor integration -- https://addons.mozilla.org/en-US/firefox/addon/6991&lt;br /&gt;
* Faviconize -- A command called Fav [open tab] to change it&#039;s state from showing/hiding title&lt;br /&gt;
* Commands for Screen grab! extension&lt;br /&gt;
* Undo Closed Tabs Button feature like the extension of that name. (Note: this is built into Firefox 3.0, no need for this extension anymore)&lt;br /&gt;
* Adblock Plus integration, along with NoScript.&lt;br /&gt;
* Ability to inject Webslices, for use with Webchunks.&lt;br /&gt;
* Fast Dial integration&lt;br /&gt;
* Overwrite the window.print command with a less intrusive UI. It would instead pop a notification/toaster (&amp;quot;this site wants to print itself. _Print_&amp;quot;).&lt;br /&gt;
** What does this have to do with Ubiquity?  Sounds like something for Bugzilla.&lt;br /&gt;
* Greasemonkey integration: &amp;quot;greasemonkey-edit &amp;lt;userscript&amp;gt;&amp;quot;. It would autocomplete the userscript name based on the list of installed userscripts.&lt;br /&gt;
* Cool iris functionality with a image flow.&lt;br /&gt;
&lt;br /&gt;
==Finished Commands==&lt;br /&gt;
* [http://shortText.com/ shortText.com] done. Create a URL of any selected text by using command &#039;shorttext&#039; or expand a shortText URL to its full content by using command &#039;longtext&#039;&lt;br /&gt;
* [http://www.google.com/sitesearch/ Google Site Search] integration. (Example: &amp;quot;search komplett.ie for cpu coolers&amp;quot;) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Metacritic (metacritic.com) review searching - [http://mysite.verizon.net/zaduma/ Done] [http://www.endolith.com/ubiquity_commands.html this version has ability to choose between example.org, subdomain.example.org, etc.]&lt;br /&gt;
** &amp;lt;tt&amp;gt;google-here &amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt;: site-search on current site (without typing it explicitly) =&amp;gt; ([http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/5c2c80df1c61d4f8 Done])&lt;br /&gt;
* Torrent search [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Reveal the exact URL-s behind tinyurl-s (see [http://ghill.customer.netspace.net.au/embiggen/ Embiggen Bookmarklet]) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* BugMeNot lookup for current page [http://www.geocities.com/lemming4242 Done]&lt;br /&gt;
* Open command (select multiple links, then open them all in tabs) [http://www.geocities.com/lemming4242/ Done]&lt;br /&gt;
* An online bible service command. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* A command to open a selected URL. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* Twitter Search - [http://gist.github.com/7594 Done] but could benefit from a sexier UI&lt;br /&gt;
* Random number generator.  Floating point value with input of the following type:  random lower-val higher-val&lt;br /&gt;
** Example:  Random 0 1;  Gives 0.252&lt;br /&gt;
** Example:  Random 1 100; Gives 275.840&lt;br /&gt;
** [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=12 Done]&lt;br /&gt;
* Go command (for switching between tabs by name)  (achieved by the &amp;quot;tab&amp;quot; command builtin to Ubiquity)&lt;br /&gt;
* Reopen an existing tab in a new tab. Sometimes you want to search for a new topic (in Wikipedia for example), and you have to re-open a new tab, then copy and paste the current url. Why not have a &amp;quot;re-open&amp;quot; command that lets you create a new tab, and copy the currently opened page over to it? (Alt+D &amp;gt; Alt+Enter currently does this. necessary?) (No. Did it anyways.) [http://ubiquitously.org/forum/viewtopic.php?f=5&amp;amp;t=22 Done]&lt;br /&gt;
* Currency conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done]&lt;br /&gt;
* Unit conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done (Same as above)]&lt;br /&gt;
* Stock quotes [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=26 Done]&lt;br /&gt;
* A &amp;quot;view source&amp;quot; for Ubiq commands. For example, &amp;quot;view-source link-to-wikipedia&amp;quot; =&amp;gt; [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1.1_Release_Notes available] in Ubiq 0.1.1, although not as a command.&lt;br /&gt;
* Link finder (like the &amp;quot;link-to-wikipedia&amp;quot; command but then, instead of inserting a link to wikipedia, allow the user to find the link from history/bookmarks. This would save a lot of excess work because at the moment, to insert a link, you have to open up a new tab, find the page you want to link to, copy the address and then, go back to add the link) =&amp;gt; try [http://blog.monstuff.com/archives/000343.html insert-link]&lt;br /&gt;
* Command that takes each search plugin/provider you have in the search-bar (by default, right of the locationbar in IE7 &amp;amp; FF2 &amp;amp; 3, plus more), and turns it into a command you can use.  Thus, having search plugin/providers at your fingertips in ubiquity, and adding a search plugin/provider command is just as easy as using already created functionality;  This could either be done in the underlying code of Ubiquity, or maybe have it so that the command is done as &amp;quot;Search &amp;lt;Plugin/Provider&amp;gt; &amp;lt;Terms&amp;gt;&lt;br /&gt;
** I&#039;m a moron..I actually had a command that did this.[http://theunfocused.net/moz/ubiquity/verbs/?cmd=search]&lt;br /&gt;
** Dup:  Integration of your installed Firefox search engines.&lt;br /&gt;
* Timezone converter - something like &amp;quot;get time in australia&amp;quot; ([https://wiki.mozilla.org/Labs/Ubiquity/Commands_In_The_Wild#Time Done])&lt;br /&gt;
* Ping.fm - can potentially replace twitter and facebook-status commands ([http://waleed.doubleudesigns.com/2008/08/ubiquity-and-pingfm/ Done])&lt;br /&gt;
* Mibbit IRC (mibbit [server] [optional:channels]) ([http://scguy318.freeshell.org/Mibbit%20Ubiquity%20Script.html Done])&lt;br /&gt;
Can anyone write a command that decodes 2D barcodes in images on a web page?&lt;br /&gt;
&lt;br /&gt;
-I am working on a 2D barcode translator now. I have a standard barcode reader command working: http://devstatus.com ~ matt&lt;br /&gt;
&lt;br /&gt;
*I just finished a simple Woot checker that goes to the &amp;quot;Want One&amp;quot; page on enter: [http://gist.github.com/41227 Woot]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131035</id>
		<title>Labs/Ubiquity/Ubiquity Command Suggestions</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131035"/>
		<updated>2009-02-27T17:33:55Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Finished Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the commands suggested on this page have already been implemented, either by us or by third parties.  Please take a look at [https://labs.toolness.com/ubiquity-herd/all-feeds/ | The Herd&#039;s command feed index] to see what commands other people have implemented.  You may find what you&#039;re looking for there!&lt;br /&gt;
&lt;br /&gt;
Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
==Interesting Commands ==&lt;br /&gt;
&lt;br /&gt;
These commands are either extremely useful to everyone (likely to be included as a builtin command) or they push the boundaries of what Ubiquity can do.&lt;br /&gt;
&lt;br /&gt;
* Search the Herd for new Ubiquity commands directly using Ubiquity without having to physically navigate to the site. &lt;br /&gt;
* Commands for all of the menu items (so that I never have to reach for the mouse to menu again). Sandro mentioned this recently. &lt;br /&gt;
* Program launcher (When in Chrome, JS can launch other applications)&lt;br /&gt;
* &amp;quot;cmd&amp;quot; command to pass selected text to the command line, i.e. &amp;quot;cmd wget&amp;quot; would pass the selected text to the wget function via the cli.&lt;br /&gt;
* Upload code to pastebin (useful for sharing commands from the command-editor)&lt;br /&gt;
* Integration with webchuck extension (with the ability to view webchunks in the preview).&lt;br /&gt;
* BlueOrganizer (be inspired by this addon and it&#039;s somewhat semantic knowledge)&lt;br /&gt;
* Graphing data (currently, only sparklines are supported). Would be nice to plot bar graphs and pie charts of things like countries by GDP from Wikipedia or browser usage on my website. There&#039;s a lot to think about here but this could potentially become one of the best features of Ubiquity.&lt;br /&gt;
* Task-specific tab grouping. Allow for opening and closing a set of tabs all at once. The key question here is how to add tabs to groups using Ubiquity.&lt;br /&gt;
&lt;br /&gt;
==Search Commands==&lt;br /&gt;
*Creative Commons: Find something in CC&lt;br /&gt;
*Wikipedia in spanish: (or use it in another languages)&lt;br /&gt;
*Bookmarklet command; execute any bookmarklet via the keyboard.(This could include normal bookmarks something like quick dial with the keyboard)&lt;br /&gt;
*Map contact command, a command to get the location(s) of a contact from your contact list.( map-contact (name) )&lt;br /&gt;
* Google site search multiple urls in selection.  You would select a block of text containing multiple urls, and be able to search them all simultaneously for any given text.&lt;br /&gt;
** Is this even possible?  What is the format?  &amp;quot;site:mozilla.org,wikipedia.org test&amp;quot;?  &amp;quot;site:mozilla.org site:wikipedia.org test&amp;quot;?&lt;br /&gt;
* Flickr search (a [http://194.95.111.244/%7Ecountzero/scripts/_myImageFlow/ coverflow-like preview] would be awesome)&lt;br /&gt;
* last.fm search with preview (a first attempt has been made [http://www.geero.net/ here])&lt;br /&gt;
* Google Image Search with preview&lt;br /&gt;
** Built-in image-search command does this, no?&lt;br /&gt;
* Google Sets (part of Google labs) to give related terms based on user input&lt;br /&gt;
* More specific Google searches, like google video search on &#039;video&#039;, and google definition search type &amp;quot;define:mozilla&amp;quot; into google.&lt;br /&gt;
* A search for the Gawker sites eg: Gizmodo, Lifehacker, etc...&lt;br /&gt;
* a command to find the largest number in a given tab/present page&lt;br /&gt;
* A search for books by ISBN number for availability in libraries of your choice. Use the [http://en.wikipedia.org/wiki/Special:BookSources/ &#039;Book sources&#039;] by wikipedia to find it. To find the book with ISBN number 1871890306 in SF, you Ubiq &amp;quot;ISBN 1871890306 in San Francisco&amp;quot;, or if you are in San Francisco, you can type &amp;quot;ISBN 1871890306 here&amp;quot;, using your geo-location by ip attached to the [http://labs.toolness.com/trac/ticket/179 magic word &#039;here&#039;], which I believe will be part of Ubiq 0.2. Integration with maps in a later stage? Discuss [http://getsatisfaction.com/mozilla/topics/book_source_your_isbn_numbers_through_ubiquity here]. &lt;br /&gt;
* One command should be able to launch several searches on different sites in different tabs. It worked before, with several Utils.openUrlInBrowser&#039;s, but 0.1.1 broke it.&lt;br /&gt;
* Froogle search ([http://stanford.edu/~marce110/verbs/froogle-search.html This] works pretty well for now, but it&#039;s messy and would break if Google changed the format of the search results.)&lt;br /&gt;
* search google calendar&lt;br /&gt;
* taking the name of a television show, search for the show&#039;s schedule and add that schedule to google calendar&lt;br /&gt;
* A command that searches the web for a picture similar to one selected. using similar pixel arraignment to find pictures of better resolution or less cropped than one you might find roaming randomly.&lt;br /&gt;
** [http://blogs.msdn.com/livesearch/archive/2008/12/01/using-images-to-find-other-images.aspx Microsoft Live Search can do this]&lt;br /&gt;
* A image cover flow or even just something as simple as a image viewer. Also it should be able to add images into e-mails like the maps.&lt;br /&gt;
* Would love to see a search function for Calorie King to look up Nutrition Fact tables for foods ([http://is.gd/euXv like this one]).&lt;br /&gt;
* A search function for XHTML entities (maybe looking like [http://www.digitalmediaminute.com/reference/entity/index.php this]?) would be awesome. Not sure what auto-complete would look like for this....&lt;br /&gt;
* A function where you can highlight a text and then add additional text to that in ubiquity. For example I highlight a bands name on wiki then open Ubiquity and add a song name and then search on youtube.&lt;br /&gt;
*A search function for custom search command adding.&lt;br /&gt;
For example, allowing a user to search [input] using www.ffxiclopedia.org&#039;s main search [input] by setting &amp;quot;ffxi&amp;quot; command to it.&lt;br /&gt;
&lt;br /&gt;
==Program Integration==&lt;br /&gt;
* Goto command for navigating the web quick and easy but I want it in the core.&lt;br /&gt;
* Search command (allows you to search for text in any open tab, and then navigate you there)&lt;br /&gt;
* Flock stuff (be inspired by whatever seems to be actually useful in Flock)&lt;br /&gt;
** Especially nice if it could integrate with existing application launchers (ie: Quicksilver, Launchy, etc)&lt;br /&gt;
* Ability to take snapshots of the current window&lt;br /&gt;
* Queries for places datastores, rendering in plain html blue links (Beltzer showed me a little js console script that is a fine starting point).&lt;br /&gt;
** tag:(hci gestuers)&lt;br /&gt;
** site:google date:yesterday show:clicks&lt;br /&gt;
** starred intitle:Concept&lt;br /&gt;
* Integrate with Thunderbird, Sunbird, Songbird and other Mozilla software&lt;br /&gt;
* Allow for commands to be treated as content/arguments for other commands ie: email {map Washington DC} to myfriend@gmail.com would open up an email box to friend1 with a map of DC in the content pane&lt;br /&gt;
* clone of email command for Gajim/Pidgin/Psi/Adium...&lt;br /&gt;
* Integration with Instant Messenger clients (AIM, Pidgin, Trillion, etc) to allow inserting content into a message for a particular contact ie &#039;IM this to John&#039;&lt;br /&gt;
* Idea:: have a very, very small program run on start up, that detects when the key combination is pressed and will launch Ubiquity. After Ubiquity is dismissed, it will return to its original state.&lt;br /&gt;
* In Firefox, &amp;quot;Bookmark this&amp;quot; &amp;amp; &amp;quot;Create bookmark folder &amp;lt;data&amp;gt;&amp;quot;&lt;br /&gt;
* For Linux, allow users and other commands to be sent to the terminal...eg. IF you had selected text and wanted to open in gedit, ubiquity would tell the terminal to open gedit then paste in text..etc&lt;br /&gt;
* Ability to select the address-bar. I.e. &amp;quot;Select-address&amp;quot; would jump to the address-bar and highlight it.&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
* Annotate web pages and then share those annotations (perhaps using google notebook?)&lt;br /&gt;
* Close unrelated tabs: similar to close all related tabs&lt;br /&gt;
* Download manager - A text based download manager like wget on linux&lt;br /&gt;
* Related articles and images, possibly using Zemanta like [https://addons.mozilla.org/en-US/firefox/addon/7571 this plugin].&lt;br /&gt;
* Replace words in selected text (optional: regular expressions)&lt;br /&gt;
* Save current site into a PDF file&lt;br /&gt;
** &amp;quot;convert&amp;quot; command already does this&lt;br /&gt;
* Save page as... &amp;quot;Web Page, complete&amp;quot; to a pre-specified folder&lt;br /&gt;
* Save selection/highlighted text to a file in a pre-specified location&lt;br /&gt;
* Spell checker - any text, not just form fields&lt;br /&gt;
* Related to spell checker - take highlighted text, pass it through any number of online dictionaries, and let user select which word to use as replacement.&lt;br /&gt;
* Status message editor - Easily modify status and/or status message on popular IM protocols&lt;br /&gt;
* Perhaps &amp;quot;convert 8pm australian time to my time&amp;quot; where my timezone could automatically be obtained from CmdUtils.getLocation()&lt;br /&gt;
* &#039;Tag&#039; function:&lt;br /&gt;
** Auto-complete from current tags list would be excellent&lt;br /&gt;
** Needs to handle multiple, comma-separated tags, better.  Currently adds the comma to the tag name (eg. &#039;tag snacks, quick-meals&#039; creates a new tag called &amp;quot;snacks,&amp;quot;)&lt;br /&gt;
* &#039;Undo&#039; function should work on in-page replacements (eg. translating highlighted text or inserting a map into page)&lt;br /&gt;
* Upload selected image to [http://tinypic.com tinypic] or the like&lt;br /&gt;
* Disable &amp;quot;window.print()&amp;quot; API for all pages, or replace it with a less intrusive variant (toast notification?)&lt;br /&gt;
* Command Creator From Forms: Kind of like how you can create keyword searches by right clicking any search box, but you would be able to right-click any form from any search or web publish forms and select &amp;quot;Create Ubiquity Command...&amp;quot; which pops a box where you say the the command keyword&lt;br /&gt;
* Add a domain (current domain as default) to cookie whitelist&lt;br /&gt;
* Add a thesaurus search function&lt;br /&gt;
** http://www.zacharyspencer.com/2008/09/my-first-ubiquity-command/&lt;br /&gt;
* Restart Firefox&lt;br /&gt;
** Built-in &amp;quot;restart&amp;quot; command does this&lt;br /&gt;
* Download instead of opening URL&lt;br /&gt;
* The ability to Edit existing/installed commands. I.E. &amp;quot;edit-command define&amp;quot; would search for an installed &amp;quot;define&amp;quot; command and open the source in the command-editor.&lt;br /&gt;
* The ability to bookmark a page and bypass the [ok/cancel] dialog box so that you can bookmark related tabs all at once.&lt;br /&gt;
&lt;br /&gt;
==Site Integration==&lt;br /&gt;
*Forum (BBCode) formatting&lt;br /&gt;
*Youtube: Highlight a youtube link and embed the video. Could be used with other sites as well.&lt;br /&gt;
* Blogger:&lt;br /&gt;
** &#039;blog&#039; function, to create a new blog post from selected text&lt;br /&gt;
*Command for [http://www.mytextfile.com MyTextFile] such as, &amp;quot;note/textfile (text).&amp;quot; It should auto-save so you never leave Ubiquity, unless, opening a new tab is necessary. Very similar to how email works now.&lt;br /&gt;
* Google Calendar: &lt;br /&gt;
**ability to add more information to a calendar appointment such as location (perhaps signaled by @ ), calendar choice ( [ ] ), improved date parsing (you could say next Wednesday, and it could figure it out, maybe like [http://www.datejs.com/ DateJS]).&lt;br /&gt;
**ability to get a preview of my next 10 calendar entries.&lt;br /&gt;
** access HTTPS version of calendar, perhaps with &#039;add-to-scalendar&#039; and &#039;check-scalendar&#039;&lt;br /&gt;
* Gmail:&lt;br /&gt;
** Add contact, from a selected text to your contact list in gmail.&lt;br /&gt;
*** Add a contact group (and contacts if needed) from the emails list in a received email (all cc&#039;ed people, including the sender, excluding yourself), or from a list of email address&#039;.&lt;br /&gt;
** Gmail labels, alphabetical lookup from available labels.  Code possibly similar to the greasemonkey script [http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html macros] for gmail.&lt;br /&gt;
* Google Maps - &lt;br /&gt;
** when a google map image is inserted into a form, the image should have a link to the map on the google map site. e.g.: http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Budapest,+Hungary&amp;amp;ie=UTF8&amp;amp;z=11&amp;amp;iwloc=addr&lt;br /&gt;
** Google Directions search, perhaps separating locations with a semicolon if Ubiquity doesn&#039;t understand multiple word arguments.&lt;br /&gt;
** Route information&lt;br /&gt;
* Internationalisation (google.co.uk, ebay.co.uk. etc) &lt;br /&gt;
** weather command in Celsius&lt;br /&gt;
** localize verbs (and their parameters: 01/09 = 1st September in some country)&lt;br /&gt;
** &amp;quot;map&amp;quot; command needs to be country-specific (maps.google.com.xx)&lt;br /&gt;
* Flickr integration (ability to inject pictures/slideshows and post found images to Flickr) &lt;br /&gt;
* More advanced twitter integration (a command to view last x messages from a specific friend and another to view your recent friends timeline)&lt;br /&gt;
* Blog integration (select a chunk of text or an image and then blog about it in your favorite blog software)&lt;br /&gt;
* Fly command (possibly using [http://tripeedo.com/ Tripeedo]&#039;s built-in natural language search and the site&#039;s preview or the Kayak API) to make booking flights easier&lt;br /&gt;
* Digg (see Sandro&#039;s [http://ubiquity-firefox.googlegroups.com/web/diggthis.js diggthis command])&lt;br /&gt;
* Reddit/Mixx&lt;br /&gt;
* Del.icio.us (e.g. &amp;quot;delic this&amp;quot; or &amp;quot;delic this with tag1 tag2 tag3&amp;quot;)&lt;br /&gt;
* Turn referencing friend feed comments and tweets on a page (defaulted to the current page) into page annotations via command &amp;quot;show conversations&amp;quot;&lt;br /&gt;
* Integration with Jaiku, Plurk, Pownce, and other microblogging services (not only with Twitter)&lt;br /&gt;
* Integration with Google Docs and Google Notebook&lt;br /&gt;
* Command to send selected text to tinypaste.com and/or &amp;lt;strike&amp;gt;shorttext.com&amp;lt;/strike&amp;gt; (&amp;lt;i&amp;gt;[http://shortText.com/ Commands &#039;shorttext&#039;, &#039;longtext&#039;] now available&amp;lt;/i&amp;gt;), pastebin.com, cl1p.net etc.&lt;br /&gt;
* Subscribe to current site&#039;s feed via Google Reader or other RSS reader&lt;br /&gt;
* Add to Google Bookmarks&lt;br /&gt;
* Easily control [http://www.bitlet.org BitLet.org]&lt;br /&gt;
* Add torrents with [http://www.azureuswiki.com/index.php/HTML_WebUI Azureus&#039; HTML WebUI]. =&amp;gt; this can be done with Greasemonkey already&lt;br /&gt;
* Geotag flickr photos easily (see [http://labs.sumaato.net/tools/flickr_geocode_bookmarklet/ Localize Bookmarklet])&lt;br /&gt;
* Take highlighted thread, and paste it in a forum.  Because of the amount of forums, it might be better to just have a template for each forum type.&lt;br /&gt;
* Evernote command (post this page/text to evernote) suggested by Ben [http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/68d7f5d7f817c4d5?hl=en here]&lt;br /&gt;
* Adobe Buzzword integration&lt;br /&gt;
* tempomail / jetable (temp mail address) integration. Implemented. See [http://gist.github.com/11261 Jetable]&lt;br /&gt;
* Horde email/calendar&lt;br /&gt;
* SMS Messaging. Text-message content to a contact or phone number. Could integrate with an existing service such as: http://smseverywhere.com/send.htm&lt;br /&gt;
* Set tv recording. For those people using mythtv / myth* or a TiVo with a web front-end, if you saw a show on some web site, like tvrage or any channel that shows tv-listings, highlight the show, and say &#039;record this&#039;. This would probably be very dependent on your specific web front-end / TVR hardware.&lt;br /&gt;
*integrate into MySpace. command such as &amp;quot;send this to (myspace contact): (selected text or image, maybe even if your on youtube, it will automatically imbed.)&amp;quot; Another could be &amp;quot;set headline as (selected text or input)&amp;quot;&lt;br /&gt;
* Integrate with [http://www.squirrelmail.org/ SqirrelMail]&lt;br /&gt;
* Integrate with [http://roundcube.net/ RoundCube Mail]&lt;br /&gt;
* Integrate with [http://sourceforge.net/projects/scuttle/ Scuttle Bookmarks]&lt;br /&gt;
* Integrate with [http://webcalendar.sourceforge.net/ WebCalendar]&lt;br /&gt;
* Integrate with [http://www.rememberthemilk.com/ Remember The Milk]. Add tasks, get list of tasks, mark tasks as completed, etc. They have a really rich API. (Adding tasks is done: [http://garyhodgson.com/ubiquity/rtm.html here], with a more advanced version [http://garyhodgson.com/ubiquity/rtm-wip.html in progress].)&lt;br /&gt;
* Integrate with [http://www.toodledo.com/ Toodledo] in a similar way to that described for RTM&lt;br /&gt;
* [http://www.facebook.com Facebook] status setting-resetting integration. Ping.fm has been implemented but there are users (like me) that prefer to use only one social networking site, hence they don&#039;t need a ping.fm account. (already done [http://home.comcast.net/~captainbeah/ubiquity/facebook/ here])&lt;br /&gt;
* Integrate with [http://www.me.com/ MobileMe] to allow similar email and calendar editing integration as for the Google equivalents (GMail etc.)&lt;br /&gt;
* Integrate with [http://www.ryanair.com/ Ryanair] to allow searching for flights using Ubiquity.&lt;br /&gt;
* Subscribe with Bloglines&lt;br /&gt;
* Integrate with Google Apps (Gmail, Calendar) [http://www.google.com/apps/] to allow using the standard commands&lt;br /&gt;
&lt;br /&gt;
==Extension Integration==&lt;br /&gt;
* PasswordMaker: http://passwordmaker.org/&lt;br /&gt;
* BlueOrganizer (be inspired by [https://addons.mozilla.org/en-US/firefox/addon/3481 this addon] and it&#039;s somewhat semantic knowledge)  &lt;br /&gt;
* Take inspiration from [https://addons.mozilla.org/en-US/firefox/addon/1407  Clipmarks]&lt;br /&gt;
* Firebug integration, inspect DOM-Reference, show firebug net panel&lt;br /&gt;
* Media player control similar to [https://addons.mozilla.org/en-US/firefox/addon/219 FoxyTunes]&lt;br /&gt;
* AnyColor integration -- https://addons.mozilla.org/en-US/firefox/addon/6991&lt;br /&gt;
* Faviconize -- A command called Fav [open tab] to change it&#039;s state from showing/hiding title&lt;br /&gt;
* Commands for Screen grab! extension&lt;br /&gt;
* Undo Closed Tabs Button feature like the extension of that name. (Note: this is built into Firefox 3.0, no need for this extension anymore)&lt;br /&gt;
* Adblock Plus integration, along with NoScript.&lt;br /&gt;
* Ability to inject Webslices, for use with Webchunks.&lt;br /&gt;
* Fast Dial integration&lt;br /&gt;
* Overwrite the window.print command with a less intrusive UI. It would instead pop a notification/toaster (&amp;quot;this site wants to print itself. _Print_&amp;quot;).&lt;br /&gt;
** What does this have to do with Ubiquity?  Sounds like something for Bugzilla.&lt;br /&gt;
* Greasemonkey integration: &amp;quot;greasemonkey-edit &amp;lt;userscript&amp;gt;&amp;quot;. It would autocomplete the userscript name based on the list of installed userscripts.&lt;br /&gt;
* Cool iris functionality with a image flow.&lt;br /&gt;
&lt;br /&gt;
==Finished Commands==&lt;br /&gt;
* [http://shortText.com/ shortText.com] done. Create a URL of any selected text by using command &#039;shorttext&#039; or expand a shortText URL to its full content by using command &#039;longtext&#039;&lt;br /&gt;
* [http://www.google.com/sitesearch/ Google Site Search] integration. (Example: &amp;quot;search komplett.ie for cpu coolers&amp;quot;) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Metacritic (metacritic.com) review searching - [http://mysite.verizon.net/zaduma/ Done] [http://www.endolith.com/ubiquity_commands.html this version has ability to choose between example.org, subdomain.example.org, etc.]&lt;br /&gt;
* Torrent search [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Reveal the exact URL-s behind tinyurl-s (see [http://ghill.customer.netspace.net.au/embiggen/ Embiggen Bookmarklet]) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* BugMeNot lookup for current page [http://www.geocities.com/lemming4242 Done]&lt;br /&gt;
* Open command (select multiple links, then open them all in tabs) [http://www.geocities.com/lemming4242/ Done]&lt;br /&gt;
* An online bible service command. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* A command to open a selected URL. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* Twitter Search - [http://gist.github.com/7594 Done] but could benefit from a sexier UI&lt;br /&gt;
* Random number generator.  Floating point value with input of the following type:  random lower-val higher-val&lt;br /&gt;
** Example:  Random 0 1;  Gives 0.252&lt;br /&gt;
** Example:  Random 1 100; Gives 275.840&lt;br /&gt;
** [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=12 Done]&lt;br /&gt;
* Go command (for switching between tabs by name)  (achieved by the &amp;quot;tab&amp;quot; command builtin to Ubiquity)&lt;br /&gt;
* Reopen an existing tab in a new tab. Sometimes you want to search for a new topic (in Wikipedia for example), and you have to re-open a new tab, then copy and paste the current url. Why not have a &amp;quot;re-open&amp;quot; command that lets you create a new tab, and copy the currently opened page over to it? (Alt+D &amp;gt; Alt+Enter currently does this. necessary?) (No. Did it anyways.) [http://ubiquitously.org/forum/viewtopic.php?f=5&amp;amp;t=22 Done]&lt;br /&gt;
* Currency conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done]&lt;br /&gt;
* Unit conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done (Same as above)]&lt;br /&gt;
* Stock quotes [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=26 Done]&lt;br /&gt;
* A &amp;quot;view source&amp;quot; for Ubiq commands. For example, &amp;quot;view-source link-to-wikipedia&amp;quot; =&amp;gt; [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1.1_Release_Notes available] in Ubiq 0.1.1, although not as a command.&lt;br /&gt;
* Link finder (like the &amp;quot;link-to-wikipedia&amp;quot; command but then, instead of inserting a link to wikipedia, allow the user to find the link from history/bookmarks. This would save a lot of excess work because at the moment, to insert a link, you have to open up a new tab, find the page you want to link to, copy the address and then, go back to add the link) =&amp;gt; try [http://blog.monstuff.com/archives/000343.html insert-link]&lt;br /&gt;
* Command that takes each search plugin/provider you have in the search-bar (by default, right of the locationbar in IE7 &amp;amp; FF2 &amp;amp; 3, plus more), and turns it into a command you can use.  Thus, having search plugin/providers at your fingertips in ubiquity, and adding a search plugin/provider command is just as easy as using already created functionality;  This could either be done in the underlying code of Ubiquity, or maybe have it so that the command is done as &amp;quot;Search &amp;lt;Plugin/Provider&amp;gt; &amp;lt;Terms&amp;gt;&lt;br /&gt;
** I&#039;m a moron..I actually had a command that did this.[http://theunfocused.net/moz/ubiquity/verbs/?cmd=search]&lt;br /&gt;
** Dup:  Integration of your installed Firefox search engines.&lt;br /&gt;
* Timezone converter - something like &amp;quot;get time in australia&amp;quot; ([https://wiki.mozilla.org/Labs/Ubiquity/Commands_In_The_Wild#Time Done])&lt;br /&gt;
* Ping.fm - can potentially replace twitter and facebook-status commands ([http://waleed.doubleudesigns.com/2008/08/ubiquity-and-pingfm/ Done])&lt;br /&gt;
* Mibbit IRC (mibbit [server] [optional:channels]) ([http://scguy318.freeshell.org/Mibbit%20Ubiquity%20Script.html Done])&lt;br /&gt;
* &amp;lt;tt&amp;gt;google-here &amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt;: site-search on current site (without typing it explicitly) =&amp;gt; ([http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/5c2c80df1c61d4f8 Done])&lt;br /&gt;
Can anyone write a command that decodes 2D barcodes in images on a web page?&lt;br /&gt;
&lt;br /&gt;
-I am working on a 2D barcode translator now. I have a standard barcode reader command working: http://devstatus.com ~ matt&lt;br /&gt;
&lt;br /&gt;
*I just finished a simple Woot checker that goes to the &amp;quot;Want One&amp;quot; page on enter: [http://gist.github.com/41227 Woot]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131034</id>
		<title>Labs/Ubiquity/Ubiquity Command Suggestions</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131034"/>
		<updated>2009-02-27T17:30:48Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Extension Integration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the commands suggested on this page have already been implemented, either by us or by third parties.  Please take a look at [https://labs.toolness.com/ubiquity-herd/all-feeds/ | The Herd&#039;s command feed index] to see what commands other people have implemented.  You may find what you&#039;re looking for there!&lt;br /&gt;
&lt;br /&gt;
Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
==Interesting Commands ==&lt;br /&gt;
&lt;br /&gt;
These commands are either extremely useful to everyone (likely to be included as a builtin command) or they push the boundaries of what Ubiquity can do.&lt;br /&gt;
&lt;br /&gt;
* Search the Herd for new Ubiquity commands directly using Ubiquity without having to physically navigate to the site. &lt;br /&gt;
* Commands for all of the menu items (so that I never have to reach for the mouse to menu again). Sandro mentioned this recently. &lt;br /&gt;
* Program launcher (When in Chrome, JS can launch other applications)&lt;br /&gt;
* &amp;quot;cmd&amp;quot; command to pass selected text to the command line, i.e. &amp;quot;cmd wget&amp;quot; would pass the selected text to the wget function via the cli.&lt;br /&gt;
* Upload code to pastebin (useful for sharing commands from the command-editor)&lt;br /&gt;
* Integration with webchuck extension (with the ability to view webchunks in the preview).&lt;br /&gt;
* BlueOrganizer (be inspired by this addon and it&#039;s somewhat semantic knowledge)&lt;br /&gt;
* Graphing data (currently, only sparklines are supported). Would be nice to plot bar graphs and pie charts of things like countries by GDP from Wikipedia or browser usage on my website. There&#039;s a lot to think about here but this could potentially become one of the best features of Ubiquity.&lt;br /&gt;
* Task-specific tab grouping. Allow for opening and closing a set of tabs all at once. The key question here is how to add tabs to groups using Ubiquity.&lt;br /&gt;
&lt;br /&gt;
==Search Commands==&lt;br /&gt;
*Creative Commons: Find something in CC&lt;br /&gt;
*Wikipedia in spanish: (or use it in another languages)&lt;br /&gt;
*Bookmarklet command; execute any bookmarklet via the keyboard.(This could include normal bookmarks something like quick dial with the keyboard)&lt;br /&gt;
*Map contact command, a command to get the location(s) of a contact from your contact list.( map-contact (name) )&lt;br /&gt;
* Google site search multiple urls in selection.  You would select a block of text containing multiple urls, and be able to search them all simultaneously for any given text.&lt;br /&gt;
** Is this even possible?  What is the format?  &amp;quot;site:mozilla.org,wikipedia.org test&amp;quot;?  &amp;quot;site:mozilla.org site:wikipedia.org test&amp;quot;?&lt;br /&gt;
* Flickr search (a [http://194.95.111.244/%7Ecountzero/scripts/_myImageFlow/ coverflow-like preview] would be awesome)&lt;br /&gt;
* last.fm search with preview (a first attempt has been made [http://www.geero.net/ here])&lt;br /&gt;
* Google Image Search with preview&lt;br /&gt;
** Built-in image-search command does this, no?&lt;br /&gt;
* Google Sets (part of Google labs) to give related terms based on user input&lt;br /&gt;
* More specific Google searches, like google video search on &#039;video&#039;, and google definition search type &amp;quot;define:mozilla&amp;quot; into google.&lt;br /&gt;
* A search for the Gawker sites eg: Gizmodo, Lifehacker, etc...&lt;br /&gt;
* a command to find the largest number in a given tab/present page&lt;br /&gt;
* A search for books by ISBN number for availability in libraries of your choice. Use the [http://en.wikipedia.org/wiki/Special:BookSources/ &#039;Book sources&#039;] by wikipedia to find it. To find the book with ISBN number 1871890306 in SF, you Ubiq &amp;quot;ISBN 1871890306 in San Francisco&amp;quot;, or if you are in San Francisco, you can type &amp;quot;ISBN 1871890306 here&amp;quot;, using your geo-location by ip attached to the [http://labs.toolness.com/trac/ticket/179 magic word &#039;here&#039;], which I believe will be part of Ubiq 0.2. Integration with maps in a later stage? Discuss [http://getsatisfaction.com/mozilla/topics/book_source_your_isbn_numbers_through_ubiquity here]. &lt;br /&gt;
* One command should be able to launch several searches on different sites in different tabs. It worked before, with several Utils.openUrlInBrowser&#039;s, but 0.1.1 broke it.&lt;br /&gt;
* Froogle search ([http://stanford.edu/~marce110/verbs/froogle-search.html This] works pretty well for now, but it&#039;s messy and would break if Google changed the format of the search results.)&lt;br /&gt;
* search google calendar&lt;br /&gt;
* taking the name of a television show, search for the show&#039;s schedule and add that schedule to google calendar&lt;br /&gt;
* A command that searches the web for a picture similar to one selected. using similar pixel arraignment to find pictures of better resolution or less cropped than one you might find roaming randomly.&lt;br /&gt;
** [http://blogs.msdn.com/livesearch/archive/2008/12/01/using-images-to-find-other-images.aspx Microsoft Live Search can do this]&lt;br /&gt;
* A image cover flow or even just something as simple as a image viewer. Also it should be able to add images into e-mails like the maps.&lt;br /&gt;
* Would love to see a search function for Calorie King to look up Nutrition Fact tables for foods ([http://is.gd/euXv like this one]).&lt;br /&gt;
* A search function for XHTML entities (maybe looking like [http://www.digitalmediaminute.com/reference/entity/index.php this]?) would be awesome. Not sure what auto-complete would look like for this....&lt;br /&gt;
* A function where you can highlight a text and then add additional text to that in ubiquity. For example I highlight a bands name on wiki then open Ubiquity and add a song name and then search on youtube.&lt;br /&gt;
*A search function for custom search command adding.&lt;br /&gt;
For example, allowing a user to search [input] using www.ffxiclopedia.org&#039;s main search [input] by setting &amp;quot;ffxi&amp;quot; command to it.&lt;br /&gt;
&lt;br /&gt;
==Program Integration==&lt;br /&gt;
* Goto command for navigating the web quick and easy but I want it in the core.&lt;br /&gt;
* Search command (allows you to search for text in any open tab, and then navigate you there)&lt;br /&gt;
* Flock stuff (be inspired by whatever seems to be actually useful in Flock)&lt;br /&gt;
** Especially nice if it could integrate with existing application launchers (ie: Quicksilver, Launchy, etc)&lt;br /&gt;
* Ability to take snapshots of the current window&lt;br /&gt;
* Queries for places datastores, rendering in plain html blue links (Beltzer showed me a little js console script that is a fine starting point).&lt;br /&gt;
** tag:(hci gestuers)&lt;br /&gt;
** site:google date:yesterday show:clicks&lt;br /&gt;
** starred intitle:Concept&lt;br /&gt;
* Integrate with Thunderbird, Sunbird, Songbird and other Mozilla software&lt;br /&gt;
* Allow for commands to be treated as content/arguments for other commands ie: email {map Washington DC} to myfriend@gmail.com would open up an email box to friend1 with a map of DC in the content pane&lt;br /&gt;
* clone of email command for Gajim/Pidgin/Psi/Adium...&lt;br /&gt;
* Integration with Instant Messenger clients (AIM, Pidgin, Trillion, etc) to allow inserting content into a message for a particular contact ie &#039;IM this to John&#039;&lt;br /&gt;
* Idea:: have a very, very small program run on start up, that detects when the key combination is pressed and will launch Ubiquity. After Ubiquity is dismissed, it will return to its original state.&lt;br /&gt;
* In Firefox, &amp;quot;Bookmark this&amp;quot; &amp;amp; &amp;quot;Create bookmark folder &amp;lt;data&amp;gt;&amp;quot;&lt;br /&gt;
* For Linux, allow users and other commands to be sent to the terminal...eg. IF you had selected text and wanted to open in gedit, ubiquity would tell the terminal to open gedit then paste in text..etc&lt;br /&gt;
* Ability to select the address-bar. I.e. &amp;quot;Select-address&amp;quot; would jump to the address-bar and highlight it.&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
* Annotate web pages and then share those annotations (perhaps using google notebook?)&lt;br /&gt;
* Close unrelated tabs: similar to close all related tabs&lt;br /&gt;
* Download manager - A text based download manager like wget on linux&lt;br /&gt;
* Related articles and images, possibly using Zemanta like [https://addons.mozilla.org/en-US/firefox/addon/7571 this plugin].&lt;br /&gt;
* Replace words in selected text (optional: regular expressions)&lt;br /&gt;
* Save current site into a PDF file&lt;br /&gt;
** &amp;quot;convert&amp;quot; command already does this&lt;br /&gt;
* Save page as... &amp;quot;Web Page, complete&amp;quot; to a pre-specified folder&lt;br /&gt;
* Save selection/highlighted text to a file in a pre-specified location&lt;br /&gt;
* Spell checker - any text, not just form fields&lt;br /&gt;
* Related to spell checker - take highlighted text, pass it through any number of online dictionaries, and let user select which word to use as replacement.&lt;br /&gt;
* Status message editor - Easily modify status and/or status message on popular IM protocols&lt;br /&gt;
* Perhaps &amp;quot;convert 8pm australian time to my time&amp;quot; where my timezone could automatically be obtained from CmdUtils.getLocation()&lt;br /&gt;
* &#039;Tag&#039; function:&lt;br /&gt;
** Auto-complete from current tags list would be excellent&lt;br /&gt;
** Needs to handle multiple, comma-separated tags, better.  Currently adds the comma to the tag name (eg. &#039;tag snacks, quick-meals&#039; creates a new tag called &amp;quot;snacks,&amp;quot;)&lt;br /&gt;
* &#039;Undo&#039; function should work on in-page replacements (eg. translating highlighted text or inserting a map into page)&lt;br /&gt;
* Upload selected image to [http://tinypic.com tinypic] or the like&lt;br /&gt;
* Disable &amp;quot;window.print()&amp;quot; API for all pages, or replace it with a less intrusive variant (toast notification?)&lt;br /&gt;
* Command Creator From Forms: Kind of like how you can create keyword searches by right clicking any search box, but you would be able to right-click any form from any search or web publish forms and select &amp;quot;Create Ubiquity Command...&amp;quot; which pops a box where you say the the command keyword&lt;br /&gt;
* Add a domain (current domain as default) to cookie whitelist&lt;br /&gt;
* Add a thesaurus search function&lt;br /&gt;
** http://www.zacharyspencer.com/2008/09/my-first-ubiquity-command/&lt;br /&gt;
* Restart Firefox&lt;br /&gt;
** Built-in &amp;quot;restart&amp;quot; command does this&lt;br /&gt;
* Download instead of opening URL&lt;br /&gt;
* The ability to Edit existing/installed commands. I.E. &amp;quot;edit-command define&amp;quot; would search for an installed &amp;quot;define&amp;quot; command and open the source in the command-editor.&lt;br /&gt;
* The ability to bookmark a page and bypass the [ok/cancel] dialog box so that you can bookmark related tabs all at once.&lt;br /&gt;
&lt;br /&gt;
==Site Integration==&lt;br /&gt;
*Forum (BBCode) formatting&lt;br /&gt;
*Youtube: Highlight a youtube link and embed the video. Could be used with other sites as well.&lt;br /&gt;
* Blogger:&lt;br /&gt;
** &#039;blog&#039; function, to create a new blog post from selected text&lt;br /&gt;
*Command for [http://www.mytextfile.com MyTextFile] such as, &amp;quot;note/textfile (text).&amp;quot; It should auto-save so you never leave Ubiquity, unless, opening a new tab is necessary. Very similar to how email works now.&lt;br /&gt;
* Google Calendar: &lt;br /&gt;
**ability to add more information to a calendar appointment such as location (perhaps signaled by @ ), calendar choice ( [ ] ), improved date parsing (you could say next Wednesday, and it could figure it out, maybe like [http://www.datejs.com/ DateJS]).&lt;br /&gt;
**ability to get a preview of my next 10 calendar entries.&lt;br /&gt;
** access HTTPS version of calendar, perhaps with &#039;add-to-scalendar&#039; and &#039;check-scalendar&#039;&lt;br /&gt;
* Gmail:&lt;br /&gt;
** Add contact, from a selected text to your contact list in gmail.&lt;br /&gt;
*** Add a contact group (and contacts if needed) from the emails list in a received email (all cc&#039;ed people, including the sender, excluding yourself), or from a list of email address&#039;.&lt;br /&gt;
** Gmail labels, alphabetical lookup from available labels.  Code possibly similar to the greasemonkey script [http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html macros] for gmail.&lt;br /&gt;
* Google Maps - &lt;br /&gt;
** when a google map image is inserted into a form, the image should have a link to the map on the google map site. e.g.: http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Budapest,+Hungary&amp;amp;ie=UTF8&amp;amp;z=11&amp;amp;iwloc=addr&lt;br /&gt;
** Google Directions search, perhaps separating locations with a semicolon if Ubiquity doesn&#039;t understand multiple word arguments.&lt;br /&gt;
** Route information&lt;br /&gt;
* Internationalisation (google.co.uk, ebay.co.uk. etc) &lt;br /&gt;
** weather command in Celsius&lt;br /&gt;
** localize verbs (and their parameters: 01/09 = 1st September in some country)&lt;br /&gt;
** &amp;quot;map&amp;quot; command needs to be country-specific (maps.google.com.xx)&lt;br /&gt;
* Flickr integration (ability to inject pictures/slideshows and post found images to Flickr) &lt;br /&gt;
* More advanced twitter integration (a command to view last x messages from a specific friend and another to view your recent friends timeline)&lt;br /&gt;
* Blog integration (select a chunk of text or an image and then blog about it in your favorite blog software)&lt;br /&gt;
* Fly command (possibly using [http://tripeedo.com/ Tripeedo]&#039;s built-in natural language search and the site&#039;s preview or the Kayak API) to make booking flights easier&lt;br /&gt;
* Digg (see Sandro&#039;s [http://ubiquity-firefox.googlegroups.com/web/diggthis.js diggthis command])&lt;br /&gt;
* Reddit/Mixx&lt;br /&gt;
* Del.icio.us (e.g. &amp;quot;delic this&amp;quot; or &amp;quot;delic this with tag1 tag2 tag3&amp;quot;)&lt;br /&gt;
* Turn referencing friend feed comments and tweets on a page (defaulted to the current page) into page annotations via command &amp;quot;show conversations&amp;quot;&lt;br /&gt;
* Integration with Jaiku, Plurk, Pownce, and other microblogging services (not only with Twitter)&lt;br /&gt;
* Integration with Google Docs and Google Notebook&lt;br /&gt;
* Command to send selected text to tinypaste.com and/or &amp;lt;strike&amp;gt;shorttext.com&amp;lt;/strike&amp;gt; (&amp;lt;i&amp;gt;[http://shortText.com/ Commands &#039;shorttext&#039;, &#039;longtext&#039;] now available&amp;lt;/i&amp;gt;), pastebin.com, cl1p.net etc.&lt;br /&gt;
* Subscribe to current site&#039;s feed via Google Reader or other RSS reader&lt;br /&gt;
* Add to Google Bookmarks&lt;br /&gt;
* Easily control [http://www.bitlet.org BitLet.org]&lt;br /&gt;
* Add torrents with [http://www.azureuswiki.com/index.php/HTML_WebUI Azureus&#039; HTML WebUI]. =&amp;gt; this can be done with Greasemonkey already&lt;br /&gt;
* Geotag flickr photos easily (see [http://labs.sumaato.net/tools/flickr_geocode_bookmarklet/ Localize Bookmarklet])&lt;br /&gt;
* Take highlighted thread, and paste it in a forum.  Because of the amount of forums, it might be better to just have a template for each forum type.&lt;br /&gt;
* Evernote command (post this page/text to evernote) suggested by Ben [http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/68d7f5d7f817c4d5?hl=en here]&lt;br /&gt;
* Adobe Buzzword integration&lt;br /&gt;
* tempomail / jetable (temp mail address) integration. Implemented. See [http://gist.github.com/11261 Jetable]&lt;br /&gt;
* Horde email/calendar&lt;br /&gt;
* SMS Messaging. Text-message content to a contact or phone number. Could integrate with an existing service such as: http://smseverywhere.com/send.htm&lt;br /&gt;
* Set tv recording. For those people using mythtv / myth* or a TiVo with a web front-end, if you saw a show on some web site, like tvrage or any channel that shows tv-listings, highlight the show, and say &#039;record this&#039;. This would probably be very dependent on your specific web front-end / TVR hardware.&lt;br /&gt;
*integrate into MySpace. command such as &amp;quot;send this to (myspace contact): (selected text or image, maybe even if your on youtube, it will automatically imbed.)&amp;quot; Another could be &amp;quot;set headline as (selected text or input)&amp;quot;&lt;br /&gt;
* Integrate with [http://www.squirrelmail.org/ SqirrelMail]&lt;br /&gt;
* Integrate with [http://roundcube.net/ RoundCube Mail]&lt;br /&gt;
* Integrate with [http://sourceforge.net/projects/scuttle/ Scuttle Bookmarks]&lt;br /&gt;
* Integrate with [http://webcalendar.sourceforge.net/ WebCalendar]&lt;br /&gt;
* Integrate with [http://www.rememberthemilk.com/ Remember The Milk]. Add tasks, get list of tasks, mark tasks as completed, etc. They have a really rich API. (Adding tasks is done: [http://garyhodgson.com/ubiquity/rtm.html here], with a more advanced version [http://garyhodgson.com/ubiquity/rtm-wip.html in progress].)&lt;br /&gt;
* Integrate with [http://www.toodledo.com/ Toodledo] in a similar way to that described for RTM&lt;br /&gt;
* [http://www.facebook.com Facebook] status setting-resetting integration. Ping.fm has been implemented but there are users (like me) that prefer to use only one social networking site, hence they don&#039;t need a ping.fm account. (already done [http://home.comcast.net/~captainbeah/ubiquity/facebook/ here])&lt;br /&gt;
* Integrate with [http://www.me.com/ MobileMe] to allow similar email and calendar editing integration as for the Google equivalents (GMail etc.)&lt;br /&gt;
* Integrate with [http://www.ryanair.com/ Ryanair] to allow searching for flights using Ubiquity.&lt;br /&gt;
* Subscribe with Bloglines&lt;br /&gt;
* Integrate with Google Apps (Gmail, Calendar) [http://www.google.com/apps/] to allow using the standard commands&lt;br /&gt;
&lt;br /&gt;
==Extension Integration==&lt;br /&gt;
* PasswordMaker: http://passwordmaker.org/&lt;br /&gt;
* BlueOrganizer (be inspired by [https://addons.mozilla.org/en-US/firefox/addon/3481 this addon] and it&#039;s somewhat semantic knowledge)  &lt;br /&gt;
* Take inspiration from [https://addons.mozilla.org/en-US/firefox/addon/1407  Clipmarks]&lt;br /&gt;
* Firebug integration, inspect DOM-Reference, show firebug net panel&lt;br /&gt;
* Media player control similar to [https://addons.mozilla.org/en-US/firefox/addon/219 FoxyTunes]&lt;br /&gt;
* AnyColor integration -- https://addons.mozilla.org/en-US/firefox/addon/6991&lt;br /&gt;
* Faviconize -- A command called Fav [open tab] to change it&#039;s state from showing/hiding title&lt;br /&gt;
* Commands for Screen grab! extension&lt;br /&gt;
* Undo Closed Tabs Button feature like the extension of that name. (Note: this is built into Firefox 3.0, no need for this extension anymore)&lt;br /&gt;
* Adblock Plus integration, along with NoScript.&lt;br /&gt;
* Ability to inject Webslices, for use with Webchunks.&lt;br /&gt;
* Fast Dial integration&lt;br /&gt;
* Overwrite the window.print command with a less intrusive UI. It would instead pop a notification/toaster (&amp;quot;this site wants to print itself. _Print_&amp;quot;).&lt;br /&gt;
** What does this have to do with Ubiquity?  Sounds like something for Bugzilla.&lt;br /&gt;
* Greasemonkey integration: &amp;quot;greasemonkey-edit &amp;lt;userscript&amp;gt;&amp;quot;. It would autocomplete the userscript name based on the list of installed userscripts.&lt;br /&gt;
* Cool iris functionality with a image flow.&lt;br /&gt;
&lt;br /&gt;
==Finished Commands==&lt;br /&gt;
* [http://shortText.com/ shortText.com] done. Create a URL of any selected text by using command &#039;shorttext&#039; or expand a shortText URL to its full content by using command &#039;longtext&#039;&lt;br /&gt;
* [http://www.google.com/sitesearch/ Google Site Search] integration. (Example: &amp;quot;search komplett.ie for cpu coolers&amp;quot;) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Metacritic (metacritic.com) review searching - [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Torrent search [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Reveal the exact URL-s behind tinyurl-s (see [http://ghill.customer.netspace.net.au/embiggen/ Embiggen Bookmarklet]) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* BugMeNot lookup for current page [http://www.geocities.com/lemming4242 Done]&lt;br /&gt;
* Open command (select multiple links, then open them all in tabs) [http://www.geocities.com/lemming4242/ Done]&lt;br /&gt;
* An online bible service command. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* A command to open a selected URL. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* Twitter Search - [http://gist.github.com/7594 Done] but could benefit from a sexier UI&lt;br /&gt;
* Random number generator.  Floating point value with input of the following type:  random lower-val higher-val&lt;br /&gt;
** Example:  Random 0 1;  Gives 0.252&lt;br /&gt;
** Example:  Random 1 100; Gives 275.840&lt;br /&gt;
** [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=12 Done]&lt;br /&gt;
* Go command (for switching between tabs by name)  (achieved by the &amp;quot;tab&amp;quot; command builtin to Ubiquity)&lt;br /&gt;
* Reopen an existing tab in a new tab. Sometimes you want to search for a new topic (in Wikipedia for example), and you have to re-open a new tab, then copy and paste the current url. Why not have a &amp;quot;re-open&amp;quot; command that lets you create a new tab, and copy the currently opened page over to it? (Alt+D &amp;gt; Alt+Enter currently does this. necessary?) (No. Did it anyways.) [http://ubiquitously.org/forum/viewtopic.php?f=5&amp;amp;t=22 Done]&lt;br /&gt;
* Currency conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done]&lt;br /&gt;
* Unit conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done (Same as above)]&lt;br /&gt;
* Stock quotes [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=26 Done]&lt;br /&gt;
* A &amp;quot;view source&amp;quot; for Ubiq commands. For example, &amp;quot;view-source link-to-wikipedia&amp;quot; =&amp;gt; [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1.1_Release_Notes available] in Ubiq 0.1.1, although not as a command.&lt;br /&gt;
* Link finder (like the &amp;quot;link-to-wikipedia&amp;quot; command but then, instead of inserting a link to wikipedia, allow the user to find the link from history/bookmarks. This would save a lot of excess work because at the moment, to insert a link, you have to open up a new tab, find the page you want to link to, copy the address and then, go back to add the link) =&amp;gt; try [http://blog.monstuff.com/archives/000343.html insert-link]&lt;br /&gt;
* Command that takes each search plugin/provider you have in the search-bar (by default, right of the locationbar in IE7 &amp;amp; FF2 &amp;amp; 3, plus more), and turns it into a command you can use.  Thus, having search plugin/providers at your fingertips in ubiquity, and adding a search plugin/provider command is just as easy as using already created functionality;  This could either be done in the underlying code of Ubiquity, or maybe have it so that the command is done as &amp;quot;Search &amp;lt;Plugin/Provider&amp;gt; &amp;lt;Terms&amp;gt;&lt;br /&gt;
** I&#039;m a moron..I actually had a command that did this.[http://theunfocused.net/moz/ubiquity/verbs/?cmd=search]&lt;br /&gt;
** Dup:  Integration of your installed Firefox search engines.&lt;br /&gt;
* Timezone converter - something like &amp;quot;get time in australia&amp;quot; ([https://wiki.mozilla.org/Labs/Ubiquity/Commands_In_The_Wild#Time Done])&lt;br /&gt;
* Ping.fm - can potentially replace twitter and facebook-status commands ([http://waleed.doubleudesigns.com/2008/08/ubiquity-and-pingfm/ Done])&lt;br /&gt;
* Mibbit IRC (mibbit [server] [optional:channels]) ([http://scguy318.freeshell.org/Mibbit%20Ubiquity%20Script.html Done])&lt;br /&gt;
* &amp;lt;tt&amp;gt;google-here &amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt;: site-search on current site (without typing it explicitly) =&amp;gt; ([http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/5c2c80df1c61d4f8 Done])&lt;br /&gt;
Can anyone write a command that decodes 2D barcodes in images on a web page?&lt;br /&gt;
&lt;br /&gt;
-I am working on a 2D barcode translator now. I have a standard barcode reader command working: http://devstatus.com ~ matt&lt;br /&gt;
&lt;br /&gt;
*I just finished a simple Woot checker that goes to the &amp;quot;Want One&amp;quot; page on enter: [http://gist.github.com/41227 Woot]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131033</id>
		<title>Labs/Ubiquity/Ubiquity Command Suggestions</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131033"/>
		<updated>2009-02-27T17:26:38Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Tools */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the commands suggested on this page have already been implemented, either by us or by third parties.  Please take a look at [https://labs.toolness.com/ubiquity-herd/all-feeds/ | The Herd&#039;s command feed index] to see what commands other people have implemented.  You may find what you&#039;re looking for there!&lt;br /&gt;
&lt;br /&gt;
Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
==Interesting Commands ==&lt;br /&gt;
&lt;br /&gt;
These commands are either extremely useful to everyone (likely to be included as a builtin command) or they push the boundaries of what Ubiquity can do.&lt;br /&gt;
&lt;br /&gt;
* Search the Herd for new Ubiquity commands directly using Ubiquity without having to physically navigate to the site. &lt;br /&gt;
* Commands for all of the menu items (so that I never have to reach for the mouse to menu again). Sandro mentioned this recently. &lt;br /&gt;
* Program launcher (When in Chrome, JS can launch other applications)&lt;br /&gt;
* &amp;quot;cmd&amp;quot; command to pass selected text to the command line, i.e. &amp;quot;cmd wget&amp;quot; would pass the selected text to the wget function via the cli.&lt;br /&gt;
* Upload code to pastebin (useful for sharing commands from the command-editor)&lt;br /&gt;
* Integration with webchuck extension (with the ability to view webchunks in the preview).&lt;br /&gt;
* BlueOrganizer (be inspired by this addon and it&#039;s somewhat semantic knowledge)&lt;br /&gt;
* Graphing data (currently, only sparklines are supported). Would be nice to plot bar graphs and pie charts of things like countries by GDP from Wikipedia or browser usage on my website. There&#039;s a lot to think about here but this could potentially become one of the best features of Ubiquity.&lt;br /&gt;
* Task-specific tab grouping. Allow for opening and closing a set of tabs all at once. The key question here is how to add tabs to groups using Ubiquity.&lt;br /&gt;
&lt;br /&gt;
==Search Commands==&lt;br /&gt;
*Creative Commons: Find something in CC&lt;br /&gt;
*Wikipedia in spanish: (or use it in another languages)&lt;br /&gt;
*Bookmarklet command; execute any bookmarklet via the keyboard.(This could include normal bookmarks something like quick dial with the keyboard)&lt;br /&gt;
*Map contact command, a command to get the location(s) of a contact from your contact list.( map-contact (name) )&lt;br /&gt;
* Google site search multiple urls in selection.  You would select a block of text containing multiple urls, and be able to search them all simultaneously for any given text.&lt;br /&gt;
** Is this even possible?  What is the format?  &amp;quot;site:mozilla.org,wikipedia.org test&amp;quot;?  &amp;quot;site:mozilla.org site:wikipedia.org test&amp;quot;?&lt;br /&gt;
* Flickr search (a [http://194.95.111.244/%7Ecountzero/scripts/_myImageFlow/ coverflow-like preview] would be awesome)&lt;br /&gt;
* last.fm search with preview (a first attempt has been made [http://www.geero.net/ here])&lt;br /&gt;
* Google Image Search with preview&lt;br /&gt;
** Built-in image-search command does this, no?&lt;br /&gt;
* Google Sets (part of Google labs) to give related terms based on user input&lt;br /&gt;
* More specific Google searches, like google video search on &#039;video&#039;, and google definition search type &amp;quot;define:mozilla&amp;quot; into google.&lt;br /&gt;
* A search for the Gawker sites eg: Gizmodo, Lifehacker, etc...&lt;br /&gt;
* a command to find the largest number in a given tab/present page&lt;br /&gt;
* A search for books by ISBN number for availability in libraries of your choice. Use the [http://en.wikipedia.org/wiki/Special:BookSources/ &#039;Book sources&#039;] by wikipedia to find it. To find the book with ISBN number 1871890306 in SF, you Ubiq &amp;quot;ISBN 1871890306 in San Francisco&amp;quot;, or if you are in San Francisco, you can type &amp;quot;ISBN 1871890306 here&amp;quot;, using your geo-location by ip attached to the [http://labs.toolness.com/trac/ticket/179 magic word &#039;here&#039;], which I believe will be part of Ubiq 0.2. Integration with maps in a later stage? Discuss [http://getsatisfaction.com/mozilla/topics/book_source_your_isbn_numbers_through_ubiquity here]. &lt;br /&gt;
* One command should be able to launch several searches on different sites in different tabs. It worked before, with several Utils.openUrlInBrowser&#039;s, but 0.1.1 broke it.&lt;br /&gt;
* Froogle search ([http://stanford.edu/~marce110/verbs/froogle-search.html This] works pretty well for now, but it&#039;s messy and would break if Google changed the format of the search results.)&lt;br /&gt;
* search google calendar&lt;br /&gt;
* taking the name of a television show, search for the show&#039;s schedule and add that schedule to google calendar&lt;br /&gt;
* A command that searches the web for a picture similar to one selected. using similar pixel arraignment to find pictures of better resolution or less cropped than one you might find roaming randomly.&lt;br /&gt;
** [http://blogs.msdn.com/livesearch/archive/2008/12/01/using-images-to-find-other-images.aspx Microsoft Live Search can do this]&lt;br /&gt;
* A image cover flow or even just something as simple as a image viewer. Also it should be able to add images into e-mails like the maps.&lt;br /&gt;
* Would love to see a search function for Calorie King to look up Nutrition Fact tables for foods ([http://is.gd/euXv like this one]).&lt;br /&gt;
* A search function for XHTML entities (maybe looking like [http://www.digitalmediaminute.com/reference/entity/index.php this]?) would be awesome. Not sure what auto-complete would look like for this....&lt;br /&gt;
* A function where you can highlight a text and then add additional text to that in ubiquity. For example I highlight a bands name on wiki then open Ubiquity and add a song name and then search on youtube.&lt;br /&gt;
*A search function for custom search command adding.&lt;br /&gt;
For example, allowing a user to search [input] using www.ffxiclopedia.org&#039;s main search [input] by setting &amp;quot;ffxi&amp;quot; command to it.&lt;br /&gt;
&lt;br /&gt;
==Program Integration==&lt;br /&gt;
* Goto command for navigating the web quick and easy but I want it in the core.&lt;br /&gt;
* Search command (allows you to search for text in any open tab, and then navigate you there)&lt;br /&gt;
* Flock stuff (be inspired by whatever seems to be actually useful in Flock)&lt;br /&gt;
** Especially nice if it could integrate with existing application launchers (ie: Quicksilver, Launchy, etc)&lt;br /&gt;
* Ability to take snapshots of the current window&lt;br /&gt;
* Queries for places datastores, rendering in plain html blue links (Beltzer showed me a little js console script that is a fine starting point).&lt;br /&gt;
** tag:(hci gestuers)&lt;br /&gt;
** site:google date:yesterday show:clicks&lt;br /&gt;
** starred intitle:Concept&lt;br /&gt;
* Integrate with Thunderbird, Sunbird, Songbird and other Mozilla software&lt;br /&gt;
* Allow for commands to be treated as content/arguments for other commands ie: email {map Washington DC} to myfriend@gmail.com would open up an email box to friend1 with a map of DC in the content pane&lt;br /&gt;
* clone of email command for Gajim/Pidgin/Psi/Adium...&lt;br /&gt;
* Integration with Instant Messenger clients (AIM, Pidgin, Trillion, etc) to allow inserting content into a message for a particular contact ie &#039;IM this to John&#039;&lt;br /&gt;
* Idea:: have a very, very small program run on start up, that detects when the key combination is pressed and will launch Ubiquity. After Ubiquity is dismissed, it will return to its original state.&lt;br /&gt;
* In Firefox, &amp;quot;Bookmark this&amp;quot; &amp;amp; &amp;quot;Create bookmark folder &amp;lt;data&amp;gt;&amp;quot;&lt;br /&gt;
* For Linux, allow users and other commands to be sent to the terminal...eg. IF you had selected text and wanted to open in gedit, ubiquity would tell the terminal to open gedit then paste in text..etc&lt;br /&gt;
* Ability to select the address-bar. I.e. &amp;quot;Select-address&amp;quot; would jump to the address-bar and highlight it.&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
* Annotate web pages and then share those annotations (perhaps using google notebook?)&lt;br /&gt;
* Close unrelated tabs: similar to close all related tabs&lt;br /&gt;
* Download manager - A text based download manager like wget on linux&lt;br /&gt;
* Related articles and images, possibly using Zemanta like [https://addons.mozilla.org/en-US/firefox/addon/7571 this plugin].&lt;br /&gt;
* Replace words in selected text (optional: regular expressions)&lt;br /&gt;
* Save current site into a PDF file&lt;br /&gt;
** &amp;quot;convert&amp;quot; command already does this&lt;br /&gt;
* Save page as... &amp;quot;Web Page, complete&amp;quot; to a pre-specified folder&lt;br /&gt;
* Save selection/highlighted text to a file in a pre-specified location&lt;br /&gt;
* Spell checker - any text, not just form fields&lt;br /&gt;
* Related to spell checker - take highlighted text, pass it through any number of online dictionaries, and let user select which word to use as replacement.&lt;br /&gt;
* Status message editor - Easily modify status and/or status message on popular IM protocols&lt;br /&gt;
* Perhaps &amp;quot;convert 8pm australian time to my time&amp;quot; where my timezone could automatically be obtained from CmdUtils.getLocation()&lt;br /&gt;
* &#039;Tag&#039; function:&lt;br /&gt;
** Auto-complete from current tags list would be excellent&lt;br /&gt;
** Needs to handle multiple, comma-separated tags, better.  Currently adds the comma to the tag name (eg. &#039;tag snacks, quick-meals&#039; creates a new tag called &amp;quot;snacks,&amp;quot;)&lt;br /&gt;
* &#039;Undo&#039; function should work on in-page replacements (eg. translating highlighted text or inserting a map into page)&lt;br /&gt;
* Upload selected image to [http://tinypic.com tinypic] or the like&lt;br /&gt;
* Disable &amp;quot;window.print()&amp;quot; API for all pages, or replace it with a less intrusive variant (toast notification?)&lt;br /&gt;
* Command Creator From Forms: Kind of like how you can create keyword searches by right clicking any search box, but you would be able to right-click any form from any search or web publish forms and select &amp;quot;Create Ubiquity Command...&amp;quot; which pops a box where you say the the command keyword&lt;br /&gt;
* Add a domain (current domain as default) to cookie whitelist&lt;br /&gt;
* Add a thesaurus search function&lt;br /&gt;
** http://www.zacharyspencer.com/2008/09/my-first-ubiquity-command/&lt;br /&gt;
* Restart Firefox&lt;br /&gt;
** Built-in &amp;quot;restart&amp;quot; command does this&lt;br /&gt;
* Download instead of opening URL&lt;br /&gt;
* The ability to Edit existing/installed commands. I.E. &amp;quot;edit-command define&amp;quot; would search for an installed &amp;quot;define&amp;quot; command and open the source in the command-editor.&lt;br /&gt;
* The ability to bookmark a page and bypass the [ok/cancel] dialog box so that you can bookmark related tabs all at once.&lt;br /&gt;
&lt;br /&gt;
==Site Integration==&lt;br /&gt;
*Forum (BBCode) formatting&lt;br /&gt;
*Youtube: Highlight a youtube link and embed the video. Could be used with other sites as well.&lt;br /&gt;
* Blogger:&lt;br /&gt;
** &#039;blog&#039; function, to create a new blog post from selected text&lt;br /&gt;
*Command for [http://www.mytextfile.com MyTextFile] such as, &amp;quot;note/textfile (text).&amp;quot; It should auto-save so you never leave Ubiquity, unless, opening a new tab is necessary. Very similar to how email works now.&lt;br /&gt;
* Google Calendar: &lt;br /&gt;
**ability to add more information to a calendar appointment such as location (perhaps signaled by @ ), calendar choice ( [ ] ), improved date parsing (you could say next Wednesday, and it could figure it out, maybe like [http://www.datejs.com/ DateJS]).&lt;br /&gt;
**ability to get a preview of my next 10 calendar entries.&lt;br /&gt;
** access HTTPS version of calendar, perhaps with &#039;add-to-scalendar&#039; and &#039;check-scalendar&#039;&lt;br /&gt;
* Gmail:&lt;br /&gt;
** Add contact, from a selected text to your contact list in gmail.&lt;br /&gt;
*** Add a contact group (and contacts if needed) from the emails list in a received email (all cc&#039;ed people, including the sender, excluding yourself), or from a list of email address&#039;.&lt;br /&gt;
** Gmail labels, alphabetical lookup from available labels.  Code possibly similar to the greasemonkey script [http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html macros] for gmail.&lt;br /&gt;
* Google Maps - &lt;br /&gt;
** when a google map image is inserted into a form, the image should have a link to the map on the google map site. e.g.: http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Budapest,+Hungary&amp;amp;ie=UTF8&amp;amp;z=11&amp;amp;iwloc=addr&lt;br /&gt;
** Google Directions search, perhaps separating locations with a semicolon if Ubiquity doesn&#039;t understand multiple word arguments.&lt;br /&gt;
** Route information&lt;br /&gt;
* Internationalisation (google.co.uk, ebay.co.uk. etc) &lt;br /&gt;
** weather command in Celsius&lt;br /&gt;
** localize verbs (and their parameters: 01/09 = 1st September in some country)&lt;br /&gt;
** &amp;quot;map&amp;quot; command needs to be country-specific (maps.google.com.xx)&lt;br /&gt;
* Flickr integration (ability to inject pictures/slideshows and post found images to Flickr) &lt;br /&gt;
* More advanced twitter integration (a command to view last x messages from a specific friend and another to view your recent friends timeline)&lt;br /&gt;
* Blog integration (select a chunk of text or an image and then blog about it in your favorite blog software)&lt;br /&gt;
* Fly command (possibly using [http://tripeedo.com/ Tripeedo]&#039;s built-in natural language search and the site&#039;s preview or the Kayak API) to make booking flights easier&lt;br /&gt;
* Digg (see Sandro&#039;s [http://ubiquity-firefox.googlegroups.com/web/diggthis.js diggthis command])&lt;br /&gt;
* Reddit/Mixx&lt;br /&gt;
* Del.icio.us (e.g. &amp;quot;delic this&amp;quot; or &amp;quot;delic this with tag1 tag2 tag3&amp;quot;)&lt;br /&gt;
* Turn referencing friend feed comments and tweets on a page (defaulted to the current page) into page annotations via command &amp;quot;show conversations&amp;quot;&lt;br /&gt;
* Integration with Jaiku, Plurk, Pownce, and other microblogging services (not only with Twitter)&lt;br /&gt;
* Integration with Google Docs and Google Notebook&lt;br /&gt;
* Command to send selected text to tinypaste.com and/or &amp;lt;strike&amp;gt;shorttext.com&amp;lt;/strike&amp;gt; (&amp;lt;i&amp;gt;[http://shortText.com/ Commands &#039;shorttext&#039;, &#039;longtext&#039;] now available&amp;lt;/i&amp;gt;), pastebin.com, cl1p.net etc.&lt;br /&gt;
* Subscribe to current site&#039;s feed via Google Reader or other RSS reader&lt;br /&gt;
* Add to Google Bookmarks&lt;br /&gt;
* Easily control [http://www.bitlet.org BitLet.org]&lt;br /&gt;
* Add torrents with [http://www.azureuswiki.com/index.php/HTML_WebUI Azureus&#039; HTML WebUI]. =&amp;gt; this can be done with Greasemonkey already&lt;br /&gt;
* Geotag flickr photos easily (see [http://labs.sumaato.net/tools/flickr_geocode_bookmarklet/ Localize Bookmarklet])&lt;br /&gt;
* Take highlighted thread, and paste it in a forum.  Because of the amount of forums, it might be better to just have a template for each forum type.&lt;br /&gt;
* Evernote command (post this page/text to evernote) suggested by Ben [http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/68d7f5d7f817c4d5?hl=en here]&lt;br /&gt;
* Adobe Buzzword integration&lt;br /&gt;
* tempomail / jetable (temp mail address) integration. Implemented. See [http://gist.github.com/11261 Jetable]&lt;br /&gt;
* Horde email/calendar&lt;br /&gt;
* SMS Messaging. Text-message content to a contact or phone number. Could integrate with an existing service such as: http://smseverywhere.com/send.htm&lt;br /&gt;
* Set tv recording. For those people using mythtv / myth* or a TiVo with a web front-end, if you saw a show on some web site, like tvrage or any channel that shows tv-listings, highlight the show, and say &#039;record this&#039;. This would probably be very dependent on your specific web front-end / TVR hardware.&lt;br /&gt;
*integrate into MySpace. command such as &amp;quot;send this to (myspace contact): (selected text or image, maybe even if your on youtube, it will automatically imbed.)&amp;quot; Another could be &amp;quot;set headline as (selected text or input)&amp;quot;&lt;br /&gt;
* Integrate with [http://www.squirrelmail.org/ SqirrelMail]&lt;br /&gt;
* Integrate with [http://roundcube.net/ RoundCube Mail]&lt;br /&gt;
* Integrate with [http://sourceforge.net/projects/scuttle/ Scuttle Bookmarks]&lt;br /&gt;
* Integrate with [http://webcalendar.sourceforge.net/ WebCalendar]&lt;br /&gt;
* Integrate with [http://www.rememberthemilk.com/ Remember The Milk]. Add tasks, get list of tasks, mark tasks as completed, etc. They have a really rich API. (Adding tasks is done: [http://garyhodgson.com/ubiquity/rtm.html here], with a more advanced version [http://garyhodgson.com/ubiquity/rtm-wip.html in progress].)&lt;br /&gt;
* Integrate with [http://www.toodledo.com/ Toodledo] in a similar way to that described for RTM&lt;br /&gt;
* [http://www.facebook.com Facebook] status setting-resetting integration. Ping.fm has been implemented but there are users (like me) that prefer to use only one social networking site, hence they don&#039;t need a ping.fm account. (already done [http://home.comcast.net/~captainbeah/ubiquity/facebook/ here])&lt;br /&gt;
* Integrate with [http://www.me.com/ MobileMe] to allow similar email and calendar editing integration as for the Google equivalents (GMail etc.)&lt;br /&gt;
* Integrate with [http://www.ryanair.com/ Ryanair] to allow searching for flights using Ubiquity.&lt;br /&gt;
* Subscribe with Bloglines&lt;br /&gt;
* Integrate with Google Apps (Gmail, Calendar) [http://www.google.com/apps/] to allow using the standard commands&lt;br /&gt;
&lt;br /&gt;
==Extension Integration==&lt;br /&gt;
* PasswordMaker: http://passwordmaker.org/&lt;br /&gt;
* BlueOrganizer (be inspired by [https://addons.mozilla.org/en-US/firefox/addon/3481 this addon] and it&#039;s somewhat semantic knowledge)  &lt;br /&gt;
* Take inspiration from [https://addons.mozilla.org/en-US/firefox/addon/1407  Clipmarks]&lt;br /&gt;
* Firebug integration, inspect DOM-Reference, show firebug net panel&lt;br /&gt;
* Media player control similar to [https://addons.mozilla.org/en-US/firefox/addon/219 FoxyTunes]&lt;br /&gt;
* AnyColor integration -- https://addons.mozilla.org/en-US/firefox/addon/6991&lt;br /&gt;
* Faviconize -- A command called Fav [open tab] to change it&#039;s state from showing/hiding title&lt;br /&gt;
* Commands for Screen grab! extension&lt;br /&gt;
* Undo Closed Tabs Button feature like the extension of that name. (Note: this is built into Firefox 3.0, no need for this extension anymore)&lt;br /&gt;
* Adblock Plus integration, along with NoScript.&lt;br /&gt;
* Ability to inject Webslices, for use with Webchunks.&lt;br /&gt;
* Fast Dial integration&lt;br /&gt;
* Overwrite the window.print command with a less intrusive UI. It would instead pop a notification/toaster (&amp;quot;this site wants to print itself. _Print_&amp;quot;).&lt;br /&gt;
* Greasemonkey integration: &amp;quot;greasemonkey-edit &amp;lt;userscript&amp;gt;&amp;quot;. It would autocomplete the userscript name based on the list of installed userscripts.&lt;br /&gt;
* Cool iris functionality with a image flow.&lt;br /&gt;
&lt;br /&gt;
==Finished Commands==&lt;br /&gt;
* [http://shortText.com/ shortText.com] done. Create a URL of any selected text by using command &#039;shorttext&#039; or expand a shortText URL to its full content by using command &#039;longtext&#039;&lt;br /&gt;
* [http://www.google.com/sitesearch/ Google Site Search] integration. (Example: &amp;quot;search komplett.ie for cpu coolers&amp;quot;) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Metacritic (metacritic.com) review searching - [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Torrent search [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Reveal the exact URL-s behind tinyurl-s (see [http://ghill.customer.netspace.net.au/embiggen/ Embiggen Bookmarklet]) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* BugMeNot lookup for current page [http://www.geocities.com/lemming4242 Done]&lt;br /&gt;
* Open command (select multiple links, then open them all in tabs) [http://www.geocities.com/lemming4242/ Done]&lt;br /&gt;
* An online bible service command. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* A command to open a selected URL. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* Twitter Search - [http://gist.github.com/7594 Done] but could benefit from a sexier UI&lt;br /&gt;
* Random number generator.  Floating point value with input of the following type:  random lower-val higher-val&lt;br /&gt;
** Example:  Random 0 1;  Gives 0.252&lt;br /&gt;
** Example:  Random 1 100; Gives 275.840&lt;br /&gt;
** [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=12 Done]&lt;br /&gt;
* Go command (for switching between tabs by name)  (achieved by the &amp;quot;tab&amp;quot; command builtin to Ubiquity)&lt;br /&gt;
* Reopen an existing tab in a new tab. Sometimes you want to search for a new topic (in Wikipedia for example), and you have to re-open a new tab, then copy and paste the current url. Why not have a &amp;quot;re-open&amp;quot; command that lets you create a new tab, and copy the currently opened page over to it? (Alt+D &amp;gt; Alt+Enter currently does this. necessary?) (No. Did it anyways.) [http://ubiquitously.org/forum/viewtopic.php?f=5&amp;amp;t=22 Done]&lt;br /&gt;
* Currency conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done]&lt;br /&gt;
* Unit conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done (Same as above)]&lt;br /&gt;
* Stock quotes [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=26 Done]&lt;br /&gt;
* A &amp;quot;view source&amp;quot; for Ubiq commands. For example, &amp;quot;view-source link-to-wikipedia&amp;quot; =&amp;gt; [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1.1_Release_Notes available] in Ubiq 0.1.1, although not as a command.&lt;br /&gt;
* Link finder (like the &amp;quot;link-to-wikipedia&amp;quot; command but then, instead of inserting a link to wikipedia, allow the user to find the link from history/bookmarks. This would save a lot of excess work because at the moment, to insert a link, you have to open up a new tab, find the page you want to link to, copy the address and then, go back to add the link) =&amp;gt; try [http://blog.monstuff.com/archives/000343.html insert-link]&lt;br /&gt;
* Command that takes each search plugin/provider you have in the search-bar (by default, right of the locationbar in IE7 &amp;amp; FF2 &amp;amp; 3, plus more), and turns it into a command you can use.  Thus, having search plugin/providers at your fingertips in ubiquity, and adding a search plugin/provider command is just as easy as using already created functionality;  This could either be done in the underlying code of Ubiquity, or maybe have it so that the command is done as &amp;quot;Search &amp;lt;Plugin/Provider&amp;gt; &amp;lt;Terms&amp;gt;&lt;br /&gt;
** I&#039;m a moron..I actually had a command that did this.[http://theunfocused.net/moz/ubiquity/verbs/?cmd=search]&lt;br /&gt;
** Dup:  Integration of your installed Firefox search engines.&lt;br /&gt;
* Timezone converter - something like &amp;quot;get time in australia&amp;quot; ([https://wiki.mozilla.org/Labs/Ubiquity/Commands_In_The_Wild#Time Done])&lt;br /&gt;
* Ping.fm - can potentially replace twitter and facebook-status commands ([http://waleed.doubleudesigns.com/2008/08/ubiquity-and-pingfm/ Done])&lt;br /&gt;
* Mibbit IRC (mibbit [server] [optional:channels]) ([http://scguy318.freeshell.org/Mibbit%20Ubiquity%20Script.html Done])&lt;br /&gt;
* &amp;lt;tt&amp;gt;google-here &amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt;: site-search on current site (without typing it explicitly) =&amp;gt; ([http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/5c2c80df1c61d4f8 Done])&lt;br /&gt;
Can anyone write a command that decodes 2D barcodes in images on a web page?&lt;br /&gt;
&lt;br /&gt;
-I am working on a 2D barcode translator now. I have a standard barcode reader command working: http://devstatus.com ~ matt&lt;br /&gt;
&lt;br /&gt;
*I just finished a simple Woot checker that goes to the &amp;quot;Want One&amp;quot; page on enter: [http://gist.github.com/41227 Woot]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131029</id>
		<title>Labs/Ubiquity/Ubiquity Command Suggestions</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131029"/>
		<updated>2009-02-27T16:54:09Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Search Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the commands suggested on this page have already been implemented, either by us or by third parties.  Please take a look at [https://labs.toolness.com/ubiquity-herd/all-feeds/ | The Herd&#039;s command feed index] to see what commands other people have implemented.  You may find what you&#039;re looking for there!&lt;br /&gt;
&lt;br /&gt;
Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
==Interesting Commands ==&lt;br /&gt;
&lt;br /&gt;
These commands are either extremely useful to everyone (likely to be included as a builtin command) or they push the boundaries of what Ubiquity can do.&lt;br /&gt;
&lt;br /&gt;
* Search the Herd for new Ubiquity commands directly using Ubiquity without having to physically navigate to the site. &lt;br /&gt;
* Commands for all of the menu items (so that I never have to reach for the mouse to menu again). Sandro mentioned this recently. &lt;br /&gt;
* Program launcher (When in Chrome, JS can launch other applications)&lt;br /&gt;
* &amp;quot;cmd&amp;quot; command to pass selected text to the command line, i.e. &amp;quot;cmd wget&amp;quot; would pass the selected text to the wget function via the cli.&lt;br /&gt;
* Upload code to pastebin (useful for sharing commands from the command-editor)&lt;br /&gt;
* Integration with webchuck extension (with the ability to view webchunks in the preview).&lt;br /&gt;
* BlueOrganizer (be inspired by this addon and it&#039;s somewhat semantic knowledge)&lt;br /&gt;
* Graphing data (currently, only sparklines are supported). Would be nice to plot bar graphs and pie charts of things like countries by GDP from Wikipedia or browser usage on my website. There&#039;s a lot to think about here but this could potentially become one of the best features of Ubiquity.&lt;br /&gt;
* Task-specific tab grouping. Allow for opening and closing a set of tabs all at once. The key question here is how to add tabs to groups using Ubiquity.&lt;br /&gt;
&lt;br /&gt;
==Search Commands==&lt;br /&gt;
*Creative Commons: Find something in CC&lt;br /&gt;
*Wikipedia in spanish: (or use it in another languages)&lt;br /&gt;
*Bookmarklet command; execute any bookmarklet via the keyboard.(This could include normal bookmarks something like quick dial with the keyboard)&lt;br /&gt;
*Map contact command, a command to get the location(s) of a contact from your contact list.( map-contact (name) )&lt;br /&gt;
* Google site search multiple urls in selection.  You would select a block of text containing multiple urls, and be able to search them all simultaneously for any given text.&lt;br /&gt;
** Is this even possible?  What is the format?  &amp;quot;site:mozilla.org,wikipedia.org test&amp;quot;?  &amp;quot;site:mozilla.org site:wikipedia.org test&amp;quot;?&lt;br /&gt;
* Flickr search (a [http://194.95.111.244/%7Ecountzero/scripts/_myImageFlow/ coverflow-like preview] would be awesome)&lt;br /&gt;
* last.fm search with preview (a first attempt has been made [http://www.geero.net/ here])&lt;br /&gt;
* Google Image Search with preview&lt;br /&gt;
** Built-in image-search command does this, no?&lt;br /&gt;
* Google Sets (part of Google labs) to give related terms based on user input&lt;br /&gt;
* More specific Google searches, like google video search on &#039;video&#039;, and google definition search type &amp;quot;define:mozilla&amp;quot; into google.&lt;br /&gt;
* A search for the Gawker sites eg: Gizmodo, Lifehacker, etc...&lt;br /&gt;
* a command to find the largest number in a given tab/present page&lt;br /&gt;
* A search for books by ISBN number for availability in libraries of your choice. Use the [http://en.wikipedia.org/wiki/Special:BookSources/ &#039;Book sources&#039;] by wikipedia to find it. To find the book with ISBN number 1871890306 in SF, you Ubiq &amp;quot;ISBN 1871890306 in San Francisco&amp;quot;, or if you are in San Francisco, you can type &amp;quot;ISBN 1871890306 here&amp;quot;, using your geo-location by ip attached to the [http://labs.toolness.com/trac/ticket/179 magic word &#039;here&#039;], which I believe will be part of Ubiq 0.2. Integration with maps in a later stage? Discuss [http://getsatisfaction.com/mozilla/topics/book_source_your_isbn_numbers_through_ubiquity here]. &lt;br /&gt;
* One command should be able to launch several searches on different sites in different tabs. It worked before, with several Utils.openUrlInBrowser&#039;s, but 0.1.1 broke it.&lt;br /&gt;
* Froogle search ([http://stanford.edu/~marce110/verbs/froogle-search.html This] works pretty well for now, but it&#039;s messy and would break if Google changed the format of the search results.)&lt;br /&gt;
* search google calendar&lt;br /&gt;
* taking the name of a television show, search for the show&#039;s schedule and add that schedule to google calendar&lt;br /&gt;
* A command that searches the web for a picture similar to one selected. using similar pixel arraignment to find pictures of better resolution or less cropped than one you might find roaming randomly.&lt;br /&gt;
** [http://blogs.msdn.com/livesearch/archive/2008/12/01/using-images-to-find-other-images.aspx Microsoft Live Search can do this]&lt;br /&gt;
* A image cover flow or even just something as simple as a image viewer. Also it should be able to add images into e-mails like the maps.&lt;br /&gt;
* Would love to see a search function for Calorie King to look up Nutrition Fact tables for foods ([http://is.gd/euXv like this one]).&lt;br /&gt;
* A search function for XHTML entities (maybe looking like [http://www.digitalmediaminute.com/reference/entity/index.php this]?) would be awesome. Not sure what auto-complete would look like for this....&lt;br /&gt;
* A function where you can highlight a text and then add additional text to that in ubiquity. For example I highlight a bands name on wiki then open Ubiquity and add a song name and then search on youtube.&lt;br /&gt;
*A search function for custom search command adding.&lt;br /&gt;
For example, allowing a user to search [input] using www.ffxiclopedia.org&#039;s main search [input] by setting &amp;quot;ffxi&amp;quot; command to it.&lt;br /&gt;
&lt;br /&gt;
==Program Integration==&lt;br /&gt;
* Goto command for navigating the web quick and easy but I want it in the core.&lt;br /&gt;
* Search command (allows you to search for text in any open tab, and then navigate you there)&lt;br /&gt;
* Flock stuff (be inspired by whatever seems to be actually useful in Flock)&lt;br /&gt;
** Especially nice if it could integrate with existing application launchers (ie: Quicksilver, Launchy, etc)&lt;br /&gt;
* Ability to take snapshots of the current window&lt;br /&gt;
* Queries for places datastores, rendering in plain html blue links (Beltzer showed me a little js console script that is a fine starting point).&lt;br /&gt;
** tag:(hci gestuers)&lt;br /&gt;
** site:google date:yesterday show:clicks&lt;br /&gt;
** starred intitle:Concept&lt;br /&gt;
* Integrate with Thunderbird, Sunbird, Songbird and other Mozilla software&lt;br /&gt;
* Allow for commands to be treated as content/arguments for other commands ie: email {map Washington DC} to myfriend@gmail.com would open up an email box to friend1 with a map of DC in the content pane&lt;br /&gt;
* clone of email command for Gajim/Pidgin/Psi/Adium...&lt;br /&gt;
* Integration with Instant Messenger clients (AIM, Pidgin, Trillion, etc) to allow inserting content into a message for a particular contact ie &#039;IM this to John&#039;&lt;br /&gt;
* Idea:: have a very, very small program run on start up, that detects when the key combination is pressed and will launch Ubiquity. After Ubiquity is dismissed, it will return to its original state.&lt;br /&gt;
* In Firefox, &amp;quot;Bookmark this&amp;quot; &amp;amp; &amp;quot;Create bookmark folder &amp;lt;data&amp;gt;&amp;quot;&lt;br /&gt;
* For Linux, allow users and other commands to be sent to the terminal...eg. IF you had selected text and wanted to open in gedit, ubiquity would tell the terminal to open gedit then paste in text..etc&lt;br /&gt;
* Ability to select the address-bar. I.e. &amp;quot;Select-address&amp;quot; would jump to the address-bar and highlight it.&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
* Annotate web pages and then share those annotations (perhaps using google notebook?)&lt;br /&gt;
* Close unrelated tabs: similar to close all related tabs&lt;br /&gt;
* Download manager - A text based download manager like wget on linux&lt;br /&gt;
* Related articles and images, possibly using Zemanta like [https://addons.mozilla.org/en-US/firefox/addon/7571 this plugin].&lt;br /&gt;
* Replace words in selected text (optional: regular expressions)&lt;br /&gt;
* Save current site into a PDF file&lt;br /&gt;
* Save page as... &amp;quot;Web Page, complete&amp;quot; to a pre-specified folder&lt;br /&gt;
* Save selection/highlighted text to a file in a pre-specified location&lt;br /&gt;
* Spell checker - any text, not just form fields&lt;br /&gt;
* Related to spell checker - take highlighted text, pass it through any number of online dictionaries, and let user select which word to use as replacement.&lt;br /&gt;
* Status message editor - Easily modify status and/or status message on popular IM protocols&lt;br /&gt;
* Perhaps &amp;quot;convert 8pm australian time to my time&amp;quot; where my timezone could automatically be obtained from CmdUtils.getLocation()&lt;br /&gt;
* &#039;Tag&#039; function:&lt;br /&gt;
** Auto-complete from current tags list would be excellent&lt;br /&gt;
** Needs to handle multiple, comma-separated tags, better.  Currently adds the comma to the tag name (eg. &#039;tag snacks, quick-meals&#039; creates a new tag called &amp;quot;snacks,&amp;quot;)&lt;br /&gt;
* &#039;Undo&#039; function should work on in-page replacements (eg. translating highlighted text or inserting a map into page)&lt;br /&gt;
* Upload selected image to [http://tinypic.com tinypic] or the like&lt;br /&gt;
* Disable &amp;quot;window.print()&amp;quot; API for all pages, or replace it with a less intrusive variant (toast notification?)&lt;br /&gt;
* Command Creator From Forms: Kind of like how you can create keyword searches by right clicking any search box, but you would be able to right-click any form from any search or web publish forms and select &amp;quot;Create Ubiquity Command...&amp;quot; which pops a box where you say the the command keyword&lt;br /&gt;
* Add a domain (current domain as default) to cookie whitelist&lt;br /&gt;
* Add a thesaurus search function&lt;br /&gt;
* Restart Firefox&lt;br /&gt;
* Download instead of opening URL&lt;br /&gt;
* The ability to Edit existing/installed commands. I.E. &amp;quot;edit-command define&amp;quot; would search for an installed &amp;quot;define&amp;quot; command and open the source in the command-editor.&lt;br /&gt;
* The ability to bookmark a page and bypass the [ok/cancel] dialog box so that you can bookmark related tabs all at once.&lt;br /&gt;
&lt;br /&gt;
==Site Integration==&lt;br /&gt;
*Forum (BBCode) formatting&lt;br /&gt;
*Youtube: Highlight a youtube link and embed the video. Could be used with other sites as well.&lt;br /&gt;
* Blogger:&lt;br /&gt;
** &#039;blog&#039; function, to create a new blog post from selected text&lt;br /&gt;
*Command for [http://www.mytextfile.com MyTextFile] such as, &amp;quot;note/textfile (text).&amp;quot; It should auto-save so you never leave Ubiquity, unless, opening a new tab is necessary. Very similar to how email works now.&lt;br /&gt;
* Google Calendar: &lt;br /&gt;
**ability to add more information to a calendar appointment such as location (perhaps signaled by @ ), calendar choice ( [ ] ), improved date parsing (you could say next Wednesday, and it could figure it out, maybe like [http://www.datejs.com/ DateJS]).&lt;br /&gt;
**ability to get a preview of my next 10 calendar entries.&lt;br /&gt;
** access HTTPS version of calendar, perhaps with &#039;add-to-scalendar&#039; and &#039;check-scalendar&#039;&lt;br /&gt;
* Gmail:&lt;br /&gt;
** Add contact, from a selected text to your contact list in gmail.&lt;br /&gt;
*** Add a contact group (and contacts if needed) from the emails list in a received email (all cc&#039;ed people, including the sender, excluding yourself), or from a list of email address&#039;.&lt;br /&gt;
** Gmail labels, alphabetical lookup from available labels.  Code possibly similar to the greasemonkey script [http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html macros] for gmail.&lt;br /&gt;
* Google Maps - &lt;br /&gt;
** when a google map image is inserted into a form, the image should have a link to the map on the google map site. e.g.: http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Budapest,+Hungary&amp;amp;ie=UTF8&amp;amp;z=11&amp;amp;iwloc=addr&lt;br /&gt;
** Google Directions search, perhaps separating locations with a semicolon if Ubiquity doesn&#039;t understand multiple word arguments.&lt;br /&gt;
** Route information&lt;br /&gt;
* Internationalisation (google.co.uk, ebay.co.uk. etc) &lt;br /&gt;
** weather command in Celsius&lt;br /&gt;
** localize verbs (and their parameters: 01/09 = 1st September in some country)&lt;br /&gt;
** &amp;quot;map&amp;quot; command needs to be country-specific (maps.google.com.xx)&lt;br /&gt;
* Flickr integration (ability to inject pictures/slideshows and post found images to Flickr) &lt;br /&gt;
* More advanced twitter integration (a command to view last x messages from a specific friend and another to view your recent friends timeline)&lt;br /&gt;
* Blog integration (select a chunk of text or an image and then blog about it in your favorite blog software)&lt;br /&gt;
* Fly command (possibly using [http://tripeedo.com/ Tripeedo]&#039;s built-in natural language search and the site&#039;s preview or the Kayak API) to make booking flights easier&lt;br /&gt;
* Digg (see Sandro&#039;s [http://ubiquity-firefox.googlegroups.com/web/diggthis.js diggthis command])&lt;br /&gt;
* Reddit/Mixx&lt;br /&gt;
* Del.icio.us (e.g. &amp;quot;delic this&amp;quot; or &amp;quot;delic this with tag1 tag2 tag3&amp;quot;)&lt;br /&gt;
* Turn referencing friend feed comments and tweets on a page (defaulted to the current page) into page annotations via command &amp;quot;show conversations&amp;quot;&lt;br /&gt;
* Integration with Jaiku, Plurk, Pownce, and other microblogging services (not only with Twitter)&lt;br /&gt;
* Integration with Google Docs and Google Notebook&lt;br /&gt;
* Command to send selected text to tinypaste.com and/or &amp;lt;strike&amp;gt;shorttext.com&amp;lt;/strike&amp;gt; (&amp;lt;i&amp;gt;[http://shortText.com/ Commands &#039;shorttext&#039;, &#039;longtext&#039;] now available&amp;lt;/i&amp;gt;), pastebin.com, cl1p.net etc.&lt;br /&gt;
* Subscribe to current site&#039;s feed via Google Reader or other RSS reader&lt;br /&gt;
* Add to Google Bookmarks&lt;br /&gt;
* Easily control [http://www.bitlet.org BitLet.org]&lt;br /&gt;
* Add torrents with [http://www.azureuswiki.com/index.php/HTML_WebUI Azureus&#039; HTML WebUI]. =&amp;gt; this can be done with Greasemonkey already&lt;br /&gt;
* Geotag flickr photos easily (see [http://labs.sumaato.net/tools/flickr_geocode_bookmarklet/ Localize Bookmarklet])&lt;br /&gt;
* Take highlighted thread, and paste it in a forum.  Because of the amount of forums, it might be better to just have a template for each forum type.&lt;br /&gt;
* Evernote command (post this page/text to evernote) suggested by Ben [http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/68d7f5d7f817c4d5?hl=en here]&lt;br /&gt;
* Adobe Buzzword integration&lt;br /&gt;
* tempomail / jetable (temp mail address) integration. Implemented. See [http://gist.github.com/11261 Jetable]&lt;br /&gt;
* Horde email/calendar&lt;br /&gt;
* SMS Messaging. Text-message content to a contact or phone number. Could integrate with an existing service such as: http://smseverywhere.com/send.htm&lt;br /&gt;
* Set tv recording. For those people using mythtv / myth* or a TiVo with a web front-end, if you saw a show on some web site, like tvrage or any channel that shows tv-listings, highlight the show, and say &#039;record this&#039;. This would probably be very dependent on your specific web front-end / TVR hardware.&lt;br /&gt;
*integrate into MySpace. command such as &amp;quot;send this to (myspace contact): (selected text or image, maybe even if your on youtube, it will automatically imbed.)&amp;quot; Another could be &amp;quot;set headline as (selected text or input)&amp;quot;&lt;br /&gt;
* Integrate with [http://www.squirrelmail.org/ SqirrelMail]&lt;br /&gt;
* Integrate with [http://roundcube.net/ RoundCube Mail]&lt;br /&gt;
* Integrate with [http://sourceforge.net/projects/scuttle/ Scuttle Bookmarks]&lt;br /&gt;
* Integrate with [http://webcalendar.sourceforge.net/ WebCalendar]&lt;br /&gt;
* Integrate with [http://www.rememberthemilk.com/ Remember The Milk]. Add tasks, get list of tasks, mark tasks as completed, etc. They have a really rich API. (Adding tasks is done: [http://garyhodgson.com/ubiquity/rtm.html here], with a more advanced version [http://garyhodgson.com/ubiquity/rtm-wip.html in progress].)&lt;br /&gt;
* Integrate with [http://www.toodledo.com/ Toodledo] in a similar way to that described for RTM&lt;br /&gt;
* [http://www.facebook.com Facebook] status setting-resetting integration. Ping.fm has been implemented but there are users (like me) that prefer to use only one social networking site, hence they don&#039;t need a ping.fm account. (already done [http://home.comcast.net/~captainbeah/ubiquity/facebook/ here])&lt;br /&gt;
* Integrate with [http://www.me.com/ MobileMe] to allow similar email and calendar editing integration as for the Google equivalents (GMail etc.)&lt;br /&gt;
* Integrate with [http://www.ryanair.com/ Ryanair] to allow searching for flights using Ubiquity.&lt;br /&gt;
* Subscribe with Bloglines&lt;br /&gt;
* Integrate with Google Apps (Gmail, Calendar) [http://www.google.com/apps/] to allow using the standard commands&lt;br /&gt;
&lt;br /&gt;
==Extension Integration==&lt;br /&gt;
* PasswordMaker: http://passwordmaker.org/&lt;br /&gt;
* BlueOrganizer (be inspired by [https://addons.mozilla.org/en-US/firefox/addon/3481 this addon] and it&#039;s somewhat semantic knowledge)  &lt;br /&gt;
* Take inspiration from [https://addons.mozilla.org/en-US/firefox/addon/1407  Clipmarks]&lt;br /&gt;
* Firebug integration, inspect DOM-Reference, show firebug net panel&lt;br /&gt;
* Media player control similar to [https://addons.mozilla.org/en-US/firefox/addon/219 FoxyTunes]&lt;br /&gt;
* AnyColor integration -- https://addons.mozilla.org/en-US/firefox/addon/6991&lt;br /&gt;
* Faviconize -- A command called Fav [open tab] to change it&#039;s state from showing/hiding title&lt;br /&gt;
* Commands for Screen grab! extension&lt;br /&gt;
* Undo Closed Tabs Button feature like the extension of that name. (Note: this is built into Firefox 3.0, no need for this extension anymore)&lt;br /&gt;
* Adblock Plus integration, along with NoScript.&lt;br /&gt;
* Ability to inject Webslices, for use with Webchunks.&lt;br /&gt;
* Fast Dial integration&lt;br /&gt;
* Overwrite the window.print command with a less intrusive UI. It would instead pop a notification/toaster (&amp;quot;this site wants to print itself. _Print_&amp;quot;).&lt;br /&gt;
* Greasemonkey integration: &amp;quot;greasemonkey-edit &amp;lt;userscript&amp;gt;&amp;quot;. It would autocomplete the userscript name based on the list of installed userscripts.&lt;br /&gt;
* Cool iris functionality with a image flow.&lt;br /&gt;
&lt;br /&gt;
==Finished Commands==&lt;br /&gt;
* [http://shortText.com/ shortText.com] done. Create a URL of any selected text by using command &#039;shorttext&#039; or expand a shortText URL to its full content by using command &#039;longtext&#039;&lt;br /&gt;
* [http://www.google.com/sitesearch/ Google Site Search] integration. (Example: &amp;quot;search komplett.ie for cpu coolers&amp;quot;) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Metacritic (metacritic.com) review searching - [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Torrent search [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Reveal the exact URL-s behind tinyurl-s (see [http://ghill.customer.netspace.net.au/embiggen/ Embiggen Bookmarklet]) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* BugMeNot lookup for current page [http://www.geocities.com/lemming4242 Done]&lt;br /&gt;
* Open command (select multiple links, then open them all in tabs) [http://www.geocities.com/lemming4242/ Done]&lt;br /&gt;
* An online bible service command. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* A command to open a selected URL. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* Twitter Search - [http://gist.github.com/7594 Done] but could benefit from a sexier UI&lt;br /&gt;
* Random number generator.  Floating point value with input of the following type:  random lower-val higher-val&lt;br /&gt;
** Example:  Random 0 1;  Gives 0.252&lt;br /&gt;
** Example:  Random 1 100; Gives 275.840&lt;br /&gt;
** [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=12 Done]&lt;br /&gt;
* Go command (for switching between tabs by name)  (achieved by the &amp;quot;tab&amp;quot; command builtin to Ubiquity)&lt;br /&gt;
* Reopen an existing tab in a new tab. Sometimes you want to search for a new topic (in Wikipedia for example), and you have to re-open a new tab, then copy and paste the current url. Why not have a &amp;quot;re-open&amp;quot; command that lets you create a new tab, and copy the currently opened page over to it? (Alt+D &amp;gt; Alt+Enter currently does this. necessary?) (No. Did it anyways.) [http://ubiquitously.org/forum/viewtopic.php?f=5&amp;amp;t=22 Done]&lt;br /&gt;
* Currency conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done]&lt;br /&gt;
* Unit conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done (Same as above)]&lt;br /&gt;
* Stock quotes [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=26 Done]&lt;br /&gt;
* A &amp;quot;view source&amp;quot; for Ubiq commands. For example, &amp;quot;view-source link-to-wikipedia&amp;quot; =&amp;gt; [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1.1_Release_Notes available] in Ubiq 0.1.1, although not as a command.&lt;br /&gt;
* Link finder (like the &amp;quot;link-to-wikipedia&amp;quot; command but then, instead of inserting a link to wikipedia, allow the user to find the link from history/bookmarks. This would save a lot of excess work because at the moment, to insert a link, you have to open up a new tab, find the page you want to link to, copy the address and then, go back to add the link) =&amp;gt; try [http://blog.monstuff.com/archives/000343.html insert-link]&lt;br /&gt;
* Command that takes each search plugin/provider you have in the search-bar (by default, right of the locationbar in IE7 &amp;amp; FF2 &amp;amp; 3, plus more), and turns it into a command you can use.  Thus, having search plugin/providers at your fingertips in ubiquity, and adding a search plugin/provider command is just as easy as using already created functionality;  This could either be done in the underlying code of Ubiquity, or maybe have it so that the command is done as &amp;quot;Search &amp;lt;Plugin/Provider&amp;gt; &amp;lt;Terms&amp;gt;&lt;br /&gt;
** I&#039;m a moron..I actually had a command that did this.[http://theunfocused.net/moz/ubiquity/verbs/?cmd=search]&lt;br /&gt;
** Dup:  Integration of your installed Firefox search engines.&lt;br /&gt;
* Timezone converter - something like &amp;quot;get time in australia&amp;quot; ([https://wiki.mozilla.org/Labs/Ubiquity/Commands_In_The_Wild#Time Done])&lt;br /&gt;
* Ping.fm - can potentially replace twitter and facebook-status commands ([http://waleed.doubleudesigns.com/2008/08/ubiquity-and-pingfm/ Done])&lt;br /&gt;
* Mibbit IRC (mibbit [server] [optional:channels]) ([http://scguy318.freeshell.org/Mibbit%20Ubiquity%20Script.html Done])&lt;br /&gt;
* &amp;lt;tt&amp;gt;google-here &amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt;: site-search on current site (without typing it explicitly) =&amp;gt; ([http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/5c2c80df1c61d4f8 Done])&lt;br /&gt;
Can anyone write a command that decodes 2D barcodes in images on a web page?&lt;br /&gt;
&lt;br /&gt;
-I am working on a 2D barcode translator now. I have a standard barcode reader command working: http://devstatus.com ~ matt&lt;br /&gt;
&lt;br /&gt;
*I just finished a simple Woot checker that goes to the &amp;quot;Want One&amp;quot; page on enter: [http://gist.github.com/41227 Woot]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131025</id>
		<title>Labs/Ubiquity/Ubiquity Command Suggestions</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_Command_Suggestions&amp;diff=131025"/>
		<updated>2009-02-27T16:43:18Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Search Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the commands suggested on this page have already been implemented, either by us or by third parties.  Please take a look at [https://labs.toolness.com/ubiquity-herd/all-feeds/ | The Herd&#039;s command feed index] to see what commands other people have implemented.  You may find what you&#039;re looking for there!&lt;br /&gt;
&lt;br /&gt;
Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
==Interesting Commands ==&lt;br /&gt;
&lt;br /&gt;
These commands are either extremely useful to everyone (likely to be included as a builtin command) or they push the boundaries of what Ubiquity can do.&lt;br /&gt;
&lt;br /&gt;
* Search the Herd for new Ubiquity commands directly using Ubiquity without having to physically navigate to the site. &lt;br /&gt;
* Commands for all of the menu items (so that I never have to reach for the mouse to menu again). Sandro mentioned this recently. &lt;br /&gt;
* Program launcher (When in Chrome, JS can launch other applications)&lt;br /&gt;
* &amp;quot;cmd&amp;quot; command to pass selected text to the command line, i.e. &amp;quot;cmd wget&amp;quot; would pass the selected text to the wget function via the cli.&lt;br /&gt;
* Upload code to pastebin (useful for sharing commands from the command-editor)&lt;br /&gt;
* Integration with webchuck extension (with the ability to view webchunks in the preview).&lt;br /&gt;
* BlueOrganizer (be inspired by this addon and it&#039;s somewhat semantic knowledge)&lt;br /&gt;
* Graphing data (currently, only sparklines are supported). Would be nice to plot bar graphs and pie charts of things like countries by GDP from Wikipedia or browser usage on my website. There&#039;s a lot to think about here but this could potentially become one of the best features of Ubiquity.&lt;br /&gt;
* Task-specific tab grouping. Allow for opening and closing a set of tabs all at once. The key question here is how to add tabs to groups using Ubiquity.&lt;br /&gt;
&lt;br /&gt;
==Search Commands==&lt;br /&gt;
*Creative Commons: Find something in CC&lt;br /&gt;
*Wikipedia in spanish: (or use it in another languages)&lt;br /&gt;
*Bookmarklet command; execute any bookmarklet via the keyboard.(This could include normal bookmarks something like quick dial with the keyboard)&lt;br /&gt;
*Map contact command, a command to get the location(s) of a contact from your contact list.( map-contact (name) )&lt;br /&gt;
* Google site search multiple urls in selection.  You would select a block of text containing multiple urls, and be able to search them all simultaneously for any given text.&lt;br /&gt;
** Is this even possible?  What is the format?  &amp;quot;site:mozilla.org,wikipedia.org test&amp;quot;?  &amp;quot;site:mozilla.org site:wikipedia.org test&amp;quot;?&lt;br /&gt;
* Flickr search (a [http://194.95.111.244/%7Ecountzero/scripts/_myImageFlow/ coverflow-like preview] would be awesome)&lt;br /&gt;
* last.fm search with preview (a first attempt has been made [http://www.geero.net/ here])&lt;br /&gt;
* Google Image Search with preview&lt;br /&gt;
* Google Sets (part of Google labs) to give related terms based on user input&lt;br /&gt;
* More specific Google searches, like google video search on &#039;video&#039;, and google definition search type &amp;quot;define:mozilla&amp;quot; into google.&lt;br /&gt;
* A search for the Gawker sites eg: Gizmodo, Lifehacker, etc...&lt;br /&gt;
* a command to find the largest number in a given tab/present page&lt;br /&gt;
* A search for books by ISBN number for availability in libraries of your choice. Use the [http://en.wikipedia.org/wiki/Special:BookSources/ &#039;Book sources&#039;] by wikipedia to find it. To find the book with ISBN number 1871890306 in SF, you Ubiq &amp;quot;ISBN 1871890306 in San Francisco&amp;quot;, or if you are in San Francisco, you can type &amp;quot;ISBN 1871890306 here&amp;quot;, using your geo-location by ip attached to the [http://labs.toolness.com/trac/ticket/179 magic word &#039;here&#039;], which I believe will be part of Ubiq 0.2. Integration with maps in a later stage? Discuss [http://getsatisfaction.com/mozilla/topics/book_source_your_isbn_numbers_through_ubiquity here]. &lt;br /&gt;
* One command should be able to launch several searches on different sites in different tabs. It worked before, with several Utils.openUrlInBrowser&#039;s, but 0.1.1 broke it.&lt;br /&gt;
* Froogle search ([http://stanford.edu/~marce110/verbs/froogle-search.html This] works pretty well for now, but it&#039;s messy and would break if Google changed the format of the search results.)&lt;br /&gt;
* search google calendar&lt;br /&gt;
* taking the name of a television show, search for the show&#039;s schedule and add that schedule to google calendar&lt;br /&gt;
* A command that searches the web for a picture similar to one selected. using similar pixel arraignment to find pictures of better resolution or less cropped than one you might find roaming randomly.&lt;br /&gt;
** [http://blogs.msdn.com/livesearch/archive/2008/12/01/using-images-to-find-other-images.aspx Microsoft Live Search can do this]&lt;br /&gt;
* A image cover flow or even just something as simple as a image viewer. Also it should be able to add images into e-mails like the maps.&lt;br /&gt;
* Would love to see a search function for Calorie King to look up Nutrition Fact tables for foods ([http://is.gd/euXv like this one]).&lt;br /&gt;
* A search function for XHTML entities (maybe looking like [http://www.digitalmediaminute.com/reference/entity/index.php this]?) would be awesome. Not sure what auto-complete would look like for this....&lt;br /&gt;
* A function where you can highlight a text and then add additional text to that in ubiquity. For example I highlight a bands name on wiki then open Ubiquity and add a song name and then search on youtube.&lt;br /&gt;
*A search function for custom search command adding.&lt;br /&gt;
For example, allowing a user to search [input] using www.ffxiclopedia.org&#039;s main search [input] by setting &amp;quot;ffxi&amp;quot; command to it.&lt;br /&gt;
&lt;br /&gt;
==Program Integration==&lt;br /&gt;
* Goto command for navigating the web quick and easy but I want it in the core.&lt;br /&gt;
* Search command (allows you to search for text in any open tab, and then navigate you there)&lt;br /&gt;
* Flock stuff (be inspired by whatever seems to be actually useful in Flock)&lt;br /&gt;
** Especially nice if it could integrate with existing application launchers (ie: Quicksilver, Launchy, etc)&lt;br /&gt;
* Ability to take snapshots of the current window&lt;br /&gt;
* Queries for places datastores, rendering in plain html blue links (Beltzer showed me a little js console script that is a fine starting point).&lt;br /&gt;
** tag:(hci gestuers)&lt;br /&gt;
** site:google date:yesterday show:clicks&lt;br /&gt;
** starred intitle:Concept&lt;br /&gt;
* Integrate with Thunderbird, Sunbird, Songbird and other Mozilla software&lt;br /&gt;
* Allow for commands to be treated as content/arguments for other commands ie: email {map Washington DC} to myfriend@gmail.com would open up an email box to friend1 with a map of DC in the content pane&lt;br /&gt;
* clone of email command for Gajim/Pidgin/Psi/Adium...&lt;br /&gt;
* Integration with Instant Messenger clients (AIM, Pidgin, Trillion, etc) to allow inserting content into a message for a particular contact ie &#039;IM this to John&#039;&lt;br /&gt;
* Idea:: have a very, very small program run on start up, that detects when the key combination is pressed and will launch Ubiquity. After Ubiquity is dismissed, it will return to its original state.&lt;br /&gt;
* In Firefox, &amp;quot;Bookmark this&amp;quot; &amp;amp; &amp;quot;Create bookmark folder &amp;lt;data&amp;gt;&amp;quot;&lt;br /&gt;
* For Linux, allow users and other commands to be sent to the terminal...eg. IF you had selected text and wanted to open in gedit, ubiquity would tell the terminal to open gedit then paste in text..etc&lt;br /&gt;
* Ability to select the address-bar. I.e. &amp;quot;Select-address&amp;quot; would jump to the address-bar and highlight it.&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
* Annotate web pages and then share those annotations (perhaps using google notebook?)&lt;br /&gt;
* Close unrelated tabs: similar to close all related tabs&lt;br /&gt;
* Download manager - A text based download manager like wget on linux&lt;br /&gt;
* Related articles and images, possibly using Zemanta like [https://addons.mozilla.org/en-US/firefox/addon/7571 this plugin].&lt;br /&gt;
* Replace words in selected text (optional: regular expressions)&lt;br /&gt;
* Save current site into a PDF file&lt;br /&gt;
* Save page as... &amp;quot;Web Page, complete&amp;quot; to a pre-specified folder&lt;br /&gt;
* Save selection/highlighted text to a file in a pre-specified location&lt;br /&gt;
* Spell checker - any text, not just form fields&lt;br /&gt;
* Related to spell checker - take highlighted text, pass it through any number of online dictionaries, and let user select which word to use as replacement.&lt;br /&gt;
* Status message editor - Easily modify status and/or status message on popular IM protocols&lt;br /&gt;
* Perhaps &amp;quot;convert 8pm australian time to my time&amp;quot; where my timezone could automatically be obtained from CmdUtils.getLocation()&lt;br /&gt;
* &#039;Tag&#039; function:&lt;br /&gt;
** Auto-complete from current tags list would be excellent&lt;br /&gt;
** Needs to handle multiple, comma-separated tags, better.  Currently adds the comma to the tag name (eg. &#039;tag snacks, quick-meals&#039; creates a new tag called &amp;quot;snacks,&amp;quot;)&lt;br /&gt;
* &#039;Undo&#039; function should work on in-page replacements (eg. translating highlighted text or inserting a map into page)&lt;br /&gt;
* Upload selected image to [http://tinypic.com tinypic] or the like&lt;br /&gt;
* Disable &amp;quot;window.print()&amp;quot; API for all pages, or replace it with a less intrusive variant (toast notification?)&lt;br /&gt;
* Command Creator From Forms: Kind of like how you can create keyword searches by right clicking any search box, but you would be able to right-click any form from any search or web publish forms and select &amp;quot;Create Ubiquity Command...&amp;quot; which pops a box where you say the the command keyword&lt;br /&gt;
* Add a domain (current domain as default) to cookie whitelist&lt;br /&gt;
* Add a thesaurus search function&lt;br /&gt;
* Restart Firefox&lt;br /&gt;
* Download instead of opening URL&lt;br /&gt;
* The ability to Edit existing/installed commands. I.E. &amp;quot;edit-command define&amp;quot; would search for an installed &amp;quot;define&amp;quot; command and open the source in the command-editor.&lt;br /&gt;
* The ability to bookmark a page and bypass the [ok/cancel] dialog box so that you can bookmark related tabs all at once.&lt;br /&gt;
&lt;br /&gt;
==Site Integration==&lt;br /&gt;
*Forum (BBCode) formatting&lt;br /&gt;
*Youtube: Highlight a youtube link and embed the video. Could be used with other sites as well.&lt;br /&gt;
* Blogger:&lt;br /&gt;
** &#039;blog&#039; function, to create a new blog post from selected text&lt;br /&gt;
*Command for [http://www.mytextfile.com MyTextFile] such as, &amp;quot;note/textfile (text).&amp;quot; It should auto-save so you never leave Ubiquity, unless, opening a new tab is necessary. Very similar to how email works now.&lt;br /&gt;
* Google Calendar: &lt;br /&gt;
**ability to add more information to a calendar appointment such as location (perhaps signaled by @ ), calendar choice ( [ ] ), improved date parsing (you could say next Wednesday, and it could figure it out, maybe like [http://www.datejs.com/ DateJS]).&lt;br /&gt;
**ability to get a preview of my next 10 calendar entries.&lt;br /&gt;
** access HTTPS version of calendar, perhaps with &#039;add-to-scalendar&#039; and &#039;check-scalendar&#039;&lt;br /&gt;
* Gmail:&lt;br /&gt;
** Add contact, from a selected text to your contact list in gmail.&lt;br /&gt;
*** Add a contact group (and contacts if needed) from the emails list in a received email (all cc&#039;ed people, including the sender, excluding yourself), or from a list of email address&#039;.&lt;br /&gt;
** Gmail labels, alphabetical lookup from available labels.  Code possibly similar to the greasemonkey script [http://blog.persistent.info/2007/11/macros-for-new-version-of-gmail.html macros] for gmail.&lt;br /&gt;
* Google Maps - &lt;br /&gt;
** when a google map image is inserted into a form, the image should have a link to the map on the google map site. e.g.: http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Budapest,+Hungary&amp;amp;ie=UTF8&amp;amp;z=11&amp;amp;iwloc=addr&lt;br /&gt;
** Google Directions search, perhaps separating locations with a semicolon if Ubiquity doesn&#039;t understand multiple word arguments.&lt;br /&gt;
** Route information&lt;br /&gt;
* Internationalisation (google.co.uk, ebay.co.uk. etc) &lt;br /&gt;
** weather command in Celsius&lt;br /&gt;
** localize verbs (and their parameters: 01/09 = 1st September in some country)&lt;br /&gt;
** &amp;quot;map&amp;quot; command needs to be country-specific (maps.google.com.xx)&lt;br /&gt;
* Flickr integration (ability to inject pictures/slideshows and post found images to Flickr) &lt;br /&gt;
* More advanced twitter integration (a command to view last x messages from a specific friend and another to view your recent friends timeline)&lt;br /&gt;
* Blog integration (select a chunk of text or an image and then blog about it in your favorite blog software)&lt;br /&gt;
* Fly command (possibly using [http://tripeedo.com/ Tripeedo]&#039;s built-in natural language search and the site&#039;s preview or the Kayak API) to make booking flights easier&lt;br /&gt;
* Digg (see Sandro&#039;s [http://ubiquity-firefox.googlegroups.com/web/diggthis.js diggthis command])&lt;br /&gt;
* Reddit/Mixx&lt;br /&gt;
* Del.icio.us (e.g. &amp;quot;delic this&amp;quot; or &amp;quot;delic this with tag1 tag2 tag3&amp;quot;)&lt;br /&gt;
* Turn referencing friend feed comments and tweets on a page (defaulted to the current page) into page annotations via command &amp;quot;show conversations&amp;quot;&lt;br /&gt;
* Integration with Jaiku, Plurk, Pownce, and other microblogging services (not only with Twitter)&lt;br /&gt;
* Integration with Google Docs and Google Notebook&lt;br /&gt;
* Command to send selected text to tinypaste.com and/or &amp;lt;strike&amp;gt;shorttext.com&amp;lt;/strike&amp;gt; (&amp;lt;i&amp;gt;[http://shortText.com/ Commands &#039;shorttext&#039;, &#039;longtext&#039;] now available&amp;lt;/i&amp;gt;), pastebin.com, cl1p.net etc.&lt;br /&gt;
* Subscribe to current site&#039;s feed via Google Reader or other RSS reader&lt;br /&gt;
* Add to Google Bookmarks&lt;br /&gt;
* Easily control [http://www.bitlet.org BitLet.org]&lt;br /&gt;
* Add torrents with [http://www.azureuswiki.com/index.php/HTML_WebUI Azureus&#039; HTML WebUI]. =&amp;gt; this can be done with Greasemonkey already&lt;br /&gt;
* Geotag flickr photos easily (see [http://labs.sumaato.net/tools/flickr_geocode_bookmarklet/ Localize Bookmarklet])&lt;br /&gt;
* Take highlighted thread, and paste it in a forum.  Because of the amount of forums, it might be better to just have a template for each forum type.&lt;br /&gt;
* Evernote command (post this page/text to evernote) suggested by Ben [http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/68d7f5d7f817c4d5?hl=en here]&lt;br /&gt;
* Adobe Buzzword integration&lt;br /&gt;
* tempomail / jetable (temp mail address) integration. Implemented. See [http://gist.github.com/11261 Jetable]&lt;br /&gt;
* Horde email/calendar&lt;br /&gt;
* SMS Messaging. Text-message content to a contact or phone number. Could integrate with an existing service such as: http://smseverywhere.com/send.htm&lt;br /&gt;
* Set tv recording. For those people using mythtv / myth* or a TiVo with a web front-end, if you saw a show on some web site, like tvrage or any channel that shows tv-listings, highlight the show, and say &#039;record this&#039;. This would probably be very dependent on your specific web front-end / TVR hardware.&lt;br /&gt;
*integrate into MySpace. command such as &amp;quot;send this to (myspace contact): (selected text or image, maybe even if your on youtube, it will automatically imbed.)&amp;quot; Another could be &amp;quot;set headline as (selected text or input)&amp;quot;&lt;br /&gt;
* Integrate with [http://www.squirrelmail.org/ SqirrelMail]&lt;br /&gt;
* Integrate with [http://roundcube.net/ RoundCube Mail]&lt;br /&gt;
* Integrate with [http://sourceforge.net/projects/scuttle/ Scuttle Bookmarks]&lt;br /&gt;
* Integrate with [http://webcalendar.sourceforge.net/ WebCalendar]&lt;br /&gt;
* Integrate with [http://www.rememberthemilk.com/ Remember The Milk]. Add tasks, get list of tasks, mark tasks as completed, etc. They have a really rich API. (Adding tasks is done: [http://garyhodgson.com/ubiquity/rtm.html here], with a more advanced version [http://garyhodgson.com/ubiquity/rtm-wip.html in progress].)&lt;br /&gt;
* Integrate with [http://www.toodledo.com/ Toodledo] in a similar way to that described for RTM&lt;br /&gt;
* [http://www.facebook.com Facebook] status setting-resetting integration. Ping.fm has been implemented but there are users (like me) that prefer to use only one social networking site, hence they don&#039;t need a ping.fm account. (already done [http://home.comcast.net/~captainbeah/ubiquity/facebook/ here])&lt;br /&gt;
* Integrate with [http://www.me.com/ MobileMe] to allow similar email and calendar editing integration as for the Google equivalents (GMail etc.)&lt;br /&gt;
* Integrate with [http://www.ryanair.com/ Ryanair] to allow searching for flights using Ubiquity.&lt;br /&gt;
* Subscribe with Bloglines&lt;br /&gt;
* Integrate with Google Apps (Gmail, Calendar) [http://www.google.com/apps/] to allow using the standard commands&lt;br /&gt;
&lt;br /&gt;
==Extension Integration==&lt;br /&gt;
* PasswordMaker: http://passwordmaker.org/&lt;br /&gt;
* BlueOrganizer (be inspired by [https://addons.mozilla.org/en-US/firefox/addon/3481 this addon] and it&#039;s somewhat semantic knowledge)  &lt;br /&gt;
* Take inspiration from [https://addons.mozilla.org/en-US/firefox/addon/1407  Clipmarks]&lt;br /&gt;
* Firebug integration, inspect DOM-Reference, show firebug net panel&lt;br /&gt;
* Media player control similar to [https://addons.mozilla.org/en-US/firefox/addon/219 FoxyTunes]&lt;br /&gt;
* AnyColor integration -- https://addons.mozilla.org/en-US/firefox/addon/6991&lt;br /&gt;
* Faviconize -- A command called Fav [open tab] to change it&#039;s state from showing/hiding title&lt;br /&gt;
* Commands for Screen grab! extension&lt;br /&gt;
* Undo Closed Tabs Button feature like the extension of that name. (Note: this is built into Firefox 3.0, no need for this extension anymore)&lt;br /&gt;
* Adblock Plus integration, along with NoScript.&lt;br /&gt;
* Ability to inject Webslices, for use with Webchunks.&lt;br /&gt;
* Fast Dial integration&lt;br /&gt;
* Overwrite the window.print command with a less intrusive UI. It would instead pop a notification/toaster (&amp;quot;this site wants to print itself. _Print_&amp;quot;).&lt;br /&gt;
* Greasemonkey integration: &amp;quot;greasemonkey-edit &amp;lt;userscript&amp;gt;&amp;quot;. It would autocomplete the userscript name based on the list of installed userscripts.&lt;br /&gt;
* Cool iris functionality with a image flow.&lt;br /&gt;
&lt;br /&gt;
==Finished Commands==&lt;br /&gt;
* [http://shortText.com/ shortText.com] done. Create a URL of any selected text by using command &#039;shorttext&#039; or expand a shortText URL to its full content by using command &#039;longtext&#039;&lt;br /&gt;
* [http://www.google.com/sitesearch/ Google Site Search] integration. (Example: &amp;quot;search komplett.ie for cpu coolers&amp;quot;) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Metacritic (metacritic.com) review searching - [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Torrent search [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* Reveal the exact URL-s behind tinyurl-s (see [http://ghill.customer.netspace.net.au/embiggen/ Embiggen Bookmarklet]) [http://mysite.verizon.net/zaduma/ Done]&lt;br /&gt;
* BugMeNot lookup for current page [http://www.geocities.com/lemming4242 Done]&lt;br /&gt;
* Open command (select multiple links, then open them all in tabs) [http://www.geocities.com/lemming4242/ Done]&lt;br /&gt;
* An online bible service command. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* A command to open a selected URL. [http://tim.sorbera.googlepages.com/ubiquity.html Done]&lt;br /&gt;
* Twitter Search - [http://gist.github.com/7594 Done] but could benefit from a sexier UI&lt;br /&gt;
* Random number generator.  Floating point value with input of the following type:  random lower-val higher-val&lt;br /&gt;
** Example:  Random 0 1;  Gives 0.252&lt;br /&gt;
** Example:  Random 1 100; Gives 275.840&lt;br /&gt;
** [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=12 Done]&lt;br /&gt;
* Go command (for switching between tabs by name)  (achieved by the &amp;quot;tab&amp;quot; command builtin to Ubiquity)&lt;br /&gt;
* Reopen an existing tab in a new tab. Sometimes you want to search for a new topic (in Wikipedia for example), and you have to re-open a new tab, then copy and paste the current url. Why not have a &amp;quot;re-open&amp;quot; command that lets you create a new tab, and copy the currently opened page over to it? (Alt+D &amp;gt; Alt+Enter currently does this. necessary?) (No. Did it anyways.) [http://ubiquitously.org/forum/viewtopic.php?f=5&amp;amp;t=22 Done]&lt;br /&gt;
* Currency conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done]&lt;br /&gt;
* Unit conversion [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=25 Done (Same as above)]&lt;br /&gt;
* Stock quotes [http://ubiquitously.org/forum/viewtopic.php?f=4&amp;amp;t=26 Done]&lt;br /&gt;
* A &amp;quot;view source&amp;quot; for Ubiq commands. For example, &amp;quot;view-source link-to-wikipedia&amp;quot; =&amp;gt; [https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1.1_Release_Notes available] in Ubiq 0.1.1, although not as a command.&lt;br /&gt;
* Link finder (like the &amp;quot;link-to-wikipedia&amp;quot; command but then, instead of inserting a link to wikipedia, allow the user to find the link from history/bookmarks. This would save a lot of excess work because at the moment, to insert a link, you have to open up a new tab, find the page you want to link to, copy the address and then, go back to add the link) =&amp;gt; try [http://blog.monstuff.com/archives/000343.html insert-link]&lt;br /&gt;
* Command that takes each search plugin/provider you have in the search-bar (by default, right of the locationbar in IE7 &amp;amp; FF2 &amp;amp; 3, plus more), and turns it into a command you can use.  Thus, having search plugin/providers at your fingertips in ubiquity, and adding a search plugin/provider command is just as easy as using already created functionality;  This could either be done in the underlying code of Ubiquity, or maybe have it so that the command is done as &amp;quot;Search &amp;lt;Plugin/Provider&amp;gt; &amp;lt;Terms&amp;gt;&lt;br /&gt;
** I&#039;m a moron..I actually had a command that did this.[http://theunfocused.net/moz/ubiquity/verbs/?cmd=search]&lt;br /&gt;
** Dup:  Integration of your installed Firefox search engines.&lt;br /&gt;
* Timezone converter - something like &amp;quot;get time in australia&amp;quot; ([https://wiki.mozilla.org/Labs/Ubiquity/Commands_In_The_Wild#Time Done])&lt;br /&gt;
* Ping.fm - can potentially replace twitter and facebook-status commands ([http://waleed.doubleudesigns.com/2008/08/ubiquity-and-pingfm/ Done])&lt;br /&gt;
* Mibbit IRC (mibbit [server] [optional:channels]) ([http://scguy318.freeshell.org/Mibbit%20Ubiquity%20Script.html Done])&lt;br /&gt;
* &amp;lt;tt&amp;gt;google-here &amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt;: site-search on current site (without typing it explicitly) =&amp;gt; ([http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/5c2c80df1c61d4f8 Done])&lt;br /&gt;
Can anyone write a command that decodes 2D barcodes in images on a web page?&lt;br /&gt;
&lt;br /&gt;
-I am working on a 2D barcode translator now. I have a standard barcode reader command working: http://devstatus.com ~ matt&lt;br /&gt;
&lt;br /&gt;
*I just finished a simple Woot checker that goes to the &amp;quot;Want One&amp;quot; page on enter: [http://gist.github.com/41227 Woot]&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Insert non-formatted text here&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial&amp;diff=124806</id>
		<title>Labs/Ubiquity/Ubiquity 0.1 Author Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial&amp;diff=124806"/>
		<updated>2009-01-21T04:42:14Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Using CreateCommand */ add link to Ubiquity Code Documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
Author: Aza Raskin, Blair McBride, Abimanyu Raja, Jono DiCarlo, Atul Varma&lt;br /&gt;
&lt;br /&gt;
== In other languages ==&lt;br /&gt;
&lt;br /&gt;
* [[zh-CN:Ubiquity 0.1 Author Tutoria|简体中文l]]&lt;br /&gt;
* [[ja:Ubiquity 0.1.2 User Tutorial|日本語で]] &lt;br /&gt;
* [[es:Ubiquity 0.1.2 User Tutorial|En español]]&lt;br /&gt;
* [[mr:Ubiquity 0.1.2 User Tutorial|Mr मराठी (Marathi)]]&lt;br /&gt;
* [[Labs/Ubiquity/hi:Ubiquity 0.1.2 User Tutorial|Hi हिंदी (Hindi)]]&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your first language feel free to read the tutorial in your own language. If it doesn&#039;t exists, feel free to jump in and translate.&lt;br /&gt;
&lt;br /&gt;
= The Ubiquity 0.1 Command Tutorial =&lt;br /&gt;
&lt;br /&gt;
The great power of Ubiquity&amp;amp;mdash;from a developer standpoint&amp;amp;mdash;is how easy it is to create commands. With only a couple of lines of Javascript, Ubiquity enables even casual web developers to drastically enhance the features of the browser. From an 8-line command to insert a contact&#039;s email address in any text field, to a 50-line Twitter integration, this tutorial walks you through the process of being generative with Ubiquity.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING&#039;&#039;&#039;: Ubiquity is still in flux. This is a 0.1 release. The API is  likely to change drastically in later revisions. While this means that what you write today might not work next week, it also means that by writing commands and giving us [[Labs/Ubiquity#Participation|your feedback]], you&#039;ll be able to directly influence the direction that Ubiquity goes.&lt;br /&gt;
&lt;br /&gt;
The rest of this page documents the command developer API as it currently stands in the latest released version of Ubiquity, 0.1.1.  However, if you have the latest source checkout, then you&#039;ll have a newer API with some additional features not in 0.1.1.  You can read about the latest and greatest source-tip API on [[Labs/Ubiquity/Ubiquity Source Tip Author Tutorial|Ubiquity Source Tip Author Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Real Time Development ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t require you to restart Firefox as you develop. That&#039;s a barbaric act, and we want none of it. Instead, Ubiquity reloads the commands every time it is summoned. When you are using the built-in editor then you don&#039;t even need to save!&lt;br /&gt;
&lt;br /&gt;
To open the Ubiquity command editor, summon Ubiquity (control/alt + space) and use the &amp;quot;command-editor&amp;quot; command. Throughout this tutorial, when we want you to run a command in Ubiquity, we&#039;ll say &#039;&#039;&#039;Ubiq&#039;&#039;&#039; it. For instance, to open the editor, just Ubiq &amp;quot;command-editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the following examples, just type in this editor. Updates happen the next time you summon Ubiquity.&lt;br /&gt;
&lt;br /&gt;
= Hello World: The First Command =&lt;br /&gt;
&lt;br /&gt;
== Just a Function: As Simple as it Gets ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s start with the standard programing trope: printing &amp;quot;Hello, World!&amp;quot;. In Ubiquity, commands are simply functions with various attributes tacked on. We&#039;ll start by manually making a function to define a command, but we&#039;ll quickly move to using a more elegant method.&lt;br /&gt;
&lt;br /&gt;
In the command editor type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function cmd_hello_world() {&lt;br /&gt;
  displayMessage( &amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now try Ubiq-ing &amp;quot;hello-world&amp;quot;. You&#039;ll see that &amp;quot;Hello, World!&amp;quot; is immediatly displayed on the screen. If you are on Mac OSX with [http://en.wikipedia.org/wiki/Growl_(software) Growl] installed the message will appear as a Growl notification. If you are on Windows, then it will appears as a standard &amp;quot;toaster&amp;quot; notification in the bottom right-hand corner of the screen.&lt;br /&gt;
&lt;br /&gt;
http://img367.imageshack.us/img367/7051/picture1ui2.png&lt;br /&gt;
&lt;br /&gt;
http://img517.imageshack.us/img517/7726/picture2vx2.png&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 8.04 (Hardy Heron) this appears thus:&lt;br /&gt;
&lt;br /&gt;
http://img293.imageshack.us/img293/7746/ubiqubuntuhelloworldeq9.png&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have Growl installed on OSX, or aren&#039;t on a Windows XP/Vista or Ubuntu Hardy/Intrepid, then you won&#039;t get any sort of notification. That&#039;s something to be [http://labs.toolness.com/trac/ticket/19 worked on] in future released of Ubiquity.&lt;br /&gt;
&lt;br /&gt;
There&#039;s not much in this command, so let&#039;s dive straight in. Any function that starts with &amp;lt;code&amp;gt;cmd_&amp;lt;/code&amp;gt; automatically becomes a Ubiquity command. It&#039;s a little bit of namespace magic that makes development super-simple.&lt;br /&gt;
&lt;br /&gt;
There are other prefixes that have other effects, like running code on page load (&amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;), and startup (&amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt;), but that&#039;s for a different tutorial.&lt;br /&gt;
&lt;br /&gt;
Back to the example. The meat of the command is in the function &amp;lt;code&amp;gt;displayMessage()&amp;lt;/code&amp;gt;, which displays the message in whichever way the operating system can.&lt;br /&gt;
&lt;br /&gt;
You may be wondering why there is a hyphen in the name, instead of a space. That&#039;s because the Ubiquity natural language parser isn&#039;t yet smart enough to handle commands that are multiple words &amp;lt;i&amp;gt;and&amp;lt;/i&amp;gt; arguments that are multiple words. It&#039;s something we&#039;ll be working on in the future.&lt;br /&gt;
&lt;br /&gt;
== Using CreateCommand ==&lt;br /&gt;
&lt;br /&gt;
For commands that are more complicated than our simple &amp;quot;hello-world&amp;quot; command, you can use the helper function &amp;lt;code&amp;gt;CmdUtils.CreateCommand()&amp;lt;/code&amp;gt;, which takes an options dictionary. To redo the &amp;quot;hello-world&amp;quot; command using the convenience function, we&#039;d write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;hello-world&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may not seem to be much of a win (and it isn&#039;t for simple commands) but as the commands become more complex, you&#039;ll see that it helps a lot. For one, you can name the command more freely with the method&amp;amp;mdash;unicode non-English characters are now fair game.&lt;br /&gt;
&lt;br /&gt;
There are a number of other useful functions in the CmdUtils namespace. We don&#039;t yet have full documentation for these commands, but you&#039;ll get a sense of the useful ones in this tutorial. For more detailed information, take a look at the [https://ubiquity.mozilla.com/hg/ubiquity-firefox/raw-file/tip/ubiquity/index.html automatically generated documentation] or [http://hg.toolness.com/ubiquity-firefox/file/9a6c9935da9f/ubiquity/chrome/content/cmdutils.js cmdutils.js].&lt;br /&gt;
&lt;br /&gt;
== Adding a Preview ==&lt;br /&gt;
&lt;br /&gt;
http://img352.imageshack.us/img352/1002/picture3ex0.png&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a preview to our new command. Previews give the user feedback about what a command does before it&#039;s executed. Previews are great for providing rich visual feedback like displaying a graphical representation of atmospheric conditions when using the weather command as shown above. Previews have the full expressive power of HTML, including animations, so there&#039;s a lot you can do with them.&lt;br /&gt;
&lt;br /&gt;
One point of design: Preview code should never have side-effects. That is, a preview should never (without user interaction) change the state of the system.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;hello-world&amp;quot; command, we don&#039;t need anything fancy: just some help text that is more descriptive than the default &amp;quot;Executes the hello-world command.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;hello-world&amp;quot;,&lt;br /&gt;
  preview: &amp;quot;Displays a &amp;lt;i&amp;gt;salutary&amp;lt;/i&amp;gt; greeting to the planet.&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the preview is an HTML-formatted string. The preview can also be a function. We&#039;ll get to that in the next section.&lt;br /&gt;
&lt;br /&gt;
= The Date Command: The Second Command =&lt;br /&gt;
&lt;br /&gt;
= Setting the Selection =&lt;br /&gt;
&lt;br /&gt;
I often forget what day it is. That may be because I need to go outside more often, but, like any programmer, I generally solve my problem&#039;s symptoms with technology rather then addressing the root cause. My solution is to create a command that inserts the date at the location of the cursor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    CmdUtils.setSelection( date.toLocaleDateString() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new function here is &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt;. This inserts the passed-in text onto the page at the location of the cursor. If the cursor is in an editable text or rich-text fields, the text gets dumped there. If the cursor isn&#039;t in an editable area, &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt; will still be able to insert the date. (Even when it isn&#039;t displayed, Firefox always keeps track of a cursor position. To see it, type F7.) Try going to a page, selecting some non-mutable text, and using the command. See, it works! This is particularly useful for commands like &amp;quot;translate&amp;quot;, where you want to replace non-editable text with its translation.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;toLocalDateString()&amp;lt;/code&amp;gt; function is native to Javascript, so if you&#039;re not familiar with it check out the documentation for the Javascript [http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date Date object].&lt;br /&gt;
&lt;br /&gt;
== A Better Preview ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s time to add a better preview to the date command. Let&#039;s have the preview show the date, so that the user will know what to expect when they execute the command. (As a side benefit the user doesn&#039;t even need to execute the command to do a quick check of the day.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  _date: function(){&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    return date.toLocaleDateString();&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &#039;Inserts todays date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function() {&lt;br /&gt;
    CmdUtils.setSelection( this._date() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&#039;ve done two things here. The first was to factor out the code for getting the date into the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt; function. This way we don&#039;t break [http://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY] by repeating code across the preview and execute functions. Notice that to access the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt;, we use the &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
&lt;br /&gt;
The second thing we&#039;ve done is to add a preview function. The first argument is the DOM element that gets displayed as the preview for your command. Modify &amp;lt;code&amp;gt;pblock&amp;lt;/code&amp;gt; and you modify the preview. In this case, we set the &amp;lt;code&amp;gt;innerHTML&amp;lt;/code&amp;gt; of the preview block to be the message we want.&lt;br /&gt;
&lt;br /&gt;
The other thing I&#039;ve done is to do some string formatting using the &amp;lt;code&amp;gt;renderTemplate()&amp;lt;/code&amp;gt; function. This takes a template string and performs the appropriate substitution given the passed-in JSON object. Templates can handle a wide range of functionality, as we are currently using TrimPath&#039;s [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates JavascriptTemplates]. You should read their site for more documentation. Although JavascriptTemplates has some nice properties, we are contemplating moving to [http://mjtemplate.org/ MJT] sometime soon.&lt;br /&gt;
&lt;br /&gt;
Previews display something meaningful to the user immediately. If you have a preview that requires an AJAX request&amp;amp;mdash;say, to fetch some search results&amp;amp;mdash;that call might take a while to return. In the meantime, your command should display a placeholder preview giving the user feedback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    pblock.innerHTML = &amp;quot;This will show until the AJAX request returns&amp;quot;;&lt;br /&gt;
    // AJAX request&lt;br /&gt;
    pblock.innerHTML = getFromServer();&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the future, we may work on streamlining this process.&lt;br /&gt;
&lt;br /&gt;
== Documentation and Metadata ==&lt;br /&gt;
&lt;br /&gt;
Before you share your command with the world, you should consider adding some attributions to the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you should &amp;lt;em&amp;gt;definitely&amp;lt;/em&amp;gt; add some documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Inserts today&#039;s date.&amp;quot;,&lt;br /&gt;
  help: &amp;quot;If you&#039;re in an editable text area, inserts today&#039;s date, formatted for the current locale.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.description&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.help&amp;lt;/code&amp;gt; attributes are both automatically displayed alongside your command&#039;s name on the command-list page.  (The user can get to this page at any time by issuing the &amp;quot;command-list&amp;quot; command.)  HTML tags can be used in both of these strings.&lt;br /&gt;
&lt;br /&gt;
Description is a one-line summary of what the command does, while Help is a longer description that can include examples, caveats, and so on. If your command is simple enough that all you have to say about it fits in one line, it&#039;s OK to use a description alone and leave out the help.&lt;br /&gt;
&lt;br /&gt;
== Sharing it with the World ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our awesome new &amp;quot;date&amp;quot; command, let&#039;s share it with the world. All you have to do is put it the javascript file on the web somewhere, and make an html page linking to it with &amp;quot;link rel&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;pre&amp;gt;&amp;lt;link rel=&amp;quot;commands&amp;quot; href=&amp;quot;http://path-to-js&amp;quot; name=&amp;quot;Title Goes Here&amp;quot; /&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: your webserver must serve .js files as &#039;application/x-javascript&#039;. The mime-type &#039;text/javascript&#039; is silently ignored.&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Anyone with Ubiquity who visits will get a message offering them the choice of subscribing to your command.&lt;br /&gt;
&lt;br /&gt;
[[Image:Subscribe.png]]&lt;br /&gt;
&lt;br /&gt;
If the user chooses to subscribe to a command from an untrusted source, they will get a security warning message before they can install the command.  (And in Ubiquity 0.1, ALL sources are considered untrusted, so don&#039;t take it personally!)  Because Ubiquity commands can execute arbitrary javascript with chrome privileges, subscribing to a command from a website means allowing that site full access to do whatever it wants to your browser.  We want to make sure people understand the dangers before subscribing to commands, so we made the warning page pretty scary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Warning.PNG]]&lt;br /&gt;
&lt;br /&gt;
In the future, we&#039;re going to have something set up that we call a &amp;quot;trust network&amp;quot;.  When you try out a Ubiquity command from a website, and determine that the command is safe (or unsafe), you&#039;ll be able to leave an approval (or a warning).  When your friends with Ubiquity installed visit the same site, they&#039;ll see the approval or the warning that you left.  In this way, users will be able to rely on the judgement of other people they already know and trust in order to help them make decisions about whether a command is safe to install or not.&lt;br /&gt;
&lt;br /&gt;
By the way, the reason we call it &amp;quot;subscribing&amp;quot; to a command, rather than &amp;quot;installing&amp;quot; a command, is that if the javascript file changes -- if the site owner adds new commands, removes old commands, or updates existing commands -- all users subscribed to that URL will automatically get the updates.  This will be very convenient for both users and developers, but it will also introduce another type of security risk: just because you decided a command was safe at one point in time doesn&#039;t mean that the command will always remain safe.  For this reason, we&#039;ll need to make sure that the trust network keeps track of when commands have been modified, and notifies users of changes that may make a command unsafe.&lt;br /&gt;
&lt;br /&gt;
== Map Me! Location, Snapshots, and Inserting HTML ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;map&amp;quot; command that comes with Ubiquity is fairly powerful. It&#039;s also fairly complicated&amp;amp;mdash;well, comparatively. It&#039;s still only a couple hundred lines of code. The command, though, can get even more useful. Imagine being able to select some houses on Craigslist, or a list of restaurant names, and Ubiq &amp;quot;map these&amp;quot; to get just the map you want. The concept of &amp;quot;these&amp;quot; puts the power of mashups into the users hands. But I digress. Let&#039;s make a simple command that inserts a map of your current location.&lt;br /&gt;
&lt;br /&gt;
In this command, we use the Google [http://code.google.com/apis/maps/documentation/staticmaps/ static map API] and the Ubiquity function &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; to insert a map of your current location. Ubiquity currently uses the [http://www.maxmind.com/app/api MaxMind] API for trying to guess your location from your IP. That will probably change in the future.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;map-me&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  _getMapUrl: function() {&lt;br /&gt;
    var loc = CmdUtils.getGeoLocation();&lt;br /&gt;
    var mapUrl = &amp;quot;http://maps.google.com/staticmap?&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    var params = {&lt;br /&gt;
      center: loc.lat + &amp;quot;,&amp;quot; + loc.long,&lt;br /&gt;
      size: &amp;quot;500x400&amp;quot;,&lt;br /&gt;
      zoom: 14,&lt;br /&gt;
      key: &amp;quot;ABQIAAAAGZ11mh1LzgQ8-8LRW3wEShQeSuJunOpTb3RsLsk00-MAdzxmXhQoiCd940lo0KlfQM5PeNYEPLW-3w&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    return mapUrl + jQuery.param( params );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &amp;quot;Inserts a map of your current location: &amp;lt;br/&amp;gt;&amp;quot;;&lt;br /&gt;
    msg += &amp;quot;&amp;lt;img src=&#039;%s&#039;/&amp;gt;&amp;quot;.replace( /%s/, this._getMapUrl() );&lt;br /&gt;
    pblock.innerHTML = msg;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( ) {&lt;br /&gt;
    CmdUtils.getImageSnapshot( this._getMapUrl(), function(imgData) {&lt;br /&gt;
      CmdUtils.setSelection( &amp;quot;&amp;lt;img src=&#039;&amp;quot; + imgData +&amp;quot;&#039;/&amp;gt;&amp;quot;);&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are three new things here: &amp;lt;code&amp;gt;CmdUtils.setSelection&amp;lt;/code&amp;gt; to set HTML (yep, it can do that); the use of &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt;; and using &amp;lt;code&amp;gt;CmdUtils.getImageSnapshot()&amp;lt;/code&amp;gt; to capture the bits for the image.&lt;br /&gt;
&lt;br /&gt;
I find getting the location&amp;amp;mdash;as imprecise as IP-based location can be&amp;amp;mdash;useful for doing sensible defaults for location-based commands, like Yelp. &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; returns an object which has the following properties: city, state, country, lat, and long.&lt;br /&gt;
&lt;br /&gt;
Why do we need to use &amp;lt;code&amp;gt;CmdUtils.getImageSnapshot()&amp;lt;/code&amp;gt;? Because the Google Maps API requires a key that is tied to a particular URL. If we naively inject the image tag into a random web page, the image won&#039;t load because the key doesn&#039;t match that random web page&#039;s URL. Thus, we use the &amp;lt;code&amp;gt;snapshotImage()&amp;lt;/code&amp;gt; function to convert the image into a [http://en.wikipedia.org/wiki/Data:_URI_scheme data url].&lt;br /&gt;
&lt;br /&gt;
There&#039;s also a &amp;lt;code&amp;gt;CmdUtils.getWindowSnapshot()&amp;lt;/code&amp;gt; function, which allows you to get the image data for any tab/window. The function takes a window as the first paramater, and a callback for the second.&lt;br /&gt;
&lt;br /&gt;
= Commands with Arguments =&lt;br /&gt;
&lt;br /&gt;
== Echo ==&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be working towards making some fun and useful commands&amp;amp;mdash;commands that let you control the seething tendrils of the internet with your little pinky. But, let&#039;s start by making a simple command to echo back whatever you type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;echo&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;your shout&amp;quot;: noun_arb_text},&lt;br /&gt;
  preview: function( pblock, theShout ) {&lt;br /&gt;
    pblock.innerHTML = &amp;quot;Will echo: &amp;quot; + theShout.text;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function( theShout ) {&lt;br /&gt;
    var msg = theShout.text + &amp;quot;... &amp;quot; + theShout.text + &amp;quot;......&amp;quot;;&lt;br /&gt;
    displayMessage( msg );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This says that the command &amp;quot;echo&amp;quot; takes one argument which is arbitrary text. Whatever text the user enters will get wrapped in an input object and passed into both the preview and execute function.&lt;br /&gt;
&lt;br /&gt;
Ubiquity takes care of parsing the user&#039;s input, so you don&#039;t need to worry about handling prounoun substitution or any of the other natural-language-like features of the Ubiquity parser. Try selecting some text on a page, and Ubiq &amp;quot;echo this&amp;quot;. Ubiquity should now echo the selected text.&lt;br /&gt;
&lt;br /&gt;
=== The Input Object ===&lt;br /&gt;
&lt;br /&gt;
The input object that your execute and preview functions receive has the following attributes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  inputObject.text  // a string of the input in plain text, without formatting&lt;br /&gt;
  inputObject.html  // a string of the input in formatted html, including tags&lt;br /&gt;
  inputObject.data  // for non-text input types, an arbitrary data object&lt;br /&gt;
  inputObject.summary // for very long inputs, an abbreviated display string&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our example command only cares about the &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; attribute of the input, because it simply wants plain text.  Often, when the user invokes your command by typing a few short words into the input box, &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.html&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; will all have exactly the same value, and &amp;lt;code&amp;gt;.data&amp;lt;/code&amp;gt; will be null.  Many, if not most, commands that you write will only care about the text value.  Nevertheless, the other versions of the input data are provided to you in case they differ from &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; and in case your command has a use for them.&lt;br /&gt;
&lt;br /&gt;
=== Introduction to Noun Types ===&lt;br /&gt;
&lt;br /&gt;
Notice that we specified the type of argument to expect by passing in an object &amp;amp;mdash; in this case, the predefined &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; object, which accepts any arbitrary text as a valid argument.  If we had wanted to restrict the inputs that our command could take, we could have used a more specific noun-type object to restrict the scope of the argument: for instance, &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; to accept only dates (like the &amp;quot;check-calendar&amp;quot; command) or &amp;lt;code&amp;gt;noun_type_language&amp;lt;/code&amp;gt; to accept only names of languages (like the optional modifiers for the &amp;quot;translate&amp;quot; command).&lt;br /&gt;
&lt;br /&gt;
The benefit of specifying a more restrictive noun-type is that it helps the Ubiquity parser generate better suggestions and auto-completions based on user-input.  For instance, if the user has a date selected, commands that operate specifically on dates are more likely to be apropos than commands that take arbitrary text, so Ubiquity can suggest the date-specific commands first.&lt;br /&gt;
&lt;br /&gt;
There are many types of nouns that a command could conceivably take: people, dates, places, tabs, etc. Many of these noun-types aren&#039;t implemented yet, and most of the them currently have a lack-luster implementation. This is one of the areas where Ubiquity could use the greatest help. Noun-types enable creating compelling user experiences, with minimal amounts of code. It also allows for code-reuse across numerous commands.&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with writing commands, you should check out the [http://hg.toolness.com/ubiquity-firefox/file/6caa9d66b3bb/ubiquity/chrome/content/nlparser/en/nountypes.js nountypes.js], which has the implementation for most of the noun-types.  You can see what noun types are already available for your commands to use, what still needs to be written, and where the existing implementations could use improvement &amp;amp;mdash; and then come [[Labs/Ubiquity#Participation|get involved]] to help us improve them.&lt;br /&gt;
&lt;br /&gt;
== Insert Email: Commands with Specific Argument Types ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s take a look at one of the special noun-types: &amp;lt;code&amp;gt;noun_type_contact&amp;lt;/code&amp;gt;. This lets Ubiquity know to expect a person (either by name or email address). By using the noun-type, Ubiquity will also autocomplete to known people while the user is entering the command. This is what the built-in Ubiquity command &amp;quot;email&amp;quot; uses.&lt;br /&gt;
&lt;br /&gt;
At the moment, Ubiquity figures out what people you know through reading your Gmail contacts. In this prototyped version, you&#039;ll need to use Gmail and be logged in for for Ubiquity to know who you know. Eventually, we&#039;d like to be able to interface with all major web-mail sites, as well as desktop software like Thunderbird.&lt;br /&gt;
&lt;br /&gt;
Enough rambling. It&#039;s time for a command. I constantly find that I need to fetch someone&#039;s email address to paste into a text field because I don&#039;t know it off-hand. This command solves that by letting you insert someone&#039;s email address using autocomplete.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;insert-email&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;person&amp;quot;: noun_type_contact},&lt;br /&gt;
  preview: &amp;quot;Inserts someone&#039;s email address by name.&amp;quot;,&lt;br /&gt;
  execute: function( email ) {&lt;br /&gt;
    CmdUtils.setSelection( email.text );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This one command sums up what I love about Ubiquity. In 8 lines of code, I can fundamentally enhance the browser&#039;s functionality. Doing the same thing using a normal Firefox extension methodology takes pages and pages of code&amp;amp;mdash;and the interface would take more thought still. Doing the same thing using a bookmarklet would require a server-side component (to get around cross-site Ajax request ban) as well as forcing the user to give up their email password.&lt;br /&gt;
&lt;br /&gt;
Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web.&lt;br /&gt;
&lt;br /&gt;
== TinyURL: Network Calls and jQuery ==&lt;br /&gt;
&lt;br /&gt;
Often while writing emails, I&#039;ll discover that I&#039;ve pasted in a URL long enough to be used for unfortunate analogies. I&#039;d like to be able to quickly turn that into a [http://en.wikipedia.org/wiki/Tinyurl TinyURL]&amp;amp;mdash;but the process of making a TinyURL involves lots of fiddly steps. Ubiquity to the rescue.&lt;br /&gt;
&lt;br /&gt;
Because we include [http://en.wikipedia.org/wiki/jQuery jQuery] with Ubiquity, it is simple to perform Ajax calls as well as parse returning data. TinyUrl.com provides an easy to use RESTful API where you pass a URL and it returns its shortened form. We use that API in this command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;tinyurl&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;url to shorten&amp;quot;: noun_arb_text},&lt;br /&gt;
  preview: &amp;quot;Replaces the selected URL with a TinyUrl.&amp;quot;,&lt;br /&gt;
  execute: function( urlToShorten ) {&lt;br /&gt;
    var baseUrl = &amp;quot;http://tinyurl.com/api-create.php&amp;quot;;&lt;br /&gt;
    var params = {url: urlToShorten.text};&lt;br /&gt;
    jQuery.get( baseUrl, params, function( tinyUrl ) {&lt;br /&gt;
      CmdUtils.setSelection( tinyUrl );&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although I used the &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; command noun-type, I should have used the &amp;lt;code&amp;gt;noun_type_url&amp;lt;/code&amp;gt;&amp;amp;mdash;if such a thing existed. It doesn&#039;t yet.&lt;br /&gt;
&lt;br /&gt;
jQuery is a powerful tool. With it, you can fairly effortlessly cherry-pick the data you need from RSS feeds, XML, and all sorts of other data formats. It also makes doing in-preview animations a breeze.&lt;br /&gt;
&lt;br /&gt;
== Color: Creating Bounded Noun Types ==&lt;br /&gt;
&lt;br /&gt;
Suppose you&#039;re writing a set of commands for artists and&lt;br /&gt;
web designers, and you know that several of the commands will operate&lt;br /&gt;
on colors.  You&#039;d like to be able to specify that certain commands&lt;br /&gt;
expect names of colors as arguments.  Since there are a finite number of&lt;br /&gt;
named colors, you can define a custom noun type for them based on a list&lt;br /&gt;
of strings, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
noun_type_color = new CmdUtils.NounType( &amp;quot;Color&amp;quot;,&lt;br /&gt;
  [&amp;quot;red&amp;quot;, &amp;quot;orange&amp;quot;, &amp;quot;yellow&amp;quot;, &amp;quot;green&amp;quot;, &amp;quot;blue&amp;quot;, &amp;quot;violet&amp;quot;, &amp;quot;black&amp;quot;, &amp;quot;white&amp;quot;,&lt;br /&gt;
   &amp;quot;grey&amp;quot;, &amp;quot;brown&amp;quot;, &amp;quot;beige&amp;quot;, &amp;quot;magenta&amp;quot;, &amp;quot;cerulean&amp;quot;, &amp;quot;puce&amp;quot;] // etc...&lt;br /&gt;
  );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we gave the new object a name starting with &amp;quot;&amp;lt;code&amp;gt;noun_&amp;lt;/code&amp;gt;&amp;quot;.&lt;br /&gt;
The Ubiquity command loader automatically detects objects starting with&lt;br /&gt;
&amp;quot;&amp;lt;code&amp;gt;noun_&amp;lt;/code&amp;gt;&amp;quot; as custom noun-types, in the same way as it auto-detects&lt;br /&gt;
functions starting with &amp;quot;&amp;lt;code&amp;gt;cmd_&amp;lt;/code&amp;gt;&amp;quot; as custom commands.&lt;br /&gt;
&lt;br /&gt;
Once you&#039;ve defined a custom noun-type, you can use it in as many commands&lt;br /&gt;
as you like, thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;get-color-code&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;color&amp;quot;: noun_type_color},&lt;br /&gt;
  preview: &amp;quot;Inserts the HTML hex-code for the given color.&amp;quot;,&lt;br /&gt;
  // etc...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One benefit of creating the custom color noun-type is that if the user&lt;br /&gt;
has entered &amp;quot;get-color bl&amp;quot;, for instance, Ubiquity will be able to suggest&lt;br /&gt;
&amp;quot;black&amp;quot; and &amp;quot;blue&amp;quot; as the two valid completions based on the input.&lt;br /&gt;
&lt;br /&gt;
Of course, not every type of noun you&#039;d be interested in can be represented&lt;br /&gt;
as a finite list.  If you want to be able to accept or reject input based&lt;br /&gt;
on some algorithmic test, you can do so by creating your own noun-type&lt;br /&gt;
implementation instead of instantiating &amp;lt;code&amp;gt;CmdUtils.NounType&amp;lt;/code&amp;gt;.  There is an example of this in the section on the tab commands, below.&lt;br /&gt;
&lt;br /&gt;
== Replace: Commands With Multiple Arguments ==&lt;br /&gt;
&lt;br /&gt;
Commands, like the translate command, can take multiple (and possibly optional) arguments. Ubiquity takes care of the parsing&amp;amp;mdash;you don&#039;t have to worry about what order the user types them in, you&#039;ll just get passed a dictionary with the appropriate entries.&lt;br /&gt;
&lt;br /&gt;
To illustrate that, let&#039;s make a simple regular-expression-based &amp;quot;replace&amp;quot; command. It will take three arguments: the thing to replace, the replacement, and the scope-text to do the replacing in. Here&#039;s the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;replace&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;what&amp;quot;: noun_arb_text},&lt;br /&gt;
  modifiers: {&amp;quot;with&amp;quot;: noun_arb_text, &amp;quot;in&amp;quot;: noun_arb_text},&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock, what, mods ) {&lt;br /&gt;
    // args contains .with and .in, both of which are input objects.&lt;br /&gt;
    var msg = &#039;Replaces &amp;quot;${whatText}&amp;quot; with ${withText} in ${inText}.&#039;;&lt;br /&gt;
    var subs = {whatText: what.text, withText: mods[&amp;quot;with&amp;quot;].text, inText: mods[&amp;quot;in&amp;quot;].text};&lt;br /&gt;
    &lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, subs );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( what, mods ) {&lt;br /&gt;
    // If the scope text isn&#039;t specified, use the current selection.&lt;br /&gt;
    var text = mods[&amp;quot;in&amp;quot;].text || CmdUtils.getSelection();&lt;br /&gt;
    var newText = text.replace( what.text, mods[&amp;quot;with&amp;quot;].text, &amp;quot;i&amp;quot;);&lt;br /&gt;
    CmdUtils.setSelection( newText );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In earlier prototypes, modifier arguments could only accept a single-word value, but this has now been fixed.)&lt;br /&gt;
&lt;br /&gt;
The modifiers argument takes a dictionary, where the key is the name of the argument and the value is the noun-type of the argument. In later releases we may include further options, like the ability to specify an argument as required/optional, etc.&lt;br /&gt;
&lt;br /&gt;
The translate command is a good place to learn more about modifiers and the &amp;lt;code&amp;gt;noun_type_language&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Twitter: Putting It All Together =&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now covered everything we need to cover in order to write a command that allows us to [http://en.wikipedia.org/wiki/Twitter Twitter] from Ubiquity. Many thanks to [http://theunfocused.net/ Blair McBride] for writing this command. This is a fully functioning command: the browser takes care of the odd edge cases, like not being logged in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// max of 140 chars is recommended, but it really allows 160&lt;br /&gt;
const TWITTER_STATUS_MAXLEN = 160;&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;twitter&amp;quot;,&lt;br /&gt;
  takes: {status: noun_arb_text},&lt;br /&gt;
  &lt;br /&gt;
  homepage: &amp;quot;http://theunfocused.net/moz/ubiquity/verbs/&amp;quot;,&lt;br /&gt;
  author: {name: &amp;quot;Blair McBride&amp;quot;, homepage: &amp;quot;http://theunfocused.net/&amp;quot;},&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  preview: function(previewBlock, statusText) {&lt;br /&gt;
    var previewTemplate = &amp;quot;Updates your Twitter status to: &amp;lt;br/&amp;gt;&amp;quot; +       &lt;br /&gt;
                          &amp;quot;&amp;lt;b&amp;gt;${status}&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;quot; + &lt;br /&gt;
                          &amp;quot;Characters remaining: &amp;lt;b&amp;gt;${chars}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    var truncateTemplate = &amp;quot;&amp;lt;br /&amp;gt;The last &amp;lt;b&amp;gt;${truncate}&amp;lt;/b&amp;gt; &amp;quot; + &lt;br /&gt;
                           &amp;quot;characters will be truncated!&amp;quot;;&lt;br /&gt;
    var previewData = {&lt;br /&gt;
      status: statusText.text,&lt;br /&gt;
      chars: TWITTER_STATUS_MAXLEN - statusText.text.length&lt;br /&gt;
    };&lt;br /&gt;
      &lt;br /&gt;
    var previewHTML = CmdUtils.renderTemplate(previewTemplate,&lt;br /&gt;
                                                    previewData);&lt;br /&gt;
    &lt;br /&gt;
    if(previewData.chars &amp;lt; 0) {&lt;br /&gt;
      var truncateData = {&lt;br /&gt;
        truncate: 0 - previewData.chars&lt;br /&gt;
      };&lt;br /&gt;
      &lt;br /&gt;
      previewHTML += CmdUtils.renderTemplate(truncateTemplate,&lt;br /&gt;
                                                   truncateData);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    previewBlock.innerHTML = previewHTML;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function(statusText) {&lt;br /&gt;
    if(statusText.text.length &amp;lt; 1) {&lt;br /&gt;
      displayMessage(&amp;quot;Twitter requires a status to be entered&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var updateUrl = &amp;quot;https://twitter.com/statuses/update.json&amp;quot;;&lt;br /&gt;
    var updateParams = {&lt;br /&gt;
      source: &amp;quot;ubiquity&amp;quot;,&lt;br /&gt;
      status: statusText.text&lt;br /&gt;
    };&lt;br /&gt;
    &lt;br /&gt;
    jQuery.ajax({&lt;br /&gt;
      type: &amp;quot;POST&amp;quot;,&lt;br /&gt;
      url: updateUrl,&lt;br /&gt;
      data: updateParams,&lt;br /&gt;
      dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
      error: function() {&lt;br /&gt;
        displayMessage(&amp;quot;Twitter error - status not updated&amp;quot;);&lt;br /&gt;
      },&lt;br /&gt;
      success: function() {&lt;br /&gt;
        displayMessage(&amp;quot;Twitter status updated&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Switching Tabs =&lt;br /&gt;
&lt;br /&gt;
The final command in this tutorial is for switching between tabs. The end goal is this: type a few keys to that matches the title of an open tab (in any window), hit return, and you&#039;ve switched to that tab.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll write this command in two steps. The first step is creating a tab noun-type. The second step is using that noun-type to create the tab-switching command.&lt;br /&gt;
&lt;br /&gt;
== Switching: Writing your own Noun-Types ==&lt;br /&gt;
&lt;br /&gt;
A noun-type needs to only have two things: A name and a suggest function. Soon, we&#039;ll probably move to having a convenience &amp;lt;code&amp;gt;CmdUtils.CreateNounType()&amp;lt;/code&amp;gt;, which will simplify things even more.&lt;br /&gt;
&lt;br /&gt;
The name is what shows up when the command prompts for input. Suggest returns a list of input objects, each one containing the name of a matching tab. We&#039;re using [http://developer.mozilla.org/en/docs/FUEL FUEL] to interact with the browser, which is where the &amp;quot;Application&amp;quot; variable comes from.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_tab = {&lt;br /&gt;
  _name: &amp;quot;tab name&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  // Returns all tabs from all windows.&lt;br /&gt;
  getTabs: function(){&lt;br /&gt;
    var tabs = {};&lt;br /&gt;
&lt;br /&gt;
    for( var j=0; j &amp;lt; Application.windows.length; j++ ) {&lt;br /&gt;
      var window = Application.windows[j];&lt;br /&gt;
      for (var i = 0; i &amp;lt; window.tabs.length; i++) {&lt;br /&gt;
        var tab = window.tabs[i];&lt;br /&gt;
        tabs[tab.document.title] = tab;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return tabs;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    &lt;br /&gt;
    var suggestions  = [];&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
&lt;br /&gt;
    //TODO: implement a better match algorithm&lt;br /&gt;
    for ( var tabName in tabs ) {&lt;br /&gt;
      if (tabName.match(text, &amp;quot;i&amp;quot;))&lt;br /&gt;
	 suggestions.push( CmdUtils.makeSugg(tabName) );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Return a list of input objects, limited to at most five:&lt;br /&gt;
    return suggestions.splice(0, 5);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The suggest method of a noun type always gets passed both text and html.  If the input is coming from a part of a web page that the user has selected, these&lt;br /&gt;
values can be different: they are both strings, but the html value contains markup tags while the text value does not. The Tab noun type only cares about the plain text of the tab name, so we ignore the value of html.&lt;br /&gt;
&lt;br /&gt;
We use the convenience function &amp;lt;code&amp;gt;CmdUtils.makeSugg()&amp;lt;/code&amp;gt; to generate an&lt;br /&gt;
input object of the type that the Ubiquity parser expects.  The full signature of this function is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.makeSugg( text, html, data );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
but html and data are optional and need be provided only if they differ from text.&lt;br /&gt;
&lt;br /&gt;
If the text or html input is very long, &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; generates a summary for us, and puts it in the &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; attribute of the input object.&lt;br /&gt;
&lt;br /&gt;
We could have accomplished mostly the same thing without calling &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; by returning a list of anonymous objects like these:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ text: tabName,&lt;br /&gt;
  html: tabName,&lt;br /&gt;
  data: null,&lt;br /&gt;
  summary: tabName };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The input objects that our &amp;lt;code&amp;gt;.suggest()&amp;lt;/code&amp;gt; method generates are the same objects that will eventually get passed in to the &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; methods of any commands that use this noun type.&lt;br /&gt;
&lt;br /&gt;
== Switching Tabs: The Command ==&lt;br /&gt;
&lt;br /&gt;
Now that we are armed with the tab noun-type, it is easy to make the tab-switching command. Again, we use FUEL to focus the selected tab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;tab&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;tab name&amp;quot;: noun_type_tab},&lt;br /&gt;
&lt;br /&gt;
  execute: function( directObj ) {&lt;br /&gt;
    var tabName = directObj.text;&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
    tabs[tabName]._window.focus();&lt;br /&gt;
    tabs[tabName].focus();&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  preview: function( pblock, directObj ) {&lt;br /&gt;
    var tabName = directObj.text;&lt;br /&gt;
    if( tabName.length &amp;gt; 1 ){&lt;br /&gt;
        var msg = &amp;quot;Changes to &amp;lt;b style=\&amp;quot;color:yellow\&amp;quot;&amp;gt;%s&amp;lt;/b&amp;gt; tab.&amp;quot;;&lt;br /&gt;
        pblock.innerHTML = msg.replace(/%s/, tabName);&lt;br /&gt;
     }&lt;br /&gt;
    else&lt;br /&gt;
      pblock.innerHTML = &amp;quot;Switch to a tab by name.&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Development Hints =&lt;br /&gt;
&lt;br /&gt;
You now know all you need to know to get started developing useful Ubiquity commands of your own.&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous tips that didn&#039;t fit elsewhere on this page, that may make development easier for you.&lt;br /&gt;
&lt;br /&gt;
== The Source Code of Built-In Commands ==&lt;br /&gt;
&lt;br /&gt;
Looking at the source code of built-in commands and built-in noun types can be a very useful aid to development.  If you have the source checkout of Ubiquity (see [https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.1_Development_Tutorial the development tutorial] to find out how to get this), the source code can be found in the files and directories:&lt;br /&gt;
&lt;br /&gt;
 ubiquity/standard-feeds/&lt;br /&gt;
 ubiquity/builtin-feeds/en/builtincmds.js&lt;br /&gt;
 ubiquity/feed-parts/header/en/nountypes.js&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a checkout of the source code, you can view the latest version on the web here:&lt;br /&gt;
&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/standard-feeds/ standard-feeds]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/builtin-feeds/en/builtincmds.js builtincmds.js]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/feed-parts/header/en/nountypes.js nountypes.js]&lt;br /&gt;
&lt;br /&gt;
== Interacting with Other Extensions ==&lt;br /&gt;
&lt;br /&gt;
http://img363.imageshack.us/img363/1906/picture7cm5.png&lt;br /&gt;
&lt;br /&gt;
There isn&#039;t much to say here besides that it&#039;s easy. For example, here&#039;s a command (thanks to [http://foyrek.com/lyrics.html Abimanyu Raja] for writing this code) that finds the lyrics for a song. You can simply Ubiq something like &amp;quot;get-lyrics wild international&amp;quot; but the command will also interface with the FoxyTunes extension (if it is installed) and add the currently playing song to the suggestion list. Interfacing with other extensions, too, is easy because you can view the source code for every Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_song = {&lt;br /&gt;
  _name: &amp;quot;song name&amp;quot;,&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    var suggestions  = [CmdUtils.makeSugg(text)];&lt;br /&gt;
    if(window.foxytunesGetCurrentTrackTitle){&lt;br /&gt;
   suggestions.push(CmdUtils.makeSugg(window.foxytunesGetCurrentTrackTitle()));&lt;br /&gt;
  	}&lt;br /&gt;
    return suggestions;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;get-lyrics&amp;quot;,&lt;br /&gt;
  takes: {song: noun_type_song},&lt;br /&gt;
  preview: function(pblock, directObject) {&lt;br /&gt;
    &lt;br /&gt;
    searchText = jQuery.trim(directObject.text);&lt;br /&gt;
    if(searchText.length &amp;lt; 1) {&lt;br /&gt;
      pblock.innerHTML = &amp;quot;Searches for lyrics of the song&amp;quot;;&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var previewTemplate = &amp;quot;Searches for the lyrics of &amp;lt;b&amp;gt;${query}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    var previewData = {query: searchText};&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate(previewTemplate, previewData);&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(directObject) {&lt;br /&gt;
    var url = &amp;quot;http://www.google.com/search?q={QUERY}&amp;quot;&lt;br /&gt;
    var query = directObject.text + &amp;quot; lyrics&amp;quot;;&lt;br /&gt;
    var urlString = url.replace(&amp;quot;{QUERY}&amp;quot;, query);&lt;br /&gt;
    Utils.openUrlInBrowser(urlString);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementing Asynchronous Noun Suggestions ==&lt;br /&gt;
&lt;br /&gt;
The noun types we&#039;ve seen so far in this tutorial have all worked synchronously, returning their suggestions right away. However, Ubiquity also supports asynchronous noun suggestions. These are useful for when a noun type needs to do some potentially time-consuming work before it can make suggestions &amp;amp;mdash; most commonly when it needs to call an external service.&lt;br /&gt;
&lt;br /&gt;
Implementing asynchronous suggestions is simple. Whenever the Ubiquity parser calls a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function, it includes a callback function that may be used to send suggestions back to the parser as they become available. In the most typical case, the noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function makes an AJAX request, invoking the parser&#039;s callback function from within the callback function for the AJAX request.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example: a noun type that suggests [http://www.freebase.com/ Freebase] topics based on the text the user has typed or selected, and a barebones &amp;lt;code&amp;gt;freebase-lookup&amp;lt;/code&amp;gt; command that uses the noun type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_freebase_topic = {&lt;br /&gt;
  _name: &amp;quot;Freebase topic&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  suggest: function suggest( text, html, callback ) {&lt;br /&gt;
    jQuery.ajax( {&lt;br /&gt;
      url: &amp;quot;http://www.freebase.com/api/service/search&amp;quot;,&lt;br /&gt;
      dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
      data: { prefix: text, limit: 5 },&lt;br /&gt;
      success: function suggestTopics( response ) {&lt;br /&gt;
        var i, results, result;&lt;br /&gt;
        results = response.result;&lt;br /&gt;
        for ( i = 0; i &amp;lt; results.length; i++ ) {&lt;br /&gt;
          result = results[ i ];&lt;br /&gt;
          callback( CmdUtils.makeSugg( result.name, result.name, result ) );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    } );&lt;br /&gt;
    return [];&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
CmdUtils.CreateCommand( {&lt;br /&gt;
  name: &amp;quot;freebase-lookup&amp;quot;,&lt;br /&gt;
  takes: { topic: noun_type_freebase_topic },&lt;br /&gt;
  preview: function preview( container, topic ) {&lt;br /&gt;
    var text = topic.text || &amp;quot;any topic&amp;quot;;&lt;br /&gt;
    container.innerHTML = &amp;quot;Go to the Freebase topic page for &amp;quot; + text + &amp;quot;.&amp;quot;;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function goToFreebase( topic ) {&lt;br /&gt;
    if ( topic ) {&lt;br /&gt;
      Utils.openUrlInBrowser( &amp;quot;http://www.freebase.com/view&amp;quot; + topic.data.id );&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A few notes:&lt;br /&gt;
&lt;br /&gt;
* The parser&#039;s callback function expects only one suggestion (not an array of suggestions), so it must be called one time for each suggestion, even if the noun type has multiple suggestions available at the same time (as in the Freebase example above). This is a bit different from the synchronous case, in which the &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function is expected to return an array.&lt;br /&gt;
* A noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function typically returns an empty array when it intends to make asynchronous suggestions, but it can return one or more suggestions synchronously if it has them available.&lt;br /&gt;
* Because the work being done to generate asynchronous suggestions is generally somewhat expensive, and because a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function may be called for every keystroke the user makes, you should probably consider implementing a delay before starting the work and/or caching the work at some level. Ubiquity currently leaves this up to each noun type individually.&lt;br /&gt;
* A much more robust implementation of Freebase-derived noun types can be found [http://graynorton.com/ubiquity/freebase-nouns.html here].&lt;br /&gt;
&lt;br /&gt;
== Running on page load and startup ==&lt;br /&gt;
&lt;br /&gt;
In order to run some code on page load, you simply have to prefix your function with &amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;. For example, if you want to say &amp;quot;Hi&amp;quot; every time a page is loaded, your code would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function pageLoad_hi(){&lt;br /&gt;
 displayMessage(&amp;quot;hi&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you modify the function and want to see the changes, remember to first invoke Ubiquity. Although your function like above, might not be a Ubiquity command, this is necessary to refresh the cached code.&lt;br /&gt;
&lt;br /&gt;
Similarly, if you want to run some code everytime Firefox starts up, you just have to prefix the function with &amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
The awesome thing about these functions is the ability to develop whole Firefox extensions (that require minimal UI) as Ubiquity plugins in lesser lines of code. You don&#039;t need to worry about chrome.manifest or install.rdf. Another added benefit is that you never have to restart your Firefox during development unless of course, you are running code on Firefox startup.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;http://img388.imageshack.us/img388/3086/picture5eo9.png&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code for [http://foyrek.com/commands/keyscape.js Keyscape] which is a Ubiquity command that makes use of &amp;lt;code&amp;gt;pageLoad&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;startup&amp;lt;/code&amp;gt; to recreate the functionality of the [https://addons.mozilla.org/en-US/firefox/addon/339 Search Keys extension] by Jesse Ruderman. In line with Ubiquity&#039;s aim to let you do things quicker using your keyboard, this command lets you go to search results on Google by just pressing a number. It&#039;ll add hints to show the number of each link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//A lot of this code is borrowed from the Search Keys extension&lt;br /&gt;
//Many thanks to Jeese Ruderman&lt;br /&gt;
&lt;br /&gt;
function startup_keyscape() {&lt;br /&gt;
  window.addEventListener(&amp;quot;keydown&amp;quot;, keyscape_down, true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function pageLoad_keyscape(doc){&lt;br /&gt;
&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
  //If we are on about: or chrome://, just return&lt;br /&gt;
  if(uri.scheme != &amp;quot;http&amp;quot;)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  //Check if the page we are on is google&lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	      		    &lt;br /&gt;
    for(var num=1; num&amp;lt;=10; num++){&lt;br /&gt;
&lt;br /&gt;
      var link = jQuery(doc.body).find(&#039;a.l&#039;)[num-1];&lt;br /&gt;
      &lt;br /&gt;
      if( link ){&lt;br /&gt;
&lt;br /&gt;
        var hint = doc.createElementNS(&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;, &amp;quot;span&amp;quot;);&lt;br /&gt;
        hint.style.color = &amp;quot;blue&amp;quot;;&lt;br /&gt;
        hint.style.background = &amp;quot;white&amp;quot;;&lt;br /&gt;
        hint.style.padding = &amp;quot;1px 2px 1px 2px&amp;quot;;&lt;br /&gt;
        hint.style.marginLeft = &amp;quot;.5em&amp;quot;;&lt;br /&gt;
        hint.appendChild(doc.createTextNode(num == 10 ? 0 : num));&lt;br /&gt;
        link.parentNode.insertBefore(hint, link.nextSibling);&lt;br /&gt;
      }  		&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_isGoogle(uri){&lt;br /&gt;
  return uri.host.indexOf(&amp;quot;google&amp;quot;) != -1 &lt;br /&gt;
	 &amp;amp;&amp;amp; (uri.path.substr(0,8) == &amp;quot;/search?&amp;quot; &lt;br /&gt;
         || uri.path.substr(0,8) == &amp;quot;/custom?&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_down(event){&lt;br /&gt;
&lt;br /&gt;
  var doc =  Application.activeWindow.activeTab.document;	&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
 &lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	&lt;br /&gt;
   var key = parseInt(event.keyCode || event.charCode);	&lt;br /&gt;
   var num;&lt;br /&gt;
	&lt;br /&gt;
   if(48 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 57) //number keys&lt;br /&gt;
     num = key - 48;&lt;br /&gt;
   else if(96 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 105) //numeric keypad with numlock on&lt;br /&gt;
     num = key - 96;&lt;br /&gt;
   else&lt;br /&gt;
     return;&lt;br /&gt;
&lt;br /&gt;
   //Don&#039;t do anything if we are in a textbox&lt;br /&gt;
   //or some other related elements&lt;br /&gt;
   var elt = window.document.commandDispatcher.focusedElement;&lt;br /&gt;
   &lt;br /&gt;
   if (elt) {&lt;br /&gt;
     var ln = new String(elt.localName).toLowerCase();&lt;br /&gt;
     if (ln == &amp;quot;input&amp;quot; || ln == &amp;quot;textarea&amp;quot; || ln == &amp;quot;select&amp;quot; || ln == &amp;quot;isindex&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
   //Get the link url from the search results page&lt;br /&gt;
   var url_dest = jQuery(doc.body).find(&#039;a.l&#039;).eq(num-1).attr(&#039;href&#039;);&lt;br /&gt;
   &lt;br /&gt;
   if(event.altKey){&lt;br /&gt;
     //Open in new tab&lt;br /&gt;
     Application.activeWindow.open(Utils.url(url_dest));&lt;br /&gt;
   }else{&lt;br /&gt;
     //Open in same tab&lt;br /&gt;
     doc.location.href = url_dest;&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If Ubiquity does indeed become ubiquitous, a lot of extensions can be re-written as Ubiquity commands. This is much nicer for the end-user, as well, because the Ubiquity command installation process is a lot easier.&lt;br /&gt;
&lt;br /&gt;
In the future, Ubiquity is also likely to have the ability to convert your Ubiquity commands into proper Firefox extensions. Look [http://labs.toolness.com/trac/ticket/3 here] to check on the progress of this functionality.&lt;br /&gt;
&lt;br /&gt;
== Firebug ==&lt;br /&gt;
&lt;br /&gt;
You should enable Chrome Errors and Warnings if you want the errors in your code to appear in the Firebug console. Use CmdUtils.log() rather than console.log() &#039;&#039;Note: For now, you can only pass one argument to log()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Adding Commands Programmatically ==&lt;br /&gt;
&lt;br /&gt;
Here is a snippet of code that shows how a developer can programmatically register a command included in a Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Helper function used to determine the local directory where the&lt;br /&gt;
// extension which contains the command is installed. This is used&lt;br /&gt;
// to create the URL of the js file which includes the implementation&lt;br /&gt;
// of the list of commands you want to add.&lt;br /&gt;
function getExtensionDir() {&lt;br /&gt;
    var extMgr = Components.classes[&amp;quot;@mozilla.org/extensions/manager;1&amp;quot;]&lt;br /&gt;
                 .getService(Components.interfaces.nsIExtensionManager);&lt;br /&gt;
    return extMgr.getInstallLocation( &amp;quot;feedly@devhd&amp;quot; ).getItemLocation( &amp;quot;feedly@devhd&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function getBaseUri() {&lt;br /&gt;
    var ioSvc = Components.classes[&amp;quot;@mozilla.org/network/io-service;1&amp;quot;]&lt;br /&gt;
	                  .getService(Components.interfaces.nsIIOService);&lt;br /&gt;
    var extDir = getExtensionDir();&lt;br /&gt;
    var baseUri = ioSvc.newFileURI(extDir).spec;&lt;br /&gt;
    return baseUri;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// your extension needs to call the addUbiquity command each time a new browser&lt;br /&gt;
// session is create and your extension is loaded.&lt;br /&gt;
function addUbiquityCommands(){&lt;br /&gt;
     // url of the file which contains the implementation of the commands&lt;br /&gt;
     // we want to add. &lt;br /&gt;
     var url = getBaseUri() + &amp;quot;content/app/ubiquity/commands.js&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
     // link to the ubiquity setup module.&lt;br /&gt;
     var jsm = {}; &lt;br /&gt;
     Components.utils.import(&amp;quot;resource://ubiquity/modules/setup.js&amp;quot;, jsm); &lt;br /&gt;
		&lt;br /&gt;
     // look up the feed manager and add a new command. Note: we are using the&lt;br /&gt;
     // isBuiltIn=true option so that the command is only added for the duration&lt;br /&gt;
     // of the browser session. This simplifies the overall lifecycle: if the&lt;br /&gt;
     // extension is disabled or un-installed, it will be automatically&lt;br /&gt;
     // &amp;quot;removed&amp;quot; from ubiquity.&lt;br /&gt;
     jsm.UbiquitySetup.createServices().feedManager.addSubscribedFeed( {&lt;br /&gt;
	url: url,&lt;br /&gt;
        sourceUrl: url,&lt;br /&gt;
        canAutoUpdate: true,&lt;br /&gt;
        isBuiltIn: true&lt;br /&gt;
     });&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your command implementation, you can use importing modules or looking up a singleton XPCOM component to link your command back to the functionality encapsulated by your extension. Here is a sample command which does that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var StreetsUtils = function(){&lt;br /&gt;
    var that = {};&lt;br /&gt;
    that.lookupCore = function(){&lt;br /&gt;
        return Components.classes[&amp;quot;@devhd.com/feedly-boot;1&amp;quot;]&lt;br /&gt;
				.getService(Components.interfaces.nsIFeedlyBoot)&lt;br /&gt;
				.wrappedJSObject&lt;br /&gt;
				.lookupCore();&lt;br /&gt;
    };&lt;br /&gt;
    return that;&lt;br /&gt;
}();&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;my-extension-test&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;message&amp;quot;: noun_arb_text},&lt;br /&gt;
  icon: &amp;quot;chrome://my-extension-test/skin/icon-16x16.png&amp;quot;,&lt;br /&gt;
  modifiers: {to: noun_type_contact},&lt;br /&gt;
  description:&amp;quot;Testing the feedly+ubiquity integration&amp;quot;,&lt;br /&gt;
  help:&amp;quot;This is a test help message&amp;quot;,&lt;br /&gt;
  preview: function(pblock, directObj, modifiers) {&lt;br /&gt;
    var html = &amp;quot;Testing my-extension-test &amp;quot;;&lt;br /&gt;
    if (modifiers.to) {&lt;br /&gt;
      html += &amp;quot;to &amp;quot; + modifiers.to.text + &amp;quot; &amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if (directObj.html) {&lt;br /&gt;
      html += &amp;quot;with these contents:&amp;quot; + directObj.html;&lt;br /&gt;
    } else {&lt;br /&gt;
      html += &amp;quot;with a link to the current page.&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    pblock.innerHTML = html;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  execute: function(directObj, headers) {&lt;br /&gt;
      CmdUtils.log( &amp;quot;&amp;gt;&amp;gt;&amp;gt; my-extension core? &amp;quot; + ( StreetsUtils.lookupCore() != null ) );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you command file needs to include/load other JS files included in your extension, you can use the following piece of code at the top of the command js file you are adding to ubiquity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function include( partialURI )&lt;br /&gt;
{&lt;br /&gt;
    // Load JS libraries&lt;br /&gt;
    var u = &amp;quot;chrome://feedly/content/app/&amp;quot; + partialURI;&lt;br /&gt;
    var jsl = Cc[&amp;quot;@mozilla.org/moz/jssubscript-loader;1&amp;quot;]&lt;br /&gt;
			.getService(Ci.mozIJSSubScriptLoader);  &lt;br /&gt;
		&lt;br /&gt;
    jsl.loadSubScript( u );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
include( &amp;quot;ubiquity/templates.ubiquity.js&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Conclusion =&lt;br /&gt;
&lt;br /&gt;
To reiterate a point I made before: Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web. You are one of those agents.&lt;br /&gt;
&lt;br /&gt;
Now, go forth and create.&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial&amp;diff=124805</id>
		<title>Labs/Ubiquity/Ubiquity 0.1 Author Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial&amp;diff=124805"/>
		<updated>2009-01-21T04:38:37Z</updated>

		<summary type="html">&lt;p&gt;Endolith: /* Just a Function: As Simple as it Gets */ notifications work in Intrepid, too&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs/Ubiquity]].&lt;br /&gt;
&lt;br /&gt;
Author: Aza Raskin, Blair McBride, Abimanyu Raja, Jono DiCarlo, Atul Varma&lt;br /&gt;
&lt;br /&gt;
== In other languages ==&lt;br /&gt;
&lt;br /&gt;
* [[zh-CN:Ubiquity 0.1 Author Tutoria|简体中文l]]&lt;br /&gt;
* [[ja:Ubiquity 0.1.2 User Tutorial|日本語で]] &lt;br /&gt;
* [[es:Ubiquity 0.1.2 User Tutorial|En español]]&lt;br /&gt;
* [[mr:Ubiquity 0.1.2 User Tutorial|Mr मराठी (Marathi)]]&lt;br /&gt;
* [[Labs/Ubiquity/hi:Ubiquity 0.1.2 User Tutorial|Hi हिंदी (Hindi)]]&lt;br /&gt;
&lt;br /&gt;
If English isn&#039;t your first language feel free to read the tutorial in your own language. If it doesn&#039;t exists, feel free to jump in and translate.&lt;br /&gt;
&lt;br /&gt;
= The Ubiquity 0.1 Command Tutorial =&lt;br /&gt;
&lt;br /&gt;
The great power of Ubiquity&amp;amp;mdash;from a developer standpoint&amp;amp;mdash;is how easy it is to create commands. With only a couple of lines of Javascript, Ubiquity enables even casual web developers to drastically enhance the features of the browser. From an 8-line command to insert a contact&#039;s email address in any text field, to a 50-line Twitter integration, this tutorial walks you through the process of being generative with Ubiquity.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING&#039;&#039;&#039;: Ubiquity is still in flux. This is a 0.1 release. The API is  likely to change drastically in later revisions. While this means that what you write today might not work next week, it also means that by writing commands and giving us [[Labs/Ubiquity#Participation|your feedback]], you&#039;ll be able to directly influence the direction that Ubiquity goes.&lt;br /&gt;
&lt;br /&gt;
The rest of this page documents the command developer API as it currently stands in the latest released version of Ubiquity, 0.1.1.  However, if you have the latest source checkout, then you&#039;ll have a newer API with some additional features not in 0.1.1.  You can read about the latest and greatest source-tip API on [[Labs/Ubiquity/Ubiquity Source Tip Author Tutorial|Ubiquity Source Tip Author Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Real Time Development ==&lt;br /&gt;
&lt;br /&gt;
Ubiquity doesn&#039;t require you to restart Firefox as you develop. That&#039;s a barbaric act, and we want none of it. Instead, Ubiquity reloads the commands every time it is summoned. When you are using the built-in editor then you don&#039;t even need to save!&lt;br /&gt;
&lt;br /&gt;
To open the Ubiquity command editor, summon Ubiquity (control/alt + space) and use the &amp;quot;command-editor&amp;quot; command. Throughout this tutorial, when we want you to run a command in Ubiquity, we&#039;ll say &#039;&#039;&#039;Ubiq&#039;&#039;&#039; it. For instance, to open the editor, just Ubiq &amp;quot;command-editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In the following examples, just type in this editor. Updates happen the next time you summon Ubiquity.&lt;br /&gt;
&lt;br /&gt;
= Hello World: The First Command =&lt;br /&gt;
&lt;br /&gt;
== Just a Function: As Simple as it Gets ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s start with the standard programing trope: printing &amp;quot;Hello, World!&amp;quot;. In Ubiquity, commands are simply functions with various attributes tacked on. We&#039;ll start by manually making a function to define a command, but we&#039;ll quickly move to using a more elegant method.&lt;br /&gt;
&lt;br /&gt;
In the command editor type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function cmd_hello_world() {&lt;br /&gt;
  displayMessage( &amp;quot;Hello, World!&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now try Ubiq-ing &amp;quot;hello-world&amp;quot;. You&#039;ll see that &amp;quot;Hello, World!&amp;quot; is immediatly displayed on the screen. If you are on Mac OSX with [http://en.wikipedia.org/wiki/Growl_(software) Growl] installed the message will appear as a Growl notification. If you are on Windows, then it will appears as a standard &amp;quot;toaster&amp;quot; notification in the bottom right-hand corner of the screen.&lt;br /&gt;
&lt;br /&gt;
http://img367.imageshack.us/img367/7051/picture1ui2.png&lt;br /&gt;
&lt;br /&gt;
http://img517.imageshack.us/img517/7726/picture2vx2.png&lt;br /&gt;
&lt;br /&gt;
In Ubuntu 8.04 (Hardy Heron) this appears thus:&lt;br /&gt;
&lt;br /&gt;
http://img293.imageshack.us/img293/7746/ubiqubuntuhelloworldeq9.png&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have Growl installed on OSX, or aren&#039;t on a Windows XP/Vista or Ubuntu Hardy/Intrepid, then you won&#039;t get any sort of notification. That&#039;s something to be [http://labs.toolness.com/trac/ticket/19 worked on] in future released of Ubiquity.&lt;br /&gt;
&lt;br /&gt;
There&#039;s not much in this command, so let&#039;s dive straight in. Any function that starts with &amp;lt;code&amp;gt;cmd_&amp;lt;/code&amp;gt; automatically becomes a Ubiquity command. It&#039;s a little bit of namespace magic that makes development super-simple.&lt;br /&gt;
&lt;br /&gt;
There are other prefixes that have other effects, like running code on page load (&amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;), and startup (&amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt;), but that&#039;s for a different tutorial.&lt;br /&gt;
&lt;br /&gt;
Back to the example. The meat of the command is in the function &amp;lt;code&amp;gt;displayMessage()&amp;lt;/code&amp;gt;, which displays the message in whichever way the operating system can.&lt;br /&gt;
&lt;br /&gt;
You may be wondering why there is a hyphen in the name, instead of a space. That&#039;s because the Ubiquity natural language parser isn&#039;t yet smart enough to handle commands that are multiple words &amp;lt;i&amp;gt;and&amp;lt;/i&amp;gt; arguments that are multiple words. It&#039;s something we&#039;ll be working on in the future.&lt;br /&gt;
&lt;br /&gt;
== Using CreateCommand ==&lt;br /&gt;
&lt;br /&gt;
For commands that are more complicated than our simple &amp;quot;hello-world&amp;quot; command, you can use the helper function &amp;lt;code&amp;gt;CmdUtils.CreateCommand()&amp;lt;/code&amp;gt;, which takes an options dictionary. To redo the &amp;quot;hello-world&amp;quot; command using the convenience function, we&#039;d write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;hello-world&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may not seem to be much of a win (and it isn&#039;t for simple commands) but as the commands become more complex, you&#039;ll see that it helps a lot. For one, you can name the command more freely with the method&amp;amp;mdash;unicode non-English characters are now fair game.&lt;br /&gt;
&lt;br /&gt;
There are a number of other useful functions in the CmdUtils namespace. We don&#039;t yet have full documentation for these commands, but you&#039;ll get a sense of the useful ones in this tutorial. For more detailed information, take a look at [http://hg.toolness.com/ubiquity-firefox/file/9a6c9935da9f/ubiquity/chrome/content/cmdutils.js cmdutils.js].&lt;br /&gt;
&lt;br /&gt;
== Adding a Preview ==&lt;br /&gt;
&lt;br /&gt;
http://img352.imageshack.us/img352/1002/picture3ex0.png&lt;br /&gt;
&lt;br /&gt;
Let&#039;s add a preview to our new command. Previews give the user feedback about what a command does before it&#039;s executed. Previews are great for providing rich visual feedback like displaying a graphical representation of atmospheric conditions when using the weather command as shown above. Previews have the full expressive power of HTML, including animations, so there&#039;s a lot you can do with them.&lt;br /&gt;
&lt;br /&gt;
One point of design: Preview code should never have side-effects. That is, a preview should never (without user interaction) change the state of the system.&lt;br /&gt;
&lt;br /&gt;
For the &amp;quot;hello-world&amp;quot; command, we don&#039;t need anything fancy: just some help text that is more descriptive than the default &amp;quot;Executes the hello-world command.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;hello-world&amp;quot;,&lt;br /&gt;
  preview: &amp;quot;Displays a &amp;lt;i&amp;gt;salutary&amp;lt;/i&amp;gt; greeting to the planet.&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    displayMessage( &amp;quot;Hello, World!&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the preview is an HTML-formatted string. The preview can also be a function. We&#039;ll get to that in the next section.&lt;br /&gt;
&lt;br /&gt;
= The Date Command: The Second Command =&lt;br /&gt;
&lt;br /&gt;
= Setting the Selection =&lt;br /&gt;
&lt;br /&gt;
I often forget what day it is. That may be because I need to go outside more often, but, like any programmer, I generally solve my problem&#039;s symptoms with technology rather then addressing the root cause. My solution is to create a command that inserts the date at the location of the cursor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  execute: function() {&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    CmdUtils.setSelection( date.toLocaleDateString() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new function here is &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt;. This inserts the passed-in text onto the page at the location of the cursor. If the cursor is in an editable text or rich-text fields, the text gets dumped there. If the cursor isn&#039;t in an editable area, &amp;lt;code&amp;gt;setSelection()&amp;lt;/code&amp;gt; will still be able to insert the date. (Even when it isn&#039;t displayed, Firefox always keeps track of a cursor position. To see it, type F7.) Try going to a page, selecting some non-mutable text, and using the command. See, it works! This is particularly useful for commands like &amp;quot;translate&amp;quot;, where you want to replace non-editable text with its translation.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;toLocalDateString()&amp;lt;/code&amp;gt; function is native to Javascript, so if you&#039;re not familiar with it check out the documentation for the Javascript [http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date Date object].&lt;br /&gt;
&lt;br /&gt;
== A Better Preview ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s time to add a better preview to the date command. Let&#039;s have the preview show the date, so that the user will know what to expect when they execute the command. (As a side benefit the user doesn&#039;t even need to execute the command to do a quick check of the day.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  _date: function(){&lt;br /&gt;
    var date = new Date();&lt;br /&gt;
    return date.toLocaleDateString();&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &#039;Inserts todays date: &amp;quot;&amp;lt;i&amp;gt;${date}&amp;lt;/i&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, {date: this._date()} );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function() {&lt;br /&gt;
    CmdUtils.setSelection( this._date() );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We&#039;ve done two things here. The first was to factor out the code for getting the date into the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt; function. This way we don&#039;t break [http://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY] by repeating code across the preview and execute functions. Notice that to access the &amp;lt;code&amp;gt;_date()&amp;lt;/code&amp;gt;, we use the &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
&lt;br /&gt;
The second thing we&#039;ve done is to add a preview function. The first argument is the DOM element that gets displayed as the preview for your command. Modify &amp;lt;code&amp;gt;pblock&amp;lt;/code&amp;gt; and you modify the preview. In this case, we set the &amp;lt;code&amp;gt;innerHTML&amp;lt;/code&amp;gt; of the preview block to be the message we want.&lt;br /&gt;
&lt;br /&gt;
The other thing I&#039;ve done is to do some string formatting using the &amp;lt;code&amp;gt;renderTemplate()&amp;lt;/code&amp;gt; function. This takes a template string and performs the appropriate substitution given the passed-in JSON object. Templates can handle a wide range of functionality, as we are currently using TrimPath&#039;s [http://code.google.com/p/trimpath/wiki/JavaScriptTemplates JavascriptTemplates]. You should read their site for more documentation. Although JavascriptTemplates has some nice properties, we are contemplating moving to [http://mjtemplate.org/ MJT] sometime soon.&lt;br /&gt;
&lt;br /&gt;
Previews display something meaningful to the user immediately. If you have a preview that requires an AJAX request&amp;amp;mdash;say, to fetch some search results&amp;amp;mdash;that call might take a while to return. In the meantime, your command should display a placeholder preview giving the user feedback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    pblock.innerHTML = &amp;quot;This will show until the AJAX request returns&amp;quot;;&lt;br /&gt;
    // AJAX request&lt;br /&gt;
    pblock.innerHTML = getFromServer();&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the future, we may work on streamlining this process.&lt;br /&gt;
&lt;br /&gt;
== Documentation and Metadata ==&lt;br /&gt;
&lt;br /&gt;
Before you share your command with the world, you should consider adding some attributions to the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you should &amp;lt;em&amp;gt;definitely&amp;lt;/em&amp;gt; add some documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;date&amp;quot;,&lt;br /&gt;
  homepage: &amp;quot;http://azarask.in/&amp;quot;,&lt;br /&gt;
  author: { name: &amp;quot;Aza Raskin&amp;quot;, email: &amp;quot;aza@mozilla.com&amp;quot;},&lt;br /&gt;
  contributors: [&amp;quot;Atul Varma&amp;quot;],&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Inserts today&#039;s date.&amp;quot;,&lt;br /&gt;
  help: &amp;quot;If you&#039;re in an editable text area, inserts today&#039;s date, formatted for the current locale.&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  /* THE REST OF THE CODE HERE */&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;.description&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.help&amp;lt;/code&amp;gt; attributes are both automatically displayed alongside your command&#039;s name on the command-list page.  (The user can get to this page at any time by issuing the &amp;quot;command-list&amp;quot; command.)  HTML tags can be used in both of these strings.&lt;br /&gt;
&lt;br /&gt;
Description is a one-line summary of what the command does, while Help is a longer description that can include examples, caveats, and so on. If your command is simple enough that all you have to say about it fits in one line, it&#039;s OK to use a description alone and leave out the help.&lt;br /&gt;
&lt;br /&gt;
== Sharing it with the World ==&lt;br /&gt;
&lt;br /&gt;
Now that we&#039;ve got our awesome new &amp;quot;date&amp;quot; command, let&#039;s share it with the world. All you have to do is put it the javascript file on the web somewhere, and make an html page linking to it with &amp;quot;link rel&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;pre&amp;gt;&amp;lt;link rel=&amp;quot;commands&amp;quot; href=&amp;quot;http://path-to-js&amp;quot; name=&amp;quot;Title Goes Here&amp;quot; /&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: your webserver must serve .js files as &#039;application/x-javascript&#039;. The mime-type &#039;text/javascript&#039; is silently ignored.&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Anyone with Ubiquity who visits will get a message offering them the choice of subscribing to your command.&lt;br /&gt;
&lt;br /&gt;
[[Image:Subscribe.png]]&lt;br /&gt;
&lt;br /&gt;
If the user chooses to subscribe to a command from an untrusted source, they will get a security warning message before they can install the command.  (And in Ubiquity 0.1, ALL sources are considered untrusted, so don&#039;t take it personally!)  Because Ubiquity commands can execute arbitrary javascript with chrome privileges, subscribing to a command from a website means allowing that site full access to do whatever it wants to your browser.  We want to make sure people understand the dangers before subscribing to commands, so we made the warning page pretty scary.&lt;br /&gt;
&lt;br /&gt;
[[Image:Warning.PNG]]&lt;br /&gt;
&lt;br /&gt;
In the future, we&#039;re going to have something set up that we call a &amp;quot;trust network&amp;quot;.  When you try out a Ubiquity command from a website, and determine that the command is safe (or unsafe), you&#039;ll be able to leave an approval (or a warning).  When your friends with Ubiquity installed visit the same site, they&#039;ll see the approval or the warning that you left.  In this way, users will be able to rely on the judgement of other people they already know and trust in order to help them make decisions about whether a command is safe to install or not.&lt;br /&gt;
&lt;br /&gt;
By the way, the reason we call it &amp;quot;subscribing&amp;quot; to a command, rather than &amp;quot;installing&amp;quot; a command, is that if the javascript file changes -- if the site owner adds new commands, removes old commands, or updates existing commands -- all users subscribed to that URL will automatically get the updates.  This will be very convenient for both users and developers, but it will also introduce another type of security risk: just because you decided a command was safe at one point in time doesn&#039;t mean that the command will always remain safe.  For this reason, we&#039;ll need to make sure that the trust network keeps track of when commands have been modified, and notifies users of changes that may make a command unsafe.&lt;br /&gt;
&lt;br /&gt;
== Map Me! Location, Snapshots, and Inserting HTML ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;map&amp;quot; command that comes with Ubiquity is fairly powerful. It&#039;s also fairly complicated&amp;amp;mdash;well, comparatively. It&#039;s still only a couple hundred lines of code. The command, though, can get even more useful. Imagine being able to select some houses on Craigslist, or a list of restaurant names, and Ubiq &amp;quot;map these&amp;quot; to get just the map you want. The concept of &amp;quot;these&amp;quot; puts the power of mashups into the users hands. But I digress. Let&#039;s make a simple command that inserts a map of your current location.&lt;br /&gt;
&lt;br /&gt;
In this command, we use the Google [http://code.google.com/apis/maps/documentation/staticmaps/ static map API] and the Ubiquity function &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; to insert a map of your current location. Ubiquity currently uses the [http://www.maxmind.com/app/api MaxMind] API for trying to guess your location from your IP. That will probably change in the future.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;map-me&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  _getMapUrl: function() {&lt;br /&gt;
    var loc = CmdUtils.getGeoLocation();&lt;br /&gt;
    var mapUrl = &amp;quot;http://maps.google.com/staticmap?&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    var params = {&lt;br /&gt;
      center: loc.lat + &amp;quot;,&amp;quot; + loc.long,&lt;br /&gt;
      size: &amp;quot;500x400&amp;quot;,&lt;br /&gt;
      zoom: 14,&lt;br /&gt;
      key: &amp;quot;ABQIAAAAGZ11mh1LzgQ8-8LRW3wEShQeSuJunOpTb3RsLsk00-MAdzxmXhQoiCd940lo0KlfQM5PeNYEPLW-3w&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    return mapUrl + jQuery.param( params );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock ) {&lt;br /&gt;
    var msg = &amp;quot;Inserts a map of your current location: &amp;lt;br/&amp;gt;&amp;quot;;&lt;br /&gt;
    msg += &amp;quot;&amp;lt;img src=&#039;%s&#039;/&amp;gt;&amp;quot;.replace( /%s/, this._getMapUrl() );&lt;br /&gt;
    pblock.innerHTML = msg;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( ) {&lt;br /&gt;
    CmdUtils.getImageSnapshot( this._getMapUrl(), function(imgData) {&lt;br /&gt;
      CmdUtils.setSelection( &amp;quot;&amp;lt;img src=&#039;&amp;quot; + imgData +&amp;quot;&#039;/&amp;gt;&amp;quot;);&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are three new things here: &amp;lt;code&amp;gt;CmdUtils.setSelection&amp;lt;/code&amp;gt; to set HTML (yep, it can do that); the use of &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt;; and using &amp;lt;code&amp;gt;CmdUtils.getImageSnapshot()&amp;lt;/code&amp;gt; to capture the bits for the image.&lt;br /&gt;
&lt;br /&gt;
I find getting the location&amp;amp;mdash;as imprecise as IP-based location can be&amp;amp;mdash;useful for doing sensible defaults for location-based commands, like Yelp. &amp;lt;code&amp;gt;CmdUtils.getGeoLocation()&amp;lt;/code&amp;gt; returns an object which has the following properties: city, state, country, lat, and long.&lt;br /&gt;
&lt;br /&gt;
Why do we need to use &amp;lt;code&amp;gt;CmdUtils.getImageSnapshot()&amp;lt;/code&amp;gt;? Because the Google Maps API requires a key that is tied to a particular URL. If we naively inject the image tag into a random web page, the image won&#039;t load because the key doesn&#039;t match that random web page&#039;s URL. Thus, we use the &amp;lt;code&amp;gt;snapshotImage()&amp;lt;/code&amp;gt; function to convert the image into a [http://en.wikipedia.org/wiki/Data:_URI_scheme data url].&lt;br /&gt;
&lt;br /&gt;
There&#039;s also a &amp;lt;code&amp;gt;CmdUtils.getWindowSnapshot()&amp;lt;/code&amp;gt; function, which allows you to get the image data for any tab/window. The function takes a window as the first paramater, and a callback for the second.&lt;br /&gt;
&lt;br /&gt;
= Commands with Arguments =&lt;br /&gt;
&lt;br /&gt;
== Echo ==&lt;br /&gt;
&lt;br /&gt;
We&#039;ll be working towards making some fun and useful commands&amp;amp;mdash;commands that let you control the seething tendrils of the internet with your little pinky. But, let&#039;s start by making a simple command to echo back whatever you type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;echo&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;your shout&amp;quot;: noun_arb_text},&lt;br /&gt;
  preview: function( pblock, theShout ) {&lt;br /&gt;
    pblock.innerHTML = &amp;quot;Will echo: &amp;quot; + theShout.text;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function( theShout ) {&lt;br /&gt;
    var msg = theShout.text + &amp;quot;... &amp;quot; + theShout.text + &amp;quot;......&amp;quot;;&lt;br /&gt;
    displayMessage( msg );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This says that the command &amp;quot;echo&amp;quot; takes one argument which is arbitrary text. Whatever text the user enters will get wrapped in an input object and passed into both the preview and execute function.&lt;br /&gt;
&lt;br /&gt;
Ubiquity takes care of parsing the user&#039;s input, so you don&#039;t need to worry about handling prounoun substitution or any of the other natural-language-like features of the Ubiquity parser. Try selecting some text on a page, and Ubiq &amp;quot;echo this&amp;quot;. Ubiquity should now echo the selected text.&lt;br /&gt;
&lt;br /&gt;
=== The Input Object ===&lt;br /&gt;
&lt;br /&gt;
The input object that your execute and preview functions receive has the following attributes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  inputObject.text  // a string of the input in plain text, without formatting&lt;br /&gt;
  inputObject.html  // a string of the input in formatted html, including tags&lt;br /&gt;
  inputObject.data  // for non-text input types, an arbitrary data object&lt;br /&gt;
  inputObject.summary // for very long inputs, an abbreviated display string&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our example command only cares about the &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; attribute of the input, because it simply wants plain text.  Often, when the user invokes your command by typing a few short words into the input box, &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;.html&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; will all have exactly the same value, and &amp;lt;code&amp;gt;.data&amp;lt;/code&amp;gt; will be null.  Many, if not most, commands that you write will only care about the text value.  Nevertheless, the other versions of the input data are provided to you in case they differ from &amp;lt;code&amp;gt;.text&amp;lt;/code&amp;gt; and in case your command has a use for them.&lt;br /&gt;
&lt;br /&gt;
=== Introduction to Noun Types ===&lt;br /&gt;
&lt;br /&gt;
Notice that we specified the type of argument to expect by passing in an object &amp;amp;mdash; in this case, the predefined &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; object, which accepts any arbitrary text as a valid argument.  If we had wanted to restrict the inputs that our command could take, we could have used a more specific noun-type object to restrict the scope of the argument: for instance, &amp;lt;code&amp;gt;noun_type_date&amp;lt;/code&amp;gt; to accept only dates (like the &amp;quot;check-calendar&amp;quot; command) or &amp;lt;code&amp;gt;noun_type_language&amp;lt;/code&amp;gt; to accept only names of languages (like the optional modifiers for the &amp;quot;translate&amp;quot; command).&lt;br /&gt;
&lt;br /&gt;
The benefit of specifying a more restrictive noun-type is that it helps the Ubiquity parser generate better suggestions and auto-completions based on user-input.  For instance, if the user has a date selected, commands that operate specifically on dates are more likely to be apropos than commands that take arbitrary text, so Ubiquity can suggest the date-specific commands first.&lt;br /&gt;
&lt;br /&gt;
There are many types of nouns that a command could conceivably take: people, dates, places, tabs, etc. Many of these noun-types aren&#039;t implemented yet, and most of the them currently have a lack-luster implementation. This is one of the areas where Ubiquity could use the greatest help. Noun-types enable creating compelling user experiences, with minimal amounts of code. It also allows for code-reuse across numerous commands.&lt;br /&gt;
&lt;br /&gt;
Once you are familiar with writing commands, you should check out the [http://hg.toolness.com/ubiquity-firefox/file/6caa9d66b3bb/ubiquity/chrome/content/nlparser/en/nountypes.js nountypes.js], which has the implementation for most of the noun-types.  You can see what noun types are already available for your commands to use, what still needs to be written, and where the existing implementations could use improvement &amp;amp;mdash; and then come [[Labs/Ubiquity#Participation|get involved]] to help us improve them.&lt;br /&gt;
&lt;br /&gt;
== Insert Email: Commands with Specific Argument Types ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s take a look at one of the special noun-types: &amp;lt;code&amp;gt;noun_type_contact&amp;lt;/code&amp;gt;. This lets Ubiquity know to expect a person (either by name or email address). By using the noun-type, Ubiquity will also autocomplete to known people while the user is entering the command. This is what the built-in Ubiquity command &amp;quot;email&amp;quot; uses.&lt;br /&gt;
&lt;br /&gt;
At the moment, Ubiquity figures out what people you know through reading your Gmail contacts. In this prototyped version, you&#039;ll need to use Gmail and be logged in for for Ubiquity to know who you know. Eventually, we&#039;d like to be able to interface with all major web-mail sites, as well as desktop software like Thunderbird.&lt;br /&gt;
&lt;br /&gt;
Enough rambling. It&#039;s time for a command. I constantly find that I need to fetch someone&#039;s email address to paste into a text field because I don&#039;t know it off-hand. This command solves that by letting you insert someone&#039;s email address using autocomplete.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;insert-email&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;person&amp;quot;: noun_type_contact},&lt;br /&gt;
  preview: &amp;quot;Inserts someone&#039;s email address by name.&amp;quot;,&lt;br /&gt;
  execute: function( email ) {&lt;br /&gt;
    CmdUtils.setSelection( email.text );&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This one command sums up what I love about Ubiquity. In 8 lines of code, I can fundamentally enhance the browser&#039;s functionality. Doing the same thing using a normal Firefox extension methodology takes pages and pages of code&amp;amp;mdash;and the interface would take more thought still. Doing the same thing using a bookmarklet would require a server-side component (to get around cross-site Ajax request ban) as well as forcing the user to give up their email password.&lt;br /&gt;
&lt;br /&gt;
Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web.&lt;br /&gt;
&lt;br /&gt;
== TinyURL: Network Calls and jQuery ==&lt;br /&gt;
&lt;br /&gt;
Often while writing emails, I&#039;ll discover that I&#039;ve pasted in a URL long enough to be used for unfortunate analogies. I&#039;d like to be able to quickly turn that into a [http://en.wikipedia.org/wiki/Tinyurl TinyURL]&amp;amp;mdash;but the process of making a TinyURL involves lots of fiddly steps. Ubiquity to the rescue.&lt;br /&gt;
&lt;br /&gt;
Because we include [http://en.wikipedia.org/wiki/jQuery jQuery] with Ubiquity, it is simple to perform Ajax calls as well as parse returning data. TinyUrl.com provides an easy to use RESTful API where you pass a URL and it returns its shortened form. We use that API in this command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;tinyurl&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;url to shorten&amp;quot;: noun_arb_text},&lt;br /&gt;
  preview: &amp;quot;Replaces the selected URL with a TinyUrl.&amp;quot;,&lt;br /&gt;
  execute: function( urlToShorten ) {&lt;br /&gt;
    var baseUrl = &amp;quot;http://tinyurl.com/api-create.php&amp;quot;;&lt;br /&gt;
    var params = {url: urlToShorten.text};&lt;br /&gt;
    jQuery.get( baseUrl, params, function( tinyUrl ) {&lt;br /&gt;
      CmdUtils.setSelection( tinyUrl );&lt;br /&gt;
    })&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although I used the &amp;lt;code&amp;gt;noun_arb_text&amp;lt;/code&amp;gt; command noun-type, I should have used the &amp;lt;code&amp;gt;noun_type_url&amp;lt;/code&amp;gt;&amp;amp;mdash;if such a thing existed. It doesn&#039;t yet.&lt;br /&gt;
&lt;br /&gt;
jQuery is a powerful tool. With it, you can fairly effortlessly cherry-pick the data you need from RSS feeds, XML, and all sorts of other data formats. It also makes doing in-preview animations a breeze.&lt;br /&gt;
&lt;br /&gt;
== Color: Creating Bounded Noun Types ==&lt;br /&gt;
&lt;br /&gt;
Suppose you&#039;re writing a set of commands for artists and&lt;br /&gt;
web designers, and you know that several of the commands will operate&lt;br /&gt;
on colors.  You&#039;d like to be able to specify that certain commands&lt;br /&gt;
expect names of colors as arguments.  Since there are a finite number of&lt;br /&gt;
named colors, you can define a custom noun type for them based on a list&lt;br /&gt;
of strings, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
noun_type_color = new CmdUtils.NounType( &amp;quot;Color&amp;quot;,&lt;br /&gt;
  [&amp;quot;red&amp;quot;, &amp;quot;orange&amp;quot;, &amp;quot;yellow&amp;quot;, &amp;quot;green&amp;quot;, &amp;quot;blue&amp;quot;, &amp;quot;violet&amp;quot;, &amp;quot;black&amp;quot;, &amp;quot;white&amp;quot;,&lt;br /&gt;
   &amp;quot;grey&amp;quot;, &amp;quot;brown&amp;quot;, &amp;quot;beige&amp;quot;, &amp;quot;magenta&amp;quot;, &amp;quot;cerulean&amp;quot;, &amp;quot;puce&amp;quot;] // etc...&lt;br /&gt;
  );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we gave the new object a name starting with &amp;quot;&amp;lt;code&amp;gt;noun_&amp;lt;/code&amp;gt;&amp;quot;.&lt;br /&gt;
The Ubiquity command loader automatically detects objects starting with&lt;br /&gt;
&amp;quot;&amp;lt;code&amp;gt;noun_&amp;lt;/code&amp;gt;&amp;quot; as custom noun-types, in the same way as it auto-detects&lt;br /&gt;
functions starting with &amp;quot;&amp;lt;code&amp;gt;cmd_&amp;lt;/code&amp;gt;&amp;quot; as custom commands.&lt;br /&gt;
&lt;br /&gt;
Once you&#039;ve defined a custom noun-type, you can use it in as many commands&lt;br /&gt;
as you like, thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;get-color-code&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;color&amp;quot;: noun_type_color},&lt;br /&gt;
  preview: &amp;quot;Inserts the HTML hex-code for the given color.&amp;quot;,&lt;br /&gt;
  // etc...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One benefit of creating the custom color noun-type is that if the user&lt;br /&gt;
has entered &amp;quot;get-color bl&amp;quot;, for instance, Ubiquity will be able to suggest&lt;br /&gt;
&amp;quot;black&amp;quot; and &amp;quot;blue&amp;quot; as the two valid completions based on the input.&lt;br /&gt;
&lt;br /&gt;
Of course, not every type of noun you&#039;d be interested in can be represented&lt;br /&gt;
as a finite list.  If you want to be able to accept or reject input based&lt;br /&gt;
on some algorithmic test, you can do so by creating your own noun-type&lt;br /&gt;
implementation instead of instantiating &amp;lt;code&amp;gt;CmdUtils.NounType&amp;lt;/code&amp;gt;.  There is an example of this in the section on the tab commands, below.&lt;br /&gt;
&lt;br /&gt;
== Replace: Commands With Multiple Arguments ==&lt;br /&gt;
&lt;br /&gt;
Commands, like the translate command, can take multiple (and possibly optional) arguments. Ubiquity takes care of the parsing&amp;amp;mdash;you don&#039;t have to worry about what order the user types them in, you&#039;ll just get passed a dictionary with the appropriate entries.&lt;br /&gt;
&lt;br /&gt;
To illustrate that, let&#039;s make a simple regular-expression-based &amp;quot;replace&amp;quot; command. It will take three arguments: the thing to replace, the replacement, and the scope-text to do the replacing in. Here&#039;s the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;replace&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;what&amp;quot;: noun_arb_text},&lt;br /&gt;
  modifiers: {&amp;quot;with&amp;quot;: noun_arb_text, &amp;quot;in&amp;quot;: noun_arb_text},&lt;br /&gt;
  &lt;br /&gt;
  preview: function( pblock, what, mods ) {&lt;br /&gt;
    // args contains .with and .in, both of which are input objects.&lt;br /&gt;
    var msg = &#039;Replaces &amp;quot;${whatText}&amp;quot; with ${withText} in ${inText}.&#039;;&lt;br /&gt;
    var subs = {whatText: what.text, withText: mods[&amp;quot;with&amp;quot;].text, inText: mods[&amp;quot;in&amp;quot;].text};&lt;br /&gt;
    &lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate( msg, subs );&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function( what, mods ) {&lt;br /&gt;
    // If the scope text isn&#039;t specified, use the current selection.&lt;br /&gt;
    var text = mods[&amp;quot;in&amp;quot;].text || CmdUtils.getSelection();&lt;br /&gt;
    var newText = text.replace( what.text, mods[&amp;quot;with&amp;quot;].text, &amp;quot;i&amp;quot;);&lt;br /&gt;
    CmdUtils.setSelection( newText );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In earlier prototypes, modifier arguments could only accept a single-word value, but this has now been fixed.)&lt;br /&gt;
&lt;br /&gt;
The modifiers argument takes a dictionary, where the key is the name of the argument and the value is the noun-type of the argument. In later releases we may include further options, like the ability to specify an argument as required/optional, etc.&lt;br /&gt;
&lt;br /&gt;
The translate command is a good place to learn more about modifiers and the &amp;lt;code&amp;gt;noun_type_language&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Twitter: Putting It All Together =&lt;br /&gt;
&lt;br /&gt;
We&#039;ve now covered everything we need to cover in order to write a command that allows us to [http://en.wikipedia.org/wiki/Twitter Twitter] from Ubiquity. Many thanks to [http://theunfocused.net/ Blair McBride] for writing this command. This is a fully functioning command: the browser takes care of the odd edge cases, like not being logged in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// max of 140 chars is recommended, but it really allows 160&lt;br /&gt;
const TWITTER_STATUS_MAXLEN = 160;&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;twitter&amp;quot;,&lt;br /&gt;
  takes: {status: noun_arb_text},&lt;br /&gt;
  &lt;br /&gt;
  homepage: &amp;quot;http://theunfocused.net/moz/ubiquity/verbs/&amp;quot;,&lt;br /&gt;
  author: {name: &amp;quot;Blair McBride&amp;quot;, homepage: &amp;quot;http://theunfocused.net/&amp;quot;},&lt;br /&gt;
  license: &amp;quot;MPL&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  preview: function(previewBlock, statusText) {&lt;br /&gt;
    var previewTemplate = &amp;quot;Updates your Twitter status to: &amp;lt;br/&amp;gt;&amp;quot; +       &lt;br /&gt;
                          &amp;quot;&amp;lt;b&amp;gt;${status}&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;quot; + &lt;br /&gt;
                          &amp;quot;Characters remaining: &amp;lt;b&amp;gt;${chars}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    var truncateTemplate = &amp;quot;&amp;lt;br /&amp;gt;The last &amp;lt;b&amp;gt;${truncate}&amp;lt;/b&amp;gt; &amp;quot; + &lt;br /&gt;
                           &amp;quot;characters will be truncated!&amp;quot;;&lt;br /&gt;
    var previewData = {&lt;br /&gt;
      status: statusText.text,&lt;br /&gt;
      chars: TWITTER_STATUS_MAXLEN - statusText.text.length&lt;br /&gt;
    };&lt;br /&gt;
      &lt;br /&gt;
    var previewHTML = CmdUtils.renderTemplate(previewTemplate,&lt;br /&gt;
                                                    previewData);&lt;br /&gt;
    &lt;br /&gt;
    if(previewData.chars &amp;lt; 0) {&lt;br /&gt;
      var truncateData = {&lt;br /&gt;
        truncate: 0 - previewData.chars&lt;br /&gt;
      };&lt;br /&gt;
      &lt;br /&gt;
      previewHTML += CmdUtils.renderTemplate(truncateTemplate,&lt;br /&gt;
                                                   truncateData);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    previewBlock.innerHTML = previewHTML;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  execute: function(statusText) {&lt;br /&gt;
    if(statusText.text.length &amp;lt; 1) {&lt;br /&gt;
      displayMessage(&amp;quot;Twitter requires a status to be entered&amp;quot;);&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var updateUrl = &amp;quot;https://twitter.com/statuses/update.json&amp;quot;;&lt;br /&gt;
    var updateParams = {&lt;br /&gt;
      source: &amp;quot;ubiquity&amp;quot;,&lt;br /&gt;
      status: statusText.text&lt;br /&gt;
    };&lt;br /&gt;
    &lt;br /&gt;
    jQuery.ajax({&lt;br /&gt;
      type: &amp;quot;POST&amp;quot;,&lt;br /&gt;
      url: updateUrl,&lt;br /&gt;
      data: updateParams,&lt;br /&gt;
      dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
      error: function() {&lt;br /&gt;
        displayMessage(&amp;quot;Twitter error - status not updated&amp;quot;);&lt;br /&gt;
      },&lt;br /&gt;
      success: function() {&lt;br /&gt;
        displayMessage(&amp;quot;Twitter status updated&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Switching Tabs =&lt;br /&gt;
&lt;br /&gt;
The final command in this tutorial is for switching between tabs. The end goal is this: type a few keys to that matches the title of an open tab (in any window), hit return, and you&#039;ve switched to that tab.&lt;br /&gt;
&lt;br /&gt;
We&#039;ll write this command in two steps. The first step is creating a tab noun-type. The second step is using that noun-type to create the tab-switching command.&lt;br /&gt;
&lt;br /&gt;
== Switching: Writing your own Noun-Types ==&lt;br /&gt;
&lt;br /&gt;
A noun-type needs to only have two things: A name and a suggest function. Soon, we&#039;ll probably move to having a convenience &amp;lt;code&amp;gt;CmdUtils.CreateNounType()&amp;lt;/code&amp;gt;, which will simplify things even more.&lt;br /&gt;
&lt;br /&gt;
The name is what shows up when the command prompts for input. Suggest returns a list of input objects, each one containing the name of a matching tab. We&#039;re using [http://developer.mozilla.org/en/docs/FUEL FUEL] to interact with the browser, which is where the &amp;quot;Application&amp;quot; variable comes from.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_tab = {&lt;br /&gt;
  _name: &amp;quot;tab name&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
  // Returns all tabs from all windows.&lt;br /&gt;
  getTabs: function(){&lt;br /&gt;
    var tabs = {};&lt;br /&gt;
&lt;br /&gt;
    for( var j=0; j &amp;lt; Application.windows.length; j++ ) {&lt;br /&gt;
      var window = Application.windows[j];&lt;br /&gt;
      for (var i = 0; i &amp;lt; window.tabs.length; i++) {&lt;br /&gt;
        var tab = window.tabs[i];&lt;br /&gt;
        tabs[tab.document.title] = tab;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return tabs;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    &lt;br /&gt;
    var suggestions  = [];&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
&lt;br /&gt;
    //TODO: implement a better match algorithm&lt;br /&gt;
    for ( var tabName in tabs ) {&lt;br /&gt;
      if (tabName.match(text, &amp;quot;i&amp;quot;))&lt;br /&gt;
	 suggestions.push( CmdUtils.makeSugg(tabName) );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Return a list of input objects, limited to at most five:&lt;br /&gt;
    return suggestions.splice(0, 5);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The suggest method of a noun type always gets passed both text and html.  If the input is coming from a part of a web page that the user has selected, these&lt;br /&gt;
values can be different: they are both strings, but the html value contains markup tags while the text value does not. The Tab noun type only cares about the plain text of the tab name, so we ignore the value of html.&lt;br /&gt;
&lt;br /&gt;
We use the convenience function &amp;lt;code&amp;gt;CmdUtils.makeSugg()&amp;lt;/code&amp;gt; to generate an&lt;br /&gt;
input object of the type that the Ubiquity parser expects.  The full signature of this function is&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.makeSugg( text, html, data );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
but html and data are optional and need be provided only if they differ from text.&lt;br /&gt;
&lt;br /&gt;
If the text or html input is very long, &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; generates a summary for us, and puts it in the &amp;lt;code&amp;gt;.summary&amp;lt;/code&amp;gt; attribute of the input object.&lt;br /&gt;
&lt;br /&gt;
We could have accomplished mostly the same thing without calling &amp;lt;code&amp;gt;makeSugg()&amp;lt;/code&amp;gt; by returning a list of anonymous objects like these:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ text: tabName,&lt;br /&gt;
  html: tabName,&lt;br /&gt;
  data: null,&lt;br /&gt;
  summary: tabName };&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The input objects that our &amp;lt;code&amp;gt;.suggest()&amp;lt;/code&amp;gt; method generates are the same objects that will eventually get passed in to the &amp;lt;code&amp;gt;execute()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;preview()&amp;lt;/code&amp;gt; methods of any commands that use this noun type.&lt;br /&gt;
&lt;br /&gt;
== Switching Tabs: The Command ==&lt;br /&gt;
&lt;br /&gt;
Now that we are armed with the tab noun-type, it is easy to make the tab-switching command. Again, we use FUEL to focus the selected tab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;tab&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;tab name&amp;quot;: noun_type_tab},&lt;br /&gt;
&lt;br /&gt;
  execute: function( directObj ) {&lt;br /&gt;
    var tabName = directObj.text;&lt;br /&gt;
    var tabs = noun_type_tab.getTabs();&lt;br /&gt;
    tabs[tabName]._window.focus();&lt;br /&gt;
    tabs[tabName].focus();&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  preview: function( pblock, directObj ) {&lt;br /&gt;
    var tabName = directObj.text;&lt;br /&gt;
    if( tabName.length &amp;gt; 1 ){&lt;br /&gt;
        var msg = &amp;quot;Changes to &amp;lt;b style=\&amp;quot;color:yellow\&amp;quot;&amp;gt;%s&amp;lt;/b&amp;gt; tab.&amp;quot;;&lt;br /&gt;
        pblock.innerHTML = msg.replace(/%s/, tabName);&lt;br /&gt;
     }&lt;br /&gt;
    else&lt;br /&gt;
      pblock.innerHTML = &amp;quot;Switch to a tab by name.&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Development Hints =&lt;br /&gt;
&lt;br /&gt;
You now know all you need to know to get started developing useful Ubiquity commands of your own.&lt;br /&gt;
&lt;br /&gt;
Here are some miscellaneous tips that didn&#039;t fit elsewhere on this page, that may make development easier for you.&lt;br /&gt;
&lt;br /&gt;
== The Source Code of Built-In Commands ==&lt;br /&gt;
&lt;br /&gt;
Looking at the source code of built-in commands and built-in noun types can be a very useful aid to development.  If you have the source checkout of Ubiquity (see [https://wiki.mozilla.org/index.php?title=Labs/Ubiquity/Ubiquity_0.1_Development_Tutorial the development tutorial] to find out how to get this), the source code can be found in the files and directories:&lt;br /&gt;
&lt;br /&gt;
 ubiquity/standard-feeds/&lt;br /&gt;
 ubiquity/builtin-feeds/en/builtincmds.js&lt;br /&gt;
 ubiquity/feed-parts/header/en/nountypes.js&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have a checkout of the source code, you can view the latest version on the web here:&lt;br /&gt;
&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/standard-feeds/ standard-feeds]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/builtin-feeds/en/builtincmds.js builtincmds.js]&lt;br /&gt;
 [http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/feed-parts/header/en/nountypes.js nountypes.js]&lt;br /&gt;
&lt;br /&gt;
== Interacting with Other Extensions ==&lt;br /&gt;
&lt;br /&gt;
http://img363.imageshack.us/img363/1906/picture7cm5.png&lt;br /&gt;
&lt;br /&gt;
There isn&#039;t much to say here besides that it&#039;s easy. For example, here&#039;s a command (thanks to [http://foyrek.com/lyrics.html Abimanyu Raja] for writing this code) that finds the lyrics for a song. You can simply Ubiq something like &amp;quot;get-lyrics wild international&amp;quot; but the command will also interface with the FoxyTunes extension (if it is installed) and add the currently playing song to the suggestion list. Interfacing with other extensions, too, is easy because you can view the source code for every Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_song = {&lt;br /&gt;
  _name: &amp;quot;song name&amp;quot;,&lt;br /&gt;
  suggest: function( text, html ) {&lt;br /&gt;
    var suggestions  = [CmdUtils.makeSugg(text)];&lt;br /&gt;
    if(window.foxytunesGetCurrentTrackTitle){&lt;br /&gt;
   suggestions.push(CmdUtils.makeSugg(window.foxytunesGetCurrentTrackTitle()));&lt;br /&gt;
  	}&lt;br /&gt;
    return suggestions;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;get-lyrics&amp;quot;,&lt;br /&gt;
  takes: {song: noun_type_song},&lt;br /&gt;
  preview: function(pblock, directObject) {&lt;br /&gt;
    &lt;br /&gt;
    searchText = jQuery.trim(directObject.text);&lt;br /&gt;
    if(searchText.length &amp;lt; 1) {&lt;br /&gt;
      pblock.innerHTML = &amp;quot;Searches for lyrics of the song&amp;quot;;&lt;br /&gt;
      return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var previewTemplate = &amp;quot;Searches for the lyrics of &amp;lt;b&amp;gt;${query}&amp;lt;/b&amp;gt;&amp;quot;;&lt;br /&gt;
    var previewData = {query: searchText};&lt;br /&gt;
    pblock.innerHTML = CmdUtils.renderTemplate(previewTemplate, previewData);&lt;br /&gt;
&lt;br /&gt;
  },&lt;br /&gt;
  execute: function(directObject) {&lt;br /&gt;
    var url = &amp;quot;http://www.google.com/search?q={QUERY}&amp;quot;&lt;br /&gt;
    var query = directObject.text + &amp;quot; lyrics&amp;quot;;&lt;br /&gt;
    var urlString = url.replace(&amp;quot;{QUERY}&amp;quot;, query);&lt;br /&gt;
    Utils.openUrlInBrowser(urlString);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementing Asynchronous Noun Suggestions ==&lt;br /&gt;
&lt;br /&gt;
The noun types we&#039;ve seen so far in this tutorial have all worked synchronously, returning their suggestions right away. However, Ubiquity also supports asynchronous noun suggestions. These are useful for when a noun type needs to do some potentially time-consuming work before it can make suggestions &amp;amp;mdash; most commonly when it needs to call an external service.&lt;br /&gt;
&lt;br /&gt;
Implementing asynchronous suggestions is simple. Whenever the Ubiquity parser calls a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function, it includes a callback function that may be used to send suggestions back to the parser as they become available. In the most typical case, the noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function makes an AJAX request, invoking the parser&#039;s callback function from within the callback function for the AJAX request.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a simple example: a noun type that suggests [http://www.freebase.com/ Freebase] topics based on the text the user has typed or selected, and a barebones &amp;lt;code&amp;gt;freebase-lookup&amp;lt;/code&amp;gt; command that uses the noun type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var noun_type_freebase_topic = {&lt;br /&gt;
  _name: &amp;quot;Freebase topic&amp;quot;,&lt;br /&gt;
  &lt;br /&gt;
  suggest: function suggest( text, html, callback ) {&lt;br /&gt;
    jQuery.ajax( {&lt;br /&gt;
      url: &amp;quot;http://www.freebase.com/api/service/search&amp;quot;,&lt;br /&gt;
      dataType: &amp;quot;json&amp;quot;,&lt;br /&gt;
      data: { prefix: text, limit: 5 },&lt;br /&gt;
      success: function suggestTopics( response ) {&lt;br /&gt;
        var i, results, result;&lt;br /&gt;
        results = response.result;&lt;br /&gt;
        for ( i = 0; i &amp;lt; results.length; i++ ) {&lt;br /&gt;
          result = results[ i ];&lt;br /&gt;
          callback( CmdUtils.makeSugg( result.name, result.name, result ) );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    } );&lt;br /&gt;
    return [];&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
CmdUtils.CreateCommand( {&lt;br /&gt;
  name: &amp;quot;freebase-lookup&amp;quot;,&lt;br /&gt;
  takes: { topic: noun_type_freebase_topic },&lt;br /&gt;
  preview: function preview( container, topic ) {&lt;br /&gt;
    var text = topic.text || &amp;quot;any topic&amp;quot;;&lt;br /&gt;
    container.innerHTML = &amp;quot;Go to the Freebase topic page for &amp;quot; + text + &amp;quot;.&amp;quot;;&lt;br /&gt;
  },&lt;br /&gt;
  execute: function goToFreebase( topic ) {&lt;br /&gt;
    if ( topic ) {&lt;br /&gt;
      Utils.openUrlInBrowser( &amp;quot;http://www.freebase.com/view&amp;quot; + topic.data.id );&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A few notes:&lt;br /&gt;
&lt;br /&gt;
* The parser&#039;s callback function expects only one suggestion (not an array of suggestions), so it must be called one time for each suggestion, even if the noun type has multiple suggestions available at the same time (as in the Freebase example above). This is a bit different from the synchronous case, in which the &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function is expected to return an array.&lt;br /&gt;
* A noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function typically returns an empty array when it intends to make asynchronous suggestions, but it can return one or more suggestions synchronously if it has them available.&lt;br /&gt;
* Because the work being done to generate asynchronous suggestions is generally somewhat expensive, and because a noun type&#039;s &amp;lt;code&amp;gt;suggest&amp;lt;/code&amp;gt; function may be called for every keystroke the user makes, you should probably consider implementing a delay before starting the work and/or caching the work at some level. Ubiquity currently leaves this up to each noun type individually.&lt;br /&gt;
* A much more robust implementation of Freebase-derived noun types can be found [http://graynorton.com/ubiquity/freebase-nouns.html here].&lt;br /&gt;
&lt;br /&gt;
== Running on page load and startup ==&lt;br /&gt;
&lt;br /&gt;
In order to run some code on page load, you simply have to prefix your function with &amp;lt;code&amp;gt;pageLoad_&amp;lt;/code&amp;gt;. For example, if you want to say &amp;quot;Hi&amp;quot; every time a page is loaded, your code would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function pageLoad_hi(){&lt;br /&gt;
 displayMessage(&amp;quot;hi&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you modify the function and want to see the changes, remember to first invoke Ubiquity. Although your function like above, might not be a Ubiquity command, this is necessary to refresh the cached code.&lt;br /&gt;
&lt;br /&gt;
Similarly, if you want to run some code everytime Firefox starts up, you just have to prefix the function with &amp;lt;code&amp;gt;startup_&amp;lt;/code&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
The awesome thing about these functions is the ability to develop whole Firefox extensions (that require minimal UI) as Ubiquity plugins in lesser lines of code. You don&#039;t need to worry about chrome.manifest or install.rdf. Another added benefit is that you never have to restart your Firefox during development unless of course, you are running code on Firefox startup.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;http://img388.imageshack.us/img388/3086/picture5eo9.png&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code for [http://foyrek.com/commands/keyscape.js Keyscape] which is a Ubiquity command that makes use of &amp;lt;code&amp;gt;pageLoad&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;startup&amp;lt;/code&amp;gt; to recreate the functionality of the [https://addons.mozilla.org/en-US/firefox/addon/339 Search Keys extension] by Jesse Ruderman. In line with Ubiquity&#039;s aim to let you do things quicker using your keyboard, this command lets you go to search results on Google by just pressing a number. It&#039;ll add hints to show the number of each link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//A lot of this code is borrowed from the Search Keys extension&lt;br /&gt;
//Many thanks to Jeese Ruderman&lt;br /&gt;
&lt;br /&gt;
function startup_keyscape() {&lt;br /&gt;
  window.addEventListener(&amp;quot;keydown&amp;quot;, keyscape_down, true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function pageLoad_keyscape(doc){&lt;br /&gt;
&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
  //If we are on about: or chrome://, just return&lt;br /&gt;
  if(uri.scheme != &amp;quot;http&amp;quot;)&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
  //Check if the page we are on is google&lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	      		    &lt;br /&gt;
    for(var num=1; num&amp;lt;=10; num++){&lt;br /&gt;
&lt;br /&gt;
      var link = jQuery(doc.body).find(&#039;a.l&#039;)[num-1];&lt;br /&gt;
      &lt;br /&gt;
      if( link ){&lt;br /&gt;
&lt;br /&gt;
        var hint = doc.createElementNS(&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;, &amp;quot;span&amp;quot;);&lt;br /&gt;
        hint.style.color = &amp;quot;blue&amp;quot;;&lt;br /&gt;
        hint.style.background = &amp;quot;white&amp;quot;;&lt;br /&gt;
        hint.style.padding = &amp;quot;1px 2px 1px 2px&amp;quot;;&lt;br /&gt;
        hint.style.marginLeft = &amp;quot;.5em&amp;quot;;&lt;br /&gt;
        hint.appendChild(doc.createTextNode(num == 10 ? 0 : num));&lt;br /&gt;
        link.parentNode.insertBefore(hint, link.nextSibling);&lt;br /&gt;
      }  		&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_isGoogle(uri){&lt;br /&gt;
  return uri.host.indexOf(&amp;quot;google&amp;quot;) != -1 &lt;br /&gt;
	 &amp;amp;&amp;amp; (uri.path.substr(0,8) == &amp;quot;/search?&amp;quot; &lt;br /&gt;
         || uri.path.substr(0,8) == &amp;quot;/custom?&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function keyscape_down(event){&lt;br /&gt;
&lt;br /&gt;
  var doc =  Application.activeWindow.activeTab.document;	&lt;br /&gt;
  var uri = Utils.url(doc.documentURI);&lt;br /&gt;
 &lt;br /&gt;
  if( keyscape_isGoogle(uri) ){&lt;br /&gt;
	&lt;br /&gt;
   var key = parseInt(event.keyCode || event.charCode);	&lt;br /&gt;
   var num;&lt;br /&gt;
	&lt;br /&gt;
   if(48 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 57) //number keys&lt;br /&gt;
     num = key - 48;&lt;br /&gt;
   else if(96 &amp;lt;= key &amp;amp;&amp;amp; key &amp;lt;= 105) //numeric keypad with numlock on&lt;br /&gt;
     num = key - 96;&lt;br /&gt;
   else&lt;br /&gt;
     return;&lt;br /&gt;
&lt;br /&gt;
   //Don&#039;t do anything if we are in a textbox&lt;br /&gt;
   //or some other related elements&lt;br /&gt;
   var elt = window.document.commandDispatcher.focusedElement;&lt;br /&gt;
   &lt;br /&gt;
   if (elt) {&lt;br /&gt;
     var ln = new String(elt.localName).toLowerCase();&lt;br /&gt;
     if (ln == &amp;quot;input&amp;quot; || ln == &amp;quot;textarea&amp;quot; || ln == &amp;quot;select&amp;quot; || ln == &amp;quot;isindex&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
   //Get the link url from the search results page&lt;br /&gt;
   var url_dest = jQuery(doc.body).find(&#039;a.l&#039;).eq(num-1).attr(&#039;href&#039;);&lt;br /&gt;
   &lt;br /&gt;
   if(event.altKey){&lt;br /&gt;
     //Open in new tab&lt;br /&gt;
     Application.activeWindow.open(Utils.url(url_dest));&lt;br /&gt;
   }else{&lt;br /&gt;
     //Open in same tab&lt;br /&gt;
     doc.location.href = url_dest;&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If Ubiquity does indeed become ubiquitous, a lot of extensions can be re-written as Ubiquity commands. This is much nicer for the end-user, as well, because the Ubiquity command installation process is a lot easier.&lt;br /&gt;
&lt;br /&gt;
In the future, Ubiquity is also likely to have the ability to convert your Ubiquity commands into proper Firefox extensions. Look [http://labs.toolness.com/trac/ticket/3 here] to check on the progress of this functionality.&lt;br /&gt;
&lt;br /&gt;
== Firebug ==&lt;br /&gt;
&lt;br /&gt;
You should enable Chrome Errors and Warnings if you want the errors in your code to appear in the Firebug console. Use CmdUtils.log() rather than console.log() &#039;&#039;Note: For now, you can only pass one argument to log()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Adding Commands Programmatically ==&lt;br /&gt;
&lt;br /&gt;
Here is a snippet of code that shows how a developer can programmatically register a command included in a Firefox extension.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Helper function used to determine the local directory where the&lt;br /&gt;
// extension which contains the command is installed. This is used&lt;br /&gt;
// to create the URL of the js file which includes the implementation&lt;br /&gt;
// of the list of commands you want to add.&lt;br /&gt;
function getExtensionDir() {&lt;br /&gt;
    var extMgr = Components.classes[&amp;quot;@mozilla.org/extensions/manager;1&amp;quot;]&lt;br /&gt;
                 .getService(Components.interfaces.nsIExtensionManager);&lt;br /&gt;
    return extMgr.getInstallLocation( &amp;quot;feedly@devhd&amp;quot; ).getItemLocation( &amp;quot;feedly@devhd&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function getBaseUri() {&lt;br /&gt;
    var ioSvc = Components.classes[&amp;quot;@mozilla.org/network/io-service;1&amp;quot;]&lt;br /&gt;
	                  .getService(Components.interfaces.nsIIOService);&lt;br /&gt;
    var extDir = getExtensionDir();&lt;br /&gt;
    var baseUri = ioSvc.newFileURI(extDir).spec;&lt;br /&gt;
    return baseUri;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// your extension needs to call the addUbiquity command each time a new browser&lt;br /&gt;
// session is create and your extension is loaded.&lt;br /&gt;
function addUbiquityCommands(){&lt;br /&gt;
     // url of the file which contains the implementation of the commands&lt;br /&gt;
     // we want to add. &lt;br /&gt;
     var url = getBaseUri() + &amp;quot;content/app/ubiquity/commands.js&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
     // link to the ubiquity setup module.&lt;br /&gt;
     var jsm = {}; &lt;br /&gt;
     Components.utils.import(&amp;quot;resource://ubiquity/modules/setup.js&amp;quot;, jsm); &lt;br /&gt;
		&lt;br /&gt;
     // look up the feed manager and add a new command. Note: we are using the&lt;br /&gt;
     // isBuiltIn=true option so that the command is only added for the duration&lt;br /&gt;
     // of the browser session. This simplifies the overall lifecycle: if the&lt;br /&gt;
     // extension is disabled or un-installed, it will be automatically&lt;br /&gt;
     // &amp;quot;removed&amp;quot; from ubiquity.&lt;br /&gt;
     jsm.UbiquitySetup.createServices().feedManager.addSubscribedFeed( {&lt;br /&gt;
	url: url,&lt;br /&gt;
        sourceUrl: url,&lt;br /&gt;
        canAutoUpdate: true,&lt;br /&gt;
        isBuiltIn: true&lt;br /&gt;
     });&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside your command implementation, you can use importing modules or looking up a singleton XPCOM component to link your command back to the functionality encapsulated by your extension. Here is a sample command which does that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var StreetsUtils = function(){&lt;br /&gt;
    var that = {};&lt;br /&gt;
    that.lookupCore = function(){&lt;br /&gt;
        return Components.classes[&amp;quot;@devhd.com/feedly-boot;1&amp;quot;]&lt;br /&gt;
				.getService(Components.interfaces.nsIFeedlyBoot)&lt;br /&gt;
				.wrappedJSObject&lt;br /&gt;
				.lookupCore();&lt;br /&gt;
    };&lt;br /&gt;
    return that;&lt;br /&gt;
}();&lt;br /&gt;
&lt;br /&gt;
CmdUtils.CreateCommand({&lt;br /&gt;
  name: &amp;quot;my-extension-test&amp;quot;,&lt;br /&gt;
  takes: {&amp;quot;message&amp;quot;: noun_arb_text},&lt;br /&gt;
  icon: &amp;quot;chrome://my-extension-test/skin/icon-16x16.png&amp;quot;,&lt;br /&gt;
  modifiers: {to: noun_type_contact},&lt;br /&gt;
  description:&amp;quot;Testing the feedly+ubiquity integration&amp;quot;,&lt;br /&gt;
  help:&amp;quot;This is a test help message&amp;quot;,&lt;br /&gt;
  preview: function(pblock, directObj, modifiers) {&lt;br /&gt;
    var html = &amp;quot;Testing my-extension-test &amp;quot;;&lt;br /&gt;
    if (modifiers.to) {&lt;br /&gt;
      html += &amp;quot;to &amp;quot; + modifiers.to.text + &amp;quot; &amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if (directObj.html) {&lt;br /&gt;
      html += &amp;quot;with these contents:&amp;quot; + directObj.html;&lt;br /&gt;
    } else {&lt;br /&gt;
      html += &amp;quot;with a link to the current page.&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    pblock.innerHTML = html;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  execute: function(directObj, headers) {&lt;br /&gt;
      CmdUtils.log( &amp;quot;&amp;gt;&amp;gt;&amp;gt; my-extension core? &amp;quot; + ( StreetsUtils.lookupCore() != null ) );&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you command file needs to include/load other JS files included in your extension, you can use the following piece of code at the top of the command js file you are adding to ubiquity.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function include( partialURI )&lt;br /&gt;
{&lt;br /&gt;
    // Load JS libraries&lt;br /&gt;
    var u = &amp;quot;chrome://feedly/content/app/&amp;quot; + partialURI;&lt;br /&gt;
    var jsl = Cc[&amp;quot;@mozilla.org/moz/jssubscript-loader;1&amp;quot;]&lt;br /&gt;
			.getService(Ci.mozIJSSubScriptLoader);  &lt;br /&gt;
		&lt;br /&gt;
    jsl.loadSubScript( u );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
include( &amp;quot;ubiquity/templates.ubiquity.js&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Conclusion =&lt;br /&gt;
&lt;br /&gt;
To reiterate a point I made before: Ubiquity increases the surface area of innovation for the browser many-fold, by making anyone who can write simple Javascript into an agent for bettering the browser and the open Web. You are one of those agents.&lt;br /&gt;
&lt;br /&gt;
Now, go forth and create.&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
	<entry>
		<id>https://wiki.mozilla.org/index.php?title=Labs/Ubiquity&amp;diff=124629</id>
		<title>Labs/Ubiquity</title>
		<link rel="alternate" type="text/html" href="https://wiki.mozilla.org/index.php?title=Labs/Ubiquity&amp;diff=124629"/>
		<updated>2009-01-20T03:16:57Z</updated>

		<summary type="html">&lt;p&gt;Endolith: I kept looking at this page when it updated, and couldn&amp;#039;t find the release notes. Now I look in about:ubiquity&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Labs]].&lt;br /&gt;
&lt;br /&gt;
[https://ubiquity.mozilla.com/xpi/ubiquity-latest.xpi Install latest version of Ubiquity for Firefox]&lt;br /&gt;
&lt;br /&gt;
[https://ubiquity.mozilla.com/xpi/ubiquity-latest-beta.xpi Install the latest beta of Ubiquity for Firefox]&lt;br /&gt;
&lt;br /&gt;
= What is Ubiquity? =&lt;br /&gt;
You can learn more about Ubiquity by reading Atul&#039;s blog post entitled [http://www.toolness.com/wp/?p=54 Ubiquitous Interfaces, Ubiquitous Functionality], or try it out via the [[Labs/Ubiquity/Latest Ubiquity User Tutorial|User Tutorial]].&lt;br /&gt;
&lt;br /&gt;
Other informative blog posts about Ubiquity include:&lt;br /&gt;
# [http://www.toolness.com/wp/?p=64 Trusting Functionality] by Atul&lt;br /&gt;
# [http://www.azarask.in/blog/post/can-ubiquity-be-used-only-with-the-mouse/ Mouse-Based Ubiquity]&lt;br /&gt;
# [http://azarask.in/blog/post/sharing-streamable-functionality/ Sharing Streamable Functionality] by Aza&lt;br /&gt;
# [http://jonoscript.wordpress.com/2008/07/21/language-based-interfaces-part-1-the-problem/ Language-Based Interfaces, part 1: The Problem] by Jono&lt;br /&gt;
# [http://jonoscript.wordpress.com/2008/07/25/our-presentation-at-labs-night/ Our Presentation at Labs Night] by Jono&lt;br /&gt;
# [http://jonoscript.wordpress.com/2008/07/26/why-verbs/ Why Verbs?] by Jono&lt;br /&gt;
# [[Labs/Ubiquity/Selected Press|Selected Press]]&lt;br /&gt;
&lt;br /&gt;
= Participation =&lt;br /&gt;
# [http://getsatisfaction.com/mozilla/products/mozilla_ubiquity Ideas, Complaints, Forum, and &amp;quot;Customer Service&amp;quot;]&lt;br /&gt;
# [http://groups.google.com/group/ubiquity-firefox General Google Group/mailing list] - Useful for discussion of command development, user interface, feature suggestions, and other high-level discussions.&lt;br /&gt;
# [[Labs/Ubiquity/Commands In The Wild|Commands In The Wild]] Add links to your commands here.&lt;br /&gt;
# [http://ubiquitously.org/forum Ubiquitously, an Ubiquity developer geared forum]&lt;br /&gt;
# [irc://irc.mozilla.org/ubiquity #ubiquity irc.mozilla.org] - Live internet relay chat discussion.&lt;br /&gt;
# [http://labs.toolness.com/trac/report/1 Issue Tracker] - Used to report/discuss bugs and submit patches for Ubiquity.&lt;br /&gt;
# [http://hg.toolness.com/ubiquity-firefox/ Ubiquity HG Repository] - The Mercurial source code repository for Ubiquity.&lt;br /&gt;
# [http://labs.toolness.com:8010/ Buildbot] - Continuous integration that runs Ubiquity unit tests after every commit.  If the tests fail, they&#039;re reported immediately to the mailing list.&lt;br /&gt;
# [http://groups.google.com/group/ubiquity-core Core Google Group/mailing list] - Discussion of low-level internals of Ubiquity.&lt;br /&gt;
# [[Labs/Ubiquity/Credits|Credits]]&lt;br /&gt;
&lt;br /&gt;
= Meeting Notes =&lt;br /&gt;
# [http://docs.google.com/Doc?id=ddf2vjms_24cpjjq9g9 Meeting notes for 0.1 release]&lt;br /&gt;
# [[Labs/Ubiquity/November 12 Meeting Notes|November 12 Meeting Notes]]&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
# [[Labs/Ubiquity/Latest Ubiquity User Tutorial|Ubiquity Tutorial]] &lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1_Author_Tutorial|Creating Commands Tutorial]]&lt;br /&gt;
# [[Labs/Ubiquity/Skins/|Skinning Ubiquity Tutorial]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1_Development_Tutorial|Contributing to Core Development]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1_Localization_Tutorial|Localizing Ubiquity to Your Language]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1_Nountypes_Reference|Noun-types Reference]]&lt;br /&gt;
# [[Labs/Ubiquity/Bundled Libraries|Bundled libraries]]&lt;br /&gt;
# [[Labs/Ubiquity/jQuery in Ubiquity|Using jQuery in Ubiquity]]&lt;br /&gt;
# [https://developer.mozilla.org/en/JavaScript_style_guide JavaScript style guide]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity_Source_Tip_Author_Tutorial|Source-tip Commands Tutorial]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity_0.1.3_Architecture|Ubiquity 0.1.3 Architecture]]&lt;br /&gt;
&lt;br /&gt;
= The Herd =&lt;br /&gt;
The Herd keeps track of all Ubiquity scripts. For more information, see the following links:&lt;br /&gt;
# [http://hg.toolness.com/ubiquity-site/ Herd HG Repository]&lt;br /&gt;
# [http://hg.toolness.com/ubiquity-site/file/tip/README Herd Developer FAQ]&lt;br /&gt;
# [http://wiki.apache.org/couchdb/HttpViewApi CouchDB] - database used for Herd&lt;br /&gt;
# [https://ubiquity.mozilla.com/herd/ The Herd]-The Herd Itself.&lt;br /&gt;
&lt;br /&gt;
= Proposals =&lt;br /&gt;
&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity Command Suggestions|Command Suggestions]] - use this page to suggest new Ubiquity commands you&#039;d like to see.&lt;br /&gt;
# [[Labs/Ubiquity/Nouns | Proposals for New Nouns]]&lt;br /&gt;
# [[Labs/Ubiquity/Magic_Words | Proposals for new &amp;quot;Magic Words&amp;quot;]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity_Commands_Center | Ubiquity Commands Center]] - an idea for a web-panel that maintains a database of Ubiquity scripts.&lt;br /&gt;
# [[Labs/Ubiquity/TrustNetwork | Ubiquity Trust Network]] - a proposal for a distributed trust network&lt;br /&gt;
# [[Labs/Ubiquity/Thunderbird | Ubiquity In Thunderbird]] - let&#039;s make Ubiquity work in Thunderbird!&lt;br /&gt;
# [[Labs/Ubiquity/0.2 Roadmap Proposals | 0.2 Roadmap Proposals]] - Brainstorming on possible directions to go for Ubiquity 0.2.&lt;br /&gt;
# [[Labs/Ubiquity/0.2 Design: UI and Security Extensibility|0.2 Design: UI and Security Extensibility]] - Design-related thoughts on how to make Ubiquity extensible in regards to security/command-execution and access by other Firefox UIs.&lt;br /&gt;
# [[Labs/Ubiquity/0.2 Proposed Uplift Commands| Proposed commands for uplift into Ubiquity 0.2]]&lt;br /&gt;
&lt;br /&gt;
= Release Notes =&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1.1 Release Notes|Ubiquity 0.1.1 Release Notes]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1.2 Release Notes (Raging Stream)|Ubiquity 0.1.2 Release Notes (Raging Stream)]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity 0.1.3 Release Notes|Ubiquity 0.1.3 Release Notes]]&lt;br /&gt;
# [[Labs/Ubiquity/Ubiquity_0.1.5_Release_Notes|Ubiquity 0.1.5 Release Notes]]&lt;br /&gt;
# ...&lt;/div&gt;</summary>
		<author><name>Endolith</name></author>
	</entry>
</feed>