From 0c0a7efe70012675d1db1899ad3d051f1271200a Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 1 Oct 2017 09:59:34 +0900 Subject: [PATCH] console component --- src/components/completion.js | 6 ++ src/components/console.js | 131 +++++++++++++++++++++++++++++++++++ src/pages/console.js | 93 +++---------------------- 3 files changed, 146 insertions(+), 84 deletions(-) create mode 100644 src/components/console.js diff --git a/src/components/completion.js b/src/components/completion.js index e6ee0cb..489061c 100644 --- a/src/components/completion.js +++ b/src/components/completion.js @@ -2,10 +2,14 @@ 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 = ''; @@ -24,6 +28,8 @@ export default class Completion { } } } + + this.prevState = state; } createCompletionTitle(text) { diff --git a/src/components/console.js b/src/components/console.js new file mode 100644 index 0000000..a4bdad5 --- /dev/null +++ b/src/components/console.js @@ -0,0 +1,131 @@ +import messages from '../content/messages'; +import * as completionActions from '../actions/completion'; + +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)); + } + + static 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 + }); + case KeyboardEvent.DOM_VK_TAB: + if (e.shiftKey) { + this.store.dispatch(completionActions.selectPrev()); + } else { + this.store.dispatch(completionActions.selectNext()); + } + 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_CHANGEED, + text: e.target.value + }); + } + + // TODO use store/reducer to update state. + update(state) { + 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(); + } + + 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'; + } +} diff --git a/src/pages/console.js b/src/pages/console.js index 1e1b3fd..feaf725 100644 --- a/src/pages/console.js +++ b/src/pages/console.js @@ -1,114 +1,39 @@ import './console.scss'; import messages from '../content/messages'; import CompletionComponent from '../components/completion'; +import ConsoleComponent from '../components/console'; import completionReducer from '../reducers/completion'; import * as store from '../store'; import * as completionActions from '../actions/completion'; const completionStore = store.createStore(completionReducer); let completionComponent = null; +let consoleComponent = null; window.addEventListener('load', () => { let wrapper = document.querySelector('#vimvixen-console-completion'); completionComponent = new CompletionComponent(wrapper, completionStore); -}); -// TODO consider object-oriented -let prevValue = ''; -let completionOrigin = ''; -let prevState = {}; + // TODO use root root store instead of completionStore + consoleComponent = new ConsoleComponent(document.body, completionStore); +}); completionStore.subscribe(() => { completionComponent.update(); let state = completionStore.getState(); - let input = window.document.querySelector('#vimvixen-console-command-input'); - if (state.groupSelection >= 0) { let item = state.groups[state.groupSelection].items[state.itemSelection]; - input.value = item.content; + consoleComponent.setCommandValue(item.content); } else if (state.groups.length > 0) { - input.value = completionOrigin; - } -}); - -const handleBlur = () => { - return browser.runtime.sendMessage({ - type: messages.CONSOLE_BLURRED, - }); -}; - -const handleKeydown = (e) => { - let input = window.document.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 - }); - case KeyboardEvent.DOM_VK_TAB: - if (e.shiftKey) { - completionStore.dispatch(completionActions.selectPrev()); - } else { - completionStore.dispatch(completionActions.selectNext()); - } - e.stopPropagation(); - e.preventDefault(); - break; - } -}; - -const handleKeyup = (e) => { - if (e.keyCode === KeyboardEvent.DOM_VK_TAB) { - return; - } - if (e.target.value === prevValue) { - return; + consoleComponent.setCommandCompletionOrigin(); } - - let input = window.document.querySelector('#vimvixen-console-command-input'); - completionOrigin = input.value; - - prevValue = e.target.value; - return browser.runtime.sendMessage({ - type: messages.CONSOLE_CHANGEED, - text: e.target.value - }); -}; - -window.addEventListener('load', () => { - let input = window.document.querySelector('#vimvixen-console-command-input'); - input.addEventListener('blur', handleBlur); - input.addEventListener('keydown', handleKeydown); - input.addEventListener('keyup', handleKeyup); }); -const updateCompletions = (completions) => { - completionStore.dispatch(completionActions.setItems(completions)); -}; - const update = (state) => { - let error = window.document.querySelector('#vimvixen-console-error'); - let command = window.document.querySelector('#vimvixen-console-command'); - let input = window.document.querySelector('#vimvixen-console-command-input'); - - error.style.display = state.errorShown ? 'block' : 'none'; - error.textContent = state.errorText; - - command.style.display = state.commandShown ? 'block' : 'none'; - if (state.commandShown && !prevState.commandShown) { - input.value = state.commandText; - input.focus(); - } - if (JSON.stringify(state.completions) !== - JSON.stringify(prevState.completions)) { - updateCompletions(state.completions); - } + consoleComponent.update(state); - prevState = state; + completionStore.dispatch(completionActions.setItems(state.completions)); }; browser.runtime.onMessage.addListener((action) => {