<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -4,10 +4,10 @@ require 'action_view/helpers/prototype_helper'
 module ActionView
   module Helpers
     # Provides functionality for working with JavaScript in your views.
-    # 
+    #
     # == Ajax, controls and visual effects
-    # 
-    # * For information on using Ajax, see 
+    #
+    # * For information on using Ajax, see
     #   ActionView::Helpers::PrototypeHelper.
     # * For information on using controls and visual effects, see
     #   ActionView::Helpers::ScriptaculousHelper.
@@ -20,22 +20,22 @@ module ActionView
     # and ActionView::Helpers::ScriptaculousHelper), you must do one of the
     # following:
     #
-    # * Use &lt;tt&gt;&lt;%= javascript_include_tag :defaults %&gt;&lt;/tt&gt; in the HEAD 
-    #   section of your page (recommended): This function will return 
+    # * Use &lt;tt&gt;&lt;%= javascript_include_tag :defaults %&gt;&lt;/tt&gt; in the HEAD
+    #   section of your page (recommended): This function will return
     #   references to the JavaScript files created by the +rails+ command in
     #   your &lt;tt&gt;public/javascripts&lt;/tt&gt; directory. Using it is recommended as
-    #   the browser can then cache the libraries instead of fetching all the 
+    #   the browser can then cache the libraries instead of fetching all the
     #   functions anew on every request.
-    # * Use &lt;tt&gt;&lt;%= javascript_include_tag 'prototype' %&gt;&lt;/tt&gt;: As above, but 
+    # * Use &lt;tt&gt;&lt;%= javascript_include_tag 'prototype' %&gt;&lt;/tt&gt;: As above, but
     #   will only include the Prototype core library, which means you are able
-    #   to use all basic AJAX functionality. For the Scriptaculous-based 
-    #   JavaScript helpers, like visual effects, autocompletion, drag and drop 
+    #   to use all basic AJAX functionality. For the Scriptaculous-based
+    #   JavaScript helpers, like visual effects, autocompletion, drag and drop
     #   and so on, you should use the method described above.
     # * Use &lt;tt&gt;&lt;%= define_javascript_functions %&gt;&lt;/tt&gt;: this will copy all the
     #   JavaScript support functions within a single script block. Not
     #   recommended.
     #
-    # For documentation on +javascript_include_tag+ see 
+    # For documentation on +javascript_include_tag+ see
     # ActionView::Helpers::AssetTagHelper.
     module JavaScriptHelper
       unless const_defined? :JAVASCRIPT_PATH
@@ -43,13 +43,13 @@ module ActionView
       end
 
       include PrototypeHelper
-      
-      # Returns a link that will trigger a JavaScript +function+ using the 
+
+      # Returns a link that will trigger a JavaScript +function+ using the
       # onclick handler and return false after the fact.
       #
       # The +function+ argument can be omitted in favor of an +update_page+
       # block, which evaluates to a string when the template is rendered
-      # (instead of making an Ajax request first).      
+      # (instead of making an Ajax request first).
       #
       # Examples:
       #   link_to_function &quot;Greeting&quot;, &quot;alert('Hello world!')&quot;
@@ -70,36 +70,31 @@ module ActionView
       #       &lt;a href=&quot;#&quot; id=&quot;more_link&quot; onclick=&quot;try {
       #         $(&amp;quot;details&amp;quot;).visualEffect(&amp;quot;toggle_blind&amp;quot;);
       #         $(&amp;quot;more_link&amp;quot;).update(&amp;quot;Show me less&amp;quot;);
-      #       } 
-      #       catch (e) { 
-      #         alert('RJS error:\n\n' + e.toString()); 
+      #       }
+      #       catch (e) {
+      #         alert('RJS error:\n\n' + e.toString());
       #         alert('$(\&amp;quot;details\&amp;quot;).visualEffect(\&amp;quot;toggle_blind\&amp;quot;);
       #         \n$(\&amp;quot;more_link\&amp;quot;).update(\&amp;quot;Show me less\&amp;quot;);');
-      #         throw e 
+      #         throw e
       #       };
       #       return false;&quot;&gt;Show me more&lt;/a&gt;
       #
       def link_to_function(name, *args, &amp;block)
