LibWeb: Convert Editing API internals to UTF-16

Both sides of the Editing internals now have to deal with some awkward
converting between UTF-8 and UTF-16, but the upside is that it
immediately exposed an issue with the `insertText` command: instead of
dealing with code units, it was iterating over code points causing the
selection to be updated only once instead of twice. This resulted in the
final selection potentially ending up in between a surrogate pair.

Fixes #5547 (pasting/typing surrogate pairs).
This commit is contained in:
Jelle Raaijmakers
2025-07-23 11:43:21 +02:00
committed by Tim Flynn
parent 9a03ee1c24
commit e029e785d2
Notes: github-actions[bot] 2025-07-24 11:19:43 +00:00
8 changed files with 277 additions and 250 deletions

View File

@@ -3,17 +3,29 @@
<div contenteditable="true">foobar</div>
<script>
test(() => {
const selection = getSelection();
const reportSelection = () => {
if (selection.rangeCount === 0) {
println('No range.');
return;
}
const range = selection.getRangeAt(0);
println(`${range.startContainer.nodeName} ${range.startOffset} - ${range.endContainer.nodeName} ${range.endOffset}`);
};
var divElm = document.querySelector('div');
divElm.addEventListener('input', (e) => println('input triggered'));
// Put cursor between 'foo' and 'bar'
var range = document.createRange();
getSelection().addRange(range);
range.setStart(divElm.childNodes[0], 3);
range.setEnd(divElm.childNodes[0], 3);
selection.setBaseAndExtent(divElm.childNodes[0], 3, divElm.childNodes[0], 3);
// Insert text
document.execCommand('insertText', false, 'baz');
reportSelection();
// Insert Unicode
document.execCommand('insertText', false, '🙂');
reportSelection();
println(divElm.innerHTML);
});