From 0ff4e96c0a4039a9e6545d5bad8127584b2e13d1 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 28 Feb 2025 14:52:41 +0100 Subject: [PATCH] Fix offset compensation See-also: 51099347f2f51d3bb5c0d30febc5dcaa2ad62f45 --- service.js | 92 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/service.js b/service.js index 71646a7..fc89217 100644 --- a/service.js +++ b/service.js @@ -362,14 +362,13 @@ class BesService { * @param {*} match Grammar checking rule match */ drawMistakeMarkup(match) { - const range = match.range - match.highlights = Array.from(range.getClientRects()) - if (match.highlights.length === 0) return const canvasPanelRect = this.canvasPanel.getBoundingClientRect() - for (let rect of match.highlights) { - rect.x -= canvasPanelRect.x - rect.y -= canvasPanelRect.y - } + match.highlights = BesService.getClientRects( + match.range, + canvasPanelRect.x, + canvasPanelRect.y + ) + if (match.highlights.length === 0) return const dpr = window.devicePixelRatio this.ctx.lineWidth = 2 * dpr // Use 2 for clearer visibility const ruleId = match.match.rule.id @@ -486,21 +485,29 @@ class BesService { const scale = (markerY2 - markerY1) / 18 if (/^\s+$/.test(toRemove)) { - const rect = this.makeRange( - match.data, - match.match.offset, - match.match.offset - lengthDiff - )?.getClientRects()[0] + const rect = BesService.getClientRects( + this.makeRange( + match.data, + match.match.offset, + match.match.offset - lengthDiff + ), + canvasPanelRect.x, + canvasPanelRect.y + )[0] const x = (rect.left + rect.right) / 2 const y1 = rect.top const y2 = rect.bottom this.drawWrongSpacing(x, y1, y2, scale) } else { - for (let rect of this.makeRange( - match.data, - match.match.offset, - match.match.offset - lengthDiff - )?.getClientRects()) + for (let rect of BesService.getClientRects( + this.makeRange( + match.data, + match.match.offset, + match.match.offset - lengthDiff + ), + canvasPanelRect.x, + canvasPanelRect.y + )) this.drawExcessiveText( rect.left, rect.bottom, @@ -516,21 +523,29 @@ class BesService { const scale = (markerY2 - markerY1) / 18 if (/^\s+$/.test(toRemove)) { - const rect = this.makeRange( - match.data, - match.match.offset + match.match.length + lengthDiff, - match.match.offset + match.match.length - )?.getClientRects()[0] + const rect = BesService.getClientRects( + this.makeRange( + match.data, + match.match.offset + match.match.length + lengthDiff, + match.match.offset + match.match.length + ), + canvasPanelRect.x, + canvasPanelRect.y + )[0] const x = (rect.left + rect.right) / 2 const y1 = rect.top const y2 = rect.bottom this.drawWrongSpacing(x, y1, y2, scale) } else { - for (let rect of this.makeRange( - match.data, - match.match.offset + match.match.length + lengthDiff, - match.match.offset + match.match.length - )?.getClientRects()) + for (let rect of BesService.getClientRects( + this.makeRange( + match.data, + match.match.offset + match.match.length + lengthDiff, + match.match.offset + match.match.length + ), + canvasPanelRect.x, + canvasPanelRect.y + )) this.drawExcessiveText( rect.left, rect.bottom, @@ -574,12 +589,14 @@ class BesService { } } else { // Patch differences. - const rects = Array.from( + const rects = BesService.getClientRects( this.makeRange( match.data, match.match.offset + lengthL, match.match.offset + match.match.length - lengthR - )?.getClientRects() + ), + canvasPanelRect.x, + canvasPanelRect.y ) markerY1 = Math.min(...rects.map(rect => rect.top)) markerY2 = Math.max(...rects.map(rect => rect.bottom)) @@ -863,6 +880,23 @@ class BesService { this.ctx.stroke() } + /** + * Calculates rectangles covering a given range and compensates for scroll offset + * + * @param {Range} range Range to get client rectangles for + * @param {Number} offsetX X offset to subtract from coordinates [px] + * @param {Number} offsetY Y offset to subtract from coordinates [px] + * @returns Array of rectangles + */ + static getClientRects(range, offsetX, offsetY) { + const rects = Array.from(range.getClientRects()) + for (let rect of rects) { + rect.x -= offsetX + rect.y -= offsetY + } + return rects + } + /** * Calculates common string prefix length *