aboutsummaryrefslogtreecommitdiff
path: root/ext/fg/js/popup.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fg/js/popup.js')
-rw-r--r--ext/fg/js/popup.js109
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) {