diff options
Diffstat (limited to 'ext/fg')
-rw-r--r-- | ext/fg/js/popup.js | 144 |
1 files changed, 78 insertions, 66 deletions
diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index fafc15aa..bdc63b7f 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -19,33 +19,45 @@ class Popup { constructor(id, depth, frameIdPromise) { - this.id = id; - this.depth = depth; - this.frameIdPromise = frameIdPromise; - this.frameId = null; - this.parent = null; - this.child = null; - this.childrenSupported = true; - this.injectPromise = null; - this.isInjected = false; - this.visible = false; - this.visibleOverride = null; - this.options = null; - this.stylesheetInjectedViaApi = false; - - this.container = document.createElement('iframe'); - 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._id = id; + this._depth = depth; + this._frameIdPromise = frameIdPromise; + this._frameId = null; + this._parent = null; + this._child = null; + this._childrenSupported = true; + this._injectPromise = null; + this._isInjected = false; + this._visible = false; + this._visibleOverride = null; + this._options = null; + this._stylesheetInjectedViaApi = false; + + this._container = document.createElement('iframe'); + 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._updateVisibility(); } // Public properties + get parent() { + return this._parent; + } + + get child() { + return this._child; + } + + get depth() { + return this._depth; + } + get url() { return window.location.href; } @@ -57,7 +69,7 @@ class Popup { } async setOptions(options) { - this.options = options; + this._options = options; this.updateTheme(); } @@ -67,8 +79,8 @@ class Popup { } this._setVisible(false); - if (this.child !== null) { - this.child.hide(false); + if (this._child !== null) { + this._child.hide(false); } if (changeFocus) { this._focusParent(); @@ -80,13 +92,13 @@ class Popup { } setVisibleOverride(visible) { - this.visibleOverride = visible; + this._visibleOverride = visible; this._updateVisibility(); } async containsPoint(x, y) { - for (let popup = this; popup !== null && popup.isVisible(); popup = popup.child) { - const rect = popup.container.getBoundingClientRect(); + for (let popup = this; popup !== null && popup.isVisible(); popup = popup._child) { + const rect = popup._container.getBoundingClientRect(); if (x >= rect.left && y >= rect.top && x < rect.right && y < rect.bottom) { return true; } @@ -106,7 +118,7 @@ class Popup { } clearAutoPlayTimer() { - if (this.isInjected) { + if (this._isInjected) { this._invokeApi('clearAutoPlayTimer'); } } @@ -117,28 +129,28 @@ class Popup { if (parent === null) { throw new Error('Cannot set popup parent to null'); } - if (this.parent !== null) { + if (this._parent !== null) { throw new Error('Popup already has a parent'); } - if (parent.child !== null) { + if (parent._child !== null) { throw new Error('Cannot parent popup to another popup which already has a child'); } - this.parent = parent; - parent.child = this; + this._parent = parent; + parent._child = this; } isVisible() { - return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible); + return this._isInjected && (this._visibleOverride !== null ? this._visibleOverride : this._visible); } updateTheme() { - this.container.dataset.yomichanTheme = this.options.general.popupOuterTheme; - this.container.dataset.yomichanSiteColor = this._getSiteColor(); + this._container.dataset.yomichanTheme = this._options.general.popupOuterTheme; + this._container.dataset.yomichanSiteColor = this._getSiteColor(); } async setCustomOuterCss(css, injectDirectly) { // Cannot repeatedly inject stylesheets using web extension APIs since there is no way to remove them. - if (this.stylesheetInjectedViaApi) { return; } + if (this._stylesheetInjectedViaApi) { return; } if (injectDirectly || Popup._isOnExtensionPage()) { Popup.injectOuterStylesheet(css); @@ -146,7 +158,7 @@ class Popup { if (!css) { return; } try { await apiInjectStylesheet(css); - this.stylesheetInjectedViaApi = true; + this._stylesheetInjectedViaApi = true; } catch (e) { // NOP } @@ -154,15 +166,15 @@ class Popup { } setChildrenSupported(value) { - this.childrenSupported = value; + this._childrenSupported = value; } getContainer() { - return this.container; + return this._container; } getContainerRect() { - return this.container.getBoundingClientRect(); + return this._container.getBoundingClientRect(); } static injectOuterStylesheet(css) { @@ -188,53 +200,53 @@ class Popup { // Private functions _inject() { - if (this.injectPromise === null) { - this.injectPromise = this._createInjectPromise(); + if (this._injectPromise === null) { + this._injectPromise = this._createInjectPromise(); } - return this.injectPromise; + return this._injectPromise; } async _createInjectPromise() { try { - const {frameId} = await this.frameIdPromise; + const {frameId} = await this._frameIdPromise; if (typeof frameId === 'number') { - this.frameId = frameId; + this._frameId = frameId; } } catch (e) { // NOP } return new Promise((resolve) => { - const parentFrameId = (typeof this.frameId === 'number' ? this.frameId : null); - this.container.addEventListener('load', () => { + const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null); + this._container.addEventListener('load', () => { this._invokeApi('initialize', { - options: this.options, + options: this._options, popupInfo: { - id: this.id, - depth: this.depth, + id: this._id, + depth: this._depth, parentFrameId }, url: this.url, - childrenSupported: this.childrenSupported + childrenSupported: this._childrenSupported }); resolve(); }); this._observeFullscreen(); this._onFullscreenChanged(); - this.setCustomOuterCss(this.options.general.customPopupOuterCss, false); - this.isInjected = true; + this.setCustomOuterCss(this._options.general.customPopupOuterCss, false); + this._isInjected = true; }); } _isInitialized() { - return this.options !== null; + return this._options !== null; } async _show(elementRect, writingMode) { await this._inject(); - const optionsGeneral = this.options.general; - const container = this.container; + const optionsGeneral = this._options.general; + const container = this._container; const containerRect = container.getBoundingClientRect(); const getPosition = ( writingMode === 'horizontal-tb' || optionsGeneral.popupVerticalTextPosition === 'default' ? @@ -260,31 +272,31 @@ class Popup { container.style.height = `${height}px`; this._setVisible(true); - if (this.child !== null) { - this.child.hide(true); + if (this._child !== null) { + this._child.hide(true); } } _setVisible(visible) { - this.visible = visible; + this._visible = visible; this._updateVisibility(); } _updateVisibility() { - this.container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); + this._container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important'); } _focusParent() { - if (this.parent !== null) { + if (this._parent !== null) { // Chrome doesn't like focusing iframe without contentWindow. - const contentWindow = this.parent.container.contentWindow; + const contentWindow = this._parent.container.contentWindow; if (contentWindow !== null) { contentWindow.focus(); } } else { // Firefox doesn't like focusing window without first blurring the iframe. // this.container.contentWindow.blur() doesn't work on Firefox for some reason. - this.container.blur(); + this._container.blur(); // This is needed for Chrome. window.focus(); } @@ -299,7 +311,7 @@ class Popup { } _invokeApi(action, params={}) { - this.container.contentWindow.postMessage({action, params}, '*'); + this._container.contentWindow.postMessage({action, params}, '*'); } _observeFullscreen() { @@ -325,8 +337,8 @@ class Popup { _onFullscreenChanged() { const parent = (this._getFullscreenElement() || document.body || null); - if (parent !== null && this.container.parentNode !== parent) { - parent.appendChild(this.container); + if (parent !== null && this._container.parentNode !== parent) { + parent.appendChild(this._container); } } |