Omnibox Decorators
The Omnibox decorators allow you to easily respond to browser address bar (omnibox) events in your extension services. These decorators provide a clean way to handle user interactions with your extension's keyword in the address bar.
Method Decorators
onOmniboxInputStarted
This decorator handles events that fire when the user begins typing in the omnibox with your extension's keyword selected.
import { onOmniboxInputStarted, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputStarted()
handleInputStarted() {
console.log('User started typing with our keyword');
this.prepareSearchEnvironment();
}
private prepareSearchEnvironment() {
// Prepare any resources needed for search suggestions
}
}
onOmniboxInputChanged
This decorator handles events that fire when the user types in the omnibox with your extension's keyword selected.
import { onOmniboxInputChanged, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputChanged()
handleInputChanged(arg: { text: string, suggest: (suggestResults: browser.Omnibox.SuggestResult[]) => void }) {
console.log('User input:', arg.text);
// Generate suggestions based on user input
const suggestions = this.generateSuggestions(arg.text);
// Send suggestions back to the browser
arg.suggest(suggestions);
}
private generateSuggestions(query: string): browser.Omnibox.SuggestResult[] {
return [
{ content: `search:${query}`, description: `Search for "${query}"` },
{ content: `lucky:${query}`, description: `I'm feeling lucky: "${query}"` },
];
}
}
With parameter decorator:
import { onOmniboxInputChanged, omniboxInputChangedDetails, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputChanged()
handleInputChanged(
@omniboxInputChangedDetails('text') text: string,
@omniboxInputChangedDetails('suggest') suggest: (results: browser.Omnibox.SuggestResult[]) => void
) {
const suggestions = [
{ content: `search:${text}`, description: `Search for "${text}"` },
{ content: `lucky:${text}`, description: `I'm feeling lucky: "${text}"` },
];
suggest(suggestions);
}
}
onOmniboxInputEntered
This decorator handles events that fire when the user accepts a suggestion or submits what they've typed in the omnibox.
import { onOmniboxInputEntered, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputEntered()
handleInputEntered(arg: { text: string, disposition: browser.Omnibox.OnInputEnteredDisposition }) {
console.log('User entered:', arg.text);
console.log('Disposition:', arg.disposition);
// Determine what to do based on the input
if (arg.text.startsWith('search:')) {
const query = arg.text.substring(7);
this.performSearch(query, arg.disposition);
} else if (arg.text.startsWith('lucky:')) {
const query = arg.text.substring(6);
this.performLuckySearch(query, arg.disposition);
}
}
private performSearch(query: string, disposition: browser.Omnibox.OnInputEnteredDisposition) {
const url = `https://example.com/search?q=${encodeURIComponent(query)}`;
this.navigateBasedOnDisposition(url, disposition);
}
private performLuckySearch(query: string, disposition: browser.Omnibox.OnInputEnteredDisposition) {
const url = `https://example.com/lucky?q=${encodeURIComponent(query)}`;
this.navigateBasedOnDisposition(url, disposition);
}
private navigateBasedOnDisposition(url: string, disposition: browser.Omnibox.OnInputEnteredDisposition) {
switch (disposition) {
case 'currentTab':
browser.tabs.update({ url });
break;
case 'newForegroundTab':
browser.tabs.create({ url, active: true });
break;
case 'newBackgroundTab':
browser.tabs.create({ url, active: false });
break;
}
}
}
With parameter decorator:
import { onOmniboxInputEntered, omniboxInputEntered, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputEntered()
handleInputEntered(
@omniboxInputEntered('text') text: string,
@omniboxInputEntered('disposition') disposition: browser.Omnibox.OnInputEnteredDisposition
) {
const url = `https://example.com/search?q=${encodeURIComponent(text)}`;
this.openUrl(url, disposition);
}
private openUrl(url: string, disposition: browser.Omnibox.OnInputEnteredDisposition) {
switch (disposition) {
case 'currentTab':
browser.tabs.update({ url });
break;
case 'newForegroundTab':
browser.tabs.create({ url, active: true });
break;
case 'newBackgroundTab':
browser.tabs.create({ url, active: false });
break;
}
}
}
onOmniboxInputCancelled
This decorator handles events that fire when the user cancels their input in the omnibox.
import { onOmniboxInputCancelled, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputCancelled()
handleInputCancelled() {
console.log('User cancelled omnibox input');
this.cleanupSearchResources();
}
private cleanupSearchResources() {
// Clean up any resources that were allocated for search
}
}
onOmniboxDeleteSuggestion
This decorator handles events that fire when the user deletes a suggestion from the omnibox.
import { onOmniboxDeleteSuggestion, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxDeleteSuggestion()
handleDeleteSuggestion(text: string) {
console.log('User deleted suggestion:', text);
this.removeFromHistory(text);
}
private removeFromHistory(query: string) {
// Remove the query from search history or suggestion database
}
}
Parameter Decorators
The Omnibox API provides parameter decorators for events that pass parameters:
omniboxInputChangedDetails
Used with onOmniboxInputChanged
to extract specific properties:
import { onOmniboxInputChanged, omniboxInputChangedDetails, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputChanged()
provideSearchSuggestions(
@omniboxInputChangedDetails('text') userInput: string,
@omniboxInputChangedDetails('suggest') provideSuggestions: (results: browser.Omnibox.SuggestResult[]) => void
) {
// Generate and provide suggestions based on user input
const results = this.search(userInput);
provideSuggestions(results);
}
private search(query: string): browser.Omnibox.SuggestResult[] {
// Search implementation
return [];
}
}
omniboxInputEntered
Used with onOmniboxInputEntered
to extract specific properties:
import { onOmniboxInputEntered, omniboxInputEntered, InjectableService } from 'deco-ext';
@InjectableService()
class SearchService {
@onOmniboxInputEntered()
handleSearchExecution(
@omniboxInputEntered('text') query: string,
@omniboxInputEntered('disposition') openBehavior: browser.Omnibox.OnInputEnteredDisposition
) {
// Execute search based on the finalized query
const searchUrl = `https://example.com/search?q=${encodeURIComponent(query)}`;
// Open the result based on the user's behavior (current tab, new tab, etc.)
this.openSearchResult(searchUrl, openBehavior);
}
private openSearchResult(url: string, behavior: browser.Omnibox.OnInputEnteredDisposition) {
// Implementation for opening the URL based on the disposition
}
}
Omnibox API Concepts
Suggest Results
When providing suggestions in the onOmniboxInputChanged
event, you use the SuggestResult
format:
interface SuggestResult {
// The text that is put into the URL bar when the user selects this suggestion
content: string;
// The text shown in the dropdown
description: string;
// Optional: Whether the suggestion should be accepted when highlighting it with arrow keys
// (without requiring explicit user selection)
deletable?: boolean;
}
Disposition Types
The disposition
parameter in onOmniboxInputEntered
can be one of:
'currentTab'
: Open the result in the current tab'newForegroundTab'
: Open the result in a new tab and switch to it'newBackgroundTab'
: Open the result in a new background tab without switching to it
Implementation Details
These decorators use a singleton pattern to ensure only one event listener is registered per event type, and then route events to all decorated methods. When an omnibox event occurs:
- The event is received by the single registered browser API listener
- The event data is passed to all registered method handlers
- For each handler:
- The class instance is resolved from the dependency injection container
- If the class has an
init
method, it's called before handling the event - If parameter decorators are used, the event data is transformed accordingly
- The method is called with the appropriate parameters
The decorators can only be used on methods within classes that have been decorated with the InjectableService
decorator from deco-ext.
Setting Up the Omnibox Keyword
To use the omnibox API, you must specify a keyword in your extension's manifest:
{
"omnibox": {
"keyword": "mysearch"
}
}
This allows users to access your extension's functionality by typing "mysearch" followed by a space in the address bar.