mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-17 14:59:12 +02:00
Add Omnibox API example (#164)
* Add Omnibox API example * Add an example for the omnibox api * Resolved pull request comments and did some minor refactoring * Resolved pull request comments and did some minor refactoring * Fix error when handling default suggestion * Fix error when handling default suggestion * Require Firefox 52, update version to 1.0, and update match pattern to be more specific
This commit is contained in:
13
firefox-code-search/README.md
Normal file
13
firefox-code-search/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# firefox-code-search
|
||||
|
||||
## What it does
|
||||
|
||||
This extension allows you to search the Firefox codebase using the awesome bar.
|
||||
|
||||
To test it out, type 'cs' into the awesome bar followed by a search string (e.g. `cs hello world`). The results will be shown as suggestions, and clicking on a suggestion will navigate to the file where the result was found.
|
||||
|
||||
To search a specific file, use the "path:" prefix (e.g. `cs hello path:omnibox.js`)
|
||||
|
||||
## What it shows
|
||||
|
||||
How to use the omnibox API to add custom suggestions to the awesome bar.
|
||||
101
firefox-code-search/background.js
Normal file
101
firefox-code-search/background.js
Normal file
@@ -0,0 +1,101 @@
|
||||
const BASE_URL = "https://searchfox.org/mozilla-central";
|
||||
const SEARCH_URL = `${BASE_URL}/search`;
|
||||
const SOURCE_URL = `${BASE_URL}/source`;
|
||||
|
||||
// Provide help text to the user.
|
||||
browser.omnibox.setDefaultSuggestion({
|
||||
description: `Search the firefox codebase
|
||||
(e.g. "hello world" | "path:omnibox.js onInputChanged")`
|
||||
});
|
||||
|
||||
// Update the suggestions whenever the input is changed.
|
||||
browser.omnibox.onInputChanged.addListener((text, addSuggestions) => {
|
||||
let headers = new Headers({"Accept": "application/json"});
|
||||
let init = {method: 'GET', headers};
|
||||
let url = buildSearchURL(text);
|
||||
let request = new Request(url, init);
|
||||
|
||||
fetch(request)
|
||||
.then(createSuggestionsFromResponse)
|
||||
.then(addSuggestions);
|
||||
});
|
||||
|
||||
// Open the page based on how the user clicks on a suggestion.
|
||||
browser.omnibox.onInputEntered.addListener((text, disposition) => {
|
||||
let url = text;
|
||||
if (!text.startsWith(SOURCE_URL)) {
|
||||
// Update the url if the user clicks on the default suggestion.
|
||||
url = `${SEARCH_URL}?q=${text}`;
|
||||
}
|
||||
switch (disposition) {
|
||||
case "currentTab":
|
||||
browser.tabs.update({url});
|
||||
break;
|
||||
case "newForegroundTab":
|
||||
browser.tabs.create({url});
|
||||
break;
|
||||
case "newBackgroundTab":
|
||||
browser.tabs.create({url, active: false});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function buildSearchURL(text) {
|
||||
let path = '';
|
||||
let queryParts = [];
|
||||
let query = '';
|
||||
let parts = text.split(' ');
|
||||
|
||||
parts.forEach(part => {
|
||||
if (part.startsWith("path:")) {
|
||||
path = part.slice(5);
|
||||
} else {
|
||||
queryParts.push(part);
|
||||
}
|
||||
});
|
||||
|
||||
query = queryParts.join(' ');
|
||||
return `${SEARCH_URL}?q=${query}&path=${path}`;
|
||||
}
|
||||
|
||||
function createSuggestionsFromResponse(response) {
|
||||
return new Promise(resolve => {
|
||||
let suggestions = [];
|
||||
let suggestionsOnEmptyResults = [{
|
||||
content: SOURCE_URL,
|
||||
description: "no results found"
|
||||
}];
|
||||
response.json().then(json => {
|
||||
if (!json.normal) {
|
||||
return resolve(suggestionsOnEmptyResults);
|
||||
}
|
||||
|
||||
let occurrences = json.normal["Textual Occurrences"];
|
||||
let files = json.normal["Files"];
|
||||
|
||||
if (!occurrences && !files) {
|
||||
return resolve(suggestionsOnEmptyResults);
|
||||
}
|
||||
|
||||
if (occurrences) {
|
||||
occurrences.forEach(({path, lines}) => {
|
||||
suggestions.push({
|
||||
content: `${SOURCE_URL}/${path}#${lines[0].lno}`,
|
||||
description: lines[0].line,
|
||||
});
|
||||
});
|
||||
return resolve(suggestions);
|
||||
}
|
||||
|
||||
// There won't be any textual occurrences if the "path:" prefix is used.
|
||||
files.forEach(({path}) => {
|
||||
suggestions.push({
|
||||
content: `${SOURCE_URL}/${path}`,
|
||||
description: path,
|
||||
});
|
||||
});
|
||||
return resolve(suggestions);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
18
firefox-code-search/manifest.json
Normal file
18
firefox-code-search/manifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Firefox Code Search",
|
||||
"description" : "To use, type 'cs' plus a search term into the url bar.",
|
||||
"version": "1.0",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"strict_min_version": "52.0a1"
|
||||
}
|
||||
},
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
},
|
||||
"omnibox": { "keyword" : "cs" },
|
||||
"manifest_version": 2,
|
||||
"permissions": [
|
||||
"https://searchfox.org/"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user