commit
c1f64927b6
78 changed files with 785 additions and 1821 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@ |
||||
import { injectable } from 'tsyringe'; |
||||
import ContentMessageListener from './infrastructures/ContentMessageListener'; |
||||
import SettingController from './controllers/SettingController'; |
||||
import VersionController from './controllers/VersionController'; |
||||
|
||||
@injectable() |
||||
export default class Application { |
||||
constructor( |
||||
private contentMessageListener: ContentMessageListener, |
||||
private settingController: SettingController, |
||||
private versionController: VersionController, |
||||
) { |
||||
} |
||||
|
||||
run() { |
||||
this.settingController.reload(); |
||||
|
||||
browser.runtime.onInstalled.addListener((details) => { |
||||
if (details.reason !== 'install' && details.reason !== 'update') { |
||||
return; |
||||
} |
||||
this.versionController.notify(); |
||||
}); |
||||
|
||||
this.contentMessageListener.run(); |
||||
browser.storage.onChanged.addListener((changes, area) => { |
||||
if (area !== 'local') { |
||||
return; |
||||
} |
||||
if (changes.settings) { |
||||
this.settingController.reload(); |
||||
} |
||||
}); |
||||
} |
||||
} |
@ -1,23 +1,6 @@ |
||||
import ContentMessageListener from './infrastructures/ContentMessageListener'; |
||||
import SettingController from './controllers/SettingController'; |
||||
import VersionController from './controllers/VersionController'; |
||||
import 'reflect-metadata'; |
||||
import { container } from 'tsyringe'; |
||||
import Application from './Application'; |
||||
|
||||
let settingController = new SettingController(); |
||||
settingController.reload(); |
||||
|
||||
browser.runtime.onInstalled.addListener((details) => { |
||||
if (details.reason !== 'install' && details.reason !== 'update') { |
||||
return; |
||||
} |
||||
new VersionController().notify(); |
||||
}); |
||||
|
||||
new ContentMessageListener().run(); |
||||
browser.storage.onChanged.addListener((changes, area) => { |
||||
if (area !== 'local') { |
||||
return; |
||||
} |
||||
if (changes.settings) { |
||||
settingController.reload(); |
||||
} |
||||
}); |
||||
let app = container.resolve(Application); |
||||
app.run(); |
||||
|
@ -0,0 +1,111 @@ |
||||
import { injectable } from 'tsyringe'; |
||||
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'; |
||||
|
||||
type Message = messages.Message; |
||||
|
||||
@injectable() |
||||
export default class Application { |
||||
|
||||
// eslint-disable-next-line max-params
|
||||
constructor( |
||||
private messageListener: MessageListener, |
||||
private findController: FindController, |
||||
private markController: MarkController, |
||||
private followMasterController: FollowMasterController, |
||||
private followSlaveController: FollowSlaveController, |
||||
private followKeyController: FollowKeyController, |
||||
private keymapController: KeymapController, |
||||
private addonEnabledUseCase: AddonEnabledUseCase, |
||||
private markKeyController: MarkKeyController, |
||||
private addonEnabledController: AddonEnabledController, |
||||
private settingController: SettingController, |
||||
private consoleFrameController: ConsoleFrameController, |
||||
) { |
||||
} |
||||
|
||||
run() { |
||||
this.routeCommonComponents(); |
||||
if (window.self === window.top) { |
||||
this.routeMasterComponents(); |
||||
} |
||||
} |
||||
|
||||
private routeMasterComponents() { |
||||
this.messageListener.onWebMessage((msg: Message, sender: Window) => { |
||||
switch (msg.type) { |
||||
case messages.CONSOLE_ENTER_FIND: |
||||
return this.findController.start(msg); |
||||
case messages.FIND_NEXT: |
||||
return this.findController.next(msg); |
||||
case messages.FIND_PREV: |
||||
return this.findController.prev(msg); |
||||
case messages.CONSOLE_UNFOCUS: |
||||
return this.consoleFrameController.unfocus(msg); |
||||
case messages.FOLLOW_START: |
||||
return this.followMasterController.followStart(msg); |
||||
case messages.FOLLOW_RESPONSE_COUNT_TARGETS: |
||||
return this.followMasterController.responseCountTargets(msg, sender); |
||||
case messages.FOLLOW_KEY_PRESS: |
||||
return this.followMasterController.keyPress(msg); |
||||
} |
||||
return undefined; |
||||
}); |
||||
|
||||
this.messageListener.onBackgroundMessage((msg: Message) => { |
||||
switch (msg.type) { |
||||
case messages.ADDON_ENABLED_QUERY: |
||||
return this.addonEnabledController.getAddonEnabled(msg); |
||||
case messages.TAB_SCROLL_TO: |
||||
return this.markController.scrollTo(msg); |
||||
} |
||||
return undefined; |
||||
}); |
||||
} |
||||
|
||||
private routeCommonComponents() { |
||||
this.messageListener.onWebMessage((msg: Message) => { |
||||
switch (msg.type) { |
||||
case messages.FOLLOW_REQUEST_COUNT_TARGETS: |
||||
return this.followSlaveController.countTargets(msg); |
||||
case messages.FOLLOW_CREATE_HINTS: |
||||
return this.followSlaveController.createHints(msg); |
||||
case messages.FOLLOW_SHOW_HINTS: |
||||
return this.followSlaveController.showHints(msg); |
||||
case messages.FOLLOW_ACTIVATE: |
||||
return this.followSlaveController.activate(msg); |
||||
case messages.FOLLOW_REMOVE_HINTS: |
||||
return this.followSlaveController.clear(msg); |
||||
} |
||||
return undefined; |
||||
}); |
||||
|
||||
this.messageListener.onBackgroundMessage((msg: Message): any => { |
||||
switch (msg.type) { |
||||
case messages.SETTINGS_CHANGED: |
||||
return this.settingController.reloadSettings(msg); |
||||
case messages.ADDON_TOGGLE_ENABLED: |
||||
return this.addonEnabledUseCase.toggle(); |
||||
} |
||||
}); |
||||
|
||||
let inputDriver = new InputDriver(window.document.body); |
||||
inputDriver.onKey(key => this.followKeyController.press(key)); |
||||
inputDriver.onKey(key => this.markKeyController.press(key)); |
||||
inputDriver.onKey(key => this.keymapController.press(key)); |
||||
|
||||
this.settingController.initSettings(); |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
import FollowSlaveClient, { FollowSlaveClientImpl } from './FollowSlaveClient'; |
||||
|
||||
export default interface FollowSlaveClientFactory { |
||||
create(window: Window): FollowSlaveClient; |
||||
|
||||
// eslint-disable-next-line semi
|
||||
} |
||||
|
||||
export class FollowSlaveClientFactoryImpl implements FollowSlaveClientFactory { |
||||
create(window: Window): FollowSlaveClient { |
||||
return new FollowSlaveClientImpl(window); |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
/* eslint-disable max-len */ |
||||
|
||||
import { AddonEnabledRepositoryImpl } from './repositories/AddonEnabledRepository'; |
||||
import { AddonIndicatorClientImpl } from './client/AddonIndicatorClient'; |
||||
import { ClipboardRepositoryImpl } from './repositories/ClipboardRepository'; |
||||
import { ConsoleClientImpl } from './client/ConsoleClient'; |
||||
import { ConsoleFramePresenterImpl } from './presenters/ConsoleFramePresenter'; |
||||
import { FindClientImpl } from './client/FindClient'; |
||||
import { FindMasterClientImpl } from './client/FindMasterClient'; |
||||
import { FindPresenterImpl } from './presenters/FindPresenter'; |
||||
import { FindRepositoryImpl } from './repositories/FindRepository'; |
||||
import { FocusPresenterImpl } from './presenters/FocusPresenter'; |
||||
import { FollowKeyRepositoryImpl } from './repositories/FollowKeyRepository'; |
||||
import { FollowMasterClientImpl } from './client/FollowMasterClient'; |
||||
import { FollowMasterRepositoryImpl } from './repositories/FollowMasterRepository'; |
||||
import { FollowPresenterImpl } from './presenters/FollowPresenter'; |
||||
import { FollowSlaveClientFactoryImpl } from './client/FollowSlaveClientFactory'; |
||||
import { FollowSlaveRepositoryImpl } from './repositories/FollowSlaveRepository'; |
||||
import { KeymapRepositoryImpl } from './repositories/KeymapRepository'; |
||||
import { MarkClientImpl } from './client/MarkClient'; |
||||
import { MarkKeyRepositoryImpl } from './repositories/MarkKeyRepository'; |
||||
import { MarkRepositoryImpl } from './repositories/MarkRepository'; |
||||
import { NavigationPresenterImpl } from './presenters/NavigationPresenter'; |
||||
import { ScrollPresenterImpl } from './presenters/ScrollPresenter'; |
||||
import { SettingClientImpl } from './client/SettingClient'; |
||||
import { SettingRepositoryImpl } from './repositories/SettingRepository'; |
||||
import { TabsClientImpl } from './client/TabsClient'; |
||||
import { container } from 'tsyringe'; |
||||
|
||||
container.register('FollowMasterClient', { useValue: new FollowMasterClientImpl(window.top) }); |
||||
container.register('AddonEnabledRepository', { useClass: AddonEnabledRepositoryImpl }); |
||||
container.register('AddonIndicatorClient', { useClass: AddonIndicatorClientImpl }); |
||||
container.register('ClipboardRepository', { useClass: ClipboardRepositoryImpl }); |
||||
container.register('ConsoleClient', { useClass: ConsoleClientImpl }); |
||||
container.register('ConsoleFramePresenter', { useClass: ConsoleFramePresenterImpl }); |
||||
container.register('FindClient', { useClass: FindClientImpl }); |
||||
container.register('FindMasterClient', { useClass: FindMasterClientImpl }); |
||||
container.register('FindPresenter', { useClass: FindPresenterImpl }); |
||||
container.register('FindRepository', { useClass: FindRepositoryImpl }); |
||||
container.register('FocusPresenter', { useClass: FocusPresenterImpl }); |
||||
container.register('FollowKeyRepository', { useClass: FollowKeyRepositoryImpl }); |
||||
container.register('FollowMasterRepository', { useClass: FollowMasterRepositoryImpl }); |
||||
container.register('FollowPresenter', { useClass: FollowPresenterImpl }); |
||||
container.register('FollowSlaveClientFactory', { useClass: FollowSlaveClientFactoryImpl }); |
||||
container.register('FollowSlaveRepository', { useClass: FollowSlaveRepositoryImpl }); |
||||
container.register('KeymapRepository', { useClass: KeymapRepositoryImpl }); |
||||
container.register('MarkClient', { useClass: MarkClientImpl }); |
||||
container.register('MarkKeyRepository', { useClass: MarkKeyRepositoryImpl }); |
||||
container.register('MarkRepository', { useClass: MarkRepositoryImpl }); |
||||
container.register('NavigationPresenter', { useClass: NavigationPresenterImpl }); |
||||
container.register('ScrollPresenter', { useClass: ScrollPresenterImpl }); |
||||
container.register('SettingClient', { useClass: SettingClientImpl }); |
||||
container.register('SettingRepository', { useClass: SettingRepositoryImpl }); |
||||
container.register('TabsClient', { useClass: TabsClientImpl }); |
@ -1,97 +0,0 @@ |
||||
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; |
||||
}); |
||||
}; |
@ -1,6 +1,8 @@ |
||||
import chai from 'chai'; |
||||
import 'reflect-metadata'; |
||||
import { expect } from 'chai'; |
||||
|
||||
const browserFake = require('webextensions-api-fake'); |
||||
const browser = browserFake(); |
||||
|
||||
global.expect = chai.expect; |
||||
global.expect = expect; |
||||
global.browser = browser; |
||||
|
Reference in new issue