Compare commits

...

7 Commits

Author SHA1 Message Date
bf7b844e1c Same grammar mistake shouldn't be highlighted twice 2025-02-28 12:45:33 +01:00
d990cd061a Update function documentation 2025-02-28 12:42:16 +01:00
51099347f2 Revise scrolling 2025-02-28 12:25:58 +01:00
d246d07d7f <textarea>: Populate text panel content sooner
This makes the text panel contain true content and size earlier at the
registration time.
2025-02-28 11:35:11 +01:00
6b1b46de55 Rename markup drawing methods
This matches what they are doing better.
2025-02-28 11:33:24 +01:00
9c7c967039 Rotate panel names
The new name reflects the purpose of the panel better:

- panelParent → correctionPanel: This is our (0, 0) positioned <div>
  inside which most of the magic happens. We do need it to be able to
  position it's child properly.

- correctionPanel → scrollPanel: This is a <div> which size and
  placement should exactly match the hostElement. We need it to provide
  a scrollable (hence the name) viewport for our canvas.
2025-02-28 11:02:04 +01:00
acd7ac1a2b Cleanup CSS 2025-02-28 10:28:39 +01:00
3 changed files with 230 additions and 182 deletions

View File

@ -8,9 +8,33 @@
<link rel="stylesheet" href="styles.css" />
<script>const besUrl = 'http://localhost:225/api/v2';</script>
<script src="../service.js"></script>
<style>
.mock-resizable {
overflow-x: scroll;
position: relative;
display: inline-block;
border: 1px solid #ccc;
width: 300px;
height: 400px;
border-radius: 3px;
background-color: #f9f9f9;
}
.mock-content {
width: 1000px;
height: 600px;
background-color: #f9f9f9;
}
.mock-flex {
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div class="flex">
<div class="mock-flex">
<div class="mock-content">
<p>Element to delete</p>
<p>Element to delete</p>
@ -18,7 +42,7 @@
<p>Element to delete</p>
<p>Element to delete</p>
</div>
<div class="resizable">
<div class="mock-resizable">
<div class="my-block my-control bes-service" contenteditable="true">
<p>Tukaj vpišite besedilo ki ga želite popraviti.</p>
<p>Prišla je njena lepa hčera. Smatram da tega nebi bilo potrebno storiti. Predavanje je trajalo dve ure. S njim grem v Kamnik. Janez jutri nebo prišel. Prišel je z 100 idejami.</p>

View File

@ -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()
}
/**
@ -198,7 +201,7 @@ class BesService {
*/
setMarkupStyle(style) {
this.markupStyle = style
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
}
/**
@ -354,17 +357,19 @@ class BesService {
}
/**
* Creates grammar mistake markup in DOM and populates collection of highlight rectangles.
* Draws grammar mistake markup on canvas and populates collection of highlight rectangles.
*
* @param {*} match Grammar checking rule match
*/
addMistakeMarkup(match) {
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,36 +653,22 @@ 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)
}
static commonPrefixLength(s1, s2) {
let i = 0
let len = Math.min(s1.length, s2.length)
while (i < len && s1[i] === s2[i]) i++
return i
}
static commonSuffixLength(s1, s2) {
let i = 0
let i1 = s1.length
let i2 = s2.length
while (0 < i1-- && 0 < i2-- && s1[i1] === s2[i2]) i++
return i
this.drawSideMarker(markerY1, markerY2)
}
/**
* Draws the marker that helps visualize lines of text where grammar mistakes were detected
*
* @param {Number} y1 Marker top [px]
* @param {Number} y2 Marker bottom [px]
*/
drawSideMarker(y1, y2) {
const dpr = window.devicePixelRatio
const markerX = this.canvasPanel.width - 5 * dpr
@ -723,6 +678,14 @@ class BesService {
this.ctx.stroke()
}
/**
* Draws the missing comma sign
*
* @param {Number} x Sign center [px]
* @param {Number} y Sign bottom [px]
* @param {Number} scale Sign scale
* @param {String} comment Text to display above the marker
*/
drawMissingComma(x, y, scale, comment) {
const dpr = window.devicePixelRatio
this.ctx.beginPath()
@ -739,6 +702,14 @@ class BesService {
}
}
/**
* Draws the wrong spacing sign. Control direction of chevrons by reversing y1 and y2.
*
* @param {Number} x Sign center [px]
* @param {Number} y1 Sign top/bottom [px]
* @param {Number} y2 Sign bottom/top [px]
* @param {Number} scale Sign scale
*/
drawWrongSpacing(x, y1, y2, scale) {
const dpr = window.devicePixelRatio
this.ctx.beginPath()
@ -753,6 +724,14 @@ class BesService {
this.ctx.stroke()
}
/**
* Strikes out the excessive text
*
* @param {Number} x1 Strike line start X [px]
* @param {Number} y1 Strike line start Y [px]
* @param {Number} x2 Strike line end X [px]
* @param {Number} y2 Strike line end Y [px]
*/
drawExcessiveText(x1, y1, x2, y2) {
const dpr = window.devicePixelRatio
this.ctx.beginPath()
@ -761,6 +740,16 @@ class BesService {
this.ctx.stroke()
}
/**
* Strikes out the text and draws the replacement text above
*
* @param {Number} x1 Strike line start X [px]
* @param {Number} y1 Strike line start Y [px]
* @param {Number} x2 Strike line end X [px]
* @param {Number} y2 Strike line end Y [px]
* @param {Number} scale Sign scale
* @param {String} text Text to display above
*/
drawWrongText(x1, y1, x2, y2, scale, text) {
const dpr = window.devicePixelRatio
this.ctx.beginPath()
@ -785,6 +774,15 @@ class BesService {
)
}
/**
* Draws the sign some text is missing
*
* @param {Number} x Sign center [px]
* @param {Number} y1 Sign bottom [px]
* @param {Number} y2 Sign top [px]
* @param {Number} scale Sign scale
* @param {String} text Text to display above
*/
drawMissingText(x, y1, y2, scale, text) {
const dpr = window.devicePixelRatio
this.ctx.beginPath()
@ -811,6 +809,14 @@ class BesService {
)
}
/**
* Draws zig-zag line
*
* @param {Number} x1 Sign left [px]
* @param {Number} x2 Sign right [px]
* @param {Number} y Sign baseline [px]
* @param {Number} scale Sign scale
*/
drawAttentionRequired(x1, x2, y, scale) {
const dpr = window.devicePixelRatio
this.ctx.beginPath()
@ -824,6 +830,35 @@ class BesService {
this.ctx.stroke()
}
/**
* Calculates common string prefix length
*
* @param {String} s1 First string
* @param {String} s2 Second string
* @returns Number of characters the beginnings of the strings are equal
*/
static commonPrefixLength(s1, s2) {
let i = 0
let len = Math.min(s1.length, s2.length)
while (i < len && s1[i] === s2[i]) i++
return i
}
/**
* Calculates common string suffix length
*
* @param {String} s1 First string
* @param {String} s2 Second string
* @returns Number of characters the endings of the strings are equal
*/
static commonSuffixLength(s1, s2) {
let i = 0
let i1 = s1.length
let i2 = s2.length
while (0 < i1-- && 0 < i2-- && s1[i1] === s2[i2]) i++
return i
}
/**
* Tests if given coordinate is inside of a rectangle.
*
@ -840,21 +875,21 @@ class BesService {
* Creates auxiliary DOM elements for text adornments.
*/
createCorrectionPanel() {
this.panelParent = document.createElement('div')
this.panelParent.classList.add('bes-correction-panel-parent')
this.correctionPanel = document.createElement('div')
this.correctionPanel.classList.add('bes-correction-panel')
this.scrollPanel = document.createElement('div')
this.scrollPanel.classList.add('bes-scroll-panel')
this.canvasPanel = document.createElement('canvas')
this.canvasPanel.classList.add('bes-canvas')
this.ctx = this.canvasPanel.getContext('2d')
this.ctx.scale(1, 1)
this.panelParent.appendChild(this.correctionPanel)
this.correctionPanel.appendChild(this.canvasPanel)
this.correctionPanel.appendChild(this.scrollPanel)
this.scrollPanel.appendChild(this.canvasPanel)
this.textElement.parentElement.insertBefore(
this.panelParent,
this.correctionPanel,
this.textElement
)
this.setCorrectionPanelSize()
@ -864,7 +899,7 @@ class BesService {
* Clears auxiliary DOM elements for text adornments.
*/
clearCorrectionPanel() {
this.panelParent.remove()
this.correctionPanel.remove()
}
/**
@ -872,15 +907,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.correctionPanel.style.marginLeft = styles.marginLeft
this.correctionPanel.style.marginTop = styles.marginTop
this.correctionPanel.style.marginRight = styles.marginRight
this.correctionPanel.style.marginBottom = styles.marginBottom
this.correctionPanel.style.boxSizing = styles.boxSizing
this.correctionPanel.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
@ -893,8 +924,16 @@ class BesService {
) {
this.canvasPanel.width = newCanvasWidth
this.canvasPanel.height = newCanvasHeight
this.repositionAllMarkup()
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) +
@ -902,12 +941,14 @@ class BesService {
parseFloat(styles.width) +
parseFloat(styles.marginRight) +
parseFloat(styles.paddingRight)
this.correctionPanel.style.width = `${totalWidth}px`
this.correctionPanel.style.height = styles.height
this.scrollPanel.style.width = `${totalWidth}px`
this.scrollPanel.style.height = styles.height
} else {
this.correctionPanel.style.width = `${hostRect.width}px`
this.correctionPanel.style.height = `${hostRect.height}px`
const hostRect = this.hostElement.getBoundingClientRect()
this.scrollPanel.style.width = `${hostRect.width}px`
this.scrollPanel.style.height = `${hostRect.height}px`
}
this.enableMutationObserver()
}
@ -929,11 +970,12 @@ class BesService {
}
/**
* Removes previously highlighted grammar mistake and highlights new one.
* Highlights given grammar mistake.
*
* @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 +984,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)
@ -975,12 +1017,12 @@ class BesService {
}
/**
* Updates all grammar mistake markup positions.
* Redraws all grammar mistake markup.
*/
repositionAllMarkup() {
redrawAllMistakeMarkup() {
this.ctx.clearRect(0, 0, this.canvasPanel.width, this.canvasPanel.height)
this.results.forEach(result => {
result.matches.forEach(match => this.addMistakeMarkup(match))
result.matches.forEach(match => this.drawMistakeMarkup(match))
})
}
@ -1136,7 +1178,7 @@ class BesTreeService extends BesService {
),
match: match
}
this.addMistakeMarkup(m)
this.drawMistakeMarkup(m)
matches.push(m)
})
this.markProofed(node, matches)
@ -1221,7 +1263,7 @@ class BesTreeService extends BesService {
this.results = this.results.filter(
result => !BesTreeService.isSameParagraph(result.element, el)
)
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
}
/**
@ -1357,12 +1399,16 @@ class BesTreeService extends BesService {
const source = event?.detail !== 1 ? event?.detail : event
const el = this.getBlockParent(source.targetElement || source.target)
if (!el) return
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 })
break
}
}
}
@ -1452,7 +1498,7 @@ class BesDOMService extends BesTreeService {
*/
onInput() {
// Now that the text is done changing, we can correctly calculate markup position.
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
this.dismissPopup()
// Defer grammar-checking to reduce stress on grammar-checking server.
this.scheduleProofing(1000)
@ -1534,7 +1580,7 @@ class BesCKService extends BesTreeService {
// element, it will not be updated immediately.
setTimeout(() => {
// Now that the text is done changing, we can correctly calculate markup position.
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
// Defer grammar-checking to reduce stress on grammar-checking server.
this.scheduleProofing(1000)
@ -1701,7 +1747,7 @@ class BesQuillService extends BesTreeService {
this.clearProofing(domElement)
setTimeout(() => {
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
this.scheduleProofing(1000)
}, 0)
}
@ -1887,7 +1933,7 @@ class BesPlainTextService extends BesService {
),
match: match
}
this.addMistakeMarkup(m)
this.drawMistakeMarkup(m)
matches.push(m)
})
this.markProofed(paragraphRange, matches)
@ -1978,7 +2024,7 @@ class BesPlainTextService extends BesService {
this.results = this.results.filter(
result => !BesPlainTextService.isSameParagraph(result.range, range)
)
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
}
/**
@ -2021,12 +2067,16 @@ class BesPlainTextService extends BesService {
const source = event?.detail !== 1 ? event?.detail : event
const el = source.targetElement || source.target || this.hostElement
if (!el) return
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 })
break
}
}
}
@ -2146,7 +2196,7 @@ class BesDOMPlainTextService extends BesPlainTextService {
delete this.textBeforeChange
// Now that the text is done changing, we can correctly calculate markup position.
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
this.dismissPopup()
// Defer grammar-checking to reduce stress on grammar-checking server.
this.scheduleProofing(1000)
@ -2224,9 +2274,6 @@ class BesTAService extends BesPlainTextService {
*/
constructor(hostElement, eventSink) {
super(hostElement, BesTAService.createTextElement(hostElement), eventSink)
this.textElement.replaceChildren(
document.createTextNode(this.hostElement.value)
)
}
/**
@ -2266,6 +2313,7 @@ class BesTAService extends BesPlainTextService {
static createTextElement(hostElement) {
const textElement = document.createElement('div')
textElement.classList.add('bes-text-panel')
textElement.replaceChildren(document.createTextNode(hostElement.value))
BesTAService.setTextElementSize(hostElement, textElement)
hostElement.parentNode.insertBefore(textElement, hostElement)
return textElement
@ -2415,7 +2463,7 @@ class BesTAService extends BesPlainTextService {
})
// Now that the text is done changing, we can correctly calculate markup position.
this.repositionAllMarkup()
this.redrawAllMistakeMarkup()
// Defer grammar-checking to reduce stress on grammar-checking server.
this.scheduleProofing(1000)

View File

@ -22,14 +22,8 @@
background: rgb(255, 115, 0);
}
.bes-canvas {
position: relative;
z-index: 3;
cursor: text;
}
/* Styles required to ensure full functionality and optimal user experience. */
.bes-correction-panel-parent {
.bes-correction-panel {
position: relative;
overflow: visible;
float: left;
@ -40,7 +34,7 @@
z-index: 1;
}
.bes-correction-panel {
.bes-scroll-panel {
position: relative;
overflow: hidden;
border-color: transparent;
@ -48,6 +42,12 @@
pointer-events: none;
}
.bes-canvas {
position: relative;
z-index: 3;
cursor: text;
}
.bes-text-panel {
position: absolute;
overflow: hidden;
@ -56,27 +56,3 @@
border-color: transparent;
background: none;
}
/* TODO: Styles below should be removed after testing period is over */
.resizable {
overflow-x: scroll;
position: relative;
display: inline-block;
border: 1px solid #ccc;
width: 300px;
height: 400px;
border-radius: 3px;
background-color: #f9f9f9;
}
.mock-content {
width: 1000px;
height: 600px;
background-color: #f9f9f9;
}
.flex {
display: flex;
justify-content: center;
align-items: center;
}