actionpack 3.0.0.beta → 3.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (118) hide show
  1. data/CHANGELOG +291 -260
  2. data/lib/abstract_controller.rb +5 -2
  3. data/lib/abstract_controller/assigns.rb +21 -0
  4. data/lib/abstract_controller/base.rb +13 -5
  5. data/lib/abstract_controller/collector.rb +2 -0
  6. data/lib/abstract_controller/helpers.rb +4 -14
  7. data/lib/abstract_controller/layouts.rb +50 -99
  8. data/lib/abstract_controller/logger.rb +2 -2
  9. data/lib/abstract_controller/rendering.rb +105 -173
  10. data/lib/abstract_controller/view_paths.rb +69 -0
  11. data/lib/action_controller.rb +1 -2
  12. data/lib/action_controller/base.rb +10 -32
  13. data/lib/action_controller/caching.rb +19 -18
  14. data/lib/action_controller/caching/actions.rb +17 -11
  15. data/lib/action_controller/caching/fragments.rb +5 -17
  16. data/lib/action_controller/caching/pages.rb +24 -24
  17. data/lib/action_controller/caching/sweeping.rb +1 -3
  18. data/lib/action_controller/deprecated.rb +0 -2
  19. data/lib/action_controller/deprecated/base.rb +143 -0
  20. data/lib/action_controller/metal.rb +29 -26
  21. data/lib/action_controller/metal/compatibility.rb +18 -87
  22. data/lib/action_controller/metal/cookies.rb +0 -1
  23. data/lib/action_controller/metal/head.rb +1 -0
  24. data/lib/action_controller/metal/helpers.rb +2 -2
  25. data/lib/action_controller/metal/hide_actions.rb +4 -6
  26. data/lib/action_controller/metal/http_authentication.rb +18 -33
  27. data/lib/action_controller/metal/implicit_render.rb +21 -0
  28. data/lib/action_controller/metal/instrumentation.rb +1 -1
  29. data/lib/action_controller/metal/mime_responds.rb +2 -1
  30. data/lib/action_controller/metal/rack_delegation.rb +3 -8
  31. data/lib/action_controller/metal/redirecting.rb +2 -1
  32. data/lib/action_controller/metal/renderers.rb +4 -2
  33. data/lib/action_controller/metal/rendering.rb +31 -44
  34. data/lib/action_controller/metal/request_forgery_protection.rb +41 -4
  35. data/lib/action_controller/metal/responder.rb +2 -0
  36. data/lib/action_controller/metal/session_management.rb +0 -36
  37. data/lib/action_controller/metal/streaming.rb +20 -47
  38. data/lib/action_controller/metal/testing.rb +0 -1
  39. data/lib/action_controller/metal/url_for.rb +11 -148
  40. data/lib/action_controller/middleware.rb +2 -1
  41. data/lib/action_controller/polymorphic_routes.rb +1 -2
  42. data/lib/action_controller/railtie.rb +63 -10
  43. data/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb} +5 -12
  44. data/lib/action_controller/railties/url_helpers.rb +14 -0
  45. data/lib/action_controller/record_identifier.rb +20 -1
  46. data/lib/action_controller/test_case.rb +123 -12
  47. data/lib/action_dispatch.rb +1 -0
  48. data/lib/action_dispatch/http/cache.rb +20 -3
  49. data/lib/action_dispatch/http/filter_parameters.rb +40 -25
  50. data/lib/action_dispatch/http/mime_negotiation.rb +6 -17
  51. data/lib/action_dispatch/http/mime_type.rb +2 -7
  52. data/lib/action_dispatch/http/request.rb +12 -33
  53. data/lib/action_dispatch/http/response.rb +35 -15
  54. data/lib/action_dispatch/http/upload.rb +2 -0
  55. data/lib/action_dispatch/http/url.rb +5 -32
  56. data/lib/action_dispatch/middleware/callbacks.rb +1 -1
  57. data/lib/action_dispatch/middleware/cookies.rb +4 -3
  58. data/lib/action_dispatch/middleware/params_parser.rb +4 -3
  59. data/lib/action_dispatch/middleware/remote_ip.rb +51 -0
  60. data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -0
  61. data/lib/action_dispatch/middleware/session/cookie_store.rb +6 -8
  62. data/lib/action_dispatch/middleware/show_exceptions.rb +0 -14
  63. data/lib/action_dispatch/middleware/stack.rb +6 -2
  64. data/lib/action_dispatch/railtie.rb +3 -1
  65. data/lib/action_dispatch/routing.rb +2 -0
  66. data/lib/action_dispatch/routing/deprecated_mapper.rb +35 -7
  67. data/lib/action_dispatch/routing/mapper.rb +134 -48
  68. data/lib/action_dispatch/routing/route.rb +2 -2
  69. data/lib/action_dispatch/routing/route_set.rb +217 -158
  70. data/lib/action_dispatch/routing/url_for.rb +139 -0
  71. data/lib/action_dispatch/testing/assertions/response.rb +14 -61
  72. data/lib/action_dispatch/testing/assertions/routing.rb +25 -14
  73. data/lib/action_dispatch/testing/integration.rb +32 -50
  74. data/lib/action_dispatch/testing/performance_test.rb +3 -1
  75. data/lib/action_dispatch/testing/test_process.rb +2 -0
  76. data/lib/action_dispatch/testing/test_request.rb +2 -0
  77. data/lib/action_pack/version.rb +4 -3
  78. data/lib/action_view.rb +11 -6
  79. data/lib/action_view/base.rb +33 -121
  80. data/lib/action_view/context.rb +0 -2
  81. data/lib/action_view/helpers.rb +26 -23
  82. data/lib/action_view/helpers/active_model_helper.rb +28 -18
  83. data/lib/action_view/helpers/asset_tag_helper.rb +109 -54
  84. data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
  85. data/lib/action_view/helpers/cache_helper.rb +22 -1
  86. data/lib/action_view/helpers/capture_helper.rb +22 -22
  87. data/lib/action_view/helpers/date_helper.rb +6 -5
  88. data/lib/action_view/helpers/form_helper.rb +78 -63
  89. data/lib/action_view/helpers/form_options_helper.rb +6 -4
  90. data/lib/action_view/helpers/form_tag_helper.rb +26 -15
  91. data/lib/action_view/helpers/javascript_helper.rb +90 -10
  92. data/lib/action_view/helpers/number_helper.rb +315 -118
  93. data/lib/action_view/helpers/prototype_helper.rb +19 -46
  94. data/lib/action_view/helpers/record_tag_helper.rb +4 -4
  95. data/lib/action_view/helpers/tag_helper.rb +7 -24
  96. data/lib/action_view/helpers/text_helper.rb +8 -7
  97. data/lib/action_view/helpers/translation_helper.rb +7 -5
  98. data/lib/action_view/helpers/url_helper.rb +19 -16
  99. data/lib/action_view/locale/en.yml +45 -6
  100. data/lib/action_view/lookup_context.rb +190 -0
  101. data/lib/action_view/paths.rb +22 -63
  102. data/lib/action_view/railtie.rb +14 -4
  103. data/lib/action_view/railties/{subscriber.rb → log_subscriber.rb} +1 -1
  104. data/lib/action_view/render/layouts.rb +73 -0
  105. data/lib/action_view/render/partials.rb +15 -41
  106. data/lib/action_view/render/rendering.rb +27 -78
  107. data/lib/action_view/template.rb +20 -24
  108. data/lib/action_view/template/error.rb +22 -2
  109. data/lib/action_view/template/handlers/erb.rb +33 -9
  110. data/lib/action_view/template/handlers/rjs.rb +1 -2
  111. data/lib/action_view/template/resolver.rb +46 -104
  112. data/lib/action_view/template/text.rb +5 -12
  113. data/lib/action_view/test_case.rb +14 -23
  114. metadata +83 -40
  115. data/lib/abstract_controller/compatibility.rb +0 -18
  116. data/lib/abstract_controller/localized_cache.rb +0 -49
  117. data/lib/action_controller/metal/configuration.rb +0 -28
  118. data/lib/action_controller/url_rewriter.rb +0 -76
