Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Haml 4, Rails 4, textarea whitespace #643

Closed
ollym opened this issue Feb 28, 2013 · 42 comments
Closed

Haml 4, Rails 4, textarea whitespace #643

ollym opened this issue Feb 28, 2013 · 42 comments

Comments

@ollym
Copy link

ollym commented Feb 28, 2013

new.html.haml

= form_for @user do |f|
  .modal-body
    = render 'form', f:f
  .modal-footer
    = f.button :submit

_form.html.haml

= f.input :name
= f.input :description

Reproduces a textarea with 2 whitespace prepending any value in the description text area.

Interesting to note though... this doesn't produce the two whitespace:

= form_for @user do |f|
  = render 'form', f:f
  .modal-footer
    = f.button :submit
@norman
Copy link
Contributor

norman commented Feb 28, 2013

What version of Haml?

@norman
Copy link
Contributor

norman commented Feb 28, 2013

Specifically, does this happen with 4.0.0 or 4.0.1.rc.1? 4.0.1.rc.1 includes changes specifically to how textareas are handled in Rails.

@ollym
Copy link
Author

ollym commented Feb 28, 2013

From Gemfile.lock

    haml (4.0.1.rc.1)
      tilt
    haml-rails (0.4)
      actionpack (>= 3.1, < 4.1)
      activesupport (>= 3.1, < 4.1)
      haml (>= 3.1, < 4.1)
      railties (>= 3.1, < 4.1)

@ollym
Copy link
Author

ollym commented Feb 28, 2013

Screen Shot 2013-02-28 at 17 34 01

@norman
Copy link
Contributor

norman commented Feb 28, 2013

Great, thanks a lot for the detailed report. I'll look into it soon.

@norman
Copy link
Contributor

norman commented Mar 2, 2013

I'm working on a fix for this right now. A couple of notes:

  • I'm able to reproduce the error using both Simple Form 1.4.x and the latest beta.
  • If you need a fix for this now, keep in mind that this doesn't affect Haml when running in ugly mode (i.e., the default in Rails production), the error is only when using indenting.

norman added a commit that referenced this issue Mar 2, 2013
This commit fixes textarea behavior by stripping all leading space from
a textarea added as a result of Haml's indentation.

Leading space that is a part of the textarea content is preseved by
replacing the first space with a hexadecimal character reference.

Resolves #643
@norman
Copy link
Contributor

norman commented Mar 2, 2013

Ok, I've committed a fix to stable. Please try using Haml from the stable branch and confirm if it resolves your issue.

@mjc-gh
Copy link

mjc-gh commented Mar 14, 2013

Was having this issue in my app and can confirm the fix addresses the problem. 👍

@norman
Copy link
Contributor

norman commented Mar 14, 2013

@mikeycgto thanks for the confirmation. We'll fix a few more small bugs that were discovered and release 4.0.1 soon.

@ollym
Copy link
Author

ollym commented Mar 15, 2013

Yes this fixed it for me too, sorry for not saying so earlier. Thanks!

@polarblau
Copy link

Unfortunately I’m still seeing this or a similar problem with Haml 4.0.3 on Rails 4 when using the text_area form helper — in particular I’ve noticed it because the textareas contain a white space which prevents the placeholders from showing up:

The form is contained in a partial as well  

= form_for @model do |f|
  %label.description
    = f.text_area :description, placeholder: "Description"

and is rendered to

<! -- Other wrappers -->
        <form accept-charset="UTF-8" action="/models" >
          <label class='description'>
            <textarea id="model_description" name="model[description]" placeholder="Description">
  </textarea>

I’m not fully clear on why an empty textarea needs to contain a line break to boot, but this has been done explicitly on Rails’ side: https://github.com/rails/rails/blob/master/actionpack/lib/action_view/helpers/tag_helper.rb#L19 — which might maybe make this a Rails issue?

Weirdly enough this solution seems to have been introduced to aid Haml users — rails/rails@1438e0e .

Workaround

As a temporary solution setting

Haml::Template.options[:remove_whitespace] = true

seems to help.

polarblau referenced this issue in rails/rails Jun 5, 2013
See issue #393, issue #4000, issue #5190, and issue #5191. Adds a newline after the textarea opening tag based on @codykrieger's original patch so that we don't cause regressions in Haml-using apps. The regression caused textarea tags to add newlines to the field unintentionally (each update/save added an extra newline.)

Also fix 6 more tests that didn't yet have the newline expectation.
@jcoleman
Copy link

jcoleman commented Jun 5, 2013

@polarblau An textarea requires a line break because that's the HTML spec. And actually if you look at the fix history, you'll note that the original fix (to make Rails generate spec-compliant HTML) actually caused HAML to add visible newlines (browsers parse out the true \n but Haml was changing it into an encoded entity.) So the patch you linked to changed the implementation to still generate proper HTML but without passing along the newline as content (where Haml would encode it.)

@jcoleman
Copy link

