Compare commits

...

2 Commits

Author SHA1 Message Date
32690de8a7 samples: Fix CKEditor markup style switching 2025-02-28 14:56:12 +01:00
0ff4e96c0a Fix offset compensation
See-also: 51099347f2f51d3bb5c0d30febc5dcaa2ad62f45
2025-02-28 14:52:41 +01:00
2 changed files with 65 additions and 31 deletions

View File

@ -75,8 +75,8 @@ Kvazimodo ji je ponavadi prinesel hrano in pijačo, medtem ko je spala, da ne bi
let my_ckeditor = null let my_ckeditor = null
ClassicEditor.create(document.querySelector('#ckeditor-control')) ClassicEditor.create(document.querySelector('#ckeditor-control'))
.then(newEditor => { .then(newEditor => {
my_ckeditor = newEditor my_ckeditor = newEditor.ui.view.editable.element
BesCKService.register(newEditor.ui.view.editable.element, newEditor, new BesCKStatusIconEventSink()) BesCKService.register(my_ckeditor, newEditor, new BesCKStatusIconEventSink())
}) })
.catch(error => console.error(error)) .catch(error => console.error(error))
</script> </script>

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