draft-js icon indicating copy to clipboard operation
draft-js copied to clipboard

Typing after insertSoftNewline results in extra new lines in Microsoft Edge

Open si13b opened this issue 8 years ago • 7 comments

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/.

  1. Open editor
  2. Type "a"
  3. Press Shift+Return to insert soft new line
  4. Type "b" (note cursor moves to next line)
  5. Type "c" (note cursor moves to next line again)
  6. 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)

si13b avatar Feb 20 '17 05:02 si13b

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.

si13b avatar Mar 07 '17 00:03 si13b

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.

si13b avatar Mar 07 '17 01:03 si13b

We are experiencing the same issue. Do there is a quick fix that can be applied in order to fix this behaviour? Thanks.

OliverNicolini avatar Apr 05 '17 17:04 OliverNicolini

Update: this is still an issue in [email protected]

philippe-git avatar Apr 09 '18 16:04 philippe-git

I've come across this issue in Firefox. Other browsers seem to be fine, including Edge.

v-erse avatar Sep 28 '20 03:09 v-erse

@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.

danieljee avatar Dec 25 '20 11:12 danieljee

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.

hejtmii avatar May 18 '22 21:05 hejtmii