Alex-D / Trumbowyg

A lightweight and amazing WYSIWYG JavaScript editor under 10kB
https://alex-d.github.io/Trumbowyg
MIT License
3.99k stars 612 forks source link

When 'semantic' is true, content pasted at 'end' of editor forces new line #449

Closed rogerlos closed 7 years ago

rogerlos commented 7 years ago

Firefox 50.0.1, Windows 10, 3280 x 1900

Reproduce by ensuring semantic is true and removeFormatPasted is true.

The editor on-screen will show an apparent successful paste, with the caret at the end of the line. As soon as you start typing, your cursor will jump to a new line and all text will appear there.

When examining .html() on the tbwpaste action, the editor seems to be wrapping the "final" content with <p> tags automatically, though it was not so-wrapped before pasting. The caret is probably just outside the </p>, despite it appearing to be on the same line to the user.

When the user continues typing, a non-breaking space &nbsp; is inserted before the caret, along with a <br> tag after the caret.

(An enhancement would be for trumbowyg to pass the content it pastes to the tbwpaste action.)

This does not seem to happen when content is pasted into the middle of an existing text block.

Alex-D commented 7 years ago

Too tricky, sorry :/

Caret position bugs are hard to resolve in Trumbowyg.

rogerlos commented 7 years ago

In case you're curious, this root of this issue seems to be that for pasted content in the editor, "range" does not work as expected. Pasting creates a new offset of "1" as the pasted content is wrapped in something by the browser (at least FF). So any trumbowyg functions which rely on range at that instant are going to be wonky.

In the function semanticCode, trumboqyg always wrap everythings in paragraph tags as a result, as the detection of the "working" final content doesn't work.

In addition, semanticCode seems to be called twice, once on the timeout function at the end of the past handler, and once when you use execCommand() to insert the text.

I was able to get around the "new paragraph on paste" problem by commenting out the call in the timeout function, and changing the parameters of the call in execCmd to t.semanticCode( false, false );. Probably not the best solution, but it works, I guess.

Playing around a bit, when trumbowyg is working correctly, range.anchorNode is always a text node when getting the range. When it's not, it's because range.anchorNode is the editor itself (this happens on paste). Using a caret detector like http://jsfiddle.net/TjXEG/900/ does always return the correct position of the caret, so maybe a simply comparison of the range start to that value might help.

Thanks for the plugin, otherwise working pretty nicely.

Alex-D commented 7 years ago

Thanks for your feedback :)