diff options
Diffstat (limited to 'src/content/components')
-rw-r--r-- | src/content/components/common/follow.ts | 231 | ||||
-rw-r--r-- | src/content/components/common/hint.ts | 62 | ||||
-rw-r--r-- | src/content/components/common/index.ts | 61 | ||||
-rw-r--r-- | src/content/components/common/input.ts | 80 | ||||
-rw-r--r-- | src/content/components/common/keymapper.ts | 68 | ||||
-rw-r--r-- | src/content/components/common/mark.ts | 79 | ||||
-rw-r--r-- | src/content/components/frame-content.ts | 3 | ||||
-rw-r--r-- | src/content/components/top-content/find.ts | 46 | ||||
-rw-r--r-- | src/content/components/top-content/follow-controller.ts | 166 | ||||
-rw-r--r-- | src/content/components/top-content/index.ts | 51 |
10 files changed, 0 insertions, 847 deletions
diff --git a/src/content/components/common/follow.ts b/src/content/components/common/follow.ts deleted file mode 100644 index 67f2dd9..0000000 --- a/src/content/components/common/follow.ts +++ /dev/null @@ -1,231 +0,0 @@ -import MessageListener from '../../MessageListener'; -import Hint from './hint'; -import * as dom from '../../../shared/utils/dom'; -import * as messages from '../../../shared/messages'; -import * as keyUtils from '../../../shared/utils/keys'; - -const TARGET_SELECTOR = [ - 'a', 'button', 'input', 'textarea', 'area', - '[contenteditable=true]', '[contenteditable=""]', '[tabindex]', - '[role="button"]', 'summary' -].join(','); - -interface Size { - width: number; - height: number; -} - -interface Point { - x: number; - y: number; -} - -const inViewport = ( - win: Window, - element: Element, - viewSize: Size, - framePosition: Point, -): boolean => { - let { - top, left, bottom, right - } = dom.viewportRect(element); - let doc = win.document; - let frameWidth = doc.documentElement.clientWidth; - let frameHeight = doc.documentElement.clientHeight; - - if (right < 0 || bottom < 0 || top > frameHeight || left > frameWidth) { - // out of frame - return false; - } - if (right + framePosition.x < 0 || bottom + framePosition.y < 0 || - left + framePosition.x > viewSize.width || - top + framePosition.y > viewSize.height) { - // out of viewport - return false; - } - return true; -}; - -const isAriaHiddenOrAriaDisabled = (win: Window, element: Element): boolean => { - if (!element || win.document.documentElement === element) { - return false; - } - for (let attr of ['aria-hidden', 'aria-disabled']) { - let value = element.getAttribute(attr); - if (value !== null) { - let hidden = value.toLowerCase(); - if (hidden === '' || hidden === 'true') { - return true; - } - } - } - return isAriaHiddenOrAriaDisabled(win, element.parentElement as Element); -}; - -export default class Follow { - private win: Window; - - private newTab: boolean; - - private background: boolean; - - private hints: {[key: string]: Hint }; - - private targets: HTMLElement[] = []; - - constructor(win: Window) { - this.win = win; - this.newTab = false; - this.background = false; - this.hints = {}; - this.targets = []; - - new MessageListener().onWebMessage(this.onMessage.bind(this)); - } - - key(key: keyUtils.Key): boolean { - if (Object.keys(this.hints).length === 0) { - return false; - } - this.win.parent.postMessage(JSON.stringify({ - type: messages.FOLLOW_KEY_PRESS, - key: key.key, - ctrlKey: key.ctrlKey, - }), '*'); - return true; - } - - openLink(element: HTMLAreaElement|HTMLAnchorElement) { - // Browser prevent new tab by link with target='_blank' - if (!this.newTab && element.getAttribute('target') !== '_blank') { - element.click(); - return; - } - - let href = element.getAttribute('href'); - - // eslint-disable-next-line no-script-url - if (!href || href === '#' || href.toLowerCase().startsWith('javascript:')) { - return; - } - return browser.runtime.sendMessage({ - type: messages.OPEN_URL, - url: element.href, - newTab: true, - background: this.background, - }); - } - - countHints(sender: any, viewSize: Size, framePosition: Point) { - this.targets = Follow.getTargetElements(this.win, viewSize, framePosition); - sender.postMessage(JSON.stringify({ - type: messages.FOLLOW_RESPONSE_COUNT_TARGETS, - count: this.targets.length, - }), '*'); - } - - createHints(keysArray: string[], newTab: boolean, background: boolean) { - if (keysArray.length !== this.targets.length) { - throw new Error('illegal hint count'); - } - - this.newTab = newTab; - this.background = background; - this.hints = {}; - for (let i = 0; i < keysArray.length; ++i) { - let keys = keysArray[i]; - let hint = new Hint(this.targets[i], keys); - this.hints[keys] = hint; - } - } - - showHints(keys: string) { - Object.keys(this.hints).filter(key => key.startsWith(keys)) - .forEach(key => this.hints[key].show()); - Object.keys(this.hints).filter(key => !key.startsWith(keys)) - .forEach(key => this.hints[key].hide()); - } - - removeHints() { - Object.keys(this.hints).forEach((key) => { - this.hints[key].remove(); - }); - this.hints = {}; - this.targets = []; - } - - activateHints(keys: string) { - let hint = this.hints[keys]; - if (!hint) { - return; - } - let element = hint.getTarget(); - switch (element.tagName.toLowerCase()) { - case 'a': - return this.openLink(element as HTMLAnchorElement); - case 'area': - return this.openLink(element as HTMLAreaElement); - case 'input': - switch ((element as HTMLInputElement).type) { - case 'file': - case 'checkbox': - case 'radio': - case 'submit': - case 'reset': - case 'button': - case 'image': - case 'color': - return element.click(); - default: - return element.focus(); - } - case 'textarea': - return element.focus(); - case 'button': - case 'summary': - return element.click(); - default: - if (dom.isContentEditable(element)) { - return element.focus(); - } else if (element.hasAttribute('tabindex')) { - return element.click(); - } - } - } - - onMessage(message: messages.Message, sender: any) { - switch (message.type) { - case messages.FOLLOW_REQUEST_COUNT_TARGETS: - return this.countHints(sender, message.viewSize, message.framePosition); - case messages.FOLLOW_CREATE_HINTS: - return this.createHints( - message.keysArray, message.newTab, message.background); - case messages.FOLLOW_SHOW_HINTS: - return this.showHints(message.keys); - case messages.FOLLOW_ACTIVATE: - return this.activateHints(message.keys); - case messages.FOLLOW_REMOVE_HINTS: - return this.removeHints(); - } - } - - static getTargetElements( - win: Window, - viewSize: - Size, framePosition: Point, - ): HTMLElement[] { - let all = win.document.querySelectorAll(TARGET_SELECTOR); - let filtered = Array.prototype.filter.call(all, (element: HTMLElement) => { - let style = win.getComputedStyle(element); - - // AREA's 'display' in Browser style is 'none' - return (element.tagName === 'AREA' || style.display !== 'none') && - style.visibility !== 'hidden' && - (element as HTMLInputElement).type !== 'hidden' && - element.offsetHeight > 0 && - !isAriaHiddenOrAriaDisabled(win, element) && - inViewport(win, element, viewSize, framePosition); - }); - return filtered; - } -} diff --git a/src/content/components/common/hint.ts b/src/content/components/common/hint.ts deleted file mode 100644 index 2fcbb0f..0000000 --- a/src/content/components/common/hint.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as dom from '../../../shared/utils/dom'; - -interface Point { - x: number; - y: number; -} - -const hintPosition = (element: Element): Point => { - let { left, top, right, bottom } = dom.viewportRect(element); - - if (element.tagName !== 'AREA') { - return { x: left, y: top }; - } - - return { - x: (left + right) / 2, - y: (top + bottom) / 2, - }; -}; - -export default class Hint { - private target: HTMLElement; - - private element: HTMLElement; - - constructor(target: HTMLElement, tag: string) { - let doc = target.ownerDocument; - if (doc === null) { - throw new TypeError('ownerDocument is null'); - } - - let { x, y } = hintPosition(target); - let { scrollX, scrollY } = window; - - this.target = target; - - this.element = doc.createElement('span'); - this.element.className = 'vimvixen-hint'; - this.element.textContent = tag; - this.element.style.left = x + scrollX + 'px'; - this.element.style.top = y + scrollY + 'px'; - - this.show(); - doc.body.append(this.element); - } - - show(): void { - this.element.style.display = 'inline'; - } - - hide(): void { - this.element.style.display = 'none'; - } - - remove(): void { - this.element.remove(); - } - - getTarget(): HTMLElement { - return this.target; - } -} diff --git a/src/content/components/common/index.ts b/src/content/components/common/index.ts deleted file mode 100644 index 5b097b6..0000000 --- a/src/content/components/common/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -import InputComponent from './input'; -import FollowComponent from './follow'; -import MarkComponent from './mark'; -import KeymapperComponent from './keymapper'; -import * as settingActions from '../../actions/setting'; -import * as messages from '../../../shared/messages'; -import MessageListener from '../../MessageListener'; -import * as addonActions from '../../actions/addon'; -import * as blacklists from '../../../shared/blacklists'; -import * as keys from '../../../shared/utils/keys'; -import * as actions from '../../actions'; - -export default class Common { - private win: Window; - - private store: any; - - constructor(win: Window, store: any) { - const input = new InputComponent(win.document.body); - const follow = new FollowComponent(win); - const mark = new MarkComponent(store); - const keymapper = new KeymapperComponent(store); - - input.onKey((key: keys.Key) => follow.key(key)); - input.onKey((key: keys.Key) => mark.key(key)); - input.onKey((key: keys.Key) => keymapper.key(key)); - - this.win = win; - this.store = store; - - this.reloadSettings(); - - new MessageListener().onBackgroundMessage(this.onMessage.bind(this)); - } - - onMessage(message: messages.Message) { - let { enabled } = this.store.getState().addon; - switch (message.type) { - case messages.SETTINGS_CHANGED: - return this.reloadSettings(); - case messages.ADDON_TOGGLE_ENABLED: - this.store.dispatch(addonActions.setEnabled(!enabled)); - } - } - - reloadSettings() { - try { - this.store.dispatch(settingActions.load()) - .then((action: actions.SettingAction) => { - let enabled = !blacklists.includes( - action.settings.blacklist, this.win.location.href - ); - this.store.dispatch(addonActions.setEnabled(enabled)); - }); - } catch (e) { - // Sometime sendMessage fails when background script is not ready. - console.warn(e); - setTimeout(() => this.reloadSettings(), 500); - } - } -} diff --git a/src/content/components/common/input.ts b/src/content/components/common/input.ts deleted file mode 100644 index 1fe34c9..0000000 --- a/src/content/components/common/input.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as dom from '../../../shared/utils/dom'; -import * as keys from '../../../shared/utils/keys'; - -const cancelKey = (e: KeyboardEvent): boolean => { - return e.key === 'Escape' || e.key === '[' && e.ctrlKey; -}; - -export default class InputComponent { - private pressed: {[key: string]: string} = {}; - - private onKeyListeners: ((key: keys.Key) => boolean)[] = []; - - constructor(target: HTMLElement) { - this.pressed = {}; - this.onKeyListeners = []; - - target.addEventListener('keypress', this.onKeyPress.bind(this)); - target.addEventListener('keydown', this.onKeyDown.bind(this)); - target.addEventListener('keyup', this.onKeyUp.bind(this)); - } - - onKey(cb: (key: keys.Key) => boolean) { - this.onKeyListeners.push(cb); - } - - onKeyPress(e: KeyboardEvent) { - if (this.pressed[e.key] && this.pressed[e.key] !== 'keypress') { - return; - } - this.pressed[e.key] = 'keypress'; - this.capture(e); - } - - onKeyDown(e: KeyboardEvent) { - if (this.pressed[e.key] && this.pressed[e.key] !== 'keydown') { - return; - } - this.pressed[e.key] = 'keydown'; - this.capture(e); - } - - onKeyUp(e: KeyboardEvent) { - delete this.pressed[e.key]; - } - - // eslint-disable-next-line max-statements - capture(e: KeyboardEvent) { - let target = e.target; - if (!(target instanceof HTMLElement)) { - return; - } - if (this.fromInput(target)) { - if (cancelKey(e) && target.blur) { - target.blur(); - } - return; - } - if (['Shift', 'Control', 'Alt', 'OS'].includes(e.key)) { - // pressing only meta key is ignored - return; - } - - let key = keys.fromKeyboardEvent(e); - for (let listener of this.onKeyListeners) { - let stop = listener(key); - if (stop) { - e.preventDefault(); - e.stopPropagation(); - break; - } - } - } - - fromInput(e: Element) { - return e instanceof HTMLInputElement || - e instanceof HTMLTextAreaElement || - e instanceof HTMLSelectElement || - dom.isContentEditable(e); - } -} diff --git a/src/content/components/common/keymapper.ts b/src/content/components/common/keymapper.ts deleted file mode 100644 index c94bae0..0000000 --- a/src/content/components/common/keymapper.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as inputActions from '../../actions/input'; -import * as operationActions from '../../actions/operation'; -import * as operations from '../../../shared/operations'; -import * as keyUtils from '../../../shared/utils/keys'; - -const mapStartsWith = ( - mapping: keyUtils.Key[], - keys: keyUtils.Key[], -): boolean => { - if (mapping.length < keys.length) { - return false; - } - for (let i = 0; i < keys.length; ++i) { - if (!keyUtils.equals(mapping[i], keys[i])) { - return false; - } - } - return true; -}; - -export default class KeymapperComponent { - private store: any; - - constructor(store: any) { - this.store = store; - } - - // eslint-disable-next-line max-statements - key(key: keyUtils.Key): boolean { - this.store.dispatch(inputActions.keyPress(key)); - - let state = this.store.getState(); - let input = state.input; - let keymaps = new Map<keyUtils.Key[], operations.Operation>( - state.setting.keymaps.map( - (e: {key: keyUtils.Key[], op: operations.Operation}) => [e.key, e.op], - ) - ); - - let matched = Array.from(keymaps.keys()).filter( - (mapping: keyUtils.Key[]) => { - return mapStartsWith(mapping, input.keys); - }); - if (!state.addon.enabled) { - // available keymaps are only ADDON_ENABLE and ADDON_TOGGLE_ENABLED if - // the addon disabled - matched = matched.filter((keys) => { - let type = (keymaps.get(keys) as operations.Operation).type; - return type === operations.ADDON_ENABLE || - type === operations.ADDON_TOGGLE_ENABLED; - }); - } - if (matched.length === 0) { - this.store.dispatch(inputActions.clearKeys()); - return false; - } else if (matched.length > 1 || - matched.length === 1 && input.keys.length < matched[0].length) { - return true; - } - let operation = keymaps.get(matched[0]) as operations.Operation; - let act = operationActions.exec( - operation, state.setting, state.addon.enabled - ); - this.store.dispatch(act); - this.store.dispatch(inputActions.clearKeys()); - return true; - } -} diff --git a/src/content/components/common/mark.ts b/src/content/components/common/mark.ts deleted file mode 100644 index 1237385..0000000 --- a/src/content/components/common/mark.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as markActions from '../../actions/mark'; -import * as scrolls from '../..//scrolls'; -import * as consoleFrames from '../..//console-frames'; -import * as keyUtils from '../../../shared/utils/keys'; -import Mark from '../../Mark'; - -const cancelKey = (key: keyUtils.Key): boolean => { - return key.key === 'Esc' || key.key === '[' && Boolean(key.ctrlKey); -}; - -const globalKey = (key: string): boolean => { - return (/^[A-Z0-9]$/).test(key); -}; - -export default class MarkComponent { - private store: any; - - constructor(store: any) { - this.store = store; - } - - // eslint-disable-next-line max-statements - key(key: keyUtils.Key) { - let { mark: markState, setting } = this.store.getState(); - let smoothscroll = setting.properties.smoothscroll; - - if (!markState.setMode && !markState.jumpMode) { - return false; - } - - if (cancelKey(key)) { - this.store.dispatch(markActions.cancel()); - return true; - } - - if (key.ctrlKey || key.metaKey || key.altKey) { - consoleFrames.postError('Unknown mark'); - } else if (globalKey(key.key) && markState.setMode) { - this.doSetGlobal(key); - } else if (globalKey(key.key) && markState.jumpMode) { - this.doJumpGlobal(key); - } else if (markState.setMode) { - this.doSet(key); - } else if (markState.jumpMode) { - this.doJump(markState.marks, key, smoothscroll); - } - - this.store.dispatch(markActions.cancel()); - return true; - } - - doSet(key: keyUtils.Key) { - let { x, y } = scrolls.getScroll(); - this.store.dispatch(markActions.setLocal(key.key, x, y)); - } - - doJump( - marks: { [key: string]: Mark }, - key: keyUtils.Key, - smoothscroll: boolean, - ) { - if (!marks[key.key]) { - consoleFrames.postError('Mark is not set'); - return; - } - - let { x, y } = marks[key.key]; - scrolls.scrollTo(x, y, smoothscroll); - } - - doSetGlobal(key: keyUtils.Key) { - let { x, y } = scrolls.getScroll(); - this.store.dispatch(markActions.setGlobal(key.key, x, y)); - } - - doJumpGlobal(key: keyUtils.Key) { - this.store.dispatch(markActions.jumpGlobal(key.key)); - } -} diff --git a/src/content/components/frame-content.ts b/src/content/components/frame-content.ts deleted file mode 100644 index ca999ba..0000000 --- a/src/content/components/frame-content.ts +++ /dev/null @@ -1,3 +0,0 @@ -import CommonComponent from './common'; - -export default CommonComponent; diff --git a/src/content/components/top-content/find.ts b/src/content/components/top-content/find.ts deleted file mode 100644 index 74b95bc..0000000 --- a/src/content/components/top-content/find.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as findActions from '../../actions/find'; -import * as messages from '../../../shared/messages'; -import MessageListener from '../../MessageListener'; - -export default class FindComponent { - private store: any; - - constructor(store: any) { - this.store = store; - - new MessageListener().onWebMessage(this.onMessage.bind(this)); - } - - onMessage(message: messages.Message) { - switch (message.type) { - case messages.CONSOLE_ENTER_FIND: - return this.start(message.text); - case messages.FIND_NEXT: - return this.next(); - case messages.FIND_PREV: - return this.prev(); - } - } - - start(text: string) { - let state = this.store.getState().find; - - if (text.length === 0) { - return this.store.dispatch( - findActions.next(state.keyword as string, true)); - } - return this.store.dispatch(findActions.next(text, true)); - } - - next() { - let state = this.store.getState().find; - return this.store.dispatch( - findActions.next(state.keyword as string, false)); - } - - prev() { - let state = this.store.getState().find; - return this.store.dispatch( - findActions.prev(state.keyword as string, false)); - } -} diff --git a/src/content/components/top-content/follow-controller.ts b/src/content/components/top-content/follow-controller.ts deleted file mode 100644 index d49b22a..0000000 --- a/src/content/components/top-content/follow-controller.ts +++ /dev/null @@ -1,166 +0,0 @@ -import * as followControllerActions from '../../actions/follow-controller'; -import * as messages from '../../../shared/messages'; -import MessageListener, { WebMessageSender } from '../../MessageListener'; -import HintKeyProducer from '../../hint-key-producer'; - -const broadcastMessage = (win: Window, message: messages.Message): void => { - let json = JSON.stringify(message); - let frames = [win.self].concat(Array.from(win.frames as any)); - frames.forEach(frame => frame.postMessage(json, '*')); -}; - -export default class FollowController { - private win: Window; - - private store: any; - - private state: { - enabled?: boolean; - newTab?: boolean; - background?: boolean; - keys?: string, - }; - - private keys: string[]; - - private producer: HintKeyProducer | null; - - constructor(win: Window, store: any) { - this.win = win; - this.store = store; - this.state = {}; - this.keys = []; - this.producer = null; - - new MessageListener().onWebMessage(this.onMessage.bind(this)); - - store.subscribe(() => { - this.update(); - }); - } - - onMessage(message: messages.Message, sender: WebMessageSender) { - switch (message.type) { - case messages.FOLLOW_START: - return this.store.dispatch( - followControllerActions.enable(message.newTab, message.background)); - case messages.FOLLOW_RESPONSE_COUNT_TARGETS: - return this.create(message.count, sender); - case messages.FOLLOW_KEY_PRESS: - return this.keyPress(message.key, message.ctrlKey); - } - } - - update(): void { - let prevState = this.state; - this.state = this.store.getState().followController; - - if (!prevState.enabled && this.state.enabled) { - this.count(); - } else if (prevState.enabled && !this.state.enabled) { - this.remove(); - } else if (prevState.keys !== this.state.keys) { - this.updateHints(); - } - } - - updateHints(): void { - let shown = this.keys.filter((key) => { - return key.startsWith(this.state.keys as string); - }); - if (shown.length === 1) { - this.activate(); - this.store.dispatch(followControllerActions.disable()); - } - - broadcastMessage(this.win, { - type: messages.FOLLOW_SHOW_HINTS, - keys: this.state.keys as string, - }); - } - - activate(): void { - broadcastMessage(this.win, { - type: messages.FOLLOW_ACTIVATE, - keys: this.state.keys as string, - }); - } - - keyPress(key: string, ctrlKey: boolean): boolean { - if (key === '[' && ctrlKey) { - this.store.dispatch(followControllerActions.disable()); - return true; - } - switch (key) { - case 'Enter': - this.activate(); - this.store.dispatch(followControllerActions.disable()); - break; - case 'Esc': - this.store.dispatch(followControllerActions.disable()); - break; - case 'Backspace': - case 'Delete': - this.store.dispatch(followControllerActions.backspace()); - break; - default: - if (this.hintchars().includes(key)) { - this.store.dispatch(followControllerActions.keyPress(key)); - } - break; - } - return true; - } - - count() { - this.producer = new HintKeyProducer(this.hintchars()); - let doc = this.win.document; - let viewWidth = this.win.innerWidth || doc.documentElement.clientWidth; - let viewHeight = this.win.innerHeight || doc.documentElement.clientHeight; - let frameElements = this.win.document.querySelectorAll('frame,iframe'); - - this.win.postMessage(JSON.stringify({ - type: messages.FOLLOW_REQUEST_COUNT_TARGETS, - viewSize: { width: viewWidth, height: viewHeight }, - framePosition: { x: 0, y: 0 }, - }), '*'); - frameElements.forEach((ele) => { - let { left: frameX, top: frameY } = ele.getBoundingClientRect(); - let message = JSON.stringify({ - type: messages.FOLLOW_REQUEST_COUNT_TARGETS, - viewSize: { width: viewWidth, height: viewHeight }, - framePosition: { x: frameX, y: frameY }, - }); - if (ele instanceof HTMLFrameElement && ele.contentWindow || - ele instanceof HTMLIFrameElement && ele.contentWindow) { - ele.contentWindow.postMessage(message, '*'); - } - }); - } - - create(count: number, sender: WebMessageSender) { - let produced = []; - for (let i = 0; i < count; ++i) { - produced.push((this.producer as HintKeyProducer).produce()); - } - this.keys = this.keys.concat(produced); - - (sender as Window).postMessage(JSON.stringify({ - type: messages.FOLLOW_CREATE_HINTS, - keysArray: produced, - newTab: this.state.newTab, - background: this.state.background, - }), '*'); - } - - remove() { - this.keys = []; - broadcastMessage(this.win, { - type: messages.FOLLOW_REMOVE_HINTS, - }); - } - - hintchars() { - return this.store.getState().setting.properties.hintchars; - } -} diff --git a/src/content/components/top-content/index.ts b/src/content/components/top-content/index.ts deleted file mode 100644 index ac95ea9..0000000 --- a/src/content/components/top-content/index.ts +++ /dev/null @@ -1,51 +0,0 @@ -import CommonComponent from '../common'; -import FollowController from './follow-controller'; -import FindComponent from './find'; -import * as consoleFrames from '../../console-frames'; -import * as messages from '../../../shared/messages'; -import MessageListener from '../../MessageListener'; -import * as scrolls from '../../scrolls'; - -export default class TopContent { - private win: Window; - - private store: any; - - constructor(win: Window, store: any) { - this.win = win; - this.store = store; - - new CommonComponent(win, store); // eslint-disable-line no-new - new FollowController(win, store); // eslint-disable-line no-new - new FindComponent(store); // eslint-disable-line no-new - - // TODO make component - consoleFrames.initialize(this.win.document); - - new MessageListener().onWebMessage(this.onWebMessage.bind(this)); - new MessageListener().onBackgroundMessage( - this.onBackgroundMessage.bind(this)); - } - - onWebMessage(message: messages.Message) { - switch (message.type) { - case messages.CONSOLE_UNFOCUS: - this.win.focus(); - consoleFrames.blur(window.document); - } - } - - onBackgroundMessage(message: messages.Message) { - let addonState = this.store.getState().addon; - - switch (message.type) { - case messages.ADDON_ENABLED_QUERY: - return Promise.resolve({ - type: messages.ADDON_ENABLED_RESPONSE, - enabled: addonState.enabled, - }); - case messages.TAB_SCROLL_TO: - return scrolls.scrollTo(message.x, message.y, false); - } - } -} |