Merge pull request #177 from toasted-nutbread/doc-range-from-point-improvements

Doc range from point improvements
This commit is contained in:
Alex Yatskov 2019-08-17 09:04:05 -07:00 committed by GitHub
commit 778d1d6e79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 31 deletions

View File

@ -17,6 +17,8 @@
*/ */
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;
@ -69,43 +71,23 @@ function docRangeFromPoint(point) {
const element = document.elementFromPoint(point.x, point.y); const element = document.elementFromPoint(point.x, point.y);
let imposter = null; let imposter = null;
if (element) { if (element) {
if (element.nodeName === 'IMG' || element.nodeName === 'BUTTON') { switch (element.nodeName) {
return new TextSourceElement(element); case 'IMG':
} else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') { case 'BUTTON':
imposter = docImposterCreate(element); return new TextSourceElement(element);
case 'INPUT':
case 'TEXTAREA':
imposter = docImposterCreate(element);
break;
} }
} }
if (!document.caretRangeFromPoint) {
document.caretRangeFromPoint = (x, y) => {
const position = document.caretPositionFromPoint(x,y);
if (position && position.offsetNode && position.offsetNode.nodeType === Node.TEXT_NODE) {
const range = document.createRange();
range.setStart(position.offsetNode, position.offset);
range.setEnd(position.offsetNode, position.offset);
return range;
}
return null;
};
}
const range = document.caretRangeFromPoint(point.x, point.y); const range = document.caretRangeFromPoint(point.x, point.y);
if (range === null) { if (imposter !== null) {
return; imposter.style.zIndex = -2147483646;
} }
if(imposter !== null) imposter.style.zIndex = -2147483646; return range !== null && isPointInRange(point, range) ? new TextSourceRange(range) : null;
const rects = range.getClientRects();
for (const rect of rects) {
if (point.y <= rect.bottom + 2) {
return new TextSourceRange(range);
}
}
if (navigator.userAgent.match(/Firefox/)) {
return new TextSourceRange(range);
}
} }
function docSentenceExtract(source, extent) { function docSentenceExtract(source, extent) {
@ -178,3 +160,33 @@ function docSentenceExtract(source, extent) {
offset: position - startPos - padding offset: position - startPos - padding
}; };
} }
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.
return true;
}
const y = point.y - 2;
for (const rect of range.getClientRects()) {
if (y <= rect.bottom) {
return true;
}
}
return false;
}
if (typeof document.caretRangeFromPoint !== 'function') {
document.caretRangeFromPoint = (x, y) => {
const position = document.caretPositionFromPoint(x, y);
if (position && position.offsetNode && position.offsetNode.nodeType === Node.TEXT_NODE) {
const range = document.createRange();
range.setStart(position.offsetNode, position.offset);
range.setEnd(position.offsetNode, position.offset);
return range;
}
return null;
};
}

View File

@ -81,6 +81,9 @@ class Display {
const clickedElement = $(e.target); const clickedElement = $(e.target);
const textSource = docRangeFromPoint({x: e.clientX, y: e.clientY}); const textSource = docRangeFromPoint({x: e.clientX, y: e.clientY});
if (textSource === null) {
return false;
}
textSource.setEndOffset(this.options.scanning.length); textSource.setEndOffset(this.options.scanning.length);
const {definitions, length} = await apiTermsFind(textSource.text()); const {definitions, length} = await apiTermsFind(textSource.text());