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 'reflect-metadata'; |
||||||
import SettingController from './controllers/SettingController'; |
import { container } from 'tsyringe'; |
||||||
import VersionController from './controllers/VersionController'; |
import Application from './Application'; |
||||||
|
|
||||||
let settingController = new SettingController(); |
let app = container.resolve(Application); |
||||||
settingController.reload(); |
app.run(); |
||||||
|
|
||||||
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(); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
@ -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 browserFake = require('webextensions-api-fake'); |
||||||
const browser = browserFake(); |
const browser = browserFake(); |
||||||
|
|
||||||
global.expect = chai.expect; |
global.expect = expect; |
||||||
global.browser = browser; |
global.browser = browser; |
||||||
|
Reference in new issue