From bf283c732ef9424d365ca1b09ce8b174f61c336c Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 11 Oct 2018 15:00:50 +0900 Subject: Add mark action and reducer --- src/content/reducers/mark.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/content/reducers/mark.js (limited to 'src/content/reducers') diff --git a/src/content/reducers/mark.js b/src/content/reducers/mark.js new file mode 100644 index 0000000..b6a071f --- /dev/null +++ b/src/content/reducers/mark.js @@ -0,0 +1,25 @@ +import actions from 'content/actions'; + +const defaultState = { + set: false, + jump: false, + marks: {}, +}; + +export default function reducer(state = defaultState, action = {}) { + switch (action.type) { + case actions.MARK_START_SET: + return { ...state, set: true }; + case actions.MARK_START_JUMP: + return { ...state, jump: true }; + case actions.MARK_CANCEL: + return { ...state, set: false, jump: false }; + case actions.MARK_SET_LOCAL: { + let marks = { ...state.marks }; + marks[action.key] = { y: action.y }; + return { ...state, marks }; + } + default: + return state; + } +} -- cgit v1.2.3 From 2055dfb2fb0f3fa86d359984583789db155903a1 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 11 Oct 2018 15:35:28 +0900 Subject: Rename mode acton and reducer --- src/content/actions/operation.js | 5 +++++ src/content/reducers/mark.js | 10 +++++----- test/content/reducers/mark.test.js | 16 ++++++++-------- 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'src/content/reducers') diff --git a/src/content/actions/operation.js b/src/content/actions/operation.js index 89d7fec..94aa356 100644 --- a/src/content/actions/operation.js +++ b/src/content/actions/operation.js @@ -6,6 +6,7 @@ import * as focuses from 'content/focuses'; import * as urls from 'content/urls'; import * as consoleFrames from 'content/console-frames'; import * as addonActions from './addon'; +import * as markActions from './mark'; import * as properties from 'shared/settings/properties'; // eslint-disable-next-line complexity, max-lines-per-function @@ -57,6 +58,10 @@ const exec = (operation, repeat, settings, addonEnabled) => { background: operation.background, }), '*'); break; + case operations.MARK_SET_PREFIX: + return markActions.startSet(); + case operations.MARK_JUMP_PREFIX: + return markActions.startJump(); case operations.NAVIGATE_HISTORY_PREV: navigates.historyPrev(window); break; diff --git a/src/content/reducers/mark.js b/src/content/reducers/mark.js index b6a071f..700c03f 100644 --- a/src/content/reducers/mark.js +++ b/src/content/reducers/mark.js @@ -1,19 +1,19 @@ import actions from 'content/actions'; const defaultState = { - set: false, - jump: false, + setMode: false, + jumpMode: false, marks: {}, }; export default function reducer(state = defaultState, action = {}) { switch (action.type) { case actions.MARK_START_SET: - return { ...state, set: true }; + return { ...state, setMode: true }; case actions.MARK_START_JUMP: - return { ...state, jump: true }; + return { ...state, jumpMode: true }; case actions.MARK_CANCEL: - return { ...state, set: false, jump: false }; + return { ...state, setMode: false, jumpMode: false }; case actions.MARK_SET_LOCAL: { let marks = { ...state.marks }; marks[action.key] = { y: action.y }; diff --git a/test/content/reducers/mark.test.js b/test/content/reducers/mark.test.js index 39c04cd..6358bf1 100644 --- a/test/content/reducers/mark.test.js +++ b/test/content/reducers/mark.test.js @@ -4,30 +4,30 @@ import reducer from 'content/reducers/mark'; describe("mark reducer", () => { it('return the initial state', () => { let state = reducer(undefined, {}); - expect(state.set).to.be.false; - expect(state.jump).to.be.false; + expect(state.setMode).to.be.false; + expect(state.jumpMode).to.be.false; expect(state.marks).to.be.empty; }); it('starts set mode', () => { let action = { type: actions.MARK_START_SET }; let state = reducer(undefined, action); - expect(state.set).to.be.true; + expect(state.setMode).to.be.true; }); it('starts jump mode', () => { let action = { type: actions.MARK_START_JUMP }; let state = reducer(undefined, action); - expect(state.jump).to.be.true; + expect(state.jumpMode).to.be.true; }); it('cancels set and jump mode', () => { let action = { type: actions.MARK_CANCEL }; - let state = reducer({ set: true }, action); - expect(state.set).to.be.false; + let state = reducer({ setMode: true }, action); + expect(state.setMode).to.be.false; - state = reducer({ jump: true }, action); - expect(state.jump).to.be.false; + state = reducer({ jumpMode: true }, action); + expect(state.jumpMode).to.be.false; }); it('stores local mark', () => { -- cgit v1.2.3 From c89b92d9bb03a607704cd1ccf45d34a8b9001f1a Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 11 Oct 2018 17:02:17 +0900 Subject: Make setMode false on mark is set --- src/content/reducers/mark.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/content/reducers') diff --git a/src/content/reducers/mark.js b/src/content/reducers/mark.js index 700c03f..b6137f3 100644 --- a/src/content/reducers/mark.js +++ b/src/content/reducers/mark.js @@ -17,7 +17,7 @@ export default function reducer(state = defaultState, action = {}) { case actions.MARK_SET_LOCAL: { let marks = { ...state.marks }; marks[action.key] = { y: action.y }; - return { ...state, marks }; + return { ...state, setMode: false, marks }; } default: return state; -- cgit v1.2.3 From f66e75575dd26b7f60e70c9856d8cd56770f74e7 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 11 Oct 2018 17:20:02 +0900 Subject: Store x position into marks --- src/content/actions/mark.js | 3 ++- src/content/reducers/mark.js | 2 +- test/content/actions/mark.test.js | 3 ++- test/content/reducers/mark.test.js | 8 +++++--- 4 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src/content/reducers') diff --git a/src/content/actions/mark.js b/src/content/actions/mark.js index baf5825..1f5174e 100644 --- a/src/content/actions/mark.js +++ b/src/content/actions/mark.js @@ -12,10 +12,11 @@ const cancel = () => { return { type: actions.MARK_CANCEL }; }; -const setLocal = (key, y) => { +const setLocal = (key, x, y) => { return { type: actions.MARK_SET_LOCAL, key, + x, y, }; }; diff --git a/src/content/reducers/mark.js b/src/content/reducers/mark.js index b6137f3..2c96cc5 100644 --- a/src/content/reducers/mark.js +++ b/src/content/reducers/mark.js @@ -16,7 +16,7 @@ export default function reducer(state = defaultState, action = {}) { return { ...state, setMode: false, jumpMode: false }; case actions.MARK_SET_LOCAL: { let marks = { ...state.marks }; - marks[action.key] = { y: action.y }; + marks[action.key] = { x: action.x, y: action.y }; return { ...state, setMode: false, marks }; } default: diff --git a/test/content/actions/mark.test.js b/test/content/actions/mark.test.js index 47d31cd..adbf06b 100644 --- a/test/content/actions/mark.test.js +++ b/test/content/actions/mark.test.js @@ -25,9 +25,10 @@ describe('mark actions', () => { describe('setLocal', () => { it('create setLocal action', () => { - let action = markActions.setLocal('a', 30); + let action = markActions.setLocal('a', 20, 30); expect(action.type).to.equal(actions.MARK_SET_LOCAL); expect(action.key).to.equal('a'); + expect(action.x).to.equal(20); expect(action.y).to.equal(30); }); }); diff --git a/test/content/reducers/mark.test.js b/test/content/reducers/mark.test.js index 6358bf1..76efbf7 100644 --- a/test/content/reducers/mark.test.js +++ b/test/content/reducers/mark.test.js @@ -31,9 +31,11 @@ describe("mark reducer", () => { }); it('stores local mark', () => { - let action = { type: actions.MARK_SET_LOCAL, key: 'a', y: 10 }; - let state = reducer(undefined, action); + let action = { type: actions.MARK_SET_LOCAL, key: 'a', x: 20, y: 30}; + let state = reducer({ setMode: true }, action); + expect(state.setMode).to.be.false; expect(state.marks['a']).to.be.an('object') - expect(state.marks['a'].y).to.equal(10) + expect(state.marks['a'].x).to.equal(20) + expect(state.marks['a'].y).to.equal(30) }); }); -- cgit v1.2.3 From 6e6e306275a8ee5632a22b1e30c807bd5ae9cc7e Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 11 Oct 2018 17:42:38 +0900 Subject: Store local marks --- src/content/actions/operation.js | 8 ++--- src/content/components/common/index.js | 7 ++-- src/content/components/common/mark.js | 59 ++++++++++++++++++++++++++++++++++ src/content/reducers/index.js | 3 +- src/content/scrolls.js | 30 +++++++++++------ 5 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 src/content/components/common/mark.js (limited to 'src/content/reducers') diff --git a/src/content/actions/operation.js b/src/content/actions/operation.js index 94aa356..1aeb8be 100644 --- a/src/content/actions/operation.js +++ b/src/content/actions/operation.js @@ -40,16 +40,16 @@ const exec = (operation, repeat, settings, addonEnabled) => { scrolls.scrollPages(operation.count, smoothscroll, repeat); break; case operations.SCROLL_TOP: - scrolls.scrollTop(smoothscroll, repeat); + scrolls.scrollToTop(smoothscroll); break; case operations.SCROLL_BOTTOM: - scrolls.scrollBottom(smoothscroll, repeat); + scrolls.scrollToBottom(smoothscroll); break; case operations.SCROLL_HOME: - scrolls.scrollHome(smoothscroll, repeat); + scrolls.scrollToHome(smoothscroll); break; case operations.SCROLL_END: - scrolls.scrollEnd(smoothscroll, repeat); + scrolls.scrollToEnd(smoothscroll); break; case operations.FOLLOW_START: window.top.postMessage(JSON.stringify({ diff --git a/src/content/components/common/index.js b/src/content/components/common/index.js index a1e71a1..bcab4fa 100644 --- a/src/content/components/common/index.js +++ b/src/content/components/common/index.js @@ -1,6 +1,7 @@ import InputComponent from './input'; -import KeymapperComponent from './keymapper'; import FollowComponent from './follow'; +import MarkComponent from './mark'; +import KeymapperComponent from './keymapper'; import * as settingActions from 'content/actions/setting'; import messages from 'shared/messages'; import * as addonActions from '../../actions/addon'; @@ -8,11 +9,13 @@ import * as blacklists from 'shared/blacklists'; export default class Common { constructor(win, store) { - const follow = new FollowComponent(win, store); const input = new InputComponent(win.document.body, store); + const follow = new FollowComponent(win, store); + const mark = new MarkComponent(win.document.body, store); const keymapper = new KeymapperComponent(store); input.onKey(key => follow.key(key)); + input.onKey(key => mark.key(key)); input.onKey(key => keymapper.key(key)); this.win = win; diff --git a/src/content/components/common/mark.js b/src/content/components/common/mark.js new file mode 100644 index 0000000..06b2657 --- /dev/null +++ b/src/content/components/common/mark.js @@ -0,0 +1,59 @@ +import * as markActions from 'content/actions/mark'; +import * as scrolls from 'content/scrolls'; +import * as consoleFrames from 'content/console-frames'; +import * as properties from 'shared/settings/properties'; + +const cancelKey = (key) => { + return key.key === 'Esc' || key.key === '[' && key.ctrlKey; +}; + +export default class MarkComponent { + constructor(body, store) { + this.body = body; + this.store = store; + } + + // eslint-disable-next-line max-statements + key(key) { + let { mark: markStage, setting } = this.store.getState(); + let smoothscroll = setting.properties.smoothscroll || + properties.defaults.smoothscroll; + + if (!markStage.setMode && !markStage.jumpMode) { + return false; + } + + if (cancelKey(key)) { + this.store.dispatch(markActions.cancel()); + return true; + } + + if (key.ctrlKey || key.metaKey || key.altKey) { + consoleFrames.postError(window.document, 'Unknown mark'); + } else if (key.shiftKey) { + consoleFrames.postError(window.document, 'Globa marks not supported'); + } else if (markStage.setMode) { + this.doSet(key); + } else if (markStage.jumpMode) { + this.doJump(markStage.marks, key, smoothscroll); + } + + this.store.dispatch(markActions.cancel()); + return true; + } + + doSet(key) { + let { x, y } = scrolls.getScroll(); + this.store.dispatch(markActions.setLocal(key.key, x, y)); + } + + doJump(marks, key, smoothscroll) { + if (!marks[key.key]) { + consoleFrames.postError(window.document, 'Mark is not set'); + return; + } + + let { x, y } = marks[key.key]; + scrolls.scrollTo(x, y, smoothscroll); + } +} diff --git a/src/content/reducers/index.js b/src/content/reducers/index.js index 6e6a147..bf612a3 100644 --- a/src/content/reducers/index.js +++ b/src/content/reducers/index.js @@ -4,7 +4,8 @@ import find from './find'; import setting from './setting'; import input from './input'; import followController from './follow-controller'; +import mark from './mark'; export default combineReducers({ - addon, find, setting, input, followController, + addon, find, setting, input, followController, mark, }); diff --git a/src/content/scrolls.js b/src/content/scrolls.js index 0d1f7c8..b9a4bc3 100644 --- a/src/content/scrolls.js +++ b/src/content/scrolls.js @@ -130,6 +130,11 @@ const scroller = (element, smooth, repeat) => { return new RoughtScroller(element); }; +const getScroll = () => { + let target = scrollTarget(); + return { x: target.scrollLeft, y: target.scrollTop }; +}; + const scrollVertically = (count, smooth, repeat) => { let target = scrollTarget(); let x = target.scrollLeft; @@ -158,35 +163,42 @@ const scrollPages = (count, smooth, repeat) => { scroller(target, smooth, repeat).scroll(x, y); }; -const scrollTop = (smooth, repeat) => { +const scrollTo = (x, y, smooth) => { + let target = scrollTarget(); + scroller(target, smooth, false).scroll(x, y); +}; + +const scrollToTop = (smooth) => { let target = scrollTarget(); let x = target.scrollLeft; let y = 0; - scroller(target, smooth, repeat).scroll(x, y); + scroller(target, smooth, false).scroll(x, y); }; -const scrollBottom = (smooth, repeat) => { +const scrollToBottom = (smooth) => { let target = scrollTarget(); let x = target.scrollLeft; let y = target.scrollHeight; - scroller(target, smooth, repeat).scroll(x, y); + scroller(target, smooth, false).scroll(x, y); }; -const scrollHome = (smooth, repeat) => { +const scrollToHome = (smooth) => { let target = scrollTarget(); let x = 0; let y = target.scrollTop; - scroller(target, smooth, repeat).scroll(x, y); + scroller(target, smooth, false).scroll(x, y); }; -const scrollEnd = (smooth, repeat) => { +const scrollToEnd = (smooth) => { let target = scrollTarget(); let x = target.scrollWidth; let y = target.scrollTop; - scroller(target, smooth, repeat).scroll(x, y); + scroller(target, smooth, false).scroll(x, y); }; export { + getScroll, scrollVertically, scrollHorizonally, scrollPages, - scrollTop, scrollBottom, scrollHome, scrollEnd + scrollTo, + scrollToTop, scrollToBottom, scrollToHome, scrollToEnd }; -- cgit v1.2.3