@@ -1,6 +1,7 @@
1
1
  require 'set'
2
2
  require 'active_support/json'
3
3
  require 'active_support/core_ext/object/returning'
4
+ require 'active_support/core_ext/object/blank'
4
5
 
5
6
  module ActionView
6
7
  module Helpers
@@ -35,7 +36,7 @@ module ActionView
35
36
  #
36
37
  # ...through a form...
37
38
  #
38
- # <% form_remote_tag :url => '/shipping' do -%>
39
+ # <%= form_remote_tag :url => '/shipping' do -%>
39
40
  # <div><%= submit_tag 'Recalculate Shipping' %></div>
40
41
  # <% end -%>
41
42
  #
@@ -102,39 +103,6 @@ module ActionView
102
103
  :form, :with, :update, :script, :type ]).merge(CALLBACKS)
103
104
  end
104
105
 
105
- # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
106
- # onclick handler.
107
- #
108
- # The first argument +name+ is used as the button's value or display text.
109
- #
110
- # The next arguments are optional and may include the javascript function definition and a hash of html_options.
111
- #
112
- # The +function+ argument can be omitted in favor of an +update_page+
113
- # block, which evaluates to a string when the template is rendered
114
- # (instead of making an Ajax request first).
115
- #
116
- # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
117
- #
118
- # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
119
- #
120
- # Examples:
121
- # button_to_function "Greeting", "alert('Hello world!')"
122
- # button_to_function "Delete", "if (confirm('Really?')) do_delete()"
123
- # button_to_function "Details" do |page|
124
- # page[:details].visual_effect :toggle_slide
125
- # end
126
- # button_to_function "Details", :class => "details_button" do |page|
127
- # page[:details].visual_effect :toggle_slide
128
- # end
129
- def button_to_function(name, *args, &block)
130
- html_options = args.extract_options!.symbolize_keys
131
-
132
- function = block_given? ? update_page(&block) : args[0] || ''
133
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
134
-
135
- tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
136
- end
137
-
138
106
  # Returns the JavaScript needed for a remote function.
