add scripts functionality

This commit is contained in:
Cade Scroggins
2021-01-20 22:13:08 +05:30
parent 0250e4555c
commit 0f7bdb44a9
+115 -45
View File
@@ -40,6 +40,24 @@
search: '/search?q={}', search: '/search?q={}',
url: 'https://www.google.com', url: 'https://www.google.com',
}, },
{
key: 'duckduckgo',
name: 'DuckDuckGo',
search: '/?q={}',
url: 'https://duckduckgo.com',
},
{
key: 'ecosia',
name: 'Ecosia',
search: '/search?q={}',
url: 'https://www.ecosia.org',
},
{
key: 'bing',
name: 'Bing',
search: '/search?q={}',
url: 'https://www.bing.com',
},
{ {
category: 'Google', category: 'Google',
hues: ['217', '197'], hues: ['217', '197'],
@@ -303,6 +321,15 @@
// to search GitHub for tilde, you'd type "g'tilde". // to search GitHub for tilde, you'd type "g'tilde".
querySearchDelimiter: "'", querySearchDelimiter: "'",
// Scripts allow you to open or search multiple sites at once. For example,
// to search Google, DuckDuckGo, Ecosia and Bing for cats at the same time,
// you'd type "se'cats".
scripts: {
se: ['bing', 'ecosia', 'duckduckgo', '*'],
sn: ['f', 'n', 's'],
sp: ['g/notifications', 'a', 's/client/T7K3RFA1M', 'm/mail/u/1'],
},
// Default search suggestions for the specified queries. // Default search suggestions for the specified queries.
suggestionDefaults: { suggestionDefaults: {
'.': ['./inout/in/invoices/create'], '.': ['./inout/in/invoices/create'],
@@ -875,8 +902,8 @@
} }
getSuggestions(rawQuery) { getSuggestions(rawQuery) {
if (this._isTooShort(rawQuery)) return Promise.resolve([]);
const { query } = this._parseQuery(rawQuery); const { query } = this._parseQuery(rawQuery);
if (this._isTooShort(rawQuery) || !query) return Promise.resolve([]);
return new Promise((resolve) => { return new Promise((resolve) => {
const callback = 'autocompleteCallback'; const callback = 'autocompleteCallback';
@@ -1150,60 +1177,95 @@
this._commands = options.commands; this._commands = options.commands;
this._searchDelimiter = options.searchDelimiter; this._searchDelimiter = options.searchDelimiter;
this._pathDelimiter = options.pathDelimiter; this._pathDelimiter = options.pathDelimiter;
this._scripts = options.scripts;
this._protocolRegex = /^[a-zA-Z]+:\/\//i; this._protocolRegex = /^[a-zA-Z]+:\/\//i;
this._urlRegex = /^((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)$/i; this._urlRegex = /^((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)$/i;
this._cachedQuery = '';
this._cachedRes = {};
this.parse = this.parse.bind(this); this.parse = this.parse.bind(this);
} }
parse(query) { parse(query) {
if (this._cachedQuery === query) return this._cachedRes; const res = [];
this._cachedQuery = query; res.query = query;
const res = { query: query, split: null }; res.split = null;
if (this._urlRegex.test(query)) { if (this._urlRegex.test(query)) {
const hasProtocol = this._protocolRegex.test(query); const hasProtocol = this._protocolRegex.test(query);
res.redirect = hasProtocol ? query : 'http://' + query; res.redirect = hasProtocol ? query : 'http://' + query;
} else { res.color = QueryParser._getColorFromUrl(this._commands, res.redirect);
const trimmed = query.trim(); return res;
const splitSearch = trimmed.split(this._searchDelimiter);
const splitPath = trimmed.split(this._pathDelimiter);
this._commands.some(({ key, search, url }) => {
if (query === key) {
res.key = key;
res.isKey = true;
res.redirect = url;
return true;
}
if (splitSearch[0] === key && search) {
res.key = key;
res.isSearch = true;
res.split = this._searchDelimiter;
res.query = QueryParser._shiftAndTrim(splitSearch, res.split);
res.redirect = QueryParser._prepSearch(url, search, res.query);
return true;
}
if (splitPath[0] === key) {
res.key = key;
res.isPath = true;
res.split = this._pathDelimiter;
res.path = QueryParser._shiftAndTrim(splitPath, res.split);
res.redirect = QueryParser._prepPath(url, res.path);
return true;
}
if (key === '*') {
res.redirect = QueryParser._prepSearch(url, search, query);
}
});
} }
const trimmed = query.trim();
const splitSearch = trimmed.split(this._searchDelimiter);
const splitPath = trimmed.split(this._pathDelimiter);
const isScript = Object.entries(this._scripts).some(([key, script]) => {
if (query === key) {
res.key = key;
res.isKey = true;
script.forEach((command) => res.push(this.parse(command)));
return true;
}
if (splitSearch[0] === key) {
res.key = key;
res.isSearch = true;
res.split = this._searchDelimiter;
res.query = QueryParser._shiftAndTrim(splitSearch, res.split);
script.forEach((command) =>
res.push(this.parse(`${command}${res.split}${res.query}`))
);
return true;
}
if (splitPath[0] === key) {
res.key = key;
res.split = this._pathDelimiter;
res.path = QueryParser._shiftAndTrim(splitPath, res.split);
script.forEach((command) =>
res.push(this.parse(`${command}${this._pathDelimiter}${res.path}`))
);
return true;
}
});
if (isScript) return res;
this._commands.some(({ key, search, url }) => {
if (query === key) {
res.key = key;
res.isKey = true;
res.redirect = url;
return true;
}
if (splitSearch[0] === key) {
res.key = key;
res.isSearch = true;
res.split = this._searchDelimiter;
res.query = QueryParser._shiftAndTrim(splitSearch, res.split);
res.redirect = QueryParser._prepSearch(url, search, res.query);
return true;
}
if (splitPath[0] === key) {
res.key = key;
res.split = this._pathDelimiter;
res.path = QueryParser._shiftAndTrim(splitPath, res.split);
res.redirect = QueryParser._prepPath(url, res.path);
return true;
}
if (key === '*') {
res.redirect = QueryParser._prepSearch(url, search, query);
}
});
res.color = QueryParser._getColorFromUrl(this._commands, res.redirect); res.color = QueryParser._getColorFromUrl(this._commands, res.redirect);
this._cachedRes = res;
return res; return res;
} }
@@ -1324,8 +1386,8 @@
this._setColorsFromQuery(value); this._setColorsFromQuery(value);
} }
_redirect(redirect) { _redirect(redirect, forceNewTab) {
if (this._newTab) { if (this._newTab || forceNewTab) {
window.open(redirect, '_blank', 'noopener noreferrer'); window.open(redirect, '_blank', 'noopener noreferrer');
} else { } else {
window.location.href = redirect; window.location.href = redirect;
@@ -1354,7 +1416,14 @@
const query = this._inputEl.value; const query = this._inputEl.value;
if (this._suggester) this._suggester.success(query); if (this._suggester) this._suggester.success(query);
this.hide(); this.hide();
this._redirect(this._parseQuery(query).redirect); const res = this._parseQuery(query);
if (res.length) {
res.forEach((r) => this._redirect(r.redirect, true));
return;
}
this._redirect(res.redirect);
} }
_submitWithValue(value) { _submitWithValue(value) {
@@ -1388,6 +1457,7 @@
const queryParser = new QueryParser({ const queryParser = new QueryParser({
commands, commands,
pathDelimiter: CONFIG.queryPathDelimiter, pathDelimiter: CONFIG.queryPathDelimiter,
scripts: CONFIG.scripts,
searchDelimiter: CONFIG.querySearchDelimiter, searchDelimiter: CONFIG.querySearchDelimiter,
}); });