aboutsummaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/commands.js143
-rw-r--r--src/shared/operations.js38
-rw-r--r--src/shared/validators/setting.js2
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) => {