Bug 39801 - REGRESSION (r45962): Pasted newlines are stripped on form submit at paste.nerv.fi
Summary: REGRESSION (r45962): Pasted newlines are stripped on form submit at paste.ner...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Forms (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P1 Normal
Assignee: Nobody
URL: http://paste.nerv.fi/
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2010-05-26 18:08 PDT by Ojan Vafai
Modified: 2011-01-05 00:40 PST (History)
5 users (show)

See Also:


Attachments
Patch (244.06 KB, patch)
2010-06-03 12:25 PDT, Ojan Vafai
no flags Details | Formatted Diff | Diff
attempt to preserve newlines (8.27 KB, patch)
2010-06-04 00:11 PDT, Shinichiro Hamaji
ojan: review-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ojan Vafai 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.
Comment 1 Alexey Proskuryakov 2010-05-28 13:12:59 PDT
Works in Safari/WebKit 4.0.5, fails in r60308.
Comment 2 Alexey Proskuryakov 2010-05-28 13:14:13 PDT
<rdar://problem/8040778>
Comment 3 Ojan Vafai 2010-05-28 14:02:06 PDT
Regression range: 45980:46042
Comment 4 Alexey Proskuryakov 2010-05-28 14:30:57 PDT
My testing says it's r45962.
Comment 5 Ojan Vafai 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.
Comment 6 Ojan Vafai 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.
Comment 7 Ojan Vafai 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.
Comment 8 Ojan Vafai 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.
Comment 9 Ojan Vafai 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?
Comment 10 Ojan Vafai 2010-06-03 12:25:12 PDT
Created attachment 57802 [details]
Patch
Comment 11 Shinichiro Hamaji 2010-06-04 00:11:39 PDT
Created attachment 57848 [details]
attempt to preserve newlines
Comment 12 Shinichiro Hamaji 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!
Comment 13 Ojan Vafai 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. :)
Comment 14 Ojan Vafai 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.
Comment 15 Shinichiro Hamaji 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?
Comment 16 Ojan Vafai 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.
Comment 17 Ojan Vafai 2010-07-08 11:44:09 PDT
Comment on attachment 57848 [details]
attempt to preserve newlines

r- per my previous comment.
Comment 18 Alexey Proskuryakov 2010-11-23 22:54:21 PST
What's the status of this bug?