NEW 39801
REGRESSION (r45962): Pasted newlines are stripped on form submit at paste.nerv.fi
https://bugs.webkit.org/show_bug.cgi?id=39801
Summary REGRESSION (r45962): Pasted newlines are stripped on form submit at paste.ner...
Ojan Vafai
Reported 2010-05-26 18:08:40 PDT
1. Paste text with newlines. 2. Press the "Laheta" button" The newlines get stripped. If you typing in text with newlines, they don't get stripped. Tested on WebKit nightly Mac and Chrome 6.0.408.1 (Official Build 47574) dev.
Attachments
Patch (244.06 KB, patch)
2010-06-03 12:25 PDT, Ojan Vafai
no flags
attempt to preserve newlines (8.27 KB, patch)
2010-06-04 00:11 PDT, Shinichiro Hamaji
ojan: review-
Alexey Proskuryakov
Comment 1 2010-05-28 13:12:59 PDT
Works in Safari/WebKit 4.0.5, fails in r60308.
Alexey Proskuryakov
Comment 2 2010-05-28 13:14:13 PDT
Ojan Vafai
Comment 3 2010-05-28 14:02:06 PDT
Regression range: 45980:46042
Alexey Proskuryakov
Comment 4 2010-05-28 14:30:57 PDT
My testing says it's r45962.
Ojan Vafai
Comment 5 2010-05-28 17:09:48 PDT
Got into this in a debugger. The problem is that we now propagate the white-space:no-wrap. On paste, we use divs for line-breaks instead of BRs if white-space:no-wrap. If white-space:pre-wrap, then we insert BRs. There's a simple fix to RenderTextControl::text to detect divs and insert newlines. The deeper fix would be to figure out why we insert divs instead of BRs. I'm surprised we don't have the same bug with wrap=OFF though. With wrap=OFF, we still insert newlines on paste.
Ojan Vafai
Comment 6 2010-05-28 17:12:11 PDT
What's curious is that if I paste the same thing into a contentEditable=plaintext-only div, I get a BR for the newline, not divs.
Ojan Vafai
Comment 7 2010-05-28 17:14:02 PDT
Oh, nevermind, I was setting whitespace, not white-space. contentEditable=plaintext-only has the same bug. Paste inserts divs if white-space:no-wrap instead of BRs.
Ojan Vafai
Comment 8 2010-05-28 17:48:57 PDT
OK. The behavior is correct for white-space:no-wrap. In createFragmentFromText we check if the node preserves newlines. If it does, then we use BRs, otherwise we use divs. The bug is that the text control's innerBlock has white-space:no-wrap instead of white-space:pre. I don't quite get why that's the case though. Looking at the code, it looks like it should be white-space:pre.
Ojan Vafai
Comment 9 2010-05-28 17:59:18 PDT
Oh, duh. We let the white-space property inherit now. Instead, we should make sure that white-space:no-wrap translates to white-space:pre, perhaps in RenderTextControl::updateFromElement?
Ojan Vafai
Comment 10 2010-06-03 12:25:12 PDT
Shinichiro Hamaji
Comment 11 2010-06-04 00:11:39 PDT
Created attachment 57848 [details] attempt to preserve newlines
Shinichiro Hamaji
Comment 12 2010-06-04 00:13:26 PDT
Sorry for the latency and thanks for investigations. It's unfortunate we break fast/forms/basic-textareas with Ojan's patch. This means the hixie's test will fail again, right? http://www.hixie.ch/tests/evil/mixed/wraptextarea.html I've uploaded a patch with another approach and I'm guessing this approach is better for this issue, but I'm not sure. I should admit I'm not good at editing stuff. With my patch, RenderTextControl::text() and RenderTextControl::textWithHardLineBreaks() inserts newlines when we find </div>. In this way we can preserve newlines when we submit a form. We might be able to fix this issue by modifying createFragmentFromText so it doesn't emit <div> anymore and uses <br> instead. I didn't choose this way because I guessed we may emit <div> in future for another purpose. By the way, I've noticed a similar issue when I'm creating this patch. If we input "foo bar" into nowrap textarea and submit it, the expected query string is "foo+++bar" but the actual value was "foo+%A0+bar" (%A0 is NBSP). I think we can easily fix this issue by translating a NBSP into a space in RenderTextControl::text(). If we decide to go with my approach, I'll file another bug and fix it soon later. Ojan, what do you think? Are there any big issues with my approach? Thanks!
Ojan Vafai
Comment 13 2010-06-04 14:05:09 PDT
Comment on attachment 57848 [details] attempt to preserve newlines Overall, I like this approach better. Just a couple questions. Not r-'ing since I just don't know if this is correct. WebCore/rendering/RenderTextControl.cpp:331 + if (n && n->previousSibling() && n->previousSibling()->hasTagName(divTag)) I don't understand the code that generates the DOM inside the text control well enough to know if this if-statement is sufficient. For example, can you get nested div tags through pasting? Also, can you get a BR as the last node inside the previousSibling div tag? If so, we'd get multiple newlines in both cases where the user would only see one. WebCore/rendering/RenderTextControl.cpp:357 + if (node->hasTagName(divTag)) { Why do we need to walk inside the first div tag? Not saying it's wrong, I just don't understand. :)
Ojan Vafai
Comment 14 2010-06-04 14:10:53 PDT
(In reply to comment #12) > We might be able to fix this issue by modifying createFragmentFromText so it doesn't emit <div> anymore and uses <br> instead. I didn't choose this way because I guessed we may emit <div> in future for another purpose. I think I would prefer this approach for plain text controls. For rich-text, we'd want to maintain the current behavior. I would like it even more if we added an ASSERT to text and textWithHardLineBreaks that the text control has no divs in it. It will keep programming for text controls much simpler if we can assume text controls only contain text nodes and BRs. It's hard to say without seeing the code it would take to make this work though.
Shinichiro Hamaji
Comment 15 2010-06-06 21:45:11 PDT
Thanks for comments, Ojan! (In reply to comment #14) > (In reply to comment #12) > > We might be able to fix this issue by modifying createFragmentFromText so it doesn't emit <div> anymore and uses <br> instead. I didn't choose this way because I guessed we may emit <div> in future for another purpose. > > I think I would prefer this approach for plain text controls. For rich-text, we'd want to maintain the current behavior. > > I would like it even more if we added an ASSERT to text and textWithHardLineBreaks that the text control has no divs in it. It will keep programming for text controls much simpler if we can assume text controls only contain text nodes and BRs. OK, it seems we were actually using <br> long time ago and Darin made a change so we are using <div> now. http://trac.webkit.org/changeset/8229 I couldn't see the reason of the change, but I'm sure there were some reasons :) Darin, could you tell us why you made this change?
Ojan Vafai
Comment 16 2010-06-08 18:25:13 PDT
(In reply to comment #15) > OK, it seems we were actually using <br> long time ago and Darin made a change so we are using <div> now. > > http://trac.webkit.org/changeset/8229 > > I couldn't see the reason of the change, but I'm sure there were some reasons :) Darin, could you tell us why you made this change? This is a little different. I think createFragmentFromText is used for creating a DOM from a plain-text string. It's not for creating a DOM within a plain-text element. I think we might want to do something similar to what the code did before r8229 though. The difference is that we want to do it if we're creating a DOM for a plain-text context. We kind of do this already for the preserveNewline cases at http://trac.webkit.org/browser/trunk/WebCore/editing/markup.cpp#L1170. My intuition is that we should add another case. If we're in a contentEditable=plaintext-only element (i.e. renderer->style->userModify == READ_WRITE_PLAINTEXT_ONLY), then the newlines should all be converted to BRs and then we return that DOM. That should fix textareas and, more generally, plaintext contentEditable regions.
Ojan Vafai
Comment 17 2010-07-08 11:44:09 PDT
Comment on attachment 57848 [details] attempt to preserve newlines r- per my previous comment.
Alexey Proskuryakov
Comment 18 2010-11-23 22:54:21 PST
What's the status of this bug?
Note You need to log in before you can comment on or make changes to this bug.