diff options
-rw-r--r-- | src/content/console-frames.ts | 16 | ||||
-rw-r--r-- | src/content/controllers/ConsoleFrameController.ts | 16 | ||||
-rw-r--r-- | src/content/controllers/SettingController.ts | 41 | ||||
-rw-r--r-- | src/content/index.ts | 116 | ||||
-rw-r--r-- | src/content/presenters/ConsoleFramePresenter.ts | 25 | ||||
-rw-r--r-- | src/content/routes.ts | 97 | ||||
-rw-r--r-- | src/content/usecases/ConsoleFrameUseCase.ts | 17 |
7 files changed, 201 insertions, 127 deletions
diff --git a/src/content/console-frames.ts b/src/content/console-frames.ts deleted file mode 100644 index b1b9bf6..0000000 --- a/src/content/console-frames.ts +++ /dev/null @@ -1,16 +0,0 @@ -const initialize = (doc: Document): HTMLIFrameElement => { - 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 blur = (doc: Document) => { - let ele = doc.getElementById('vimvixen-console-frame') as HTMLIFrameElement; - ele.blur(); -}; - -export { initialize, blur }; diff --git a/src/content/controllers/ConsoleFrameController.ts b/src/content/controllers/ConsoleFrameController.ts new file mode 100644 index 0000000..fafadf4 --- /dev/null +++ b/src/content/controllers/ConsoleFrameController.ts @@ -0,0 +1,16 @@ +import ConsoleFrameUseCase from '../usecases/ConsoleFrameUseCase'; +import * as messages from '../../shared/messages'; + +export default class ConsoleFrameController { + private consoleFrameUseCase: ConsoleFrameUseCase; + + constructor({ + consoleFrameUseCase = new ConsoleFrameUseCase(), + } = {}) { + this.consoleFrameUseCase = consoleFrameUseCase; + } + + unfocus(_message: messages.Message) { + this.consoleFrameUseCase.unfocus(); + } +} diff --git a/src/content/controllers/SettingController.ts b/src/content/controllers/SettingController.ts new file mode 100644 index 0000000..f0e770b --- /dev/null +++ b/src/content/controllers/SettingController.ts @@ -0,0 +1,41 @@ +import AddonEnabledUseCase from '../usecases/AddonEnabledUseCase'; +import SettingUseCase from '../usecases/SettingUseCase'; +import * as blacklists from '../../shared/blacklists'; + +import * as messages from '../../shared/messages'; + +export default class SettingController { + private addonEnabledUseCase: AddonEnabledUseCase; + + private settingUseCase: SettingUseCase; + + constructor({ + addonEnabledUseCase = new AddonEnabledUseCase(), + settingUseCase = new SettingUseCase(), + } = {}) { + this.addonEnabledUseCase = addonEnabledUseCase; + this.settingUseCase = settingUseCase; + } + + async initSettings(): Promise<void> { + try { + let current = await this.settingUseCase.reload(); + let disabled = blacklists.includes( + current.blacklist, window.location.href, + ); + if (disabled) { + this.addonEnabledUseCase.disable(); + } else { + this.addonEnabledUseCase.enable(); + } + } catch (e) { + // Sometime sendMessage fails when background script is not ready. + console.warn(e); + setTimeout(() => this.initSettings(), 500); + } + } + + async reloadSettings(_message: messages.Message): Promise<void> { + await this.settingUseCase.reload(); + } +} diff --git a/src/content/index.ts b/src/content/index.ts index 06bb34f..660ebf5 100644 --- a/src/content/index.ts +++ b/src/content/index.ts @@ -1,122 +1,16 @@ -import * as consoleFrames from './console-frames'; +import { ConsoleFramePresenterImpl } from './presenters/ConsoleFramePresenter'; import consoleFrameStyle from './site-style'; -import MessageListener from './MessageListener'; -import FindController from './controllers/FindController'; -import MarkController from './controllers/MarkController'; -import FollowMasterController from './controllers/FollowMasterController'; -import FollowSlaveController from './controllers/FollowSlaveController'; -import FollowKeyController from './controllers/FollowKeyController'; -import * as messages from '../shared/messages'; -import InputDriver from './InputDriver'; -import KeymapController from './controllers/KeymapController'; -import AddonEnabledUseCase from './usecases/AddonEnabledUseCase'; -import SettingUseCase from './usecases/SettingUseCase'; -import * as blacklists from '../shared/blacklists'; -import MarkKeyController from './controllers/MarkKeyController'; -import AddonEnabledController from './controllers/AddonEnabledController'; +import * as routes from './routes'; -let listener = new MessageListener(); if (window.self === window.top) { - let findController = new FindController(); + routes.routeMasterComponents(); - let followMasterController = new FollowMasterController(); - listener.onWebMessage((message: messages.Message, sender: Window) => { - switch (message.type) { - case messages.CONSOLE_ENTER_FIND: - return findController.start(message); - case messages.FIND_NEXT: - return findController.next(message); - case messages.FIND_PREV: - return findController.prev(message); - case messages.CONSOLE_UNFOCUS: - window.focus(); - consoleFrames.blur(window.document); - break; - case messages.FOLLOW_START: - return followMasterController.followStart(message); - case messages.FOLLOW_RESPONSE_COUNT_TARGETS: - return followMasterController.responseCountTargets(message, sender); - case messages.FOLLOW_KEY_PRESS: - return followMasterController.keyPress(message); - } - return undefined; - }); - - let markController = new MarkController(); - let addonEnabledController = new AddonEnabledController(); - - new MessageListener().onBackgroundMessage((message: messages.Message) => { - switch (message.type) { - case messages.ADDON_ENABLED_QUERY: - return addonEnabledController.getAddonEnabled(message); - case messages.TAB_SCROLL_TO: - return markController.scrollTo(message); - } - return undefined; - }); - - consoleFrames.initialize(window.document); + new ConsoleFramePresenterImpl().initialize(); } -let followSlaveController = new FollowSlaveController(); -listener.onWebMessage((message: messages.Message) => { - switch (message.type) { - case messages.FOLLOW_REQUEST_COUNT_TARGETS: - return followSlaveController.countTargets(message); - case messages.FOLLOW_CREATE_HINTS: - return followSlaveController.createHints(message); - case messages.FOLLOW_SHOW_HINTS: - return followSlaveController.showHints(message); - case messages.FOLLOW_ACTIVATE: - return followSlaveController.activate(message); - case messages.FOLLOW_REMOVE_HINTS: - return followSlaveController.clear(message); - } - return undefined; -}); +routes.routeComponents(); -let keymapController = new KeymapController(); -let markKeyController = new MarkKeyController(); -let followKeyController = new FollowKeyController(); -let inputDriver = new InputDriver(document.body); -inputDriver.onKey(key => followKeyController.press(key)); -inputDriver.onKey(key => markKeyController.press(key)); -inputDriver.onKey(key => keymapController.press(key)); let style = window.document.createElement('style'); style.textContent = consoleFrameStyle; window.document.head.appendChild(style); - -// TODO move the following to a class -const reloadSettings = async() => { - let addonEnabledUseCase = new AddonEnabledUseCase(); - let settingUseCase = new SettingUseCase(); - - try { - let current = await settingUseCase.reload(); - let disabled = blacklists.includes( - current.blacklist, window.location.href, - ); - if (disabled) { - addonEnabledUseCase.disable(); - } else { - addonEnabledUseCase.enable(); - } - } catch (e) { - // Sometime sendMessage fails when background script is not ready. - console.warn(e); - setTimeout(() => reloadSettings(), 500); - } -}; -reloadSettings(); - -new MessageListener().onBackgroundMessage((message: messages.Message): any => { - let addonEnabledUseCase = new AddonEnabledUseCase(); - - switch (message.type) { - case messages.SETTINGS_CHANGED: - return reloadSettings(); - case messages.ADDON_TOGGLE_ENABLED: - return addonEnabledUseCase.toggle(); - } -}); diff --git a/src/content/presenters/ConsoleFramePresenter.ts b/src/content/presenters/ConsoleFramePresenter.ts new file mode 100644 index 0000000..3c7477b --- /dev/null +++ b/src/content/presenters/ConsoleFramePresenter.ts @@ -0,0 +1,25 @@ +export default interface ConsoleFramePresenter { + initialize(): void; + + blur(): void; + + // eslint-disable-next-line semi +} + +export class ConsoleFramePresenterImpl implements ConsoleFramePresenter { + initialize(): void { + let iframe = document.createElement('iframe'); + iframe.src = browser.runtime.getURL('build/console.html'); + iframe.id = 'vimvixen-console-frame'; + iframe.className = 'vimvixen-console-frame'; + document.body.append(iframe); + } + + blur(): void { + let ele = document.getElementById('vimvixen-console-frame'); + if (!ele) { + throw new Error('console frame not created'); + } + ele.blur(); + } +} diff --git a/src/content/routes.ts b/src/content/routes.ts new file mode 100644 index 0000000..0bce4f5 --- /dev/null +++ b/src/content/routes.ts @@ -0,0 +1,97 @@ +import MessageListener from './MessageListener'; +import FindController from './controllers/FindController'; +import MarkController from './controllers/MarkController'; +import FollowMasterController from './controllers/FollowMasterController'; +import FollowSlaveController from './controllers/FollowSlaveController'; +import FollowKeyController from './controllers/FollowKeyController'; +import InputDriver from './InputDriver'; +import KeymapController from './controllers/KeymapController'; +import AddonEnabledUseCase from './usecases/AddonEnabledUseCase'; +import MarkKeyController from './controllers/MarkKeyController'; +import AddonEnabledController from './controllers/AddonEnabledController'; +import SettingController from './controllers/SettingController'; +import ConsoleFrameController from './controllers/ConsoleFrameController'; +import * as messages from '../shared/messages'; + +export const routeComponents = () => { + let listener = new MessageListener(); + + let followSlaveController = new FollowSlaveController(); + listener.onWebMessage((message: messages.Message) => { + switch (message.type) { + case messages.FOLLOW_REQUEST_COUNT_TARGETS: + return followSlaveController.countTargets(message); + case messages.FOLLOW_CREATE_HINTS: + return followSlaveController.createHints(message); + case messages.FOLLOW_SHOW_HINTS: + return followSlaveController.showHints(message); + case messages.FOLLOW_ACTIVATE: + return followSlaveController.activate(message); + case messages.FOLLOW_REMOVE_HINTS: + return followSlaveController.clear(message); + } + return undefined; + }); + + let keymapController = new KeymapController(); + let markKeyController = new MarkKeyController(); + let followKeyController = new FollowKeyController(); + let inputDriver = new InputDriver(document.body); + inputDriver.onKey(key => followKeyController.press(key)); + inputDriver.onKey(key => markKeyController.press(key)); + inputDriver.onKey(key => keymapController.press(key)); + + let settingController = new SettingController(); + settingController.initSettings(); + + listener.onBackgroundMessage((message: messages.Message): any => { + let addonEnabledUseCase = new AddonEnabledUseCase(); + + switch (message.type) { + case messages.SETTINGS_CHANGED: + return settingController.reloadSettings(message); + case messages.ADDON_TOGGLE_ENABLED: + return addonEnabledUseCase.toggle(); + } + }); +}; + +export const routeMasterComponents = () => { + let listener = new MessageListener(); + + let findController = new FindController(); + let followMasterController = new FollowMasterController(); + let markController = new MarkController(); + let addonEnabledController = new AddonEnabledController(); + let consoleFrameController = new ConsoleFrameController(); + + listener.onWebMessage((message: messages.Message, sender: Window) => { + switch (message.type) { + case messages.CONSOLE_ENTER_FIND: + return findController.start(message); + case messages.FIND_NEXT: + return findController.next(message); + case messages.FIND_PREV: + return findController.prev(message); + case messages.CONSOLE_UNFOCUS: + return consoleFrameController.unfocus(message); + case messages.FOLLOW_START: + return followMasterController.followStart(message); + case messages.FOLLOW_RESPONSE_COUNT_TARGETS: + return followMasterController.responseCountTargets(message, sender); + case messages.FOLLOW_KEY_PRESS: + return followMasterController.keyPress(message); + } + return undefined; + }); + + listener.onBackgroundMessage((message: messages.Message) => { + switch (message.type) { + case messages.ADDON_ENABLED_QUERY: + return addonEnabledController.getAddonEnabled(message); + case messages.TAB_SCROLL_TO: + return markController.scrollTo(message); + } + return undefined; + }); +}; diff --git a/src/content/usecases/ConsoleFrameUseCase.ts b/src/content/usecases/ConsoleFrameUseCase.ts new file mode 100644 index 0000000..b4c756c --- /dev/null +++ b/src/content/usecases/ConsoleFrameUseCase.ts @@ -0,0 +1,17 @@ +import ConsoleFramePresenter, { ConsoleFramePresenterImpl } + from '../presenters/ConsoleFramePresenter'; + +export default class ConsoleFrameUseCase { + private consoleFramePresenter: ConsoleFramePresenter; + + constructor({ + consoleFramePresenter = new ConsoleFramePresenterImpl(), + } = {}) { + this.consoleFramePresenter = consoleFramePresenter; + } + + unfocus() { + window.focus(); + this.consoleFramePresenter.blur(); + } +} |