netzke-core 0.6.6 → 0.6.7

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.
Files changed (58) hide show
  1. data/CHANGELOG.rdoc +7 -0
  2. data/app/controllers/netzke_controller.rb +47 -114
  3. data/javascripts/{core.js → base.js} +17 -93
  4. data/javascripts/core_extensions.js +42 -0
  5. data/javascripts/ext.js +1 -5
  6. data/lib/netzke/composition.rb +4 -26
  7. data/lib/netzke/core.rb +20 -0
  8. data/lib/netzke/core/dynamic_assets.rb +92 -0
  9. data/lib/netzke/core/version.rb +1 -1
  10. data/lib/netzke/javascript.rb +7 -2
  11. data/lib/netzke/railz/action_view_ext.rb +22 -23
  12. data/lib/netzke/railz/action_view_ext/ext.rb +25 -17
  13. data/lib/netzke/railz/action_view_ext/touch.rb +12 -10
  14. data/lib/netzke/railz/engine.rb +17 -1
  15. data/lib/netzke/services.rb +74 -40
  16. data/netzke-core.gemspec +39 -115
  17. data/test/rails_app/Gemfile +3 -2
  18. data/test/rails_app/Gemfile.lock +75 -74
  19. data/test/rails_app/app/components/server_caller.rb +0 -1
  20. data/test/rails_app/app/views/layouts/application.html.erb +1 -1
  21. data/test/rails_app/app/views/layouts/touch.html.erb +1 -1
  22. data/test/rails_app/config/application.rb +2 -0
  23. data/{features → test/rails_app/features}/actions.feature +0 -0
  24. data/{features → test/rails_app/features}/basic.feature +0 -0
  25. data/{features → test/rails_app/features}/client-server.feature +0 -2
  26. data/{features → test/rails_app/features}/complex_component.feature +0 -0
  27. data/{features → test/rails_app/features}/component.feature +0 -3
  28. data/{features → test/rails_app/features}/component_loader.feature +0 -2
  29. data/{features → test/rails_app/features}/composition.feature +0 -2
  30. data/{features → test/rails_app/features}/custom_css.feature +0 -0
  31. data/{features → test/rails_app/features}/ext.direct.feature +0 -0
  32. data/{features → test/rails_app/features}/file_inclusion.feature +0 -3
  33. data/{features → test/rails_app/features}/i18n.feature +0 -0
  34. data/{features → test/rails_app/features}/inheritance.feature +0 -0
  35. data/{features → test/rails_app/features}/js_include.feature +0 -0
  36. data/{features → test/rails_app/features}/nested_views.feature +0 -0
  37. data/{features → test/rails_app/features}/persistence.feature +0 -1
  38. data/{features → test/rails_app/features}/scopes.feature +0 -3
  39. data/{features → test/rails_app/features}/step_definitions/custom_css_steps.rb +0 -0
  40. data/{features → test/rails_app/features}/step_definitions/generic_steps.rb +0 -0
  41. data/{features → test/rails_app/features}/step_definitions/touch_steps.rb +0 -0
  42. data/{features → test/rails_app/features}/step_definitions/web_steps.rb +0 -0
  43. data/{features → test/rails_app/features}/support/env.rb +3 -7
  44. data/{features → test/rails_app/features}/support/paths.rb +0 -0
  45. data/{features → test/rails_app/features}/touch.feature +0 -0
  46. data/{spec → test/rails_app/spec}/component/actions_spec.rb +0 -0
  47. data/{spec → test/rails_app/spec}/component/base_spec.rb +0 -0
  48. data/{spec → test/rails_app/spec}/component/composition_spec.rb +0 -0
  49. data/{spec → test/rails_app/spec}/component/configuration_spec.rb +0 -0
  50. data/{spec → test/rails_app/spec}/component/javascript_spec.rb +0 -0
  51. data/{spec → test/rails_app/spec}/component/state_spec.rb +0 -0
  52. data/{spec → test/rails_app/spec}/core_ext_spec.rb +0 -2
  53. data/{spec → test/rails_app/spec}/spec.opt +0 -0
  54. data/{spec → test/rails_app/spec}/spec_helper.rb +1 -9
  55. metadata +40 -113
  56. data/autotest/discover.rb +0 -2
  57. data/test/rails_app/spec/controllers/touch_controller_spec.rb +0 -5
  58. data/test/rails_app/spec/helpers/touch_helper_spec.rb +0 -15