-        html_options = args.extract_options!
-        function = args[0] || ''
-
-        html_options.symbolize_keys!
-        function = update_page(&amp;block) if block_given?
-        content_tag(
-          &quot;a&quot;, name, 
-          html_options.merge({ 
-            :href =&gt; html_options[:href] || &quot;#&quot;, 
-            :onclick =&gt; (html_options[:onclick] ? &quot;#{html_options[:onclick]}; &quot; : &quot;&quot;) + &quot;#{function}; return false;&quot; 
-          })
-        )
+        html_options = args.extract_options!.symbolize_keys!
+
+        function = block_given? ? update_page(&amp;block) : args[0] || ''
+        onclick = &quot;#{&quot;#{html_options[:onclick]}; &quot; if html_options[:onclick]}#{function}; return false;&quot;
+        href = html_options[:href] || '#'
+
+        content_tag(:a, name, html_options.merge(:href =&gt; href, :onclick =&gt; onclick))
       end
-      
-      # Returns a button that'll trigger a JavaScript +function+ using the 
+
+      # Returns a button that'll trigger a JavaScript +function+ using the
       # onclick handler.
       #
       # The +function+ argument can be omitted in favor of an +update_page+
       # block, which evaluates to a string when the template is rendered
-      # (instead of making an Ajax request first).      
+      # (instead of making an Ajax request first).
       #
       # Examples:
       #   button_to_function &quot;Greeting&quot;, &quot;alert('Hello world!')&quot;
@@ -111,45 +106,56 @@ module ActionView
       #     page[:details].visual_effect :toggle_slide
       #   end
       def button_to_function(name, *args, &amp;block)
-        html_options = args.extract_options!
-        function = args[0] || ''
-
-        html_options.symbolize_keys!
-        function = update_page(&amp;block) if block_given?
-        tag(:input, html_options.merge({ 
-          :type =&gt; &quot;button&quot;, :value =&gt; name, 
-          :onclick =&gt; (html_options[:onclick] ? &quot;#{html_options[:onclick]}; &quot; : &quot;&quot;) + &quot;#{function};&quot; 
-        }))
+        html_options = args.extract_options!.symbolize_keys!
+
+        function = block_given? ? update_page(&amp;block) : args[0] || ''
+        onclick = &quot;#{&quot;#{html_options[:onclick]}; &quot; if html_options[:onclick]}#{function};&quot;
+
+        tag(:input, html_options.merge(:type =&gt; 'button', :value =&gt; name, :onclick =&gt; onclick))
       end
 
-      # Includes the Action Pack JavaScript libraries inside a single &lt;script&gt; 
+      # Includes the Action Pack JavaScript libraries inside a single &lt;script&gt;
       # tag. The function first includes prototype.js and then its core extensions,
       # (determined by filenames starting with &quot;prototype&quot;).
       # Afterwards, any additional scripts will be included in undefined order.
       #
       # Note: The recommended approach is to copy the contents of
       # lib/action_view/helpers/javascripts/ into your application's
-      # public/javascripts/ directory, and use +javascript_include_tag+ to 
+      # public/javascripts/ directory, and use +javascript_include_tag+ to
       # create remote &lt;script&gt; links.
       def define_javascript_functions
         javascript = &quot;&lt;script type=\&quot;#{Mime::JS}\&quot;&gt;&quot;
-        
-        # load prototype.js and its extensions first 
+
+        # load prototype.js and its extensions first
         prototype_libs = Dir.glob(File.join(JAVASCRIPT_PATH, 'prototype*')).sort.reverse
-        prototype_libs.each do |filename| 
+        prototype_libs.each do |filename|
           javascript &lt;&lt; &quot;\n&quot; &lt;&lt; IO.read(filename)
         end
-        
+
         # load other libraries
-        (Dir.glob(File.join(JAVASCRIPT_PATH, '*')) - prototype_libs).each do |filename| 
+        (Dir.glob(File.join(JAVASCRIPT_PATH, '*')) - prototype_libs).each do |filename|
           javascript &lt;&lt; &quot;\n&quot; &lt;&lt; IO.read(filename)
         end
         javascript &lt;&lt; '&lt;/script&gt;'
       end
 
+
+      JS_ESCAPE_MAP = {
+        '\\'    =&gt; '\\\\',
+        '&lt;/'    =&gt; '&lt;\/',
+        &quot;\r\n&quot;  =&gt; '\n',
+        &quot;\n&quot;    =&gt; '\n',
+        &quot;\r&quot;    =&gt; '\n',
+        '&quot;'     =&gt; '\\&quot;',
+        &quot;'&quot;     =&gt; &quot;\\'&quot; }
+
       # Escape carrier returns and single and double quotes for JavaScript segments.
       def escape_javascript(javascript)
-        (javascript || '').gsub('\\','\0\0').gsub('&lt;/','&lt;\/').gsub(/\r\n|\n|\r/, &quot;\\n&quot;).gsub(/[&quot;']/) { |m| &quot;\\#{m}&quot; }
+        if javascript
+          javascript.gsub(/(\\|&lt;\/|\r\n|[\n\r&quot;'])/) { JS_ESCAPE_MAP[$1] }
+        else
+          ''
+        end
       end
 
       # Returns a JavaScript tag with the +content+ inside. Example:
@@ -163,7 +169,7 @@ module ActionView
       #   &lt;/script&gt;
       #
       # +html_options+ may be a hash of attributes for the &lt;script&gt; tag. Example:
-      #   javascript_tag &quot;alert('All is good')&quot;, :defer =&gt; 'defer' 
+      #   javascript_tag &quot;alert('All is good')&quot;, :defer =&gt; 'defer'
       #   # =&gt; &lt;script defer=&quot;defer&quot; type=&quot;text/javascript&quot;&gt;alert('All is good')&lt;/script&gt;
       #
       # Instead of passing the content as an argument, you can also use a block
@@ -180,30 +186,37 @@ module ActionView
             content_or_options_with_block
           end
 
-        tag = content_tag(&quot;script&quot;, javascript_cdata_section(content), html_options.merge(:type =&gt; Mime::JS))
+        tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type =&gt; Mime::JS))
 
-        block_given? ? concat(tag) : tag
+        if block_called_from_erb?(block)
+          concat(tag)
+        else
+          tag
+        end
       end
 
       def javascript_cdata_section(content) #:nodoc:
         &quot;\n//#{cdata_section(&quot;\n#{content}\n//&quot;)}\n&quot;
       end
-      
+
     protected
       def options_for_javascript(options)
-        '{' + options.map {|k, v| &quot;#{k}:#{v}&quot;}.sort.join(', ') + '}'
+        if options.empty?
+          '{}'
+        else
+          &quot;{#{options.keys.map { |k| &quot;#{k}:#{options[k]}&quot; }.sort.join(', ')}}&quot;
+        end
       end
-      
+
       def array_or_string_for_javascript(option)
-        js_option = if option.kind_of?(Array)
+        if option.kind_of?(Array)
           &quot;['#{option.join('\',\'')}']&quot;
         elsif !option.nil?
           &quot;'#{option}'&quot;
         end
-        js_option
       end
     end
-    
+
     JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper
   end
 end</diff>
      <filename>actionpack/lib/action_view/helpers/javascript_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -115,7 +115,7 @@ module ActionView
         # can't take an &lt;% end %&gt; later on, so we have to use &lt;% ... %&gt;
         # and implicitly concat.
         def block_called_from_erb?(block)
-          eval(BLOCK_CALLED_FROM_ERB, block)
+          block &amp;&amp; eval(BLOCK_CALLED_FROM_ERB, block)
         end
 
         def content_tag_string(name, content, options, escape = true)</diff>
      <filename>actionpack/lib/action_view/helpers/tag_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -535,7 +535,7 @@ module ActionView
             when method
               &quot;#{method_javascript_function(method, url, href)}return false;&quot;
             when popup
-              popup_javascript_function(popup) + 'return false;'
+              &quot;#{popup_javascript_function(popup)}return false;&quot;
             else
               html_options[&quot;onclick&quot;]
           end</diff>
      <filename>actionpack/lib/action_view/helpers/url_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9a0e4437199a233105348938e490808fc0688626</id>
    </parent>
  </parents>
  <author>
    <name>Jeremy Kemper</name>
    <login>jeremy</login>
    <email>jeremy@bitsweat.net</email>
  </author>
  <url>http://github.com/rails/rails/commit/f4ccc179530d5b9436da87d3c221dfa8fa89119a</url>
  <id>f4ccc179530d5b9436da87d3c221dfa8fa89119a</id>
  <committed-date>2008-06-21T14:54:10-07:00</committed-date>
  <authored-date>2008-06-21T14:54:10-07:00</authored-date>
  <message>Performance: javascript helper tweaks to speed up escaping and reduce object allocations when building options strings</message>
  <tree>6ace7c7bd35cef137e84057a566cdb97dbf5b53b</tree>
  <committer>
    <name>Jeremy Kemper</name>
    <login>jeremy</login>
    <email>jeremy@bitsweat.net</email>
  </committer>
</commit>
