The how and why of this Ubiquity 0.5 release

2 views
Skip to first unread message

Aza

unread,
Jul 7, 2009, 3:18:57 PM7/7/09
to ubiquity-firefox

ms08

unread,
Jul 8, 2009, 10:51:09 AM7/8/09
to ubiquity-firefox
I just found ubiquity yesterday and installed the extension.
This evening I had time to play and honestly, I just spent the last
half hour saying Wow, Wow, WOW, Woooow.
This is unreal, I am sooooo impressed.

If this is version 0.5 what is 3.5 gunna be like in a year or three.
Keep up the good work!!!

Aza

unread,
Jul 8, 2009, 1:04:18 PM7/8/09
to ubiquity...@googlegroups.com
Thanks!

-- aza | ɐzɐ --

Timofei Shatrov

unread,
Jul 8, 2009, 1:51:42 PM7/8/09
to ubiquity-firefox
This is very interesting, but I still can't find the answer to the
question: how does a third-party command developer ensure that it
works for every user after update? Many of the users will be using
0.5, while others will be stuck with 0.1.9. How do I make my commands
work for both groups of people flawlessly?

Tiago Carmona

unread,
Jul 8, 2009, 2:03:49 PM7/8/09
to ubiquity...@googlegroups.com
I don`t know if there is something like a compatibility layer in ubiquity, but i think that if there isn`t something like that you could make 2 feeds, one with commands with the syntax of 0.1.9 and one with commands of the new syntax.


Thanks,
Tiago Carmona

Timofei Shatrov

unread,
Jul 8, 2009, 2:19:57 PM7/8/09
to ubiquity-firefox
On 9 июл, 00:03, Tiago Carmona <carmona.ti...@gmail.com> wrote:
> I don`t know if there is something like a compatibility layer in ubiquity,
> but i think that if there isn`t something like that you could make 2 feeds,
> one with commands with the syntax of 0.1.9 and one with commands of the new
> syntax.

But that would require me making 2 separate webpages so that users
could subscribe to two different feeds, and this would be really
confusing. It should be possible to either make one feed that works
with both versions, or make a single webpage "<link>" to several
feeds, and Ubiquity should be able to subscribe to the one that is
compatible with the current version.

This is not a theoretic question btw, the "urban-dictionary-search"
command that I am maintaining is used by at least 1000 users and I
have a bunch of other commands published too.

Gary Hodgson

unread,
Jul 8, 2009, 2:29:26 PM7/8/09
to ubiquity...@googlegroups.com
Timofei, I posted this in an earlier thread if it's at all useful...

For what it's worth this is my solution to the upcoming 0.5 release.  It's certainly not elegant, but it works, and it means I don't have the hassle of managing two versions of the commands whilst people migrate.

var isParser2 = function(){
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
var branch = prefs.getBranch("extensions.ubiquity.");

return (branch.getPrefType("parserVersion") != 0) ? branch.getIntPref("parserVersion") == 2 : false;
}

if (isParser2()) {


/* Parser 2 version of the CmdUtils.CreateCommand calls here */
/* ... */

} else {

/* Parser 1 version of the CmdUtils.CreateCommand calls here */
/* ... */

}

