-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should the last beforeinput to occur before compositionend be cancellable? #134
Comments
One of the reasons you cited, @masayuki-nakano, is that the author would need to implement undo/redo themselves if they were to use the approach I suggested here. As far as I know, however, if the author is using script to insert the composition text themselves, no matter the mechanism they used to remove or prevent the composed text from being inserted into the DOM, the author will need to implement undo and redo themselves since scripted changes to the DOM are not undoable. Could you clarify the scenario you'd like to make work? |
Just want to express a strong 'in favor'. I do want to note however that I am confused by
As my understanding would be that this wouldn't account for recomposition. So, initial state is "The homme is large". Then the user clicks into 'homme', so we have "The hom|me is large" (| = cursor, and italics is the active recomposition zone). One of the text suggestions is next, 'hommels', so they press it, thus the text changes to "The hommels is large" and once you hit space "The hommels is large". I once again forgot (I look at this about once per 3 months 😅🤓) exactly when composition starts and ends in that process, but deleting the last targeted range wouldn't result back in "The homme is large", but probably in "The is large". |
Oh, I didn't realize cc'ed, sorry (and anyway I don't have much time to check widely due to not good condition after 3rd vaccination). There is a scenario, yes. Traditionally, Gecko used a set of composition events to represent text input which is not simply comes from keyboard event. For example, one key press inputs multiple characters on Linux and macOS or text input without keyboard, e.g., choosing one of accented character from a popup on macOS. Then, However, we got a bug report that such input is not cancelable from This means that the applications which hit this compatibility issue are not aware of IME because text input caused by IME composition is not cancelable only with FYI: see also w3c/uievents#202. The issue does not directly related to this, but web apps cannot know composition commit timing with What I'd like to say is, current |
Why can't we just implement the |
Basically, |
I would counter that |
Yes, it is. And some web apps may not support Safari/WebKit especially when they are available only with specific browsers like web apps in intranet. Spec changes should not accept any potential backward compatibility risk. |
I think you're too worried about a hypothetical case. InputEvents spec already introduced many new inputTypes to I'll defer to whatever the spec editors decide, but I would prefer more parity with Lvl 2 over supporting quirky web apps. |
@masayuki-nakano Using that logic, no browser can ever change anything about execCommand or contenteditable - yet they all are. I agree with @Azmisov that implementing level 2 everywhere would be the best solution seen from the perspective of a web developer. The reason why we cannot do that is that apparently there is something in Android IME that is beyond the control of the Chrome developers we are talking to that makes it impossible to implement these events on Android and therefore the Chrome team has decided that they will not implement some specific parts of level 2 even on desktop. It severely cripples the specification, but there should hopefully be some relief with |
Different from I wonder, is there a reason why it should not make the last |
I've been thinking about this, and I think it may be fine if
Otherwise, assume the standard Lvl 2 spec events may/may not fire prior to div.addEventListener("beforeinput", e => {
e.preventDefault();
if (e.defaultPrevented){
// switch statement with all lvl 2 cancelable inputType's
switch (e.inputType){
case "insertText":
// insert manually ...
break;
// ... all other lvl 2 cancelable inputType's here ...
// e.g. not including insertCompositionText since uncancelable in all browsers
default:
throw Error("unexpected event was prevented")
}
}
}); This code would break if we added any additional Can we discuss what exactly "deleting the composition text" will do? The spec doesn't go into details for what the Firefox:
(type) <b>text te</b><i>ex|</i> → <b>text <i>teext|</i></b><i></i>
(type) <span class='b'>text te</span><span class='i'>ex|</span> → <span class='b'>text teext|</span><span class='i'></span>
(type) text te<u>ex| text</u> → text <u>teext| text</u>
Chrome:
(type) <b>text te</b><i>ex|</i> → <b>text te</b><i>ext|</i>
(autocomplete) <b>text te</b><i>ext|</i> → <b>text texted |</b>
(type) <span class='b'>text te</span><span class='i'>ex|</span> → <span class='b'>text te</span><span class='i'>ext|</span>
(autocomplete) <span class='b'>text te</span><span class='i'>ex|</span> → <span class='b'>text texted </span>
(autocomplete) text te<u>ex| text</u> → text texted|<u> text</u> Notice that composition events will delete elements, delete text nodes, leave elements empty, create new elements, and move text to different elements. If you'd like to test yourself, I've made Input Events Tester site to see how different browsers manipulate the DOM. I really think that "deleting the composition text" should actually revert the DOM to its state at the beginning of composition. The target ranges (either for Of course, reverting the DOM just acts to encapsulate the composition edits. While composition is happening, you'll still get whatever edits the browser applies, and unfortunately it looks like we need to wait for EditContext or other API to be able to prevent that fully. E.g. If writing a code editor, the syntax highlighting won't work with compositions, since browser will combine the text with the styles of previous identifiers/variables/etc. However, I have discovered a workaround to allow some degree of limited control for what style the browser applies: You can prepend a zero-width unicode space (u200B) to your styled element. Visually you won't see anything, but the space breaks up the IME composition so it is restricted to a single text node. This wouldn't work for IME's that operate across spaces though (if such a thing exists). I think in addition to reverting the DOM as described above, I think the last thing needed to cleanly implement editors is some way to control the bounds of composition. That way, the jankiness in composing+reverting can be minimized. For example, if I have a So the purpose is not necessarily to control the exact text that is entered, but more the DOM structure around that text. I'll elaborate here that The usage flow would be like so: Listen to CodeMirror is a good example of a widely used library that would benefit from this. Try typing TLDR; That's a lot of talking, so here's a summary of what I'm proposing:
|
@masayuki-nakano suggests that the last
beforeinput
event to occur beforecompositionend
should be cancellable in this comment. Cancelling thebeforeinput
event would remove the composed text instead of committing it to the DOM.Creating this issue to discuss whether this should be the case.
The text was updated successfully, but these errors were encountered: