How to Use the Omnibox API in Google Chrome

The Omnibox API in Chrome is currently an experimental API, which means you can’t upload the extension to the gallery if your using it. Though, it works very well for local testing, and that is what we are going to do now.

When I first heard there was going to be an Omnibox API I figured it would let us hook in on every change in the address bar and then add my own results to it. However, this isn’t how the API was implemented, and after reading Aaron’s comment about why, I understand and believe it’s the right way to go.

[…] The omnibox has a very small results space. I'm hesitant to get into a situation where a bunch of extensions are fighting to make their results the most relevant. […]

? Aaron Boodman

In fact the only difference from how I thought it would work is that each extension sets a keyword (like search engines) in the manifest (omnibox_keyword) and this is the word the extension will respond to in the Omnibox. This means that, like Aaron said, we won’t have to fight with other extensions about space – we have our own reserved space in the results list. Smart!

How to Use

Like mentioned earlier, you need to first add a setting to the manifest.json file where you specify the keyword the Omnibox will respond to. This will look identical to how the custom search engines behave in the Omnibox

omnibox-1

Currently the Omnibox API consists of four events:

  • chrome.experimental.omnibox.onInputStarted
  • chrome.experimental.omnibox.onInputChanged
  • chrome.experimental.omnibox.onInputEntered
  • chrome.experimental.omnibox.onInputCancelled

The two events you will use the most are onInputChanged and onInputEntered. InputChanged occurs every time you type something in the Omnibar (after typing the keyword). This is also the event where you will be inserting the suggestions you want to show up in the results list. This is done in the following manner (placed in the background.html file):

chrome.experimental.omnibox.onInputChanged.addListener(function (text, suggest) {
    if (text.search('coffee') > -1) {
        var suggestions = [];

        suggestions.push({ content: 'Coffee - Wikipedia', description: 'Coffee - Wikipedia' });
        suggestions.push({ content: 'Starbucks Coffee', description: 'Starbucks Coffee' });

        suggest(suggestions);
    }
});

The suggest function we are calling at the end wants an array of suggestions. Each suggestion object has tree properties; content, description, and descriptionStyles (optional). The content property is the value the address bar will get when we choose this suggestion, and also the value we receive in the onInputEntered event. The description is the text we see in the results list. Lastly the descriptionStyles; it lets us style the description in different ways, e.g. green, grayed and bold. More on how this works later.

When running this code and typing our keyword in the Omnibox (e.g. “sp”), pressing space, and typing “coffee” you will get the following results:

omnibox-3

Pretty awesome, right! Now this example is quite useless but we could do something much smarter such as submitting this command to a web server, which then starts the coffeemaker and a notification popup is shown when it’s ready.

Whenever you press enter the value will be sent to the event listeners of the onInputEntered event. This event receives the entered text through it’s first parameter “text”. See example:

chrome.experimental.omnibox.onInputEntered.addListener(function (text) {
    alert('You entered: ' + text);
});

If you liked the idea about the coffeemaker, then here is where you will send the command to the web server. Or whatever you like it to do!

Beautify it

The suggestions objects we created earlier only used the content and description properties, and leaving out the descriptionStyles property. This property is quite cool (and nicely implemented). It determines how the description will look in the results list. We can choose between four different styles:

  • styleDim – slightly grayed out, used for helper text
  • styleMatch – used to display matched text, in bold
  • styleUrl – used for URLs and filenames
  • styleNone – resets the style to normal

They are then used by inserting in an array and specifying at which offset it should take effect. This means we can stack up as many different styles we want. We only have to set the offset at which their styles begin. Lets say we have a suggestion where we will display an URL and its page title. It would look like this in code:

var url = 'http://google.com';
var title = 'Google Search';

var suggestion = {
    content: url,
    description: url + ' - ' + title,

    descriptionStyles: [
        chrome.experimental.omnibox.styleUrl(0),
        chrome.experimental.omnibox.styleDim(url.length)
    ]
};

And this is how it looks in our Omnibar:

omnibox-4

Go create some code!

That’s all I have about the Omnibox API. It’s your turn now to create some nice extensions making use of this API, I sure will. However as noted before, you can’t upload extensions using experimental APIs to the extensions gallery. Hopefully it won’t take that long before the Chrome devs finish it.

If anything’s unclear, feel free to leave a comment :-)

Resources

published in Chrome Extensions