139
107
  # Takes the same arguments as link_to_remote.
140
108
  #
@@ -180,7 +148,6 @@ module ActionView
180
148
  # #include_helpers_from_context has nothing to overwrite.
181
149
  class JavaScriptGenerator #:nodoc:
182
150
  def initialize(context, &block) #:nodoc:
183
- context._evaluate_assigns_and_ivars
184
151
  @context, @lines = context, []
185
152
  include_helpers_from_context
186
153
  @context.with_output_buffer(@lines) do
@@ -569,15 +536,19 @@ module ActionView
569
536
  end
570
537
  end
571
538
 
572
- def render(*options_for_render)
573
- old_formats = @context && @context.formats
539
+ def render(*options)
540
+ with_formats(:html) do
541
+ case option = options.first
542
+ when Hash
543
+ @context.render(*options)
544
+ else
545
+ option.to_s
546
+ end
547
+ end
548
+ end
574
549
 
575
- @context.reset_formats([:html]) if @context
576
- Hash === options_for_render.first ?
577
- @context.render(*options_for_render) :
578
- options_for_render.first.to_s
579
- ensure
580
- @context.reset_formats(old_formats) if @context
550
+ def with_formats(*args)
551
+ @context ? @context.update_details(:formats => args) { yield } : yield
581
552
  end
582
553
 
583
554
  def javascript_object_for(object)
@@ -610,7 +581,7 @@ module ActionView
610
581
  # page.hide 'spinner'
611
582
  # end
612
583
  def update_page(&block)
613
- JavaScriptGenerator.new(@template, &block).to_s.html_safe
584
+ JavaScriptGenerator.new(view_context, &block).to_s.html_safe
614
585
  end
615
586
 
616
587
  # Works like update_page but wraps the generated JavaScript in a <script>
@@ -684,6 +655,10 @@ module ActionView
684
655
  @generator << root if root
685
656
  end
686
657
 
658
+ def is_a?(klass)
659
+ klass == JavaScriptProxy
660
+ end
661
+
687
662
  private
688
663
  def method_missing(method, *arguments, &block)
689
664
  if method.to_s =~ /(.*)=$/
