summaryrefslogtreecommitdiff
path: root/ext/mixed/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-06-21 16:07:51 -0400
committerGitHub <noreply@github.com>2020-06-21 16:07:51 -0400
commite23504613f8526b90a497512c086ed48e66cde95 (patch)
tree98db1a607ba40659d727e0083f2e45032a53e3a9 /ext/mixed/js
parent4ebee3e17c2d536da7de33d16c2e44c54c4c8e51 (diff)
Use DOMTextScanner (#536)
* Use DOMTextScanner instead of TextSourceRange.seek* * Move getNodesInRange to dom.js * Move anyNodeMatchesSelector to dom.js * Remove unused functions * Update tests * Add layoutAwareScan option * Use layoutAwareScan for source and sentence scanning * Remove unused IGNORE_TEXT_PATTERN
Diffstat (limited to 'ext/mixed/js')
-rw-r--r--ext/mixed/js/display.js11
-rw-r--r--ext/mixed/js/dom.js38
-rw-r--r--ext/mixed/js/text-scanner.js11
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);
}
}