@@ -1,3 +1,10 @@
1
+ = v0.6.7 - 2011-08-16
2
+ * enhancements
3
+ * No more using +method_missing+ for invoking endpoints.
4
+ * New "cache" option for `netzke_init` which gets passed to `javascript_include_tag` (no support for css caching of this type yet)
5
+ * Netzke dynamic js and css-files such as ext.js, touch.css, now get generated at the application start, and put into "public/netzke". Solves a long standing problem with serving those files by HTTP servers in some cases. Enables caching naturally.
6
+ * Moved features and specs to test/rails_app (tests should be run from that folder from now on)
7
+
1
8
  = v0.6.6 - 2011-02-26
2
9
  * enhancements
3
10
  * Client-server communication is updated to use Ext.Direct (many thanks to @pschyska)
@@ -1,91 +1,25 @@
1
1
  class NetzkeController < ApplicationController
2
2
 
3
- def ext
4
- respond_to do |format|
5
- format.js {
6
- res = initial_dynamic_javascript << "\n"
7
-
8
- # Core JavaScript
9
- res << File.new(File.expand_path("../../../javascripts/core.js", __FILE__)).read
10
- # Ext-specific JavaScript
11
- res << File.new(File.expand_path("../../../javascripts/ext.js", __FILE__)).read
12
-
13
- # Pluggable JavaScript (used by other Netzke-powered gems like netzke-basepack)
14
- Netzke::Core.ext_javascripts.each do |path|
15
- f = File.new(path)
16
- res << f.read
17
- end
18
-
19
- render :text => defined?(::Rails) && ::Rails.env.production? ? res.strip_js_comments : res
20
- }
21
-
22
- format.css {
23
- res = File.new(File.expand_path("../../../stylesheets/core.css", __FILE__)).read
24
-
25
- # Pluggable stylesheets (may be used by other Netzke-powered gems like netzke-basepack)
26
- Netzke::Core.ext_stylesheets.each do |path|
27
- f = File.new(path)
28
- res << f.read
29
- end
30
-
31
- render :text => res
32
- }
33
- end
34
- end
35
-
36
- def touch
37
- respond_to do |format|
38
- format.js {
39
- res = initial_dynamic_javascript << "\n"
40
-
41
- # Core JavaScript
42
- res << File.new(File.expand_path("../../../javascripts/core.js", __FILE__)).read
43
- # Touch-specific JavaScript
44
- res << File.new(File.expand_path("../../../javascripts/touch.js", __FILE__)).read
45
-
46
- # Pluggable JavaScript (may be used by other Netzke-powered gems like netzke-basepack)
47
- Netzke::Core.touch_javascripts.each do |path|
48
- f = File.new(path)
49
- res << f.read
50
- end
51
-
52
- render :text => defined?(::Rails) && ::Rails.env.production? ? res.strip_js_comments : res
53
- }
54
-
55
- format.css {
56
- res = File.new(File.expand_path("../../../stylesheets/core.css", __FILE__)).read
57
-
58
- # Pluggable stylesheets (may be used by other Netzke-powered gems like netzke-basepack)
59
- Netzke::Core.touch_stylesheets.each do |path|
60
- f = File.new(path)
61
- res << f.read
62
- end
63
-
64
- render :text => res
65
- }
66
- end
67
- end
68
-
69
3
  # Action for Ext.Direct RPC calls
70
4
  def direct
71
5
  result=""
72
6
  error=false
73
7
  if params['_json'] # this is a batched request
74
8
  params['_json'].each do |batch|
75
- result+= result.blank? ? '[' : ', '
9
+ result += result.blank? ? '[' : ', '
76
10
  begin
77
- result+=invoke_endpoint batch[:act], batch[:method].underscore, batch[:data], batch[:tid]
11
+ result += invoke_endpoint(batch[:act], batch[:method].underscore, batch[:data].first, batch[:tid])
78
12
  rescue Exception => e
79
13
  Rails.logger.error "!!! Netzke: Error invoking endpoint: #{batch[:act]} #{batch[:method].underscore} #{batch[:data].inspect} #{batch[:tid]}\n"
80
14
  Rails.logger.error e.message
81
- Rails.logger.error e.backtrace
15
+ Rails.logger.error e.backtrace.join("\n")
82
16
  error=true
