actionpack 4.0.0.beta1 → 4.0.0.rc1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +195 -11
- data/lib/abstract_controller/base.rb +1 -1
- data/lib/abstract_controller/helpers.rb +2 -2
- data/lib/abstract_controller/layouts.rb +10 -5
- data/lib/abstract_controller/rendering.rb +11 -3
- data/lib/abstract_controller/translation.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +5 -0
- data/lib/action_controller/metal.rb +2 -3
- data/lib/action_controller/metal/force_ssl.rb +52 -17
- data/lib/action_controller/metal/helpers.rb +0 -1
- data/lib/action_controller/metal/hide_actions.rb +1 -1
- data/lib/action_controller/metal/http_authentication.rb +3 -2
- data/lib/action_controller/metal/live.rb +34 -0
- data/lib/action_controller/metal/rendering.rb +1 -1
- data/lib/action_controller/metal/strong_parameters.rb +7 -3
- data/lib/action_controller/test_case.rb +45 -11
- data/lib/action_dispatch.rb +4 -6
- data/lib/action_dispatch/http/cache.rb +2 -2
- data/lib/action_dispatch/http/headers.rb +39 -15
- data/lib/action_dispatch/http/mime_negotiation.rb +1 -1
- data/lib/action_dispatch/http/mime_type.rb +11 -3
- data/lib/action_dispatch/http/parameters.rb +17 -24
- data/lib/action_dispatch/http/request.rb +17 -2
- data/lib/action_dispatch/http/response.rb +2 -1
- data/lib/action_dispatch/http/upload.rb +5 -5
- data/lib/action_dispatch/http/url.rb +53 -12
- data/lib/action_dispatch/journey/formatter.rb +1 -1
- data/lib/action_dispatch/journey/path/pattern.rb +1 -1
- data/lib/action_dispatch/journey/route.rb +8 -0
- data/lib/action_dispatch/journey/router.rb +3 -1
- data/lib/action_dispatch/journey/visitors.rb +8 -0
- data/lib/action_dispatch/middleware/cookies.rb +169 -135
- data/lib/action_dispatch/middleware/exception_wrapper.rb +1 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +2 -2
- data/lib/action_dispatch/middleware/request_id.rb +1 -1
- data/lib/action_dispatch/middleware/session/cookie_store.rb +38 -58
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +4 -6
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +1 -1
- data/lib/action_dispatch/routing.rb +28 -64
- data/lib/action_dispatch/routing/mapper.rb +61 -48
- data/lib/action_dispatch/routing/route_set.rb +17 -14
- data/lib/action_dispatch/testing/assertions/routing.rb +2 -2
- data/lib/action_dispatch/testing/assertions/selector.rb +2 -2
- data/lib/action_dispatch/testing/integration.rb +36 -35
- data/lib/action_dispatch/testing/test_process.rb +1 -1
- data/lib/action_pack/version.rb +7 -6
- data/lib/action_view/buffers.rb +6 -0
- data/lib/action_view/dependency_tracker.rb +3 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +13 -8
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/date_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +56 -19
- data/lib/action_view/helpers/form_options_helper.rb +3 -3
- data/lib/action_view/helpers/form_tag_helper.rb +1 -1
- data/lib/action_view/helpers/javascript_helper.rb +2 -2
- data/lib/action_view/helpers/number_helper.rb +25 -0
- data/lib/action_view/helpers/tags/base.rb +9 -10
- data/lib/action_view/helpers/tags/check_box.rb +1 -1
- data/lib/action_view/helpers/tags/checkable.rb +2 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +3 -3
- data/lib/action_view/helpers/tags/collection_helpers.rb +3 -3
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -3
- data/lib/action_view/helpers/tags/collection_select.rb +1 -1
- data/lib/action_view/helpers/tags/color_field.rb +2 -2
- data/lib/action_view/helpers/tags/date_field.rb +2 -2
- data/lib/action_view/helpers/tags/date_select.rb +2 -2
- data/lib/action_view/helpers/tags/datetime_field.rb +2 -2
- data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -2
- data/lib/action_view/helpers/tags/datetime_select.rb +2 -2
- data/lib/action_view/helpers/tags/email_field.rb +2 -2
- data/lib/action_view/helpers/tags/file_field.rb +2 -2
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/hidden_field.rb +2 -2
- data/lib/action_view/helpers/tags/label.rb +2 -2
- data/lib/action_view/helpers/tags/month_field.rb +2 -2
- data/lib/action_view/helpers/tags/number_field.rb +2 -2
- data/lib/action_view/helpers/tags/password_field.rb +2 -2
- data/lib/action_view/helpers/tags/radio_button.rb +2 -2
- data/lib/action_view/helpers/tags/range_field.rb +2 -2
- data/lib/action_view/helpers/tags/search_field.rb +2 -2
- data/lib/action_view/helpers/tags/select.rb +2 -3
- data/lib/action_view/helpers/tags/tel_field.rb +2 -2
- data/lib/action_view/helpers/tags/text_area.rb +2 -2
- data/lib/action_view/helpers/tags/text_field.rb +2 -2
- data/lib/action_view/helpers/tags/time_field.rb +2 -2
- data/lib/action_view/helpers/tags/time_select.rb +2 -2
- data/lib/action_view/helpers/tags/time_zone_select.rb +2 -2
- data/lib/action_view/helpers/tags/url_field.rb +2 -2
- data/lib/action_view/helpers/tags/week_field.rb +2 -2
- data/lib/action_view/helpers/text_helper.rb +8 -5
- data/lib/action_view/helpers/url_helper.rb +18 -6
- data/lib/action_view/lookup_context.rb +7 -1
- data/lib/action_view/path_set.rb +6 -0
- data/lib/action_view/renderer/abstract_renderer.rb +15 -0
- data/lib/action_view/renderer/partial_renderer.rb +14 -0
- data/lib/action_view/renderer/renderer.rb +6 -0
- data/lib/action_view/template.rb +3 -2
- data/lib/action_view/template/handlers/erb.rb +29 -3
- data/lib/action_view/template/resolver.rb +3 -3
- data/lib/action_view/test_case.rb +1 -0
- data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +5 -5
- data/lib/action_view/vendor/html-scanner/html/selector.rb +8 -8
- metadata +8 -8
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActionView
|
2
2
|
module Helpers
|
3
|
-
module Tags
|
4
|
-
class GroupedCollectionSelect < Base
|
3
|
+
module Tags # :nodoc:
|
4
|
+
class GroupedCollectionSelect < Base # :nodoc:
|
5
5
|
def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
|
6
6
|
@collection = collection
|
7
7
|
@group_method = group_method
|
@@ -2,8 +2,8 @@ require 'action_view/helpers/tags/checkable'
|
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
module Helpers
|
5
|
-
module Tags
|
6
|
-
class RadioButton < Base
|
5
|
+
module Tags # :nodoc:
|
6
|
+
class RadioButton < Base # :nodoc:
|
7
7
|
include Checkable
|
8
8
|
|
9
9
|
def initialize(object_name, method_name, template_object, tag_value, options)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActionView
|
2
2
|
module Helpers
|
3
|
-
module Tags
|
4
|
-
class Select < Base
|
3
|
+
module Tags # :nodoc:
|
4
|
+
class Select < Base # :nodoc:
|
5
5
|
def initialize(object_name, method_name, template_object, choices, options, html_options)
|
6
6
|
@choices = choices
|
7
7
|
@choices = @choices.to_a if @choices.is_a?(Range)
|
@@ -31,7 +31,6 @@ module ActionView
|
|
31
31
|
#
|
32
32
|
# [nil, []]
|
33
33
|
# { nil => [] }
|
34
|
-
#
|
35
34
|
def grouped_choices?
|
36
35
|
!@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last
|
37
36
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActionView
|
2
2
|
module Helpers
|
3
|
-
module Tags
|
4
|
-
class TimeZoneSelect < Base
|
3
|
+
module Tags # :nodoc:
|
4
|
+
class TimeZoneSelect < Base # :nodoc:
|
5
5
|
def initialize(object_name, method_name, template_object, priority_zones, options, html_options)
|
6
6
|
@priority_zones = priority_zones
|
7
7
|
@html_options = html_options
|
@@ -126,8 +126,8 @@ module ActionView
|
|
126
126
|
# Extracts an excerpt from +text+ that matches the first instance of +phrase+.
|
127
127
|
# The <tt>:radius</tt> option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
|
128
128
|
# defined in <tt>:radius</tt> (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
|
129
|
-
# then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly.
|
130
|
-
# <tt>:separator</tt>
|
129
|
+
# then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. Use the
|
130
|
+
# <tt>:separator</tt> option to choose the delimitation. The resulting string will be stripped in any case. If the +phrase+
|
131
131
|
# isn't found, nil is returned.
|
132
132
|
#
|
133
133
|
# excerpt('This is an example', 'an', radius: 5)
|
@@ -145,7 +145,7 @@ module ActionView
|
|
145
145
|
# excerpt('This is also an example', 'an', radius: 8, omission: '<chop> ')
|
146
146
|
# # => <chop> is also an example
|
147
147
|
#
|
148
|
-
# excerpt('This is a very beautiful morning', 'very', separator:
|
148
|
+
# excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1)
|
149
149
|
# # => ...a very beautiful...
|
150
150
|
def excerpt(text, phrase, options = {})
|
151
151
|
return unless text && phrase
|
@@ -250,8 +250,11 @@ module ActionView
|
|
250
250
|
# simple_format("Look ma! A class!", class: 'description')
|
251
251
|
# # => "<p class='description'>Look ma! A class!</p>"
|
252
252
|
#
|
253
|
-
# simple_format("<
|
254
|
-
# # => "<p
|
253
|
+
# simple_format("<blink>Unblinkable.</blink>")
|
254
|
+
# # => "<p>Unblinkable.</p>"
|
255
|
+
#
|
256
|
+
# simple_format("<blink>Blinkable!</blink> It's true.", {}, sanitize: false)
|
257
|
+
# # => "<p><blink>Blinkable!</span> It's true.</p>"
|
255
258
|
def simple_format(text, html_options = {}, options = {})
|
256
259
|
wrapper_tag = options.fetch(:wrapper_tag, :p)
|
257
260
|
|
@@ -425,8 +425,8 @@ module ActionView
|
|
425
425
|
# * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
|
426
426
|
#
|
427
427
|
# ==== Obfuscation
|
428
|
-
# Prior to Rails 4.0, +mail_to+ provided options for encoding the address
|
429
|
-
# in order to hinder email harvesters. To take advantage of these options,
|
428
|
+
# Prior to Rails 4.0, +mail_to+ provided options for encoding the address
|
429
|
+
# in order to hinder email harvesters. To take advantage of these options,
|
430
430
|
# install the +actionview-encoded_mail_to+ gem.
|
431
431
|
#
|
432
432
|
# ==== Examples
|
@@ -439,18 +439,30 @@ module ActionView
|
|
439
439
|
# mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com",
|
440
440
|
# subject: "This is an example email"
|
441
441
|
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
|
442
|
-
|
442
|
+
#
|
443
|
+
# You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
|
444
|
+
#
|
445
|
+
# <%= mail_to "me@domain.com" do %>
|
446
|
+
# <strong>Email me:</strong> <span>me@domain.com</span>
|
447
|
+
# <% end %>
|
448
|
+
# # => <a href="mailto:me@domain.com">
|
449
|
+
# <strong>Email me:</strong> <span>me@domain.com</span>
|
450
|
+
# </a>
|
451
|
+
def mail_to(email_address, name = nil, html_options = {}, &block)
|
443
452
|
email_address = ERB::Util.html_escape(email_address)
|
444
453
|
|
445
|
-
html_options
|
454
|
+
html_options, name = name, nil if block_given?
|
455
|
+
html_options = (html_options || {}).stringify_keys
|
446
456
|
|
447
457
|
extras = %w{ cc bcc body subject }.map { |item|
|
448
458
|
option = html_options.delete(item) || next
|
449
459
|
"#{item}=#{Rack::Utils.escape_path(option)}"
|
450
460
|
}.compact
|
451
461
|
extras = extras.empty? ? '' : '?' + ERB::Util.html_escape(extras.join('&'))
|
452
|
-
|
453
|
-
|
462
|
+
|
463
|
+
html_options["href"] = "mailto:#{email_address}#{extras}".html_safe
|
464
|
+
|
465
|
+
content_tag(:a, name || email_address.html_safe, html_options, &block)
|
454
466
|
end
|
455
467
|
|
456
468
|
# True if the current request URI was generated by the given +options+.
|
@@ -43,7 +43,13 @@ module ActionView
|
|
43
43
|
module Accessors #:nodoc:
|
44
44
|
end
|
45
45
|
|
46
|
-
register_detail(:locale)
|
46
|
+
register_detail(:locale) do
|
47
|
+
locales = [I18n.locale]
|
48
|
+
locales.concat(I18n.fallbacks[I18n.locale]) if I18n.respond_to? :fallbacks
|
49
|
+
locales << I18n.default_locale
|
50
|
+
locales.uniq!
|
51
|
+
locales
|
52
|
+
end
|
47
53
|
register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] }
|
48
54
|
register_detail(:handlers){ Template::Handlers.extensions }
|
49
55
|
|
data/lib/action_view/path_set.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
module ActionView #:nodoc:
|
2
2
|
# = Action View PathSet
|
3
|
+
#
|
4
|
+
# This class is used to store and access paths in Action View. A number of
|
5
|
+
# operations are defined so that you can search among the paths in this
|
6
|
+
# set and also perform operations on other +PathSet+ objects.
|
7
|
+
#
|
8
|
+
# A +LookupContext+ will use a +PathSet+ to store the paths in its context.
|
3
9
|
class PathSet #:nodoc:
|
4
10
|
include Enumerable
|
5
11
|
|
@@ -1,4 +1,19 @@
|
|
1
1
|
module ActionView
|
2
|
+
# This class defines the interface for a renderer. Each class that
|
3
|
+
# subclasses +AbstractRenderer+ is used by the base +Renderer+ class to
|
4
|
+
# render a specific type of object.
|
5
|
+
#
|
6
|
+
# The base +Renderer+ class uses its +render+ method to delegate to the
|
7
|
+
# renderers. These currently consist of
|
8
|
+
#
|
9
|
+
# PartialRenderer - Used for rendering partials
|
10
|
+
# TemplateRenderer - Used for rendering other types of templates
|
11
|
+
# StreamingTemplateRenderer - Used for streaming
|
12
|
+
#
|
13
|
+
# Whenever the +render+ method is called on the base +Renderer+ class, a new
|
14
|
+
# renderer object of the correct type is created, and the +render+ method on
|
15
|
+
# that new object is called in turn. This abstracts the setup and rendering
|
16
|
+
# into a separate classes for partials and templates.
|
2
17
|
class AbstractRenderer #:nodoc:
|
3
18
|
delegate :find_template, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context
|
4
19
|
|
@@ -313,6 +313,13 @@ module ActionView
|
|
313
313
|
|
314
314
|
private
|
315
315
|
|
316
|
+
# Sets up instance variables needed for rendering a partial. This method
|
317
|
+
# finds the options and details and extracts them. The method also contains
|
318
|
+
# logic that handles the type of object passed in as the partial.
|
319
|
+
#
|
320
|
+
# If +options[:partial]+ is a string, then the +@path+ instance variable is
|
321
|
+
# set to that string. Otherwise, the +options[:partial]+ object must
|
322
|
+
# respond to +to_partial_path+ in order to setup the path.
|
316
323
|
def setup(context, options, block)
|
317
324
|
@view = context
|
318
325
|
partial = options[:partial]
|
@@ -413,6 +420,13 @@ module ActionView
|
|
413
420
|
end
|
414
421
|
end
|
415
422
|
|
423
|
+
# Obtains the path to where the object's partial is located. If the object
|
424
|
+
# responds to +to_partial_path+, then +to_partial_path+ will be called and
|
425
|
+
# will provide the path. If the object does not respond to +to_partial_path+,
|
426
|
+
# then an +ArgumentError+ is raised.
|
427
|
+
#
|
428
|
+
# If +prefix_partial_path_with_controller_namespace+ is true, then this
|
429
|
+
# method will prefix the partial paths with a namespace.
|
416
430
|
def partial_path(object = @object)
|
417
431
|
object = object.to_model if object.respond_to?(:to_model)
|
418
432
|
|
@@ -2,6 +2,12 @@ module ActionView
|
|
2
2
|
# This is the main entry point for rendering. It basically delegates
|
3
3
|
# to other objects like TemplateRenderer and PartialRenderer which
|
4
4
|
# actually renders the template.
|
5
|
+
#
|
6
|
+
# The Renderer will parse the options from the +render+ or +render_body+
|
7
|
+
# method and render a partial or a template based on the options. The
|
8
|
+
# +TemplateRenderer+ and +PartialRenderer+ objects are wrappers which do all
|
9
|
+
# the setup and logic necessary to render a view and a new object is created
|
10
|
+
# each time +render+ is called.
|
5
11
|
class Renderer
|
6
12
|
attr_accessor :lookup_context
|
7
13
|
|
data/lib/action_view/template.rb
CHANGED
@@ -138,7 +138,7 @@ module ActionView
|
|
138
138
|
# we use a bang in this instrumentation because you don't want to
|
139
139
|
# consume this in production. This is only slow if it's being listened to.
|
140
140
|
def render(view, locals, buffer=nil, &block)
|
141
|
-
ActiveSupport::Notifications.instrument("!render_template.action_view", :virtual_path
|
141
|
+
ActiveSupport::Notifications.instrument("!render_template.action_view", virtual_path: @virtual_path, identifier: @identifier) do
|
142
142
|
compile!(view)
|
143
143
|
view.send(method_name, locals, buffer, &block)
|
144
144
|
end
|
@@ -324,7 +324,8 @@ module ActionView
|
|
324
324
|
end
|
325
325
|
|
326
326
|
def locals_code #:nodoc:
|
327
|
-
|
327
|
+
# Double assign to suppress the dreaded 'assigned but unused variable' warning
|
328
|
+
@locals.map { |key| "#{key} = #{key} = local_assigns[:#{key}];" }.join
|
328
329
|
end
|
329
330
|
|
330
331
|
def method_name #:nodoc:
|
@@ -6,12 +6,23 @@ module ActionView
|
|
6
6
|
module Handlers
|
7
7
|
class Erubis < ::Erubis::Eruby
|
8
8
|
def add_preamble(src)
|
9
|
+
@newline_pending = 0
|
9
10
|
src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
|
10
11
|
end
|
11
12
|
|
12
13
|
def add_text(src, text)
|
13
14
|
return if text.empty?
|
14
|
-
|
15
|
+
|
16
|
+
if text == "\n"
|
17
|
+
@newline_pending += 1
|
18
|
+
else
|
19
|
+
src << "@output_buffer.safe_append='"
|
20
|
+
src << "\n" * @newline_pending if @newline_pending > 0
|
21
|
+
src << escape_text(text)
|
22
|
+
src << "';"
|
23
|
+
|
24
|
+
@newline_pending = 0
|
25
|
+
end
|
15
26
|
end
|
16
27
|
|
17
28
|
# Erubis toggles <%= and <%== behavior when escaping is enabled.
|
@@ -28,24 +39,39 @@ module ActionView
|
|
28
39
|
BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
|
29
40
|
|
30
41
|
def add_expr_literal(src, code)
|
42
|
+
flush_newline_if_pending(src)
|
31
43
|
if code =~ BLOCK_EXPR
|
32
44
|
src << '@output_buffer.append= ' << code
|
33
45
|
else
|
34
|
-
src << '@output_buffer.append=
|
46
|
+
src << '@output_buffer.append=(' << code << ');'
|
35
47
|
end
|
36
48
|
end
|
37
49
|
|
38
50
|
def add_expr_escaped(src, code)
|
51
|
+
flush_newline_if_pending(src)
|
39
52
|
if code =~ BLOCK_EXPR
|
40
53
|
src << "@output_buffer.safe_append= " << code
|
41
54
|
else
|
42
|
-
src << "@output_buffer.
|
55
|
+
src << "@output_buffer.safe_append=(" << code << ");"
|
43
56
|
end
|
44
57
|
end
|
45
58
|
|
59
|
+
def add_stmt(src, code)
|
60
|
+
flush_newline_if_pending(src)
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
46
64
|
def add_postamble(src)
|
65
|
+
flush_newline_if_pending(src)
|
47
66
|
src << '@output_buffer.to_s'
|
48
67
|
end
|
68
|
+
|
69
|
+
def flush_newline_if_pending(src)
|
70
|
+
if @newline_pending > 0
|
71
|
+
src << "@output_buffer.safe_append='#{"\n" * @newline_pending}';"
|
72
|
+
@newline_pending = 0
|
73
|
+
end
|
74
|
+
end
|
49
75
|
end
|
50
76
|
|
51
77
|
class ERB
|