draft-js
draft-js copied to clipboard
Typing after insertSoftNewline results in extra new lines in Microsoft Edge
Do you want to request a feature or report a bug? Bug
What is the current behavior? In Microsoft Edge (tested 14), typing new text into the editor immediately after inserting a soft newline will cause repeated new softlines to be inserted after each subsequent key press.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. You can use this jsfiddle to get started: https://jsfiddle.net/stopachka/m6z0xn4r/.
- Open editor
- Type "a"
- Press Shift+Return to insert soft new line
- Type "b" (note cursor moves to next line)
- Type "c" (note cursor moves to next line again)
- Type "d" (note cursor moves to next line again) etc
Outcome:
a
b
c
d
https://jsfiddle.net/m6z0xn4r/148/
What is the expected behavior?
Expected:
a
bcd
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js? Tested on 0.7.0 (in jsfiddle) and 0.10 (locally). Microsoft Edge 14 (Windows 10)
I've narrowed down the issue to editOnInput.js. This file compares the "modelText" with the "domText" after user input. If they match then nothing further occurs, otherwise it corrects the selection.
In the case of Edge, there seems to be an extra new line character at the end of the "domText" that isn't present in the "modelText". I suspect this is related to the issue.
It seems like a browser quirk. Between the setImmediate call in editOnBeforeInput and editOnInput (i.e. where the native behaviour happens), an extra line break is getting into the DOM that doesn't exist in our model.
We are experiencing the same issue. Do there is a quick fix that can be applied in order to fix this behaviour? Thanks.
Update: this is still an issue in [email protected]
I've come across this issue in Firefox. Other browsers seem to be fine, including Edge.
@a6h-s I've seen similar behaviour on Firefox as well. Typing a character after a soft new line will create another soft new line.
Hi guys, here is some info I collected during debugging to expand on what was already said:
There is an extra code in editor rendering that makes \n into \n\n at the end of the block
https://github.com/facebook/draft-js/blob/main/src/component/contents/DraftEditorLeaf.react.js#L143
// If the leaf is at the end of its block and ends in a soft newline, append
// an extra line feed character. Browsers collapse trailing newline
// characters, which leaves the cursor in the wrong place after a
// shift+enter. The extra character repairs this.
if (text.endsWith('\n') && this.props.isLast) {
text += '\n';
}
The editOnInput handler is supposed to handle it here
https://github.com/facebook/draft-js/blob/main/src/component/handlers/edit/editOnInput.js#L129
// Special-case soft newlines here. If the DOM text ends in a soft newline,
// we will have manually inserted an extra soft newline in DraftEditorLeaf.
// We want to remove this extra newline for the purpose of our comparison
// of DOM and model text.
if (domText.endsWith(DOUBLE_NEWLINE)) {
domText = domText.slice(0, -1);
}
BUT ...
Since the default is not prevented in editOnBeforeInput
https://github.com/facebook/draft-js/blob/main/src/component/handlers/edit/editOnBeforeInput.js#L238
The DOM text node already gets the updated text Something\nX\n where X is the newly typed character
Having said that, editOnInput fails to pass its DOUBLE_NEWLINE condition and just leaves the DOM the way it become
As for the fix, I am thinking about adding another condition to set mustPreventNative to true when in this specific scenario
https://github.com/facebook/draft-js/blob/main/src/component/handlers/edit/editOnBeforeInput.js#L161
Something like mustPreventNative = isSelectionAtBlockEndWithNewLine(editor._latestCommittedEditorState); to execute only for this very specific case, as most of the usual typing happens at the end of the block so we keep most of the native functionality intact.