halorgium-actionpack 3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5179 -0
- data/MIT-LICENSE +21 -0
- data/README +409 -0
- data/lib/abstract_controller.rb +16 -0
- data/lib/abstract_controller/base.rb +158 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/exceptions.rb +12 -0
- data/lib/abstract_controller/helpers.rb +151 -0
- data/lib/abstract_controller/layouts.rb +250 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +61 -0
- data/lib/abstract_controller/rendering_controller.rb +188 -0
- data/lib/action_controller.rb +72 -0
- data/lib/action_controller/base.rb +168 -0
- data/lib/action_controller/caching.rb +80 -0
- data/lib/action_controller/caching/actions.rb +163 -0
- data/lib/action_controller/caching/fragments.rb +116 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/deprecated.rb +4 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/dispatch/dispatcher.rb +57 -0
- data/lib/action_controller/metal.rb +129 -0
- data/lib/action_controller/metal/benchmarking.rb +73 -0
- data/lib/action_controller/metal/compatibility.rb +145 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +105 -0
- data/lib/action_controller/metal/exceptions.rb +55 -0
- data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
- data/lib/action_controller/metal/flash.rb +162 -0
- data/lib/action_controller/metal/head.rb +27 -0
- data/lib/action_controller/metal/helpers.rb +115 -0
- data/lib/action_controller/metal/hide_actions.rb +47 -0
- data/lib/action_controller/metal/http_authentication.rb +312 -0
- data/lib/action_controller/metal/layouts.rb +171 -0
- data/lib/action_controller/metal/mime_responds.rb +317 -0
- data/lib/action_controller/metal/rack_convenience.rb +27 -0
- data/lib/action_controller/metal/redirector.rb +22 -0
- data/lib/action_controller/metal/render_options.rb +103 -0
- data/lib/action_controller/metal/rendering_controller.rb +57 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
- data/lib/action_controller/metal/rescuable.rb +13 -0
- data/lib/action_controller/metal/responder.rb +200 -0
- data/lib/action_controller/metal/session.rb +15 -0
- data/lib/action_controller/metal/session_management.rb +45 -0
- data/lib/action_controller/metal/streaming.rb +188 -0
- data/lib/action_controller/metal/testing.rb +39 -0
- data/lib/action_controller/metal/url_for.rb +41 -0
- data/lib/action_controller/metal/verification.rb +130 -0
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/notifications.rb +10 -0
- data/lib/action_controller/polymorphic_routes.rb +183 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/testing/process.rb +111 -0
- data/lib/action_controller/testing/test_case.rb +345 -0
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +204 -0
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_dispatch.rb +70 -0
- data/lib/action_dispatch/http/headers.rb +33 -0
- data/lib/action_dispatch/http/mime_type.rb +231 -0
- data/lib/action_dispatch/http/mime_types.rb +23 -0
- data/lib/action_dispatch/http/request.rb +539 -0
- data/lib/action_dispatch/http/response.rb +290 -0
- data/lib/action_dispatch/http/status_codes.rb +42 -0
- data/lib/action_dispatch/http/utils.rb +20 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/params_parser.rb +79 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_dispatch/routing.rb +381 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
- data/lib/action_dispatch/routing/mapper.rb +327 -0
- data/lib/action_dispatch/routing/route.rb +49 -0
- data/lib/action_dispatch/routing/route_set.rb +497 -0
- data/lib/action_dispatch/testing/assertions.rb +8 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
- data/lib/action_dispatch/testing/assertions/model.rb +19 -0
- data/lib/action_dispatch/testing/assertions/response.rb +145 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
- data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
- data/lib/action_dispatch/testing/integration.rb +504 -0
- data/lib/action_dispatch/testing/performance_test.rb +15 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +131 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +58 -0
- data/lib/action_view/base.rb +308 -0
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/erb/util.rb +48 -0
- data/lib/action_view/helpers.rb +62 -0
- data/lib/action_view/helpers/active_model_helper.rb +306 -0
- data/lib/action_view/helpers/ajax_helper.rb +68 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
- data/lib/action_view/helpers/cache_helper.rb +39 -0
- data/lib/action_view/helpers/capture_helper.rb +168 -0
- data/lib/action_view/helpers/date_helper.rb +988 -0
- data/lib/action_view/helpers/debug_helper.rb +38 -0
- data/lib/action_view/helpers/form_helper.rb +1102 -0
- data/lib/action_view/helpers/form_options_helper.rb +600 -0
- data/lib/action_view/helpers/form_tag_helper.rb +495 -0
- data/lib/action_view/helpers/javascript_helper.rb +208 -0
- data/lib/action_view/helpers/number_helper.rb +311 -0
- data/lib/action_view/helpers/prototype_helper.rb +1309 -0
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +58 -0
- data/lib/action_view/helpers/sanitize_helper.rb +259 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
- data/lib/action_view/helpers/tag_helper.rb +151 -0
- data/lib/action_view/helpers/text_helper.rb +594 -0
- data/lib/action_view/helpers/translation_helper.rb +39 -0
- data/lib/action_view/helpers/url_helper.rb +639 -0
- data/lib/action_view/locale/en.yml +117 -0
- data/lib/action_view/paths.rb +80 -0
- data/lib/action_view/render/partials.rb +342 -0
- data/lib/action_view/render/rendering.rb +134 -0
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template/error.rb +101 -0
- data/lib/action_view/template/handler.rb +36 -0
- data/lib/action_view/template/handlers.rb +52 -0
- data/lib/action_view/template/handlers/builder.rb +17 -0
- data/lib/action_view/template/handlers/erb.rb +53 -0
- data/lib/action_view/template/handlers/rjs.rb +18 -0
- data/lib/action_view/template/resolver.rb +165 -0
- data/lib/action_view/template/template.rb +131 -0
- data/lib/action_view/template/text.rb +38 -0
- data/lib/action_view/test_case.rb +163 -0
- metadata +236 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/testing/performance'
|
2
|
+
require 'active_support/testing/default'
|
3
|
+
|
4
|
+
module ActionDispatch
|
5
|
+
# An integration test that runs a code profiler on your test methods.
|
6
|
+
# Profiling output for combinations of each test method, measurement, and
|
7
|
+
# output format are written to your tmp/performance directory.
|
8
|
+
#
|
9
|
+
# By default, process_time is measured and both flat and graph_html output
|
10
|
+
# formats are written, so you'll have two output files per test method.
|
11
|
+
class PerformanceTest < ActionDispatch::IntegrationTest
|
12
|
+
include ActiveSupport::Testing::Performance
|
13
|
+
include ActiveSupport::Testing::Default
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module ActionDispatch
|
2
|
+
class TestRequest < Request
|
3
|
+
DEFAULT_ENV = Rack::MockRequest.env_for('/')
|
4
|
+
|
5
|
+
def self.new(env = {})
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(env = {})
|
10
|
+
super(DEFAULT_ENV.merge(env))
|
11
|
+
|
12
|
+
self.host = 'test.host'
|
13
|
+
self.remote_addr = '0.0.0.0'
|
14
|
+
self.user_agent = 'Rails Testing'
|
15
|
+
end
|
16
|
+
|
17
|
+
def env
|
18
|
+
write_cookies!
|
19
|
+
delete_nil_values!
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def request_method=(method)
|
24
|
+
@env['REQUEST_METHOD'] = method.to_s.upcase
|
25
|
+
end
|
26
|
+
|
27
|
+
def host=(host)
|
28
|
+
@env['HTTP_HOST'] = host
|
29
|
+
end
|
30
|
+
|
31
|
+
def port=(number)
|
32
|
+
@env['SERVER_PORT'] = number.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def request_uri=(uri)
|
36
|
+
@env['REQUEST_URI'] = uri
|
37
|
+
end
|
38
|
+
|
39
|
+
def path=(path)
|
40
|
+
@env['PATH_INFO'] = path
|
41
|
+
end
|
42
|
+
|
43
|
+
def action=(action_name)
|
44
|
+
path_parameters["action"] = action_name.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def if_modified_since=(last_modified)
|
48
|
+
@env['HTTP_IF_MODIFIED_SINCE'] = last_modified
|
49
|
+
end
|
50
|
+
|
51
|
+
def if_none_match=(etag)
|
52
|
+
@env['HTTP_IF_NONE_MATCH'] = etag
|
53
|
+
end
|
54
|
+
|
55
|
+
def remote_addr=(addr)
|
56
|
+
@env['REMOTE_ADDR'] = addr
|
57
|
+
end
|
58
|
+
|
59
|
+
def user_agent=(user_agent)
|
60
|
+
@env['HTTP_USER_AGENT'] = user_agent
|
61
|
+
end
|
62
|
+
|
63
|
+
def accept=(mime_types)
|
64
|
+
@env.delete('action_dispatch.request.accepts')
|
65
|
+
@env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
|
66
|
+
end
|
67
|
+
|
68
|
+
def cookies
|
69
|
+
@cookies ||= super
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def write_cookies!
|
74
|
+
unless @cookies.blank?
|
75
|
+
@env['HTTP_COOKIE'] = @cookies.map { |name, value| "#{name}=#{value};" }.join(' ')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete_nil_values!
|
80
|
+
@env.delete_if { |k, v| v.nil? }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module ActionDispatch
|
2
|
+
# Integration test methods such as ActionDispatch::Integration::Session#get
|
3
|
+
# and ActionDispatch::Integration::Session#post return objects of class
|
4
|
+
# TestResponse, which represent the HTTP response results of the requested
|
5
|
+
# controller actions.
|
6
|
+
#
|
7
|
+
# See Response for more information on controller response objects.
|
8
|
+
class TestResponse < Response
|
9
|
+
def self.from_response(response)
|
10
|
+
new.tap do |resp|
|
11
|
+
resp.status = response.status
|
12
|
+
resp.headers = response.headers
|
13
|
+
resp.body = response.body
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module DeprecatedHelpers
|
18
|
+
def template
|
19
|
+
ActiveSupport::Deprecation.warn("response.template has been deprecated. Use controller.template instead", caller)
|
20
|
+
@template
|
21
|
+
end
|
22
|
+
attr_writer :template
|
23
|
+
|
24
|
+
def session
|
25
|
+
ActiveSupport::Deprecation.warn("response.session has been deprecated. Use request.session instead", caller)
|
26
|
+
@request.session
|
27
|
+
end
|
28
|
+
|
29
|
+
def assigns
|
30
|
+
ActiveSupport::Deprecation.warn("response.assigns has been deprecated. Use controller.assigns instead", caller)
|
31
|
+
@template.controller.assigns
|
32
|
+
end
|
33
|
+
|
34
|
+
def layout
|
35
|
+
ActiveSupport::Deprecation.warn("response.layout has been deprecated. Use template.layout instead", caller)
|
36
|
+
@template.layout
|
37
|
+
end
|
38
|
+
|
39
|
+
def redirect_url_match?(pattern)
|
40
|
+
::ActiveSupport::Deprecation.warn("response.redirect_url_match? is deprecated. Use assert_match(/foo/, response.redirect_url) instead", caller)
|
41
|
+
return false if redirect_url.nil?
|
42
|
+
p = Regexp.new(pattern) if pattern.class == String
|
43
|
+
p = pattern if pattern.class == Regexp
|
44
|
+
return false if p.nil?
|
45
|
+
p.match(redirect_url) != nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the template of the file which was used to
|
49
|
+
# render this response (or nil)
|
50
|
+
def rendered
|
51
|
+
ActiveSupport::Deprecation.warn("response.rendered has been deprecated. Use tempate.rendered instead", caller)
|
52
|
+
@template.instance_variable_get(:@_rendered)
|
53
|
+
end
|
54
|
+
|
55
|
+
# A shortcut to the flash. Returns an empty hash if no session flash exists.
|
56
|
+
def flash
|
57
|
+
ActiveSupport::Deprecation.warn("response.flash has been deprecated. Use request.flash instead", caller)
|
58
|
+
request.session['flash'] || {}
|
59
|
+
end
|
60
|
+
|
61
|
+
# Do we have a flash?
|
62
|
+
def has_flash?
|
63
|
+
ActiveSupport::Deprecation.warn("response.has_flash? has been deprecated. Use flash.any? instead", caller)
|
64
|
+
!flash.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Do we have a flash that has contents?
|
68
|
+
def has_flash_with_contents?
|
69
|
+
ActiveSupport::Deprecation.warn("response.has_flash_with_contents? has been deprecated. Use flash.any? instead", caller)
|
70
|
+
!flash.empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
# Does the specified flash object exist?
|
74
|
+
def has_flash_object?(name=nil)
|
75
|
+
ActiveSupport::Deprecation.warn("response.has_flash_object? has been deprecated. Use flash[name] instead", caller)
|
76
|
+
!flash[name].nil?
|
77
|
+
end
|
78
|
+
|
79
|
+
# Does the specified object exist in the session?
|
80
|
+
def has_session_object?(name=nil)
|
81
|
+
ActiveSupport::Deprecation.warn("response.has_session_object? has been deprecated. Use session[name] instead", caller)
|
82
|
+
!session[name].nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
# A shortcut to the template.assigns
|
86
|
+
def template_objects
|
87
|
+
ActiveSupport::Deprecation.warn("response.template_objects has been deprecated. Use tempate.assigns instead", caller)
|
88
|
+
@template.assigns || {}
|
89
|
+
end
|
90
|
+
|
91
|
+
# Does the specified template object exist?
|
92
|
+
def has_template_object?(name=nil)
|
93
|
+
ActiveSupport::Deprecation.warn("response.has_template_object? has been deprecated. Use tempate.assigns[name].nil? instead", caller)
|
94
|
+
!template_objects[name].nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns binary content (downloadable file), converted to a String
|
98
|
+
def binary_content
|
99
|
+
ActiveSupport::Deprecation.warn("response.binary_content has been deprecated. Use response.body instead", caller)
|
100
|
+
body
|
101
|
+
end
|
102
|
+
end
|
103
|
+
include DeprecatedHelpers
|
104
|
+
|
105
|
+
# Was the response successful?
|
106
|
+
def success?
|
107
|
+
(200..299).include?(response_code)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Was the URL not found?
|
111
|
+
def missing?
|
112
|
+
response_code == 404
|
113
|
+
end
|
114
|
+
|
115
|
+
# Were we redirected?
|
116
|
+
def redirect?
|
117
|
+
(300..399).include?(response_code)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Was there a server-side error?
|
121
|
+
def error?
|
122
|
+
(500..599).include?(response_code)
|
123
|
+
end
|
124
|
+
alias_method :server_error?, :error?
|
125
|
+
|
126
|
+
# Was there a client client?
|
127
|
+
def client_error?
|
128
|
+
(400..499).include?(response_code)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/action_pack.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2004-2009 David Heinemeier Hansson
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'action_pack/version'
|
data/lib/action_view.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2004-2009 David Heinemeier Hansson
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require File.join(File.dirname(__FILE__), "action_pack")
|
25
|
+
|
26
|
+
module ActionView
|
27
|
+
def self.load_all!
|
28
|
+
[Context, Base, InlineTemplate, TemplateError]
|
29
|
+
end
|
30
|
+
|
31
|
+
autoload :Base, 'action_view/base'
|
32
|
+
autoload :Context, 'action_view/context'
|
33
|
+
autoload :Helpers, 'action_view/helpers'
|
34
|
+
autoload :MissingTemplate, 'action_view/base'
|
35
|
+
autoload :Partials, 'action_view/render/partials'
|
36
|
+
autoload :Resolver, 'action_view/template/resolver'
|
37
|
+
autoload :PathResolver, 'action_view/template/resolver'
|
38
|
+
autoload :PathSet, 'action_view/paths'
|
39
|
+
autoload :Rendering, 'action_view/render/rendering'
|
40
|
+
autoload :Template, 'action_view/template/template'
|
41
|
+
autoload :TemplateError, 'action_view/template/error'
|
42
|
+
autoload :TemplateHandler, 'action_view/template/handler'
|
43
|
+
autoload :TemplateHandlers, 'action_view/template/handlers'
|
44
|
+
autoload :TextTemplate, 'action_view/template/text'
|
45
|
+
autoload :Helpers, 'action_view/helpers'
|
46
|
+
autoload :FileSystemResolverWithFallback, 'action_view/template/resolver'
|
47
|
+
autoload :SafeBuffer, 'action_view/safe_buffer'
|
48
|
+
end
|
49
|
+
|
50
|
+
require 'action_view/erb/util'
|
51
|
+
|
52
|
+
|
53
|
+
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
|
54
|
+
|
55
|
+
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
56
|
+
$:.unshift activesupport_path if File.directory?(activesupport_path)
|
57
|
+
require 'active_support'
|
58
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
@@ -0,0 +1,308 @@
|
|
1
|
+
require 'active_support/core_ext/module/attr_internal'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
|
4
|
+
module ActionView #:nodoc:
|
5
|
+
class ActionViewError < StandardError #:nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
class MissingTemplate < ActionViewError #:nodoc:
|
9
|
+
attr_reader :path, :action_name
|
10
|
+
|
11
|
+
def initialize(paths, path, template_format = nil)
|
12
|
+
@path = path
|
13
|
+
@action_name = path.split("/").last.split(".")[0...-1].join(".")
|
14
|
+
full_template_path = path.include?('.') ? path : "#{path}.erb"
|
15
|
+
display_paths = paths.compact.join(":")
|
16
|
+
template_type = (path =~ /layouts/i) ? 'layout' : 'template'
|
17
|
+
super("Missing #{template_type} #{full_template_path} in view path #{display_paths}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
|
22
|
+
# (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
|
23
|
+
# If the template file has a <tt>.rjs</tt> extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
|
24
|
+
#
|
25
|
+
# = ERb
|
26
|
+
#
|
27
|
+
# You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
|
28
|
+
# following loop for names:
|
29
|
+
#
|
30
|
+
# <b>Names of all the people</b>
|
31
|
+
# <% for person in @people %>
|
32
|
+
# Name: <%= person.name %><br/>
|
33
|
+
# <% end %>
|
34
|
+
#
|
35
|
+
# The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this
|
36
|
+
# is not just a usage suggestion. Regular output functions like print or puts won't work with ERb templates. So this would be wrong:
|
37
|
+
#
|
38
|
+
# Hi, Mr. <% puts "Frodo" %>
|
39
|
+
#
|
40
|
+
# If you absolutely must write from within a function, you can use the TextHelper#concat.
|
41
|
+
#
|
42
|
+
# <%- and -%> suppress leading and trailing whitespace, including the trailing newline, and can be used interchangeably with <% and %>.
|
43
|
+
#
|
44
|
+
# == Using sub templates
|
45
|
+
#
|
46
|
+
# Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The
|
47
|
+
# classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):
|
48
|
+
#
|
49
|
+
# <%= render "shared/header" %>
|
50
|
+
# Something really specific and terrific
|
51
|
+
# <%= render "shared/footer" %>
|
52
|
+
#
|
53
|
+
# As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the
|
54
|
+
# result of the rendering. The output embedding writes it to the current template.
|
55
|
+
#
|
56
|
+
# But you don't have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance
|
57
|
+
# variables defined using the regular embedding tags. Like this:
|
58
|
+
#
|
59
|
+
# <% @page_title = "A Wonderful Hello" %>
|
60
|
+
# <%= render "shared/header" %>
|
61
|
+
#
|
62
|
+
# Now the header can pick up on the <tt>@page_title</tt> variable and use it for outputting a title tag:
|
63
|
+
#
|
64
|
+
# <title><%= @page_title %></title>
|
65
|
+
#
|
66
|
+
# == Passing local variables to sub templates
|
67
|
+
#
|
68
|
+
# You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
|
69
|
+
#
|
70
|
+
# <%= render "shared/header", { :headline => "Welcome", :person => person } %>
|
71
|
+
#
|
72
|
+
# These can now be accessed in <tt>shared/header</tt> with:
|
73
|
+
#
|
74
|
+
# Headline: <%= headline %>
|
75
|
+
# First name: <%= person.first_name %>
|
76
|
+
#
|
77
|
+
# If you need to find out whether a certain local variable has been assigned a value in a particular render call,
|
78
|
+
# you need to use the following pattern:
|
79
|
+
#
|
80
|
+
# <% if local_assigns.has_key? :headline %>
|
81
|
+
# Headline: <%= headline %>
|
82
|
+
# <% end %>
|
83
|
+
#
|
84
|
+
# Testing using <tt>defined? headline</tt> will not work. This is an implementation restriction.
|
85
|
+
#
|
86
|
+
# == Template caching
|
87
|
+
#
|
88
|
+
# By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will
|
89
|
+
# check the file's modification time and recompile it.
|
90
|
+
#
|
91
|
+
# == Builder
|
92
|
+
#
|
93
|
+
# Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
|
94
|
+
# named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
|
95
|
+
#
|
96
|
+
# Here are some basic examples:
|
97
|
+
#
|
98
|
+
# xml.em("emphasized") # => <em>emphasized</em>
|
99
|
+
# xml.em { xml.b("emph & bold") } # => <em><b>emph & bold</b></em>
|
100
|
+
# xml.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
|
101
|
+
# xml.target("name"=>"compile", "option"=>"fast") # => <target option="fast" name="compile"\>
|
102
|
+
# # NOTE: order of attributes is not specified.
|
103
|
+
#
|
104
|
+
# Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
|
105
|
+
#
|
106
|
+
# xml.div {
|
107
|
+
# xml.h1(@person.name)
|
108
|
+
# xml.p(@person.bio)
|
109
|
+
# }
|
110
|
+
#
|
111
|
+
# would produce something like:
|
112
|
+
#
|
113
|
+
# <div>
|
114
|
+
# <h1>David Heinemeier Hansson</h1>
|
115
|
+
# <p>A product of Danish Design during the Winter of '79...</p>
|
116
|
+
# </div>
|
117
|
+
#
|
118
|
+
# A full-length RSS example actually used on Basecamp:
|
119
|
+
#
|
120
|
+
# xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
|
121
|
+
# xml.channel do
|
122
|
+
# xml.title(@feed_title)
|
123
|
+
# xml.link(@url)
|
124
|
+
# xml.description "Basecamp: Recent items"
|
125
|
+
# xml.language "en-us"
|
126
|
+
# xml.ttl "40"
|
127
|
+
#
|
128
|
+
# for item in @recent_items
|
129
|
+
# xml.item do
|
130
|
+
# xml.title(item_title(item))
|
131
|
+
# xml.description(item_description(item)) if item_description(item)
|
132
|
+
# xml.pubDate(item_pubDate(item))
|
133
|
+
# xml.guid(@person.firm.account.url + @recent_items.url(item))
|
134
|
+
# xml.link(@person.firm.account.url + @recent_items.url(item))
|
135
|
+
#
|
136
|
+
# xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
|
137
|
+
# end
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# More builder documentation can be found at http://builder.rubyforge.org.
|
143
|
+
#
|
144
|
+
# == JavaScriptGenerator
|
145
|
+
#
|
146
|
+
# JavaScriptGenerator templates end in <tt>.rjs</tt>. Unlike conventional templates which are used to
|
147
|
+
# render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
|
148
|
+
# modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
|
149
|
+
# and make updates to the page where the request originated from.
|
150
|
+
#
|
151
|
+
# An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
|
152
|
+
#
|
153
|
+
# When an <tt>.rjs</tt> action is called with +link_to_remote+, the generated JavaScript is automatically evaluated. Example:
|
154
|
+
#
|
155
|
+
# link_to_remote :url => {:action => 'delete'}
|
156
|
+
#
|
157
|
+
# The subsequently rendered <tt>delete.rjs</tt> might look like:
|
158
|
+
#
|
159
|
+
# page.replace_html 'sidebar', :partial => 'sidebar'
|
160
|
+
# page.remove "person-#{@person.id}"
|
161
|
+
# page.visual_effect :highlight, 'user-list'
|
162
|
+
#
|
163
|
+
# This refreshes the sidebar, removes a person element and highlights the user list.
|
164
|
+
#
|
165
|
+
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
|
166
|
+
class Base
|
167
|
+
module Subclasses
|
168
|
+
end
|
169
|
+
|
170
|
+
include Helpers, Rendering, Partials, ::ERB::Util
|
171
|
+
|
172
|
+
def config
|
173
|
+
self.config = DEFAULT_CONFIG unless @config
|
174
|
+
@config
|
175
|
+
end
|
176
|
+
|
177
|
+
def config=(config)
|
178
|
+
@config = ActiveSupport::OrderedOptions.new.merge(config)
|
179
|
+
end
|
180
|
+
|
181
|
+
extend ActiveSupport::Memoizable
|
182
|
+
|
183
|
+
attr_accessor :base_path, :assigns, :template_extension, :formats
|
184
|
+
attr_accessor :controller
|
185
|
+
attr_internal :captures
|
186
|
+
|
187
|
+
def reset_formats(formats)
|
188
|
+
@formats = formats
|
189
|
+
|
190
|
+
if defined?(AbstractController::HashKey)
|
191
|
+
# This is expensive, but we need to reset this when the format is updated,
|
192
|
+
# which currently only happens
|
193
|
+
Thread.current[:format_locale_key] =
|
194
|
+
AbstractController::HashKey.get(self.class, formats, I18n.locale)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class << self
|
199
|
+
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
|
200
|
+
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
|
201
|
+
end
|
202
|
+
|
203
|
+
@@debug_rjs = false
|
204
|
+
##
|
205
|
+
# :singleton-method:
|
206
|
+
# Specify whether RJS responses should be wrapped in a try/catch block
|
207
|
+
# that alert()s the caught exception (and then re-raises it).
|
208
|
+
cattr_accessor :debug_rjs
|
209
|
+
|
210
|
+
# Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed.
|
211
|
+
# Automatically reloading templates are not thread safe and should only be used in development mode.
|
212
|
+
@@cache_template_loading = nil
|
213
|
+
cattr_accessor :cache_template_loading
|
214
|
+
|
215
|
+
# :nodoc:
|
216
|
+
def self.xss_safe?
|
217
|
+
true
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.cache_template_loading?
|
221
|
+
ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading)
|
222
|
+
end
|
223
|
+
|
224
|
+
attr_internal :request, :layout
|
225
|
+
|
226
|
+
def controller_path
|
227
|
+
@controller_path ||= controller && controller.controller_path
|
228
|
+
end
|
229
|
+
|
230
|
+
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
|
231
|
+
:flash, :action_name, :controller_name, :to => :controller
|
232
|
+
|
233
|
+
delegate :logger, :to => :controller, :allow_nil => true
|
234
|
+
|
235
|
+
delegate :find, :to => :view_paths
|
236
|
+
|
237
|
+
include Context
|
238
|
+
|
239
|
+
def self.process_view_paths(value)
|
240
|
+
ActionView::PathSet.new(Array(value))
|
241
|
+
end
|
242
|
+
|
243
|
+
extlib_inheritable_accessor :helpers
|
244
|
+
attr_reader :helpers
|
245
|
+
|
246
|
+
def self.for_controller(controller)
|
247
|
+
@views ||= {}
|
248
|
+
|
249
|
+
# TODO: Decouple this so helpers are a separate concern in AV just like
|
250
|
+
# they are in AC.
|
251
|
+
if controller.class.respond_to?(:_helper_serial)
|
252
|
+
klass = @views[controller.class._helper_serial] ||= Class.new(self) do
|
253
|
+
# Try to make stack traces clearer
|
254
|
+
class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
|
255
|
+
def self.name
|
256
|
+
"ActionView for #{controller.class}"
|
257
|
+
end
|
258
|
+
|
259
|
+
def inspect
|
260
|
+
"#<#{self.class.name}>"
|
261
|
+
end
|
262
|
+
ruby_eval
|
263
|
+
|
264
|
+
if controller.respond_to?(:_helpers)
|
265
|
+
include controller._helpers
|
266
|
+
self.helpers = controller._helpers
|
267
|
+
end
|
268
|
+
end
|
269
|
+
else
|
270
|
+
klass = self
|
271
|
+
end
|
272
|
+
|
273
|
+
klass.new(controller.class.view_paths, {}, controller)
|
274
|
+
end
|
275
|
+
|
276
|
+
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc:
|
277
|
+
@formats = formats
|
278
|
+
@assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
|
279
|
+
@controller = controller
|
280
|
+
@helpers = self.class.helpers || Module.new
|
281
|
+
@_content_for = Hash.new {|h,k| h[k] = ActionView::SafeBuffer.new }
|
282
|
+
self.view_paths = view_paths
|
283
|
+
end
|
284
|
+
|
285
|
+
attr_internal :template
|
286
|
+
attr_reader :view_paths
|
287
|
+
|
288
|
+
def view_paths=(paths)
|
289
|
+
@view_paths = self.class.process_view_paths(paths)
|
290
|
+
end
|
291
|
+
|
292
|
+
def punctuate_body!(part)
|
293
|
+
flush_output_buffer
|
294
|
+
response.body_parts << part
|
295
|
+
nil
|
296
|
+
end
|
297
|
+
|
298
|
+
# Evaluates the local assigns and controller ivars, pushes them to the view.
|
299
|
+
def _evaluate_assigns_and_ivars #:nodoc:
|
300
|
+
if @controller
|
301
|
+
variables = @controller.instance_variable_names
|
302
|
+
variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
|
303
|
+
variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
end
|