From b60a085a2c1e000772e3a62f187196db21137db5 Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Tue, 21 May 2019 21:12:11 +0900
Subject: FollowSlaveClient as a factory pattern

---
 src/content/client/FollowSlaveClientFactory.ts | 13 +++++++++++
 src/content/di.ts                              | 32 ++++++++++++++------------
 src/content/usecases/FollowMasterUseCase.ts    | 17 +++++++++-----
 3 files changed, 41 insertions(+), 21 deletions(-)
 create mode 100644 src/content/client/FollowSlaveClientFactory.ts

(limited to 'src')

diff --git a/src/content/client/FollowSlaveClientFactory.ts b/src/content/client/FollowSlaveClientFactory.ts
new file mode 100644
index 0000000..cd331d4
--- /dev/null
+++ b/src/content/client/FollowSlaveClientFactory.ts
@@ -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);
+  }
+}
diff --git a/src/content/di.ts b/src/content/di.ts
index a890666..23be027 100644
--- a/src/content/di.ts
+++ b/src/content/di.ts
@@ -1,52 +1,54 @@
 /* eslint-disable max-len */
 
-import { FollowMasterClientImpl } from './client/FollowMasterClient';
-import { AddonIndicatorClientImpl } from './client/AddonIndicatorClient';
 import { AddonEnabledRepositoryImpl } from './repositories/AddonEnabledRepository';
+import { AddonIndicatorClientImpl } from './client/AddonIndicatorClient';
 import { ClipboardRepositoryImpl } from './repositories/ClipboardRepository';
-import { SettingRepositoryImpl } from './repositories/SettingRepository';
-import { TabsClientImpl } from './client/TabsClient';
 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 { FindClientImpl } from './client/FindClient';
 import { FocusPresenterImpl } from './presenters/FocusPresenter';
 import { FollowKeyRepositoryImpl } from './repositories/FollowKeyRepository';
+import { FollowMasterClientImpl } from './client/FollowMasterClient';
 import { FollowMasterRepositoryImpl } from './repositories/FollowMasterRepository';
-import { FollowSlaveRepositoryImpl } from './repositories/FollowSlaveRepository';
 import { FollowPresenterImpl } from './presenters/FollowPresenter';
+import { FollowSlaveClientFactoryImpl } from './client/FollowSlaveClientFactory';
+import { FollowSlaveRepositoryImpl } from './repositories/FollowSlaveRepository';
 import { KeymapRepositoryImpl } from './repositories/KeymapRepository';
-import { MarkKeyRepositoryImpl } from './repositories/MarkKeyRepository';
-import { ScrollPresenterImpl } from './presenters/ScrollPresenter';
 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('AddonIndicatorClient', { useClass: AddonIndicatorClientImpl });
 container.register('AddonEnabledRepository', { useClass: AddonEnabledRepositoryImpl });
+container.register('AddonIndicatorClient', { useClass: AddonIndicatorClientImpl });
 container.register('ClipboardRepository', { useClass: ClipboardRepositoryImpl });
-container.register('SettingRepository', { useClass: SettingRepositoryImpl });
-container.register('TabsClient', { useClass: TabsClientImpl });
 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('FindClient', { useClass: FindClientImpl });
 container.register('FocusPresenter', { useClass: FocusPresenterImpl });
 container.register('FollowKeyRepository', { useClass: FollowKeyRepositoryImpl });
 container.register('FollowMasterRepository', { useClass: FollowMasterRepositoryImpl });
-container.register('FollowSlaveRepository', { useClass: FollowSlaveRepositoryImpl });
 container.register('FollowPresenter', { useClass: FollowPresenterImpl });
+container.register('FollowSlaveClientFactory', { useClass: FollowSlaveClientFactoryImpl });
+container.register('FollowSlaveRepository', { useClass: FollowSlaveRepositoryImpl });
 container.register('KeymapRepository', { useClass: KeymapRepositoryImpl });
-container.register('MarkKeyRepository', { useClass: MarkKeyRepositoryImpl });
-container.register('ScrollPresenter', { useClass: ScrollPresenterImpl });
 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 });
diff --git a/src/content/usecases/FollowMasterUseCase.ts b/src/content/usecases/FollowMasterUseCase.ts
index 38c41b7..7d7e875 100644
--- a/src/content/usecases/FollowMasterUseCase.ts
+++ b/src/content/usecases/FollowMasterUseCase.ts
@@ -1,8 +1,8 @@
 import { injectable, inject } from 'tsyringe';
 import FollowKeyRepository from '../repositories/FollowKeyRepository';
 import FollowMasterRepository from '../repositories/FollowMasterRepository';
-import FollowSlaveClient, { FollowSlaveClientImpl }
-  from '../client/FollowSlaveClient';
+import FollowSlaveClient from '../client/FollowSlaveClient';
+import FollowSlaveClientFactory from '../client/FollowSlaveClientFactory';
 import SettingRepository from '../repositories/SettingRepository';
 import HintKeyProducer from './HintKeyProducer';
 
@@ -20,6 +20,9 @@ export default class FollowMasterUseCase {
 
     @inject('SettingRepository')
     private settingRepository: SettingRepository,
+
+    @inject('FollowSlaveClientFactory')
+    private followSlaveClientFactory: FollowSlaveClientFactory,
   ) {
     this.producer = null;
   }
@@ -33,7 +36,7 @@ export default class FollowMasterUseCase {
 
     let viewWidth = window.top.innerWidth;
     let viewHeight = window.top.innerHeight;
-    new FollowSlaveClientImpl(window.top).requestHintCount(
+    this.followSlaveClientFactory.create(window.top).requestHintCount(
       { width: viewWidth, height: viewHeight },
       { x: 0, y: 0 },
     );
@@ -42,7 +45,8 @@ export default class FollowMasterUseCase {
     for (let i = 0; i < frameElements.length; ++i) {
       let ele = frameElements[i] as HTMLFrameElement | HTMLIFrameElement;
       let { left: frameX, top: frameY } = ele.getBoundingClientRect();
-      new FollowSlaveClientImpl(ele.contentWindow!!).requestHintCount(
+      let client = this.followSlaveClientFactory.create(ele.contentWindow!!);
+      client.requestHintCount(
         { width: viewWidth, height: viewHeight },
         { x: frameX, y: frameY },
       );
@@ -72,7 +76,8 @@ export default class FollowMasterUseCase {
       let { left: frameX, top: frameY } = ele.getBoundingClientRect();
       pos = { x: frameX, y: frameY };
     }
-    new FollowSlaveClientImpl(sender).createHints(
+    let client = this.followSlaveClientFactory.create(sender);
+    client.createHints(
       { width: viewWidth, height: viewHeight },
       pos,
       produced,
@@ -133,7 +138,7 @@ export default class FollowMasterUseCase {
 
   private broadcastToSlaves(handler: (client: FollowSlaveClient) => void) {
     let allFrames = [window.self].concat(Array.from(window.frames as any));
-    let clients = allFrames.map(frame => new FollowSlaveClientImpl(frame));
+    let clients = allFrames.map(w => this.followSlaveClientFactory.create(w));
     for (let client of clients) {
       handler(client);
     }
-- 
cgit v1.2.3