aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/background/components/background.js3
-rw-r--r--src/background/controllers/completions.js42
-rw-r--r--src/background/domains/completion-group.js14
-rw-r--r--src/background/domains/completion-item.js24
-rw-r--r--src/background/domains/completions.js27
-rw-r--r--src/background/index.js4
-rw-r--r--src/background/infrastructures/content-message-listener.js34
-rw-r--r--src/background/usecases/completions.js40
8 files changed, 185 insertions, 3 deletions
diff --git a/src/background/components/background.js b/src/background/components/background.js
index f7b0511..d933d7b 100644
--- a/src/background/components/background.js
+++ b/src/background/components/background.js
@@ -3,7 +3,6 @@ import * as commandActions from 'background/actions/command';
import * as settingActions from 'background/actions/setting';
import * as findActions from 'background/actions/find';
import * as tabActions from 'background/actions/tab';
-import * as completions from '../shared/completions';
export default class BackgroundComponent {
constructor(store) {
@@ -41,8 +40,6 @@ export default class BackgroundComponent {
return this.broadcastSettingsChanged();
case messages.SETTINGS_QUERY:
return Promise.resolve(this.store.getState().setting.value);
- case messages.CONSOLE_QUERY_COMPLETIONS:
- return completions.complete(message.text, settings.value);
case messages.SETTINGS_RELOAD:
this.store.dispatch(settingActions.load());
return this.broadcastSettingsChanged();
diff --git a/src/background/controllers/completions.js b/src/background/controllers/completions.js
new file mode 100644
index 0000000..613940f
--- /dev/null
+++ b/src/background/controllers/completions.js
@@ -0,0 +1,42 @@
+import CompletionsInteractor from '../usecases/completions';
+import Completions from '../domains/completions';
+
+export default class ContentMessageController {
+ constructor() {
+ this.completionsInteractor = new CompletionsInteractor();
+ }
+
+ getCompletions(line) {
+ let trimmed = line.trimStart();
+ let words = trimmed.split(/ +/);
+ let name = words[0];
+ if (words.length === 1) {
+ return this.completionsInteractor.queryConsoleCommand(name);
+ }
+ switch (words[0]) {
+ case 'o':
+ case 'open':
+ case 't':
+ case 'tabopen':
+ case 'w':
+ case 'winopen':
+ break;
+ case 'b':
+ case 'buffer':
+ break;
+ case 'bd!':
+ case 'bdel!':
+ case 'bdelete!':
+ case 'bdeletes!':
+ break;
+ case 'bd':
+ case 'bdel':
+ case 'bdelete':
+ case 'bdeletes':
+ break;
+ case 'set':
+ break;
+ }
+ return Promise.resolve(Completions.empty());
+ }
+}
diff --git a/src/background/domains/completion-group.js b/src/background/domains/completion-group.js
new file mode 100644
index 0000000..1749d72
--- /dev/null
+++ b/src/background/domains/completion-group.js
@@ -0,0 +1,14 @@
+export default class CompletionGroup {
+ constructor(name, items) {
+ this.name0 = name;
+ this.items0 = items;
+ }
+
+ get name() {
+ return this.name0;
+ }
+
+ get items() {
+ return this.items0;
+ }
+}
diff --git a/src/background/domains/completion-item.js b/src/background/domains/completion-item.js
new file mode 100644
index 0000000..c7ad8a1
--- /dev/null
+++ b/src/background/domains/completion-item.js
@@ -0,0 +1,24 @@
+export default class CompletionItem {
+ constructor({ caption, content, url, icon }) {
+ this.caption0 = caption;
+ this.content0 = content;
+ this.url0 = url;
+ this.icon0 = icon;
+ }
+
+ get caption() {
+ return this.caption0;
+ }
+
+ get content() {
+ return this.content0;
+ }
+
+ get url() {
+ return this.url0;
+ }
+
+ get icon() {
+ return this.icon0;
+ }
+}
diff --git a/src/background/domains/completions.js b/src/background/domains/completions.js
new file mode 100644
index 0000000..4e4219f
--- /dev/null
+++ b/src/background/domains/completions.js
@@ -0,0 +1,27 @@
+export default class Completions {
+ constructor(groups) {
+ this.g = groups;
+ }
+
+ get groups() {
+ return this.g;
+ }
+
+ serialize() {
+ return this.groups.map(group => ({
+ name: group.name,
+ items: group.items.map(item => ({
+ caption: item.caption,
+ content: item.content,
+ url: item.url,
+ icon: item.icon,
+ })),
+ }));
+ }
+
+ static EMPTY_COMPLETIONS = new Completions([]);
+
+ static empty() {
+ return Completions.EMPTY_COMPLETIONS;
+ }
+}
diff --git a/src/background/index.js b/src/background/index.js
index 1e4c078..619b076 100644
--- a/src/background/index.js
+++ b/src/background/index.js
@@ -8,6 +8,8 @@ import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise';
import * as versions from './shared/versions';
+import ContentMessageListener from './infrastructures/content-message-listener';
+
const store = createStore(
reducers,
applyMiddleware(promise),
@@ -32,3 +34,5 @@ const indicatorComponent = new IndicatorComponent(store);
store.dispatch(settingActions.load());
checkAndNotifyUpdated();
+
+new ContentMessageListener().run();
diff --git a/src/background/infrastructures/content-message-listener.js b/src/background/infrastructures/content-message-listener.js
new file mode 100644
index 0000000..a0ed66c
--- /dev/null
+++ b/src/background/infrastructures/content-message-listener.js
@@ -0,0 +1,34 @@
+import messages from '../../shared/messages';
+import CompletionsController from '../controllers/completions';
+
+export default class ContentMessageListener {
+ constructor() {
+ this.completionsController = new CompletionsController();
+ }
+
+ run() {
+ browser.runtime.onMessage.addListener((message, sender) => {
+ try {
+ return this.onMessage(message, sender);
+ } catch (e) {
+ return browser.tabs.sendMessage(sender.tab.id, {
+ type: messages.CONSOLE_SHOW_ERROR,
+ text: e.message,
+ });
+ }
+ });
+ }
+
+ onMessage(message) {
+ switch (message.type) {
+ case messages.CONSOLE_QUERY_COMPLETIONS:
+ return this.onConsoleQueryCompletions(message);
+ }
+ }
+
+ async onConsoleQueryCompletions(message) {
+ let completions =
+ await this.completionsController.getCompletions(message.text);
+ return Promise.resolve(completions.serialize());
+ }
+}
diff --git a/src/background/usecases/completions.js b/src/background/usecases/completions.js
new file mode 100644
index 0000000..fc1ff52
--- /dev/null
+++ b/src/background/usecases/completions.js
@@ -0,0 +1,40 @@
+import CompletionItem from '../domains/completion-item';
+import CompletionGroup from '../domains/completion-group';
+import Completions from '../domains/completions';
+import CompletionRepository from '../repositories/completions';
+import CommandDocs from 'background/shared/commands/docs';
+
+export default class CompletionsInteractor {
+ constructor() {
+ this.completionRepository = new CompletionRepository();
+ }
+
+ queryConsoleCommand(prefix) {
+ let keys = Object.keys(CommandDocs);
+ let items = keys
+ .filter(name => name.startsWith(prefix))
+ .map(name => ({
+ caption: name,
+ content: name,
+ url: CommandDocs[name],
+ }));
+
+ if (items.length === 0) {
+ return Promise.resolve(Completions.empty());
+ }
+ return Promise.resolve(new Completions(
+ [new CompletionGroup('Console Command', items)]
+ ));
+ }
+
+ async queryBdeleteCommand(name, force, args) {
+ let tabs = await this.completionRepository.queryTabs(args);
+ let items = tabs.map(tab => new CompletionItem({
+ caption: tab.title,
+ content: name + ' ' + tab.title,
+ url: tab.url,
+ icon: tab.favIconUrl
+ }));
+ return [new CompletionGroup('Buffers', items)];
+ }
+}