@@ -877,5 +852,3 @@ module ActionView
877
852
  end
878
853
  end
879
854
  end
880
-
881
- require 'action_view/helpers/javascript_helper'
@@ -4,7 +4,7 @@ module ActionView
4
4
  # Produces a wrapper DIV element with id and class parameters that
5
5
  # relate to the specified Active Record object. Usage example:
6
6
  #
7
- # <% div_for(@person, :class => "foo") do %>
7
+ # <%= div_for(@person, :class => "foo") do %>
8
8
  # <%=h @person.name %>
9
9
  # <% end %>
10
10
  #
@@ -19,7 +19,7 @@ module ActionView
19
19
  # content_tag_for creates an HTML element with id and class parameters
20
20
  # that relate to the specified Active Record object. For example:
21
21
  #
22
- # <% content_tag_for(:tr, @person) do %>
22
+ # <%= content_tag_for(:tr, @person) do %>
23
23
  # <td><%=h @person.first_name %></td>
24
24
  # <td><%=h @person.last_name %></td>
25
25
  # <% end %>
@@ -31,7 +31,7 @@ module ActionView
31
31
  #
32
32
  # If you require the HTML id attribute to have a prefix, you can specify it:
33
33
  #
34
- # <% content_tag_for(:tr, @person, :foo) do %> ...
34
+ # <%= content_tag_for(:tr, @person, :foo) do %> ...
35
35
  #
36
36
  # produces:
37
37
  #
@@ -41,7 +41,7 @@ module ActionView
41
41
  # additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
42
42
  # with the default class name for your object. For example:
43
43
  #
44
- # <% content_tag_for(:li, @person, :class => "bar") %>...
44
+ # <%= content_tag_for(:li, @person, :class => "bar") %>...
45
45
  #
46
46
  # produces:
47
47
  #
@@ -1,3 +1,4 @@
1
+ require 'active_support/core_ext/object/blank'
1
2
  require 'set'
2
3
 
3
4
  module ActionView
@@ -7,6 +8,9 @@ module ActionView
7
8
  module TagHelper
8
9
  include ERB::Util
9
10
 
11
+ extend ActiveSupport::Concern
12
+ include CaptureHelper
13
+
10
14
  BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
11
15
  autoplay controls loop selected hidden scoped async
12
16
  defer reversed ismap seemless muted required
@@ -62,20 +66,14 @@ module ActionView
62
66
  # content_tag("select", options, :multiple => true)
63
67
  # # => <select multiple="multiple">...options...</select>
64
68
  #
65
- # <% content_tag :div, :class => "strong" do -%>
69
+ # <%= content_tag :div, :class => "strong" do -%>
66
70
  # Hello world!
67
71
  # <% end -%>
68
72
  # # => <div class="strong">Hello world!</div>
69
73
  def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
70
74
  if block_given?
71
75
  options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
72
- content_tag = content_tag_string(name, capture(&block), options, escape)
73
-
74
- if block_called_from_erb?(block)
75
- concat(content_tag)
76
- else
77
- content_tag
78
- end
76
+ content_tag_string(name, capture(&block), options, escape)
79
77
  else
80
78
  content_tag_string(name, content_or_options_with_block, options, escape)
81
79
  end
@@ -109,25 +107,10 @@ module ActionView
109
107
  end
110
108
 
111
109
  private
112
- BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template'
113
-
114
- if RUBY_VERSION < '1.9.0'
115
- # Check whether we're called from an erb template.
116
- # We'd return a string in any other case, but erb <%= ... %>
117
- # can't take an <% end %> later on, so we have to use <% ... %>
118
- # and implicitly concat.
119
- def block_called_from_erb?(block)
120
- block && eval(BLOCK_CALLED_FROM_ERB, block)
121
- end
122
- else
123
- def block_called_from_erb?(block)
124
- block && eval(BLOCK_CALLED_FROM_ERB, block.binding)
125
- end
126
- end
127
110
 
128
111
  def content_tag_string(name, content, options, escape = true)
129
112
  tag_options = tag_options(options, escape) if options
