mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-16 06:18:35 +02:00
* 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
102 lines
2.7 KiB
JavaScript
102 lines
2.7 KiB
JavaScript
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);
|
|
});
|
|
});
|
|
}
|
|
|