netzke-core 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
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