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 * @param {*} match Grammar checking rule match
*/ */
drawMistakeMarkup(match) { drawMistakeMarkup(match) {
const range = match.range
match.highlights = Array.from(range.getClientRects())
if (match.highlights.length === 0) return
const canvasPanelRect = this.canvasPanel.getBoundingClientRect() const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
for (let rect of match.highlights) { match.highlights = BesService.getClientRects(
rect.x -= canvasPanelRect.x match.range,
rect.y -= canvasPanelRect.y canvasPanelRect.x,
} canvasPanelRect.y
)
if (match.highlights.length === 0) return
const dpr = window.devicePixelRatio const dpr = window.devicePixelRatio
this.ctx.lineWidth = 2 * dpr // Use 2 for clearer visibility this.ctx.lineWidth = 2 * dpr // Use 2 for clearer visibility
const ruleId = match.match.rule.id const ruleId = match.match.rule.id
@ -486,21 +485,29 @@ class BesService {
const scale = (markerY2 - markerY1) / 18 const scale = (markerY2 - markerY1) / 18
if (/^\s+$/.test(toRemove)) { if (/^\s+$/.test(toRemove)) {
const rect = this.makeRange( const rect = BesService.getClientRects(
match.data, this.makeRange(
match.match.offset, match.data,
match.match.offset - lengthDiff match.match.offset,
)?.getClientRects()[0] match.match.offset - lengthDiff
),
canvasPanelRect.x,
canvasPanelRect.y
)[0]
const x = (rect.left + rect.right) / 2 const x = (rect.left + rect.right) / 2
const y1 = rect.top const y1 = rect.top
const y2 = rect.bottom const y2 = rect.bottom
this.drawWrongSpacing(x, y1, y2, scale) this.drawWrongSpacing(x, y1, y2, scale)
} else { } else {
for (let rect of this.makeRange( for (let rect of BesService.getClientRects(
match.data, this.makeRange(
match.match.offset, match.data,
match.match.offset - lengthDiff match.match.offset,
)?.getClientRects()) match.match.offset - lengthDiff
),
canvasPanelRect.x,
canvasPanelRect.y
))
this.drawExcessiveText( this.drawExcessiveText(
rect.left, rect.left,
rect.bottom, rect.bottom,
@ -516,21 +523,29 @@ class BesService {
const scale = (markerY2 - markerY1) / 18 const scale = (markerY2 - markerY1) / 18
if (/^\s+$/.test(toRemove)) { if (/^\s+$/.test(toRemove)) {
const rect = this.makeRange( const rect = BesService.getClientRects(
match.data, this.makeRange(
match.match.offset + match.match.length + lengthDiff, match.data,
match.match.offset + match.match.length match.match.offset + match.match.length + lengthDiff,
)?.getClientRects()[0] match.match.offset + match.match.length
),
canvasPanelRect.x,
canvasPanelRect.y
)[0]
const x = (rect.left + rect.right) / 2 const x = (rect.left + rect.right) / 2
const y1 = rect.top const y1 = rect.top
const y2 = rect.bottom const y2 = rect.bottom
this.drawWrongSpacing(x, y1, y2, scale) this.drawWrongSpacing(x, y1, y2, scale)
} else { } else {
for (let rect of this.makeRange( for (let rect of BesService.getClientRects(
match.data, this.makeRange(
match.match.offset + match.match.length + lengthDiff, match.data,
match.match.offset + match.match.length match.match.offset + match.match.length + lengthDiff,
)?.getClientRects()) match.match.offset + match.match.length
),
canvasPanelRect.x,
canvasPanelRect.y
))
this.drawExcessiveText( this.drawExcessiveText(
rect.left, rect.left,
rect.bottom, rect.bottom,
@ -574,12 +589,14 @@ class BesService {
} }
} else { } else {
// Patch differences. // Patch differences.
const rects = Array.from( const rects = BesService.getClientRects(
this.makeRange( this.makeRange(
match.data, match.data,
match.match.offset + lengthL, match.match.offset + lengthL,
match.match.offset + match.match.length - lengthR match.match.offset + match.match.length - lengthR
)?.getClientRects() ),
canvasPanelRect.x,
canvasPanelRect.y
) )
markerY1 = Math.min(...rects.map(rect => rect.top)) markerY1 = Math.min(...rects.map(rect => rect.top))
markerY2 = Math.max(...rects.map(rect => rect.bottom)) markerY2 = Math.max(...rects.map(rect => rect.bottom))
@ -863,6 +880,23 @@ class BesService {
this.ctx.stroke() 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 * Calculates common string prefix length
* *