(Full code is here: http://github.com/garyhodgson/ubiquity-rtm-api/blob/7299e60eab828fa89d76ce3c927faa1ad4064a23/ubiquity-rtm-api.js)

Cheers,
Gary

2009/7/8 Timofei Shatrov <timofei...@gmail.com>

Timofei Shatrov

unread,
Jul 9, 2009, 12:38:05 AM7/9/09
to ubiquity-firefox


On 9 июл, 00:29, Gary Hodgson <cont...@garyhodgson.com> wrote:
> Timofei, I posted this in an earlier
> thread<http://groups.google.com/group/ubiquity-firefox/browse_thread/thread/...>if
> it's at all useful...
>
> For what it's worth this is my solution to the upcoming 0.5 release.  It's
> certainly not elegant, but it works, and it means I don't have the hassle of
> managing two versions of the commands whilst people migrate.
>
> var isParser2 = function(){
> var prefs = Components.classes["@mozilla.org/preferences-service;1
> "].getService(Components.interfaces.nsIPrefService);
>  var branch = prefs.getBranch("extensions.ubiquity.");
>
> return (branch.getPrefType("parserVersion") != 0) ?
> branch.getIntPref("parserVersion") == 2 : false;

But would herd be able to parse such a code? I'd prefer if there was
an official solution from Ubiquity developers, as this issue would
definitely prevent me from transferring my commands to 0.5 format.

Heather

unread,
Jul 9, 2009, 3:07:01 PM7/9/09
to ubiquity-firefox
I shall attempt to write an "official" response:

1. Yesterday, Atul added a function to CmdUtils called
CmdUtils.parserVersion. It is based on Gary's solution (you got
credit in the commit message! https://ubiquity.mozilla.com/hg/ubiquity-firefox/rev/651ba8eea7bf)
and provides a way to support a Parser1 and Parser2 command in the
same file. Someone should be adding info on this to the Command
Update tutorial shortly.

2. The Herd is not Parser1/Parser2 aware right now, which means it's
not indexing new commands. The Ubiquity team decided that getting 0.5
out to the community was our top priority, so we deferred updating the
Herd.

3. Using CmdUtils.parserVersion will probably not be final solution
for how to host 0.1 and 0.5 feeds, but it will work for those of you
who are working now to get your feeds updated to support both sets of
users. In the long run this solution makes things difficult for
parsing commands in the herd, so we are exploring other options.

4. I think everyone will agree that breaking the API and branching the
release so as not to break 0.1 commands has presented some challenges
that we're working through. Thanks for your patience. I'd love to
hear feedback from command developers who have been early upgraders
about how we can make this process easier for people who follow in
your footsteps, and I appreciate those who have already offered
feedback about this.

Heather

garyhodgson

unread,
Jul 10, 2009, 3:55:54 AM7/10/09
to ubiquity-firefox
Hi,

I'm glad that the parserVersion hack is useful, but it's worth noting
that this is only useful for people who have upgraded to 0.5 or
greater. To cater for people who have not upgraded, the function
still has to be defined in the command itself. And if you do
implement it in the command itself please note the following...

The function added in CmdUtils (https://ubiquity.mozilla.com/hg/
ubiquity-firefox/rev/651ba8eea7bf) leaves out the following check:

return (branch.getPrefType("parserVersion") != 0) ? branch.getIntPref
("parserVersion") == 2 : false;

Versions prior to 0.5 of course do not have this parserVersion
preference and so getIntPref fails with an exception:

[Exception... "Component returned failure code: 0x8000ffff
(NS_ERROR_UNEXPECTED) [nsIPrefBranch.getIntPref]" nsresult:
"0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: file:///
... /extensions/ubiq...@labs.mozilla.com/modules/
sandboxfactory.js#ubiquity://command-editor-code :: parserVersion ::
line 5" data: no]

nsIPrefBranch seems to lack some basic functionality such as a
"hasPref" function, or even a nice degradation on the getPref
functions, and so using the following function works with versions
prior to 0.5:

function parserVersion() {
var prefs = Components.classes["@mozilla.org/preferences-service;
1"].getService(Components.interfaces.nsIPrefService);
var branch = prefs.getBranch("extensions.ubiquity.");
return (branch.getPrefType("parserVersion") != 0) ? branch.getIntPref
("parserVersion") == 2 : false;
}

Cheers,
Gary

Heather

unread,
Jul 10, 2009, 9:14:04 AM7/10/09
to ubiquity-firefox
Actually, CmdUtils.parserVersion was added to 0.1.9 too, and will
always return 1. You are right that it will break for versions prior
to 0.1.9.

On Jul 10, 3:55 am, garyhodgson <cont...@garyhodgson.com> wrote:
> Hi,
>
> I'm glad that the parserVersion hack is useful, but it's worth noting
> that this is only useful for people who have upgraded to 0.5 or
> greater.  To cater for people who have not upgraded, the function
> still has to be defined in the command itself.  And if you do
> implement it in the command itself please note the following...
>
> The function added in CmdUtils (https://ubiquity.mozilla.com/hg/
> ubiquity-firefox/rev/651ba8eea7bf) leaves out the following check:
>
>         return (branch.getPrefType("parserVersion") != 0) ? branch.getIntPref
> ("parserVersion") == 2 : false;
>
> Versions prior to 0.5 of course do not have this parserVersion
> preference and so getIntPref fails with an exception:
>
>         [Exception... "Component returned failure code: 0x8000ffff
> (NS_ERROR_UNEXPECTED) [nsIPrefBranch.getIntPref]" nsresult:
> "0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: file:///
> ... /extensions/ubiqu...@labs.mozilla.com/modules/

Heather

unread,
Jul 10, 2009, 12:12:23 PM7/10/09
to ubiquity-firefox
Atul and I have updated the Command Conversion tutorial to reflect the
addition of CmdUtil.parserVersion. For versions prior to 0.1.9, you
can just check to see if it returns a value.

if (!CmdUtils.parserVersion || CmdUtils.parserVersion == 1)
//parser 1 command here
else
//parser 2 command here

https://wiki.mozilla.org/Labs/Ubiquity/Parser_2_API_Conversion_Tutorial#Supporting_both_Parser_1_and_Parser_2_in_Your_Command_Feed

Atul Varma

unread,
Jul 10, 2009, 12:27:31 PM7/10/09
to ubiquity-firefox
Thanks Heather, and thanks Gary for the implementation of
CmdUtils.parserVersion in 0.5. :)

There's a few reasons we decided to go the CmdUtils.parserVersion
route. The other solution we considered was requiring the <LINK REL>
tag on the HTML page to specify the version of the parser a feed was
written for, e.g.:

<LINK REL="commands" VERSION="1" HREF="foo-parser1.js"/>
<LINK REL="commands" VERSION="2" HREF="foo-parser2.js"/>

These are the reasons we didn't go the above route:

* Because Ubiquity doesn't currently support modules or any other
kind of code-sharing system, requiring command authors to provide
completely separate feeds for different parser versions would probably
require them to copy-and-paste common code between the two feeds,
which violates DRY [1].

* There's currently a bug in Ubiquity whereby after subscribing to a
command feed, Ubiquity never checks the HTML page that contains the
<LINK REL> tag again; it only checks the .js file pointed to by the
<LINK REL> tag for updates. This bug, in addition to Ubiquity's
general architecture surrounding command feeds, means that actually
implementing the VERSION attribute would require a lot of
implementation effort to work smoothly.

* By default, github and other services that host command feeds
would have to change their behavior if we went the VERSION route.

* Python's standard library uses top-level "if" statements that
examine static conditions that won't change throughout the process
lifetime (e.g., the host OS) to define functions differently depending
on the conditions. Actually changing the parser version in ubiquity
requires a restart, so examining CmdUtils.parserVersion satisfies the
same kind of criteria. In other words, although it's not super-
elegant, it's something that's done in lots of production code out
there and there's nothing really "wrong" with it.

* The "VERSION" attribute isn't valid HTML. Firefox would be able
to read it and work with it, but it'd interfere with folks who run
their code through HTML validators and such. We also considered using
the "REV" attribute, which we thought would be short for "revision",
but that's actually not what it's intended to be used for in the HTML
specificaiton.

* To respond to Timofei's concern, the Herd will be able to figure
out which feeds are parser1 vs. parser2 using the
CmdUtils.parserVersion method. This is because, in order to figure
out what commands a feed has, the Herd actually executes the feed in a
restricted sandbox environment. Figuring out what commands a hybrid
feed provides to parser 1 and parser 2 will just involve evaluating
the code twice: once with CmdUtils.parserVersion set to 1, and again
with CmdUtils.parserVersion set to 2.

I hope this clarifies things for everyone, let us know if you have any
other questions though! :)

- Atul

[1] http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

Christian Sonne

unread,
Jul 10, 2009, 12:43:33 PM7/10/09
to ubiquity...@googlegroups.com
On Fri, Jul 10, 2009 at 6:12 PM, Heather <heatherk...@gmail.com> wrote:

Atul and I have updated the Command Conversion tutorial to reflect the
addition of CmdUtil.parserVersion.  For versions prior to 0.1.9, you
can just check to see if it returns a value.

 if (!CmdUtils.parserVersion || CmdUtils.parserVersion == 1)

Wouldn't that be:
if (!CmdUtils.parserVersion || CmdUtils.parserVersion() == 1)
? (notice the "()")

-- cers / Christian Sonne

satyr

unread,
Jul 10, 2009, 7:00:49 PM7/10/09
to ubiquity...@googlegroups.com
On Sat, Jul 11, 2009 at 1:12 AM, Heather<heatherk...@gmail.com> wrote:
>  if (!CmdUtils.parserVersion || CmdUtils.parserVersion == 1)
>   //parser 1 command here
>  else
>   //parser 2 command here

Or:

if (CmdUtils.parserVersion == 2)
//parser 2 command here
else
//parser 1 command here

On Sat, Jul 11, 2009 at 1:43 AM, Christian Sonne<frea...@gmail.com> wrote:
> Wouldn't that be:
> if (!CmdUtils.parserVersion || CmdUtils.parserVersion() == 1)
> ? (notice the "()")

https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters

Christian Sonne

unread,
Jul 10, 2009, 7:11:42 PM7/10/09
to ubiquity...@googlegroups.com

Ahh - didn't realize it was a property - testing for existence made me think method, or your approach would more sense...
Reply all
Reply to author
Forward
0 new messages