Only apply textarea fix to textareas; refactor

Textareas are the only preserved tag that is editable, so we don't need to
recode the newline for <pre> or <code> tags. With this and the last few
preceding commits we bring Haml 4.x's performance nearly back in line with Haml
3.1.4.

Haml 3.1.4:

                           user     system      total        real
compiled haml pretty   0.330000   0.000000   0.330000 (  0.332720)
compiled haml ugly     0.180000   0.000000   0.180000 (  0.173543)
cached haml pretty     0.740000   0.000000   0.740000 (  0.740294)
cached haml ugly       0.490000   0.000000   0.490000 (  0.497688)

Haml 3.1.8:

                           user     system      total        real
compiled haml pretty   0.600000   0.000000   0.600000 (  0.605575)
compiled haml ugly     0.210000   0.000000   0.210000 (  0.210508)
cached haml pretty     1.240000   0.010000   1.250000 (  1.256737)
cached haml ugly       0.520000   0.000000   0.520000 (  0.527566)

Haml 4.0.0:

                           user     system      total        real
compiled haml pretty   0.720000   0.000000   0.720000 (  0.754891)
compiled haml ugly     0.300000   0.000000   0.300000 (  0.296439)
cached haml pretty     1.300000   0.000000   1.300000 (  1.301510)
cached haml ugly       0.570000   0.000000   0.570000 (  0.578155)

This commit:

                           user     system      total        real
compiled haml pretty   0.430000   0.010000   0.440000 (  0.429153)
compiled haml ugly     0.220000   0.000000   0.220000 (  0.220758)
cached haml pretty     0.810000   0.000000   0.810000 (  0.809804)
cached haml ugly       0.510000   0.000000   0.510000 (  0.516821)
This commit is contained in:
Norman Clarke 2013-02-25 07:43:16 -08:00
parent b1d8cc3b93
commit 2efd12f27e
3 changed files with 27 additions and 37 deletions

View File

@ -156,9 +156,7 @@ module Haml
<% end %>
<% if ugly %>
if toplevel?
result = Haml::Helpers.fix_preserved_whitespace(result, nil, options)
end
fix_textareas!(result, nil) if toplevel? && result.include?('<textarea')
return result
<% else %>
<% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
@ -181,14 +179,12 @@ module Haml
if has_newline
result = result.gsub "\\n", "\\n" + tabs(tabulation)
# Add tabulation if it wasn't precompiled
<% if in_tag && !nuke_inner_whitespace %> result = tabs(tabulation) + result <% end %>
end
if toplevel?
result = Haml::Helpers.fix_preserved_whitespace(result, tabs(tabulation), options)
end
fix_textareas!(result, tabs(tabulation)) if toplevel? && result.include?('<textarea')
<% if in_tag && !nuke_inner_whitespace %>
result = "\\n\#{result}\\n\#{tabs(tabulation-1)}"
@ -265,6 +261,29 @@ RUBY
private
# Works like #{find_and_preserve}, but allows the first newline after a
# preserved opening tag to remain unencoded, and then outdents the content.
# This change was motivated primarily by the change in Rails 3.2.3 to emit
# a newline after textarea helpers.
#
# @param input [String] The text to process
# @param tabs [String] The tabs provided by the Haml::Buffer
# @param options [Hash] The options hash provided by the Haml::Buffer
# @since Haml 4.0.1
# @private
def fix_textareas!(input, tabs)
pattern = /([ ]*)<(textarea)([^>]*)>(\n|&#x000A;)(.*?)(<\/\2>)/im
input.gsub!(pattern) do |s|
match = pattern.match(s)
content = match[5]
unless tabs.nil?
content.sub!(match[1].to_s, '')
content.sub!(tabs, '')
end
"#{match[1]}<#{match[2]}#{match[3]}>\n#{content}</#{match[2]}>"
end
end
if RUBY_VERSION < "1.9"
def new_encoded_string
""

View File

@ -113,33 +113,6 @@ MESSAGE
end
end
# Works like #{find_and_preserve}, but allows the first newline after a
# preserved opening tag to remain unencoded, and then outdents the content.
# This change was motivated primarily by the change in Rails 3.2.3 to emit
# a newline after textarea helpers.
#
# There's no reason this should be part of the public API provided by Haml
# and is here only for uniformity with the other helpers' locations. In a
# future version of Haml this will likely be moved into Haml::Buffer, so
# use it at your own risk.
#
# @param input [String] The text to process
# @param tabs [String] The tabs provided by the Haml::Buffer
# @param options [Hash] The options hash provided by the Haml::Buffer
# @since Haml 4.0.1
# @private
def fix_preserved_whitespace(input, tabs, options)
input.gsub(options[:retab_pattern]) do |s|
match = options[:retab_pattern].match(s)
content = match[5]
unless tabs.nil?
content.sub!(match[1].to_s, '')
content.sub!(tabs, '')
end
"#{match[1]}<#{match[2]}#{match[3]}>\n#{content}</#{match[2]}>"
end
end
# Takes any string, finds all the newlines, and converts them to
# HTML entities so they'll render correctly in
# whitespace-sensitive tags without screwing up the indentation.

View File

@ -261,9 +261,7 @@ module Haml
#
# @return [{Symbol => Object}] The options hash
def for_buffer
options_for_buffer = {}
options_for_buffer[:retab_pattern] = /([ ]*)<(#{preserve.map(&Regexp.method(:escape)).join('|')})([^>]*)>(\n|&#x000A;)(.*?)(<\/\2>)/im
self.class.buffer_option_keys.inject(options_for_buffer) do |hash, key|
self.class.buffer_option_keys.inject({}) do |hash, key|
hash[key] = send(key)
hash
end