Merge pull request #19 from ueokande/content-and-background-redux-completely
Refactor: full redux on content and backgroundjh-changes
commit
d995ab0030
44 changed files with 360 additions and 404 deletions
@ -1,22 +0,0 @@ |
||||
import actions from '../actions'; |
||||
|
||||
const setItems = (groups) => { |
||||
return { |
||||
type: actions.COMPLETION_SET_ITEMS, |
||||
groups, |
||||
}; |
||||
}; |
||||
|
||||
const selectNext = () => { |
||||
return { |
||||
type: actions.COMPLETION_SELECT_NEXT |
||||
}; |
||||
}; |
||||
|
||||
const selectPrev = () => { |
||||
return { |
||||
type: actions.COMPLETION_SELECT_PREV |
||||
}; |
||||
}; |
||||
|
||||
export { setItems, selectNext, selectPrev }; |
@ -1,30 +1,24 @@ |
||||
import * as consoleActions from '../actions/console'; |
||||
import * as settingsActions from '../actions/setting'; |
||||
import BackgroundComponent from '../components/background'; |
||||
import BackgroundInputComponent from '../components/background-input'; |
||||
import reducers from '../reducers'; |
||||
import messages from '../content/messages'; |
||||
import * as store from '../store'; |
||||
import * as settingsActions from 'actions/setting'; |
||||
import messages from 'content/messages'; |
||||
import BackgroundComponent from 'components/background'; |
||||
import BackgroundInputComponent from 'components/background-input'; |
||||
import reducers from 'reducers'; |
||||
import { createStore } from 'store'; |
||||
|
||||
const backgroundStore = store.createStore(reducers, (e, sender) => { |
||||
const store = createStore(reducers, (e, sender) => { |
||||
console.error('Vim-Vixen:', e); |
||||
if (sender) { |
||||
backgroundStore.dispatch(consoleActions.showError(e.message), sender); |
||||
return browser.tabs.sendMessage(sender.tab.id, { |
||||
type: messages.CONSOLE_SHOW_ERROR, |
||||
text: e.message, |
||||
}); |
||||
} |
||||
}); |
||||
const backgroundComponent = new BackgroundComponent(backgroundStore); |
||||
const backgroundInputComponent = new BackgroundInputComponent(backgroundStore); |
||||
backgroundStore.subscribe((sender) => { |
||||
const backgroundComponent = new BackgroundComponent(store); |
||||
const backgroundInputComponent = new BackgroundInputComponent(store); |
||||
store.subscribe((sender) => { |
||||
backgroundComponent.update(sender); |
||||
backgroundInputComponent.update(sender); |
||||
}); |
||||
backgroundStore.subscribe((sender) => { |
||||
if (sender) { |
||||
return browser.tabs.sendMessage(sender.tab.id, { |
||||
type: messages.STATE_UPDATE, |
||||
state: backgroundStore.getState() |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
backgroundStore.dispatch(settingsActions.load()); |
||||
store.dispatch(settingsActions.load()); |
||||
|
@ -1,45 +1,34 @@ |
||||
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'; |
||||
import messages from 'content/messages'; |
||||
import CompletionComponent from 'components/completion'; |
||||
import ConsoleComponent from 'components/console'; |
||||
import reducers from 'reducers'; |
||||
import { createStore } from 'store'; |
||||
import * as consoleActions from 'actions/console'; |
||||
|
||||
const completionStore = store.createStore(completionReducer); |
||||
const store = createStore(reducers); |
||||
let completionComponent = null; |
||||
let consoleComponent = null; |
||||
let prevState = {}; |
||||
|
||||
window.addEventListener('load', () => { |
||||
let wrapper = document.querySelector('#vimvixen-console-completion'); |
||||
completionComponent = new CompletionComponent(wrapper, completionStore); |
||||
completionComponent = new CompletionComponent(wrapper, store); |
||||
|
||||
// TODO use root root store instead of completionStore
|
||||
consoleComponent = new ConsoleComponent(document.body, completionStore); |
||||
consoleComponent = new ConsoleComponent(document.body, store); |
||||
}); |
||||
|
||||
completionStore.subscribe(() => { |
||||
store.subscribe(() => { |
||||
completionComponent.update(); |
||||
|
||||
let state = completionStore.getState(); |
||||
|
||||
if (state.groupSelection >= 0) { |
||||
let item = state.groups[state.groupSelection].items[state.itemSelection]; |
||||
consoleComponent.setCommandValue(item.content); |
||||
} else if (state.groups.length > 0 && |
||||
JSON.stringify(prevState.groups) === JSON.stringify(state.groups)) { |
||||
// Reset input only completion groups not changed (unselected an item in
|
||||
// completion) in order to avoid to override previous input
|
||||
consoleComponent.setCommandCompletionOrigin(); |
||||
} |
||||
prevState = state; |
||||
consoleComponent.update(); |
||||
}); |
||||
|
||||
browser.runtime.onMessage.addListener((action) => { |
||||
if (action.type === messages.STATE_UPDATE) { |
||||
let state = action.state.console; |
||||
consoleComponent.update(state); |
||||
completionStore.dispatch(completionActions.setItems(state.completions)); |
||||
switch (action.type) { |
||||
case messages.CONSOLE_SHOW_COMMAND: |
||||
return store.dispatch(consoleActions.showCommand(action.command)); |
||||
case messages.CONSOLE_SHOW_ERROR: |
||||
return store.dispatch(consoleActions.showError(action.text)); |
||||
case messages.CONSOLE_HIDE: |
||||
return store.dispatch(consoleActions.hide(action.command)); |
||||
} |
||||
}); |
||||
|
@ -1,15 +1,15 @@ |
||||
import './settings.scss'; |
||||
import SettingComponent from '../components/setting'; |
||||
import settingReducer from '../reducers/setting'; |
||||
import * as store from '../store'; |
||||
import SettingComponent from 'components/setting'; |
||||
import settingReducer from 'reducers/setting'; |
||||
import { createStore } from 'store'; |
||||
|
||||
const settingStore = store.createStore(settingReducer); |
||||
const store = createStore(settingReducer); |
||||
let settingComponent = null; |
||||
|
||||
settingStore.subscribe(() => { |
||||
store.subscribe(() => { |
||||
settingComponent.update(); |
||||
}); |
||||
|
||||
document.addEventListener('DOMContentLoaded', () => { |
||||
settingComponent = new SettingComponent(document.body, settingStore); |
||||
settingComponent = new SettingComponent(document.body, store); |
||||
}); |
||||
|
@ -1,68 +0,0 @@ |
||||
import actions from '../actions'; |
||||
|
||||
const defaultState = { |
||||
groupSelection: -1, |
||||
itemSelection: -1, |
||||
groups: [], |
||||
}; |
||||
|
||||
const nextSelection = (state) => { |
||||
if (state.groupSelection < 0) { |
||||
return [0, 0]; |
||||
} |
||||
|
||||
let group = state.groups[state.groupSelection]; |
||||
if (state.groupSelection + 1 >= state.groups.length && |
||||
state.itemSelection + 1 >= group.items.length) { |
||||
return [-1, -1]; |
||||
} |
||||
if (state.itemSelection + 1 >= group.items.length) { |
||||
return [state.groupSelection + 1, 0]; |
||||
} |
||||
return [state.groupSelection, state.itemSelection + 1]; |
||||
}; |
||||
|
||||
const prevSelection = (state) => { |
||||
if (state.groupSelection < 0) { |
||||
return [ |
||||
state.groups.length - 1, |
||||
state.groups[state.groups.length - 1].items.length - 1 |
||||
]; |
||||
} |
||||
if (state.groupSelection === 0 && state.itemSelection === 0) { |
||||
return [-1, -1]; |
||||
} else if (state.itemSelection === 0) { |
||||
return [ |
||||
state.groupSelection - 1, |
||||
state.groups[state.groupSelection - 1].items.length - 1 |
||||
]; |
||||
} |
||||
return [state.groupSelection, state.itemSelection - 1]; |
||||
}; |
||||
|
||||
export default function reducer(state = defaultState, action = {}) { |
||||
switch (action.type) { |
||||
case actions.COMPLETION_SET_ITEMS: |
||||
return Object.assign({}, state, { |
||||
groups: action.groups, |
||||
groupSelection: -1, |
||||
itemSelection: -1, |
||||
}); |
||||
case actions.COMPLETION_SELECT_NEXT: { |
||||
let next = nextSelection(state); |
||||
return Object.assign({}, state, { |
||||
groupSelection: next[0], |
||||
itemSelection: next[1], |
||||
}); |
||||
} |
||||
case actions.COMPLETION_SELECT_PREV: { |
||||
let next = prevSelection(state); |
||||
return Object.assign({}, state, { |
||||
groupSelection: next[0], |
||||
itemSelection: next[1], |
||||
}); |
||||
} |
||||
default: |
||||
return defaultState; |
||||
} |
||||
} |
@ -1,27 +0,0 @@ |
||||
import { expect } from "chai"; |
||||
import actions from '../../src/actions'; |
||||
import * as completionActions from '../../src/actions/completion'; |
||||
|
||||
describe("completion actions", () => { |
||||
describe('setItems', () => { |
||||
it('create COMPLETION_SET_ITEMS action', () => { |
||||
let action = completionActions.setItems([1, 2, 3]); |
||||
expect(action.type).to.equal(actions.COMPLETION_SET_ITEMS); |
||||
expect(action.groups).to.deep.equal([1, 2, 3]); |
||||
}); |
||||
}); |
||||
|
||||
describe('selectNext', () => { |
||||
it('create COMPLETION_SELECT_NEXT action', () => { |
||||
let action = completionActions.selectNext(); |
||||
expect(action.type).to.equal(actions.COMPLETION_SELECT_NEXT); |
||||
}); |
||||
}); |
||||
|
||||
describe('selectPrev', () => { |
||||
it('create COMPLETION_SELECT_PREV action', () => { |
||||
let action = completionActions.selectPrev(); |
||||
expect(action.type).to.equal(actions.COMPLETION_SELECT_PREV); |
||||
}); |
||||
}); |
||||
}); |
@ -1,90 +0,0 @@ |
||||
import { expect } from "chai"; |
||||
import actions from '../../src/actions'; |
||||
import completionReducer from '../../src/reducers/completion'; |
||||
|
||||
describe("completion reducer", () => { |
||||
it ('return the initial state', () => { |
||||
let state = completionReducer(undefined, {}); |
||||
expect(state).to.have.property('groupSelection', -1); |
||||
expect(state).to.have.property('itemSelection', -1); |
||||
expect(state).to.have.deep.property('groups', []); |
||||
}); |
||||
|
||||
it ('return next state for COMPLETION_SET_ITEMS', () => { |
||||
let state = { |
||||
groupSelection: 0, |
||||
itemSelection: 0, |
||||
groups: [], |
||||
} |
||||
let action = { |
||||
type: actions.COMPLETION_SET_ITEMS, |
||||
groups: [{ |
||||
name: 'Apple', |
||||
items: [1, 2, 3] |
||||
}, { |
||||
name: 'Banana', |
||||
items: [4, 5, 6] |
||||
}] |
||||
} |
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groups', action.groups); |
||||
expect(state).to.have.property('groupSelection', -1); |
||||
expect(state).to.have.property('itemSelection', -1); |
||||
}); |
||||
|
||||
it ('return next state for COMPLETION_SELECT_NEXT', () => { |
||||
let action = { type: actions.COMPLETION_SELECT_NEXT }; |
||||
let state = { |
||||
groupSelection: -1, |
||||
itemSelection: -1, |
||||
groups: [{ |
||||
name: 'Apple', |
||||
items: [1, 2] |
||||
}, { |
||||
name: 'Banana', |
||||
items: [3] |
||||
}] |
||||
}; |
||||
|
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groupSelection', 0); |
||||
expect(state).to.have.property('itemSelection', 0); |
||||
|
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groupSelection', 0); |
||||
expect(state).to.have.property('itemSelection', 1); |
||||
|
||||
state = completionReducer(state, action); |
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groupSelection', -1); |
||||
expect(state).to.have.property('itemSelection', -1); |
||||
}); |
||||
|
||||
it ('return next state for COMPLETION_SELECT_PREV', () => { |
||||
let action = { type: actions.COMPLETION_SELECT_PREV }; |
||||
let state = { |
||||
groupSelection: -1, |
||||
itemSelection: -1, |
||||
groups: [{ |
||||
name: 'Apple', |
||||
items: [1, 2] |
||||
}, { |
||||
name: 'Banana', |
||||
items: [3] |
||||
}] |
||||
}; |
||||
|
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groupSelection', 1); |
||||
expect(state).to.have.property('itemSelection', 0); |
||||
|
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groupSelection', 0); |
||||
expect(state).to.have.property('itemSelection', 1); |
||||
|
||||
state = completionReducer(state, action); |
||||
state = completionReducer(state, action); |
||||
expect(state).to.have.property('groupSelection', -1); |
||||
expect(state).to.have.property('itemSelection', -1); |
||||
}); |
||||
}); |
Reference in new issue