From 541449b1fced9eea15f415b023206b10724f5315 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 8 Oct 2017 14:18:12 +0900 Subject: separate console --- src/console/components/completion.js | 61 +++++++++++++++ src/console/components/console.js | 148 +++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 src/console/components/completion.js create mode 100644 src/console/components/console.js (limited to 'src/console/components') diff --git a/src/console/components/completion.js b/src/console/components/completion.js new file mode 100644 index 0000000..5033b5c --- /dev/null +++ b/src/console/components/completion.js @@ -0,0 +1,61 @@ +export default class Completion { + constructor(wrapper, store) { + this.wrapper = wrapper; + this.store = store; + this.prevState = {}; + } + + update() { + let state = this.store.getState(); + if (JSON.stringify(this.prevState) === JSON.stringify(state)) { + return; + } + + this.wrapper.innerHTML = ''; + + for (let i = 0; i < state.completions.length; ++i) { + let group = state.completions[i]; + let title = this.createCompletionTitle(group.name); + this.wrapper.append(title); + + for (let j = 0; j < group.items.length; ++j) { + let item = group.items[j]; + let li = this.createCompletionItem(item.icon, item.caption, item.url); + this.wrapper.append(li); + + if (i === state.groupSelection && j === state.itemSelection) { + li.classList.add('vimvixen-completion-selected'); + } + } + } + + this.prevState = state; + } + + createCompletionTitle(text) { + let doc = this.wrapper.ownerDocument; + let li = doc.createElement('li'); + li.className = 'vimvixen-console-completion-title'; + li.textContent = text; + return li; + } + + createCompletionItem(icon, caption, url) { + let doc = this.wrapper.ownerDocument; + + let captionEle = doc.createElement('span'); + captionEle.className = 'vimvixen-console-completion-item-caption'; + captionEle.textContent = caption; + + let urlEle = doc.createElement('span'); + urlEle.className = 'vimvixen-console-completion-item-url'; + urlEle.textContent = url; + + let li = doc.createElement('li'); + li.style.backgroundImage = 'url(' + icon + ')'; + li.className = 'vimvixen-console-completion-item'; + li.append(captionEle); + li.append(urlEle); + return li; + } +} diff --git a/src/console/components/console.js b/src/console/components/console.js new file mode 100644 index 0000000..9023d91 --- /dev/null +++ b/src/console/components/console.js @@ -0,0 +1,148 @@ +import messages from 'shared/messages'; +import * as consoleActions from 'console/actions/console'; + +export default class ConsoleComponent { + constructor(wrapper, store) { + this.wrapper = wrapper; + this.prevValue = ''; + this.prevState = {}; + this.completionOrigin = ''; + this.store = store; + + let doc = this.wrapper.ownerDocument; + let input = doc.querySelector('#vimvixen-console-command-input'); + input.addEventListener('blur', this.onBlur.bind(this)); + input.addEventListener('keydown', this.onKeyDown.bind(this)); + input.addEventListener('keyup', this.onKeyUp.bind(this)); + + this.hideCommand(); + this.hideError(); + } + + onBlur() { + return browser.runtime.sendMessage({ + type: messages.CONSOLE_BLURRED, + }); + } + + onKeyDown(e) { + let doc = this.wrapper.ownerDocument; + let input = doc.querySelector('#vimvixen-console-command-input'); + + switch (e.keyCode) { + case KeyboardEvent.DOM_VK_ESCAPE: + return input.blur(); + case KeyboardEvent.DOM_VK_RETURN: + return browser.runtime.sendMessage({ + type: messages.CONSOLE_ENTERED, + text: e.target.value + }).then(this.onBlur); + case KeyboardEvent.DOM_VK_TAB: + if (e.shiftKey) { + this.store.dispatch(consoleActions.completionPrev()); + } else { + this.store.dispatch(consoleActions.completionNext()); + } + e.stopPropagation(); + e.preventDefault(); + break; + } + } + + onKeyUp(e) { + if (e.keyCode === KeyboardEvent.DOM_VK_TAB) { + return; + } + if (e.target.value === this.prevValue) { + return; + } + + let doc = this.wrapper.ownerDocument; + let input = doc.querySelector('#vimvixen-console-command-input'); + this.completionOrigin = input.value; + + this.prevValue = e.target.value; + return browser.runtime.sendMessage({ + type: messages.CONSOLE_QUERY_COMPLETIONS, + text: e.target.value + }).then((completions) => { + this.store.dispatch(consoleActions.setCompletions(completions)); + }); + } + + update() { + let state = this.store.getState(); + if (!this.prevState.commandShown && state.commandShown) { + this.showCommand(state.commandText); + } else if (!state.commandShown) { + this.hideCommand(); + } + + if (state.errorShown) { + this.setErrorText(state.errorText); + this.showError(); + } else { + this.hideError(); + } + + if (state.groupSelection >= 0 && state.itemSelection >= 0) { + let group = state.completions[state.groupSelection]; + let item = group.items[state.itemSelection]; + this.setCommandValue(item.content); + } else if (state.completions.length > 0 && + JSON.stringify(this.prevState.completions) === + JSON.stringify(state.completions)) { + // Reset input only completion groups not changed (unselected an item in + // completion) in order to avoid to override previous input + this.setCommandCompletionOrigin(); + } + + this.prevState = state; + } + + showCommand(text) { + let doc = this.wrapper.ownerDocument; + let command = doc.querySelector('#vimvixen-console-command'); + let input = doc.querySelector('#vimvixen-console-command-input'); + + command.style.display = 'block'; + input.value = text; + input.focus(); + } + + hideCommand() { + let doc = this.wrapper.ownerDocument; + let command = doc.querySelector('#vimvixen-console-command'); + command.style.display = 'none'; + } + + setCommandValue(value) { + let doc = this.wrapper.ownerDocument; + let input = doc.querySelector('#vimvixen-console-command-input'); + input.value = value; + } + + setCommandCompletionOrigin() { + let doc = this.wrapper.ownerDocument; + let input = doc.querySelector('#vimvixen-console-command-input'); + input.value = this.completionOrigin; + } + + setErrorText(text) { + let doc = this.wrapper.ownerDocument; + let error = doc.querySelector('#vimvixen-console-error'); + error.textContent = text; + } + + showError() { + let doc = this.wrapper.ownerDocument; + let error = doc.querySelector('#vimvixen-console-error'); + error.style.display = 'block'; + } + + hideError() { + let doc = this.wrapper.ownerDocument; + let error = doc.querySelector('#vimvixen-console-error'); + error.style.display = 'none'; + } +} -- cgit v1.2.3