diff options
Diffstat (limited to 'ext/mixed')
-rw-r--r-- | ext/mixed/js/display.js | 11 | ||||
-rw-r--r-- | ext/mixed/js/dom.js | 38 | ||||
-rw-r--r-- | ext/mixed/js/text-scanner.js | 11 |
3 files changed, 50 insertions, 10 deletions
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 90fd1037..1d699706 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -236,7 +236,9 @@ class Display { const {textSource, definitions} = termLookupResults; const scannedElement = e.target; - const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); + const sentenceExtent = this.options.anki.sentenceExt; + const layoutAwareScan = this.options.scanning.layoutAwareScan; + const sentence = docSentenceExtract(textSource, sentenceExtent, layoutAwareScan); this.context.update({ index: this.entryIndexFind(scannedElement), @@ -273,21 +275,22 @@ class Display { try { e.preventDefault(); - const textSource = docRangeFromPoint(e.clientX, e.clientY, this.options.scanning.deepDomScan); + const {length: scanLength, deepDomScan: deepScan, layoutAwareScan} = this.options.scanning; + const textSource = docRangeFromPoint(e.clientX, e.clientY, deepScan); if (textSource === null) { return false; } let definitions, length; try { - textSource.setEndOffset(this.options.scanning.length); + textSource.setEndOffset(scanLength, layoutAwareScan); ({definitions, length} = await api.termsFind(textSource.text(), {}, this.getOptionsContext())); if (definitions.length === 0) { return false; } - textSource.setEndOffset(length); + textSource.setEndOffset(length, layoutAwareScan); } finally { textSource.cleanup(); } diff --git a/ext/mixed/js/dom.js b/ext/mixed/js/dom.js index 0e8f4462..05764443 100644 --- a/ext/mixed/js/dom.js +++ b/ext/mixed/js/dom.js @@ -86,4 +86,42 @@ class DOM { null ); } + + static getNodesInRange(range) { + const end = range.endContainer; + const nodes = []; + for (let node = range.startContainer; node !== null; node = DOM.getNextNode(node)) { + nodes.push(node); + if (node === end) { break; } + } + return nodes; + } + + static getNextNode(node) { + let next = node.firstChild; + if (next === null) { + while (true) { + next = node.nextSibling; + if (next !== null) { break; } + + next = node.parentNode; + if (next === null) { break; } + + node = next; + } + } + return next; + } + + static anyNodeMatchesSelector(nodes, selector) { + const ELEMENT_NODE = Node.ELEMENT_NODE; + for (let node of nodes) { + for (; node !== null; node = node.parentNode) { + if (node.nodeType !== ELEMENT_NODE) { continue; } + if (node.matches(selector)) { return true; } + break; + } + } + return false; + } } diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js index b8688b08..fb275452 100644 --- a/ext/mixed/js/text-scanner.js +++ b/ext/mixed/js/text-scanner.js @@ -17,7 +17,6 @@ /* global * DOM - * TextSourceRange * docRangeFromPoint */ @@ -119,20 +118,20 @@ class TextScanner extends EventDispatcher { } } - getTextSourceContent(textSource, length) { + getTextSourceContent(textSource, length, layoutAwareScan) { const clonedTextSource = textSource.clone(); - clonedTextSource.setEndOffset(length); + clonedTextSource.setEndOffset(length, layoutAwareScan); if (this._ignoreNodes !== null && clonedTextSource.range) { length = clonedTextSource.text().length; while (clonedTextSource.range && length > 0) { - const nodes = TextSourceRange.getNodesInRange(clonedTextSource.range); - if (!TextSourceRange.anyNodeMatchesSelector(nodes, this._ignoreNodes)) { + const nodes = DOM.getNodesInRange(clonedTextSource.range); + if (!DOM.anyNodeMatchesSelector(nodes, this._ignoreNodes)) { break; } --length; - clonedTextSource.setEndOffset(length); + clonedTextSource.setEndOffset(length, layoutAwareScan); } } |