-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
background.js
101 lines (88 loc) · 2.68 KB
/
background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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);
});
});
}