eactionpack 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +7 -0
- data/MIT-LICENSE +21 -0
- data/README +469 -0
- data/RUNNING_UNIT_TESTS +24 -0
- data/Rakefile +146 -0
- data/install.rb +30 -0
- data/lib/action_controller.rb +79 -0
- data/lib/action_controller/assertions.rb +69 -0
- data/lib/action_controller/assertions/dom_assertions.rb +39 -0
- data/lib/action_controller/assertions/model_assertions.rb +20 -0
- data/lib/action_controller/assertions/response_assertions.rb +172 -0
- data/lib/action_controller/assertions/routing_assertions.rb +146 -0
- data/lib/action_controller/assertions/selector_assertions.rb +491 -0
- data/lib/action_controller/assertions/tag_assertions.rb +130 -0
- data/lib/action_controller/base.rb +1288 -0
- data/lib/action_controller/benchmarking.rb +94 -0
- data/lib/action_controller/caching.rb +72 -0
- data/lib/action_controller/caching/actions.rb +144 -0
- data/lib/action_controller/caching/fragments.rb +138 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sql_cache.rb +18 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/cookie.rb +110 -0
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
- data/lib/action_controller/cgi_process.rb +223 -0
- data/lib/action_controller/components.rb +166 -0
- data/lib/action_controller/cookies.rb +96 -0
- data/lib/action_controller/dispatcher.rb +162 -0
- data/lib/action_controller/filters.rb +642 -0
- data/lib/action_controller/flash.rb +172 -0
- data/lib/action_controller/headers.rb +31 -0
- data/lib/action_controller/helpers.rb +221 -0
- data/lib/action_controller/http_authentication.rb +124 -0
- data/lib/action_controller/integration.rb +634 -0
- data/lib/action_controller/layout.rb +309 -0
- data/lib/action_controller/mime_responds.rb +173 -0
- data/lib/action_controller/mime_type.rb +186 -0
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +191 -0
- data/lib/action_controller/record_identifier.rb +102 -0
- data/lib/action_controller/request.rb +764 -0
- data/lib/action_controller/request_forgery_protection.rb +140 -0
- data/lib/action_controller/request_profiler.rb +169 -0
- data/lib/action_controller/rescue.rb +258 -0
- data/lib/action_controller/resources.rb +572 -0
- data/lib/action_controller/response.rb +76 -0
- data/lib/action_controller/routing.rb +387 -0
- data/lib/action_controller/routing/builder.rb +203 -0
- data/lib/action_controller/routing/optimisations.rb +120 -0
- data/lib/action_controller/routing/recognition_optimisation.rb +162 -0
- data/lib/action_controller/routing/route.rb +240 -0
- data/lib/action_controller/routing/route_set.rb +436 -0
- data/lib/action_controller/routing/routing_ext.rb +46 -0
- data/lib/action_controller/routing/segments.rb +283 -0
- data/lib/action_controller/session/active_record_store.rb +340 -0
- data/lib/action_controller/session/cookie_store.rb +166 -0
- data/lib/action_controller/session/drb_server.rb +32 -0
- data/lib/action_controller/session/drb_store.rb +35 -0
- data/lib/action_controller/session/mem_cache_store.rb +98 -0
- data/lib/action_controller/session_management.rb +158 -0
- data/lib/action_controller/status_codes.rb +88 -0
- data/lib/action_controller/streaming.rb +155 -0
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/_trace.erb +26 -0
- data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
- data/lib/action_controller/templates/rescues/layout.erb +29 -0
- data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
- data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
- data/lib/action_controller/templates/rescues/template_error.erb +21 -0
- data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_controller/test_case.rb +83 -0
- data/lib/action_controller/test_process.rb +526 -0
- data/lib/action_controller/url_rewriter.rb +142 -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 +173 -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_controller/verification.rb +130 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +44 -0
- data/lib/action_view/base.rb +335 -0
- data/lib/action_view/helpers/active_record_helper.rb +276 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +599 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +143 -0
- data/lib/action_view/helpers/benchmark_helper.rb +33 -0
- data/lib/action_view/helpers/cache_helper.rb +40 -0
- data/lib/action_view/helpers/capture_helper.rb +161 -0
- data/lib/action_view/helpers/date_helper.rb +711 -0
- data/lib/action_view/helpers/debug_helper.rb +31 -0
- data/lib/action_view/helpers/form_helper.rb +767 -0
- data/lib/action_view/helpers/form_options_helper.rb +458 -0
- data/lib/action_view/helpers/form_tag_helper.rb +458 -0
- data/lib/action_view/helpers/javascript_helper.rb +148 -0
- data/lib/action_view/helpers/number_helper.rb +186 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +229 -0
- data/lib/action_view/helpers/tag_helper.rb +134 -0
- data/lib/action_view/helpers/text_helper.rb +507 -0
- data/lib/action_view/helpers/url_helper.rb +573 -0
- data/lib/action_view/inline_template.rb +20 -0
- data/lib/action_view/partial_template.rb +70 -0
- data/lib/action_view/partials.rb +158 -0
- data/lib/action_view/template.rb +125 -0
- data/lib/action_view/template_error.rb +110 -0
- data/lib/action_view/template_finder.rb +176 -0
- data/lib/action_view/template_handler.rb +34 -0
- data/lib/action_view/template_handlers/builder.rb +27 -0
- data/lib/action_view/template_handlers/compilable.rb +128 -0
- data/lib/action_view/template_handlers/erb.rb +56 -0
- data/lib/action_view/test_case.rb +58 -0
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +36 -0
- data/test/active_record_unit.rb +105 -0
- data/test/activerecord/active_record_store_test.rb +141 -0
- data/test/activerecord/render_partial_with_record_identification_test.rb +191 -0
- data/test/adv_attr_test.rb +20 -0
- data/test/controller/action_pack_assertions_test.rb +543 -0
- data/test/controller/addresses_render_test.rb +43 -0
- data/test/controller/assert_select_test.rb +331 -0
- data/test/controller/base_test.rb +219 -0
- data/test/controller/benchmark_test.rb +32 -0
- data/test/controller/caching_test.rb +581 -0
- data/test/controller/capture_test.rb +89 -0
- data/test/controller/cgi_test.rb +116 -0
- data/test/controller/components_test.rb +140 -0
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +146 -0
- data/test/controller/custom_handler_test.rb +45 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +37 -0
- data/test/controller/dispatcher_test.rb +105 -0
- data/test/controller/fake_controllers.rb +33 -0
- data/test/controller/fake_models.rb +11 -0
- data/test/controller/filter_params_test.rb +49 -0
- data/test/controller/filters_test.rb +881 -0
- data/test/controller/flash_test.rb +146 -0
- data/test/controller/header_test.rb +14 -0
- data/test/controller/helper_test.rb +210 -0
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/document_test.rb +148 -0
- data/test/controller/html-scanner/node_test.rb +89 -0
- data/test/controller/html-scanner/sanitizer_test.rb +269 -0
- data/test/controller/html-scanner/tag_node_test.rb +238 -0
- data/test/controller/html-scanner/text_node_test.rb +50 -0
- data/test/controller/html-scanner/tokenizer_test.rb +131 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +252 -0
- data/test/controller/integration_upload_test.rb +43 -0
- data/test/controller/layout_test.rb +255 -0
- data/test/controller/mime_responds_test.rb +514 -0
- data/test/controller/mime_type_test.rb +84 -0
- data/test/controller/new_render_test.rb +843 -0
- data/test/controller/polymorphic_routes_test.rb +174 -0
- data/test/controller/record_identifier_test.rb +139 -0
- data/test/controller/redirect_test.rb +289 -0
- data/test/controller/render_test.rb +484 -0
- data/test/controller/request_forgery_protection_test.rb +305 -0
- data/test/controller/request_test.rb +928 -0
- data/test/controller/rescue_test.rb +517 -0
- data/test/controller/resources_test.rb +873 -0
- data/test/controller/routing_test.rb +2464 -0
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +138 -0
- data/test/controller/session/cookie_store_test.rb +258 -0
- data/test/controller/session/mem_cache_store_test.rb +181 -0
- data/test/controller/session_fixation_test.rb +89 -0
- data/test/controller/session_management_test.rb +178 -0
- data/test/controller/test_test.rb +695 -0
- data/test/controller/url_rewriter_test.rb +310 -0
- data/test/controller/verification_test.rb +270 -0
- data/test/controller/view_paths_test.rb +140 -0
- data/test/controller/webservice_test.rb +229 -0
- data/test/fixtures/addresses/list.erb +1 -0
- data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +10 -0
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_js.js.erb +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/customers/_customer.html.erb +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +49 -0
- data/test/fixtures/developer.rb +9 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/fun/games/hello_world.erb +1 -0
- data/test/fixtures/functional_caching/_partial.erb +3 -0
- data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
- data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
- data/test/fixtures/helpers/abc_helper.rb +5 -0
- data/test/fixtures/helpers/fun/games_helper.rb +3 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/layouts/block_with_layout.erb +3 -0
- data/test/fixtures/layouts/builder.builder +3 -0
- data/test/fixtures/layouts/partial_with_layout.erb +3 -0
- data/test/fixtures/layouts/standard.erb +1 -0
- data/test/fixtures/layouts/talk_from_action.erb +2 -0
- data/test/fixtures/layouts/yield.erb +2 -0
- data/test/fixtures/mascot.rb +3 -0
- data/test/fixtures/mascots.yml +4 -0
- data/test/fixtures/mascots/_mascot.html.erb +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +10 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/javascripts/version.1.0.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
- data/test/fixtures/replies.yml +15 -0
- data/test/fixtures/reply.rb +7 -0
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
- data/test/fixtures/scope/test/modgreet.erb +1 -0
- data/test/fixtures/shared.html.erb +1 -0
- data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
- data/test/fixtures/test/_customer.erb +1 -0
- data/test/fixtures/test/_customer_counter.erb +1 -0
- data/test/fixtures/test/_customer_greeting.erb +1 -0
- data/test/fixtures/test/_form.erb +1 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/_hello.builder +1 -0
- data/test/fixtures/test/_labelling_form.erb +1 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/_partial_only.erb +1 -0
- data/test/fixtures/test/_person.erb +2 -0
- data/test/fixtures/test/_raise.html.erb +1 -0
- data/test/fixtures/test/action_talk_to_layout.erb +2 -0
- data/test/fixtures/test/block_content_for.erb +2 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/capturing.erb +4 -0
- data/test/fixtures/test/content_for.erb +2 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.erb +2 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/greeting.erb +1 -0
- data/test/fixtures/test/greeting.js.rjs +1 -0
- data/test/fixtures/test/hello.builder +4 -0
- data/test/fixtures/test/hello_world.erb +1 -0
- data/test/fixtures/test/hello_world_container.builder +3 -0
- data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
- data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
- data/test/fixtures/test/hello_xml_world.builder +11 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
- data/test/fixtures/test/potential_conflicts.erb +4 -0
- data/test/fixtures/test/render_file_from_template.html.erb +1 -0
- data/test/fixtures/test/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/render_file_with_locals.erb +1 -0
- data/test/fixtures/test/render_to_string_test.erb +1 -0
- data/test/fixtures/test/update_element_with_capture.erb +9 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/topics/_topic.html.erb +1 -0
- data/test/template/active_record_helper_test.rb +268 -0
- data/test/template/asset_tag_helper_test.rb +514 -0
- data/test/template/atom_feed_helper_test.rb +179 -0
- data/test/template/benchmark_helper_test.rb +60 -0
- data/test/template/date_helper_test.rb +1791 -0
- data/test/template/deprecated_erb_variable_test.rb +9 -0
- data/test/template/erb_util_test.rb +24 -0
- data/test/template/form_helper_test.rb +885 -0
- data/test/template/form_options_helper_test.rb +1333 -0
- data/test/template/form_tag_helper_test.rb +272 -0
- data/test/template/javascript_helper_test.rb +73 -0
- data/test/template/number_helper_test.rb +97 -0
- data/test/template/record_tag_helper_test.rb +54 -0
- data/test/template/sanitize_helper_test.rb +48 -0
- data/test/template/tag_helper_test.rb +77 -0
- data/test/template/template_finder_test.rb +73 -0
- data/test/template/template_object_test.rb +95 -0
- data/test/template/test_test.rb +56 -0
- data/test/template/text_helper_test.rb +367 -0
- data/test/template/url_helper_test.rb +544 -0
- data/test/testing_sandbox.rb +15 -0
- metadata +469 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
module ActionView #:nodoc:
|
|
2
|
+
class TemplateFinder #:nodoc:
|
|
3
|
+
|
|
4
|
+
class InvalidViewPath < StandardError #:nodoc:
|
|
5
|
+
attr_reader :unprocessed_path
|
|
6
|
+
def initialize(path)
|
|
7
|
+
@unprocessed_path = path
|
|
8
|
+
super("Unprocessed view path found: #{@unprocessed_path.inspect}. Set your view paths with #append_view_path, #prepend_view_path, or #view_paths=.")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
cattr_reader :processed_view_paths
|
|
13
|
+
@@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
|
|
14
|
+
|
|
15
|
+
cattr_reader :file_extension_cache
|
|
16
|
+
@@file_extension_cache = Hash.new {|hash, key|
|
|
17
|
+
hash[key] = Hash.new {|hash, key| hash[key] = []}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class << self #:nodoc:
|
|
21
|
+
|
|
22
|
+
# This method is not thread safe. Mutex should be used whenever this is accessed from an instance method
|
|
23
|
+
def process_view_paths(*view_paths)
|
|
24
|
+
view_paths.flatten.compact.each do |dir|
|
|
25
|
+
next if @@processed_view_paths.has_key?(dir)
|
|
26
|
+
@@processed_view_paths[dir] = []
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# Dir.glob("#{dir}/**/*/**") reads all the directories in view path and templates inside those directories
|
|
30
|
+
# Dir.glob("#{dir}/**") reads templates residing at top level of view path
|
|
31
|
+
#
|
|
32
|
+
(Dir.glob("#{dir}/**/*/**") | Dir.glob("#{dir}/**")).each do |file|
|
|
33
|
+
unless File.directory?(file)
|
|
34
|
+
@@processed_view_paths[dir] << file.split(dir).last.sub(/^\//, '')
|
|
35
|
+
|
|
36
|
+
# Build extension cache
|
|
37
|
+
extension = file.split(".").last
|
|
38
|
+
if template_handler_extensions.include?(extension)
|
|
39
|
+
key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
|
|
40
|
+
@@file_extension_cache[dir][key] << extension
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def update_extension_cache_for(extension)
|
|
48
|
+
@@processed_view_paths.keys.each do |dir|
|
|
49
|
+
Dir.glob("#{dir}/**/*.#{extension}").each do |file|
|
|
50
|
+
key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
|
|
51
|
+
@@file_extension_cache[dir][key] << extension
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def template_handler_extensions
|
|
57
|
+
ActionView::Template.template_handler_extensions
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def reload!
|
|
61
|
+
view_paths = @@processed_view_paths.keys
|
|
62
|
+
|
|
63
|
+
@@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
|
|
64
|
+
@@file_extension_cache = Hash.new {|hash, key|
|
|
65
|
+
hash[key] = Hash.new {|hash, key| hash[key] = []}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
process_view_paths(view_paths)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attr_accessor :view_paths
|
|
73
|
+
|
|
74
|
+
def initialize(*args)
|
|
75
|
+
@template = args.shift
|
|
76
|
+
|
|
77
|
+
@view_paths = args.flatten
|
|
78
|
+
@view_paths = @view_paths.respond_to?(:find) ? @view_paths.dup : [*@view_paths].compact
|
|
79
|
+
check_view_paths(@view_paths)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def prepend_view_path(path)
|
|
83
|
+
@view_paths.unshift(*path)
|
|
84
|
+
|
|
85
|
+
self.class.process_view_paths(path)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def append_view_path(path)
|
|
89
|
+
@view_paths.push(*path)
|
|
90
|
+
|
|
91
|
+
self.class.process_view_paths(path)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def view_paths=(path)
|
|
95
|
+
@view_paths = path
|
|
96
|
+
self.class.process_view_paths(path)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def pick_template(template_path, extension)
|
|
100
|
+
file_name = "#{template_path}.#{extension}"
|
|
101
|
+
base_path = find_base_path_for(file_name)
|
|
102
|
+
base_path.blank? ? false : "#{base_path}/#{file_name}"
|
|
103
|
+
end
|
|
104
|
+
alias_method :template_exists?, :pick_template
|
|
105
|
+
|
|
106
|
+
def file_exists?(template_path)
|
|
107
|
+
# Clear the forward slash in the beginning if exists
|
|
108
|
+
template_path = template_path.sub(/^\//, '')
|
|
109
|
+
|
|
110
|
+
template_file_name, template_file_extension = path_and_extension(template_path)
|
|
111
|
+
|
|
112
|
+
if template_file_extension
|
|
113
|
+
template_exists?(template_file_name, template_file_extension)
|
|
114
|
+
else
|
|
115
|
+
template_exists?(template_file_name, pick_template_extension(template_path))
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def find_base_path_for(template_file_name)
|
|
120
|
+
@view_paths.find { |path| @@processed_view_paths[path].include?(template_file_name) }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Returns the view path that the full path resides in.
|
|
124
|
+
def extract_base_path_from(full_path)
|
|
125
|
+
@view_paths.find { |p| full_path[0..p.size - 1] == p }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Gets the extension for an existing template with the given template_path.
|
|
129
|
+
# Returns the format with the extension if that template exists.
|
|
130
|
+
#
|
|
131
|
+
# pick_template_extension('users/show')
|
|
132
|
+
# # => 'html.erb'
|
|
133
|
+
#
|
|
134
|
+
# pick_template_extension('users/legacy')
|
|
135
|
+
# # => "rhtml"
|
|
136
|
+
#
|
|
137
|
+
def pick_template_extension(template_path)
|
|
138
|
+
if extension = find_template_extension_from_handler(template_path, @template.template_format) || find_template_extension_from_first_render
|
|
139
|
+
extension
|
|
140
|
+
elsif @template.template_format == :js && extension = find_template_extension_from_handler(template_path, :html)
|
|
141
|
+
@template.template_format = :html
|
|
142
|
+
extension
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def find_template_extension_from_handler(template_path, template_format = @template.template_format)
|
|
147
|
+
formatted_template_path = "#{template_path}.#{template_format}"
|
|
148
|
+
view_paths.each do |path|
|
|
149
|
+
if (extensions = @@file_extension_cache[path][formatted_template_path]).any?
|
|
150
|
+
return "#{template_format}.#{extensions.first}"
|
|
151
|
+
elsif (extensions = @@file_extension_cache[path][template_path]).any?
|
|
152
|
+
return extensions.first.to_s
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
nil
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Splits the path and extension from the given template_path and returns as an array.
|
|
159
|
+
def path_and_extension(template_path)
|
|
160
|
+
template_path_without_extension = template_path.sub(/\.(\w+)$/, '')
|
|
161
|
+
[ template_path_without_extension, $1 ]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Determine the template extension from the <tt>@first_render</tt> filename
|
|
165
|
+
def find_template_extension_from_first_render
|
|
166
|
+
File.basename(@template.first_render.to_s)[/^[^.]+\.(.+)$/, 1]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
private
|
|
170
|
+
def check_view_paths(view_paths)
|
|
171
|
+
view_paths.each do |path|
|
|
172
|
+
raise InvalidViewPath.new(path) unless @@processed_view_paths.has_key?(path)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
class TemplateHandler
|
|
3
|
+
|
|
4
|
+
def self.line_offset
|
|
5
|
+
0
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.compilable?
|
|
9
|
+
false
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(view)
|
|
13
|
+
@view = view
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def render(template)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def compile(template)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def compilable?
|
|
23
|
+
self.class.compilable?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def line_offset
|
|
27
|
+
self.class.line_offset
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Called by CacheHelper#cache
|
|
31
|
+
def cache_fragment(block, name = {}, options = nil)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'builder'
|
|
2
|
+
|
|
3
|
+
module ActionView
|
|
4
|
+
module TemplateHandlers
|
|
5
|
+
class Builder < TemplateHandler
|
|
6
|
+
include Compilable
|
|
7
|
+
|
|
8
|
+
def self.line_offset
|
|
9
|
+
2
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def compile(template)
|
|
13
|
+
content_type_handler = (@view.send!(:controller).respond_to?(:response) ? "controller.response" : "controller")
|
|
14
|
+
"#{content_type_handler}.content_type ||= Mime::XML\n" +
|
|
15
|
+
"xml = ::Builder::XmlMarkup.new(:indent => 2)\n" +
|
|
16
|
+
template.source +
|
|
17
|
+
"\nxml.target!\n"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def cache_fragment(block, name = {}, options = nil)
|
|
21
|
+
@view.fragment_for(block, name, options) do
|
|
22
|
+
eval('xml.target!', block.binding)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module TemplateHandlers
|
|
3
|
+
module Compilable
|
|
4
|
+
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.extend ClassMethod
|
|
7
|
+
|
|
8
|
+
# Map method names to their compile time
|
|
9
|
+
base.cattr_accessor :compile_time
|
|
10
|
+
base.compile_time = {}
|
|
11
|
+
|
|
12
|
+
# Map method names to the names passed in local assigns so far
|
|
13
|
+
base.cattr_accessor :template_args
|
|
14
|
+
base.template_args = {}
|
|
15
|
+
|
|
16
|
+
# Count the number of inline templates
|
|
17
|
+
base.cattr_accessor :inline_template_count
|
|
18
|
+
base.inline_template_count = 0
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module ClassMethod
|
|
22
|
+
# If a handler is mixin this module, set compilable to true
|
|
23
|
+
def compilable?
|
|
24
|
+
true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def render(template)
|
|
29
|
+
@view.send :execute, template
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Compile and evaluate the template's code
|
|
33
|
+
def compile_template(template)
|
|
34
|
+
return unless compile_template?(template)
|
|
35
|
+
|
|
36
|
+
render_symbol = assign_method_name(template)
|
|
37
|
+
render_source = create_template_source(template, render_symbol)
|
|
38
|
+
line_offset = self.template_args[render_symbol].size + self.line_offset
|
|
39
|
+
|
|
40
|
+
begin
|
|
41
|
+
file_name = template.filename || 'compiled-template'
|
|
42
|
+
ActionView::Base::CompiledTemplates.module_eval(render_source, file_name, -line_offset)
|
|
43
|
+
rescue Exception => e # errors from template code
|
|
44
|
+
if @view.logger
|
|
45
|
+
@view.logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
|
|
46
|
+
@view.logger.debug "Function body: #{render_source}"
|
|
47
|
+
@view.logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
raise ActionView::TemplateError.new(template, @view.assigns, e)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
self.compile_time[render_symbol] = Time.now
|
|
54
|
+
# logger.debug "Compiled template #{file_name || template}\n ==> #{render_symbol}" if logger
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# Method to check whether template compilation is necessary.
|
|
60
|
+
# The template will be compiled if the inline template or file has not been compiled yet,
|
|
61
|
+
# if local_assigns has a new key, which isn't supported by the compiled code yet,
|
|
62
|
+
# or if the file has changed on disk and checking file mods hasn't been disabled.
|
|
63
|
+
def compile_template?(template)
|
|
64
|
+
method_key = template.method_key
|
|
65
|
+
render_symbol = @view.method_names[method_key]
|
|
66
|
+
|
|
67
|
+
compile_time = self.compile_time[render_symbol]
|
|
68
|
+
if compile_time && supports_local_assigns?(render_symbol, template.locals)
|
|
69
|
+
if template.filename && !@view.cache_template_loading
|
|
70
|
+
template_changed_since?(template.filename, compile_time)
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def assign_method_name(template)
|
|
78
|
+
@view.method_names[template.method_key] ||= compiled_method_name(template)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def compiled_method_name(template)
|
|
82
|
+
['_run', self.class.to_s.demodulize.underscore, compiled_method_name_file_path_segment(template.filename)].compact.join('_').to_sym
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def compiled_method_name_file_path_segment(file_name)
|
|
86
|
+
if file_name
|
|
87
|
+
s = File.expand_path(file_name)
|
|
88
|
+
s.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}/, '') if defined?(RAILS_ROOT)
|
|
89
|
+
s.gsub!(/([^a-zA-Z0-9_])/) { $1.ord }
|
|
90
|
+
s
|
|
91
|
+
else
|
|
92
|
+
(self.inline_template_count += 1).to_s
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Method to create the source code for a given template.
|
|
97
|
+
def create_template_source(template, render_symbol)
|
|
98
|
+
body = compile(template)
|
|
99
|
+
|
|
100
|
+
self.template_args[render_symbol] ||= {}
|
|
101
|
+
locals_keys = self.template_args[render_symbol].keys | template.locals.keys
|
|
102
|
+
self.template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h }
|
|
103
|
+
|
|
104
|
+
locals_code = ""
|
|
105
|
+
locals_keys.each do |key|
|
|
106
|
+
locals_code << "#{key} = local_assigns[:#{key}]\n"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
"def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Return true if the given template was compiled for a superset of the keys in local_assigns
|
|
113
|
+
def supports_local_assigns?(render_symbol, local_assigns)
|
|
114
|
+
local_assigns.empty? ||
|
|
115
|
+
((args = self.template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) })
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Method to handle checking a whether a template has changed since last compile; isolated so that templates
|
|
119
|
+
# not stored on the file system can hook and extend appropriately.
|
|
120
|
+
def template_changed_since?(file_name, compile_time)
|
|
121
|
+
lstat = File.lstat(file_name)
|
|
122
|
+
compile_time < lstat.mtime ||
|
|
123
|
+
(lstat.symlink? && compile_time < File.stat(file_name).mtime)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
class ERB
|
|
4
|
+
module Util
|
|
5
|
+
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
|
6
|
+
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
|
7
|
+
|
|
8
|
+
# A utility method for escaping HTML tag characters.
|
|
9
|
+
# This method is also aliased as <tt>h</tt>.
|
|
10
|
+
#
|
|
11
|
+
# In your ERb templates, use this method to escape any unsafe content. For example:
|
|
12
|
+
# <%=h @person.name %>
|
|
13
|
+
#
|
|
14
|
+
# ==== Example:
|
|
15
|
+
# puts html_escape("is a > 0 & a < 10?")
|
|
16
|
+
# # => is a > 0 & a < 10?
|
|
17
|
+
def html_escape(s)
|
|
18
|
+
s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# A utility method for escaping HTML entities in JSON strings.
|
|
22
|
+
# This method is also aliased as <tt>j</tt>.
|
|
23
|
+
#
|
|
24
|
+
# In your ERb templates, use this method to escape any HTML entities:
|
|
25
|
+
# <%=j @person.to_json %>
|
|
26
|
+
#
|
|
27
|
+
# ==== Example:
|
|
28
|
+
# puts json_escape("is a > 0 & a < 10?")
|
|
29
|
+
# # => is a \u003E 0 \u0026 a \u003C 10?
|
|
30
|
+
def json_escape(s)
|
|
31
|
+
s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
alias j json_escape
|
|
35
|
+
module_function :j
|
|
36
|
+
module_function :json_escape
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module ActionView
|
|
41
|
+
module TemplateHandlers
|
|
42
|
+
class ERB < TemplateHandler
|
|
43
|
+
include Compilable
|
|
44
|
+
|
|
45
|
+
def compile(template)
|
|
46
|
+
::ERB.new(template.source, nil, @view.erb_trim_mode).src
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def cache_fragment(block, name = {}, options = nil) #:nodoc:
|
|
50
|
+
@view.fragment_for(block, name, options) do
|
|
51
|
+
eval(ActionView::Base.erb_variable, block.binding)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'active_support/test_case'
|
|
2
|
+
|
|
3
|
+
module ActionView
|
|
4
|
+
class TestCase < ActiveSupport::TestCase
|
|
5
|
+
class_inheritable_accessor :helper_class
|
|
6
|
+
@@helper_class = nil
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def tests(helper_class)
|
|
10
|
+
self.helper_class = helper_class
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def helper_class
|
|
14
|
+
if current_helper_class = read_inheritable_attribute(:helper_class)
|
|
15
|
+
current_helper_class
|
|
16
|
+
else
|
|
17
|
+
self.helper_class = determine_default_helper_class(name)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def determine_default_helper_class(name)
|
|
22
|
+
name.sub(/Test$/, '').constantize
|
|
23
|
+
rescue NameError
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
ActionView::Base.helper_modules.each do |helper_module|
|
|
29
|
+
include helper_module
|
|
30
|
+
end
|
|
31
|
+
include ActionController::PolymorphicRoutes
|
|
32
|
+
include ActionController::RecordIdentifier
|
|
33
|
+
|
|
34
|
+
setup :setup_with_helper_class
|
|
35
|
+
|
|
36
|
+
def setup_with_helper_class
|
|
37
|
+
if helper_class && !self.class.ancestors.include?(helper_class)
|
|
38
|
+
self.class.send(:include, helper_class)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class TestController < ActionController::Base
|
|
43
|
+
attr_accessor :request, :response
|
|
44
|
+
|
|
45
|
+
def initialize
|
|
46
|
+
@request = ActionController::TestRequest.new
|
|
47
|
+
@response = ActionController::TestResponse.new
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
def method_missing(selector, *args)
|
|
53
|
+
controller = TestController.new
|
|
54
|
+
return controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|