From 0eed357a5e1ceb3061d88ef99a612bb8c4526fa7 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 9 Sep 2017 20:16:51 +0900 Subject: broadcast an action --- src/console/console.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/console/console.js') diff --git a/src/console/console.js b/src/console/console.js index c32eca0..ae05001 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -195,9 +195,6 @@ const selectCompletion = (target) => { messages.receive(window, (message) => { switch (message.type) { - case 'vimvixen.console.show.command': - showCommand(message.text); - break; case 'vimvixen.console.show.error': showError(message.text); break; @@ -206,3 +203,11 @@ messages.receive(window, (message) => { break; } }); + +browser.runtime.onMessage.addListener((action) => { + switch (action.type) { + case 'vimvixen.console.show.command': + return showCommand(action.text); + } + return Promise.resolve(); +}); -- cgit v1.2.3 From 6a2bfc51baf22bcf66153076120d48d894a3967d Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 9 Sep 2017 20:25:21 +0900 Subject: receive message of console --- src/console/console-frame.js | 6 +++--- src/console/console.js | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/console/console.js') diff --git a/src/console/console-frame.js b/src/console/console-frame.js index a590da9..f07d8ab 100644 --- a/src/console/console-frame.js +++ b/src/console/console-frame.js @@ -1,5 +1,4 @@ import './console-frame.scss'; -import * as messages from '../shared/messages'; export default class ConsoleFrame { constructor(win) { @@ -33,9 +32,10 @@ export default class ConsoleFrame { type: 'vimvixen.console.show.error', text: text }; - messages.send(this.element.contentWindow, message); this.errorShown = true; this.element.blur(); + + return browser.runtime.sendMessage(message); } showFrame() { @@ -53,7 +53,7 @@ export default class ConsoleFrame { } setCompletions(completions) { - messages.send(this.element.contentWindow, { + return browser.runtime.sendMessage({ type: 'vimvixen.console.set.completions', completions: completions }); diff --git a/src/console/console.js b/src/console/console.js index ae05001..23a26ef 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -116,6 +116,8 @@ const showCommand = (text) => { let container = window.document.querySelector('#vimvixen-console-completion'); container.innerHTML = ''; messages.send(parent, keyupMessage(input)); + + return Promise.resolve(); } const showError = (text) => { @@ -128,6 +130,8 @@ const showError = (text) => { let completion = window.document.querySelector('#vimvixen-console-completion'); completion.style.display = 'none'; + + return Promise.resolve(); } const createCompletionTitle = (text) => { @@ -177,6 +181,8 @@ const setCompletions = (completions) => { let input = window.document.querySelector('#vimvixen-console-command-input'); completionOrigin = input.value.split(' ')[0]; + + return Promise.resolve(); } const selectCompletion = (target) => { @@ -193,21 +199,15 @@ const selectCompletion = (target) => { }); }; -messages.receive(window, (message) => { - switch (message.type) { - case 'vimvixen.console.show.error': - showError(message.text); - break; - case 'vimvixen.console.set.completions': - setCompletions(message.completions); - break; - } -}); - browser.runtime.onMessage.addListener((action) => { switch (action.type) { + case 'vimvixen.console.show.error': + return showError(action.text); + case 'vimvixen.console.set.completions': + return setCompletions(action.completions); case 'vimvixen.console.show.command': return showCommand(action.text); + default: + return Promise.resolve(); } - return Promise.resolve(); }); -- cgit v1.2.3 From e6c5aea0748a108fc2c8eccc233130d08a957fb8 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 9 Sep 2017 20:35:15 +0900 Subject: more broadcast message --- src/console/console.js | 16 +++++----------- src/content/index.js | 18 ++++++++---------- 2 files changed, 13 insertions(+), 21 deletions(-) (limited to 'src/console/console.js') diff --git a/src/console/console.js b/src/console/console.js index 23a26ef..006f640 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -1,8 +1,5 @@ import './console.scss'; import Completion from './completion'; -import * as messages from '../shared/messages'; - -const parent = window.parent; // TODO consider object-oriented var prevValue = ""; @@ -30,7 +27,7 @@ const keyupMessage = (input) => { }; const handleBlur = () => { - messages.send(parent, blurMessage()); + return browser.runtime.sendMessage(blurMessage()); }; const completeNext = () => { @@ -66,11 +63,9 @@ const completePrev = () => { const handleKeydown = (e) => { switch(e.keyCode) { case KeyboardEvent.DOM_VK_ESCAPE: - messages.send(parent, blurMessage()); - break; + return browser.runtime.sendMessage(blurMessage()); case KeyboardEvent.DOM_VK_RETURN: - messages.send(parent, keydownMessage(e.target)); - break; + return browser.runtime.sendMessage(keydownMessage(e.target)); case KeyboardEvent.DOM_VK_TAB: if (e.shiftKey) { completePrev(); @@ -90,8 +85,8 @@ const handleKeyup = (e) => { if (e.target.value === prevValue) { return; } - messages.send(parent, keyupMessage(e.target)); prevValue = e.target.value; + return browser.runtime.sendMessage(keyupMessage(e.target)); }; window.addEventListener('load', () => { @@ -115,9 +110,8 @@ const showCommand = (text) => { completion = null; let container = window.document.querySelector('#vimvixen-console-completion'); container.innerHTML = ''; - messages.send(parent, keyupMessage(input)); - return Promise.resolve(); + return browser.runtime.sendMessage(keyupMessage(input)); } const showError = (text) => { diff --git a/src/content/index.js b/src/content/index.js index a2a864d..bf90363 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -1,7 +1,6 @@ import * as scrolls from './scrolls'; import * as histories from './histories'; import * as actions from '../shared/actions'; -import * as messages from '../shared/messages'; import ConsoleFrame from '../console/console-frame'; import Follow from './follow'; @@ -84,28 +83,27 @@ const doCompletion = (line) => { vvConsole.showError(err.message); }); } + return Promise.resolve(); }; -messages.receive(window, (message) => { - switch (message.type) { +browser.runtime.onMessage.addListener((action) => { + switch (action.type) { case 'vimvixen.command.blur': if (!vvConsole.isErrorShown()) { vvConsole.hide(); } - break; + return Promise.resolve(); case 'vimvixen.command.enter': - browser.runtime.sendMessage({ + return browser.runtime.sendMessage({ type: 'event.cmd.enter', - text: message.value + text: action.value }).catch((err) => { console.error("Vim Vixen:", err); vvConsole.showError(err.message); }); - break; case 'vimvixen.command.change': - doCompletion(message.value); - break; + return doCompletion(action.value); default: - return; + return Promise.resolve(); } }); -- cgit v1.2.3 From e8056d2a709df9c9c182382fc7a31795e4dc1c0f Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 9 Sep 2017 22:07:27 +0900 Subject: console state as action/reducer in redux --- src/actions/console.js | 28 ++++++++++++ src/actions/index.js | 6 +++ src/console/console-frame.js | 21 +++------ src/console/console.js | 106 ++++++++++++++++++------------------------- src/content/index.js | 1 - src/reducers/console.js | 39 ++++++++++++++++ 6 files changed, 123 insertions(+), 78 deletions(-) create mode 100644 src/actions/console.js create mode 100644 src/actions/index.js create mode 100644 src/reducers/console.js (limited to 'src/console/console.js') diff --git a/src/actions/console.js b/src/actions/console.js new file mode 100644 index 0000000..99a46e8 --- /dev/null +++ b/src/actions/console.js @@ -0,0 +1,28 @@ +import actions from '../actions'; + +export function showCommand(text) { + return { + type: actions.CONSOLE_SHOW_COMMAND, + text: text + }; +} + +export function setCompletions(completions) { + return { + type: actions.CONSOLE_SET_COMPLETIONS, + completions: completions + }; +} + +export function showError(text) { + return { + type: actions.CONSOLE_SHOW_ERROR, + text: text + }; +} + +export function hide() { + return { + type: actions.CONSOLE_HIDE + }; +} diff --git a/src/actions/index.js b/src/actions/index.js new file mode 100644 index 0000000..38ced9d --- /dev/null +++ b/src/actions/index.js @@ -0,0 +1,6 @@ +export default { + CONSOLE_SHOW_COMMAND: 'vimvixen.console.show.command', + CONSOLE_SET_COMPLETIONS: 'vimvixen.console.set.completions', + CONSOLE_SHOW_ERROR: 'vimvixen.console.show.error', + CONSOLE_HIDE: 'vimvixen.console.hide' +}; diff --git a/src/console/console-frame.js b/src/console/console-frame.js index f07d8ab..8b4c17a 100644 --- a/src/console/console-frame.js +++ b/src/console/console-frame.js @@ -1,4 +1,5 @@ import './console-frame.scss'; +import * as consoleActions from '../actions/console'; export default class ConsoleFrame { constructor(win) { @@ -16,26 +17,17 @@ export default class ConsoleFrame { showCommand(text) { this.showFrame(); - - let message = { - type: 'vimvixen.console.show.command', - text: text - }; this.errorShown = false; - return browser.runtime.sendMessage(message); + return browser.runtime.sendMessage(consoleActions.showCommand(text)); } showError(text) { this.showFrame(); - let message = { - type: 'vimvixen.console.show.error', - text: text - }; this.errorShown = true; this.element.blur(); - return browser.runtime.sendMessage(message); + return browser.runtime.sendMessage(consoleActions.showError(text)); } showFrame() { @@ -46,6 +38,8 @@ export default class ConsoleFrame { this.element.style.display = 'none'; this.element.blur(); this.errorShown = false; + + return browser.runtime.sendMessage(consoleActions.hide()); } isErrorShown() { @@ -53,9 +47,6 @@ export default class ConsoleFrame { } setCompletions(completions) { - return browser.runtime.sendMessage({ - type: 'vimvixen.console.set.completions', - completions: completions - }); + return browser.runtime.sendMessage(consoleActions.setCompletions(completions)); } } diff --git a/src/console/console.js b/src/console/console.js index 006f640..044aa5f 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -1,10 +1,12 @@ import './console.scss'; import Completion from './completion'; +import consoleReducer, { defaultState } from '../reducers/console'; // TODO consider object-oriented var prevValue = ""; var completion = null; var completionOrigin = ""; +let state = defaultState; const blurMessage = () => { return { @@ -96,38 +98,6 @@ window.addEventListener('load', () => { input.addEventListener('keyup', handleKeyup); }); -const showCommand = (text) => { - let command = window.document.querySelector('#vimvixen-console-command'); - command.style.display = 'block'; - - let error = window.document.querySelector('#vimvixen-console-error'); - error.style.display = 'none'; - - let input = window.document.querySelector('#vimvixen-console-command-input'); - input.value = text; - input.focus(); - - completion = null; - let container = window.document.querySelector('#vimvixen-console-completion'); - container.innerHTML = ''; - - return browser.runtime.sendMessage(keyupMessage(input)); -} - -const showError = (text) => { - let error = window.document.querySelector('#vimvixen-console-error'); - error.textContent = text; - error.style.display = 'block'; - - let command = window.document.querySelector('#vimvixen-console-command'); - command.style.display = 'none'; - - let completion = window.document.querySelector('#vimvixen-console-completion'); - completion.style.display = 'none'; - - return Promise.resolve(); -} - const createCompletionTitle = (text) => { let li = document.createElement('li'); li.className = 'vimvixen-console-completion-title'; @@ -152,56 +122,68 @@ const createCompletionItem = (icon, caption, url) => { return li; } -const setCompletions = (completions) => { +const selectCompletion = (target) => { let container = window.document.querySelector('#vimvixen-console-completion'); - container.style.display = 'block'; - container.innerHTML = ''; + Array.prototype.forEach.call(container.children, (ele) => { + if (!ele.classList.contains('vimvixen-console-completion-item')) { + return; + } + if (ele === target) { + ele.classList.add('vimvixen-completion-selected'); + } else { + ele.classList.remove('vimvixen-completion-selected'); + } + }); +}; + +const updateCompletions = (completions) => { + let completionsContainer = window.document.querySelector('#vimvixen-console-completion'); + let input = window.document.querySelector('#vimvixen-console-command-input'); + + completionsContainer.innerHTML = ''; let pairs = []; for (let group of completions) { let title = createCompletionTitle(group.name); - container.append(title); + completionsContainer.append(title); for (let item of group.items) { let li = createCompletionItem(item.icon, item.caption, item.url); - container.append(li); + completionsContainer.append(li); pairs.push([item, li]); } } completion = new Completion(pairs); + completionOrigin = input.value.split(' ')[0]; +} +const update = (prevState, 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'); - completionOrigin = input.value.split(' ')[0]; - return Promise.resolve(); -} + error.style.display = state.errorShown ? 'block' : 'none'; + error.textContent = state.errorText; -const selectCompletion = (target) => { - let container = window.document.querySelector('#vimvixen-console-completion'); - Array.prototype.forEach.call(container.children, (ele) => { - if (!ele.classList.contains('vimvixen-console-completion-item')) { - return; - } - if (ele === target) { - ele.classList.add('vimvixen-completion-selected'); - } else { - ele.classList.remove('vimvixen-completion-selected'); - } - }); -}; + command.style.display = state.commandShown ? 'block' : 'none'; + if (!prevState.commandShown && state.commandShown) { + // setup input on firstly shown + input.value = state.commandText; + input.focus(); + } + + if (JSON.stringify(state.completions) !== JSON.stringify(prevState.completions)) { + updateCompletions(state.completions); + } +} browser.runtime.onMessage.addListener((action) => { - switch (action.type) { - case 'vimvixen.console.show.error': - return showError(action.text); - case 'vimvixen.console.set.completions': - return setCompletions(action.completions); - case 'vimvixen.console.show.command': - return showCommand(action.text); - default: - return Promise.resolve(); + let nextState = consoleReducer(state, action); + if (JSON.stringify(nextState) !== JSON.stringify(state)) { + update(state, nextState); + state = nextState; } }); diff --git a/src/content/index.js b/src/content/index.js index bf90363..deb3506 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -6,7 +6,6 @@ import Follow from './follow'; let vvConsole = new ConsoleFrame(window); - browser.runtime.onMessage.addListener((action) => { switch (action.type) { case actions.CMD_OPEN: diff --git a/src/reducers/console.js b/src/reducers/console.js new file mode 100644 index 0000000..62fc951 --- /dev/null +++ b/src/reducers/console.js @@ -0,0 +1,39 @@ +import actions from '../actions'; + +export const defaultState = { + errorText: '', + errorShown: false, + commandText: '', + commandShown: false, + completions: [], +}; + +export default function reducer(state = defaultState, action = {}) { + switch (action.type) { + case actions.CONSOLE_SHOW_COMMAND: + return Object.assign({}, state, { + commandShown: true, + commandText: action.text, + errorShow: false, + completions: [] + }); + case actions.CONSOLE_SET_COMPLETIONS: + return Object.assign({}, state, { + completions: action.completions + }); + case actions.CONSOLE_SHOW_ERROR: + return Object.assign({}, state, { + errorText: action.message, + errorShow: true, + commandShown: false, + }); + case actions.CONSOLE_HIDE: + return Object.assign({}, state, { + errorShown: false, + commandShown: false + + }); + default: + return state; + } +} -- cgit v1.2.3 From 7e35d11f659029febd738c83b19ab4b8a8b69642 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 9 Sep 2017 22:50:00 +0900 Subject: add console actions/reducer tests and fix targets --- src/console/console.js | 4 ++-- src/reducers/console.js | 12 ++++++------ test/actions/console.test.js | 37 +++++++++++++++++++++++++++++++++++++ test/reducers/console.test.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 test/actions/console.test.js create mode 100644 test/reducers/console.test.js (limited to 'src/console/console.js') diff --git a/src/console/console.js b/src/console/console.js index 044aa5f..35d98e0 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -1,12 +1,12 @@ import './console.scss'; import Completion from './completion'; -import consoleReducer, { defaultState } from '../reducers/console'; +import consoleReducer from '../reducers/console'; // TODO consider object-oriented var prevValue = ""; var completion = null; var completionOrigin = ""; -let state = defaultState; +let state = consoleReducer(undefined, {}); const blurMessage = () => { return { diff --git a/src/reducers/console.js b/src/reducers/console.js index 62fc951..3303802 100644 --- a/src/reducers/console.js +++ b/src/reducers/console.js @@ -1,10 +1,10 @@ import actions from '../actions'; -export const defaultState = { - errorText: '', +const defaultState = { errorShown: false, - commandText: '', + errorText: '', commandShown: false, + commandText: '', completions: [], }; @@ -14,7 +14,7 @@ export default function reducer(state = defaultState, action = {}) { return Object.assign({}, state, { commandShown: true, commandText: action.text, - errorShow: false, + errorShown: false, completions: [] }); case actions.CONSOLE_SET_COMPLETIONS: @@ -23,8 +23,8 @@ export default function reducer(state = defaultState, action = {}) { }); case actions.CONSOLE_SHOW_ERROR: return Object.assign({}, state, { - errorText: action.message, - errorShow: true, + errorText: action.text, + errorShown: true, commandShown: false, }); case actions.CONSOLE_HIDE: diff --git a/test/actions/console.test.js b/test/actions/console.test.js new file mode 100644 index 0000000..512ee40 --- /dev/null +++ b/test/actions/console.test.js @@ -0,0 +1,37 @@ +import { expect } from "chai"; +import actions from '../../src/actions'; +import * as consoleActions from '../../src/actions/console'; + +describe("console actions", () => { + describe("showCommand", () => { + it('create CONSOLE_SHOW_COMMAND action', () => { + let action = consoleActions.showCommand('hello'); + expect(action.type).to.equal(actions.CONSOLE_SHOW_COMMAND); + expect(action.text).to.equal('hello'); + }); + }); + + describe("setCompletions", () => { + it('create CONSOLE_SET_COMPLETIONS action', () => { + let action = consoleActions.setCompletions([1,2,3]); + expect(action.type).to.equal(actions.CONSOLE_SET_COMPLETIONS); + expect(action.completions).to.deep.equal([1, 2, 3]); + }); + }); + + describe("showError", () => { + it('create CONSOLE_SHOW_ERROR action', () => { + let action = consoleActions.showError('an error'); + expect(action.type).to.equal(actions.CONSOLE_SHOW_ERROR); + expect(action.text).to.equal('an error'); + }); + }); + + describe("hide", () => { + it('create CONSOLE_HIDE action', () => { + let action = consoleActions.hide(); + expect(action.type).to.equal(actions.CONSOLE_HIDE); + }); + }); +}); + diff --git a/test/reducers/console.test.js b/test/reducers/console.test.js new file mode 100644 index 0000000..9820a08 --- /dev/null +++ b/test/reducers/console.test.js @@ -0,0 +1,43 @@ +import { expect } from "chai"; +import actions from '../../src/actions'; +import consoleReducer from '../../src/reducers/console'; + +describe("console reducer", () => { + it('return the initial state', () => { + let state = consoleReducer(undefined, {}); + expect(state).to.have.property('errorShown', false); + expect(state).to.have.property('errorText', ''); + expect(state).to.have.property('commandShown', false); + expect(state).to.have.property('commandText', ''); + expect(state).to.have.deep.property('completions', []); + }); + + it('return next state for CONSOLE_SHOW_COMMAND', () => { + let action = { type: actions.CONSOLE_SHOW_COMMAND, text: 'open ' }; + let state = consoleReducer({}, action); + expect(state).to.have.property('commandShown', true); + expect(state).to.have.property('commandText', 'open '); + expect(state).to.have.property('errorShown', false); + }); + + it('return next state for CONSOLE_SET_COMPLETIONS', () => { + let action = { type: actions.CONSOLE_SET_COMPLETIONS, completions: [1, 2, 3] }; + let state = consoleReducer({}, action); + expect(state).to.have.deep.property('completions', [1, 2, 3]); + }); + + it('return next state for CONSOLE_SHOW_ERROR', () => { + let action = { type: actions.CONSOLE_SHOW_ERROR, text: 'an error' }; + let state = consoleReducer({}, action); + expect(state).to.have.property('errorShown', true); + expect(state).to.have.property('errorText', 'an error'); + expect(state).to.have.property('commandShown', false); + }); + + it('return next state for CONSOLE_HIDE', () => { + let action = { type: actions.CONSOLE_HIDE }; + let state = consoleReducer({}, action); + expect(state).to.have.property('errorShown', false); + expect(state).to.have.property('commandShown', false); + }); +}); -- cgit v1.2.3 From 3c67cc0a002aded07e88ea25acc881ff080d1ae4 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 10 Sep 2017 09:20:54 +0900 Subject: completion as action/reducer --- src/actions/background.js | 11 +++++++++++ src/actions/index.js | 4 +++- src/background/index.js | 20 +++++--------------- src/console/console-frame.js | 4 ---- src/console/console.js | 12 ++++-------- src/content/index.js | 19 ------------------- src/reducers/background.js | 38 ++++++++++++++++++++++++++++++++++++++ test/actions/background.test.js | 14 ++++++++++++++ 8 files changed, 75 insertions(+), 47 deletions(-) create mode 100644 src/actions/background.js create mode 100644 src/reducers/background.js create mode 100644 test/actions/background.test.js (limited to 'src/console/console.js') diff --git a/src/actions/background.js b/src/actions/background.js new file mode 100644 index 0000000..40b901b --- /dev/null +++ b/src/actions/background.js @@ -0,0 +1,11 @@ +import actions from '../actions'; + +export function requestCompletions(line) { + let command = line.split(' ', 1)[0]; + let keywords = line.replace(command + ' ', ''); + return { + type: actions.BACKGROUND_REQUEST_COMPLETIONS, + command, + keywords + }; +} diff --git a/src/actions/index.js b/src/actions/index.js index 38ced9d..8f22193 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -2,5 +2,7 @@ export default { CONSOLE_SHOW_COMMAND: 'vimvixen.console.show.command', CONSOLE_SET_COMPLETIONS: 'vimvixen.console.set.completions', CONSOLE_SHOW_ERROR: 'vimvixen.console.show.error', - CONSOLE_HIDE: 'vimvixen.console.hide' + CONSOLE_HIDE: 'vimvixen.console.hide', + + BACKGROUND_REQUEST_COMPLETIONS: 'vimvixen.background.request.completions' }; diff --git a/src/background/index.js b/src/background/index.js index 61d4895..a80d1ea 100644 --- a/src/background/index.js +++ b/src/background/index.js @@ -2,6 +2,7 @@ import * as actions from '../shared/actions'; import * as tabs from './tabs'; import * as zooms from './zooms'; import KeyQueue from './key-queue'; +import backgroundReducers from '../reducers/background'; const queue = new KeyQueue(); @@ -81,22 +82,11 @@ browser.runtime.onMessage.addListener((request, sender) => { return keyPressHandle(request, sender); case 'event.cmd.enter': return cmdEnterHandle(request, sender); - case 'event.cmd.tabs.completion': - return tabs.getCompletions(request.text).then((tabs) => { - let items = tabs.map((tab) => { - return { - caption: tab.title, - content: tab.title, - url: tab.url, - icon: tab.favIconUrl - } - }); - return { - name: "Buffers", - items: items - }; - }); default: return browser.tabs.sendMessage(sender.tab.id, request); } }); + +browser.runtime.onMessage.addListener((action, sender) => { + return backgroundReducers(undefined, action, sender.tab.id); +}); diff --git a/src/console/console-frame.js b/src/console/console-frame.js index 8b4c17a..063026c 100644 --- a/src/console/console-frame.js +++ b/src/console/console-frame.js @@ -45,8 +45,4 @@ export default class ConsoleFrame { isErrorShown() { return this.element.style.display === 'block' && this.errorShown; } - - setCompletions(completions) { - return browser.runtime.sendMessage(consoleActions.setCompletions(completions)); - } } diff --git a/src/console/console.js b/src/console/console.js index 35d98e0..d79e154 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -1,4 +1,5 @@ import './console.scss'; +import * as backgroundActions from '../actions/background'; import Completion from './completion'; import consoleReducer from '../reducers/console'; @@ -21,13 +22,6 @@ const keydownMessage = (input) => { }; }; -const keyupMessage = (input) => { - return { - type: 'vimvixen.command.change', - value: input.value - }; -}; - const handleBlur = () => { return browser.runtime.sendMessage(blurMessage()); }; @@ -88,7 +82,9 @@ const handleKeyup = (e) => { return; } prevValue = e.target.value; - return browser.runtime.sendMessage(keyupMessage(e.target)); + return browser.runtime.sendMessage( + backgroundActions.requestCompletions(e.target.value) + ); }; window.addEventListener('load', () => { diff --git a/src/content/index.js b/src/content/index.js index deb3506..1a7fa55 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -68,23 +68,6 @@ window.addEventListener("keypress", (e) => { }); }); -const doCompletion = (line) => { - if (line.startsWith('buffer ')) { - let keyword = line.replace('buffer ', ''); - - browser.runtime.sendMessage({ - type: 'event.cmd.tabs.completion', - text: keyword - }).then((completions) => { - vvConsole.setCompletions([completions]); - }).catch((err) => { - console.error("Vim Vixen:", err); - vvConsole.showError(err.message); - }); - } - return Promise.resolve(); -}; - browser.runtime.onMessage.addListener((action) => { switch (action.type) { case 'vimvixen.command.blur': @@ -100,8 +83,6 @@ browser.runtime.onMessage.addListener((action) => { console.error("Vim Vixen:", err); vvConsole.showError(err.message); }); - case 'vimvixen.command.change': - return doCompletion(action.value); default: return Promise.resolve(); } diff --git a/src/reducers/background.js b/src/reducers/background.js new file mode 100644 index 0000000..eccc8ca --- /dev/null +++ b/src/reducers/background.js @@ -0,0 +1,38 @@ +import * as tabs from '../background/tabs'; +import * as consoleActions from '../actions/console'; +import actions from '../actions'; + +const doCompletion = (command, keywords, sendto) => { + if (command === 'buffer') { + return tabs.getCompletions(keywords).then((tabs) => { + let items = tabs.map((tab) => { + return { + caption: tab.title, + content: tab.title, + url: tab.url, + icon: tab.favIconUrl + } + }); + let completions = { + name: "Buffers", + items: items + }; + return browser.tabs.sendMessage( + sendto, + consoleActions.setCompletions([completions])); + }); + } + return Promise.resolve(); +}; + + + +export default function reducer(state, action = {}, sendto) { + // TODO hide sendto object + switch (action.type) { + case actions.BACKGROUND_REQUEST_COMPLETIONS: + return doCompletion(action.command, action.keywords, sendto); + default: + return Promise.resolve(); + } +} diff --git a/test/actions/background.test.js b/test/actions/background.test.js new file mode 100644 index 0000000..a3203ee --- /dev/null +++ b/test/actions/background.test.js @@ -0,0 +1,14 @@ +import { expect } from "chai"; +import actions from '../../src/actions'; +import * as backgroundActions from '../../src/actions/background'; + +describe("background actions", () => { + describe("requestCompletions", () => { + it('create BACKGROUND_REQUEST_COMPLETIONS action', () => { + let action = backgroundActions.requestCompletions('buffer hoge fuga'); + expect(action.type).to.equal(actions.BACKGROUND_REQUEST_COMPLETIONS); + expect(action.command).to.equal('buffer'); + expect(action.keywords).to.equal('hoge fuga'); + }); + }); +}); -- cgit v1.2.3 From 359fdb528821844f3c2fda718b82ce229a64b29f Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 10 Sep 2017 15:49:51 +0900 Subject: blur as action/reducer --- src/console/console-frame.js | 48 -------------------------------------------- src/console/console.js | 17 ++++++++-------- src/console/frames.js | 27 +++++++++++++++++++++++++ src/content/index.js | 26 ++++++++++++------------ 4 files changed, 49 insertions(+), 69 deletions(-) delete mode 100644 src/console/console-frame.js create mode 100644 src/console/frames.js (limited to 'src/console/console.js') diff --git a/src/console/console-frame.js b/src/console/console-frame.js deleted file mode 100644 index 063026c..0000000 --- a/src/console/console-frame.js +++ /dev/null @@ -1,48 +0,0 @@ -import './console-frame.scss'; -import * as consoleActions from '../actions/console'; - -export default class ConsoleFrame { - constructor(win) { - let element = window.document.createElement('iframe'); - element.src = browser.runtime.getURL('build/console.html'); - element.className = 'vimvixen-console-frame'; - win.document.body.append(element); - - this.element = element; - - this.errorShown = true; - - this.hide(); - } - - showCommand(text) { - this.showFrame(); - this.errorShown = false; - return browser.runtime.sendMessage(consoleActions.showCommand(text)); - } - - showError(text) { - this.showFrame(); - - this.errorShown = true; - this.element.blur(); - - return browser.runtime.sendMessage(consoleActions.showError(text)); - } - - showFrame() { - this.element.style.display = 'block'; - } - - hide() { - this.element.style.display = 'none'; - this.element.blur(); - this.errorShown = false; - - return browser.runtime.sendMessage(consoleActions.hide()); - } - - isErrorShown() { - return this.element.style.display === 'block' && this.errorShown; - } -} diff --git a/src/console/console.js b/src/console/console.js index d79e154..f83f79c 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -1,5 +1,6 @@ import './console.scss'; import * as backgroundActions from '../actions/background'; +import * as consoleActions from '../actions/console'; import Completion from './completion'; import consoleReducer from '../reducers/console'; @@ -9,12 +10,6 @@ var completion = null; var completionOrigin = ""; let state = consoleReducer(undefined, {}); -const blurMessage = () => { - return { - type: 'vimvixen.command.blur' - }; -}; - const keydownMessage = (input) => { return { type: 'vimvixen.command.enter', @@ -23,7 +18,7 @@ const keydownMessage = (input) => { }; const handleBlur = () => { - return browser.runtime.sendMessage(blurMessage()); + return browser.runtime.sendMessage(consoleActions.hide()); }; const completeNext = () => { @@ -57,9 +52,11 @@ const completePrev = () => { } const handleKeydown = (e) => { + let input = window.document.querySelector('#vimvixen-console-command-input'); + switch(e.keyCode) { case KeyboardEvent.DOM_VK_ESCAPE: - return browser.runtime.sendMessage(blurMessage()); + return input.blur(); case KeyboardEvent.DOM_VK_RETURN: return browser.runtime.sendMessage(keydownMessage(e.target)); case KeyboardEvent.DOM_VK_TAB: @@ -183,3 +180,7 @@ browser.runtime.onMessage.addListener((action) => { state = nextState; } }); + +window.addEventListener('load', () => { + update({}, state); +}); diff --git a/src/console/frames.js b/src/console/frames.js new file mode 100644 index 0000000..0b6f3e2 --- /dev/null +++ b/src/console/frames.js @@ -0,0 +1,27 @@ +import './console-frame.scss'; +import * as consoleActions from '../actions/console'; + +const initialize = (doc) => { + let iframe = doc.createElement('iframe'); + iframe.src = browser.runtime.getURL('build/console.html'); + iframe.id = 'vimvixen-console-frame'; + iframe.className = 'vimvixen-console-frame'; + doc.body.append(iframe); + + return iframe; +} + +const showCommand = (text) => { + return browser.runtime.sendMessage(consoleActions.showCommand(text)); +}; + +const showError = (text) => { + return browser.runtime.sendMessage(consoleActions.showError(text)); +} + +const blur = (doc) => { + let iframe = doc.getElementById('vimvixen-console-frame'); + iframe.blur(); +} + +export { initialize, showCommand, showError, blur }; diff --git a/src/content/index.js b/src/content/index.js index 1a7fa55..4fba516 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -1,24 +1,26 @@ +import '../console/console-frame.scss'; import * as scrolls from './scrolls'; import * as histories from './histories'; import * as actions from '../shared/actions'; -import ConsoleFrame from '../console/console-frame'; +import * as consoleFrames from '../console/frames'; +import actionTypes from '../actions'; import Follow from './follow'; -let vvConsole = new ConsoleFrame(window); +consoleFrames.initialize(window.document); browser.runtime.onMessage.addListener((action) => { switch (action.type) { case actions.CMD_OPEN: - return vvConsole.showCommand(''); + return consoleFrames.showCommand(''); case actions.CMD_TABS_OPEN: if (action.alter) { // alter url - return vvConsole.showCommand('open ' + window.location.href); + return consoleFrames.showCommand('open ' + window.location.href); } else { - return vvConsole.showCommand('open '); + return consoleFrames.showCommand('open '); } case actions.CMD_BUFFER: - return vvConsole.showCommand('buffer '); + return consoleFrames.showCommand('buffer '); case actions.SCROLL_LINES: scrolls.scrollLines(window, action.count); break; @@ -64,24 +66,22 @@ window.addEventListener("keypress", (e) => { browser.runtime.sendMessage(request) .catch((err) => { console.error("Vim Vixen:", err); - vvConsole.showError(err.message); + return consoleFrames.showError(err.message); }); }); browser.runtime.onMessage.addListener((action) => { switch (action.type) { - case 'vimvixen.command.blur': - if (!vvConsole.isErrorShown()) { - vvConsole.hide(); - } - return Promise.resolve(); + case actionTypes.CONSOLE_HIDE: + window.focus(); + return consoleFrames.blur(window.document); case 'vimvixen.command.enter': return browser.runtime.sendMessage({ type: 'event.cmd.enter', text: action.value }).catch((err) => { console.error("Vim Vixen:", err); - vvConsole.showError(err.message); + return consoleFrames.showError(err.message); }); default: return Promise.resolve(); -- cgit v1.2.3 From bf890a6d9d793b581a44ee267616ed589f429bef Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 11 Sep 2017 21:07:02 +0900 Subject: command as action/reducer --- src/actions/command.js | 35 +++++++++++++++++++++++++++++++++++ src/actions/index.js | 4 ++++ src/background/index.js | 48 ++++++------------------------------------------ src/console/console.js | 10 ++-------- src/reducers/command.js | 24 ++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 50 deletions(-) create mode 100644 src/actions/command.js create mode 100644 src/reducers/command.js (limited to 'src/console/console.js') diff --git a/src/actions/command.js b/src/actions/command.js new file mode 100644 index 0000000..982255c --- /dev/null +++ b/src/actions/command.js @@ -0,0 +1,35 @@ +import actions from '../actions'; + +const normalizeUrl = (string) => { + try { + return new URL(string).href + } catch (e) { + return 'http://' + string; + } +} + +export function exec(line) { + let name = line.split(' ')[0]; + let remaining = line.replace(name + ' ', ''); + + switch (name) { + case 'open': + // TODO use search engined and pass keywords to them + return { + type: actions.COMMAND_OPEN_URL, + url: normalizeUrl(remaining) + }; + case 'tabopen': + return { + type: actions.COMMAND_TABOPEN_URL, + url: remaining + }; + case 'b': + case 'buffer': + return { + type: actions.COMMAND_BUFFER, + keywords: remaining + }; + } + throw new Error(name + ' command is not defined'); +} diff --git a/src/actions/index.js b/src/actions/index.js index 135dd4a..63d5f6f 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -33,4 +33,8 @@ export default { // User input INPUT_KEY_PRESS: 'input.key,press', INPUT_CLEAR_KEYS: 'input.clear.keys', + + COMMAND_OPEN_URL: 'command.open.url', + COMMAND_TABOPEN_URL: 'command.tabopen.url', + COMMAND_BUFFER: 'command.buffer', }; diff --git a/src/background/index.js b/src/background/index.js index 4d75b33..e72cab0 100644 --- a/src/background/index.js +++ b/src/background/index.js @@ -1,51 +1,11 @@ -import * as tabs from './tabs'; import * as keys from './keys'; import * as inputActions from '../actions/input'; import backgroundReducers from '../reducers/background'; +import commandReducer from '../reducers/command'; import inputReducers from '../reducers/input'; let inputState = inputReducers(undefined, {}); -const normalizeUrl = (string) => { - try { - return new URL(string).href - } catch (e) { - return 'http://' + string; - } -} - -const cmdBuffer = (sender, arg) => { - if (isNaN(arg)) { - return tabs.selectByKeyword(sender.tab, arg); - } else { - let index = parseInt(arg, 10) - 1; - return tabs.selectAt(index); - } -} - -const cmdEnterHandle = (request, sender) => { - let words = request.text.split(' ').filter((s) => s.length > 0); - switch (words[0]) { - case 'open': - return browser.tabs.update(sender.tab.id, { url: normalizeUrl(words[1]) }); - case 'tabopen': - return browser.tabs.create({ url: normalizeUrl(words[1]) }); - case 'b': - case 'buffer': - return cmdBuffer(sender, words[1]); - } - throw new Error(words[0] + ' command is not defined'); -}; - -browser.runtime.onMessage.addListener((request, sender) => { - switch (request.type) { - case 'event.cmd.enter': - return cmdEnterHandle(request, sender); - default: - return browser.tabs.sendMessage(sender.tab.id, request); - } -}); - const keyQueueChanged = (sender, prevState, state) => { if (state.keys.length === 0) { return Promise.resolve(); @@ -75,7 +35,11 @@ const handleMessage = (action, sender) => { inputState = nextInputState; return keyQueueChanged(sender, prevState, inputState); } - return backgroundReducers(undefined, action, sender); + return backgroundReducers(undefined, action, sender).then(() => { + return commandReducer(undefined, action, sender).then(() => { + return browser.tabs.sendMessage(sender.tab.id, action); + }); + }); }; browser.runtime.onMessage.addListener(handleMessage); diff --git a/src/console/console.js b/src/console/console.js index f83f79c..25ab36d 100644 --- a/src/console/console.js +++ b/src/console/console.js @@ -1,6 +1,7 @@ import './console.scss'; import * as backgroundActions from '../actions/background'; import * as consoleActions from '../actions/console'; +import * as commandActions from '../actions/command'; import Completion from './completion'; import consoleReducer from '../reducers/console'; @@ -10,13 +11,6 @@ var completion = null; var completionOrigin = ""; let state = consoleReducer(undefined, {}); -const keydownMessage = (input) => { - return { - type: 'vimvixen.command.enter', - value: input.value - }; -}; - const handleBlur = () => { return browser.runtime.sendMessage(consoleActions.hide()); }; @@ -58,7 +52,7 @@ const handleKeydown = (e) => { case KeyboardEvent.DOM_VK_ESCAPE: return input.blur(); case KeyboardEvent.DOM_VK_RETURN: - return browser.runtime.sendMessage(keydownMessage(e.target)); + return browser.runtime.sendMessage(commandActions.exec(e.target.value)); case KeyboardEvent.DOM_VK_TAB: if (e.shiftKey) { completePrev(); diff --git a/src/reducers/command.js b/src/reducers/command.js new file mode 100644 index 0000000..7e03593 --- /dev/null +++ b/src/reducers/command.js @@ -0,0 +1,24 @@ +import * as tabs from '../background/tabs'; +import actions from '../actions'; + +const cmdBuffer = (sender, arg) => { + if (isNaN(arg)) { + return tabs.selectByKeyword(sender.tab, arg); + } else { + let index = parseInt(arg, 10) - 1; + return tabs.selectAt(index); + } +} + +export default function reducer(state, action, sender) { + switch (action.type) { + case actions.COMMAND_OPEN_URL: + return browser.tabs.update(sender.tab.id, { url: action.url }); + case actions.COMMAND_TABOPEN_URL: + return browser.tabs.create({ url: action.url }); + case actions.COMMAND_BUFFER: + return cmdBuffer(sender, action.keywords); + default: + return Promise.resolve(); + } +} -- cgit v1.2.3