<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>0xDECAFBAD - Tag: ubiquity</title>
    <link href="http://decafbad.com/blog/atom.xml" rel="self"/>
    <link href="http://decafbad.com/blog"/>
    <updated>2011-11-16T16:29:50+00:00</updated>
    <id></id>
    <author>
        <name></name>
        <email>l.m.orchard@pobox.com</email>
    </author>
    

    <entry>
        <title>Improving my Delicious command for Ubiquity</title>
        <link href="http://decafbad.com/blog/2008/09/07/improving-my-delicious-command-for-ubiquity"/>
        <updated>2008-09-07T05:20:20+00:00</updated>
        <id>http://decafbad.com/blog/2008/09/07/improving-my-delicious-command-for-ubiquity</id>
        <content type="html">&lt;p&gt;After writing up my &lt;a href=&quot;http://decafbad.com/blog/2008/09/01/writing-a-delicious-command-for-ubiquity&quot;&gt;first stab at a Delicious command for Ubiquity&lt;/a&gt;, I planned to continue revising it based on feedback and to work on exploring more of what Ubiquity enables.  I started looking into writing my own nouns for tag suggestions, as well as playing with page load and browser startup hooks.  And, I also started poking at a little bit of deeper extension development, which took up most of my time today.&lt;/p&gt;

&lt;p&gt;I've &lt;a href=&quot;http://decafbad.com/UbiquityCommands/&quot;&gt;updated my UbiquityCommands&lt;/a&gt; page and checked in my latest revision of &lt;a href=&quot;http://decafbad.com/hgwebdir.cgi/UbiquityCommands/file/tip/delicious.ubiq.js&quot;&gt;the Delicious command&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main new feature is a status bar item reporting bookmarks for the current page:&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;padding: 0.25em&quot; src=&quot;http://decafbad.com/2008/ubiq-del-status.jpg&quot; /&gt;&amp;nbsp;&lt;img style=&quot;padding: 0.25em&quot; src=&quot;http://decafbad.com/2008/ubiq-del-tip.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see above, the command now comes with a status bar panel powered by the &lt;a href=&quot;http://delicious.com/help/feeds&quot;&gt;Delicious URL info JSON feed&lt;/a&gt;, providing bookmarking info on every page visited.  It shows a bookmark count, a tooltip with further information, and sends the user to the URL info page on Delicious when clicked.  It mostly works, but it could use some looking at.  This is my first time really cracking open the hood on Firefox and XUL, and so I'm feeling around in the dark.&lt;/p&gt;

&lt;p&gt;Specifically, I'm using Ubiquity's page load hook—but I'm also trying to augment that by tracking tab selection events, in order to keep the status bar info updated for the active tab.  But then, that leads me to trying to track new windows, to attach the tab selection event handler for every newly opened window.  Or I could just be barking up the wrong tree entirely.  At any rate, the code is probably brain-dead dumb, so I hope someone can clue me into a better way.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088289&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://blog.mozilla.com/gen/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=ef1b5a29836fa211b938d8ccbbd3e0a1&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://blog.mozilla.com/gen/&quot;&gt;Gen Kanai&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088289&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-07T08:10:39&quot;&gt;2008-09-07T08:10:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Les, you may want to let R/RW know about your new command.&lt;/p&gt;

&lt;p&gt;http://www.readwriteweb.com/archives/the_ultimate_list_of_custom_ubiquity_verbs.php&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088292&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com/&quot;&gt;Abimanyu Raja&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088292&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-07T08:55:52&quot;&gt;2008-09-07T08:55:52&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I disagree... Your command doesn't fit on that list. It's way too good for that list. :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088296&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=61fc20fbb1afbfc057df523f9dae79da&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Jeton&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088296&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-07T21:56:43&quot;&gt;2008-09-07T21:56:43&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Well, i was having problems understanding the &quot;tagged&quot; and &quot;entitled&quot;. Didn't knew it was without brackets....&lt;/p&gt;

&lt;p&gt;But i gotta say, it actually replaces the delicious firefox extension for its easy way of posting links on delicious.&lt;/p&gt;

&lt;p&gt;Well done, and seeing that it's only the begining i don't doubt that it will improve much more!&lt;/p&gt;

&lt;p&gt;Oh, and i had a WTF when i first saw that delicous icon on the status bar of Firefox. Didn't knew it was from your command ;)&lt;/p&gt;

&lt;p&gt;Thanks for making this.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088300&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=61fc20fbb1afbfc057df523f9dae79da&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Jeton&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088300&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-07T22:20:09&quot;&gt;2008-09-07T22:20:09&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;One question:
Is there a chance to remove the quotation marks (i meant the same on the above comment as well, not brackets) when saving a note about a bookmark?&lt;/p&gt;

&lt;p&gt;Everytime i bookmark a page via this command, it quotes the note.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088302&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088302&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-07T22:41:20&quot;&gt;2008-09-07T22:41:20&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Jeton: I guess the quoted thing is something I do by habit, to discriminate between what's my comment and what's summary straight from the page.  One way you can force it unquoted is with the &quot;noted&quot; modifier.  So, select some text on the page, and you can do something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sha noted this tagged foo bar baz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That should use the selected text without quotes.  Also, you can just type arbitrary stuff:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sha noted These are notes entitled A title goes here tagged foo bar baz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088304&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088304&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-07T22:44:59&quot;&gt;2008-09-07T22:44:59&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Jeton: Actually, I just made a check-in that flips it around.  There's now a &quot;quoted&quot; modifier to wrap the notes in quotes, leaving it unquoted otherwise.  I might be the weirdo here in my quote usage :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088306&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jackmottram.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3a6aa11eff36e9d968119a6bb4cea05e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jackmottram.com/&quot;&gt;Jack Mottram&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088306&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-09T10:04:12&quot;&gt;2008-09-09T10:04:12&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I'm a weirdo too, and now I can't quite work out how to get quotes around stuff I'm quoting from a page. I assumed this would work:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sha this quoted&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;but it just adds the word 'quoted' to the end of the quoted text, without quotes.&lt;/p&gt;

