summaryrefslogtreecommitdiff
path: root/ext/fg
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fg')
-rw-r--r--ext/fg/float.html1
-rw-r--r--ext/fg/js/api.js4
-rw-r--r--ext/fg/js/float.js2
-rw-r--r--ext/fg/js/frontend-api-receiver.js5
-rw-r--r--ext/fg/js/frontend-api-sender.js8
-rw-r--r--ext/fg/js/frontend.js81
-rw-r--r--ext/fg/js/popup-proxy-host.js8
-rw-r--r--ext/fg/js/popup-proxy.js6
-rw-r--r--ext/fg/js/popup.js49
-rw-r--r--ext/fg/js/util.js8
10 files changed, 100 insertions, 72 deletions
diff --git a/ext/fg/float.html b/ext/fg/float.html
index 52c7faa3..fe1aee8f 100644
--- a/ext/fg/float.html
+++ b/ext/fg/float.html
@@ -39,6 +39,7 @@
<script src="/fg/js/util.js"></script>
<script src="/fg/js/document.js"></script>
<script src="/fg/js/source.js"></script>
+ <script src="/mixed/js/audio.js"></script>
<script src="/mixed/js/display.js"></script>
<script src="/mixed/js/scroll.js"></script>
diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js
index d0ac649a..a553e514 100644
--- a/ext/fg/js/api.js
+++ b/ext/fg/js/api.js
@@ -45,8 +45,8 @@ function apiTemplateRender(template, data, dynamic) {
return utilInvoke('templateRender', {data, template, dynamic});
}
-function apiAudioGetUrl(definition, source) {
- return utilInvoke('audioGetUrl', {definition, source});
+function apiAudioGetUrl(definition, source, optionsContext) {
+ return utilInvoke('audioGetUrl', {definition, source, optionsContext});
}
function apiCommandExec(command) {
diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js
index 88842eef..8fdb6925 100644
--- a/ext/fg/js/float.js
+++ b/ext/fg/js/float.js
@@ -37,7 +37,7 @@ class DisplayFloat extends Display {
if (window.yomichan_orphaned) {
this.onOrphaned();
} else {
- window.alert(`Error: ${error.toString ? error.toString() : error}`);
+ logError(error, true);
}
}
diff --git a/ext/fg/js/frontend-api-receiver.js b/ext/fg/js/frontend-api-receiver.js
index 687e5c3c..fbfb3ab0 100644
--- a/ext/fg/js/frontend-api-receiver.js
+++ b/ext/fg/js/frontend-api-receiver.js
@@ -46,9 +46,8 @@ class FrontendApiReceiver {
result => {
this.sendResult(port, id, senderId, {result});
},
- e => {
- const error = typeof e.toString === 'function' ? e.toString() : e;
- this.sendResult(port, id, senderId, {error});
+ error => {
+ this.sendResult(port, id, senderId, {error: errorToJson(error)});
});
}
diff --git a/ext/fg/js/frontend-api-sender.js b/ext/fg/js/frontend-api-sender.js
index 2e037e62..c6eeaeb2 100644
--- a/ext/fg/js/frontend-api-sender.js
+++ b/ext/fg/js/frontend-api-sender.js
@@ -31,7 +31,7 @@ class FrontendApiSender {
invoke(action, params, target) {
if (this.disconnected) {
- return Promise.reject('Disconnected');
+ return Promise.reject(new Error('Disconnected'));
}
if (this.port === null) {
@@ -110,8 +110,8 @@ class FrontendApiSender {
clearTimeout(info.timer);
info.timer = null;
- if (typeof data.error === 'string') {
- info.reject(data.error);
+ if (typeof data.error !== 'undefined') {
+ info.reject(jsonToError(data.error));
} else {
info.resolve(data.result);
}
@@ -122,7 +122,7 @@ class FrontendApiSender {
const info = this.callbacks[id];
delete this.callbacks[id];
info.timer = null;
- info.reject(reason);
+ info.reject(new Error(reason));
}
static generateId(length) {
diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js
index 58dc0e4a..88cb93a9 100644
--- a/ext/fg/js/frontend.js
+++ b/ext/fg/js/frontend.js
@@ -38,6 +38,9 @@ class Frontend {
this.mouseDownPrevent = false;
this.clickPrevent = false;
this.scrollPrevent = false;
+
+ this.enabled = false;
+ this.eventListeners = [];
}
static create() {
@@ -53,23 +56,7 @@ class Frontend {
async prepare() {
try {
- this.options = await apiOptionsGet(this.getOptionsContext());
-
- window.addEventListener('message', this.onWindowMessage.bind(this));
- window.addEventListener('mousedown', this.onMouseDown.bind(this));
- window.addEventListener('mousemove', this.onMouseMove.bind(this));
- window.addEventListener('mouseover', this.onMouseOver.bind(this));
- window.addEventListener('mouseout', this.onMouseOut.bind(this));
- window.addEventListener('resize', this.onResize.bind(this));
-
- if (this.options.scanning.touchInputEnabled) {
- window.addEventListener('click', this.onClick.bind(this));
- window.addEventListener('touchstart', this.onTouchStart.bind(this));
- window.addEventListener('touchend', this.onTouchEnd.bind(this));
- window.addEventListener('touchcancel', this.onTouchCancel.bind(this));
- window.addEventListener('touchmove', this.onTouchMove.bind(this), {passive: false});
- window.addEventListener('contextmenu', this.onContextMenu.bind(this));
- }
+ await this.updateOptions();
chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this));
} catch (e) {
@@ -88,7 +75,6 @@ class Frontend {
if (
this.pendingLookup ||
- !this.options.general.enable ||
(e.buttons & 0x1) !== 0x0 // Left mouse button
) {
return;
@@ -145,7 +131,7 @@ class Frontend {
}
onResize() {
- this.searchClear(true);
+ this.searchClear(false);
}
onClick(e) {
@@ -242,16 +228,59 @@ class Frontend {
}
onError(error) {
- console.log(error);
+ logError(error, false);
}
- async updateOptions() {
- this.options = await apiOptionsGet(this.getOptionsContext());
- if (!this.options.enable) {
+ setEnabled(enabled) {
+ if (enabled) {
+ if (!this.enabled) {
+ this.hookEvents();
+ this.enabled = true;
+ }
+ } else {
+ if (this.enabled) {
+ this.clearEventListeners();
+ this.enabled = false;
+ }
this.searchClear(false);
}
}
+ hookEvents() {
+ this.addEventListener(window, 'message', this.onWindowMessage.bind(this));
+ this.addEventListener(window, 'mousedown', this.onMouseDown.bind(this));
+ this.addEventListener(window, 'mousemove', this.onMouseMove.bind(this));
+ this.addEventListener(window, 'mouseover', this.onMouseOver.bind(this));
+ this.addEventListener(window, 'mouseout', this.onMouseOut.bind(this));
+ this.addEventListener(window, 'resize', this.onResize.bind(this));
+
+ if (this.options.scanning.touchInputEnabled) {
+ this.addEventListener(window, 'click', this.onClick.bind(this));
+ this.addEventListener(window, 'touchstart', this.onTouchStart.bind(this));
+ this.addEventListener(window, 'touchend', this.onTouchEnd.bind(this));
+ this.addEventListener(window, 'touchcancel', this.onTouchCancel.bind(this));
+ this.addEventListener(window, 'touchmove', this.onTouchMove.bind(this), {passive: false});
+ this.addEventListener(window, 'contextmenu', this.onContextMenu.bind(this));
+ }
+ }
+
+ addEventListener(node, type, listener, options) {
+ node.addEventListener(type, listener, options);
+ this.eventListeners.push([node, type, listener, options]);
+ }
+
+ clearEventListeners() {
+ for (const [node, type, listener, options] of this.eventListeners) {
+ node.removeEventListener(type, listener, options);
+ }
+ this.eventListeners = [];
+ }
+
+ async updateOptions() {
+ this.options = await apiOptionsGet(this.getOptionsContext());
+ this.setEnabled(this.options.general.enable);
+ }
+
popupTimerSet(callback) {
const delay = this.options.scanning.delay;
if (delay > 0) {
@@ -452,7 +481,7 @@ class Frontend {
searchFromTouch(x, y, cause) {
this.popupTimerClear();
- if (!this.options.general.enable || this.pendingLookup) {
+ if (this.pendingLookup) {
return;
}
@@ -527,8 +556,8 @@ Frontend.runtimeMessageHandlers = {
self.updateOptions();
},
- popupSetVisible: (self, {visible}) => {
- self.popup.setVisible(visible);
+ popupSetVisibleOverride: (self, {visible}) => {
+ self.popup.setVisibleOverride(visible);
}
};
diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js
index cb9741be..f933639c 100644
--- a/ext/fg/js/popup-proxy-host.js
+++ b/ext/fg/js/popup-proxy-host.js
@@ -41,7 +41,7 @@ class PopupProxyHost {
show: ({id, elementRect, options}) => this.show(id, elementRect, options),
showOrphaned: ({id, elementRect, options}) => this.show(id, elementRect, options),
hide: ({id, changeFocus}) => this.hide(id, changeFocus),
- setVisible: ({id, visible}) => this.setVisible(id, visible),
+ setVisibleOverride: ({id, visible}) => this.setVisibleOverride(id, visible),
containsPoint: ({id, x, y}) => this.containsPoint(id, x, y),
termsShow: ({id, elementRect, writingMode, definitions, options, context}) => this.termsShow(id, elementRect, writingMode, definitions, options, context),
kanjiShow: ({id, elementRect, writingMode, definitions, options, context}) => this.kanjiShow(id, elementRect, writingMode, definitions, options, context),
@@ -69,7 +69,7 @@ class PopupProxyHost {
getPopup(id) {
if (!this.popups.hasOwnProperty(id)) {
- throw 'Invalid popup ID';
+ throw new Error('Invalid popup ID');
}
return this.popups[id];
@@ -103,9 +103,9 @@ class PopupProxyHost {
return popup.hide(changeFocus);
}
- async setVisible(id, visible) {
+ async setVisibleOverride(id, visible) {
const popup = this.getPopup(id);
- return popup.setVisible(visible);
+ return popup.setVisibleOverride(visible);
}
async containsPoint(id, x, y) {
diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js
index 072cebc9..efbd28b2 100644
--- a/ext/fg/js/popup-proxy.js
+++ b/ext/fg/js/popup-proxy.js
@@ -65,9 +65,9 @@ class PopupProxy {
return await this.invokeHostApi('hide', {id: this.id, changeFocus});
}
- async setVisible(visible) {
+ async setVisibleOverride(visible) {
const id = await this.getPopupId();
- return await this.invokeHostApi('setVisible', {id, visible});
+ return await this.invokeHostApi('setVisibleOverride', {id, visible});
}
async containsPoint(x, y) {
@@ -98,7 +98,7 @@ class PopupProxy {
invokeHostApi(action, params={}) {
if (typeof this.parentFrameId !== 'number') {
- return Promise.reject('Invalid frame');
+ return Promise.reject(new Error('Invalid frame'));
}
return this.apiSender.invoke(action, params, `popup-proxy-host#${this.parentFrameId}`);
}
diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js
index 9dff6f28..9ca91afa 100644
--- a/ext/fg/js/popup.js
+++ b/ext/fg/js/popup.js
@@ -34,6 +34,9 @@ class Popup {
this.container.style.height = '0px';
this.injectPromise = null;
this.isInjected = false;
+ this.visible = false;
+ this.visibleOverride = null;
+ this.updateVisibility();
}
inject(options) {
@@ -105,9 +108,11 @@ class Popup {
container.style.top = `${y}px`;
container.style.width = `${width}px`;
container.style.height = `${height}px`;
- container.style.visibility = 'visible';
- this.hideChildren(true);
+ this.setVisible(true);
+ if (this.child !== null) {
+ this.child.hide(true);
+ }
}
static getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) {
@@ -209,41 +214,35 @@ class Popup {
}
hide(changeFocus) {
- if (this.isContainerHidden()) {
- changeFocus = false;
+ if (!this.isVisible()) {
+ return;
+ }
+
+ this.setVisible(false);
+ if (this.child !== null) {
+ this.child.hide(false);
}
- this.hideChildren(changeFocus);
- this.hideContainer();
if (changeFocus) {
this.focusParent();
}
}
- hideChildren(changeFocus) {
- // Recursively hides all children.
- if (this.child !== null && !this.child.isContainerHidden()) {
- this.child.hide(changeFocus);
- }
- }
-
- hideContainer() {
- this.container.style.visibility = 'hidden';
+ isVisible() {
+ return this.isInjected && (this.visibleOverride !== null ? this.visibleOverride : this.visible);
}
- isContainerHidden() {
- return (this.container.style.visibility === 'hidden');
+ setVisible(visible) {
+ this.visible = visible;
+ this.updateVisibility();
}
- isVisible() {
- return this.isInjected && this.container.style.visibility !== 'hidden';
+ setVisibleOverride(visible) {
+ this.visibleOverride = visible;
+ this.updateVisibility();
}
- setVisible(visible) {
- if (visible) {
- this.container.style.setProperty('display', '');
- } else {
- this.container.style.setProperty('display', 'none', 'important');
- }
+ updateVisibility() {
+ this.container.style.setProperty('visibility', this.isVisible() ? 'visible' : 'hidden', 'important');
}
focusParent() {
diff --git a/ext/fg/js/util.js b/ext/fg/js/util.js
index dc99274e..9a7968a7 100644
--- a/ext/fg/js/util.js
+++ b/ext/fg/js/util.js
@@ -30,19 +30,19 @@ function utilInvoke(action, params={}) {
chrome.runtime.sendMessage(data, (response) => {
utilCheckLastError(chrome.runtime.lastError);
if (response !== null && typeof response === 'object') {
- if (response.error) {
- reject(response.error);
+ if (typeof response.error !== 'undefined') {
+ reject(jsonToError(response.error));
} else {
resolve(response.result);
}
} else {
const message = response === null ? 'Unexpected null response' : `Unexpected response of type ${typeof response}`;
- reject(`${message} (${JSON.stringify(data)})`);
+ reject(new Error(`${message} (${JSON.stringify(data)})`));
}
});
} catch (e) {
window.yomichan_orphaned = true;
- reject(e.message);
+ reject(e);
}
});
}