130
- "<#{name}#{tag_options}>#{content}</#{name}>".html_safe
113
+ "<#{name}#{tag_options}>#{ERB::Util.h(content)}</#{name}>".html_safe
131
114
  end
132
115
 
133
116
  def tag_options(options, escape = true)
@@ -1,3 +1,4 @@
1
+ require 'active_support/core_ext/object/blank'
1
2
  require 'action_view/helpers/tag_helper'
2
3
 
3
4
  module ActionView
@@ -17,7 +18,7 @@ module ActionView
17
18
  # concat "hello"
18
19
  # # is the equivalent of <%= "hello" %>
19
20
  #
20
- # if (logged_in == true):
21
+ # if logged_in
21
22
  # concat "Logged in!"
22
23
  # else
23
24
  # concat link_to('login', :action => login)
@@ -29,7 +30,7 @@ module ActionView
29
30
  end
30
31
 
31
32
  def safe_concat(string)
32
- output_buffer.safe_concat(string)
33
+ output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
33
34
  end
34
35
 
35
36
  # Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
@@ -187,7 +188,7 @@ module ActionView
187
188
  # pluralize(0, 'person')
188
189
  # # => 0 people
189
190
  def pluralize(count, singular, plural = nil)
190
- "#{count || 0} " + ((count == 1 || count == '1') ? singular : (plural || singular.pluralize))
191
+ "#{count || 0} " + ((count == 1 || count =~ /^1(\.0+)?$/) ? singular : (plural || singular.pluralize))
191
192
  end
192
193
 
193
194
  # Wraps the +text+ into lines no longer than +line_width+ width. This method
@@ -327,12 +328,12 @@ module ActionView
327
328
  # # => "<p class='description'>Look ma! A class!</p>"
328
329
  def simple_format(text, html_options={})
329
330
  start_tag = tag('p', html_options, true)
330
- text = text.to_s.dup
331
+ text = h(text)
331
332
  text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
332
333
  text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
333
334
  text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
334
335
  text.insert 0, start_tag
335
- text << "</p>"
336
+ text.safe_concat("</p>")
336
337
  end
337
338
 
338
339
  # Turns all URLs and e-mail addresses into clickable links. The <tt>:link</tt> option
@@ -415,7 +416,7 @@ module ActionView
415
416
  # {:first => 'Emily', :middle => 'Shannon', :maiden => 'Pike', :last => 'Hicks'},
416
417
  # {:first => 'June', :middle => 'Dae', :last => 'Jones'}]
417
418
  # <% @items.each do |item| %>
418
- # <tr class="<%= cycle("even", "odd", :name => "row_class") -%>">
419
+ # <tr class="<%= cycle("odd", "even", :name => "row_class") -%>">
419
420
  # <td>
420
421
  # <% item.values.each do |value| %>
421
422
  # <%# Create a named cycle "colors" %>
@@ -576,7 +577,7 @@ module ActionView
576
577
  # each email is yielded and the result is used as the link text.
577
578
  def auto_link_email_addresses(text, html_options = {})
578
579
  body = text.dup
