summaryrefslogtreecommitdiff
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.js88
1 files changed, 68 insertions, 20 deletions
diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js
index b7d4b57e..5ee62c9b 100644
--- a/ext/fg/js/popup.js
+++ b/ext/fg/js/popup.js
@@ -17,7 +17,7 @@
/* global
* DOM
- * apiOptionsGet
+ * api
* dynamicLoader
*/
@@ -47,6 +47,9 @@ class Popup {
this._frame.style.width = '0';
this._frame.style.height = '0';
+ this._container = this._frame;
+ this._shadow = null;
+
this._fullscreenEventListeners = new EventListenerCollection();
}
@@ -89,7 +92,7 @@ class Popup {
this._optionsContext = optionsContext;
this._previousOptionsContextSource = source;
- this._options = await apiOptionsGet(optionsContext);
+ this._options = await api.optionsGet(optionsContext);
this.updateTheme();
this._invokeApi('setOptionsContext', {optionsContext});
@@ -180,7 +183,12 @@ class Popup {
}
async setCustomOuterCss(css, useWebExtensionApi) {
- return await dynamicLoader.loadStyle('yomichan-popup-outer-user-stylesheet', 'code', css, useWebExtensionApi);
+ let parentNode = null;
+ if (this._shadow !== null) {
+ useWebExtensionApi = false;
+ parentNode = this._shadow;
+ }
+ return await dynamicLoader.loadStyle('yomichan-popup-outer-user-stylesheet', 'code', css, useWebExtensionApi, parentNode);
}
setChildrenSupported(value) {
@@ -195,6 +203,10 @@ class Popup {
return this._frame.getBoundingClientRect();
}
+ getContainer() {
+ return this._container;
+ }
+
// Private functions
_inject() {
@@ -326,14 +338,25 @@ class Popup {
}
async _createInjectPromise() {
- this._injectStyles();
+ if (this._options === null) {
+ throw new Error('Options not initialized');
+ }
+
+ const {useSecurePopupFrameUrl, usePopupShadowDom} = this._options.general;
+
+ await this._setUpContainer(usePopupShadowDom);
const {secret, token} = await this._initializeFrame(this._frame, this._targetOrigin, this._frameId, (frame) => {
frame.removeAttribute('src');
frame.removeAttribute('srcdoc');
this._observeFullscreen(true);
this._onFullscreenChanged();
- frame.contentDocument.location.href = chrome.runtime.getURL('/fg/float.html');
+ const url = chrome.runtime.getURL('/fg/float.html');
+ if (useSecurePopupFrameUrl) {
+ frame.contentDocument.location.href = url;
+ } else {
+ frame.setAttribute('src', url);
+ }
});
this._frameSecret = secret;
this._frameToken = token;
@@ -371,9 +394,9 @@ class Popup {
}
_resetFrame() {
- const parent = this._frame.parentNode;
+ const parent = this._container.parentNode;
if (parent !== null) {
- parent.removeChild(this._frame);
+ parent.removeChild(this._container);
}
this._frame.removeAttribute('src');
this._frame.removeAttribute('srcdoc');
@@ -384,9 +407,31 @@ class Popup {
this._injectPromiseComplete = false;
}
+ async _setUpContainer(usePopupShadowDom) {
+ if (usePopupShadowDom && typeof this._frame.attachShadow === 'function') {
+ const container = document.createElement('div');
+ container.style.setProperty('all', 'initial', 'important');
+ const shadow = container.attachShadow({mode: 'closed', delegatesFocus: true});
+ shadow.appendChild(this._frame);
+
+ this._container = container;
+ this._shadow = shadow;
+ } else {
+ const frameParentNode = this._frame.parentNode;
+ if (frameParentNode !== null) {
+ frameParentNode.removeChild(this._frame);
+ }
+
+ this._container = this._frame;
+ this._shadow = null;
+ }
+
+ await this._injectStyles();
+ }
+
async _injectStyles() {
try {
- await dynamicLoader.loadStyle('yomichan-popup-outer-stylesheet', 'file', '/fg/css/client.css', true);
+ await this._injectPopupOuterStylesheet();
} catch (e) {
// NOP
}
@@ -398,6 +443,18 @@ class Popup {
}
}
+ async _injectPopupOuterStylesheet() {
+ let fileType = 'file';
+ let useWebExtensionApi = true;
+ let parentNode = null;
+ if (this._shadow !== null) {
+ fileType = 'file-content';
+ useWebExtensionApi = false;
+ parentNode = this._shadow;
+ }
+ await dynamicLoader.loadStyle('yomichan-popup-outer-stylesheet', fileType, '/fg/css/client.css', useWebExtensionApi, parentNode);
+ }
+
_observeFullscreen(observe) {
if (!observe) {
this._fullscreenEventListeners.removeAllEventListeners();
@@ -409,22 +466,13 @@ class Popup {
return;
}
- const fullscreenEvents = [
- 'fullscreenchange',
- 'MSFullscreenChange',
- 'mozfullscreenchange',
- 'webkitfullscreenchange'
- ];
- const onFullscreenChanged = this._onFullscreenChanged.bind(this);
- for (const eventName of fullscreenEvents) {
- this._fullscreenEventListeners.addEventListener(document, eventName, onFullscreenChanged, false);
- }
+ DOM.addFullscreenChangeEventListener(this._onFullscreenChanged.bind(this), this._fullscreenEventListeners);
}
_onFullscreenChanged() {
const parent = this._getFrameParentElement();
- if (parent !== null && this._frame.parentNode !== parent) {
- parent.appendChild(this._frame);
+ if (parent !== null && this._container.parentNode !== parent) {
+ parent.appendChild(this._container);
}
}