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 };