apotomo 1.0.5 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGES.textile +35 -7
  3. data/Gemfile +0 -2
  4. data/README.rdoc +9 -9
  5. data/apotomo.gemspec +3 -3
  6. data/lib/apotomo.rb +4 -47
  7. data/lib/apotomo/event.rb +2 -0
  8. data/lib/apotomo/event_handler.rb +0 -3
  9. data/lib/apotomo/event_methods.rb +6 -2
  10. data/lib/apotomo/invoke_event_handler.rb +5 -3
  11. data/lib/apotomo/javascript_generator.rb +19 -16
  12. data/lib/apotomo/rails/controller_methods.rb +84 -131
  13. data/lib/apotomo/rails/view_helper.rb +15 -31
  14. data/lib/apotomo/railtie.rb +24 -0
  15. data/lib/apotomo/request_processor.rb +17 -48
  16. data/lib/apotomo/test_case.rb +5 -5
  17. data/lib/apotomo/tree_node.rb +52 -61
  18. data/lib/apotomo/version.rb +1 -1
  19. data/lib/apotomo/widget.rb +70 -146
  20. data/lib/apotomo/widget/javascript_methods.rb +39 -0
  21. data/lib/apotomo/widget_shortcuts.rb +14 -40
  22. data/lib/generators/apotomo/widget_generator.rb +8 -9
  23. data/lib/generators/erb/widget_generator.rb +17 -0
  24. data/lib/generators/haml/widget_generator.rb +20 -0
  25. data/lib/generators/{apotomo/templates → templates}/view.erb +1 -1
  26. data/lib/generators/templates/view.haml +4 -0
  27. data/lib/generators/{apotomo/templates → templates}/widget.rb +1 -1
  28. data/lib/generators/{apotomo/templates → templates}/widget_test.rb +1 -1
  29. data/lib/generators/test_unit/widget_generator.rb +14 -0
  30. data/test/rails/caching_test.rb +10 -17
  31. data/test/rails/controller_methods_test.rb +9 -81
  32. data/test/rails/rails_integration_test.rb +76 -60
  33. data/test/rails/view_helper_test.rb +17 -28
  34. data/test/rails/widget_generator_test.rb +19 -31
  35. data/test/support/test_case_methods.rb +6 -20
  36. data/test/test_helper.rb +15 -25
  37. data/test/unit/event_handler_test.rb +1 -0
  38. data/test/unit/event_methods_test.rb +20 -8
  39. data/test/unit/event_test.rb +5 -0
  40. data/test/unit/javascript_generator_test.rb +19 -19
  41. data/test/unit/render_test.rb +17 -112
  42. data/test/unit/request_processor_test.rb +73 -111
  43. data/test/unit/test_case_test.rb +13 -7
  44. data/test/unit/widget_shortcuts_test.rb +24 -53
  45. data/test/unit/widget_test.rb +76 -36
  46. data/test/widgets/mouse/eat.erb +1 -0
  47. data/test/{fixtures → widgets}/mouse/eating.html.erb +0 -0
  48. data/test/{fixtures → widgets}/mouse/educate.html.erb +0 -0
  49. data/test/{fixtures → widgets}/mouse/feed.html.erb +0 -0
  50. data/test/{fixtures → widgets}/mouse/make_me_squeak.html.erb +0 -0
  51. data/test/{fixtures → widgets}/mouse/posing.html.erb +0 -0
  52. data/test/widgets/mouse/snuggle.html.erb +1 -0
  53. metadata +32 -50
  54. data/lib/apotomo/container_widget.rb +0 -10
  55. data/lib/apotomo/persistence.rb +0 -112
  56. data/lib/apotomo/rails/view_methods.rb +0 -7
  57. data/lib/apotomo/stateful_widget.rb +0 -29
  58. data/lib/apotomo/transition.rb +0 -46
  59. data/lib/generators/apotomo/templates/view.haml +0 -4
  60. data/test/dummy/log/production.log +0 -0
  61. data/test/dummy/log/server.log +0 -0
  62. data/test/dummy/public/javascripts/application.js +0 -2
  63. data/test/dummy/public/javascripts/controls.js +0 -965
  64. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  65. data/test/dummy/public/javascripts/effects.js +0 -1123
  66. data/test/dummy/public/javascripts/prototype.js +0 -6001
  67. data/test/dummy/public/javascripts/rails.js +0 -175
  68. data/test/dummy/script/rails +0 -6
  69. data/test/dummy/tmp/app/cells/mouse_widget.rb +0 -11
  70. data/test/dummy/tmp/app/cells/mouse_widget/snuggle.html.erb +0 -7
  71. data/test/dummy/tmp/app/cells/mouse_widget/squeak.html.erb +0 -7
  72. data/test/dummy/tmp/test/widgets/mouse_widget_test.rb +0 -12
  73. data/test/fixtures/application_widget_tree.rb +0 -2
  74. data/test/fixtures/mouse/snuggle.html.erb +0 -1
  75. data/test/rails/view_methods_test.rb +0 -38
  76. data/test/unit/container_test.rb +0 -21
  77. data/test/unit/invoke_test.rb +0 -126
  78. data/test/unit/persistence_test.rb +0 -201
  79. data/test/unit/stateful_widget_test.rb +0 -58
  80. data/test/unit/test_addressing.rb +0 -110
  81. data/test/unit/test_jump_to_state.rb +0 -89
  82. data/test/unit/test_tab_panel.rb +0 -71
  83. data/test/unit/transition_test.rb +0 -34
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ test/dummy/log/*
5
+ test/dummy/tmp/*
data/CHANGES.textile CHANGED
@@ -1,17 +1,45 @@
1
- h2. 1.0.5
1
+ h2. 1.1
2
2
 
3
+ h3. Changes
4
+ * Widgets now reside in @app/widgets/@ and have the @Widget@ appendix per convention, identical to cells and controllers. This introduces the following changes, illustrated with an imaginary @CommentsWidget@:
5
+ ** @widget(:comments, ...)@ will search and instantiate @CommentsWidget@ (note the missing "Widget").
6
+ ** The @CommentsWidget@ views are searched in @app/widgets/comments/@ (note the missing "_widget").
7
+ * Including Apotomo::Rails::ControllerMethods by hand is optional. The first call to Controller.has_widgets will include the real module.
8
+ * You can now @#render_widget@ in your widget views to render children.
9
+ * @#widget@ now accepts one arg only (the widget prefix). @widget(:comments)@ sets id to @:comments@. We also removed the start state argument.
10
+ * Start states are no longer accepted, you have to explicitely pass the state to #render_widget. That's why #invoke now requires an explicit state as well.
11
+ * The event is no longer added to #options at triggering time.
12
+ * Options passed in #render_widget are no longer merged with #options. They are passed as state-args to reduce complexity.
13
+ * We no longer have @opts and @params but #options and #params from Cell::Base.
14
+ * The params hash is appended to the event in RequestProcessor#process_for. You can now live completely without accessing the global #params.
15
+ * #respond/#update with :selector does not longer prefix the selector with #. It's up to you.
16
+ * Event delegates #[] to #data.
17
+
18
+ h3. Removals
19
+ * Removed #param, it is simply too complex.
20
+ * Removed render :render_children and :invoke options. Use #render_widget in your state/view.
21
+ * Removed render :suppress_js as it was ugly and kills children.
22
+ * Removed #jump_to_state and #last_state.
23
+ * Removed `@cell`, now longer available in state views.
24
+ * Removed #cell, #container and #section widget shortcuts.
25
+ * Removed @rendered_children@ local in views. Use #render_widget.
26
+ * Removed ContainerWidget, nobody needs it.
27
+
3
28
  h3. Bugfixes
4
- * Fixed a bug in Widget.responds_to_event. Thanks to Scott Rainey for urging.
29
+ * Widget.responds_to_event no longer shares its options with multiple widget instances of the same class.
30
+
5
31
 
6
32
  h2. 1.0.4
7
33
 
8
34
  h3. Bugfixes
9
- * Caching states works, again. Thanks to Gudleik Rasch for spotting.
10
- * We cleanly require cells-3.4.x now. Thanks to Ryan Bates who remarked that Apotomo 1.0.x tries to require cells-3.5, which was wrong.
11
-
35
+ * Caching states works, again. Thanks to Gudleik Rasch for spotting.
36
+ * We cleanly require cells-3.4.x now. Thanks to Ryan Bates who remarked that Apotomo 1.0.x tries to require cells-3.5, which was wrong.
37
+
12
38
  h3. Notes
13
- * Removed the usage of state-args. If you want the event instance in your triggered state, use @opts[:event] or upgrade to apotomo-1.1.
14
-
39
+
40
+ * Removed the usage of state-args. If you want the event instance in your triggered state, use @opts[:event] or upgrade to apotomo-1.1.
41
+
42
+
15
43
  h2. 1.0.3
16
44
 
17
45
  h3. Bugfixes
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
-
5
- #gem "rails", :path => "/home/nick/projects/rayls"
data/README.rdoc CHANGED
@@ -42,7 +42,7 @@ Let's wrap that comments block in a widget.
42
42
 
43
43
  Go and generate a widget stub.
44
44
 
45
- $ rails generate apotomo:widget CommentsWidget display write --haml
45
+ $ rails generate apotomo:widget CommentsWidget display write -e haml
46
46
  create app/cells/
47
47
  create app/cells/comments_widget
48
48
  create app/cells/comments_widget.rb
@@ -84,8 +84,8 @@ A widget is like a cell which is like a mini-controller.
84
84
  class CommentsWidget < Apotomo::Widget
85
85
  responds_to_event :submit, :with => :write
86
86
 
87
- def display
88
- @comments = param(:post).comments # the parameter from outside.
87
+ def display(args)
88
+ @comments = args[:post].comments # the parameter from outside.
89
89
  render
90
90
  end
91
91
 
@@ -93,9 +93,9 @@ Having +display+ as the default state when rendering, this method collects comme
93
93
 
94
94
  And look at line 2 - if encountering a <tt>:submit</tt> event we invoke +write+, which is simply another state. How cool is that?
95
95
 
96
- def write
97
- @comment = Comment.new(:post => param(:post))
98
- @comment.update_attributes param(:comment) # like params[].
96
+ def write(evt)
97
+ @comment = Comment.new(:post_id => evt[:post_id])
98
+ @comment.update_attributes evt[:comment] # a bit like params[].
99
99
 
100
100
  update :state => :display
101
101
  end
@@ -160,8 +160,8 @@ Look, +replace+ basically generates
160
160
 
161
161
  If that's not what you want, do
162
162
 
163
- def write
164
- if param(:comment)[:text].explicit?
163
+ def write(evt)
164
+ if evt[:comment][:text].explicit?
165
165
  render :text => 'alert("Hey, you wanted to submit a pervert comment!");'
166
166
  end
167
167
  end
@@ -210,4 +210,4 @@ If you wanna be cool, subscribe to our feed[http://feeds.feedburner.com/Apotomo]
210
210
 
211
211
 
212
212
  == License
213
- Copyright (c) 2007-2010 Nick Sutterer <apotonick@gmail.com> under the MIT License
213
+ Copyright (c) 2007-2011 Nick Sutterer <apotonick@gmail.com> under the MIT License
data/apotomo.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.email = ["apotonick@gmail.com"]
13
13
  s.homepage = "http://github.com/apotonick/apotomo"
14
14
  s.summary = %q{Web components for Rails.}
15
- s.description = %q{Web component framework for Rails providing page widgets that trigger events and know when and how to update themselves with AJAX.}
15
+ s.description = %q{Web component framework for Rails providing widgets that trigger events and know when and how to update themselves with AJAX.}
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -20,8 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_dependency "rails", "~> 3.0"
23
- s.add_dependency "cells", "~> 3.4.0"
24
- s.add_dependency "onfire", "~> 0.1.1"
23
+ s.add_dependency "cells", "~> 3.5.4"
24
+ s.add_dependency "onfire", "~> 0.1.2"
25
25
  s.add_dependency "hooks", "~> 0.1.3"
26
26
 
27
27
  s.add_development_dependency "shoulda"
data/lib/apotomo.rb CHANGED
@@ -1,33 +1,8 @@
1
- # Copyright (c) 2007-2010 Nick Sutterer <apotonick@gmail.com>
2
- #
3
- # The MIT License
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require "rails/railtie"
24
- require 'rails/engine'
25
-
26
1
  module Apotomo
27
2
  class << self
28
3
  def js_framework=(js_framework)
29
4
  @js_framework = js_framework
30
- @js_generator = ::Apotomo::JavascriptGenerator.new(js_framework)
5
+ @js_generator = JavascriptGenerator.new(js_framework)
31
6
  end
32
7
 
33
8
  attr_reader :js_generator, :js_framework
@@ -43,31 +18,13 @@ module Apotomo
43
18
  yield self
44
19
  end
45
20
  end
46
-
47
- # Piotr Sarnacki: Railtie :P
48
- class Railtie < Rails::Railtie
49
- rake_tasks do
50
- load "apotomo/apotomo.rake"
51
- end
52
-
53
- # As we are a Railtie only, the routes won't be loaded automatically. Beside that, we want our
54
- # route to be the very first (otherwise #resources might supersede it).
55
- initializer :prepend_apotomo_routes, :after => :add_routing_paths do |app|
56
- app.routes_reloader.paths.unshift(File.dirname(__FILE__) + "/../config/routes.rb")
57
- end
58
- end
59
21
  end
60
22
 
61
-
62
23
  require 'apotomo/widget'
63
- require 'apotomo/stateful_widget'
64
- require 'apotomo/container_widget'
24
+ require 'apotomo/railtie'
65
25
  require 'apotomo/widget_shortcuts'
66
26
  require 'apotomo/rails/controller_methods'
67
-
68
-
69
27
  require 'apotomo/javascript_generator'
70
- Apotomo.js_framework = :jquery ### DISCUSS: move to rails.rb
28
+ require 'apotomo/test_case' if Rails.env == "test"
71
29
 
72
- ### FIXME: only load in test env.
73
- require 'apotomo/test_case' #if defined?("Rails") and Rails.env == "test"
30
+ Apotomo.js_framework = :jquery ### DISCUSS: move to rails.rb
data/lib/apotomo/event.rb CHANGED
@@ -5,5 +5,7 @@ module Apotomo
5
5
  def _dump(depth)
6
6
  raise "You're trying to serialize an instance of Apotomo::Event. Don't do that."
7
7
  end
8
+
9
+ delegate :[], :to => :data
8
10
  end
9
11
  end
@@ -18,6 +18,3 @@ module Apotomo
18
18
 
19
19
  end
20
20
  end
21
-
22
- require 'apotomo/invoke_event_handler'
23
- require 'apotomo/proc_event_handler'
@@ -1,4 +1,4 @@
1
- require 'apotomo/event_handler'
1
+ require 'apotomo/invoke_event_handler'
2
2
 
3
3
  module Apotomo
4
4
  # Introduces event-processing functions into the StatefulWidget.
@@ -77,7 +77,7 @@ module Apotomo
77
77
  # which can be queried in a triggered state.
78
78
  #
79
79
  # def on_drop(event)
80
- # if event.data[:area] == 59
80
+ # if event[:area] == 59
81
81
  def trigger(*args)
82
82
  fire(*args)
83
83
  end
@@ -87,5 +87,9 @@ module Apotomo
87
87
  def local_event_handlers(event)
88
88
  event_table.all_handlers_for(event.type, event.source.name) # we key with widget_id.
89
89
  end
90
+
91
+ def event_for(*args) # defined in Onfire: we want Apotomo::Event.
92
+ Event.new(*args)
93
+ end
90
94
  end
91
95
  end
@@ -1,10 +1,12 @@
1
+ require 'apotomo/event_handler'
2
+
1
3
  module Apotomo
2
4
  class InvokeEventHandler < EventHandler
3
5
  attr_accessor :widget_id, :state
4
6
 
5
- def initialize(opts={})
6
- @widget_id = opts.delete(:widget_id)
7
- @state = opts.delete(:state)
7
+ def initialize(options={})
8
+ @widget_id = options.delete(:widget_id)
9
+ @state = options.delete(:state)
8
10
  end
9
11
 
10
12
  def process_event(event)
@@ -31,27 +31,30 @@ module Apotomo
31
31
  end
32
32
 
33
33
  module Prototype
34
- def prototype; end
35
- def element(id); "$(\"#{id}\")"; end
36
- def xhr(url); "new Ajax.Request(\"#{url}\")"; end
37
- def update(id, markup); element(id) + '.update("'+escape(markup)+'")'; end
38
- def replace(id, markup); element(id) + '.replace("'+escape(markup)+'")'; end
34
+ def prototype; end
35
+ def element(id); "$(\"#{id}\")"; end
36
+ def update(id, markup); element(id) + '.update("'+escape(markup)+'")'; end
37
+ def replace(id, markup); element(id) + '.replace("'+escape(markup)+'")'; end
38
+ def update_id(id, markup); update(id, markup); end
39
+ def replace_id(id, markup); replace(id, markup); end
39
40
  end
40
41
 
41
42
  module Right
42
- def right; end
43
- def element(id); "$(\"#{id}\")"; end
44
- def xhr(url); "new Xhr(\"#{url}\", {evalScripts:true}).send()"; end
45
- def update(id, markup); element(id) + '.update("'+escape(markup)+'")'; end
46
- def replace(id, markup); element(id) + '.replace("'+escape(markup)+'")'; end
43
+ def right; end
44
+ def element(id); "$(\"#{id}\")"; end
45
+ def update(id, markup); element(id) + '.update("'+escape(markup)+'")'; end
46
+ def replace(id, markup); element(id) + '.replace("'+escape(markup)+'")'; end
47
+ def update_id(id, markup); update(id, markup); end
48
+ def replace_id(id, markup); replace(id, markup); end
47
49
  end
48
50
 
49
51
  module Jquery
50
- def jquery; end
51
- def element(id); "$(\"##{id}\")"; end
52
- def xhr(url); "$.ajax({url: \"#{url}\"})"; end
53
- def update(id, markup); element(id) + '.html("'+escape(markup)+'")'; end
54
- def replace(id, markup); element(id) + '.replaceWith("'+escape(markup)+'")'; end
52
+ def jquery; end
53
+ def element(id); "$(\"#{id}\")"; end
54
+ def update(id, markup); element(id) + '.html("'+escape(markup)+'")'; end
55
+ def replace(id, markup); element(id) + '.replaceWith("'+escape(markup)+'")'; end
56
+ def update_id(id, markup); update("##{id}", markup); end
57
+ def replace_id(id, markup); replace("##{id}", markup); end
55
58
  end
56
59
  end
57
- end
60
+ end
@@ -1,151 +1,104 @@
1
1
  require 'apotomo/request_processor'
2
- require 'apotomo/rails/view_methods'
3
2
 
4
- module Apotomo
5
- module Rails
6
- module ControllerMethods
7
- include WidgetShortcuts
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- extend WidgetShortcuts
12
-
13
- class_inheritable_array :has_widgets_blocks
14
- self.has_widgets_blocks = []
15
-
16
- helper ::Apotomo::Rails::ViewMethods
17
-
18
- after_filter :apotomo_freeze
19
- end
20
-
21
- module ClassMethods
22
- # Yields the root widget to setup your widgets for a controller. The block is executed in
23
- # controller _instance_ context, so you may use instance methods and variables of the
24
- # controller.
25
- #
26
- # Example:
27
- # class PostsController < ApplicationController
28
- # has_widgets do |root|
29
- # root << widget(:comments_widget, 'post-comments', :user => @current_user)
30
- # end
31
- def has_widgets(&block)
32
- has_widgets_blocks << block
33
- end
34
- end
35
-
36
- def bound_use_widgets_blocks
37
- session[:bound_use_widgets_blocks] ||= ProcHash.new
38
- end
39
-
40
- def flush_bound_use_widgets_blocks
41
- session[:bound_use_widgets_blocks] = nil
42
- end
43
-
44
- def apotomo_request_processor
45
- return @apotomo_request_processor if @apotomo_request_processor
46
-
47
- # happens once per request:
48
- ### DISCUSS: policy in production?
49
- options = { :flush_widgets => params[:flush_widgets],
50
- :js_framework => Apotomo.js_framework || :prototype,
51
- } ### TODO: process rails options (flush_tree, version)
52
-
53
- @apotomo_request_processor = Apotomo::RequestProcessor.new(self, session, options, self.class.has_widgets_blocks)
54
-
55
- flush_bound_use_widgets_blocks if @apotomo_request_processor.widgets_flushed?
56
-
57
-
58
- @apotomo_request_processor
59
- end
3
+ module Apotomo
4
+ module Rails
5
+ # Lazy-loads Apotomo support into controllers when needed.
6
+ module ControllerMethodsLoader
7
+ def has_widgets(*args, &block)
8
+ include ControllerMethods
9
+ has_widgets(*args, &block)
10
+ end
11
+ end
12
+
13
+
14
+ module ActionViewMethods
15
+ delegate :render_widget, :url_for_event, :to => :controller
16
+ end
17
+
18
+ module ControllerMethods
19
+ include WidgetShortcuts
20
+ extend ActiveSupport::Concern
21
+
22
+ included do
23
+ extend WidgetShortcuts
60
24
 
61
- def apotomo_root
62
- apotomo_request_processor.root
63
- end
25
+ class_inheritable_array :has_widgets_blocks
26
+ self.has_widgets_blocks = []
64
27
 
65
- # Yields the root widget for manipulating the widget tree in a controller action.
66
- # Note that the passed block is executed once per session and not in every request.
28
+ helper ActionViewMethods
29
+ end
30
+
31
+ module ClassMethods
32
+ # Yields the root widget to setup your widgets for a controller. The block is executed in
33
+ # controller _instance_ context, so you may use instance methods and variables of the
34
+ # controller.
67
35
  #
68
36
  # Example:
69
- # def login
70
- # use_widgets do |root|
71
- # root << widget(:login_widget, 'login_box')
37
+ # class PostsController < ApplicationController
38
+ # has_widgets do |root|
39
+ # root << widget(:comments_widget, 'post-comments', :user => @current_user)
72
40
  # end
73
- #
74
- # @box = render_widget 'login_box'
75
- # end
76
- def use_widgets(&block)
77
- root = apotomo_root ### DISCUSS: let RequestProcessor initialize so we get flushed, eventually. maybe add a :before filter for that? or move #use_widgets to RequestProcessor?
78
-
79
- return if bound_use_widgets_blocks.include?(block)
80
-
81
- yield root
82
-
83
- bound_use_widgets_blocks << block # remember the proc.
84
- end
85
-
86
-
87
- def render_widget(widget, options={}, &block)
88
- apotomo_request_processor.render_widget_for(widget, options, &block)
89
- end
90
-
91
- def apotomo_freeze
92
- apotomo_request_processor.freeze!
41
+ def has_widgets(&block)
42
+ has_widgets_blocks << block
93
43
  end
44
+ end
94
45
 
95
- def render_event_response
96
- page_updates = apotomo_request_processor.process_for({:type => params[:type], :source => params[:source]})
97
-
98
- return render_iframe_updates(page_updates) if params[:apotomo_iframe]
99
-
100
- render :text => apotomo_request_processor.render_page_updates(page_updates), :content_type => Mime::JS
101
- end
102
-
103
- # Returns the url to trigger a +type+ event from +:source+, which is a non-optional parameter.
104
- # Additional +options+ will be appended to the query string.
105
- #
106
- # Note that this method will use the framework's internal routing if available (e.g. #url_for in Rails).
107
- #
108
- # Example:
109
- # url_for_event(:paginate, :source => 'mouse', :page => 2)
110
- # #=> http://apotomo.de/mouse/process_event_request?type=paginate&source=mouse&page=2
111
- def url_for_event(type, options)
112
- options.reverse_merge!(:type => type)
113
-
114
- apotomo_event_path(apotomo_request_processor.address_for(options))
115
- end
46
+ def apotomo_request_processor
47
+ return @apotomo_request_processor if @apotomo_request_processor
116
48
 
117
- protected
49
+ # happens once per request:
50
+ options = { :js_framework => Apotomo.js_framework || :prototype } # FIXME: remove :prototype
118
51
 
119
- def parent_controller
120
- self
121
- end
52
+ @apotomo_request_processor = Apotomo::RequestProcessor.new(self, options, self.class.has_widgets_blocks)
53
+ end
54
+
55
+ def apotomo_root
56
+ apotomo_request_processor.root
57
+ end
58
+
59
+ def render_widget(*args, &block)
60
+ apotomo_request_processor.render_widget_for(*args, &block)
61
+ end
62
+
63
+ def render_event_response
64
+ page_updates = apotomo_request_processor.process_for(params)
122
65
 
66
+ return render_iframe_updates(page_updates) if params[:apotomo_iframe]
123
67
 
68
+ render :text => page_updates.join("\n"), :content_type => Mime::JS
69
+ end
70
+
71
+ # Returns the url to trigger a +type+ event from +:source+, which is a non-optional parameter.
72
+ # Additional +options+ will be appended to the query string.
73
+ #
74
+ # Note that this method will use the framework's internal routing if available (e.g. #url_for in Rails).
75
+ #
76
+ # Example:
77
+ # url_for_event(:paginate, :source => 'mouse', :page => 2)
78
+ # #=> http://apotomo.de/mouse/process_event_request?type=paginate&source=mouse&page=2
79
+ def url_for_event(type, options)
80
+ options.reverse_merge!(:type => type)
81
+
82
+ apotomo_event_path(apotomo_request_processor.address_for(options))
83
+ end
84
+
85
+ protected
86
+
87
+ # TODO: remove me! only needed in widget_shortcuts.
88
+ def parent_controller
89
+ self
90
+ end
91
+
92
+
93
+ # Renders the page updates through an iframe. Copied from responds_to_parent,
94
+ # see http://github.com/markcatley/responds_to_parent .
95
+ def render_iframe_updates(page_updates)
96
+ escaped_script = Apotomo::JavascriptGenerator.escape(page_updates.join("\n"))
124
97
 
125
- # Renders the page updates through an iframe. Copied from responds_to_parent,
126
- # see http://github.com/markcatley/responds_to_parent .
127
- def render_iframe_updates(page_updates)
128
- script = apotomo_request_processor.render_page_updates(page_updates)
129
- escaped_script = Apotomo::JavascriptGenerator.escape(script)
130
-
131
- render :text => "<html><body><script type='text/javascript' charset='utf-8'>
98
+ render :text => "<html><body><script type='text/javascript' charset='utf-8'>
132
99
  var loc = document.location;
133
100
  with(window.parent) { setTimeout(function() { window.eval('#{escaped_script}'); window.loc && loc.replace('about:blank'); }, 1) }
134
101
  </script></body></html>", :content_type => 'text/html'
135
- end
136
-
137
- class ProcHash < Array
138
- def id_for_proc(proc)
139
- proc.to_s.split('@').last
140
- end
141
-
142
- def <<(proc)
143
- super(id_for_proc(proc))
144
- end
145
-
146
- def include?(proc)
147
- super(id_for_proc(proc))
148
- end
149
102
  end
150
103
  end
151
104
  end