Refactor and optimize code structure

This commit is contained in:
Folyd 2019-10-30 21:24:34 +08:00
parent d12e2300b0
commit 7137c8918b
5 changed files with 111 additions and 102 deletions

View file

@ -1,104 +1,6 @@
const isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
const browser = isChrome ? window.chrome : window.browser;
// Firefox doesn't support tags in search suggestion.
const tagged = isChrome ?
(tag, str) => `<${tag}>${str}</${tag}>` :
(_, str) => str;
setup();
function setup() {
browser.omnibox.setDefaultSuggestion({
description: "Search Rust docs" +
(isChrome ? " for <match>%s</match>" : "") +
" on https://doc.rust-lang.org"
});
browser.omnibox.onInputChanged.addListener(function(query, suggestFn) {
if (!query) return;
const searchResults = window.search(query);
const suggestResults = [];
for (let i = 0; i < searchResults.length; i++) {
const result = searchResults[i];
suggestResults.push(buildSuggestResultItem(result));
}
if (suggestResults.length < 5 && /e\d{2,4}$/ig.test(query)) {
suggestErrorIndexResult(
query,
5 - suggestResults.length,
errorIndex => {
suggestResults.push({
content: "https://doc.rust-lang.org/error-index.html#" + errorIndex.toUpperCase(),
description: "Search Rust error index for " + tagged("match", errorIndex.toUpperCase())
+ " on https://doc.rust-lang.org/error-index.html"
});
});
}
if (suggestResults.length < 5) {
suggestResults.push({
content: "https://crates.io/search?q=" + encodeURIComponent(query),
description: "Search Rust crates for " + tagged("match", query) + " on https://crates.io"
})
}
suggestFn(suggestResults);
});
browser.omnibox.onInputEntered.addListener(function(text) {
if (text) {
navigateToUrl(text);
} else {
navigateToUrl(`${window.rootPath}?search=` + encodeURIComponent(text));
}
});
}
function suggestErrorIndexResult(query, length, callback) {
let baseIndex = parseInt(query.slice(1).padEnd(4, '0'));
for (let i = 1; i <= length; i++) {
let errorIndex = 'E' + String(baseIndex++).padStart(4, "0");
callback && callback(errorIndex);
}
}
function navigateToUrl(url) {
const openType = localStorage.getItem("open-type") || "current-tab";
if (openType === "current-tab") {
browser.tabs.query({active: true}, function(tab) {
browser.tabs.update(tab.id, {url: url});
});
} else {
browser.tabs.create({url: url});
}
}
// Escape the five predefined entities to display them as text.
function escape(text) {
text = text || "";
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
function buildSuggestResultItem(item) {
let description = item.displayPath + tagged("match", item.name);
if (item.desc) {
description += " - " + tagged("dim", escape(item.desc));
}
return {
content: item.href,
description: description,
}
}
function nullOrDefault(value, defaultValue) {
window.nullOrDefault = function nullOrDefault(value, defaultValue) {
return value === null ? defaultValue : value;
}
};
window.nullOrDefault = nullOrDefault;
const omnibox = new Omnibox();
omnibox.bootstrap();

View file

@ -24,6 +24,7 @@
"scripts": [
"search.js",
"search-index.js",
"omnibox.js",
"main.js"
]
},

102
extension/omnibox.js Normal file
View file

@ -0,0 +1,102 @@
function Omnibox() {
this.isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
// Firefox doesn't support tags in search suggestion.
this.tagged = this.isChrome ?
(tag, str) => `<${tag}>${str}</${tag}>` :
(_, str) => str;
this.browser = this.isChrome ? window.chrome : window.browser;
}
Omnibox.prototype.setupDefaultSuggestion = function() {
let offlineMode = JSON.parse(localStorage.getItem('offline-mode'));
offlineMode = (offlineMode === null) ? false : offlineMode;
this.browser.omnibox.setDefaultSuggestion({
description: `Search Rust docs ${ this.isChrome ? " for <match>%s</match>" : "" } on ${ offlineMode ? "offline mode" : "https://doc.rust-lang.org"}`
});
};
Omnibox.prototype.bootstrap = function() {
this.setupDefaultSuggestion();
this.browser.omnibox.onInputChanged.addListener((query, suggestFn) => {
if (!query) return;
const searchResults = window.search(query);
this.suggestResults = [];
for (let result of searchResults) {
this.appendSuggestResult(result);
}
if (this.suggestResults.length < 5 && /e\d{2,4}$/ig.test(query)) {
this.appendErrorIndexResult(query, 5 - this.suggestResults.length);
}
if (this.suggestResults.length < 5) {
this.appendCratesResult(query);
}
suggestFn(this.suggestResults);
});
this.browser.omnibox.onInputEntered.addListener(text => {
if (text.startsWith("https://") || text.startsWith("file://")) {
this.navigateToUrl(text);
} else {
this.navigateToUrl(`${window.rootPath}std/index.html?search=` + encodeURIComponent(text));
}
});
};
Omnibox.prototype.appendSuggestResult = function(item) {
let description = item.displayPath + this.tagged("match", item.name);
if (item.desc) {
description += " - " + this.tagged("dim", escape(item.desc));
}
this.suggestResults.push({
content: item.href,
description: description,
});
};
Omnibox.prototype.appendErrorIndexResult = function(query, length) {
let baseIndex = parseInt(query.slice(1).padEnd(4, '0'));
for (let i = 1; i <= length; i++) {
let errorIndex = 'E' + String(baseIndex++).padStart(4, "0");
this.suggestResults.push({
content: "https://doc.rust-lang.org/error-index.html#" + errorIndex.toUpperCase(),
description: "Search Rust error index for " + this.tagged("match", errorIndex.toUpperCase())
+ " on https://doc.rust-lang.org/error-index.html"
});
}
};
Omnibox.prototype.appendCratesResult = function(query) {
this.suggestResults.push({
content: "https://crates.io/search?q=" + encodeURIComponent(query),
description: "Search Rust crates for " + this.tagged("match", query) + " on https://crates.io"
});
};
Omnibox.prototype.navigateToUrl = function(url) {
const openType = localStorage.getItem("open-type") || "current-tab";
if (openType === "current-tab") {
this.browser.tabs.query({active: true}, tab => {
this.browser.tabs.update(tab.id, {url: url});
});
} else {
this.browser.tabs.create({url: url});
}
};
// Escape the five predefined entities to display them as text.
function escape(text) {
text = text || "";
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}

View file

@ -65,5 +65,6 @@
<input type="text" class="offline-doc-path" placeholder="Input the local std doc path">
</div>
</body>
<script src="omnibox.js"></script>
<script src="popup.js"></script>
</html>

View file

@ -1,3 +1,5 @@
const omnibox = new Omnibox();
document.addEventListener('DOMContentLoaded', function() {
const openTypeSelect = document.querySelector('select[name="open-type"]');
if (localStorage.getItem("open-type")) {
@ -26,6 +28,7 @@ function onOfflineModeChange(event) {
const enable = event.target.checked;
localStorage.setItem('offline-mode', enable);
toggleOfflinePathEnableState(enable);
omnibox.setupDefaultSuggestion();
}
function toggleOfflinePathEnableState(enable) {