From 6099de71d86b923e1bc76b32833a7ccfcab73692 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Fri, 22 Jul 2016 22:14:59 -0700 Subject: Work on supporting different text sources --- ext/fg/js/client.js | 34 ++++++++------ ext/fg/js/image.js | 56 ----------------------- ext/fg/js/range.js | 113 ---------------------------------------------- ext/fg/js/source-image.js | 56 +++++++++++++++++++++++ ext/fg/js/source-range.js | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+), 184 deletions(-) delete mode 100644 ext/fg/js/image.js delete mode 100644 ext/fg/js/range.js create mode 100644 ext/fg/js/source-image.js create mode 100644 ext/fg/js/source-range.js (limited to 'ext/fg/js') diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index 587ced86..16ee0b24 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -22,7 +22,7 @@ class Client { this.popup = new Popup(); this.audio = {}; this.lastMousePos = null; - this.lastRange = null; + this.lastTextSource = null; this.activateKey = 16; this.activateBtn = 2; this.enabled = false; @@ -87,31 +87,35 @@ class Client { } } + textSourceFromPoint(point) { + return Range.fromPoint(point); + } + searchAt(point) { - const range = Range.fromPoint(point); - if (range === null || !range.containsPoint(point)) { + const textSource = this.textSourceFromPoint(point); + if (textSource === null || !textSource.containsPoint(point)) { this.hidePopup(); return; } - if (this.lastRange !== null && this.lastRange.compareOrigin(range) === 0) { + if (this.lastTextSource !== null && this.lastTextSource.compareOrigin(textSource) === 0) { return; } - range.setLength(this.options.scanLength); - bgFindTerm(range.text(), ({definitions, length}) => { + textSource.setLength(this.options.scanLength); + bgFindTerm(textSource.text(), ({definitions, length}) => { if (length === 0) { this.hidePopup(); } else { const sequence = ++this.sequence; - range.setLength(length); + textSource.setLength(length); bgRenderText( {definitions, root: this.fgRoot, options: this.options, sequence}, 'term-list.html', (content) => { this.definitions = definitions; - this.showPopup(range, content); + this.showPopup(textSource, content); bgCanAddDefinitions(definitions, ['vocab_kanji', 'vocab_kana'], (states) => { if (states !== null) { @@ -124,24 +128,24 @@ class Client { }); } - showPopup(range, content) { - this.popup.showNextTo(range.getRect(), content); + showPopup(textSource, content) { + this.popup.showNextTo(textSource.getRect(), content); if (this.options.selectMatchedText) { - range.select(); + textSource.select(); } - this.lastRange = range; + this.lastTextSource = textSource; } hidePopup() { this.popup.hide(); - if (this.options.selectMatchedText && this.lastRange !== null) { - this.lastRange.deselect(); + if (this.options.selectMatchedText && this.lastTextSource !== null) { + this.lastTextSource.deselect(); } - this.lastRange = null; + this.lastTextSource = null; this.definitions = null; } diff --git a/ext/fg/js/image.js b/ext/fg/js/image.js deleted file mode 100644 index 187b0a1d..00000000 --- a/ext/fg/js/image.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2016 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -class Image { - constructor(image) { - - } - - text() { - - } - - setLength(length) { - - } - - containsPoint(point) { - - } - - getRect() { - - } - - getPaddedRect() { - - } - - select() { - - } - - deselect() { - - } - - compareOrigin(range) { - - } -} diff --git a/ext/fg/js/range.js b/ext/fg/js/range.js deleted file mode 100644 index c4cabf4b..00000000 --- a/ext/fg/js/range.js +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2016 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -class Range { - constructor(range) { - this.rng = range; - } - - text() { - return this.rng.toString(); - } - - setLength(length) { - const end = Range.seekEnd(this.rng.startContainer, this.rng.startOffset + length); - this.rng.setEnd(end.node, end.offset); - } - - containsPoint(point) { - const rect = this.getPaddedRect(); - return point.x >= rect.left && point.x <= rect.right; - } - - getRect() { - return this.rng.getBoundingClientRect(); - } - - getPaddedRect() { - const range = this.rng.cloneRange(); - const startOffset = range.startOffset; - const endOffset = range.endOffset; - const node = range.startContainer; - - range.setStart(node, Math.max(0, startOffset - 1)); - range.setEnd(node, Math.min(node.length, endOffset + 1)); - - return range.getBoundingClientRect(); - } - - select() { - const selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange(this.rng); - } - - deselect() { - const selection = window.getSelection(); - selection.removeAllRanges(); - } - - compareOrigin(range) { - return range.rng.compareBoundaryPoints(Range.START_TO_START, this.rng); - } - - static seekEnd(node, length) { - const state = {node, offset: 0, length}; - - if (!Range.seekEndRecurse(node, state)) { - return {node: state.node, offset: state.offset}; - } - - for (let sibling = node.nextSibling; sibling !== null; sibling = sibling.nextSibling) { - if (!Range.seekEndRecurse(sibling, state)) { - return {node: state.node, offset: state.offset}; - } - } - - for (let sibling = node.parentElement.nextSibling; sibling !== null; sibling = sibling.nextSibling) { - if (!Range.seekEndRecurse(sibling, state)) { - return {node: state.node, offset: state.offset}; - } - } - - return {node: state.node, offset: state.offset}; - } - - static seekEndRecurse(node, state) { - if (node.nodeType === 3) { - const consumed = Math.min(node.length, state.length); - state.node = node; - state.offset = consumed; - state.length -= consumed; - } else { - for (let i = 0; i < node.childNodes.length; ++i) { - if (!Range.seekEndRecurse(node.childNodes[i], state)) { - break; - } - } - } - - return state.length > 0; - } - - static fromPoint(point) { - const range = document.caretRangeFromPoint(point.x, point.y); - return range === null ? null : new Range(range); - } -} diff --git a/ext/fg/js/source-image.js b/ext/fg/js/source-image.js new file mode 100644 index 00000000..187b0a1d --- /dev/null +++ b/ext/fg/js/source-image.js @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +class Image { + constructor(image) { + + } + + text() { + + } + + setLength(length) { + + } + + containsPoint(point) { + + } + + getRect() { + + } + + getPaddedRect() { + + } + + select() { + + } + + deselect() { + + } + + compareOrigin(range) { + + } +} diff --git a/ext/fg/js/source-range.js b/ext/fg/js/source-range.js new file mode 100644 index 00000000..c4cabf4b --- /dev/null +++ b/ext/fg/js/source-range.js @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2016 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +class Range { + constructor(range) { + this.rng = range; + } + + text() { + return this.rng.toString(); + } + + setLength(length) { + const end = Range.seekEnd(this.rng.startContainer, this.rng.startOffset + length); + this.rng.setEnd(end.node, end.offset); + } + + containsPoint(point) { + const rect = this.getPaddedRect(); + return point.x >= rect.left && point.x <= rect.right; + } + + getRect() { + return this.rng.getBoundingClientRect(); + } + + getPaddedRect() { + const range = this.rng.cloneRange(); + const startOffset = range.startOffset; + const endOffset = range.endOffset; + const node = range.startContainer; + + range.setStart(node, Math.max(0, startOffset - 1)); + range.setEnd(node, Math.min(node.length, endOffset + 1)); + + return range.getBoundingClientRect(); + } + + select() { + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(this.rng); + } + + deselect() { + const selection = window.getSelection(); + selection.removeAllRanges(); + } + + compareOrigin(range) { + return range.rng.compareBoundaryPoints(Range.START_TO_START, this.rng); + } + + static seekEnd(node, length) { + const state = {node, offset: 0, length}; + + if (!Range.seekEndRecurse(node, state)) { + return {node: state.node, offset: state.offset}; + } + + for (let sibling = node.nextSibling; sibling !== null; sibling = sibling.nextSibling) { + if (!Range.seekEndRecurse(sibling, state)) { + return {node: state.node, offset: state.offset}; + } + } + + for (let sibling = node.parentElement.nextSibling; sibling !== null; sibling = sibling.nextSibling) { + if (!Range.seekEndRecurse(sibling, state)) { + return {node: state.node, offset: state.offset}; + } + } + + return {node: state.node, offset: state.offset}; + } + + static seekEndRecurse(node, state) { + if (node.nodeType === 3) { + const consumed = Math.min(node.length, state.length); + state.node = node; + state.offset = consumed; + state.length -= consumed; + } else { + for (let i = 0; i < node.childNodes.length; ++i) { + if (!Range.seekEndRecurse(node.childNodes[i], state)) { + break; + } + } + } + + return state.length > 0; + } + + static fromPoint(point) { + const range = document.caretRangeFromPoint(point.x, point.y); + return range === null ? null : new Range(range); + } +} -- cgit v1.2.3