579
- text.gsub(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
580
+ text.gsub(/([\w\.!#\$%\-+]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
580
581
  text = $1
581
582
 
582
583
  if body.match(/<a\b[^>]*>(.*)(#{Regexp.escape(text)})(.*)<\/a>/)
@@ -12,9 +12,10 @@ module ActionView
12
12
  # prepend the key with a period, nothing is converted.
13
13
  def translate(key, options = {})
14
14
  options[:raise] = true
15
- I18n.translate(scope_key_by_partial(key), options).html_safe
15
+ translation = I18n.translate(scope_key_by_partial(key), options)
16
+ (translation.respond_to?(:join) ? translation.join : translation).html_safe
16
17
  rescue I18n::MissingTranslationData => e
17
- keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope])
18
+ keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
18
19
  content_tag('span', keys.join(', '), :class => 'translation_missing')
19
20
  end
20
21
  alias :t :translate
@@ -28,9 +29,10 @@ module ActionView
28
29
  private
29
30
 
30
31
  def scope_key_by_partial(key)
31
- if key.to_s.first == "."
32
+ strkey = key.respond_to?(:join) ? key.join : key.to_s
33
+ if strkey.first == "."
32
34
  if @_virtual_path
33
- @_virtual_path.gsub(%r{/_?}, ".") + key.to_s
35
+ @_virtual_path.gsub(%r{/_?}, ".") + strkey
34
36
  else
35
37
  raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
36
38
  end
@@ -40,4 +42,4 @@ module ActionView
40
42
  end
41
43
  end
42
44
  end
43
- end
45
+ end
@@ -1,14 +1,18 @@
1
1
  require 'action_view/helpers/javascript_helper'
2
2
  require 'active_support/core_ext/array/access'
3
3
  require 'active_support/core_ext/hash/keys'
4
+ require 'action_dispatch'
4
5
 
5
6
  module ActionView
6
7
  module Helpers #:nodoc:
7
8
  # Provides a set of methods for making links and getting URLs that
8
- # depend on the routing subsystem (see ActionController::Routing).
9
+ # depend on the routing subsystem (see ActionDispatch::Routing).
9
10
  # This allows you to use the same format for links in views
10
11
  # and controllers.
11
12
  module UrlHelper
13
+ extend ActiveSupport::Concern
14
+
15
+ include ActionDispatch::Routing::UrlFor
12
16
  include JavaScriptHelper
13
17
 
14
18
  # Need to map default url options to controller one.
@@ -16,6 +20,10 @@ module ActionView
16
20
  controller.send(:default_url_options, *args)
17
21
  end
18
22
 
23
+ def url_options
24
+ controller.url_options
25
+ end
26
+
19
27
  # Returns the URL for the set of +options+ provided. This takes the
20
28
  # same options as +url_for+ in Action Controller (see the
21
29
  # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
@@ -63,7 +71,7 @@ module ActionView
63
71
  # # => /testing/jump/#tax&ship
64
72
  #
65
73
  # <%= url_for(Workshop.new) %>
66
- # # relies on Workshop answering a new_record? call (and in this case returning true)
74
+ # # relies on Workshop answering a persisted? call (and in this case returning false)
67
75
  # # => /workshops
68
76
  #
69
77
  # <%= url_for(@workshop) %>
@@ -162,7 +170,7 @@ module ActionView
162
170
  #
163
171
  # You can use a block as well if your link target is hard to fit into the name parameter. ERb example:
164
172
  #
165
- # <% link_to(@profile) do %>
173
+ # <%= link_to(@profile) do %>
166
174
  # <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
167
175
  # <% end %>
168
176
  # # => <a href="/profiles/1">
@@ -202,13 +210,11 @@ module ActionView
202
210
  #
203
211
  # link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?")
204
212
  # # => <a href='http://www.example.com' rel="nofollow" data-method="delete" data-confirm="Are you sure?">Destroy</a>
205
-
206
- #
207
213
  def link_to(*args, &block)
208
214
  if block_given?
209
215
  options = args.first || {}
210
216
  html_options = args.second
211
- safe_concat(link_to(capture(&block), options, html_options))
217
+ link_to(capture(&block), options, html_options)
212
218
  else
213
219
  name = args[0]
214
220
  options = args[1] || {}
@@ -469,14 +475,12 @@ module ActionView
469
475
  extras << "subject=#{Rack::Utils.escape(subject).gsub("+", "%20")}&" unless subject.nil?
470
476
  extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty?
471
477
 
472
- email_address = email_address.to_s
473
-
474
- email_address_obfuscated = email_address.dup
478
+ email_address_obfuscated = html_escape(email_address)
475
479
  email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at")
476
480
  email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
477
481
 
478
482
  if encode == "javascript"
479
- "document.write('#{content_tag("a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
483
+ "document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
480
484
  string << sprintf("%%%x", c)
481
485
  end
482
486
  "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>"
@@ -493,9 +497,9 @@ module ActionView
493
497
  char = c.chr
494
498
  string << (char =~ /\w/ ? sprintf("%%%x", c) : char)
495
499
  end
496
- content_tag "a", name || email_address_encoded, html_options.merge({ "href" => "#{string}#{extras}" })
500
+ content_tag "a", name || email_address_encoded.html_safe, html_options.merge({ "href" => "#{string}#{extras}" })
497
501
  else
498
- content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
502
+ content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
499
503
  end
500
504
  end
501
505
 
@@ -548,10 +552,11 @@ module ActionView
548
552
  # submitted url doesn't have any either. This lets the function
549
553
  # work with things like ?order=asc
550
554
  if url_string.index("?")
551
- request_uri = request.request_uri
555
+ request_uri = request.fullpath
552
556
  else
553
- request_uri = request.request_uri.split('?').first
557
+ request_uri = request.path
554
558
  end
559
+
555
560
  if url_string =~ /^\w+:\/\//
556
561
  url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
557
562
  else
@@ -581,8 +586,6 @@ module ActionView
581
586
  add_confirm_to_attributes!(html_options, confirm) if confirm
582
587
  add_method_to_attributes!(html_options, method) if method
583
588
 
584
- html_options["data-url"] = options[:url] if options.is_a?(Hash) && options[:url]
585
-
586
589
  html_options
587
590
  end
588
591
 
@@ -9,6 +9,11 @@
9
9
  delimiter: ","
10
10
  # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
11
11
  precision: 3
12
+ # If set to true, precision will mean the number of significant digits instead
13
+ # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
14
+ significant: false
15
+ # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
16
+ strip_insignificant_zeros: false
12
17
 
13
18
  # Used in number_to_currency()
14
19
  currency:
@@ -16,34 +21,43 @@
16
21
  # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
17
22
  format: "%u%n"
18
23
  unit: "$"
19
- # These three are to override number.format and are optional
24
+ # These five are to override number.format and are optional
20
25
  separator: "."
21
26
  delimiter: ","
22
27
  precision: 2
28
+ significant: false
29
+ strip_insignificant_zeros: false
23
30
 
24
31
  # Used in number_to_percentage()
25
32
  percentage:
26
33
  format:
27
- # These three are to override number.format and are optional
34
+ # These five are to override number.format and are optional
28
35
  # separator:
29
36
  delimiter: ""
30
37
  # precision:
38
+ # significant: false
39
+ # strip_insignificant_zeros: false
31
40
 
32
41
  # Used in number_to_precision()
33
42
  precision:
34
43
  format:
35
- # These three are to override number.format and are optional
44
+ # These five are to override number.format and are optional
36
45
  # separator:
37
46
  delimiter: ""
38
47
  # precision:
48
+ # significant: false
49
+ # strip_insignificant_zeros: false
39
50
 
40
- # Used in number_to_human_size()
51
+ # Used in number_to_human_size() and number_to_human()
41
52
  human:
42
53
  format:
43
- # These three are to override number.format and are optional
54
+ # These five are to override number.format and are optional
44
55
  # separator:
45
56
  delimiter: ""
46
- precision: 1
57
+ precision: 3
58
+ significant: true
59
+ strip_insignificant_zeros: true
60
+ # Used in number_to_human_size()
47
61
  storage_units:
48
62
  # Storage units output formatting.
49
63
  # %u is the storage unit, %n is the number (default: 2 MB)
@@ -56,6 +70,31 @@
56
70
  mb: "MB"
57
71
  gb: "GB"
58
72
  tb: "TB"
73
+ # Used in number_to_human()
74
+ decimal_units:
75
+ format: "%n %u"
76
+ # Decimal units output formatting
77
+ # By default we will only quantify some of the exponents
78
+ # but the commented ones might be defined or overridden
79
+ # by the user.
80
+ units:
81
+ # femto: Quadrillionth
82
+ # pico: Trillionth
83
+ # nano: Billionth
84
+ # micro: Millionth
85
+ # mili: Thousandth
86
+ # centi: Hundredth
87
+ # deci: Tenth
88
+ unit: ""
89
+ # ten:
90
+ # one: Ten
91
+ # other: Tens
92
+ # hundred: Hundred
93
+ thousand: Thousand
94
+ million: Million
95
+ billion: Billion
96
+ trillion: Trillion
97
+ quadrillion: Quadrillion
59
98
 
60
99
  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
61
100
  datetime: