diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 7a9bb4c68c..775e7a01f4 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -390,9 +390,13 @@ export function sanitizeEditableContent(element: any, cleanLineBreaks: boolean =
selection.removeAllRanges();
selection.addRange(range);
- for (let i = 0; i < innerText.length - tail_len; i++) {
- (selection as any).modify("move", "forward", "character");
+ while (selection.toString().length < innerText.length - tail_len) {
+ const selLen = selection.toString().length;
+ (selection as any).modify("extend", "forward", "character");
+ if (selection.toString().length == selLen) break;
}
+ range = selection.getRangeAt(0);
+ range.setStart(range.endContainer, range.endOffset);
}
}
function mergeValues(src: any, dest: any) {
diff --git a/tests/utilstests.ts b/tests/utilstests.ts
index 81f7f55e04..d218c264a2 100644
--- a/tests/utilstests.ts
+++ b/tests/utilstests.ts
@@ -16,14 +16,15 @@ function checkSanitizer(element, text, selectionNodeIndex, selectionStart, clean
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
-
sanitizeEditableContent(element, cleanLineBreaks);
- const newSelection = document.getSelection();
+ const range = document.getSelection().getRangeAt(0);
+ if (element.childNodes.length > 0) range.setStart(element.childNodes[0], 0);
return {
text: element.innerHTML,
plainText: element.innerText,
- offset: newSelection.getRangeAt(0).startOffset,
- nodeText: newSelection.getRangeAt(0).startContainer.textContent
+ position: selection?.toString().length,
+ offset: range.endOffset,
+ nodeText: range.endContainer.textContent
};
}
QUnit.test(
@@ -70,6 +71,10 @@ QUnit.test(
assert.equal(res.offset, 2);
assert.equal(res.nodeText, "some");
+ var res = checkSanitizer(element, "some
text
", 3, 0, false);
+ assert.equal(res.plainText, "some\ntext\n\n");
+ assert.equal(res.position, 10);
+
var res = checkSanitizer(element, "some
text
and more", 2, 3, false);
assert.equal(res.plainText, "some\ntext\nand more");
assert.equal(res.offset, 3);
@@ -79,6 +84,34 @@ QUnit.test(
}
);
+QUnit.test(
+ "utils: sanitizer with grapheme clusters",
+ function (assert) {
+ var element: HTMLSpanElement = document.createElement("span");
+ document.body.appendChild(element);
+ element.contentEditable = "true";
+
+ var res = checkSanitizer(element, "พุธ", 0, 2, false);
+ assert.equal(res.plainText.length, 3);
+ assert.equal(res.plainText, "พุธ");
+ assert.equal(res.offset, 2);
+ assert.equal(res.nodeText, "พุธ");
+
+ var res = checkSanitizer(element, "sพุธe", 0, 3, false);
+ assert.equal(res.plainText.length, 5);
+ assert.equal(res.plainText, "sพุธe");
+ assert.equal(res.offset, 3);
+ assert.equal(res.nodeText, "sพุธe");
+
+ var res = checkSanitizer(element, "พุธs
พุธe", 2, 2, false);
+ assert.equal(res.plainText, "พุธs\nพุธe");
+ assert.equal(res.offset, 2);
+ assert.equal(res.nodeText, "พุธe");
+
+ element.remove();
+ }
+);
+
export function createIActionArray(count: number): Array {
let result: Array = [];
for (let index = 0; index < count; ++index) {