diff options
author | Sam Stephenson <sam@37signals.com> | 2006-01-23 17:09:15 +0000 |
---|---|---|
committer | Sam Stephenson <sam@37signals.com> | 2006-01-23 17:09:15 +0000 |
commit | 9c52a41241a632315edb77381240b66a7cc5aef4 (patch) | |
tree | 872352d82ff875e7d4ddd43c0f1adbc714e8282f | |
parent | 185cca238bc1df79a3bb438679bbbeb980f82078 (diff) | |
download | rails-9c52a41241a632315edb77381240b66a7cc5aef4.tar.gz rails-9c52a41241a632315edb77381240b66a7cc5aef4.tar.bz2 rails-9c52a41241a632315edb77381240b66a7cc5aef4.zip |
Add the ability to call JavaScriptGenerator methods from helpers called in update blocks
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3476 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | actionpack/CHANGELOG | 14 | ||||
-rwxr-xr-x | actionpack/lib/action_controller/base.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/prototype_helper.rb | 58 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/scriptaculous_helper.rb | 17 | ||||
-rw-r--r-- | actionpack/test/controller/new_render_test.rb | 2 | ||||
-rw-r--r-- | actionpack/test/template/scriptaculous_helper_test.rb | 9 |
6 files changed, 62 insertions, 43 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index a99e9d7831..3f85c38106 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,19 @@ *SVN* +* Add the ability to call JavaScriptGenerator methods from helpers called in update blocks. [Sam Stephenson] Example: + module ApplicationHelper + def update_time + page.replace_html 'time', Time.now.to_s(:db) + page.visual_effect :highlight, 'time' + end + end + + class UserController < ApplicationController + def poll + render :update { |page| page.update_time } + end + end + * Add render(:update) to ActionView::Base. [Sam Stephenson] * Fix render(:update) to not render layouts. [Sam Stephenson] diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 0a9368f684..7f8ff5ed09 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -687,7 +687,7 @@ module ActionController #:nodoc: end def render_javascript(javascript, status = nil) - @response.headers['Content-type'] = 'text/javascript' + @response.headers['Content-Type'] = 'text/javascript' render_text(javascript, status) end @@ -719,7 +719,8 @@ module ActionController #:nodoc: @response.body = nil @performed_render = false end - + + # Clears the redirected results from the headers, resets the status to 200 and returns # the URL that was used to redirect or nil if there was no redirected URL # Note that +redirect_to+ will change the body of the response to indicate a redirection. diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index d35334a98c..27dc9c93cf 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -370,34 +370,52 @@ module ActionView # this in your Ajax response bodies, either in a <script> tag or as plain # JavaScript sent with a Content-type of "text/javascript". # - # Create new instances with PrototypeHelper#update_page, then call - # #insert_html, #replace_html, #remove, #show, or #hide on the yielded - # generator in any order you like to modify the content and appearance of - # the current page. (You can also call other helper methods which - # return JavaScript, such as - # ActionView::Helpers::ScriptaculousHelper#visual_effect.) + # Create new instances with PrototypeHelper#update_page or with + # ActionController::Base#render, then call #insert_html, #replace_html, + # #remove, #show, #hide, #visual_effect, or any other of the built-in + # methods on the yielded generator in any order you like to modify the + # content and appearance of the current page. # # Example: # # update_page do |page| - # page.insert_html :bottom, 'list', '<li>Last item</li>' + # page.insert_html :bottom, 'list', "<li>#{@item.name}</li>" # page.visual_effect :highlight, 'list' # page.hide 'status-indicator', 'cancel-link' # end # # generates the following JavaScript: # - # new Insertion.Bottom("list", "<li>Last item</li>"); + # new Insertion.Bottom("list", "<li>Some item</li>"); # new Effect.Highlight("list"); # ["status-indicator", "cancel-link"].each(Element.hide); # + # Helper methods can be used in conjunction with JavaScriptGenerator. + # When a helper method is called inside an update block on the +page+ + # object, that method will also have access to a +page+ object. + # + # Example: + # + # module ApplicationHelper + # def update_time + # page.replace_html 'time', Time.now.to_s(:db) + # page.visual_effect :highlight, 'time' + # end + # end + # + # # Controller action + # def poll + # render :update { |page| page.update_time } + # end + # # You can also use PrototypeHelper#update_page_tag instead of # PrototypeHelper#update_page to wrap the generated JavaScript in a # <script> tag. class JavaScriptGenerator - def initialize(context) #:nodoc: + def initialize(context, &block) #:nodoc: @context, @lines = context, [] - yield self + include_helpers_from_context + @context.instance_exec(self, &block) end def to_s #:nodoc: @@ -501,12 +519,24 @@ module ActionView yield record "}, #{(seconds * 1000).to_i})" end - + + # Starts a Scriptaculous visual effect. See + # ActionView::Helpers::ScriptaculousHelper for more information. + def visual_effect(name, id, options = {}) + record @context.send(:visual_effect, name, id, options) + end + private - def method_missing(method, *arguments, &block) - record(@context.send(method, *arguments, &block)) + def include_helpers_from_context + @context.extended_by.each do |mod| + extend mod unless mod.name =~ /^ActionView::Helpers/ + end end - + + def page + self + end + def record(line) returning line = "#{line.to_s.chomp.gsub /\;$/, ''};" do self << line diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb index 5f7e90ec33..e64966d919 100644 --- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb +++ b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb @@ -52,23 +52,6 @@ module ActionView end end - # Needs more work so + isn't required for concation of effects. Currently, you have to do: - # - # page.parallel_effects do - # page.visual_effect(:highlight, 'dom_id') + - # page.visual_effect(:fade, 'dom_id') - # end - # - # ...naturally, it would be better just to do - # - # page.parallel_effects do - # page.visual_effect :highlight, 'dom_id' - # page.visual_effect :fade, 'dom_id' - # end - def parallel_effects(js_options = {}) #:nodoc: - "new Effect.Parallel([" + yield + "], #{options_for_javascript(js_options)})" - end - # Makes the element with the DOM ID specified by +element_id+ sortable # by drag-and-drop and make an Ajax call whenever the sort order has # changed. By default, the action called gets the serialized sortable diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb index cb42142611..0208912ece 100644 --- a/actionpack/test/controller/new_render_test.rb +++ b/actionpack/test/controller/new_render_test.rb @@ -490,7 +490,7 @@ class NewRenderTest < Test::Unit::TestCase def test_update_page get :update_page assert_template nil - assert_equal 'text/javascript', @response.headers['Content-type'] + assert_equal 'text/javascript', @response.headers['Content-Type'] assert_equal 2, @response.body.split($/).length end diff --git a/actionpack/test/template/scriptaculous_helper_test.rb b/actionpack/test/template/scriptaculous_helper_test.rb index b42d8f7f04..779b5aa13b 100644 --- a/actionpack/test/template/scriptaculous_helper_test.rb +++ b/actionpack/test/template/scriptaculous_helper_test.rb @@ -40,15 +40,6 @@ class ScriptaculousHelperTest < Test::Unit::TestCase end - def test_parallel_effects - actual = parallel_effects(:duration => 2) do - visual_effect(:highlight, "posts") + - visual_effect(:fade, "fademe", :duration => 4.0) - end - - assert_equal "new Effect.Parallel([new Effect.Highlight('posts',{});new Effect.Fade('fademe',{duration:4.0});], {duration:2})", actual - end - def test_sortable_element assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create('mylist', {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize('mylist')})}})\n//]]>\n</script>), sortable_element("mylist", :url => { :action => "order" }) |