From a88324acd9fe626b59637541975abe1ee6041aa7 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 18 May 2019 13:06:37 +0900 Subject: Define client and presenter for follow --- .../components/top-content/follow-controller.ts | 95 ++++++++++++---------- 1 file changed, 52 insertions(+), 43 deletions(-) (limited to 'src/content/components/top-content') diff --git a/src/content/components/top-content/follow-controller.ts b/src/content/components/top-content/follow-controller.ts index 2a242c2..43c917e 100644 --- a/src/content/components/top-content/follow-controller.ts +++ b/src/content/components/top-content/follow-controller.ts @@ -1,18 +1,14 @@ import * as followControllerActions from '../../actions/follow-controller'; import * as messages from '../../../shared/messages'; -import MessageListener, { WebMessageSender } from '../../MessageListener'; +import MessageListener from '../../MessageListener'; import HintKeyProducer from '../../hint-key-producer'; import { SettingRepositoryImpl } from '../../repositories/SettingRepository'; +import FollowSlaveClient, { FollowSlaveClientImpl } + from '../../client/FollowSlaveClient'; let settingRepository = new SettingRepositoryImpl(); -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; @@ -43,7 +39,7 @@ export default class FollowController { }); } - onMessage(message: messages.Message, sender: WebMessageSender) { + onMessage(message: messages.Message, sender: Window) { switch (message.type) { case messages.FOLLOW_START: return this.store.dispatch( @@ -77,18 +73,17 @@ export default class FollowController { this.store.dispatch(followControllerActions.disable()); } - broadcastMessage(this.win, { - type: messages.FOLLOW_SHOW_HINTS, - keys: this.state.keys as string, + this.broadcastMessage((c: FollowSlaveClient) => { + c.filterHints(this.state.keys!!); }); } activate(): void { - broadcastMessage(this.win, { - type: messages.FOLLOW_ACTIVATE, - keys: this.state.keys as string, - newTab: this.state.newTab!!, - background: this.state.background!!, + this.broadcastMessage((c: FollowSlaveClient) => { + c.activateIfExists( + this.state.keys!!, + this.state.newTab!!, + this.state.background!!); }); } @@ -123,50 +118,64 @@ export default class FollowController { 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 frameElements = this.win.document.querySelectorAll('iframe'); + + new FollowSlaveClientImpl(this.win).requestHintCount( + { width: viewWidth, height: viewHeight }, + { x: 0, y: 0 }); + + for (let ele of Array.from(frameElements)) { 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, '*'); - } - }); + new FollowSlaveClientImpl(ele.contentWindow!!).requestHintCount( + { width: viewWidth, height: viewHeight }, + { x: frameX, y: frameY }, + ); + } } - create(count: number, sender: WebMessageSender) { + create(count: number, sender: Window) { 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, - }), '*'); + let doc = this.win.document; + let viewWidth = this.win.innerWidth || doc.documentElement.clientWidth; + let viewHeight = this.win.innerHeight || doc.documentElement.clientHeight; + let pos = { x: 0, y: 0 }; + if (sender !== window) { + let frameElements = this.win.document.querySelectorAll('iframe'); + let ele = Array.from(frameElements).find(e => e.contentWindow === sender); + if (!ele) { + // elements of the sender is gone + return; + } + let { left: frameX, top: frameY } = ele.getBoundingClientRect(); + pos = { x: frameX, y: frameY }; + } + new FollowSlaveClientImpl(sender).createHints( + { width: viewWidth, height: viewHeight }, + pos, + produced, + ); } remove() { this.keys = []; - broadcastMessage(this.win, { - type: messages.FOLLOW_REMOVE_HINTS, + this.broadcastMessage((c: FollowSlaveClient) => { + c.clearHints(); }); } private hintchars() { return settingRepository.get().properties.hintchars; } + + private broadcastMessage(f: (clinet: FollowSlaveClient) => void) { + let windows = [window.self].concat(Array.from(window.frames as any)); + windows + .map(w => new FollowSlaveClientImpl(w)) + .forEach(c => f(c)); + } } -- cgit v1.2.3