Refactor replaceText function for improved compatibility with CKEditor instances

This commit is contained in:
Aljaž Grilc 2024-03-14 12:01:43 +01:00
parent 87c7f79ebe
commit 82a86725eb
2 changed files with 10 additions and 29 deletions

View File

@ -9,7 +9,8 @@
</head> </head>
<body> <body>
<div id="editor"> <div id="editor">
<p>Na mizo nisem položil knjigo.</p> <!-- <p>Na mizo nisem položil knjigo.</p> -->
<p>Na mizo nisem položil <b>knjigo</b>.</p>
</div> </div>
<bes-popup-el></bes-popup-el> <bes-popup-el></bes-popup-el>
<script> <script>

View File

@ -520,7 +520,6 @@ class BesService {
popup.hide() popup.hide()
} }
// TODO: In rich HTML texts, match.offset has different value than in plain text.
// This function should be able to handle both cases or find a way that works for both. // This function should be able to handle both cases or find a way that works for both.
replaceText(el, match, replacement) { replaceText(el, match, replacement) {
if (this.timer) clearTimeout(this.timer) if (this.timer) clearTimeout(this.timer)
@ -622,37 +621,18 @@ class BesCKService extends BesService {
}) })
} }
// TODO: In rich HTML texts, match.offset has different value than in plain text.
// This function should be able to handle both cases or find a way that works for both. // This function should be able to handle both cases or find a way that works for both.
replaceText(el, match, replacement) { replaceText(el, match, replacement) {
if (this.timer) clearTimeout(this.timer)
this.abortController.abort()
const { ckEditorInstance } = this const { ckEditorInstance } = this
const viewRange = ckEditorInstance.editing.view.domConverter.domRangeToView(
match.range
)
const modelRange = ckEditorInstance.editing.mapper.toModelRange(viewRange)
ckEditorInstance.model.change(writer => { ckEditorInstance.model.change(writer => {
const viewElement = const attributes =
ckEditorInstance.editing.view.domConverter.mapDomToView(el) ckEditorInstance.model.document.selection.getAttributes()
const modelElement = writer.remove(modelRange)
ckEditorInstance.editing.mapper.toModelElement(viewElement) writer.insertText(replacement, attributes, modelRange.start)
if (modelElement) {
const elementRange = writer.createRangeIn(modelElement)
// TODO: This logic should work once the HTML tags are removed from match.match.offset and match.match.length if is possible.
if (
elementRange.start.offset <= match.match.offset &&
elementRange.end.offset >= match.match.offset + match.match.length
) {
const start = writer.createPositionAt(
modelElement,
match.match.offset
)
const end = writer.createPositionAt(
modelElement,
match.match.offset + match.match.length
)
const range = writer.createRange(start, end)
writer.remove(range)
writer.insertText(replacement, start)
}
}
}) })
this.clearMistakeMarkup(el) this.clearMistakeMarkup(el)
// In my opinion, this approach provides the most straightforward solution for repositioning mistakes after a change. // In my opinion, this approach provides the most straightforward solution for repositioning mistakes after a change.