From 2efd12f27e3d5e60bcbe1b34a9507518262747e4 Mon Sep 17 00:00:00 2001 From: Norman Clarke Date: Mon, 25 Feb 2013 07:43:16 -0800 Subject: [PATCH] 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
 or  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)
---
 lib/haml/buffer.rb  | 33 ++++++++++++++++++++++++++-------
 lib/haml/helpers.rb | 27 ---------------------------
 lib/haml/options.rb |  4 +---
 3 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/lib/haml/buffer.rb b/lib/haml/buffer.rb
index a8c79934..7100d344 100644
--- a/lib/haml/buffer.rb
+++ b/lib/haml/buffer.rb
@@ -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?('
         <% 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?('
           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|
)(.*?)(<\/\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}"
+      end
+    end
+
     if RUBY_VERSION < "1.9"
       def new_encoded_string
         ""
diff --git a/lib/haml/helpers.rb b/lib/haml/helpers.rb
index d8d8737a..4c85ecab 100755
--- a/lib/haml/helpers.rb
+++ b/lib/haml/helpers.rb
@@ -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}"
-      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.
diff --git a/lib/haml/options.rb b/lib/haml/options.rb
index ebe54596..b731fe85 100644
--- a/lib/haml/options.rb
+++ b/lib/haml/options.rb
@@ -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|
)(.*?)(<\/\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