&lt;p&gt;Similarly:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sha quoted this tagged test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;adds the words 'tagged' and 'test' to the end of the quoted text, though this time everything _is_ in quotes. (So it seems I can get quotes, but lose the ability to tag in the process.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sha this quoted text&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;puts the word 'text' in quotes, but drops the selected text...&lt;/p&gt;

&lt;p&gt;So, I give up - what's the secret to getting quotes around quoted text?!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088310&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jackmottram.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3a6aa11eff36e9d968119a6bb4cea05e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jackmottram.com/&quot;&gt;Jack Mottram&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088310&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-09T10:11:59&quot;&gt;2008-09-09T10:11:59&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;And of course I worked it out immediately after leaving that comment:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sha tagged test monkey whatever quoted this&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;works just fine (but feels the wrong way around to be tagging before quoting). And now I can't work out how to quote &lt;i&gt;and&lt;/i&gt; note, so to speak. I tried adding&lt;/p&gt;

&lt;p&gt;&lt;code&gt;noted These are my comments on what I just quoted&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;but it doesn't work, it puts 'noted These are my &amp;amp;c.' inside the quotes...&lt;/p&gt;

&lt;p&gt;(I should say, despite all this moaning, I really have been enjoying using the command - it's very slick compared to the official add-on.)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088312&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088312&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-09T14:30:06&quot;&gt;2008-09-09T14:30:06&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Huh, weird - that's exactly how I use the command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sha quoted this tagged foo bar baz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One major difference, though, is that I'm using a bleeding edge checkout of the Ubiquity extension.  I wonder if there's a bug in the parser for the last release.  :(  &lt;/p&gt;

&lt;p&gt;The definition of the modifiers is pretty simple, so there's not a whole lot of debugging I can do in the command itself.  Ugh.&lt;/p&gt;

&lt;p&gt;Oh, and also: RIght now it's either plain notes or quoted notes.  Presence of the quoted modifier clobbers plain notes.  But, how that I think about it I wonder if I should make those work together.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088314&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://FromTheGut.us&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3be27db3db50892929ef892ab04621a4&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://FromTheGut.us&quot;&gt;Frank&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088314&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-09T17:40:39&quot;&gt;2008-09-09T17:40:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hello, &lt;/p&gt;

&lt;p&gt;I was wondering if there was any chance you could put together a post annotating/explaining the changes/additions to your improved Delicious command. In particular, some explanations of the code dealing with the statusbar would be helpful for us beginners. Thanks.&lt;/p&gt;

&lt;p&gt;Frank&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088317&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=357a20e8c56e69d6f9734d23ef9517e8&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Tony&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088317&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-22T05:12:52&quot;&gt;2008-10-22T05:12:52&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Not a big fan of things adding stuff my status bar. :/ Ubiquity commands should just focus on Ubiquity, not XUL changes in Firefox.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088320&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088320&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-29T16:04:28&quot;&gt;2008-10-29T16:04:28&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Tony: Actually, commands are just one of the goals of Ubiquity.  Easier XUL hacking, ala Greasemonkey, is another goal, albeit under-explored so far.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088321&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://dy-verse.blogspot.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=40e05965a0c35ba44927a8e4b0546f9d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://dy-verse.blogspot.com/&quot;&gt;http://dy-verse.blogspot.com/&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088321&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-27T14:50:43&quot;&gt;2009-04-27T14:50:43&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Here is a share-to-delicious ubiquity command that automatically generates tags using YAHOO pipes. It also uses the text selected on the page as notes and the page title as the title of the article. &lt;/p&gt;

&lt;p&gt;http://gist.github.com/26425&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088327&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088327&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-28T05:25:58&quot;&gt;2009-04-28T05:25:58&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Auto-generating tags via Yahoo Pipes is a neat trick, but it's unfortunately very much frowned upon by delicious.  Not that anything negative will happen to you, but it defeats the purpose of tagging altogether.&lt;/p&gt;

&lt;p&gt;Try searching for &quot;Lazy Sheep Bookmarklet&quot; and possibly read:&lt;/p&gt;

&lt;p&gt;http://www.mail-archive.com/ydn-delicious@yahoogroups.com/msg00853.html&lt;/p&gt;

&lt;p&gt;In particular - &quot;People add metadata so that 1) they can find things and 2) other people can find things. You are removing the step in which people add the tag metadata, thus making the system less valuable to themselves and others.&quot;&lt;/p&gt;

&lt;p&gt;The key word repeated there is &quot;people&quot;&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Writing a Delicious command for Ubiquity</title>
        <link href="http://decafbad.com/blog/2008/09/01/writing-a-delicious-command-for-ubiquity"/>
        <updated>2008-09-01T04:37:03+00:00</updated>
        <id>http://decafbad.com/blog/2008/09/01/writing-a-delicious-command-for-ubiquity</id>
        <content type="html">&lt;p&gt;In my &lt;a href=&quot;http://decafbad.com/blog/2008/08/31/ubiquity-cracks-open-personal-mashup-tinkering&quot; title=&quot;Ubiquity cracks open personal mashup tinkering&quot;&gt;last post&lt;/a&gt;, I got all fluffy about how cool &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; is but didn't share any code to prove the point.  As it happens, I have come up with at least one useful command that I'm starting to use habitually in posting bookmarks to Delicious.  You can &lt;a href=&quot;http://decafbad.com/UbiquityCommands/&quot;&gt;subscribe to my command&lt;/a&gt; or &lt;a href=&quot;http://decafbad.com/hg/UbiquityCommands/file/tip/delicious.ubiq.js&quot;&gt;check out the full source&lt;/a&gt;—this post will serve as a dissection of the thing.  Since this will be fairly lengthy, follow along after the jump.&lt;/p&gt;

&lt;p&gt;Oh, and it's been awhile since I posted something this in-depth around here, so feel free to let me know how this first draft works.  And, bug reports and patches are of course welcome.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;To begin, consider the following code starting off the command source code:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
/**
 * share-on-delicious - an Ubiquity command for sharing bookmarks on
 * delicious.com
 *
 * l.m.orchard@pobox.com
 * http://decafbad.com/
 * Share and Enjoy!
 */
var uext = Application.extensions.get('ubiquity@labs.mozilla.com');

var cookie_mgr = Components.classes[&quot;@mozilla.org/cookiemanager;1&quot;]
    .getService(Components.interfaces.nsICookieManager);
&lt;/pre&gt;


&lt;p&gt;The first thing to note here is that a short header comment introduces the command.  This isn't required, but it's a good idea.  It's also something you can't really do with bookmarklets.  On the other hand, Greasemonkey user scripts expect metadata about the script to be provided here, but Ubiquity doesn't use this convention.&lt;/p&gt;

&lt;p&gt;Second, notice that the code accesses some chrome-level resources.  Again, this is something unavailable to bookmarklets and Greasemonkey user scripts.  Just take a look at the &lt;a href=&quot;http://developer.mozilla.org/en/FUEL&quot;&gt;FUEL library documentation&lt;/a&gt; to get a quick sense of what's available using that simplified API, not to mention what's available using the lower-level browser APIs.&lt;/p&gt;

&lt;p&gt;Now, check out this next chunk of code, which begins the construction of an Ubiquity command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;13&quot;&gt;
CmdUtils.CreateCommand({
    
    name:        
        'share-on-delicious',
    icon:
        'http://delicious.com/favicon.ico',
    description: 
        'Share the current page as a bookmark on delicious.com',
    help:        
        'Select text on the page to use as notes, or enter your own ' + 
        'text after the command word.  You can also assign tags to the '+ 
        'bookmark with the &quot;tagged&quot; modifier, and alter the bookmark ' + 
        'default page title with the &quot;entitled&quot; modifier.  Note that ' + 
        'you must also already be logged in at delicious.com to use ' +
        'this command.',

    homepage:   
        'http://decafbad.com',
    author: { 
        name: 'Leslie Michael Orchard', 
        email: 'l.m.orchard@pobox.com' 
    },
    license:
        'MPL/GPL/LGPL',
&lt;/pre&gt;


&lt;p&gt;Whereas Greasemonkey scripts support metadata in the header comment, the Ubiquity command script API works a little differently.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/chrome/content/cmdutils.js&quot;&gt;&lt;code&gt;CmdUtils&lt;/code&gt; module&lt;/a&gt; provided by Ubiquity offers a &lt;code&gt;CreateCommand&lt;/code&gt; function, which expects an object as a parameter.  The object literal whose construction is begun in the code above serves as a self-contained package for the command, bearing metadata describing the command as well as containing all the code necessary to implement it.&lt;/p&gt;

&lt;p&gt;So, in the above code block, you can see the machine-readable description of the command—including a command name, display icon, home page URL, author information, and license.  The command name (&lt;code&gt;share-on-delicious&lt;/code&gt;) will be used by the Ubiquity command parser, but the rest of the description will also be used in the list of commands available to the user, invoked by the &lt;code&gt;command-list&lt;/code&gt; command, like so:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/2008/ubiq-share-on-delicious-list.jpg&quot; style=&quot;border: 1px solid #333; margin: 0.25em; padding: 0.25em&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Moving along, this next chunk of code introduces the first functional bits of the command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;37&quot;&gt;
    takes: { notes: noun_arb_text },
    modifiers: { 
        tagged:  noun_arb_text,
        entitled: noun_arb_text
    },
&lt;/pre&gt;


&lt;p&gt;Like smart keyword shortcut bookmarks, Ubiquity commands accept user-supplied input.  But, what's unique to Ubiquity is that it employs a parser whose goal is to support something approximating natural language.  At present, this results in commands that support a single primary argument—declared above with the &lt;code&gt;takes&lt;/code&gt; property—and any number of additional keyword modifiers—declared above by the &lt;code&gt;modifiers&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;For the command under construction here, this establishes a pattern something like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;share-on-delicious {notes} [tagged {tags} entitled {title}]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Content for the &lt;code&gt;{notes}&lt;/code&gt; argument can either be typed directly by hand, or it can be supplied by text highlighted on the page.  To use highlighted text, you can either issue the command alone, or use the word &lt;code&gt;this&lt;/code&gt; for the &lt;code&gt;{notes}&lt;/code&gt; argument before including further modifiers.&lt;/p&gt;

&lt;p&gt;The modifiers &lt;code&gt;tagged&lt;/code&gt; and &lt;code&gt;entitled&lt;/code&gt; are optional, and can be used in any order.  Each of these keywords signifies the start of a different argument—which unfortunately can collide with the literal data supplied for notes, which will hopefully be a rare occurrence.&lt;/p&gt;

&lt;p&gt;All of this adds up command invocations including the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;share-on-delicious
share-on-delicious I really like this page tagged nifty amusing
share-on-delicious this entitled This bookmark has no tags
sh this tagged osx software apple entitled This is good OS X software
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That last example is important—since I have no other commands starting with &quot;&lt;code&gt;sh&lt;/code&gt;&quot;, I can abbreviate the full command.  Ubiquity only requires enough of a command name to disambiguate it within your collection of commands.&lt;/p&gt;

&lt;p&gt;Another thing to note is the use of the constant value &lt;code&gt;noun_arb_text&lt;/code&gt;, which declares that these arguments should expect any arbitrary text as input.&lt;/p&gt;

&lt;p&gt;This facility is not exploited for the present command, but Ubiquity defines &lt;a href=&quot;http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/chrome/content/nlparser/en/nountypes.js&quot;&gt;noun types&lt;/a&gt;.  These include concepts such as plain text, dates, address book contacts, browser tabs, bookmark tags, and more.  You can define your own noun types, as well as implement suggestion schemes that help guide the user toward constructing useful input values in the command interface.  You can &lt;a href=&quot;https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial#Introduction_to_Noun_Types&quot;&gt;read more about this&lt;/a&gt; in the official author tutorial.&lt;/p&gt;

&lt;p&gt;Next up is a quick bit of command-specific configuration:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;42&quot;&gt;
    /**
     * Command configuration settings.
     */
    _config: {
        // Base URL for the delicious v1 API
        api_base:      'https://api.del.icio.us',

        // Domain and name of the delicious login session cookie.
        cookie_domain: '.delicious.com',
        cookie_name:   '_user'
    },
&lt;/pre&gt;


&lt;p&gt;Since this command will be posting to Delicious via the V1 API, it's handy to declare the base URL for the API in an easily changed spot.  That way, you could change this value later on to point the command at another implementation of the API.&lt;/p&gt;

&lt;p&gt;Additionally, this command will employ a little-known authentication trick supported by the Delicious API that accepts the user's login cookie set by the Delicious website—this &quot;cookie god&quot; auth is used by the official Delicious addon for Firefox.  It's handy for piggybacking on the website login and removing the need to ask the user for their username and password again and possibly storing it in an insecure manner.&lt;/p&gt;

&lt;p&gt;In fact, this next chunk of code defines a utility method to rummage through the cookie jar:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;53&quot;&gt;
    /**
     * Dig up the Delicious login session cookie.
     */
    _getUserCookie: function() {
        var iter = cookie_mgr.enumerator;
        while (iter.hasMoreElements()) {
            var cookie = iter.getNext();
            if( cookie instanceof Components.interfaces.nsICookie &amp;&amp; 
                cookie.host.indexOf(this._config.cookie_domain) != -1 &amp;&amp; 
                cookie.name == this._config.cookie_name) {
                return decodeURIComponent(cookie.value);
            }
        }
    },
&lt;/pre&gt;


&lt;p&gt;The method defined above, &lt;code&gt;._getUserCookie()&lt;/code&gt;, uses the browser's cookie manager and the values defined in the previous configuration section to find the login session cookie set for Delicious.  Take note that this is far beyond the allowed capabilities of bookmarklets and Greasemoney user scripts—this is digging straight into the browser itself, skipping past the usual content-space security restrictions.&lt;/p&gt;

&lt;p&gt;In other words: In Ubiquity, &lt;em&gt;the gun is loaded&lt;/em&gt; and you should be careful.&lt;/p&gt;

&lt;p&gt;Moving along, consider this next utility method:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;67&quot;&gt;
    /**
     * Given input data and modifiers, attempt to assemble data necessary to
     * post a bookmark.
     */
    _extractBookmarkData: function(input_obj, mods) {
        return {
            _user:
                this._getUserCookie(),
            url:
                context.focusedWindow.location,
            description:
                mods.entitled.text || context.focusedWindow.document.title,
            extended: 
                input_obj.text,
            tags:
                mods.tagged.text
        };
    },
&lt;/pre&gt;


&lt;p&gt;Named &lt;code&gt;._extractBookmarkData()&lt;/code&gt;, this utility method accepts the results of Ubiquity's parser interpreting the primary argument and modifier arguments supplied by the user.  Using these data structures, it attempts to build a structure representing the fields of a Delicious bookmark.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;_user&lt;/code&gt; field is used for authentication via the site login cookie.  The &lt;code&gt;url&lt;/code&gt; is set from the location bar of the current page.  The &lt;code&gt;description&lt;/code&gt;, or title, field of the bookmark is taken from either the &lt;code&gt;entitled&lt;/code&gt; modifier or the title of the current page.  The &lt;code&gt;tags&lt;/code&gt;, if any, come from the &lt;code&gt;tagged&lt;/code&gt; modifier.  And, finally, the &lt;code&gt;extended&lt;/code&gt; notes for the bookmark are taken from the primary input argument of the command.&lt;/p&gt;

&lt;p&gt;As you'll see shortly, this utility method will be used in both the preview and the execution of the command.&lt;/p&gt;

&lt;p&gt;Next, there's one more utility method to cover:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;85&quot;&gt;
    /**
     * Given an object, build a URL query string
     */
    _buildQueryString: function(data) {
        var qs = [];
        for (k in data) if (data[k]) 
            qs.push( encodeURIComponent(k) + '=' + 
                encodeURIComponent(data[k]) );
        return qs.join('&amp;');
    },
&lt;/pre&gt;


&lt;p&gt;In anticipation of using the Delicious V1 API, the &lt;code&gt;._buildQueryString()&lt;/code&gt; method accepts an object and constructs a URL query string from the encoded properties of the object.  This will be paired with the &lt;code&gt;._extractBookmarkData()&lt;/code&gt; method to supply data for API calls.&lt;/p&gt;

&lt;p&gt;Moving along, it's time to start digging into the meat of this Ubiquity command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;95&quot;&gt;
    /**
     * Present a preview of the bookmark under construction during the course
     * of composing the command.
     */
    preview: function(pblock, input_obj, mods) {

        var bm          = this._extractBookmarkData(input_obj, mods);
        var user_cookie = this._getUserCookie();
        var user_name   = (user_cookie) ? user_cookie.split(' ')[0] : '';

        var ns = { user_name: user_name, bm: bm };
        var tmpl;
&lt;/pre&gt;


&lt;p&gt;With this code, the implementation of command method &lt;code&gt;.preview()&lt;/code&gt; has begun.  This method is used by Ubiquity to generate a live preview of the command.  Called with a DOM node (&lt;code&gt;pblock&lt;/code&gt;) and partially completed command input (&lt;code&gt;input_obj&lt;/code&gt; and &lt;code&gt;mods&lt;/code&gt;), this method is expected to build a representation of the command's results in the DOM node.  As the user types, this method will be called over and over again, ideally offering feedback as the user composes a command.&lt;/p&gt;

&lt;p&gt;Continuing on, consider this next chunk of code checking the validity of command input:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;107&quot;&gt;
        if (!user_name) {

            // If there's no user name, there's no login, so this command won't work. 
            tmpl = [ 
                '&lt;p style=&quot;color: #d44&quot;&gt;No active user found - log in at ', 
                '&lt;img src=&quot;http://delicious.com/favicon.ico&quot;&gt; ',
                '&lt;b&gt;&lt;a style=&quot;color: #3774D0&quot; href=&quot;http://delicious.com&quot;&gt;delicious.com&lt;/a&gt;&lt;/b&gt; ', 
                'to use this command.&lt;/p&gt;'
            ].join('');

        } else if (!bm.description) {

            // If there's no title, then this is an error too.
            tmpl = [ 
                '&lt;p style=&quot;color: #d44&quot;&gt;A title is required for bookmarks on ', 
                '&lt;img src=&quot;http://delicious.com/favicon.ico&quot;&gt; ',
                '&lt;b&gt;&lt;a style=&quot;color: #3774D0&quot; href=&quot;http://delicious.com&quot;&gt;delicious.com&lt;/a&gt;&lt;/b&gt; ', 
                '&lt;/p&gt;'
            ].join('');
&lt;/pre&gt;


&lt;p&gt;This chunk of code first checks for a user name, which can be extracted from a valid Delicious login cookie, if one was found.  If not found, the command will fail—so the preview built here will instruct the user to login at Delicious before going further.&lt;/p&gt;

&lt;p&gt;The second precondition for using the command is that the bookmark has been given a title.  By default, this is the title of the current page—but, some pages don't offer titles.  So, an error needs to be flagged if the user hasn't manually supplied a title in this case.&lt;/p&gt;

&lt;p&gt;Finally, notice in both of these error cases, a string of HTML is composed in the variable &lt;code&gt;tmpl&lt;/code&gt;.  This will be used at the end of the method to populate the DOM node passed in as &lt;code&gt;pblock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, assuming that all the command's prerequisites have been met, it's time to try constructing a proper preview for the results of this command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;126&quot;&gt;
        } else {

            // Attempt to construct a vaguely delicious-esque preview of a bookmark.
            tmpl = [ 
                '&lt;style type=&quot;text/css&quot;&gt;',
                    '.preview a { color: #3774D0 }',
                    '.del-bookmark { font: 12px arial; color: #ddd; background: #eee; line-height: 1.25em }',
                    '.del-bookmark a.title { color: #1259C7 }',
                    '.del-bookmark .full-url { color: #396C9B; font-size: 12px; display: block; padding: 0.25em 0 }',
                    '.del-bookmark .notes { color: #4D4D4D }',
                    '.del-bookmark .tags { color: #787878; padding-top: 0.25em; text-align: right }',
                '&lt;/style&gt;',
                '&lt;div class=&quot;preview&quot;&gt;',
                    '&lt;p&gt;Share a bookmark at &lt;img src=&quot;http://delicious.com/favicon.ico&quot;&gt; ',
                        '&lt;b&gt;&lt;a href=&quot;http://delicious.com/${user_name}&quot;&gt;delicious.com/${user_name}&lt;/a&gt;&lt;/b&gt;:&lt;/p&gt;',
                    '&lt;div class=&quot;del-bookmark&quot;&gt;',
                        '&lt;div style=&quot;padding: 1em;&quot;&gt;',
                        '&lt;a class=&quot;title&quot; href=&quot;${bm.url}&quot;&gt;${bm.description}&lt;/a&gt;',
                        '&lt;a class=&quot;full-url&quot; href=&quot;${bm.url}&quot;&gt;${bm.url}&lt;/a&gt;',
                        bm.extended ? 
                            '&lt;div class=&quot;notes&quot;&gt;${bm.extended}&lt;/div&gt;' : '',
                        bm.tags ?
                            '&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;tags:&lt;/span&gt; ${bm.tags}&lt;/div&gt;' : '',
                    '&lt;/div&gt;',
                '&lt;/div&gt;'
            ].join(&quot;\n&quot;);

        }

        pblock.innerHTML = CmdUtils.renderTemplate(tmpl, ns);
    },
&lt;/pre&gt;


&lt;p&gt;Building on the notion that previews are built in a DOM node, the code above uses both CSS and HTML to assemble a quick-and-dirty facsimile of a Delicious bookmark—which will be rendered like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/2008/ubiq-share-on-delicious-preview.jpg&quot; style=&quot;border: 1px solid #333; margin: 0.25em; padding: 0.25em&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also note that Ubiquity provides a template engine for use in generating content—namely the &lt;a href=&quot;http://code.google.com/p/trimpath/wiki/JavaScriptTemplates&quot;&gt;JavaScript Templates&lt;/a&gt; engine from the &lt;a href=&quot;http://code.google.com/p/trimpath/wiki/TrimPath&quot;&gt;TrimPath&lt;/a&gt; project.  This engine may eventually be replaced with another, but the notion is that Ubiquity will provide tools to more easily generate previews and more.&lt;/p&gt;

&lt;p&gt;The conclusion of the &lt;code&gt;.preview()&lt;/code&gt; method uses the template engine with a call to &lt;code&gt;CmdUtils.renderTemplate()&lt;/code&gt; to inject content into the preview element by way of the &lt;code&gt;.innerHTML&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Now that the preview is out of the way, it's time to get down to implementing the execution of the command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;157&quot;&gt;    
    /**
     * Attempt to use the delicious v1 API to post a bookmark using the 
     * command input
     */
    execute: function(input_obj, mods) {
        var bm          = this._extractBookmarkData(input_obj, mods);
        var user_cookie = this._getUserCookie();
        var user_name   = (user_cookie) ? user_cookie.split(' ')[0] : '';

        if (!user_name) {
            // If there's no user name, there's no login, so this command won't work. 
            displayMessage('No active user found - log in at delicious.com ' +
                'to use this command.');
            return false;
        }

        if (!bm.description) {
            // If there's no title, somehow, then this is an error too.
            displayMessage(&quot;A title is required for bookmarks at delicious.com&quot;);
            return false;
        }
&lt;/pre&gt;


&lt;p&gt;Mirroring the &lt;code&gt;.preview()&lt;/code&gt; method, the &lt;code&gt;.execute()&lt;/code&gt; method first checks for validity of the arguments given by the user.  A missing user name or title result in a notification that the command has failed.&lt;/p&gt;

&lt;p&gt;But, if the arguments are all valid, it's time to actually issue a request to the Delicious V1 API:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;178&quot;&gt;
        var path = '/v1/posts/add';
        var url  = this._config.api_base + path;

        var req = Components.classes[&quot;@mozilla.org/xmlextras/xmlhttprequest;1&quot;].
            createInstance();

        req.open('POST', url, true);

        req.onload = function(ev) { 
            displayMessage('Bookmark &quot;' + bm.description + '&quot; ' + 
                'shared at delicious.com/' + user_name);
        }

        req.onerror = function(ev) { 
            displayMessage('ERROR: Bookmark &quot;' + bm.description + '&quot; ' + 
                ' NOT shared on delicious.com/' + user_name);
        }
&lt;/pre&gt;


&lt;p&gt;Using the base URL for the Delicious API declared earlier in the configuration section, the &lt;code&gt;.execute()&lt;/code&gt; method constructs an API URL for the &lt;code&gt;/v1/posts/add&lt;/code&gt; method.  Then, it creates an instance of &lt;code&gt;XMLHttpRequest&lt;/code&gt; from the browser to be used in sending the API request.  Event handlers are registered with the object to present notifications to the user indicating whether or not the API request was successful.&lt;/p&gt;

&lt;p&gt;At long last, it's time to wrap up this method and make the API request:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;195&quot;&gt;
        req.setRequestHeader('Authorization', 'Basic Y29va2llOmNvb2tpZQ=='); // btoa('cookie:cookie')

        var mediator = Components.classes[&quot;@mozilla.org/appshell/window-mediator;1&quot;].
            getService(Components.interfaces.nsIWindowMediator);
        var win = mediator.getMostRecentWindow(null);
        var user_agent = win.navigator.userAgent + &quot;;Ubiquity-share-on-delicious&quot;;

        req.setRequestHeader(&quot;User-Agent&quot;, user_agent);      

        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.send(this._buildQueryString(bm));
    },

    EOF:null // I hate trailing commas
});
&lt;/pre&gt;


&lt;p&gt;The login cookie authentication supported by the Delicious V1 API is triggered by supplying a user name / password pair of &lt;code&gt;cookie&lt;/code&gt;, which is done by setting the &lt;code&gt;Authorization&lt;/code&gt; request header.  The login cookie is then expected to be passed in as the POST variable &lt;code&gt;_user&lt;/code&gt;, which is done in the &lt;code&gt;._extractBookmarkData()&lt;/code&gt; utility method.&lt;/p&gt;

&lt;p&gt;Another bit here that shows more access of browser resources is the construction of a unique User-Agent header for this API call based on the browser's own User-Agent string, something that's suggested in the guidelines for using the Delicious API.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;.execute()&lt;/code&gt; method—and the command itself—is wrapped up with by sending off the bookmark data encoded as POST form variables with the &lt;code&gt;._buildQueryString()&lt;/code&gt; utility method.&lt;/p&gt;

&lt;p&gt;And, that's it—a command-driven Delicious browser extension in a little over 200 lines of code.  There's still more to be done to really make this thing full-featured, but I think this shows off the basic features of Ubiquity.  I'm hoping to dig in deeper and explore further, taking a look at running Greasemonkey-style code at &lt;a href=&quot;https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial#Running_on_page_load_and_startup&quot;&gt;browser startup and page load&lt;/a&gt;, as well as playing with some more browser chrome features.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085986&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jclark.org/weblog/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=d0a9ab4b71ce193e98b7284ca257e327&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jclark.org/weblog/&quot;&gt;Jason Clark&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085986&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T14:47:35&quot;&gt;2008-09-01T14:47:35&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;First off-  fantastic post.  Great to see a lengthy post here again, although I'm one to talk.  This is an excellent introduction to Ubiquity command development, and tres useful to boot.&lt;/p&gt;

&lt;p&gt;I'm wondering why you chose to construct and post the XMLHttpRequest manually instead of using jQuery, which is included with Ubiquity.  I don't know that there's any benefit other than some simplicity, but I took a crack at converting your code to use jQuery, which works nicely.  In the 'execute' function, replace everything after &quot;var url  = this._config.api_base + path;&quot; with this (hope code blocks work in comments):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
        var win = context.focusedWindow;
        var user_agent = win.navigator.userAgent + &quot;;Ubiquity-share-on-delicious&quot;;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    jQuery.ajax({
      type: &quot;POST&quot;,
      url: url,
      data: this._buildQueryString(bm),
      username: &quot;cookie&quot;,
      password: &quot;cookie&quot;,
      beforeSend: function( req ) {
        req.setRequestHeader(&quot;User-Agent&quot;, user_agent); 
      },
      error: function() {
        displayMessage('ERROR: Bookmark &quot;' + bm.description + '&quot; ' + 
            ' NOT shared on delicious.com/' + user_name);
      },
      success: function() {
        displayMessage('Bookmark &quot;' + bm.description + '&quot; ' + 
            'shared at delicious.com/' + user_name);
      },
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Also, with both versions of the code, I'm seeing some unexpected behavior around authentication.  Assume I'm logged in to delicious, with &quot;stay logged in&quot; checked, and I restart my browser.  Trying to post with the command fails with a 401 unauthorized, even though I can see the cookie was sent (via Live HTTP Headers extension).  Going to delicious.com shows me logged in, and once I've viewed the site, the command works.  Except that now I can't reproduce; but I know it happened because I've got the headers.  At any rate, it is working nicely, but the previous failure is bugging me... feel like I'm overlooking something.  &lt;/p&gt;

&lt;p&gt;Thanks again for an awesome post.  Hope to see more of the same.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085988&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=e799a79441c7543be48562403411cd13&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Ryan Scott Scheel&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085988&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T15:07:01&quot;&gt;2008-09-01T15:07:01&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;You should be helping with the documentation, if you aren't already.  Very nice job with this article;&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085991&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://azarask.in&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=e4307f205d017ba76647806951e14bb0&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://azarask.in&quot;&gt;Aza Raskin&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085991&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-02T01:44:13&quot;&gt;2008-09-02T01:44:13&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi Leslie,&lt;/p&gt;

&lt;p&gt;This is a beautiful tutorial on writing a Ubiquity command. We'd love your help in making Ubiquity's documentation better (especially dev facing). You should totally link to this from the Ubiquity Wiki -- or even add the content in someway.&lt;/p&gt;

&lt;p&gt;Anyway, just wanted to say thanks.&lt;/p&gt;

&lt;p&gt;-- Aza&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085993&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.slackorama.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=15b474c86cd73c2d12c1d77af11c1d8a&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.slackorama.com&quot;&gt;seth&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085993&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-08T17:30:16&quot;&gt;2008-09-08T17:30:16&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Am I doing something wrong?  &lt;/p&gt;

&lt;p&gt;When I enter in &quot;sh this tagged tag1 tag2 entitled This is a title&quot; everything after the tagged is added as a tag. It's not seeing the entitled part.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085994&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spyced.blogspot.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=849810634810c960e5e7c27fa54a0f5b&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spyced.blogspot.com/&quot;&gt;http://spyced.blogspot.com/&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085994&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-15T19:12:58&quot;&gt;2008-09-15T19:12:58&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Did something break?  I'm getting a 404 accessing http://decafbad.com/hg/UbiquityCommands/file/tip/delicious.ubiq.js&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085995&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085995&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-15T23:07:42&quot;&gt;2008-09-15T23:07:42&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Yeah, looks like I had a small snafu with switching back from Lighttpd to Apache.  Left out a rewrite rule - doh!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085996&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=357a20e8c56e69d6f9734d23ef9517e8&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Tony&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085996&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-22T04:56:03&quot;&gt;2008-10-22T04:56:03&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Great article. This is replacing my delicious bookmarklet. Thanks!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085997&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=31461076fcbce091ff822fc9ac31315d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;dgtlchlk&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085997&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T01:06:57&quot;&gt;2009-04-14T01:06:57&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Great article and command.
Wish it worked correctly with the latest 0.1.8 release though. No matter what text you put in it adds everything as the notes. The tagged and entitled modifiers don't work.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085999&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.nolanhergert.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=957e24509baf770ba57ad306e20f201c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.nolanhergert.com&quot;&gt;Nolan&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085999&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-16T03:10:07&quot;&gt;2009-04-16T03:10:07&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I second that comment. Delicious is actually saying the link given was &quot;chrome://browser/content/browser.xul&quot; and marking it as harmful inside delicious!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086002&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3d056a5b07c384647fe0806b0dfc429e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Justin&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086002&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-06T12:39:39&quot;&gt;2009-07-06T12:39:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi Leslie,&lt;/p&gt;

&lt;p&gt;Thanks for the delicious ubiquity command. Unfortunately, as one of the commenters above mentions, the tagged modifier doesn't seem to work. I'm using Ubiquity 0.5 pre and typing the phrase:&lt;/p&gt;

&lt;p&gt;share tagged foo&lt;/p&gt;

&lt;p&gt;Adds the bookmark to Delicious with the note text &quot;tagged foo&quot;&lt;/p&gt;

&lt;p&gt;Cheers, Justin&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086004&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://ericscalf.com/stream&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=0775f9beff626496b86d7cb602e5f46f&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://ericscalf.com/stream&quot;&gt;Eric&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086004&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-20T22:43:17&quot;&gt;2009-07-20T22:43:17&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Echoing others.. I'm using the latest ubiquity (err, next to latest.. 0.1.8?), and doing &quot;share-on-delicious this is a note tagged testing&quot; saves the link with notes &quot;this is a note tagged testing&quot; and no tags. :(  Then again, the other delicious command I've found (by someone else) is having the same issue.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Ubiquity cracks open personal mashup tinkering</title>
        <link href="http://decafbad.com/blog/2008/08/31/ubiquity-cracks-open-personal-mashup-tinkering"/>
        <updated>2008-08-31T04:07:22+00:00</updated>
        <id>http://decafbad.com/blog/2008/08/31/ubiquity-cracks-open-personal-mashup-tinkering</id>
        <content type="html">&lt;p&gt;When I was a wee hacker, I lived my digital life though a &lt;a href=&quot;http://www.virtualsky.net/iadoremyc64/&quot;&gt;Commodore 64&lt;/a&gt;.  I played games on it, did homework, talked to people far away—you know, all the stuff they showed in the pictures on the box.  I also took things apart—both the machine itself and software running on it.  I grew up learning that my digital environment was ultimately understandable, &lt;a href=&quot;http://cbm.csbruce.com/~csbruce/cbm/transactor/&quot;&gt;susceptible to tinkering&lt;/a&gt;, and open to being bent to my own purposes.&lt;/p&gt;

&lt;p&gt;From the Commodore 64, I graduated eventually to terminals and text editors, opening portals mostly onto computers elsewhere via powerful UNIX command shells.  And, of course, over the past decade, this has largely given way to life in a browser.&lt;/p&gt;

&lt;p&gt;Yet, for a little while, particularly in the first few years of browsers, freedom to tinker seemed cramped.  JavaScript had yet to arrive, and was a little messy when it did.  There was no relatively easy addon development.  And, though the portals opened by a browser were richer than those provided by terminals, the paths of navigation defined by links controlled by site owners offered less freedom of movement than UNIX commands.  I could create my own pages, but I couldn't do much to others' pages.&lt;/p&gt;

&lt;p&gt;But then, javascript: URLs came around, dots were connected, and &lt;a href=&quot;http://en.wikipedia.org/wiki/Bookmarklet&quot;&gt;bookmarklets&lt;/a&gt; were born.  Suddenly, it was possible to customize &lt;em&gt;my&lt;/em&gt; browsing environment with arbitrary JavaScript code having access to the current page—no matter &lt;em&gt;whose&lt;/em&gt; page it was.  And, through the various tricks of the AJAX trade, bookmarklets have only gotten more capable throughout the years.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.mozilla.org/docs/end-user/keywords.html&quot;&gt;Smart keyword shortcuts&lt;/a&gt; came around a little later, allowing quick access to bookmarks via simple keywords typed into the location bar.  The smart part, though, came in the form of bookmarked URLs with placeholders and keywords given arguments to fill the placeholders—allowing not only quick access to bookmarked pages but also search engine forms bookmarked with late-bound fields.&lt;/p&gt;

&lt;p&gt;Bookmarklets inherited the benefits of smart keyword shortcuts.  The same placeholder in http: URLs can be inserted into the code of a javascript: URL, thus parameterizing the JavaScript code and incidentally turning the location bar into a kind of primitive command line.  For example, one of my most heavily used &quot;&lt;a href=&quot;http://naeblis.cx/weblog/2004/08/09/DeliciousAddresslets&quot;&gt;addresslets&lt;/a&gt;&quot; is based on &lt;a href=&quot;http://ejohn.org/blog/super-fast-delicious-bookmarklet/&quot;&gt;John Resig's original &quot;Super-Fast Delicious Bookmarklet&quot;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another leap in prying open the browser tinkering space came in the form of &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt;—an addon-powered environment created explicitly for the purpose of end-user scripting applied to others' pages.  &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt; user scripts can do more than bookmarklets, and with a much better development environment to boot.  And, though a user script can't do quite as much as a proper browser addon, they're much easier to hack on and distribute.&lt;/p&gt;

&lt;p&gt;Now, consider one of &lt;a href=&quot;http://labs.mozilla.com/&quot;&gt;Mozilla Labs&lt;/a&gt;' &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;newest projects&lt;/a&gt;, named &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt;.  This rough and experimental addon for Firefox combines and improves upon everything I've described so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; is a hackable command line environment, better than &lt;a href=&quot;http://en.wikipedia.org/wiki/Bookmarklet&quot;&gt;bookmarklets&lt;/a&gt; and smart &lt;a href=&quot;http://www.mozilla.org/docs/end-user/keywords.html&quot;&gt;keyword shortcuts&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; enables persistent customization of others' pages, not unlike &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; facilitates live in-browser creation and web-based subscription to user commands and scripts;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; gives access to browser chrome resources without a need for frequent restarts;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So far, most of the &lt;a href=&quot;https://labs.toolness.com/ubiquity-herd/&quot;&gt;commands&lt;/a&gt; I see popping up since the 0.1 release have not accomplished much more than &lt;a href=&quot;http://www.mozilla.org/docs/end-user/keywords.html&quot;&gt;smart keyword shortcuts&lt;/a&gt; in the location bar could.  But, it's early yet, and &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; is far from limited to these commands.&lt;/p&gt;

&lt;p&gt;Once the basics have been well-explored, I expect to see more people taking a crack at the broader capabilities offered by &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt;.  &lt;a href=&quot;http://en.wikipedia.org/wiki/Bookmarklet&quot;&gt;Bookmarklets&lt;/a&gt; and &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt; can't access browser chrome—but &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; can.  &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; also offers a user interface that's so much more promising than keyword shortcuts, including command previews and typed parameters with suggestions.&lt;/p&gt;

&lt;p&gt;Ubiquity promises web-wide mashups directed by a conversational command interface.  All in all, the potential of this makes me feel like my digital environment—browser and web as a whole—is getting even more intimately, personally hackable.&lt;/p&gt;

&lt;p&gt;It'll be very interesting to see where this project goes.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089574&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=22b4e824255828f5aedd0e6e2558dc52&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Raul&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089574&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T10:20:58&quot;&gt;2008-08-31T10:20:58&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi, was using the original delicious command linked from the Ubiquity wiki, just tried yours and its definitely more polished and functional. Great job with the preview and the extra functionality. Only thing is 'share-to-delicious' is too much to type so I unsubscribed the previous command and changed the namespace in yours. This is clearly going to become a problems as the commands proliferate.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089575&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089575&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T14:43:39&quot;&gt;2008-08-31T14:43:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Raul: &quot;share-to-delicious&quot; is long, but keep in mind is that you only need to type enough of the command to disambiguate it.  That is, all I type is &quot;sh this tagged osx software apple&quot; because I have no other commands starting with &quot;sh&quot;.  Watch the list of commands in the preview as you type.  Those tell you what the parser thinks of what you're typing as you type.  It's like automatic tab-completion.&lt;/p&gt;

&lt;p&gt;Also, I think there's work planned to put some usage based sorting into the command parser, preferring the commands you use most in order of disambiguation.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089576&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089576&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T15:33:24&quot;&gt;2008-08-31T15:33:24&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Nice post. I share your sentiment with regards to Ubiquity commands. A lot of commands that I see are just plain simple searches. I hope developers will work on more interesting things. For example, even things like auto-form filling for this comment (possibly even on page load without having to type a command) could be done by Ubiquity. There's still a lot more room for experimentation.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089578&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089578&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T15:45:59&quot;&gt;2008-08-31T15:45:59&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;But otherwise, I &lt;em&gt;really&lt;/em&gt; like your command especially the preivew. We should include it as a builtin command, if you don't mind. :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089580&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089580&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T15:51:20&quot;&gt;2008-08-31T15:51:20&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I noticed a bug in your command. If I select some text in the awesomebar, the bookmark url is chrome. You should use something the command utils to get the url, instead.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089582&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089582&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T06:17:37&quot;&gt;2008-09-01T06:17:37&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Abi: Making this a built-in command is totally fine by me!  It can use more work, though, for sure.&lt;/p&gt;

&lt;p&gt;Also, I can reproduce that bug.  Ugh.  I can't find any methods in the CmdUtils to get the current page URL, though.  I'll keep poking a bit though.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089584&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089584&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T06:50:23&quot;&gt;2008-09-01T06:50:23&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Your blog seems to be rejecting code (that's why I had so many posts in the first place). You can get the current page url using (with dots):&lt;/p&gt;

&lt;p&gt;CmdUtils  getDocumentInsecure() location href&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089586&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://theunfocused.net/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=738af918f39d544f8b0d765850c986f8&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://theunfocused.net/&quot;&gt;Blair McBride&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089586&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-02T02:50:12&quot;&gt;2008-09-02T02:50:12&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I recommend against using getDocumentInsecure() - its got &quot;Insecure&quot; in its name for a reason! Instead, you should use:&lt;/p&gt;

&lt;p&gt;Application.activeWindow.activeTab.uri.spec&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    
</feed>

