aboutsummaryrefslogtreecommitdiff
path: root/ext/fg/js/frontend.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fg/js/frontend.js')
-rw-r--r--ext/fg/js/frontend.js64
1 files changed, 53 insertions, 11 deletions
diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js
index 39403bbd..079a7ef2 100644
--- a/ext/fg/js/frontend.js
+++ b/ext/fg/js/frontend.js
@@ -18,14 +18,15 @@
class Frontend {
- constructor() {
- this.popup = new Popup();
+ constructor(popup, ignoreNodes) {
+ this.popup = popup;
this.popupTimer = null;
this.mouseDownLeft = false;
this.mouseDownMiddle = false;
this.textSourceLast = null;
this.pendingLookup = false;
this.options = null;
+ this.ignoreNodes = (Array.isArray(ignoreNodes) && ignoreNodes.length > 0 ? ignoreNodes.join(',') : null);
this.primaryTouchIdentifier = null;
this.contextMenuChecking = false;
@@ -36,6 +37,17 @@ class Frontend {
this.scrollPrevent = false;
}
+ static create() {
+ const initializationData = window.frontendInitializationData;
+ const isNested = (initializationData !== null && typeof initializationData === 'object');
+ const {id, parentFrameId, ignoreNodes} = isNested ? initializationData : {};
+
+ const popup = isNested ? new PopupProxy(id, parentFrameId) : PopupProxyHost.instance.createPopup(null);
+ const frontend = new Frontend(popup, ignoreNodes);
+ frontend.prepare();
+ return frontend;
+ }
+
async prepare() {
try {
this.options = await apiOptionsGet();
@@ -44,6 +56,7 @@ class Frontend {
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('mouseup', this.onMouseUp.bind(this));
window.addEventListener('resize', this.onResize.bind(this));
@@ -137,6 +150,10 @@ class Frontend {
}
}
+ onMouseOut(e) {
+ this.popupTimerClear();
+ }
+
onFrameMessage(e) {
const handlers = {
popupClose: () => {
@@ -259,9 +276,8 @@ class Frontend {
const handler = handlers[action];
if (handler) {
handler(params);
+ callback();
}
-
- callback();
}
onError(error) {
@@ -281,7 +297,7 @@ class Frontend {
}
async searchAt(point, type) {
- if (this.pendingLookup || this.popup.containsPoint(point)) {
+ if (this.pendingLookup || await this.popup.containsPoint(point)) {
return;
}
@@ -324,9 +340,14 @@ class Frontend {
}
async searchTerms(textSource, focus) {
- textSource.setEndOffset(this.options.scanning.length);
+ this.setTextSourceScanLength(textSource, this.options.scanning.length);
- const {definitions, length} = await apiTermsFind(textSource.text());
+ const searchText = textSource.text();
+ if (searchText.length === 0) {
+ return;
+ }
+
+ const {definitions, length} = await apiTermsFind(searchText);
if (definitions.length === 0) {
return false;
}
@@ -352,9 +373,14 @@ class Frontend {
}
async searchKanji(textSource, focus) {
- textSource.setEndOffset(1);
+ this.setTextSourceScanLength(textSource, 1);
- const definitions = await apiKanjiFind(textSource.text());
+ const searchText = textSource.text();
+ if (searchText.length === 0) {
+ return;
+ }
+
+ const definitions = await apiKanjiFind(searchText);
if (definitions.length === 0) {
return false;
}
@@ -480,7 +506,23 @@ class Frontend {
}
return false;
}
+
+ setTextSourceScanLength(textSource, length) {
+ textSource.setEndOffset(length);
+ if (this.ignoreNodes === null || !textSource.range) {
+ return;
+ }
+
+ length = textSource.text().length;
+ while (textSource.range && length > 0) {
+ const nodes = TextSourceRange.getNodesInRange(textSource.range);
+ if (!TextSourceRange.anyNodeMatchesSelector(nodes, this.ignoreNodes)) {
+ break;
+ }
+ --length;
+ textSource.setEndOffset(length);
+ }
+ }
}
-window.yomichan_frontend = new Frontend();
-window.yomichan_frontend.prepare();
+window.yomichan_frontend = Frontend.create();