Fix offset compensation

See-also: 51099347f2f51d3bb5c0d30febc5dcaa2ad62f45
This commit is contained in:
Simon Rozman 2025-02-28 14:52:41 +01:00
parent b6c825cc83
commit 0ff4e96c0a

View File

@ -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
*