diff options
Diffstat (limited to 'ext/fg/js/float.js')
| -rw-r--r-- | ext/fg/js/float.js | 170 | 
1 files changed, 97 insertions, 73 deletions
| diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index d86f16c3..83355c5c 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -26,39 +26,35 @@  class DisplayFloat extends Display {      constructor() {          super(document.querySelector('#spinner'), document.querySelector('#definitions')); -        this.autoPlayAudioTimer = null; - +        this._autoPlayAudioTimer = null;          this._secret = yomichan.generateId(16);          this._token = null; -          this._nestedPopupsPrepared = false; +        this._windowMessageHandlers = new Map([ +            ['initialize',         {handler: this._onMessageInitialize.bind(this), authenticate: false}], +            ['configure',          {handler: this._onMessageConfigure.bind(this)}], +            ['setOptionsContext',  {handler: this._onMessageSetOptionsContext.bind(this)}], +            ['setContent',         {handler: this._onMessageSetContent.bind(this)}], +            ['clearAutoPlayTimer', {handler: this._onMessageClearAutoPlayTimer.bind(this)}], +            ['setCustomCss',       {handler: this._onMessageSetCustomCss.bind(this)}], +            ['setContentScale',    {handler: this._onMessageSetContentScale.bind(this)}] +        ]); -        this._onKeyDownHandlers = new Map([ +        this.setOnKeyDownHandlers([              ['C', (e) => {                  if (e.ctrlKey && !window.getSelection().toString()) { -                    this.onSelectionCopy(); +                    this._copySelection();                      return true;                  }                  return false; -            }], -            ...this._onKeyDownHandlers -        ]); - -        this._windowMessageHandlers = new Map([ -            ['initialize', {handler: this._initialize.bind(this), authenticate: false}], -            ['configure', {handler: this._configure.bind(this)}], -            ['setOptionsContext', {handler: ({optionsContext}) => this.setOptionsContext(optionsContext)}], -            ['setContent', {handler: ({type, details}) => this.setContent(type, details)}], -            ['clearAutoPlayTimer', {handler: () => this.clearAutoPlayTimer()}], -            ['setCustomCss', {handler: ({css}) => this.setCustomCss(css)}], -            ['setContentScale', {handler: ({scale}) => this.setContentScale(scale)}] +            }]          ]);      }      async prepare() {          await super.prepare(); -        window.addEventListener('message', this.onMessage.bind(this), false); +        window.addEventListener('message', this._onMessage.bind(this), false);          api.broadcastTab('popupPrepared', {secret: this._secret});      } @@ -67,11 +63,46 @@ class DisplayFloat extends Display {          window.parent.postMessage('popupClose', '*');      } -    onSelectionCopy() { -        window.parent.postMessage('selectionCopy', '*'); +    async setOptionsContext(optionsContext) { +        super.setOptionsContext(optionsContext); +        await this.updateOptions();      } -    onMessage(e) { +    async getDocumentTitle() { +        try { +            const uniqueId = yomichan.generateId(16); + +            const promise = yomichan.getTemporaryListenerResult( +                chrome.runtime.onMessage, +                ({action, params}, {resolve}) => { +                    if ( +                        action === 'documentInformationBroadcast' && +                        isObject(params) && +                        params.uniqueId === uniqueId && +                        params.frameId === 0 +                    ) { +                        resolve(params); +                    } +                }, +                2000 +            ); +            api.broadcastTab('requestDocumentInformationBroadcast', {uniqueId}); + +            const {title} = await promise; +            return title; +        } catch (e) { +            return ''; +        } +    } + +    autoPlayAudio() { +        this._clearAutoPlayTimer(); +        this._autoPlayAudioTimer = window.setTimeout(() => super.autoPlayAudio(), 400); +    } + +    // Message handling + +    _onMessage(e) {          const data = e.data;          if (typeof data !== 'object' || data === null) {              this._logMessageError(e, 'Invalid data'); @@ -99,56 +130,65 @@ class DisplayFloat extends Display {          handler(data.params);      } -    autoPlayAudio() { -        this.clearAutoPlayTimer(); -        this.autoPlayAudioTimer = window.setTimeout(() => super.autoPlayAudio(), 400); +    _onMessageInitialize(params) { +        this._initialize(params);      } -    clearAutoPlayTimer() { -        if (this.autoPlayAudioTimer) { -            window.clearTimeout(this.autoPlayAudioTimer); -            this.autoPlayAudioTimer = null; +    async _onMessageConfigure({messageId, frameId, popupId, optionsContext, childrenSupported, scale}) { +        this.setOptionsContext(optionsContext); + +        await this.updateOptions(); + +        if (childrenSupported && !this._nestedPopupsPrepared) { +            const {depth, url} = optionsContext; +            this._prepareNestedPopups(popupId, depth, frameId, url); +            this._nestedPopupsPrepared = true;          } + +        this._setContentScale(scale); + +        api.sendMessageToFrame(frameId, 'popupConfigured', {messageId});      } -    async setOptionsContext(optionsContext) { -        super.setOptionsContext(optionsContext); -        await this.updateOptions(); +    _onMessageSetOptionsContext({optionsContext}) { +        this.setOptionsContext(optionsContext);      } -    setContentScale(scale) { -        const body = document.body; -        if (body === null) { return; } -        body.style.fontSize = `${scale}em`; +    _onMessageSetContent({type, details}) { +        this.setContent(type, details);      } -    async getDocumentTitle() { -        try { -            const uniqueId = yomichan.generateId(16); +    _onMessageClearAutoPlayTimer() { +        this._clearAutoPlayTimer.bind(this); +    } -            const promise = yomichan.getTemporaryListenerResult( -                chrome.runtime.onMessage, -                ({action, params}, {resolve}) => { -                    if ( -                        action === 'documentInformationBroadcast' && -                        isObject(params) && -                        params.uniqueId === uniqueId && -                        params.frameId === 0 -                    ) { -                        resolve(params); -                    } -                }, -                2000 -            ); -            api.broadcastTab('requestDocumentInformationBroadcast', {uniqueId}); +    _onMessageSetCustomCss({css}) { +        this.setCustomCss(css); +    } -            const {title} = await promise; -            return title; -        } catch (e) { -            return ''; +    _onMessageSetContentScale({scale}) { +        this._setContentScale(scale); +    } + +    // Private + +    _copySelection() { +        window.parent.postMessage('selectionCopy', '*'); +    } + +    _clearAutoPlayTimer() { +        if (this._autoPlayAudioTimer) { +            window.clearTimeout(this._autoPlayAudioTimer); +            this._autoPlayAudioTimer = null;          }      } +    _setContentScale(scale) { +        const body = document.body; +        if (body === null) { return; } +        body.style.fontSize = `${scale}em`; +    } +      _logMessageError(event, type) {          yomichan.logWarning(new Error(`Popup received invalid message from origin ${JSON.stringify(event.origin)}: ${type}`));      } @@ -166,22 +206,6 @@ class DisplayFloat extends Display {          api.sendMessageToFrame(frameId, 'popupInitialized', {secret, token});      } -    async _configure({messageId, frameId, popupId, optionsContext, childrenSupported, scale}) { -        this.setOptionsContext(optionsContext); - -        await this.updateOptions(); - -        if (childrenSupported && !this._nestedPopupsPrepared) { -            const {depth, url} = optionsContext; -            this._prepareNestedPopups(popupId, depth, frameId, url); -            this._nestedPopupsPrepared = true; -        } - -        this.setContentScale(scale); - -        api.sendMessageToFrame(frameId, 'popupConfigured', {messageId}); -    } -      _isMessageAuthenticated(message) {          return (              this._token !== null && |