diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-08-29 20:35:23 -0400 |
---|---|---|
committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-08-29 20:35:23 -0400 |
commit | ea9c5ad86794db44eda32e735b8aa22c5eb7726e (patch) | |
tree | 2a316630e49046802ce84b5eaa59b5ec216c7513 /ext/fg | |
parent | 7bf215617c9e54228bd5f5fe44b29f7b99de1abc (diff) |
Update isPointInRange to be more accurate
Diffstat (limited to 'ext/fg')
-rw-r--r-- | ext/fg/js/document.js | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/ext/fg/js/document.js b/ext/fg/js/document.js index 86396a8a..8a412f96 100644 --- a/ext/fg/js/document.js +++ b/ext/fg/js/document.js @@ -17,8 +17,6 @@ */ -const IS_FIREFOX = /Firefox/.test(navigator.userAgent); - function docOffsetCalc(element) { const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft; @@ -162,22 +160,49 @@ function docSentenceExtract(source, extent) { } function isPointInRange(point, range) { - if (IS_FIREFOX) { - // Always return true on Firefox due to an issue where range.getClientRects() - // does not return a correct set of rects for characters at the beginning of a line. + // Scan forward + const nodePre = range.endContainer; + const offsetPre = range.endOffset; + try { + const {node, offset} = TextSourceRange.seekForward(range.endContainer, range.endOffset, 1); + range.setEnd(node, offset); + + if (isPointInAnyRect(point, range.getClientRects())) { + return true; + } + } finally { + range.setEnd(nodePre, offsetPre); + } + + // Scan backward + const {node, offset} = TextSourceRange.seekBackward(range.startContainer, range.startOffset, 1); + range.setStart(node, offset); + + if (isPointInAnyRect(point, range.getClientRects())) { + // This purposefully leaves the starting offset as modified and sets teh range length to 0. + range.setEnd(node, offset); return true; } - const y = point.y - 2; - for (const rect of range.getClientRects()) { - if (y <= rect.bottom) { + // No match + return false; +} + +function isPointInAnyRect(point, rects) { + for (const rect of rects) { + if (isPointInRect(point, rect)) { return true; } } - return false; } +function isPointInRect(point, rect) { + return ( + point.x >= rect.left && point.x < rect.right && + point.y >= rect.top && point.y < rect.bottom); +} + if (typeof document.caretRangeFromPoint !== 'function') { document.caretRangeFromPoint = (x, y) => { const position = document.caretPositionFromPoint(x, y); |