83
17
  break;
84
18
  end
85
19
  end
86
20
  result+=']'
87
21
  else # this is a single request
88
- result=invoke_endpoint params[:act], params[:method].underscore, params[:data], params[:tid]
22
+ result=invoke_endpoint params[:act], params[:method].underscore, params[:data].first, params[:tid]
89
23
  end
90
24
  render :text => result, :layout => false, :status => error ? 500 : 200
91
25
  end
@@ -95,60 +29,59 @@ class NetzkeController < ApplicationController
95
29
  endpoint_dispatch(params[:address])
96
30
  end
97
31
 
98
- protected
32
+ # Used in development mode for on-the-fly generation of public/netzke/ext.[js|css]
33
+ def ext
34
+ respond_to do |format|
35
+ format.js {
36
+ render :text => Netzke::Core::DynamicAssets.ext_js
37
+ }
99
38
 
100
- def invoke_endpoint component_name, action, data, tid
101
- data=data[0] || {} # we get data as an array, extract the single argument if available
39
+ format.css {
40
+ render :text => Netzke::Core::DynamicAssets.ext_css
41
+ }
42
+ end
43
+ end
102
44
 
103
- root_component_name, *sub_components = component_name.split('__')
104
- root_component = Netzke::Base.instance_by_config Netzke::Core.session[:netzke_components][root_component_name.to_sym]
105
- if sub_components.empty?
106
- # we need to dispatch to root component, send it _#{action}_ep_wrapper
107
- endpoint_action = "_#{action}_ep_wrapper"
108
- else
109
- # we need to dispatch to one or more sub_components, send subcomp__subsubcomp__endpoint to root component
110
- endpoint_action = sub_components.join('__')+'__'+action
111
- end
112
- # send back JSON as specified in Ext.direct spec
113
- # => type: rpc
114
- # => tid, action, method as in the request, so that the client can mark the transaction and won't retry it
115
- # => result: JavaScript code from he endpoint result which gets applied to the client-side component instance
116
- result = root_component.send(endpoint_action, data)
45
+ # Used in development mode for on-the-fly generation of public/netzke/touch.[js|css]
46
+ def touch
47
+ respond_to do |format|
48
+ format.js {
49
+ render :text => Netzke::Core::DynamicAssets.touch_js
50
+ }
51
+
52
+ format.css {
53
+ render :text => Netzke::Core::DynamicAssets.touch_css
54
+ }
55
+ end
56
+ end
117
57
 
118
- {:type => "rpc", :tid => tid, :action => component_name, :method => action, :result => result.present? && result.l || {}}.to_json
58
+ protected
59
+ def invoke_endpoint(endpoint_path, action, params, tid) #:nodoc:
60
+ component_name, *sub_components = endpoint_path.split('__')
61
+ component_instance = Netzke::Base.instance_by_config(Netzke::Core.session[:netzke_components][component_name.to_sym])
62
+
63
+ result = component_instance.invoke_endpoint((sub_components + [action]).join("__"), params)
64
+
65
+ {
66
+ :type => "rpc",
67
+ :tid => tid,
68
+ :action => component_name,
69
+ :method => action,
70
+ :result => result.present? && result.l || {}
71
+ }.to_json
119
72
  end
120
73
 
121
74
  # Main dispatcher of old-style (Sencha Touch) HTTP requests. The URL contains the name of the component,
122
75
  # as well as the method of this component to be called, according to the double underscore notation.
123
76
  # E.g.: some_grid__post_grid_data.
124
- def endpoint_dispatch(method_name)
125
- component_name, *action = method_name.to_s.split('__')
126
- component_name = component_name.to_sym
127
- action = !action.empty? && action.join("__").to_sym
128
-
129
- if action
130
- w_instance = Netzke::Base.instance_by_config(Netzke::Core.session[:netzke_components][component_name])
131
- # only component's actions starting with "endpoint_" are accessible from outside (security)
132
- endpoint_action = action.to_s.index('__') ? action : "_#{action}_ep_wrapper"
133
- render :text => w_instance.send(endpoint_action, params), :layout => false
134
- else
135
- super
136
- end
137
- end
138
-
139
- # Generates initial javascript code that is dependent on Rails environement
140
- def initial_dynamic_javascript
141
- res = []
142
- res << %(Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection)
143
- res << %{Ext.ns('Netzke');}
144
- res << %{Ext.ns('Netzke.core');}
145
- res << %{Netzke.RelativeUrlRoot = '#{ActionController::Base.config.relative_url_root}';}
146
- res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}/extjs';}
77
+ def endpoint_dispatch(endpoint_path)
78
+ component_name, *sub_components = endpoint_path.split('__')
79
+ component_instance = Netzke::Base.instance_by_config(Netzke::Core.session[:netzke_components][component_name.to_sym])
147
80
 
