actionpack 3.0.0.beta4 → 3.0.0.rc
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.
- data/CHANGELOG +36 -0
- data/{README → README.rdoc} +79 -137
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +3 -12
- data/lib/abstract_controller/rendering.rb +2 -2
- data/lib/abstract_controller/view_paths.rb +2 -1
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +3 -9
- data/lib/action_controller/log_subscriber.rb +56 -0
- data/lib/action_controller/metal.rb +10 -3
- data/lib/action_controller/metal/helpers.rb +5 -4
- data/lib/action_controller/metal/hide_actions.rb +3 -3
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/mime_responds.rb +13 -10
- data/lib/action_controller/metal/rack_delegation.rb +0 -4
- data/lib/action_controller/metal/request_forgery_protection.rb +1 -1
- data/lib/action_controller/metal/rescue.rb +9 -0
- data/lib/action_controller/metal/responder.rb +13 -5
- data/lib/action_controller/metal/streaming.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +5 -5
- data/lib/action_controller/railtie.rb +14 -23
- data/lib/action_controller/record_identifier.rb +6 -25
- data/lib/action_controller/test_case.rb +18 -6
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -0
- data/lib/action_dispatch.rb +6 -0
- data/lib/action_dispatch/http/cache.rb +2 -2
- data/lib/action_dispatch/http/filter_parameters.rb +10 -66
- data/lib/action_dispatch/http/mime_type.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +72 -0
- data/lib/action_dispatch/http/parameters.rb +31 -2
- data/lib/action_dispatch/http/request.rb +4 -1
- data/lib/action_dispatch/http/upload.rb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +4 -4
- data/lib/action_dispatch/middleware/cookies.rb +39 -6
- data/lib/action_dispatch/middleware/flash.rb +9 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +121 -36
- data/lib/action_dispatch/middleware/session/cookie_store.rb +26 -19
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/stack.rb +12 -5
- data/lib/action_dispatch/railtie.rb +1 -1
- data/lib/action_dispatch/routing.rb +11 -13
- data/lib/action_dispatch/routing/deprecated_mapper.rb +6 -388
- data/lib/action_dispatch/routing/mapper.rb +364 -234
- data/lib/action_dispatch/routing/polymorphic_routes.rb +186 -0
- data/lib/action_dispatch/routing/route.rb +11 -2
- data/lib/action_dispatch/routing/route_set.rb +62 -28
- data/lib/action_dispatch/routing/url_for.rb +2 -1
- data/lib/action_dispatch/testing/assertions.rb +0 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +0 -1
- data/lib/action_dispatch/testing/assertions/selector.rb +20 -24
- data/lib/action_dispatch/testing/integration.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +1 -0
- data/lib/action_view/base.rb +20 -21
- data/lib/action_view/context.rb +9 -12
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/helpers/active_model_helper.rb +17 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +15 -33
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -3
- data/lib/action_view/helpers/cache_helper.rb +4 -2
- data/lib/action_view/helpers/capture_helper.rb +4 -4
- data/lib/action_view/helpers/csrf_helper.rb +3 -1
- data/lib/action_view/helpers/date_helper.rb +10 -5
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +36 -30
- data/lib/action_view/helpers/form_options_helper.rb +7 -6
- data/lib/action_view/helpers/form_tag_helper.rb +17 -6
- data/lib/action_view/helpers/javascript_helper.rb +1 -0
- data/lib/action_view/helpers/number_helper.rb +16 -45
- data/lib/action_view/helpers/prototype_helper.rb +14 -16
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_tag_helper.rb +5 -0
- data/lib/action_view/helpers/sanitize_helper.rb +26 -20
- data/lib/action_view/helpers/scriptaculous_helper.rb +6 -5
- data/lib/action_view/helpers/tag_helper.rb +2 -1
- data/lib/action_view/helpers/text_helper.rb +24 -111
- data/lib/action_view/helpers/translation_helper.rb +17 -10
- data/lib/action_view/helpers/url_helper.rb +26 -33
- data/lib/action_view/log_subscriber.rb +28 -0
- data/lib/action_view/lookup_context.rb +2 -0
- data/lib/action_view/paths.rb +1 -0
- data/lib/action_view/railtie.rb +15 -3
- data/lib/action_view/render/layouts.rb +2 -1
- data/lib/action_view/render/partials.rb +3 -1
- data/lib/action_view/render/rendering.rb +2 -1
- data/lib/action_view/template.rb +12 -8
- data/lib/action_view/template/error.rb +1 -0
- data/lib/action_view/template/handlers.rb +1 -0
- data/lib/action_view/template/resolver.rb +2 -1
- data/lib/action_view/template/text.rb +1 -0
- data/lib/action_view/test_case.rb +42 -20
- metadata +44 -23
- data/lib/action_controller/polymorphic_routes.rb +0 -182
- data/lib/action_controller/railties/log_subscriber.rb +0 -56
- data/lib/action_controller/railties/url_helpers.rb +0 -14
- data/lib/action_dispatch/testing/assertions/model.rb +0 -19
- data/lib/action_view/helpers/record_identification_helper.rb +0 -20
- data/lib/action_view/railties/log_subscriber.rb +0 -24
@@ -1,21 +1,28 @@
|
|
1
1
|
require 'action_view/helpers/tag_helper'
|
2
2
|
|
3
3
|
module ActionView
|
4
|
+
# = Action View Translation Helpers
|
4
5
|
module Helpers
|
5
6
|
module TranslationHelper
|
6
|
-
# Delegates to I18n#translate but also performs three additional functions.
|
7
|
-
#
|
7
|
+
# Delegates to I18n#translate but also performs three additional functions.
|
8
|
+
# First, it'll catch MissingTranslationData exceptions and turn them into
|
9
|
+
# inline spans that contains the missing key, such that you can see in a
|
10
|
+
# view what is missing where.
|
8
11
|
#
|
9
|
-
# Second, it'll scope the key by the current partial if the key starts
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
12
|
+
# Second, it'll scope the key by the current partial if the key starts
|
13
|
+
# with a period. So if you call <tt>translate(".foo")</tt> from the
|
14
|
+
# <tt>people/index.html.erb</tt> template, you'll actually be calling
|
15
|
+
# <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
|
16
|
+
# to translate many keys within the same partials and gives you a simple framework
|
17
|
+
# for scoping them consistently. If you don't prepend the key with a period,
|
18
|
+
# nothing is converted.
|
13
19
|
#
|
14
|
-
# Third, it
|
15
|
-
# "
|
16
|
-
#
|
20
|
+
# Third, it'll mark the translation as safe HTML if the key has the suffix
|
21
|
+
# "_html" or the last element of the key is the word "html". For example,
|
22
|
+
# calling translate("footer_html") or translate("footer.html") will return
|
23
|
+
# a safe HTML string that won't be escaped by other HTML helper methods. This
|
24
|
+
# naming convention helps to identify translations that include HTML tags so that
|
17
25
|
# you know what kind of output to expect when you call translate in a template.
|
18
|
-
|
19
26
|
def translate(key, options = {})
|
20
27
|
translation = I18n.translate(scope_key_by_partial(key), options.merge!(:raise => true))
|
21
28
|
if html_safe_translation_key?(key) && translation.respond_to?(:html_safe)
|
@@ -4,6 +4,7 @@ require 'active_support/core_ext/hash/keys'
|
|
4
4
|
require 'action_dispatch'
|
5
5
|
|
6
6
|
module ActionView
|
7
|
+
# = Action View URL Helpers
|
7
8
|
module Helpers #:nodoc:
|
8
9
|
# Provides a set of methods for making links and getting URLs that
|
9
10
|
# depend on the routing subsystem (see ActionDispatch::Routing).
|
@@ -11,8 +12,8 @@ module ActionView
|
|
11
12
|
# and controllers.
|
12
13
|
module UrlHelper
|
13
14
|
# This helper may be included in any class that includes the
|
14
|
-
# URL helpers of a
|
15
|
-
# provided here will only work in
|
15
|
+
# URL helpers of a routes (routes.url_helpers). Some methods
|
16
|
+
# provided here will only work in the4 context of a request
|
16
17
|
# (link_to_unless_current, for instance), which must be provided
|
17
18
|
# as a method called #request on the context.
|
18
19
|
|
@@ -37,9 +38,6 @@ module ActionView
|
|
37
38
|
# <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action"
|
38
39
|
# instead of the fully qualified URL like "http://example.com/controller/action".
|
39
40
|
#
|
40
|
-
# When called from a view, +url_for+ returns an HTML escaped url. If you
|
41
|
-
# need an unescaped url, pass <tt>:escape => false</tt> in the +options+.
|
42
|
-
#
|
43
41
|
# ==== Options
|
44
42
|
# * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path.
|
45
43
|
# * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified).
|
@@ -49,7 +47,6 @@ module ActionView
|
|
49
47
|
# * <tt>:protocol</tt> - Overrides the default (current) protocol if provided.
|
50
48
|
# * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present).
|
51
49
|
# * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present).
|
52
|
-
# * <tt>:escape</tt> - Determines whether the returned URL will be HTML escaped or not (<tt>true</tt> by default).
|
53
50
|
#
|
54
51
|
# ==== Relying on named routes
|
55
52
|
#
|
@@ -71,10 +68,7 @@ module ActionView
|
|
71
68
|
# <%= url_for(:action => 'play', :anchor => 'player') %>
|
72
69
|
# # => /messages/play/#player
|
73
70
|
#
|
74
|
-
# <%= url_for(:action => '
|
75
|
-
# # => /testing/jump/#tax&ship
|
76
|
-
#
|
77
|
-
# <%= url_for(:action => 'checkout', :anchor => 'tax&ship', :escape => false) %>
|
71
|
+
# <%= url_for(:action => 'jump', :anchor => 'tax&ship') %>
|
78
72
|
# # => /testing/jump/#tax&ship
|
79
73
|
#
|
80
74
|
# <%= url_for(Workshop.new) %>
|
@@ -99,21 +93,17 @@ module ActionView
|
|
99
93
|
options ||= {}
|
100
94
|
url = case options
|
101
95
|
when String
|
102
|
-
escape = true
|
103
96
|
options
|
104
97
|
when Hash
|
105
|
-
options =
|
106
|
-
escape = options.key?(:escape) ? options.delete(:escape) : false
|
98
|
+
options = options.symbolize_keys.reverse_merge!(:only_path => options[:host].nil?)
|
107
99
|
super
|
108
100
|
when :back
|
109
|
-
escape = false
|
110
101
|
controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
|
111
102
|
else
|
112
|
-
escape = false
|
113
103
|
polymorphic_path(options)
|
114
104
|
end
|
115
105
|
|
116
|
-
|
106
|
+
url
|
117
107
|
end
|
118
108
|
|
119
109
|
# Creates a link tag of the given +name+ using a URL created by the set
|
@@ -253,8 +243,8 @@ module ActionView
|
|
253
243
|
tag_options = nil
|
254
244
|
end
|
255
245
|
|
256
|
-
href_attr = "href=\"#{url}\"" unless href
|
257
|
-
"<a #{href_attr}#{tag_options}>#{
|
246
|
+
href_attr = "href=\"#{html_escape(url)}\"" unless href
|
247
|
+
"<a #{href_attr}#{tag_options}>#{html_escape(name || url)}</a>".html_safe
|
258
248
|
end
|
259
249
|
end
|
260
250
|
|
@@ -338,7 +328,7 @@ module ActionView
|
|
338
328
|
|
339
329
|
html_options.merge!("type" => "submit", "value" => name)
|
340
330
|
|
341
|
-
("<form method=\"#{form_method}\" action=\"#{
|
331
|
+
("<form method=\"#{form_method}\" action=\"#{html_escape(url)}\" #{"data-remote=\"true\"" if remote} class=\"button_to\"><div>" +
|
342
332
|
method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe
|
343
333
|
end
|
344
334
|
|
@@ -408,7 +398,7 @@ module ActionView
|
|
408
398
|
def link_to_unless(condition, name, options = {}, html_options = {}, &block)
|
409
399
|
if condition
|
410
400
|
if block_given?
|
411
|
-
block.arity <= 1 ?
|
401
|
+
block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
|
412
402
|
else
|
413
403
|
name
|
414
404
|
end
|
@@ -484,24 +474,27 @@ module ActionView
|
|
484
474
|
# :subject => "This is an example email"
|
485
475
|
# # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
|
486
476
|
def mail_to(email_address, name = nil, html_options = {})
|
477
|
+
email_address = html_escape(email_address)
|
478
|
+
|
487
479
|
html_options = html_options.stringify_keys
|
488
480
|
encode = html_options.delete("encode").to_s
|
489
481
|
cc, bcc, subject, body = html_options.delete("cc"), html_options.delete("bcc"), html_options.delete("subject"), html_options.delete("body")
|
490
482
|
|
491
|
-
|
492
|
-
extras
|
493
|
-
extras << "
|
494
|
-
extras << "
|
495
|
-
extras << "
|
496
|
-
extras
|
497
|
-
|
498
|
-
|
499
|
-
email_address_obfuscated = html_escape(email_address)
|
483
|
+
extras = []
|
484
|
+
extras << "cc=#{Rack::Utils.escape(cc).gsub("+", "%20")}" unless cc.nil?
|
485
|
+
extras << "bcc=#{Rack::Utils.escape(bcc).gsub("+", "%20")}" unless bcc.nil?
|
486
|
+
extras << "body=#{Rack::Utils.escape(body).gsub("+", "%20")}" unless body.nil?
|
487
|
+
extras << "subject=#{Rack::Utils.escape(subject).gsub("+", "%20")}" unless subject.nil?
|
488
|
+
extras = extras.empty? ? '' : '?' + html_escape(extras.join('&'))
|
489
|
+
|
490
|
+
email_address_obfuscated = email_address.dup
|
500
491
|
email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at")
|
501
492
|
email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
|
502
493
|
|
494
|
+
string = ''
|
495
|
+
|
503
496
|
if encode == "javascript"
|
504
|
-
"document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge(
|
497
|
+
"document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe))}');".each_byte do |c|
|
505
498
|
string << sprintf("%%%x", c)
|
506
499
|
end
|
507
500
|
"<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>".html_safe
|
@@ -518,9 +511,9 @@ module ActionView
|
|
518
511
|
char = c.chr
|
519
512
|
string << (char =~ /\w/ ? sprintf("%%%x", c) : char)
|
520
513
|
end
|
521
|
-
content_tag "a", name || email_address_encoded.html_safe, html_options.merge(
|
514
|
+
content_tag "a", name || email_address_encoded.html_safe, html_options.merge("href" => "#{string}#{extras}".html_safe)
|
522
515
|
else
|
523
|
-
content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge(
|
516
|
+
content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)
|
524
517
|
end
|
525
518
|
end
|
526
519
|
|
@@ -573,7 +566,7 @@ module ActionView
|
|
573
566
|
"in a #request method"
|
574
567
|
end
|
575
568
|
|
576
|
-
url_string =
|
569
|
+
url_string = url_for(options)
|
577
570
|
|
578
571
|
# We ignore any extra parameters in the request_uri if the
|
579
572
|
# submitted url doesn't have any either. This lets the function
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActionView
|
2
|
+
# = Action View Log Subscriber
|
3
|
+
#
|
4
|
+
# Provides functionality so that Rails can output logs from Action View.
|
5
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
6
|
+
def render_template(event)
|
7
|
+
message = "Rendered #{from_rails_root(event.payload[:identifier])}"
|
8
|
+
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
9
|
+
message << (" (%.1fms)" % event.duration)
|
10
|
+
info(message)
|
11
|
+
end
|
12
|
+
alias :render_partial :render_template
|
13
|
+
alias :render_collection :render_template
|
14
|
+
|
15
|
+
# TODO: Ideally, ActionView should have its own logger so it does not depend on AC.logger
|
16
|
+
def logger
|
17
|
+
ActionController::Base.logger if defined?(ActionController::Base)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def from_rails_root(string)
|
23
|
+
string.sub("#{Rails.root}/", "").sub(/^app\/views\//, "")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
ActionView::LogSubscriber.attach_to :action_view
|
@@ -2,6 +2,8 @@ require 'active_support/core_ext/array/wrap'
|
|
2
2
|
require 'active_support/core_ext/object/blank'
|
3
3
|
|
4
4
|
module ActionView
|
5
|
+
# = Action View Lookup Context
|
6
|
+
#
|
5
7
|
# LookupContext is the object responsible to hold all information required to lookup
|
6
8
|
# templates, i.e. view paths and details. The LookupContext is also responsible to
|
7
9
|
# generate a key, given to view paths, used in the resolver cache lookup. Since
|
data/lib/action_view/paths.rb
CHANGED
data/lib/action_view/railtie.rb
CHANGED
@@ -2,11 +2,11 @@ require "action_view"
|
|
2
2
|
require "rails"
|
3
3
|
|
4
4
|
module ActionView
|
5
|
+
# = Action View Railtie
|
5
6
|
class Railtie < Rails::Railtie
|
6
7
|
config.action_view = ActiveSupport::OrderedOptions.new
|
7
|
-
|
8
|
-
|
9
|
-
log_subscriber :action_view, ActionView::Railties::LogSubscriber.new
|
8
|
+
config.action_view.stylesheet_expansions = {}
|
9
|
+
config.action_view.javascript_expansions = { :defaults => ['prototype', 'effects', 'dragdrop', 'controls', 'rails'] }
|
10
10
|
|
11
11
|
initializer "action_view.cache_asset_timestamps" do |app|
|
12
12
|
unless app.config.cache_classes
|
@@ -16,6 +16,18 @@ module ActionView
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
initializer "action_view.javascript_expansions" do |app|
|
20
|
+
ActiveSupport.on_load(:action_view) do
|
21
|
+
ActionView::Helpers::AssetTagHelper.register_javascript_expansion(
|
22
|
+
app.config.action_view.delete(:javascript_expansions)
|
23
|
+
)
|
24
|
+
|
25
|
+
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion(
|
26
|
+
app.config.action_view.delete(:stylesheet_expansions)
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
initializer "action_view.set_configs" do |app|
|
20
32
|
ActiveSupport.on_load(:action_view) do
|
21
33
|
app.config.action_view.each do |k,v|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module ActionView
|
2
|
+
# = Action View Layouts
|
2
3
|
module Layouts
|
3
4
|
# Returns the contents that are yielded to a layout, given a name or a block.
|
4
5
|
#
|
@@ -55,7 +56,7 @@ module ActionView
|
|
55
56
|
end
|
56
57
|
|
57
58
|
# This is the method which actually finds the layout using details in the lookup
|
58
|
-
# context object. If no layout is found, it
|
59
|
+
# context object. If no layout is found, it checks if at least a layout with
|
59
60
|
# the given name exists across all details before raising the error.
|
60
61
|
def find_layout(layout)
|
61
62
|
begin
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'active_support/core_ext/object/blank'
|
2
2
|
|
3
3
|
module ActionView
|
4
|
+
# = Action View Partials
|
5
|
+
#
|
4
6
|
# There's also a convenience method for rendering sub templates within the current controller that depends on a
|
5
7
|
# single object (we call this kind of sub templates for partials). It relies on the fact that partials should
|
6
8
|
# follow the naming convention of being prefixed with an underscore -- as to separate them from regular
|
@@ -316,7 +318,7 @@ module ActionView
|
|
316
318
|
|
317
319
|
object.class.model_name.partial_path.dup.tap do |partial|
|
318
320
|
path = @view.controller_path
|
319
|
-
partial.insert(0, "#{File.dirname(path)}/") if path.include?(?/)
|
321
|
+
partial.insert(0, "#{File.dirname(path)}/") if partial.include?(?/) && path.include?(?/)
|
320
322
|
end
|
321
323
|
end
|
322
324
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_support/core_ext/object/try'
|
2
2
|
|
3
3
|
module ActionView
|
4
|
+
# = Action View Rendering
|
4
5
|
module Rendering
|
5
6
|
# Returns the result of a render that's dictated by the options hash. The primary options are:
|
6
7
|
#
|
@@ -56,7 +57,7 @@ module ActionView
|
|
56
57
|
:identifier => template.identifier, :layout => layout.try(:virtual_path)) do
|
57
58
|
|
58
59
|
content = template.render(self, locals) { |*name| _layout_for(*name) }
|
59
|
-
@_content_for[:layout] = content
|
60
|
+
@_content_for[:layout] = content if layout
|
60
61
|
|
61
62
|
content = _render_layout(layout, locals) if layout
|
62
63
|
content
|
data/lib/action_view/template.rb
CHANGED
@@ -3,6 +3,7 @@ require 'active_support/core_ext/object/blank'
|
|
3
3
|
require 'active_support/core_ext/kernel/singleton_class'
|
4
4
|
|
5
5
|
module ActionView
|
6
|
+
# = Action View Template
|
6
7
|
class Template
|
7
8
|
extend ActiveSupport::Autoload
|
8
9
|
|
@@ -155,11 +156,12 @@ module ActionView
|
|
155
156
|
end
|
156
157
|
|
157
158
|
def inspect
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
159
|
+
@inspect ||=
|
160
|
+
if defined?(Rails.root)
|
161
|
+
identifier.sub("#{Rails.root}/", '')
|
162
|
+
else
|
163
|
+
identifier
|
164
|
+
end
|
163
165
|
end
|
164
166
|
|
165
167
|
private
|
@@ -266,9 +268,11 @@ module ActionView
|
|
266
268
|
end
|
267
269
|
|
268
270
|
def build_method_name(locals)
|
269
|
-
|
270
|
-
|
271
|
-
|
271
|
+
@method_names[locals.keys.hash] ||= "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}_#{locals.keys.hash}".gsub('-', "_")
|
272
|
+
end
|
273
|
+
|
274
|
+
def identifier_method_name
|
275
|
+
@identifier_method_name ||= inspect.gsub(/[^a-z_]/, '_')
|
272
276
|
end
|
273
277
|
end
|
274
278
|
end
|
@@ -3,6 +3,7 @@ require "active_support/core_ext/class"
|
|
3
3
|
require "action_view/template"
|
4
4
|
|
5
5
|
module ActionView
|
6
|
+
# = Action View Resolver
|
6
7
|
class Resolver
|
7
8
|
def initialize
|
8
9
|
@cached = Hash.new { |h1,k1| h1[k1] =
|
@@ -98,7 +99,7 @@ module ActionView
|
|
98
99
|
def initialize(path)
|
99
100
|
raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
|
100
101
|
super()
|
101
|
-
@path =
|
102
|
+
@path = File.expand_path(path)
|
102
103
|
end
|
103
104
|
|
104
105
|
def eql?(resolver)
|
@@ -4,6 +4,7 @@ require 'action_controller/test_case'
|
|
4
4
|
require 'action_view'
|
5
5
|
|
6
6
|
module ActionView
|
7
|
+
# = Action View Test Case
|
7
8
|
class TestCase < ActiveSupport::TestCase
|
8
9
|
class TestController < ActionController::Base
|
9
10
|
include ActionDispatch::TestProcess
|
@@ -36,7 +37,7 @@ module ActionView
|
|
36
37
|
include ActionController::TemplateAssertions
|
37
38
|
include ActionView::Context
|
38
39
|
|
39
|
-
include
|
40
|
+
include ActionDispatch::Routing::PolymorphicRoutes
|
40
41
|
include ActionController::RecordIdentifier
|
41
42
|
|
42
43
|
include AbstractController::Helpers
|
@@ -84,6 +85,7 @@ module ActionView
|
|
84
85
|
|
85
86
|
def setup_with_controller
|
86
87
|
@controller = ActionView::TestCase::TestController.new
|
88
|
+
@request = @controller.request
|
87
89
|
@output_buffer = ActiveSupport::SafeBuffer.new
|
88
90
|
@rendered = ''
|
89
91
|
|
@@ -97,10 +99,15 @@ module ActionView
|
|
97
99
|
end
|
98
100
|
|
99
101
|
def render(options = {}, local_assigns = {}, &block)
|
100
|
-
|
102
|
+
view.assign(_assigns)
|
103
|
+
@rendered << output = view.render(options, local_assigns, &block)
|
101
104
|
output
|
102
105
|
end
|
103
106
|
|
107
|
+
def locals
|
108
|
+
@locals ||= {}
|
109
|
+
end
|
110
|
+
|
104
111
|
included do
|
105
112
|
setup :setup_with_controller
|
106
113
|
end
|
@@ -130,36 +137,51 @@ module ActionView
|
|
130
137
|
end
|
131
138
|
end
|
132
139
|
|
133
|
-
|
134
|
-
|
135
|
-
|
140
|
+
module Locals
|
141
|
+
attr_accessor :locals
|
142
|
+
|
143
|
+
def _render_partial(options)
|
144
|
+
locals[options[:partial]] = options[:locals]
|
145
|
+
super(options)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# The instance of ActionView::Base that is used by +render+.
|
150
|
+
def view
|
151
|
+
@view ||= begin
|
152
|
+
view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
|
136
153
|
view.singleton_class.send :include, _helpers
|
137
|
-
view.singleton_class.send :include, @controller.
|
154
|
+
view.singleton_class.send :include, @controller._routes.url_helpers
|
138
155
|
view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
|
156
|
+
view.extend(Locals)
|
157
|
+
view.locals = self.locals
|
139
158
|
view.output_buffer = self.output_buffer
|
140
159
|
view
|
141
160
|
end
|
142
161
|
end
|
143
162
|
|
163
|
+
alias_method :_view, :view
|
164
|
+
|
144
165
|
EXCLUDE_IVARS = %w{
|
166
|
+
@_assertion_wrapped
|
145
167
|
@_result
|
168
|
+
@controller
|
169
|
+
@layouts
|
170
|
+
@locals
|
171
|
+
@method_name
|
146
172
|
@output_buffer
|
173
|
+
@partials
|
147
174
|
@rendered
|
175
|
+
@request
|
176
|
+
@routes
|
148
177
|
@templates
|
149
|
-
@view_context_class
|
150
|
-
@layouts
|
151
|
-
@partials
|
152
|
-
@controller
|
153
|
-
|
154
|
-
@method_name
|
155
|
-
@fixture_cache
|
156
|
-
@loaded_fixtures
|
157
178
|
@test_passed
|
179
|
+
@view
|
180
|
+
@view_context_class
|
158
181
|
}
|
159
182
|
|
160
183
|
def _instance_variables
|
161
|
-
instance_variables - EXCLUDE_IVARS
|
162
|
-
instance_variables
|
184
|
+
instance_variables.map(&:to_s) - EXCLUDE_IVARS
|
163
185
|
end
|
164
186
|
|
165
187
|
def _assigns
|
@@ -170,13 +192,13 @@ module ActionView
|
|
170
192
|
end
|
171
193
|
end
|
172
194
|
|
173
|
-
def
|
174
|
-
@controller.
|
195
|
+
def _routes
|
196
|
+
@controller._routes if @controller.respond_to?(:_routes)
|
175
197
|
end
|
176
198
|
|
177
199
|
def method_missing(selector, *args)
|
178
|
-
if @controller.respond_to?(:
|
179
|
-
@controller.
|
200
|
+
if @controller.respond_to?(:_routes) &&
|
201
|
+
@controller._routes.named_routes.helpers.include?(selector)
|
180
202
|
@controller.__send__(selector, *args)
|
181
203
|
else
|
182
204
|
super
|