Conversation
Should hopefully prevent overly long non-ASCII messages from
getting eaten during send attempts.
Seems like the current implementation could have worked with
a bit more space in buf (enough to fit the next largest UTF-8
character) and comparing `written` instead of `read` as `read`
is in UTF-16 code units instead of bytes, but it still has
weird behavior when the caret is not at the end of the string
(on regular input it's forced to the end, if you paste
something the existing text at the end gets cut off if the
entire string is too long).
The behavior of the built-in `maxlength` attribute is not very
consistent across browsers: if the user attempts to replace
currently selected text and not even one character from the
replacement string fits, Firefox preserves the selection while
Chromium discards it instead. This implementation discards the
selection.
Shortcoming: hitting the length limit breaks undo (does nothing).
(This is a problem with the current implementation as well, it's
just a bit more hidden as ASCII inputs get properly constrained
via HTML `maxlength`.)
Test code:
// "|" is the caret
const tests = [
// below the byte limit, unchanged
"🐱|", "🐱",
"あい|", "あい",
"abc🐱|", "abc🐱",
"abcdあ|", "abcdあ",
"abcdefg|", "abcdefg",
// above the byte limit, truncated
"abcdefgh|", "abcdefg",
"あabcde|", "あabcd",
"abcdeあ|", "abcde",
"abcd🐱|", "abcd",
"あいう|", "あい",
"🐱🦈|", "🐱",
// above the byte limit, caret in the middle of the string
"abcd|efgh", "abcefgh",
"あb|cdef", "あcdef",
"abc|deあ", "abdeあ",
"abc|d🐱", "abd🐱",
"あい|う", "あう",
"🐱|🦈", "🦈",
];
const cbl = constrainByteLength(7);
for (let i = 0; i < tests.length; i += 2) {
const sel = tests[i].indexOf('|');
console.assert(sel >= 0, `no caret in ${tests[i]}`);
const inVal = tests[i].substring(0, sel) + tests[i].substring(sel+1);
const event = {target: {value: inVal, selectionStart: sel, selectionEnd: sel}};
cbl(event);
const actual = event.target.value, expected = tests[i+1];
console.assert(expected === actual, `expected ${expected}, got ${actual}`);
}
|
I can help testing with this on another platform, please wait a little while |
|
i tested your test snippet on several platform
Manual test on macOS Chrome + Japanese IME, (haven't tested anything else yet, sorry
this seems related to IME composition: many
With these additions, IME input and normal typing both remain within the 150 UTF-8 byte limit across the tested environments. displaying the current UTF-8 byte count as an indicator in the chat box could also improve the overall UX. i will experiment with this on my side when once your implementation is finalized. |
True; As for limiting right before sending: I was not able to find a case where it was needed after adding a handler for
I think doing this and letting the user freely exceed the limit (but prevent them from submitting if text is too long) is a much better idea than the current approach of emulating HTML |
ba5ebf3 to
26a1c69
Compare
that makes sence, it does seem somewhat redundant after adding the compositionend handler.
yes in that case, would it be okay if we merge this PR first so that the current design is completed as intended?
Okay, after that, i will then triage it as a separate issue for UX improvements and additional feature implementation. |
Might require more testing; I have run the tests on Firefox and Chromium and tested the input manually with Firefox (and IME input with Mozc on Linux) but have not tested on other platforms.
Should hopefully prevent overly long non-ASCII messages from getting eaten during send attempts.
Seems like the current implementation as present in
mastercould have worked with a bit more space inbuf(enough to fit the next largest UTF-8 character) and comparingwritteninstead ofreadasreadis in UTF-16 code units instead of bytes, but it still has weird behavior when the caret is not at the end of the string (on regular input it's forced to the end; if you paste something and the entire string is too long the existing text at the end gets cut off).The behavior of the built-in
maxlengthattribute is not very consistent across browsers: if the user attempts to replace currently selected text and not even one character from the replacement string fits, Firefox preserves the selection while Chromium discards it instead. This implementation discards the selection.Shortcoming: hitting the length limit breaks undo (does nothing). (This is a problem with the current implementation as well, it's just a bit more hidden as ASCII inputs get properly constrained via HTML
maxlength.)Test code