diff options
Diffstat (limited to 'ext/js/display/query-parser.js')
-rw-r--r-- | ext/js/display/query-parser.js | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/ext/js/display/query-parser.js b/ext/js/display/query-parser.js index cbcf7cff..e2578fcf 100644 --- a/ext/js/display/query-parser.js +++ b/ext/js/display/query-parser.js @@ -117,6 +117,8 @@ class QueryParser extends EventDispatcher { } if (e.type === null) { return; } + e.sentenceOffset = this._getSentenceOffset(e.textSource); + this.trigger('searched', e); } @@ -208,29 +210,33 @@ class QueryParser extends EventDispatcher { } _createParseResult(data) { + let offset = 0; const fragment = document.createDocumentFragment(); for (const term of data) { const termNode = document.createElement('span'); termNode.className = 'query-parser-term'; + termNode.dataset.offset = `${offset}`; for (const {text, reading} of term) { if (reading.length === 0) { termNode.appendChild(document.createTextNode(text)); } else { const reading2 = this._convertReading(text, reading); - termNode.appendChild(this._createSegment(text, reading2)); + termNode.appendChild(this._createSegment(text, reading2, offset)); } + offset += text.length; } fragment.appendChild(termNode); } return fragment; } - _createSegment(text, reading) { + _createSegment(text, reading, offset) { const segmentNode = document.createElement('ruby'); segmentNode.className = 'query-parser-segment'; const textNode = document.createElement('span'); textNode.className = 'query-parser-segment-text'; + textNode.dataset.offset = `${offset}`; const readingNode = document.createElement('rt'); readingNode.className = 'query-parser-segment-reading'; @@ -265,4 +271,30 @@ class QueryParser extends EventDispatcher { return reading; } } + + _getSentenceOffset(textSource) { + if (textSource.type === 'range') { + const {range} = textSource; + const node = this._getParentElement(range.startContainer); + if (node !== null) { + const {offset} = node.dataset; + if (typeof offset === 'string') { + const value = Number.parseInt(offset, 10); + if (Number.isFinite(value)) { + return Math.max(0, value) + range.startOffset; + } + } + } + } + return null; + } + + _getParentElement(node) { + const {ELEMENT_NODE} = Node; + while (true) { + node = node.parentNode; + if (node === null) { return null; } + if (node.nodeType === ELEMENT_NODE) { return node; } + } + } } |