diff --git a/ext/bg/js/yomichan.js b/ext/bg/js/yomichan.js index bf277a2f..6aca4b5d 100644 --- a/ext/bg/js/yomichan.js +++ b/ext/bg/js/yomichan.js @@ -171,7 +171,9 @@ class Yomichan { 'kunyomi', 'onyomi', 'reading', + 'sentence', 'tags', + 'url', ]; for (let tag of tags) { diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index 2c46e9cf..a8fbaa68 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -19,17 +19,18 @@ class Client { constructor() { - this.popup = new Popup(); - this.audio = {}; - this.lastMousePos = null; + this.popup = new Popup(); + this.audio = {}; + this.lastMousePos = null; this.lastTextSource = null; - this.activateKey = 16; - this.activateBtn = 2; - this.enabled = false; - this.options = {}; - this.definitions = null; - this.sequence = 0; - this.fgRoot = chrome.extension.getURL('fg'); + this.activateKey = 16; + this.activateBtn = 2; + this.sentenceExtent = 200; + this.enabled = false; + this.options = {}; + this.definitions = null; + this.sequence = 0; + this.fgRoot = chrome.extension.getURL('fg'); chrome.runtime.onMessage.addListener(this.onBgMessage.bind(this)); window.addEventListener('message', this.onFrameMessage.bind(this)); @@ -94,9 +95,15 @@ class Client { if (length === 0) { this.hidePopup(); } else { - const sequence = ++this.sequence; textSource.setEndOffset(length); + const sentence = Client.extractSentence(textSource, this.sentenceExtent); + definitions.forEach((definition) => { + definition.url = window.location.href; + definition.sentence = sentence; + }); + + const sequence = ++this.sequence; bgRenderText( {definitions, root: this.fgRoot, options: this.options, sequence}, 'term-list.html', @@ -180,6 +187,10 @@ class Client { api_displayKanji(kanji) { bgFindKanji(kanji, (definitions) => { + definitions.forEach((definition) => { + definition.url = window.location.href; + }); + const sequence = ++this.sequence; bgRenderText( {definitions, root: this.fgRoot, options: this.options, sequence}, @@ -219,11 +230,16 @@ class Client { return null; } - static extractSentence(content, position) { - const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'}; - const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'}; + static extractSentence(source, extent) { + const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'}; + const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'}; const terminators = '…。..??!!'; + const sourceLocal = source.clone(); + const position = sourceLocal.setStartOffset(extent); + sourceLocal.setEndOffset(position + extent); + const content = sourceLocal.text(); + let quoteStack = []; let startPos = 0; diff --git a/ext/fg/js/source-input.js b/ext/fg/js/source-input.js index 9f5a76a0..d3c92793 100644 --- a/ext/fg/js/source-input.js +++ b/ext/fg/js/source-input.js @@ -18,9 +18,13 @@ class TextSourceInput { - constructor(input) { + constructor(input, length=-1) { this.input = input; - this.length = -1; + this.length = length; + } + + clone() { + return new TextSourceInput(this.input, this.length); } text() { diff --git a/ext/fg/js/source-range.js b/ext/fg/js/source-range.js index fbab45f9..879b949c 100644 --- a/ext/fg/js/source-range.js +++ b/ext/fg/js/source-range.js @@ -22,20 +22,26 @@ class TextSourceRange { this.rng = range; } + clone() { + return new TextSourceRange(this.rng.cloneRange()); + } + text() { return this.rng.toString(); } setEndOffset(length) { - const end = TextSourceRange.seekForward(this.rng.startContainer, this.rng.startOffset + length); - this.rng.setEnd(end.node, end.offset); - return length - end.length; + const lengthAdj = length + this.rng.startOffset; + const state = TextSourceRange.seekForward(this.rng.startContainer, lengthAdj); + this.rng.setEnd(state.node, state.offset); + return length - state.length; } setStartOffset(length) { - const start = TextSourceRange.seekBackward(this.rng.startContainer, length + (this.rng.startContainer.length - this.rng.startOffset)); - this.rng.setStart(start.node, start.offset); - return length - start.length; + const lengthAdj = length + (this.rng.startContainer.length - this.rng.startOffset); + const state = TextSourceRange.seekBackward(this.rng.startContainer, lengthAdj); + this.rng.setStart(state.node, state.offset); + return length - state.length; } containsPoint(point) { @@ -48,10 +54,10 @@ class TextSourceRange { } getPaddedRect() { - const range = this.rng.cloneRange(); + const range = this.rng.cloneRange(); const startOffset = range.startOffset; - const endOffset = range.endOffset; - const node = range.startContainer; + 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));