diff options
Diffstat (limited to 'ext/fg/js/popup.js')
| -rw-r--r-- | ext/fg/js/popup.js | 109 | 
1 files changed, 71 insertions, 38 deletions
| diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 0b142dda..de05f9f5 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -28,8 +28,6 @@ class Popup {          this._child = null;          this._childrenSupported = true;          this._injectPromise = null; -        this._isInjected = false; -        this._isInjectedAndLoaded = false;          this._visible = false;          this._visibleOverride = null;          this._options = null; @@ -41,19 +39,28 @@ class Popup {          this._container.className = 'yomichan-float';          this._container.addEventListener('mousedown', (e) => e.stopPropagation());          this._container.addEventListener('scroll', (e) => e.stopPropagation()); -        this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html'));          this._container.style.width = '0px';          this._container.style.height = '0px'; +        this._fullscreenEventListeners = new EventListenerCollection(); +          this._updateVisibility();      }      // Public properties +    get id() { +        return this._id; +    } +      get parent() {          return this._parent;      } +    get child() { +        return this._child; +    } +      get depth() {          return this._depth;      } @@ -118,16 +125,12 @@ class Popup {      }      clearAutoPlayTimer() { -        if (this._isInjectedAndLoaded) { -            this._invokeApi('clearAutoPlayTimer'); -        } +        this._invokeApi('clearAutoPlayTimer');      }      setContentScale(scale) {          this._contentScale = scale; -        if (this._isInjectedAndLoaded) { -            this._invokeApi('setContentScale', {scale}); -        } +        this._invokeApi('setContentScale', {scale});      }      // Popup-only public functions @@ -147,7 +150,7 @@ class Popup {      }      isVisibleSync() { -        return this._isInjected && (this._visibleOverride !== null ? this._visibleOverride : this._visible); +        return (this._visibleOverride !== null ? this._visibleOverride : this._visible);      }      updateTheme() { @@ -226,8 +229,10 @@ class Popup {          return new Promise((resolve) => {              const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null);              this._container.addEventListener('load', () => { -                this._isInjectedAndLoaded = true; -                this._invokeApi('initialize', { +                const uniqueId = yomichan.generateId(32); +                Popup._listenForDisplayPrepareCompleted(uniqueId, resolve); + +                this._invokeApi('prepare', {                      options: this._options,                      popupInfo: {                          id: this._id, @@ -236,17 +241,47 @@ class Popup {                      },                      url: this.url,                      childrenSupported: this._childrenSupported, -                    scale: this._contentScale +                    scale: this._contentScale, +                    uniqueId                  }); -                resolve();              }); -            this._observeFullscreen(); +            this._observeFullscreen(true);              this._onFullscreenChanged();              this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); -            this._isInjected = true; +            this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html'));          });      } +    _observeFullscreen(observe) { +        if (!observe) { +            this._fullscreenEventListeners.removeAllEventListeners(); +            return; +        } + +        if (this._fullscreenEventListeners.size > 0) { +            // Already observing +            return; +        } + +        const fullscreenEvents = [ +            'fullscreenchange', +            'MSFullscreenChange', +            'mozfullscreenchange', +            'webkitfullscreenchange' +        ]; +        const onFullscreenChanged = () => this._onFullscreenChanged(); +        for (const eventName of fullscreenEvents) { +            this._fullscreenEventListeners.addEventListener(document, eventName, onFullscreenChanged, false); +        } +    } + +    _onFullscreenChanged() { +        const parent = (Popup._getFullscreenElement() || document.body || null); +        if (parent !== null && this._container.parentNode !== parent) { +            parent.appendChild(this._container); +        } +    } +      async _show(elementRect, writingMode) {          await this._inject(); @@ -328,38 +363,36 @@ class Popup {      }      _invokeApi(action, params={}) { -        if (!this._isInjectedAndLoaded) { -            throw new Error('Frame not loaded'); -        } -        this._container.contentWindow.postMessage({action, params}, '*'); -    } - -    _observeFullscreen() { -        const fullscreenEvents = [ -            'fullscreenchange', -            'MSFullscreenChange', -            'mozfullscreenchange', -            'webkitfullscreenchange' -        ]; -        for (const eventName of fullscreenEvents) { -            document.addEventListener(eventName, () => this._onFullscreenChanged(), false); +        if (this._container.contentWindow) { +            this._container.contentWindow.postMessage({action, params}, '*');          }      } -    _getFullscreenElement() { +    static _getFullscreenElement() {          return (              document.fullscreenElement ||              document.msFullscreenElement ||              document.mozFullScreenElement || -            document.webkitFullscreenElement +            document.webkitFullscreenElement || +            null          );      } -    _onFullscreenChanged() { -        const parent = (this._getFullscreenElement() || document.body || null); -        if (parent !== null && this._container.parentNode !== parent) { -            parent.appendChild(this._container); -        } +    static _listenForDisplayPrepareCompleted(uniqueId, resolve) { +        const runtimeMessageCallback = ({action, params}, sender, callback) => { +            if ( +                action === 'popupPrepareCompleted' && +                typeof params === 'object' && +                params !== null && +                params.uniqueId === uniqueId +            ) { +                chrome.runtime.onMessage.removeListener(runtimeMessageCallback); +                callback(); +                resolve(); +                return false; +            } +        }; +        chrome.runtime.onMessage.addListener(runtimeMessageCallback);      }      static _getPositionForHorizontalText(elementRect, width, height, viewport, offsetScale, optionsGeneral) { |