diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2018-01-08 16:08:55 +0900 |
---|---|---|
committer | Shin'ya Ueoka <ueokande@i-beam.org> | 2018-01-08 16:25:55 +0900 |
commit | 5c449df9b6f084d4e71627b1434154ebd7c30bc6 (patch) | |
tree | 41dfcdd6c4cdfcc8c98e9ae28d4f8854da3161a7 /src/shared/commands | |
parent | fe48dce1c9b6f003c669cb19542063c8ac0c91ba (diff) |
separate command
Diffstat (limited to 'src/shared/commands')
-rw-r--r-- | src/shared/commands/complete.js | 84 | ||||
-rw-r--r-- | src/shared/commands/exec.js | 85 | ||||
-rw-r--r-- | src/shared/commands/index.js | 4 |
3 files changed, 173 insertions, 0 deletions
diff --git a/src/shared/commands/complete.js b/src/shared/commands/complete.js new file mode 100644 index 0000000..0bdbab8 --- /dev/null +++ b/src/shared/commands/complete.js @@ -0,0 +1,84 @@ +import * as tabs from 'background/tabs'; +import * as histories from 'background/histories'; + +const getOpenCompletions = (command, keywords, searchConfig) => { + return histories.getCompletions(keywords).then((pages) => { + let historyItems = pages.map((page) => { + return { + caption: page.title, + content: command + ' ' + page.url, + url: page.url + }; + }); + let engineNames = Object.keys(searchConfig.engines); + let engineItems = engineNames.filter(name => name.startsWith(keywords)) + .map(name => ({ + caption: name, + content: command + ' ' + name + })); + + let completions = []; + if (engineItems.length > 0) { + completions.push({ + name: 'Search Engines', + items: engineItems + }); + } + if (historyItems.length > 0) { + completions.push({ + name: 'History', + items: historyItems + }); + } + return completions; + }); +}; + +const getCompletions = (line, settings) => { + let typedWords = line.trim().split(/ +/); + let typing = ''; + if (!line.endsWith(' ')) { + typing = typedWords.pop(); + } + + if (typedWords.length === 0) { + return Promise.resolve([]); + } + let name = typedWords.shift(); + let keywords = typedWords.concat(typing).join(' '); + + switch (name) { + case 'o': + case 'open': + case 't': + case 'tabopen': + case 'w': + case 'winopen': + return getOpenCompletions(name, keywords, settings.search); + case 'b': + case 'buffer': + return tabs.getCompletions(keywords).then((gotTabs) => { + let items = gotTabs.map((tab) => { + return { + caption: tab.title, + content: name + ' ' + tab.title, + url: tab.url, + icon: tab.favIconUrl + }; + }); + return [ + { + name: 'Buffers', + items: items + } + ]; + }); + } + return Promise.resolve([]); +}; + +const complete = (line, settings) => { + return getCompletions(line, settings); +}; + +export default complete; diff --git a/src/shared/commands/exec.js b/src/shared/commands/exec.js new file mode 100644 index 0000000..7248827 --- /dev/null +++ b/src/shared/commands/exec.js @@ -0,0 +1,85 @@ +import * as tabs from 'background/tabs'; +import * as histories from 'background/histories'; + +const normalizeUrl = (args, searchConfig) => { + let concat = args.join(' '); + try { + return new URL(concat).href; + } catch (e) { + if (concat.includes('.') && !concat.includes(' ')) { + return 'http://' + concat; + } + let query = concat; + let template = searchConfig.engines[ + searchConfig.default + ]; + for (let key in searchConfig.engines) { + if (args[0] === key) { + query = args.slice(1).join(' '); + template = searchConfig.engines[key]; + } + } + return template.replace('{}', encodeURIComponent(query)); + } +}; + +const openCommand = (url) => { + return browser.tabs.query({ + active: true, currentWindow: true + }).then((gotTabs) => { + if (gotTabs.length > 0) { + return browser.tabs.update(gotTabs[0].id, { url: url }); + } + }); +}; + +const tabopenCommand = (url) => { + return browser.tabs.create({ url: url }); +}; + +const winopenCommand = (url) => { + return browser.windows.create({ url }); +}; + +const bufferCommand = (keywords) => { + if (keywords.length === 0) { + return Promise.resolve([]); + } + let keywordsStr = keywords.join(' '); + return browser.tabs.query({ + active: true, currentWindow: true + }).then((gotTabs) => { + if (gotTabs.length > 0) { + if (isNaN(keywordsStr)) { + return tabs.selectByKeyword(gotTabs[0], keywordsStr); + } + let index = parseInt(keywordsStr, 10) - 1; + return tabs.selectAt(index); + } + }); +}; + +const exec = (line, settings) => { + let words = line.trim().split(/ +/); + let name = words.shift(); + + switch (name) { + case 'o': + case 'open': + return openCommand(normalizeUrl(words, settings.search)); + case 't': + case 'tabopen': + return tabopenCommand(normalizeUrl(words, settings.search)); + case 'w': + case 'winopen': + return winopenCommand(normalizeUrl(words, settings.search)); + case 'b': + case 'buffer': + return bufferCommand(words); + case '': + return Promise.resolve(); + } + throw new Error(name + ' command is not defined'); +}; + +export default exec; diff --git a/src/shared/commands/index.js b/src/shared/commands/index.js new file mode 100644 index 0000000..c2cea3e --- /dev/null +++ b/src/shared/commands/index.js @@ -0,0 +1,4 @@ +import exec from './exec'; +import complete from './complete'; + +export { exec, complete }; |