Merge pull request #193 from toasted-nutbread/fix-is-point-in-range

Update isPointInRange to be more accurate
This commit is contained in:
Alex Yatskov 2019-08-29 18:00:36 -07:00 committed by GitHub
commit 3bf8a9ab00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -17,8 +17,6 @@
*/ */
const IS_FIREFOX = /Firefox/.test(navigator.userAgent);
function docOffsetCalc(element) { function docOffsetCalc(element) {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft; const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
@ -162,22 +160,49 @@ function docSentenceExtract(source, extent) {
} }
function isPointInRange(point, range) { function isPointInRange(point, range) {
if (IS_FIREFOX) { // Scan forward
// Always return true on Firefox due to an issue where range.getClientRects() const nodePre = range.endContainer;
// does not return a correct set of rects for characters at the beginning of a line. 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; return true;
} }
const y = point.y - 2; // No match
for (const rect of range.getClientRects()) {
if (y <= rect.bottom) {
return true;
}
}
return false; 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') { if (typeof document.caretRangeFromPoint !== 'function') {
document.caretRangeFromPoint = (x, y) => { document.caretRangeFromPoint = (x, y) => {
const position = document.caretPositionFromPoint(x, y); const position = document.caretPositionFromPoint(x, y);