jcoleman commented Jun 5, 2013

@polarblau Also, you should try using :ugly mode. Indented mode is probably the source of your problems.

@polarblau
Copy link

@jcoleman, thanks for your reply. I wasn’t aware that a the HTML spec requires line break within an empty text area and TBH it surprises me slightly. Would you be able to link to some background on this (couldn’t find anything during a quick glance at the spec)? — I'd love to find out what's the idea behind this requirement.

And, yes — the indented mode is definitely the source for my problems, but switching modes doesn’t seem like an appropriate solution in the long run.

@jcoleman
Copy link

jcoleman commented Jun 5, 2013

So :ugly mode should be used in production anyways (for performance reasons), so I'd suggest that switching modes is definitely an appropriate solution. Particularly since the only real reason for indented mode is to have human readable HTML, but tools like WebKit's Dev Tools make that pretty much unused at this point.

But regardless, the reasoning for the line break is because the textarea tag (also the pre tag to a different degree) treats the content inside of it as raw text--rather than as quasi-xml like every other tag does. So the newline is kind of a separator. It's admittedly odd, but without it if you have a preceding newline in your actual content, it'll be eaten by the browser when rendering the tag.

There's a good discussion on the spec/browser behavior at rails/rails#393.

@norman
Copy link
Contributor

norman commented Jun 5, 2013

@jcoleman is spot on. Indented mode exists largely for applications that
generate static HTML like Middleman; using it in production in a Rails app
serves no purpose unless your use case involves people specifically reading
the raw source HTML. We'll likely make ugly mode the default for Rails
development mode in a future release.

@polarblau
Copy link

Thanks — I'm in fact using the ugly mode in production (and now in development) but always found the indented mode very convenient in development (@norman I guess I’m one of the people who are reading the source 😸), despite having developer tools at hand.
It doesn’t feel like an “appropriate” solution to me, because the very use of a simple HTML tag requires to disable a complete feature of Haml. Be this as it may, I'm grateful for the work–around!

Thanks as well for explaining the need for the line break — I will check the discussion over at the Rails repo, but I can’t really follow the reasoning to accomodate the case of a leading line break in this case just yet. Maybe reading up on this will change my mind.

@jcoleman
Copy link

jcoleman commented Jun 5, 2013

