Revise scrolling
This commit is contained in:
parent
d246d07d7f
commit
51099347f2
183
service.js
183
service.js
@ -73,6 +73,9 @@ class BesService {
|
||||
})
|
||||
|
||||
besServices.push(this)
|
||||
|
||||
// Initial sync the scroll as hostElement may be scrolled by non-(0, 0) at the time of BesService registration.
|
||||
this.onScroll()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -360,11 +363,13 @@ class BesService {
|
||||
*/
|
||||
drawMistakeMarkup(match) {
|
||||
const range = match.range
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
const scrollX = canvasPanelRect.left
|
||||
const scrollY = canvasPanelRect.top
|
||||
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
|
||||
}
|
||||
const dpr = window.devicePixelRatio
|
||||
this.ctx.lineWidth = 2 * dpr // Use 2 for clearer visibility
|
||||
const ruleId = match.match.rule.id
|
||||
@ -386,7 +391,7 @@ class BesService {
|
||||
const scale = (markerY2 - markerY1) / 18
|
||||
const x = match.highlights[0].left
|
||||
const y = match.highlights[0].bottom
|
||||
this.drawMissingComma(x - scrollX, y - scrollY, scale, '?')
|
||||
this.drawMissingComma(x, y, scale, '?')
|
||||
break
|
||||
}
|
||||
|
||||
@ -413,25 +418,20 @@ class BesService {
|
||||
// in another line, making a confusing UX.
|
||||
const x = match.highlights[0].left
|
||||
const y = match.highlights[0].bottom
|
||||
this.drawMissingComma(x - scrollX, y - scrollY, scale)
|
||||
this.drawMissingComma(x, y, scale)
|
||||
} else if (/^\s+$/.test(toInsert)) {
|
||||
const x = match.highlights[0].left
|
||||
const y1 = match.highlights[0].bottom - 2 * scale
|
||||
const y2 = match.highlights[0].top + 2 * scale
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawWrongSpacing(x, y1, y2, scale)
|
||||
} else {
|
||||
const x = match.highlights[0].left - 1 * scale
|
||||
const y1 = match.highlights[0].bottom
|
||||
const y2 = match.highlights[0].top
|
||||
this.drawMissingText(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
x,
|
||||
y1,
|
||||
y2,
|
||||
scale,
|
||||
replacement.substr(lengthDiff).trim()
|
||||
)
|
||||
@ -446,25 +446,20 @@ class BesService {
|
||||
if (toInsert === ',') {
|
||||
const x = match.highlights.at(-1).right
|
||||
const y = match.highlights.at(-1).bottom
|
||||
this.drawMissingComma(x - scrollX, y - scrollY, scale)
|
||||
this.drawMissingComma(x, y, scale)
|
||||
} else if (/^\s+$/.test(toInsert)) {
|
||||
const x = match.highlights.at(-1).right
|
||||
const y1 = match.highlights.at(-1).bottom - 2 * scale
|
||||
const y2 = match.highlights.at(-1).top + 2 * scale
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawWrongSpacing(x, y1, y2, scale)
|
||||
} else {
|
||||
const x = match.highlights.at(-1).right + 1 * scale
|
||||
const y1 = match.highlights.at(-1).bottom
|
||||
const y2 = match.highlights.at(-1).top
|
||||
this.drawMissingText(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
x,
|
||||
y1,
|
||||
y2,
|
||||
scale,
|
||||
replacement.substr(-lengthDiff).trim()
|
||||
)
|
||||
@ -488,12 +483,7 @@ class BesService {
|
||||
const x = (rect.left + rect.right) / 2
|
||||
const y1 = rect.top
|
||||
const y2 = rect.bottom
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawWrongSpacing(x, y1, y2, scale)
|
||||
} else {
|
||||
for (let rect of this.makeRange(
|
||||
match.data,
|
||||
@ -501,10 +491,10 @@ class BesService {
|
||||
match.match.offset - lengthDiff
|
||||
)?.getClientRects())
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top
|
||||
)
|
||||
}
|
||||
} else if (context.substr(0, replacement.length) === replacement) {
|
||||
@ -523,12 +513,7 @@ class BesService {
|
||||
const x = (rect.left + rect.right) / 2
|
||||
const y1 = rect.top
|
||||
const y2 = rect.bottom
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawWrongSpacing(x, y1, y2, scale)
|
||||
} else {
|
||||
for (let rect of this.makeRange(
|
||||
match.data,
|
||||
@ -536,10 +521,10 @@ class BesService {
|
||||
match.match.offset + match.match.length
|
||||
)?.getClientRects())
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -559,20 +544,20 @@ class BesService {
|
||||
for (let rect of match.highlights) {
|
||||
if (first) {
|
||||
this.drawWrongText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY,
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top,
|
||||
scale,
|
||||
replacement
|
||||
)
|
||||
first = false
|
||||
} else {
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -600,22 +585,11 @@ class BesService {
|
||||
if (/^\s+$/.test(toInsert)) {
|
||||
const y1 = rects[0].bottom - 2 * scale
|
||||
const y2 = rects[0].top + 2 * scale
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawWrongSpacing(x, y1, y2, scale)
|
||||
} else {
|
||||
const y1 = rects[0].bottom
|
||||
const y2 = rects[0].top
|
||||
this.drawMissingText(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale,
|
||||
toInsert.trim()
|
||||
)
|
||||
this.drawMissingText(x, y1, y2, scale, toInsert.trim())
|
||||
}
|
||||
} else if (lengthL + lengthR === replacement.length) {
|
||||
// Something to remove
|
||||
@ -629,19 +603,14 @@ class BesService {
|
||||
const x = (rects[0].left + rects[0].right) / 2
|
||||
const y1 = rects[0].top
|
||||
const y2 = rects[0].bottom
|
||||
this.drawWrongSpacing(
|
||||
x - scrollX,
|
||||
y1 - scrollY,
|
||||
y2 - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawWrongSpacing(x, y1, y2, scale)
|
||||
} else {
|
||||
for (let rect of rects)
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -655,20 +624,20 @@ class BesService {
|
||||
for (let rect of rects) {
|
||||
if (first) {
|
||||
this.drawWrongText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY,
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top,
|
||||
scale,
|
||||
toReplace
|
||||
)
|
||||
first = false
|
||||
} else {
|
||||
this.drawExcessiveText(
|
||||
rect.left - scrollX,
|
||||
rect.bottom - scrollY,
|
||||
rect.right - scrollX,
|
||||
rect.top - scrollY
|
||||
rect.left,
|
||||
rect.bottom,
|
||||
rect.right,
|
||||
rect.top
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -684,19 +653,14 @@ class BesService {
|
||||
const x2 = rect.right
|
||||
const y = rect.bottom
|
||||
const scale = (rect.bottom - rect.top) / 18
|
||||
this.drawAttentionRequired(
|
||||
x1 - scrollX,
|
||||
x2 - scrollX,
|
||||
y - scrollY,
|
||||
scale
|
||||
)
|
||||
this.drawAttentionRequired(x1, x2, y, scale)
|
||||
}
|
||||
|
||||
markerY1 = Math.min(...match.highlights.map(rect => rect.top))
|
||||
markerY2 = Math.max(...match.highlights.map(rect => rect.bottom))
|
||||
}
|
||||
|
||||
this.drawSideMarker(markerY1 - scrollY, markerY2 - scrollY)
|
||||
this.drawSideMarker(markerY1, markerY2)
|
||||
}
|
||||
|
||||
static commonPrefixLength(s1, s2) {
|
||||
@ -872,15 +836,11 @@ class BesService {
|
||||
*/
|
||||
setCorrectionPanelSize() {
|
||||
this.disableMutationObserver()
|
||||
|
||||
const styles = window.getComputedStyle(this.hostElement)
|
||||
const hostRect = this.hostElement.getBoundingClientRect()
|
||||
// Sync margins one by one. Firefox is not happy when syncing all at once.
|
||||
this.scrollPanel.style.marginLeft = styles.marginLeft
|
||||
this.scrollPanel.style.marginTop = styles.marginTop
|
||||
this.scrollPanel.style.marginRight = styles.marginRight
|
||||
this.scrollPanel.style.marginBottom = styles.marginBottom
|
||||
this.scrollPanel.style.boxSizing = styles.boxSizing
|
||||
this.scrollPanel.style.scrollBehavior = styles.scrollBehavior
|
||||
this.textFont = styles.fontFamily
|
||||
|
||||
// Resize canvas if needed.
|
||||
this.canvasPanel.style.width = `${this.hostElement.scrollWidth}px`
|
||||
this.canvasPanel.style.height = `${this.hostElement.scrollHeight}px`
|
||||
const dpr = window.devicePixelRatio
|
||||
@ -895,6 +855,14 @@ class BesService {
|
||||
this.canvasPanel.height = newCanvasHeight
|
||||
this.redrawAllMistakeMarkup()
|
||||
}
|
||||
|
||||
// Note: Firefox is not happy when syncing all margins at once.
|
||||
this.scrollPanel.style.marginLeft = styles.marginLeft
|
||||
this.scrollPanel.style.marginTop = styles.marginTop
|
||||
this.scrollPanel.style.marginRight = styles.marginRight
|
||||
this.scrollPanel.style.marginBottom = styles.marginBottom
|
||||
this.scrollPanel.style.boxSizing = styles.boxSizing
|
||||
this.scrollPanel.style.scrollBehavior = styles.scrollBehavior
|
||||
if (this.isHostElementInline()) {
|
||||
const totalWidth =
|
||||
parseFloat(styles.paddingLeft) +
|
||||
@ -905,9 +873,11 @@ class BesService {
|
||||
this.scrollPanel.style.width = `${totalWidth}px`
|
||||
this.scrollPanel.style.height = styles.height
|
||||
} else {
|
||||
const hostRect = this.hostElement.getBoundingClientRect()
|
||||
this.scrollPanel.style.width = `${hostRect.width}px`
|
||||
this.scrollPanel.style.height = `${hostRect.height}px`
|
||||
}
|
||||
|
||||
this.enableMutationObserver()
|
||||
}
|
||||
|
||||
@ -934,6 +904,7 @@ class BesService {
|
||||
* @param {*} match Grammar checking rule match
|
||||
*/
|
||||
highlightMistake(match) {
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
match.highlights.forEach(rect => {
|
||||
const el = document.createElement('div')
|
||||
el.classList.add('bes-highlight-rect')
|
||||
@ -942,8 +913,8 @@ class BesService {
|
||||
? 'bes-highlight-spelling-rect'
|
||||
: 'bes-highlight-grammar-rect'
|
||||
)
|
||||
el.style.left = `${rect.x + window.scrollX}px`
|
||||
el.style.top = `${rect.y + window.scrollY}px`
|
||||
el.style.left = `${rect.x + canvasPanelRect.x + window.scrollX}px`
|
||||
el.style.top = `${rect.y + canvasPanelRect.y + window.scrollY}px`
|
||||
el.style.width = `${rect.width}px`
|
||||
el.style.height = `${rect.height}px`
|
||||
document.body.appendChild(el)
|
||||
@ -1357,12 +1328,14 @@ class BesTreeService extends BesService {
|
||||
const source = event?.detail !== 1 ? event?.detail : event
|
||||
const el = this.getBlockParent(source.targetElement || source.target)
|
||||
if (!el) return
|
||||
// TODO: Adjust source.clientX and source.clientY for scrolling offset.
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
let x = source.clientX - canvasPanelRect.x
|
||||
let y = source.clientY - canvasPanelRect.y
|
||||
const pointsInRect = []
|
||||
for (let result of this.results) {
|
||||
for (let m of result.matches) {
|
||||
for (let rect of m.highlights) {
|
||||
if (BesService.isPointInRect(source.clientX, source.clientY, rect)) {
|
||||
if (BesService.isPointInRect(x, y, rect)) {
|
||||
pointsInRect.push({ el, match: m })
|
||||
}
|
||||
}
|
||||
@ -2022,12 +1995,14 @@ class BesPlainTextService extends BesService {
|
||||
const source = event?.detail !== 1 ? event?.detail : event
|
||||
const el = source.targetElement || source.target || this.hostElement
|
||||
if (!el) return
|
||||
// TODO: Adjust source.clientX and source.clientY for scrolling offset.
|
||||
const canvasPanelRect = this.canvasPanel.getBoundingClientRect()
|
||||
let x = source.clientX - canvasPanelRect.x
|
||||
let y = source.clientY - canvasPanelRect.y
|
||||
const pointsInRect = []
|
||||
for (let result of this.results) {
|
||||
for (let m of result.matches) {
|
||||
for (let rect of m.highlights) {
|
||||
if (BesService.isPointInRect(source.clientX, source.clientY, rect)) {
|
||||
if (BesService.isPointInRect(x, y, rect)) {
|
||||
pointsInRect.push({ el: result.range, match: m })
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user