diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/commands.js | 143 | ||||
-rw-r--r-- | src/shared/operations.js | 38 | ||||
-rw-r--r-- | src/shared/validators/setting.js | 2 |
3 files changed, 182 insertions, 1 deletions
diff --git a/src/shared/commands.js b/src/shared/commands.js new file mode 100644 index 0000000..b1d8780 --- /dev/null +++ b/src/shared/commands.js @@ -0,0 +1,143 @@ +import * as tabs from 'background/tabs'; +import * as histories from 'background/histories'; + +const normalizeUrl = (string, searchConfig) => { + try { + return new URL(string).href; + } catch (e) { + if (string.includes('.') && !string.includes(' ')) { + return 'http://' + string; + } + let query = encodeURI(string); + let template = searchConfig.engines[ + searchConfig.default + ]; + for (let key in searchConfig.engines) { + if (string.startsWith(key + ' ')) { + query = encodeURI(string.replace(key + ' ', '')); + template = searchConfig.engines[key]; + } + } + return template.replace('{}', 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 bufferCommand = (keywords) => { + return browser.tabs.query({ + active: true, currentWindow: true + }).then((gotTabs) => { + if (gotTabs.length > 0) { + if (isNaN(keywords)) { + return tabs.selectByKeyword(gotTabs[0], keywords); + } + let index = parseInt(keywords, 10) - 1; + return tabs.selectAt(index); + } + }); +}; + +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 doCommand = (name, remaining, settings) => { + switch (name) { + case 'o': + case 'open': + // TODO use search engined and pass keywords to them + return openCommand(normalizeUrl(remaining, settings.search)); + case 't': + case 'tabopen': + return tabopenCommand(normalizeUrl(remaining, settings.search)); + case 'b': + case 'buffer': + return bufferCommand(remaining); + } + throw new Error(name + ' command is not defined'); +}; + +const getCompletions = (command, keywords, settings) => { + switch (command) { + case 'o': + case 'open': + case 't': + case 'tabopen': + return getOpenCompletions(command, keywords, settings.search); + case 'b': + case 'buffer': + return tabs.getCompletions(keywords).then((gotTabs) => { + let items = gotTabs.map((tab) => { + return { + caption: tab.title, + content: command + ' ' + tab.title, + url: tab.url, + icon: tab.favIconUrl + }; + }); + return [ + { + name: 'Buffers', + items: items + } + ]; + }); + } + return Promise.resolve([]); +}; + +const exec = (line, settings) => { + let name = line.split(' ')[0]; + let remaining = line.replace(name + ' ', ''); + return doCommand(name, remaining, settings); +}; + +const complete = (line, settings) => { + let command = line.split(' ', 1)[0]; + let keywords = line.replace(command + ' ', ''); + return getCompletions(command, keywords, settings); +}; + +export { exec, complete }; diff --git a/src/shared/operations.js b/src/shared/operations.js new file mode 100644 index 0000000..b68f59d --- /dev/null +++ b/src/shared/operations.js @@ -0,0 +1,38 @@ +export default { + // Command + COMMAND_SHOW: 'command.show', + COMMAND_SHOW_OPEN: 'command.show.open', + COMMAND_SHOW_TABOPEN: 'command.show.tabopen', + COMMAND_SHOW_BUFFER: 'command.show.buffer', + + // Scrolls + SCROLL_LINES: 'scroll.lines', + SCROLL_PAGES: 'scroll.pages', + SCROLL_TOP: 'scroll.top', + SCROLL_BOTTOM: 'scroll.bottom', + SCROLL_HOME: 'scroll.home', + SCROLL_END: 'scroll.end', + + // Follows + FOLLOW_START: 'follow.start', + + // Navigations + NAVIGATE_HISTORY_PREV: 'navigate.history.prev', + NAVIGATE_HISTORY_NEXT: 'navigate.history.next', + NAVIGATE_LINK_PREV: 'navigate.link.prev', + NAVIGATE_LINK_NEXT: 'navigate.link.next', + NAVIGATE_PARENT: 'navigate.parent', + NAVIGATE_ROOT: 'navigate.root', + + // Tabs + TAB_CLOSE: 'tabs.close', + TAB_REOPEN: 'tabs.reopen', + TAB_PREV: 'tabs.prev', + TAB_NEXT: 'tabs.next', + TAB_RELOAD: 'tabs.reload', + + // Zooms + ZOOM_IN: 'zoom.in', + ZOOM_OUT: 'zoom.out', + ZOOM_NEUTRAL: 'zoom.neutral', +}; diff --git a/src/shared/validators/setting.js b/src/shared/validators/setting.js index caba5cc..5039ec2 100644 --- a/src/shared/validators/setting.js +++ b/src/shared/validators/setting.js @@ -1,4 +1,4 @@ -import operations from '../../operations'; +import operations from 'shared/operations'; const VALID_TOP_KEYS = ['keymaps', 'search']; const VALID_OPERATION_VALUES = Object.keys(operations).map((key) => { |