148
- # TODO: this will needs some DRYing
149
- res << %{Netzke.core.directMaxRetries = '#{Netzke::Core.js_direct_max_retries}';}
81
+ # We render text/plain, so that the browser never modifies our response
82
+ response.headers["Content-Type"] = "text/plain; charset=utf-8"
150
83
 
151
- res.join("\n")
84
+ render :text => component_instance.invoke_endpoint(sub_components.join("__"), params), :layout => false
152
85
  end
153
86
 
154
87
  end
@@ -9,11 +9,9 @@ At this time the following constants have been set by Rails:
9
9
  // Initial stuff
10
10
  Ext.BLANK_IMAGE_URL = Netzke.RelativeExtUrl + "/resources/images/default/s.gif";
11
11
  Ext.ns('Ext.netzke'); // namespace for extensions that depend on Ext
12
-
13
- Netzke.isLoading=function () {
14
- return Netzke.runningRequests != 0;
15
- }
16
- Netzke.runningRequests = 0;
12
+ Ext.ns('Netzke.page'); // namespace for all component instantces on the page
13
+ Ext.ns('Netzke.classes'); // namespace for all component classes
14
+ Ext.ns('Netzke.classes.Core'); // namespace for Core mixins
17
15
 
18
16
  Netzke.deprecationWarning = function(msg){
19
17
  if (typeof console == 'undefined') {
@@ -23,10 +21,15 @@ Netzke.deprecationWarning = function(msg){
23
21
  }
24
22
  };
25
23
 
26
- Ext.ns('Netzke.page'); // namespace for all component instantces on the page
27
- Ext.ns('Netzke.classes'); // namespace for all component classes
28
- Ext.ns('Netzke.classes.Core'); // namespace for all component classes
24
+ // Used in testing
25
+ Netzke.runningRequests = 0;
26
+ Netzke.isLoading=function () {
27
+ return Netzke.runningRequests != 0;
28
+ }
29
29
 
30
+ // Similar to Ext.apply, but can accept any number of parameters, e.g.
31
+ //
32
+ // Netzke.chainApply(targetObject, {...}, {...}, {...});
30
33
  Netzke.chainApply = function(){
31
34
  var res = {};
32
35
  Ext.each(arguments, function(o){
@@ -35,55 +38,18 @@ Netzke.chainApply = function(){
35
38
  return res;
36
39
  };
37
40
 
38
- // Some Ruby-ish String extensions
39
- // from http://code.google.com/p/inflection-js/
40
- String.prototype.camelize=function(lowFirstLetter)
41
- {
42
- var str=this; //.toLowerCase();
43
- var str_path=str.split('/');
44
- for(var i=0;i<str_path.length;i++)
45
- {
46
- var str_arr=str_path[i].split('_');
47
- var initX=((lowFirstLetter&&i+1==str_path.length)?(1):(0));
48
- for(var x=initX;x<str_arr.length;x++)
49
- str_arr[x]=str_arr[x].charAt(0).toUpperCase()+str_arr[x].substring(1);
50
- str_path[i]=str_arr.join('');
51
- }
52
- str=str_path.join('::');
53
- return str;
54
- };
55
-
56
- String.prototype.capitalize=function()
57
- {
58
- var str=this.toLowerCase();
59
- str=str.substring(0,1).toUpperCase()+str.substring(1);
60
- return str;
61
- };
62
-
63
- String.prototype.humanize=function(lowFirstLetter)
64
- {
65
- var str=this.toLowerCase();
66
- str=str.replace(new RegExp('_id','g'),'');
67
- str=str.replace(new RegExp('_','g'),' ');
68
- if(!lowFirstLetter)str=str.capitalize();
69
- return str;
70
- };
41
+ /* Similar to Rails' alias_method_chain. Usefull when using mixins. E.g.:
71
42
 
72
- // This one is borrowed from prototype.js
73
- String.prototype.underscore = function() {
74
- return this.replace(/::/g, '/')
75
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
76
- .replace(/([a-z\d])([A-Z])/g, '$1_$2')
77
- .replace(/-/g, '_')
78
- .toLowerCase();
79
- };
43
+ Netzke.aliasMethodChain(this, "initComponent", "netzke")
80
44
 
81
- // Usefull when using mixins
45
+ will result in 2 new methods on this.initComponentWithNetzke and this.initComponentWithoutNetzke
46
+ */
82
47
  Netzke.aliasMethodChain = function(klass, method, feature) {
83
48
  klass[method + "Without" + feature.capitalize()] = klass[method];
84
49
  klass[method] = klass[method + "With" + feature.capitalize()];
85
50
  };
86
51
 
52
+ // xtypes of cached Netzke classes
87
53
  Netzke.cache = [];
88
54
 
89
55
  // Registering a Netzke component
@@ -99,14 +65,6 @@ Netzke.classes.Core.Mixin = {};
99
65
  // Properties/methods common to all Netzke component classes
100
66
  Netzke.componentMixin = Ext.applyIf(Netzke.classes.Core.Mixin, {
101
67
  isNetzke: true, // to distinguish Netzke components from regular Ext components
102
- latestResult: {}, // latest result returned from the server via an API call
103
- /*
104
- Overriding the constructor to only apply an "alias method chain" to initComponent
105
- */
106
- // constructor: function(config){
107
- // Netzke.aliasMethodChain(this, "initComponent", "netzke");
108
- // receiver.superclass.constructor.call(this, config);
109
- // },
110
68
 
111
69
  /*
112
70
  Detects component placeholders in the passed object (typically, "items"),
@@ -149,7 +107,7 @@ Netzke.componentMixin = Ext.applyIf(Netzke.classes.Core.Mixin, {
149
107
  /*
150
108
  Gets id in the context of provided parent.
151
109
  For example, the components "properties", being a child of "books" has global id "books__properties",
152
- which *is* its widegt's real id. This methods, with the instance of "books" passed as parameter,
110
+ which *is* its component's real id. This methods, with the instance of "books" passed as parameter,
153
111
  returns "properties".
154
112
  */
155
113
  localId : function(parent){
@@ -296,37 +254,3 @@ Ext.override(Ext.Container, {
296
254
  this.remove(this.getNetzkeComponent());
297
255
  }
298
256
  });
299
-
300
-
301
- // Feedback Ghost
302
- Netzke.FeedbackGhost = function(){};
303
- Ext.apply(Netzke.FeedbackGhost.prototype, {
304
- showFeedback: function(msg){
305
- var createBox = function(s, l){
306
- return ['<div class="msg">',
307
- '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
308
- '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc">', s, '</div></div></div>',
309
- '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
310
- '</div>'].join('');
311
- }
312
-
313
- var showBox = function(msg, lvl){
314
- if (!lvl) {lvl = 'notice'};
315
-
316
- var msgCt = Ext.get('netzke-feedback') || Ext.DomHelper.insertFirst(document.body, {id: 'netzke-feedback', 'class':'netzke-feedback'}, true);
317
-
318
- var m = Ext.DomHelper.append(msgCt, {html:createBox(msg,lvl)}, true);
319
- m.slideIn('t').pause(2).ghost("b", {remove:true});
320
- }
321
-
322
- if (typeof msg != 'string') {
323
- var compoundMsg = "";
324
- Ext.each(msg, function(m){
325
- compoundMsg += m.msg + '<br>';
326
- });
327
- if (compoundMsg != "") showBox(compoundMsg, null); // the second parameter will be level
328
- } else {
329
- showBox(msg);
330
- }
331
- }
332
- });
@@ -0,0 +1,42 @@
1
+ // Some Ruby-ish String extensions
2
+ // from http://code.google.com/p/inflection-js/
3
+ if (!String.prototype.camelize) String.prototype.camelize = function(lowFirstLetter)
4
+ {
5
+ var str=this; //.toLowerCase();
6
+ var str_path=str.split('/');
7
+ for(var i=0;i<str_path.length;i++)
8
+ {
9
+ var str_arr=str_path[i].split('_');
10
+ var initX=((lowFirstLetter&&i+1==str_path.length)?(1):(0));
11
+ for(var x=initX;x<str_arr.length;x++)
12
+ str_arr[x]=str_arr[x].charAt(0).toUpperCase()+str_arr[x].substring(1);
13
+ str_path[i]=str_arr.join('');
14
+ }
15
+ str=str_path.join('::');
16
+ return str;
17
+ };
18
+
19
+ if (!String.prototype.capitalize) String.prototype.capitalize = function()
20
+ {
21
+ var str=this.toLowerCase();
22
+ str=str.substring(0,1).toUpperCase()+str.substring(1);
23
+ return str;
24
+ };
25
+
26
+ if (!String.prototype.humanize) String.prototype.humanize = function(lowFirstLetter)
27
+ {
28
+ var str=this.toLowerCase();
29
+ str=str.replace(new RegExp('_id','g'),'');
30
+ str=str.replace(new RegExp('_','g'),' ');
31
+ if(!lowFirstLetter)str=str.capitalize();
32
+ return str;
33
+ };
34
+
35
+ // This one is borrowed from prototype.js
36
+ if (!String.prototype.underscore) String.prototype.underscore = function() {
37
+ return this.replace(/::/g, '/')
38
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
39
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
40
+ .replace(/-/g, '_')
41
+ .toLowerCase();
42
+ };
@@ -15,7 +15,7 @@ Ext.state.Provider.prototype.set = function(){};
15
15
  }
16
16
  })();
17
17
 
18
- Netzke.classes.NetzkeRemotingProvider=Ext.extend(Ext.direct.RemotingProvider,{
18
+ Netzke.classes.NetzkeRemotingProvider = Ext.extend(Ext.direct.RemotingProvider, {
19
19
  getCallData: function(t){
20
20
  return {
21
21
  act: t.action, // rails doesn't really support having a parameter named "action"
@@ -115,9 +115,6 @@ Ext.apply(Netzke.classes.Core.Mixin, {
115
115
  }
116
116
  }
117
117
 
118
- // From everywhere accessible FeedbackGhost
119
- this.feedbackGhost = new Netzke.FeedbackGhost();
120
-
121
118
  // Call the original initComponent
122
119
  this.initComponentWithoutNetzke();
123
120
  },
@@ -133,7 +130,6 @@ Ext.apply(Netzke.classes.Core.Mixin, {
133
130
 
134
131
  Ext.each(endpoints, function(intp){
135
132
  directActions.push({"name":intp.camelize(true), "len":1});
136
- //this[intp.camelize(true)] = function(args, callback, scope){ this.callServer(intp, args, callback, scope); }
137
133
  this[intp.camelize(true)] = function(arg, callback, scope) {
138
134
  Netzke.runningRequests++;
139
135
  scope=scope || that;
@@ -1,7 +1,9 @@
1
1
  # require 'active_support/core_ext/class/inheritable_attributes'
2
2
 
3
3
  module Netzke
4
- # You can define a nested components by calling the class method +component+:
4
+ # This module takes care of components composition.
5
+ #
6
+ # You can define a nested component by calling the +component+ class method:
5
7
  #
6
8
  # component :users, :data_class => "GridPanel", :model => "User"
7
9
  #
@@ -198,30 +200,6 @@ module Netzke
198
200
  end
199
201
  end
200
202
 
201
- # Method dispatcher - instantiates an component and calls the method on it
202
- # E.g.:
203
- # users__center__get_data
204
- # instantiates component "users", and calls "center__get_data" on it
205
- # books__move_column
206
- # instantiates component "books", and calls "endpoint_move_column" on it
207
- def method_missing(method_name, params = {})
208
- component, *action = method_name.to_s.split('__')
209
- component = component.to_sym
210
- action = !action.empty? && action.join("__").to_sym
211
-
212
- if action
213
- if components[component]
214
- # only actions starting with "endpoint_" are accessible
215
- endpoint_action = action.to_s.index('__') ? action : "_#{action}_ep_wrapper"
216
- component_instance(component).send(endpoint_action, params)
217
- else
218
- component_missing(component)
219
- end
220
- else
221
- super
222
- end
223
- end
224
-
225
203
  protected
226
204
 
227
205
  def normalize_components(items) #:nodoc:
@@ -250,4 +228,4 @@ module Netzke
250
228
  end
251
229
 
252
230
  end
253
- end
231
+ end