From 9de83050d3a4b260d4aeb5d09ec4eb64f913ba64 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 15 Mar 2010 11:58:05 -0700 Subject: Add deprecation notices for <% %>. * The approach is to compile <% %> into a method call that checks whether the value returned from a block is a String. If it is, it concats to the buffer and prints a deprecation warning. * <%= %> uses exactly the same logic to compile the template, which first checks to see whether it's compiling a block. * This should have no impact on other uses of block in templates. For instance, in <% [1,2,3].each do |i| %><%= i %><% end %>, the call to each returns an Array, not a String, so the result is not concatenated * In two cases (#capture and #cache), a String can be returned that should *never* be concatenated. We have temporarily created a String subclass called NonConcattingString which behaves (and is serialized) identically to String, but is not concatenated by the code that handles deprecated <% %> block helpers. Once we remove support for <% %> block helpers, we can remove NonConcattingString. --- actionpack/lib/action_view/base.rb | 3 ++ actionpack/lib/action_view/helpers/cache_helper.rb | 2 +- .../lib/action_view/helpers/capture_helper.rb | 28 ++++++------ .../helpers/deprecated_block_helpers.rb | 52 ---------------------- .../lib/action_view/helpers/prototype_helper.rb | 4 ++ actionpack/lib/action_view/render/rendering.rb | 3 +- .../lib/action_view/template/handlers/erb.rb | 19 +++++++- 7 files changed, 42 insertions(+), 69 deletions(-) delete mode 100644 actionpack/lib/action_view/helpers/deprecated_block_helpers.rb (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index feaf45c333..3920d8593f 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -3,6 +3,9 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' module ActionView #:nodoc: + class NonConcattingString < ActiveSupport::SafeBuffer + end + class ActionViewError < StandardError #:nodoc: end diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb index d5cc14b29a..3729d7daa8 100644 --- a/actionpack/lib/action_view/helpers/cache_helper.rb +++ b/actionpack/lib/action_view/helpers/cache_helper.rb @@ -32,7 +32,7 @@ module ActionView # Topics listed alphabetically # <% end %> def cache(name = {}, options = nil, &block) - controller.fragment_for(output_buffer, name, options, &block) + controller.fragment_for(name, options, &block) end end end diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 03c7ba5a87..b64dc1533f 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -2,22 +2,22 @@ module ActionView module Helpers # CaptureHelper exposes methods to let you extract generated markup which # can be used in other parts of a template or layout file. - # It provides a method to capture blocks into variables through capture and + # It provides a method to capture blocks into variables through capture and # a way to capture a block of markup for use in a layout through content_for. module CaptureHelper - # The capture method allows you to extract part of a template into a - # variable. You can then use this variable anywhere in your templates or layout. - # + # The capture method allows you to extract part of a template into a + # variable. You can then use this variable anywhere in your templates or layout. + # # ==== Examples # The capture method can be used in ERb templates... - # + # # <% @greeting = capture do %> # Welcome to my shiny new web page! The date and time is # <%= Time.now %> # <% end %> # # ...and Builder (RXML) templates. - # + # # @timestamp = capture do # "The current timestamp is #{Time.now}." # end @@ -33,15 +33,17 @@ module ActionView def capture(*args) value = nil buffer = with_output_buffer { value = yield *args } - buffer.presence || value + if string = buffer.presence || value and string.is_a?(String) + NonConcattingString.new(string) + end end # Calling content_for stores a block of markup in an identifier for later use. # You can make subsequent calls to the stored content in other templates or the layout # by passing the identifier as an argument to yield. - # + # # ==== Examples - # + # # <% content_for :not_authorized do %> # alert('You are not authorized to do that!') # <% end %> @@ -92,7 +94,7 @@ module ActionView # <% end %> # # <%# Add some other content, or use a different template: %> - # + # # <% content_for :navigation do %> #
  • <%= link_to 'Login', :action => 'login' %>
  • # <% end %> @@ -109,13 +111,13 @@ module ActionView # for elements that will be fragment cached. def content_for(name, content = nil, &block) content = capture(&block) if block_given? - return @_content_for[name] << content if content - @_content_for[name] + @_content_for[name] << content if content + @_content_for[name] unless content end # content_for? simply checks whether any content has been captured yet using content_for # Useful to render parts of your layout differently based on what is in your views. - # + # # ==== Examples # # Perhaps you will use different css in you layout if no content_for :right_column diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb deleted file mode 100644 index 3d0657e873..0000000000 --- a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb +++ /dev/null @@ -1,52 +0,0 @@ -module ActionView - module Helpers - module DeprecatedBlockHelpers - extend ActiveSupport::Concern - - include ActionView::Helpers::TagHelper - include ActionView::Helpers::TextHelper - include ActionView::Helpers::JavaScriptHelper - include ActionView::Helpers::FormHelper - - def content_tag(*, &block) - block_called_from_erb?(block) ? safe_concat(super) : super - end - - def javascript_tag(*, &block) - block_called_from_erb?(block) ? safe_concat(super) : super - end - - def form_for(*, &block) - block_called_from_erb?(block) ? safe_concat(super) : super - end - - def form_tag(*, &block) - block_called_from_erb?(block) ? safe_concat(super) : super - end - - def fields_for(*, &block) - block_called_from_erb?(block) ? safe_concat(super) : super - end - - def field_set_tag(*, &block) - block_called_from_erb?(block) ? safe_concat(super) : super - end - - BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' - - if RUBY_VERSION < '1.9.0' - # Check whether we're called from an erb template. - # We'd return a string in any other case, but erb <%= ... %> - # can't take an <% end %> later on, so we have to use <% ... %> - # and implicitly concat. - def block_called_from_erb?(block) - block && eval(BLOCK_CALLED_FROM_ERB, block) - end - else - def block_called_from_erb?(block) - block && eval(BLOCK_CALLED_FROM_ERB, block.binding) - end - end - end - end -end \ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index e58fdf81fb..e46ca53275 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -689,6 +689,10 @@ module ActionView @generator << root if root end + def is_a?(klass) + klass == JavaScriptProxy + end + private def method_missing(method, *arguments, &block) if method.to_s =~ /(.*)=$/ diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 310efe40e2..d8dfd5077b 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -16,8 +16,7 @@ module ActionView case options when Hash if block_given? - content = _render_partial(options.merge(:partial => options[:layout]), &block) - safe_concat(content) + _render_partial(options.merge(:partial => options[:layout]), &block) elsif options.key?(:partial) _render_partial(options) else diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index ac5902cc0e..705c2bf82e 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -8,6 +8,13 @@ module ActionView super(value.to_s) end alias :append= :<< + + def append_if_string=(value) + if value.is_a?(String) && !value.is_a?(NonConcattingString) + ActiveSupport::Deprecation.warn("<% %> style block helpers are deprecated. Please use <%= %>", caller) + self << value + end + end end module Template::Handlers @@ -21,14 +28,24 @@ module ActionView src << "@output_buffer.safe_concat('" << escape_text(text) << "');" end + BLOCK_EXPR = /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ + def add_expr_literal(src, code) - if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ + if code =~ BLOCK_EXPR src << '@output_buffer.append= ' << code else src << '@output_buffer.append= (' << code << ');' end end + def add_stmt(src, code) + if code =~ BLOCK_EXPR + src << '@output_buffer.append_if_string= ' << code + else + super + end + end + def add_expr_escaped(src, code) src << '@output_buffer.append= ' << escaped_expr(code) << ';' end -- cgit v1.2.3 From 8dd731bc502a07f4fb76eb2706a1f3bca479ef63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Mar 2010 02:08:34 +0100 Subject: Move more normalization up to the lookup context, so it does not have to repeat in every resolver. --- actionpack/lib/action_view/lookup_context.rb | 36 ++++++++++++++++++++----- actionpack/lib/action_view/template/resolver.rb | 24 +---------------- 2 files changed, 31 insertions(+), 29 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 8eb17bf8f1..598007c7a4 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -15,12 +15,10 @@ module ActionView def self.register_detail(name, options = {}, &block) self.registered_details << name - Setters.send :define_method, :"_#{name}_defaults", &block Setters.module_eval <<-METHOD, __FILE__, __LINE__ + 1 def #{name}=(value) value = Array(value.presence || _#{name}_defaults) - #{"value << nil unless value.include?(nil)" unless options[:allow_nil] == false} unless value == @details[:#{name}] @details_key, @details = nil, @details.merge(:#{name} => value) @@ -69,16 +67,16 @@ module ActionView end def find(name, prefix = nil, partial = false) - @view_paths.find(name, prefix, partial, details, details_key) + @view_paths.find(*args_for_lookup(name, prefix, partial)) end alias :find_template :find def find_all(name, prefix = nil, partial = false) - @view_paths.find_all(name, prefix, partial, details, details_key) + @view_paths.find_all(*args_for_lookup(name, prefix, partial)) end def exists?(name, prefix = nil, partial = false) - @view_paths.exists?(name, prefix, partial, details, details_key) + @view_paths.exists?(*args_for_lookup(name, prefix, partial)) end alias :template_exists? :exists? @@ -94,6 +92,32 @@ module ActionView ensure added_resolvers.times { view_paths.pop } end + + protected + + def args_for_lookup(name, prefix, partial) #:nodoc: + name, prefix = normalize_name(name, prefix) + details_key = self.details_key + details = self.details.merge(:handlers => default_handlers) + [name, prefix, partial || false, details, details_key] + end + + # Support legacy foo.erb names even though we now ignore .erb + # as well as incorrectly putting part of the path in the template + # name instead of the prefix. + def normalize_name(name, prefix) #:nodoc: + name = name.to_s.gsub(handlers_regexp, '') + parts = name.split('/') + return parts.pop, [prefix, *parts].compact.join("/") + end + + def default_handlers #:nodoc: + @detault_handlers ||= Template::Handlers.extensions + end + + def handlers_regexp #:nodoc: + @handlers_regexp ||= /\.(?:#{default_handlers.join('|')})$/ + end end module Details @@ -113,7 +137,7 @@ module ActionView end # Overload formats= to reject [:"*/*"] values. - def formats=(value, freeze=true) + def formats=(value) value = nil if value == [:"*/*"] super(value) end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index a43597e728..ee13707327 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -14,15 +14,8 @@ module ActionView @cached.clear end - def find(*args) - find_all(*args).first - end - # Normalizes the arguments and passes it on to find_template. def find_all(name, prefix=nil, partial=false, details={}, key=nil) - name, prefix = normalize_name(name, prefix) - details = details.merge(:handlers => default_handlers) - cached(key, prefix, name, partial) do find_templates(name, prefix, partial, details) end @@ -34,10 +27,6 @@ module ActionView @caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes end - def default_handlers - Template::Handlers.extensions + [nil] - end - # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. @@ -45,17 +34,6 @@ module ActionView raise NotImplementedError end - # Support legacy foo.erb names even though we now ignore .erb - # as well as incorrectly putting part of the path in the template - # name instead of the prefix. - def normalize_name(name, prefix) - handlers = Template::Handlers.extensions.join('|') - name = name.to_s.gsub(/\.(?:#{handlers})$/, '') - - parts = name.split('/') - return parts.pop, [prefix, *parts].compact.join("/") - end - def cached(key, prefix, name, partial) return yield unless key && caching? scope = @cached[key][prefix][name] @@ -93,7 +71,7 @@ module ActionView query = File.join(@path, path) exts.each do |ext| - query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}' + query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << ',}' end Dir[query].reject { |p| File.directory?(p) }.map do |p| -- cgit v1.2.3 From 9e1e95f70af3c566190f47ee7a52fd49f785ec12 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 15 Mar 2010 23:05:12 -0700 Subject: link_to_remote -> link_to :remote => true --- actionpack/lib/action_view/helpers/capture_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index b64dc1533f..42a67756e4 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -77,7 +77,7 @@ module ActionView # # Then, in another view, you could to do something like this: # - # <%= link_to_remote 'Logout', :action => 'logout' %> + # <%= link_to 'Logout', :action => 'logout', :remote => true %> # # <% content_for :script do %> # <%= javascript_include_tag :defaults %> -- cgit v1.2.3 From b3b6ff48dff49ebbdab0a53f576bc0572116767f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 15 Mar 2010 23:26:48 -0700 Subject: Fix link_to with block --- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 14d59034f1..94f1cecade 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -206,7 +206,7 @@ module ActionView if block_given? options = args.first || {} html_options = args.second - safe_concat(link_to(capture(&block), options, html_options)) + link_to(capture(&block), options, html_options) else name = args[0] options = args[1] || {} -- cgit v1.2.3 From e13c179499f227071cbe829221877e1c0d03c0b1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 8 Mar 2010 19:55:57 -0200 Subject: Change array entries to safe doesn't worth then the array is joined as a string losing the safe property of his entries [#4134 status:resolved] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 8a89ee58a0..f996762d6f 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -13,7 +13,7 @@ module ActionView def translate(key, options = {}) options[:raise] = true translation = I18n.translate(scope_key_by_partial(key), options) - translation.is_a?(Array) ? translation.map { |entry| entry.html_safe } : translation.html_safe + translation.respond_to?(:html_safe) ? translation.html_safe : translation rescue I18n::MissingTranslationData => e keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') -- cgit v1.2.3 From c61ed70b00c93bdf42c7538a334f07e58c60bc4e Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 16 Mar 2010 11:43:04 -0700 Subject: Some more tweaks on <% %>. * The cache helper is now semantically "mark this region for caching" * As a result, <% x = cache do %> no longer works --- actionpack/lib/action_view/helpers/cache_helper.rb | 3 ++- actionpack/lib/action_view/helpers/text_helper.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb index 3729d7daa8..f5c2127d3f 100644 --- a/actionpack/lib/action_view/helpers/cache_helper.rb +++ b/actionpack/lib/action_view/helpers/cache_helper.rb @@ -32,7 +32,8 @@ module ActionView # Topics listed alphabetically # <% end %> def cache(name = {}, options = nil, &block) - controller.fragment_for(name, options, &block) + safe_concat controller.fragment_for(name, options, &block) + nil end end end diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index b19a9754f4..b5bf813e07 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -29,7 +29,7 @@ module ActionView end def safe_concat(string) - output_buffer.safe_concat(string) + output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string) end # Truncates a given +text+ after a given :length if +text+ is longer than :length -- cgit v1.2.3 From 12bf636461e3aab661119ceb3a104cfb70a11666 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 16 Mar 2010 17:36:09 -0300 Subject: translation method of TranslationHelper module returns always SafeBuffer [#4194 status:resolved] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index f996762d6f..26ba4e2ca4 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -13,7 +13,7 @@ module ActionView def translate(key, options = {}) options[:raise] = true translation = I18n.translate(scope_key_by_partial(key), options) - translation.respond_to?(:html_safe) ? translation.html_safe : translation + (translation.respond_to?(:join) ? translation.join : translation).html_safe rescue I18n::MissingTranslationData => e keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') -- cgit v1.2.3 From 56fb60ebfe9a20ced1366f3e35b2f9bd0bac8e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Mar 2010 23:35:45 +0100 Subject: Fix rendering of HTML partials inside JS templates [#4197 status:resolved] --- actionpack/lib/action_view/render/layouts.rb | 17 ++++++++++++++--- actionpack/lib/action_view/template.rb | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index 0cb688ca77..b4720aa681 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -43,10 +43,16 @@ module ActionView # This is the method which actually finds the layout using details in the lookup # context object. If no layout is found, it checkes if at least a layout with # the given name exists across all details before raising the error. - def find_layout(layout) #:nodoc: + # + # If self.formats contains several formats, just the first one is considered in + # the layout lookup. + def find_layout(layout) begin - layout =~ /^\// ? - with_fallbacks { find_template(layout) } : find_template(layout) + if formats.size == 1 + _find_layout(layout) + else + update_details(:formats => self.formats[0,1]){ _find_layout(layout) } + end rescue ActionView::MissingTemplate => e update_details(:formats => nil) do raise unless template_exists?(layout) @@ -54,6 +60,11 @@ module ActionView end end + def _find_layout(layout) #:nodoc: + layout =~ /^\// ? + with_fallbacks { find_template(layout) } : find_template(layout) + end + # Contains the logic that actually renders the layout. def _render_layout(layout, locals, &block) #:nodoc: layout.render(self, locals){ |*name| _layout_for(*name, &block) } diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index b4fdb49d3b..15fafac53d 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -31,7 +31,9 @@ module ActionView format = details[:format] format ||= handler.default_format.to_sym if handler.respond_to?(:default_format) format ||= :html + @formats = [format.to_sym] + @formats << :html if @formats.first == :js end def render(view, locals, &block) -- cgit v1.2.3 From 23b6def0eb76ac0719e420fce91ba862f880a37b Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Tue, 16 Mar 2010 14:55:42 -0700 Subject: Do not always include the named URL helpers into AC::Base and AV::Base. --- actionpack/lib/action_view/base.rb | 4 ++++ actionpack/lib/action_view/helpers/url_helper.rb | 7 +++++++ actionpack/lib/action_view/test_case.rb | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 3920d8593f..daabe6d196 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -235,6 +235,10 @@ module ActionView #:nodoc: include controller._helpers self.helpers = controller._helpers end + + if controller.respond_to?(:_router) + include controller._router.url_helpers + end end else klass = self diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 94f1cecade..f877378ebe 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -9,6 +9,9 @@ module ActionView # This allows you to use the same format for links in views # and controllers. module UrlHelper + extend ActiveSupport::Concern + + include ActionDispatch::Routing::UrlFor include JavaScriptHelper # Need to map default url options to controller one. @@ -16,6 +19,10 @@ module ActionView controller.send(:default_url_options, *args) end + def url_options + controller.url_options + end + # Returns the URL for the set of +options+ provided. This takes the # same options as +url_for+ in Action Controller (see the # documentation for ActionController::Base#url_for). Note that by default diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 1578ac9479..7e609eb640 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -124,7 +124,8 @@ module ActionView def _view view = ActionView::Base.new(ActionController::Base.view_paths, _assigns, @controller) - view.class.send :include, _helpers + view.singleton_class.send :include, _helpers + view.singleton_class.send :include, @controller._router.url_helpers view.output_buffer = self.output_buffer view end -- cgit v1.2.3 From 0c1ac36ccb7d72f3d17d950d030442a7e83d0708 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 16 Mar 2010 20:12:04 -0300 Subject: scope_key_by_partial fix for Ruby 1.9 when there's virtual_path [#4202 state:resolved] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_view/helpers/translation_helper.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 26ba4e2ca4..457944dbb6 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -29,9 +29,10 @@ module ActionView private def scope_key_by_partial(key) - if (key.respond_to?(:join) ? key.join : key.to_s).first == "." + strkey = key.respond_to?(:join) ? key.join : key.to_s + if strkey.first == "." if @_virtual_path - @_virtual_path.gsub(%r{/_?}, ".") + key.to_s + @_virtual_path.gsub(%r{/_?}, ".") + strkey else raise "Cannot use t(#{key.inspect}) shortcut because path is not available" end -- cgit v1.2.3 From 55aac2c6969e4f5209ba786120f1d7b57c80b9a0 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 16 Mar 2010 17:32:42 -0700 Subject: Fix missing require --- actionpack/lib/action_view/helpers/url_helper.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index f877378ebe..79232e297f 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -1,6 +1,7 @@ require 'action_view/helpers/javascript_helper' require 'active_support/core_ext/array/access' require 'active_support/core_ext/hash/keys' +require 'action_dispatch' module ActionView module Helpers #:nodoc: -- cgit v1.2.3 From d69e5616e821afc40efa5936c5ab6e087eb4e0c6 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 16 Mar 2010 22:06:16 -0500 Subject: link_to_function is here to stay --- .../lib/action_view/helpers/javascript_helper.rb | 87 ++++++++++++++++++++++ .../lib/action_view/helpers/prototype_helper.rb | 33 -------- 2 files changed, 87 insertions(+), 33 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 8dab3094dd..0aa539031d 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -89,6 +89,93 @@ module ActionView def javascript_cdata_section(content) #:nodoc: "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe end + + # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the + # onclick handler. + # + # The first argument +name+ is used as the button's value or display text. + # + # The next arguments are optional and may include the javascript function definition and a hash of html_options. + # + # The +function+ argument can be omitted in favor of an +update_page+ + # block, which evaluates to a string when the template is rendered + # (instead of making an Ajax request first). + # + # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" + # + # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil + # + # Examples: + # button_to_function "Greeting", "alert('Hello world!')" + # button_to_function "Delete", "if (confirm('Really?')) do_delete()" + # button_to_function "Details" do |page| + # page[:details].visual_effect :toggle_slide + # end + # button_to_function "Details", :class => "details_button" do |page| + # page[:details].visual_effect :toggle_slide + # end + def button_to_function(name, *args, &block) + html_options = args.extract_options!.symbolize_keys + + function = block_given? ? update_page(&block) : args[0] || '' + onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" + + tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) + end + + # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the + # onclick handler and return false after the fact. + # + # The first argument +name+ is used as the link text. + # + # The next arguments are optional and may include the javascript function definition and a hash of html_options. + # + # The +function+ argument can be omitted in favor of an +update_page+ + # block, which evaluates to a string when the template is rendered + # (instead of making an Ajax request first). + # + # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" + # + # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil + # + # + # Examples: + # link_to_function "Greeting", "alert('Hello world!')" + # Produces: + # Greeting + # + # link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()") + # Produces: + # + # Delete + # + # + # link_to_function("Show me more", nil, :id => "more_link") do |page| + # page[:details].visual_effect :toggle_blind + # page[:more_link].replace_html "Show me less" + # end + # Produces: + # Show me more + # + def link_to_function(name, *args, &block) + html_options = args.extract_options!.symbolize_keys + + function = block_given? ? update_page(&block) : args[0] || '' + onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" + href = html_options[:href] || '#' + + content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) + end end end end diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index e46ca53275..ad3bc8c79c 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -102,39 +102,6 @@ module ActionView :form, :with, :update, :script, :type ]).merge(CALLBACKS) end - # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the - # onclick handler. - # - # The first argument +name+ is used as the button's value or display text. - # - # The next arguments are optional and may include the javascript function definition and a hash of html_options. - # - # The +function+ argument can be omitted in favor of an +update_page+ - # block, which evaluates to a string when the template is rendered - # (instead of making an Ajax request first). - # - # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" - # - # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil - # - # Examples: - # button_to_function "Greeting", "alert('Hello world!')" - # button_to_function "Delete", "if (confirm('Really?')) do_delete()" - # button_to_function "Details" do |page| - # page[:details].visual_effect :toggle_slide - # end - # button_to_function "Details", :class => "details_button" do |page| - # page[:details].visual_effect :toggle_slide - # end - def button_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys - - function = block_given? ? update_page(&block) : args[0] || '' - onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" - - tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) - end - # Returns the JavaScript needed for a remote function. # Takes the same arguments as link_to_remote. # -- cgit v1.2.3 From cd9ffd11e13ef6e62eba2cbd5c3760ff04132820 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 16 Mar 2010 23:24:00 -0700 Subject: Eliminate warnings for AM on 1.8 --- actionpack/lib/action_view/helpers/capture_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 42a67756e4..f0be814700 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -32,7 +32,7 @@ module ActionView # def capture(*args) value = nil - buffer = with_output_buffer { value = yield *args } + buffer = with_output_buffer { value = yield(*args) } if string = buffer.presence || value and string.is_a?(String) NonConcattingString.new(string) end -- cgit v1.2.3 From a5587efc1903fd27d4b179753aa6e139445ad18c Mon Sep 17 00:00:00 2001 From: wycats Date: Wed, 17 Mar 2010 00:15:55 -0700 Subject: Remove some 1.9 warnings (resulting in some fixed bugs). Remaining AM warnings are in dependencies. --- actionpack/lib/action_view/base.rb | 1 + actionpack/lib/action_view/helpers/form_helper.rb | 6 +++--- actionpack/lib/action_view/helpers/javascript_helper.rb | 1 - actionpack/lib/action_view/helpers/prototype_helper.rb | 2 -- actionpack/lib/action_view/helpers/text_helper.rb | 2 +- actionpack/lib/action_view/template.rb | 1 - 6 files changed, 5 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index daabe6d196..326b79f9bf 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -187,6 +187,7 @@ module ActionView #:nodoc: @@debug_rjs = false class_attribute :helpers + remove_method :helpers attr_reader :helpers class << self diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 48df26efaa..01a585af95 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1014,7 +1014,7 @@ module ActionView class FormBuilder #:nodoc: # The methods which wrap a form helper call. class_inheritable_accessor :field_helpers - self.field_helpers = (FormHelper.instance_methods - ['form_for']) + self.field_helpers = (FormHelper.instance_method_names - ['form_for']) attr_accessor :object_name, :object, :options @@ -1040,7 +1040,7 @@ module ActionView end (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector| - src = <<-end_src + src, file, line = <<-end_src, __FILE__, __LINE__ + 1 def #{selector}(method, options = {}) # def text_field(method, options = {}) @template.send( # @template.send( #{selector.inspect}, # "text_field", @@ -1049,7 +1049,7 @@ module ActionView objectify_options(options)) # objectify_options(options)) end # end end_src - class_eval src, __FILE__, __LINE__ + class_eval src, file, line end def fields_for(record_or_name_or_array, *args, &block) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 0aa539031d..5635f88c11 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -1,5 +1,4 @@ require 'action_view/helpers/tag_helper' -require 'action_view/helpers/prototype_helper' module ActionView module Helpers diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index ad3bc8c79c..2e5fe5744e 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -853,5 +853,3 @@ module ActionView end end end - -require 'action_view/helpers/javascript_helper' diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index b5bf813e07..13fad0ed7a 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -576,7 +576,7 @@ module ActionView # each email is yielded and the result is used as the link text. def auto_link_email_addresses(text, html_options = {}) body = text.dup - text.gsub(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do + text.gsub(/([\w\.!#\$%\-+]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do text = $1 if body.match(/]*>(.*)(#{Regexp.escape(text)})(.*)<\/a>/) diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 15fafac53d..6315e502dd 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -2,7 +2,6 @@ # This is so that templates compiled in this file are UTF-8 require 'set' -require "action_view/template/resolver" module ActionView class Template -- cgit v1.2.3 From 947f86c699b33bd44703b3554db58e4cfca37c86 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 17 Mar 2010 14:19:42 -0700 Subject: Modify assert_template to use instrumentation --- actionpack/lib/action_view/template.rb | 8 ++++++-- actionpack/lib/action_view/test_case.rb | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 6315e502dd..ad37eb4c4a 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -36,8 +36,12 @@ module ActionView end def render(view, locals, &block) - method_name = compile(locals, view) - view.send(method_name, locals, &block) + # TODO: Revisit this name + # This is only slow if it's being listened to. Do not instrument this in production. + ActiveSupport::Notifications.instrument("action_view.slow_render_template", :virtual_path => @virtual_path) do + method_name = compile(locals, view) + view.send(method_name, locals, &block) + end rescue Exception => e if e.is_a?(Template::Error) e.sub_template_of(self) diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 7e609eb640..8750a501b7 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -42,6 +42,7 @@ module ActionView end include ActionDispatch::Assertions, ActionDispatch::TestProcess + include ActionController::TemplateAssertions include ActionView::Context include ActionController::PolymorphicRoutes -- cgit v1.2.3 From 6416a35f4b3290a93145d40045147fc01d36e756 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 17 Mar 2010 14:23:00 -0700 Subject: Remove unneeded AV::Base and AV::Template monkey-patches --- actionpack/lib/action_view/test_case.rb | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 8750a501b7..1c69c23bfc 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -2,27 +2,6 @@ require 'action_controller/test_case' require 'action_view' module ActionView - class Base - alias_method :initialize_without_template_tracking, :initialize - def initialize(*args) - @_rendered = { :template => nil, :partials => Hash.new(0) } - initialize_without_template_tracking(*args) - end - - attr_internal :rendered - end - - class Template - alias_method :render_without_tracking, :render - def render(view, locals, &blk) - rendered = view.rendered - rendered[:partials][self] += 1 if partial? - rendered[:template] ||= [] - rendered[:template] << self - render_without_tracking(view, locals, &blk) - end - end - class TestCase < ActiveSupport::TestCase class TestController < ActionController::Base attr_accessor :request, :response, :params -- cgit v1.2.3 From a6dc227167a8a720bd18495268305b15aa08d8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 17 Mar 2010 23:44:03 +0100 Subject: Mark bang instrumentations as something that you shuold not be listening to. --- actionpack/lib/action_view/template.rb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index ad37eb4c4a..9145d007a8 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -23,7 +23,6 @@ module ActionView @identifier = identifier @handler = handler - @partial = details[:partial] @virtual_path = details[:virtual_path] @method_names = {} @@ -36,9 +35,9 @@ module ActionView end def render(view, locals, &block) - # TODO: Revisit this name - # This is only slow if it's being listened to. Do not instrument this in production. - ActiveSupport::Notifications.instrument("action_view.slow_render_template", :virtual_path => @virtual_path) do + # Notice that we use a bang in this instrumentation because you don't want to + # consume this in production. This is only slow if it's being listened to. + ActiveSupport::Notifications.instrument("action_view.render_template!", :virtual_path => @virtual_path) do method_name = compile(locals, view) view.send(method_name, locals, &block) end @@ -63,10 +62,6 @@ module ActionView @counter_name ||= "#{variable_name}_counter".to_sym end - def partial? - @partial - end - def inspect if defined?(Rails.root) identifier.sub("#{Rails.root}/", '') -- cgit v1.2.3 From d9375f3f302a5d1856ad57946c7263d4e6a45a2a Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 17 Mar 2010 16:28:05 -0700 Subject: Modify assert_template to use notifications. Also, remove ActionController::Base#template since it is no longer needed. --- actionpack/lib/action_view/base.rb | 9 +++++++-- actionpack/lib/action_view/helpers/prototype_helper.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 3 +-- actionpack/lib/action_view/test_case.rb | 4 +++- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 326b79f9bf..4d9f53cf95 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -196,7 +196,7 @@ module ActionView #:nodoc: end attr_accessor :base_path, :assigns, :template_extension, :lookup_context - attr_internal :captures, :request, :layout, :controller, :template, :config + attr_internal :captures, :request, :controller, :template, :config delegate :find_template, :template_exists?, :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context @@ -206,6 +206,11 @@ module ActionView #:nodoc: delegate :logger, :to => :controller, :allow_nil => true + # TODO: HACK FOR RJS + def view_context + self + end + def self.xss_safe? #:nodoc: true end @@ -254,7 +259,7 @@ module ActionView #:nodoc: @helpers = self.class.helpers || Module.new @_controller = controller - @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller + @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller && controller.respond_to?(:config) @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 2e5fe5744e..aba2565c67 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -582,7 +582,7 @@ module ActionView # page.hide 'spinner' # end def update_page(&block) - JavaScriptGenerator.new(@template, &block).to_s.html_safe + JavaScriptGenerator.new(view_context, &block).to_s.html_safe end # Works like update_page but wraps the generated JavaScript in a