The reasoning for the need for the line break is probably unnecessarily confusing. The point is that all textarea content has to be unindented (since it's not actually HTML) and the SGML spec actually says that all opening tags should be followed by a newline (which the browser ignores.) With respect to almost all tags, browsers don't implement this behavior per se (certainly not the requirement.) But it's more important in the case of the textarea tag to follow the spec since you can't treat the content as parseable HTML (if it were, newlines would be dropped anyway.) So the decision was set this way, and there's no going back now. I suppose they could have made the opposite decision when coding browsers...but that would have ignored how the SGML spec functioned. So it is what it is.

As to it not feeling like an "appropriate" solution, the thing is that indented mode is actually controller to the HTML spec/browser behavior with regard to the textarea tag. The closing tag and all content (particularly if it has line breaks) would have to be non-indented anyway to work properly (unless you encode everything as HTML entities.) Even if you wrote the HTML by hand. So the Haml "feature" is kind of at odds with how hand-coding would work anyway.

@JeanMertz
Copy link

👍 Was having this issue as well. Since I only use the Chrome Inspector I can easily enable ugly mode in development.

@jmuheim
Copy link

jmuheim commented Feb 19, 2014

We couldn't solve this issue without setting Haml::Template.options[:ugly] = true for development mode. There also seem to exist other side-effects of not having this set to true, e.g. https://coderwall.com/p/tashig.

@tfl
Copy link

tfl commented Apr 10, 2014

The problem seems to exist until today. I develop a small application with Sinatra and wondered why I have so much whitespace at the beginning of each line in my textareas. I tested the POST values, I testet the values before and after they where added to the database and before they where given to the template engine. All fine. Then I changed to ERB in the edit-template and voila, all was fine. Back to haml and I have whitespace line prefix again.

I even tested Haml::Template.options[:remove_whitespace] = true and Haml::Template.options[:ugly] = true both without success

I have just installed haml 4.0.2 using Ruby 2.1.1 (self compiled) on an x86-32 VirtualBox machine (debian Wheezy). In fact all gems are at its most recent version.

@norman
Copy link
Contributor

norman commented Apr 10, 2014

I have just installed haml 4.0.2
all gems are at its most recent version.

The current version of Haml is 4.0.5.

@tfl
Copy link

tfl commented Apr 11, 2014

Oops, forgot a bundle update. Now its using 4.0.5 - and still the problem persists.

@norman
Copy link
Contributor

norman commented Apr 11, 2014

@tfl could you create a small demo app that shows the problem?

@tfl
Copy link

tfl commented Apr 11, 2014

I created a bare-bone minimum example. Just show, edit, show. But I cannot reproduce the effect on my production server. The error occurs only on my development machine. So it can't be HAML since the version on both machines is the same (Debian, ruby, whatelse). I checked that twice. So thanks for your patience and sorry for this. I had created an extra VM to check this before I even post this issue... But, sometimes you loose and sometimes the other one wins ;)

@norman
Copy link
Contributor

norman commented Apr 11, 2014

You might not be seeing it in production because you have ugly mode enabled there, whereas you have indented mode in development. Still, it would be good to resolve the issue in indented mode as well, so if you don't mind sharing your example with me it could be helpful.

@jcoleman
Copy link

Perhaps the issue isn't with haml but with your app/sinatra/another gem?
When we fixed this for Rails, the appropriate text area tag helper method
had to be adjusted as well to make sure that it was outputting encoded
initial newlines (in accordance with the HTML spec) as well as fix haml to
handle them properly.

On Fri, Apr 11, 2014 at 11:46 AM, Norman Clarke notifications@github.comwrote:

You might not be seeing it in production because you have ugly mode
enabled there, whereas you have indented mode in development. Still, it
would be good to resolve the issue in indented mode as well, so if you
don't mind sharing your example with me it could be helpful.


Reply to this email directly or view it on GitHubhttps://github.com//issues/643#issuecomment-40218424
.

@tfl
Copy link

tfl commented Apr 11, 2014

I did not even used the ugly mode anymore. It just worked on the server. And I did this in development mode: just executed ruby -i ./app.rb and got == Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Thin

@jcoleman might be right. I have to search deeper on that.

@jcoleman
Copy link

@tfl It might help to look the fix introduced into Rails: rails/rails@1438e0e

I assume you're using some kind of library that provides input helpers? I'm not familiar with Sinatra enough to know if that's built in or if you have an additional library involved.

@tfl
Copy link

tfl commented Apr 13, 2014

I just got the answer. Suppose you have fetched a text from the database. I use this snippet to load the text into the textarea:

%textarea{:id => '_body', :rows => 20, :name => 'body'}
    = @post.body

This produces nice whitespaced indention for each line starting after a blank line and even adds the same amount of whitespace to the formerly empty line. And now comes the fun part. With the following snippet all is fine again:

%textarea{:id => '_body', :rows => 20, :name => 'body'}= @post.body

See the difference? In my simple app I created I could not see the problem because I put the value right after the closing bracket. I changed that now and you can see the effect at http://lvps176-28-12-150.dedicated.hosteurope.de:4567/1

@tfl
Copy link

tfl commented Apr 13, 2014

OK, I now found #506 and this tells me everything I needed to know about this. Sorry for wasting your time.

@adavia
Copy link

adavia commented Jun 5, 2016

I am facing this same problem using Rails 5 and haml-rails 0.9.0
Fix it with Haml::Template.options[:remove_whitespace] = true

@gcsmckinnon
Copy link

@adavia I can confirm the same issue and solution

@kesin
Copy link

kesin commented Oct 22, 2016

I can confirm the same issue too

fix it with
Haml::Template.options[:remove_whitespace] = true
or replace with
%textarea{id: 'post_content', name: 'post[content]'}= @post.content

rails 5.0.0.1
haml-rails 0.9.0
haml 4.0.7

@haslo
Copy link

haslo commented Oct 26, 2016

Yep, this issue is still around (same Gem versions as @kesin, and also earlier ones).

  • Haml::Template.options[:remove_whitespace] = true broke some whitespace-based layouts for us.
  • But Haml::Template.options[:ugly] = true fixed the issue, too, and didn't break the whitespace-based layouts.

@gamecreature
Copy link

Using a ~ in stead of the = also is a workaround for this problem

~ f.text_area :value

@dlittle1
Copy link

@gamecreature It worked for me as well. But why?

@gamecreature
Copy link

@dlittle1 The ~ command is used to enable white-space preservation.
The manual explicitly mentions the use for textareas: http://haml.info/docs/yardoc/file.REFERENCE.html#whitespace_preservation

@vizcay
Copy link

vizcay commented Apr 26, 2017

Hi, I've just been bitten by this also in Rails 5.. for a moment I've stared to believe that I was going nuts for the inexplicable behaviour..

gem 'rails', '~> 5.0.1'
gem 'haml-rails', '0.9.0'

@tschoppi
Copy link

This issue persists.

  • rails 5.0.1
  • haml 4.0.7

The following fix, as pointed out previously in this thread, also still works:

# config/initializers/haml.rb
Haml::Template.options[:ugly] = true

@k0kubun
Copy link
Member

k0kubun commented Apr 28, 2017

haml 4.0.7

Could you try latest Haml 5.0.0? If "Haml::Template.options[:ugly] = true fixed the issue" is true, it is already resolved because Haml 5 is always ugly: true.

@tschoppi
Copy link

Could you try latest Haml 5.0.0?

I just did and can confirm that switching to 5.0.0 will get rid of the issue without additional configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests