netzke-core 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +9 -6
- data/README.rdoc +14 -15
- data/Rakefile +20 -15
- data/TODO +1 -1
- data/app/controllers/netzke_controller.rb +9 -9
- data/app/models/netzke_preference.rb +27 -27
- data/features/actions.feature +1 -1
- data/features/basic.feature +1 -1
- data/features/client-server.feature +1 -1
- data/features/component_loader.feature +6 -7
- data/features/composition.feature +5 -6
- data/features/custom_css.feature +1 -1
- data/features/inheritance.feature +0 -1
- data/features/persistence.feature +3 -3
- data/features/scopes.feature +3 -3
- data/features/step_definitions/web_steps.rb +5 -5
- data/features/support/env.rb +6 -6
- data/generators/netzke_core/netzke_core_generator.rb +2 -2
- data/javascripts/core.js +43 -43
- data/lib/generators/migration_helper.rb +6 -6
- data/lib/generators/netzke/USAGE +2 -3
- data/lib/generators/netzke/core_generator.rb +7 -7
- data/lib/netzke/actions.rb +18 -18
- data/lib/netzke/base.rb +72 -85
- data/lib/netzke/composition.rb +30 -30
- data/lib/netzke/configuration.rb +15 -15
- data/lib/netzke/core/masquerading.rb +3 -3
- data/lib/netzke/core/session.rb +1 -1
- data/lib/netzke/core/version.rb +1 -1
- data/lib/netzke/core.rb +9 -9
- data/lib/netzke/core_ext/array.rb +5 -5
- data/lib/netzke/core_ext/hash.rb +7 -7
- data/lib/netzke/core_ext/string.rb +4 -4
- data/lib/netzke/core_ext/symbol.rb +3 -3
- data/lib/netzke/embedding.rb +2 -2
- data/lib/netzke/ext_component.rb +4 -4
- data/lib/netzke/javascript.rb +36 -25
- data/lib/netzke/persistence.rb +16 -16
- data/lib/netzke/rails/action_view_ext.rb +20 -20
- data/lib/netzke/rails/controller_extensions.rb +1 -1
- data/lib/netzke/rails/routes.rb +1 -1
- data/lib/netzke/services.rb +12 -12
- data/lib/netzke/session.rb +4 -4
- data/lib/netzke/stylesheets.rb +8 -8
- data/lib/netzke-core.rb +2 -2
- data/netzke-core.gemspec +4 -5
- data/spec/component/actions_spec.rb +18 -18
- data/spec/component/base_spec.rb +6 -6
- data/spec/component/composition_spec.rb +12 -12
- data/spec/component/javascript_spec.rb +2 -2
- data/spec/core_ext_spec.rb +3 -3
- data/templates/core/create_netzke_preferences.rb +1 -1
- data/test/rails_app/app/components/component_loader.rb +8 -8
- data/test/rails_app/app/components/component_with_actions.rb +9 -9
- data/test/rails_app/app/components/component_with_custom_css.rb +2 -2
- data/test/rails_app/app/components/component_with_included_js.rb +5 -5
- data/test/rails_app/app/components/component_with_session_persistence.rb +3 -3
- data/test/rails_app/app/components/deprecated/server_caller.rb +2 -2
- data/test/rails_app/app/components/extended_component_with_actions.rb +1 -1
- data/test/rails_app/app/components/extended_server_caller.rb +3 -3
- data/test/rails_app/app/components/kinda_complex_component/basic_stuff.rb +8 -8
- data/test/rails_app/app/components/kinda_complex_component/extra_stuff.rb +2 -2
- data/test/rails_app/app/components/loader_of_component_with_custom_css.rb +2 -2
- data/test/rails_app/app/components/server_caller.rb +3 -3
- data/test/rails_app/app/components/simple_component.rb +1 -1
- data/test/rails_app/app/components/simple_tab_panel.rb +2 -2
- data/test/rails_app/app/components/some_composite.rb +16 -16
- data/test/rails_app/config/routes.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/test/unit/core_ext_test.rb +13 -13
- data/test/unit/netzke_core_test.rb +20 -20
- data/test/unit/netzke_preference_test.rb +12 -12
- metadata +6 -6
data/javascripts/core.js
CHANGED
@@ -94,7 +94,7 @@ Netzke.componentMixin = function(receiver){
|
|
94
94
|
border: false,
|
95
95
|
isNetzke: true, // to distinguish Netzke components from regular Ext components
|
96
96
|
latestResult: {}, // latest result returned from the server via an API call
|
97
|
-
|
97
|
+
|
98
98
|
/*
|
99
99
|
Overriding the constructor to only apply an "alias method chain" to initComponent
|
100
100
|
*/
|
@@ -102,22 +102,22 @@ Netzke.componentMixin = function(receiver){
|
|
102
102
|
Netzke.aliasMethodChain(this, "initComponent", "netzke");
|
103
103
|
receiver.superclass.constructor.call(this, config);
|
104
104
|
},
|
105
|
-
|
105
|
+
|
106
106
|
/* initComponent common for all Netzke components */
|
107
107
|
initComponentWithNetzke : function(){
|
108
108
|
this.normalizeActions();
|
109
|
-
|
109
|
+
|
110
110
|
this.detectActions(this);
|
111
|
-
|
111
|
+
|
112
112
|
this.detectComponents(this.items);
|
113
|
-
|
113
|
+
|
114
114
|
this.normalizeTools();
|
115
|
-
|
115
|
+
|
116
116
|
this.processEndpoints();
|
117
|
-
|
117
|
+
|
118
118
|
// This is where the references to different callback functions will be stored
|
119
119
|
this.callbackHash = {};
|
120
|
-
|
120
|
+
|
121
121
|
// This is where we store the information about components that are currently being loaded with this.loadComponent()
|
122
122
|
this.componentsBeingLoaded = {};
|
123
123
|
|
@@ -141,8 +141,8 @@ Netzke.componentMixin = function(receiver){
|
|
141
141
|
this.initComponentWithoutNetzke();
|
142
142
|
},
|
143
143
|
|
144
|
-
/*
|
145
|
-
Dynamically creates methods for api points, so that we could later call them like: this.myEndpointMethod()
|
144
|
+
/*
|
145
|
+
Dynamically creates methods for api points, so that we could later call them like: this.myEndpointMethod()
|
146
146
|
*/
|
147
147
|
processEndpoints : function(){
|
148
148
|
var endpoints = this.endpoints || [];
|
@@ -158,7 +158,7 @@ Netzke.componentMixin = function(receiver){
|
|
158
158
|
Ext.each(this.tools, function(tool){
|
159
159
|
// Create an event for each action (so that higher-level components could interfere)
|
160
160
|
this.addEvents(tool.id+'click');
|
161
|
-
|
161
|
+
|
162
162
|
var handler = this.toolActionHandler.createDelegate(this, [tool]);
|
163
163
|
normTools.push({id : tool, handler : handler, scope : this});
|
164
164
|
}, this);
|
@@ -166,8 +166,8 @@ Netzke.componentMixin = function(receiver){
|
|
166
166
|
}
|
167
167
|
},
|
168
168
|
|
169
|
-
/*
|
170
|
-
Replaces actions configs with Ext.Action instances, assigning default handler to them
|
169
|
+
/*
|
170
|
+
Replaces actions configs with Ext.Action instances, assigning default handler to them
|
171
171
|
*/
|
172
172
|
normalizeActions : function(){
|
173
173
|
var normActions = {};
|
@@ -222,7 +222,7 @@ Netzke.componentMixin = function(receiver){
|
|
222
222
|
},
|
223
223
|
|
224
224
|
/*
|
225
|
-
Detects component placeholders in the passed object (typically, "items"),
|
225
|
+
Detects component placeholders in the passed object (typically, "items"),
|
226
226
|
and merges them with the corresponding config from this.components.
|
227
227
|
This way it becomes ready to be instantiated properly by Ext.
|
228
228
|
*/
|
@@ -252,20 +252,20 @@ Netzke.componentMixin = function(receiver){
|
|
252
252
|
params.name = params.id;
|
253
253
|
Netzke.deprecationWarning("Using 'id' in loadComponent is deprecated. Use 'name' instead.");
|
254
254
|
}
|
255
|
-
|
255
|
+
|
256
256
|
params.name = params.name.underscore();
|
257
257
|
|
258
258
|
// params that will be provided for the server API call (deliver_component); all what's passed in params.params is merged in. This way we exclude from sending along such things as :scope, :callback, etc.
|
259
259
|
var serverParams = params.params || {};
|
260
260
|
serverParams.name = params.name;
|
261
|
-
|
261
|
+
|
262
262
|
// Build the list of already loaded ("cached") classes
|
263
263
|
serverParams.cache = [];
|
264
|
-
|
264
|
+
|
265
265
|
for (var klass in Netzke.classes) {
|
266
266
|
serverParams.cache.push(klass);
|
267
267
|
}
|
268
|
-
|
268
|
+
|
269
269
|
serverParams.cache = serverParams.cache.join();
|
270
270
|
|
271
271
|
var storedConfig = this.componentsBeingLoaded[params.name] = {};
|
@@ -296,9 +296,9 @@ Netzke.componentMixin = function(receiver){
|
|
296
296
|
if (this.fireEvent('componentload'), config) {
|
297
297
|
var storedConfig = this.componentsBeingLoaded[config.name] || {};
|
298
298
|
delete this.componentsBeingLoaded[config.name];
|
299
|
-
|
299
|
+
|
300
300
|
var componentInstance;
|
301
|
-
|
301
|
+
|
302
302
|
if (storedConfig.container) {
|
303
303
|
var container = Ext.getCmp(storedConfig.container);
|
304
304
|
componentInstance = container.instantiateChild(config);
|
@@ -352,9 +352,9 @@ Netzke.componentMixin = function(receiver){
|
|
352
352
|
},
|
353
353
|
|
354
354
|
/*
|
355
|
-
Gets id in the context of provided parent.
|
356
|
-
For example, the components "properties", being a child of "books" has global id "books__properties",
|
357
|
-
which *is* its widegt's real id. This methods, with the instance of "books" passed as parameter,
|
355
|
+
Gets id in the context of provided parent.
|
356
|
+
For example, the components "properties", being a child of "books" has global id "books__properties",
|
357
|
+
which *is* its widegt's real id. This methods, with the instance of "books" passed as parameter,
|
358
358
|
returns "properties".
|
359
359
|
*/
|
360
360
|
localId : function(parent){
|
@@ -386,18 +386,18 @@ Netzke.componentMixin = function(receiver){
|
|
386
386
|
},
|
387
387
|
|
388
388
|
/*
|
389
|
-
Executes a bunch of methods. This method is called almost every time a communication to the server takes place.
|
389
|
+
Executes a bunch of methods. This method is called almost every time a communication to the server takes place.
|
390
390
|
Thus the server side of a component can provide any set of commands to its client side.
|
391
391
|
Args:
|
392
|
-
- instructions: array of methods, in the order of execution.
|
392
|
+
- instructions: array of methods, in the order of execution.
|
393
393
|
Each item is an object in one of the following 2 formats:
|
394
394
|
1) {method1:args1, method2:args2}, where methodN is a name of a public method of this component; these methods are called in no particular order
|
395
395
|
2) {component:component_id, methods:arrayOfMethods}, used for recursive call to bulkExecute on some child component
|
396
396
|
|
397
|
-
Example:
|
397
|
+
Example:
|
398
398
|
- [
|
399
399
|
// the same as this.feedback("Your order is accepted")
|
400
|
-
{feedback: "You order is accepted"},
|
400
|
+
{feedback: "You order is accepted"},
|
401
401
|
|
402
402
|
// the same as this.getChildComponent('users').bulkExecute([{setTitle:'Suprise!'}, {setDisabled:true}])
|
403
403
|
{component:'users', methods:[{setTitle:'Suprise!'}, {setDisabled:true}] },
|
@@ -451,12 +451,12 @@ Netzke.componentMixin = function(receiver){
|
|
451
451
|
// var customHandler = action.initialConfig.customHandler;
|
452
452
|
// var methodName = (customHandler && customHandler.camelize(true)) || "on" + actionName.camelize();
|
453
453
|
// if (!this[methodName]) {throw "Netzke: action handler '" + methodName + "' is undefined"}
|
454
|
-
//
|
454
|
+
//
|
455
455
|
// // call the handler passing it the triggering component
|
456
456
|
// this[methodName](comp);
|
457
457
|
// }
|
458
458
|
// },
|
459
|
-
//
|
459
|
+
//
|
460
460
|
// // Common handler for tools
|
461
461
|
// toolActionHandler : function(tool){
|
462
462
|
// // If firing corresponding event doesn't return false, call the handler
|
@@ -472,7 +472,7 @@ Netzke.componentMixin = function(receiver){
|
|
472
472
|
Netzke.deprecationWarning("buildApiUrl() is deprecated. Use endpointUrl() first");
|
473
473
|
return this.endpointUrl(endpoint);
|
474
474
|
},
|
475
|
-
|
475
|
+
|
476
476
|
endpointUrl: function(endpoint){
|
477
477
|
return Netzke.RelativeUrlRoot + "/netzke/" + this.id + "__" + endpoint;
|
478
478
|
},
|
@@ -489,7 +489,7 @@ Netzke.componentMixin = function(receiver){
|
|
489
489
|
this.bulkExecute(Ext.decode(response.responseText));
|
490
490
|
|
491
491
|
// provide callback if needed
|
492
|
-
if (typeof callback == 'function') {
|
492
|
+
if (typeof callback == 'function') {
|
493
493
|
if (!scope) scope = this;
|
494
494
|
callback.apply(scope, [this.latestResult]);
|
495
495
|
}
|
@@ -551,23 +551,23 @@ Netzke.componentMixin = function(receiver){
|
|
551
551
|
// if (!owner) {
|
552
552
|
// owner = this;
|
553
553
|
// }
|
554
|
-
//
|
555
|
-
// if (!!this.hostMenu) {
|
556
|
-
// this.hostMenu(menu, owner);
|
554
|
+
//
|
555
|
+
// if (!!this.hostMenu) {
|
556
|
+
// this.hostMenu(menu, owner);
|
557
557
|
// } else {
|
558
558
|
// if (this.ownerComponent) {
|
559
559
|
// this.ownerComponent.addMenu(menu, owner);
|
560
560
|
// }
|
561
561
|
// }
|
562
562
|
// },
|
563
|
-
//
|
563
|
+
//
|
564
564
|
// cleanUpMenu : function(owner){
|
565
565
|
// if (!owner) {
|
566
566
|
// owner = this;
|
567
567
|
// }
|
568
|
-
//
|
569
|
-
// if (!!this.unhostMenu) {
|
570
|
-
// this.unhostMenu(owner);
|
568
|
+
//
|
569
|
+
// if (!!this.unhostMenu) {
|
570
|
+
// this.unhostMenu(owner);
|
571
571
|
// } else {
|
572
572
|
// if (this.ownerComponent) {
|
573
573
|
// this.ownerComponent.cleanUpMenu(owner);
|
@@ -599,7 +599,7 @@ Netzke.componentMixin = function(receiver){
|
|
599
599
|
this[methodName]();
|
600
600
|
}
|
601
601
|
},
|
602
|
-
|
602
|
+
|
603
603
|
onComponentLoad:Ext.emptyFn // gets overridden
|
604
604
|
}
|
605
605
|
}
|
@@ -614,14 +614,14 @@ Ext.override(Ext.Container, {
|
|
614
614
|
if (instance.isXType("window")) {
|
615
615
|
instance.show();
|
616
616
|
} else {
|
617
|
-
this.remove(this.getNetzkeComponent()); // first delete previous component
|
617
|
+
this.remove(this.getNetzkeComponent()); // first delete previous component
|
618
618
|
this.add(instance);
|
619
619
|
this.doLayout();
|
620
620
|
}
|
621
621
|
return instance;
|
622
622
|
},
|
623
623
|
|
624
|
-
/**
|
624
|
+
/**
|
625
625
|
Get Netzke component that this Ext.Container is part of (*not* the parent component, for which call getParent)
|
626
626
|
It searches up the Ext.Container hierarchy until it finds a Container that has isNetzke property set to true
|
627
627
|
(or until it reaches the top).
|
@@ -637,12 +637,12 @@ Ext.override(Ext.Container, {
|
|
637
637
|
}
|
638
638
|
}
|
639
639
|
},
|
640
|
-
|
640
|
+
|
641
641
|
// Get the component that we are hosting
|
642
642
|
getNetzkeComponent: function(){
|
643
643
|
return this.items ? this.items.first() : null; // need this check in case when the container is not yet rendered, like an inactive tab in the TabPanel
|
644
644
|
},
|
645
|
-
|
645
|
+
|
646
646
|
// Remove the child
|
647
647
|
removeChild : function(){
|
648
648
|
this.remove(this.getNetzkeComponent());
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module MigrationHelper
|
2
|
-
include Rails::Generators::Migration
|
3
|
-
|
4
|
-
module ClassMethods
|
2
|
+
include Rails::Generators::Migration
|
3
|
+
|
4
|
+
module ClassMethods
|
5
5
|
def migration_lookup_at(dirname) #:nodoc:
|
6
6
|
Dir.glob("#{dirname}/[0-9]*_*.rb")
|
7
7
|
end
|
@@ -23,10 +23,10 @@ module MigrationHelper
|
|
23
23
|
rescue
|
24
24
|
raise NotImplementedError
|
25
25
|
end
|
26
|
-
end
|
26
|
+
end
|
27
27
|
|
28
|
-
def self.included(base) #:nodoc:
|
28
|
+
def self.included(base) #:nodoc:
|
29
29
|
puts "MigrationHelper included by #{base}"
|
30
|
-
base.extend ClassMethods
|
30
|
+
base.extend ClassMethods
|
31
31
|
end
|
32
32
|
end
|
data/lib/generators/netzke/USAGE
CHANGED
@@ -3,22 +3,22 @@ require 'rails/generators/migration'
|
|
3
3
|
require 'generators/migration_helper'
|
4
4
|
|
5
5
|
module Netzke
|
6
|
-
module Generators
|
6
|
+
module Generators
|
7
7
|
class CoreGenerator < Rails::Generators::Base
|
8
8
|
include ::MigrationHelper
|
9
|
-
|
9
|
+
|
10
10
|
def execute
|
11
11
|
migration_template 'create_netzke_preferences.rb', 'db/migrate/create_netzke_preferences.rb'
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def self.source_root
|
15
15
|
File.join(gem_root, 'templates', 'core')
|
16
|
-
end
|
17
|
-
|
16
|
+
end
|
17
|
+
|
18
18
|
def self.gem_root
|
19
19
|
File.expand_path("../../../../", __FILE__)
|
20
|
-
end
|
21
|
-
|
20
|
+
end
|
21
|
+
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/lib/netzke/actions.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
module Netzke
|
2
2
|
# Netzke component allows specifying Ext actions.
|
3
|
-
# An action can be defined in 2 different ways, both of which result in a method definition like this
|
3
|
+
# An action can be defined in 2 different ways, both of which result in a method definition like this
|
4
4
|
# def _<some_action>_action
|
5
5
|
# ...
|
6
6
|
# end
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# The 2 ways to define an action are:
|
9
9
|
# * as a hash:
|
10
|
-
# action :bug_server, :text => "Call server", :icon => "/images/icons/phone.png"
|
11
|
-
#
|
10
|
+
# action :bug_server, :text => "Call server", :icon => "/images/icons/phone.png"
|
11
|
+
#
|
12
12
|
# * as a block:
|
13
13
|
# action :bug_server do
|
14
14
|
# {:text => config[:text], :disabled => true}
|
15
15
|
# end
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# The block can optionally receive the configuration of an action being overridden:
|
18
18
|
# action :bug_server do |orig|
|
19
19
|
# {:text => config[:text] + orig[:text], :disabled => orig[:disabled]}
|
@@ -23,16 +23,16 @@ module Netzke
|
|
23
23
|
|
24
24
|
ACTION_METHOD_NAME = "%s_action"
|
25
25
|
ACTION_METHOD_REGEXP = /^(.+)_action$/
|
26
|
-
|
26
|
+
|
27
27
|
included do
|
28
28
|
alias_method_chain :js_config, :actions
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
module ClassMethods
|
32
32
|
def action(name, config = {}, &block)
|
33
33
|
config[:name] = name.to_s
|
34
34
|
method_name = ACTION_METHOD_NAME % name
|
35
|
-
|
35
|
+
|
36
36
|
if block_given?
|
37
37
|
define_method(method_name, &block)
|
38
38
|
else
|
@@ -48,7 +48,7 @@ module Netzke
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
# Actions to be used in the config
|
53
53
|
def actions
|
54
54
|
# Call all the action related methods to collect the actions
|
@@ -61,29 +61,29 @@ module Netzke
|
|
61
61
|
def js_config_with_actions #:nodoc
|
62
62
|
actions.empty? ? js_config_without_actions : js_config_without_actions.merge(:actions => actions)
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
private
|
66
66
|
def normalize_action_config(config)
|
67
67
|
if config[:icon].is_a?(Symbol)
|
68
68
|
config[:icon] = Netzke::Core.with_icons ? Netzke::Core.icons_uri + "/" + config[:icon].to_s + ".png" : nil
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
config[:text] ||= config[:name].humanize
|
72
|
-
|
72
|
+
|
73
73
|
config
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
def auto_collect_actions_from_config_and_js_properties
|
77
77
|
# res = extract_actions(js_properties)
|
78
78
|
# puts %Q(!!! res: #{res.inspect}\n)
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
# def extract_actions(hsh)
|
82
|
-
# hsh.each_pair.inject({}) do |r,(k,v)|
|
82
|
+
# hsh.each_pair.inject({}) do |r,(k,v)|
|
83
83
|
# v.is_a?(Array) ? r.merge(extract_actions_from_array(v)) : r
|
84
84
|
# end
|
85
85
|
# end
|
86
|
-
#
|
86
|
+
#
|
87
87
|
# def extract_actions_from_array(arry)
|
88
88
|
# arry.inject({}) do |r, el|
|
89
89
|
# if el.is_a?(Hash)
|
@@ -93,10 +93,10 @@ module Netzke
|
|
93
93
|
# end
|
94
94
|
# end
|
95
95
|
# end
|
96
|
-
#
|
96
|
+
#
|
97
97
|
# def default_action_config(action_name)
|
98
98
|
# {:text => action_name.to_s.humanize}
|
99
99
|
# end
|
100
|
-
|
100
|
+
|
101
101
|
end
|
102
102
|
end
|
data/lib/netzke/base.rb
CHANGED
@@ -11,43 +11,22 @@ require 'netzke/actions'
|
|
11
11
|
require 'netzke/session'
|
12
12
|
|
13
13
|
module Netzke
|
14
|
-
#
|
15
|
-
# Base class for every Netzke component
|
14
|
+
# The base for every Netzke component
|
16
15
|
#
|
17
|
-
#
|
16
|
+
# == Class-level configuration
|
17
|
+
# You can configure any component's class as follows:
|
18
|
+
# # e.g. in the initializers/netzke.rb
|
19
|
+
# MyComponent.setup do |config|
|
20
|
+
# config.default_instance_config = { :some_option => true }
|
21
|
+
# end
|
18
22
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# == Configuration
|
22
|
-
# * <tt>:class_name</tt> - name of the component class in the scope of the Netzke module, e.g. "FormPanel".
|
23
|
-
# When a component is defined in the controller and this option is omitted, component class is deferred from the component's
|
24
|
-
# name. E.g.:
|
25
|
-
#
|
26
|
-
# netzke :grid_panel, :model => "User"
|
27
|
-
#
|
28
|
-
# In this case <tt>:class_name</tt> is assumed to be "GridPanel"
|
29
|
-
#
|
30
|
-
# * <tt>:persistent_config</tt> - if set to <tt>true</tt>, the component will use persistent storage to store its state;
|
31
|
-
# for instance, Netzke::GridPanel stores there its columns state (width, visibility, order, headers, etc).
|
32
|
-
# A component may or may not provide interface to its persistent settings. GridPanel and FormPanel from netzke-basepack
|
33
|
-
# are examples of components that by default do.
|
34
|
-
#
|
35
|
-
# Examples of configuration:
|
36
|
-
#
|
37
|
-
# netzke :books,
|
38
|
-
# :class_name => "GridPanel",
|
39
|
-
# :model => "Book", # GridPanel specific option
|
40
|
-
# :persistent_config => false, # don't use persistent config for this instance
|
41
|
-
# :icon_cls => 'icon-grid',
|
42
|
-
# :title => "My books"
|
43
|
-
#
|
44
|
-
# netzke :form_panel,
|
45
|
-
# :model => "User" # FormPanel specific option
|
23
|
+
# Netzke::Base provides the following class-level configuration options:
|
24
|
+
# * default_instance_config - a hash that will be used as default configuration for this component's instances
|
46
25
|
class Base
|
47
|
-
|
26
|
+
|
48
27
|
class_attribute :default_instance_config
|
49
28
|
self.default_instance_config = {}
|
50
|
-
|
29
|
+
|
51
30
|
include Session
|
52
31
|
include Persistence
|
53
32
|
include Configuration
|
@@ -58,12 +37,50 @@ module Netzke
|
|
58
37
|
include Embedding
|
59
38
|
include Actions
|
60
39
|
|
61
|
-
|
40
|
+
# Parent component
|
41
|
+
attr_reader :parent
|
42
|
+
|
43
|
+
# Name that the parent can reference us by. The last part of +global_id+
|
44
|
+
attr_reader :name
|
45
|
+
|
46
|
+
# Global id in the components tree, following the double-underscore notation, e.g. +books__config_panel__form+
|
47
|
+
attr_reader :global_id
|
48
|
+
|
49
|
+
class << self
|
50
|
+
# Component's short class name, e.g.:
|
51
|
+
# "Netzke::Module::SomeComponent" => "Module::SomeComponent"
|
52
|
+
def short_component_class_name
|
53
|
+
self.name.sub(/^Netzke::/, "")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Component's class, given its name
|
57
|
+
def constantize_class_name(class_name)
|
58
|
+
"#{class_name}".constantize rescue "Netzke::#{class_name}".constantize
|
59
|
+
end
|
60
|
+
|
61
|
+
# Instance of component by config
|
62
|
+
def instance_by_config(config)
|
63
|
+
constantize_class_name(config[:class_name]).new(config)
|
64
|
+
end
|
62
65
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
66
|
+
# All ancestor classes in the Netzke class hierarchy (i.e. up to Netzke::Base)
|
67
|
+
def class_ancestors
|
68
|
+
if self == Netzke::Base
|
69
|
+
[]
|
70
|
+
else
|
71
|
+
superclass.class_ancestors + [self]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Same as +read_inheritable_attribute+ returning a hash, but returns empty hash when it's equal to superclass's
|
76
|
+
def read_clean_inheritable_hash(attr_name)
|
77
|
+
res = read_inheritable_attribute(attr_name) || {}
|
78
|
+
# We don't want here any values from the superclass (which is the consequence of using inheritable attributes).
|
79
|
+
res == self.superclass.read_inheritable_attribute(attr_name) ? {} : res
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Instantiates a component instance. A parent can optionally be provided.
|
67
84
|
def initialize(conf = {}, parent = nil)
|
68
85
|
@passed_config = conf # configuration passed at the moment of instantiation
|
69
86
|
@passed_config.deep_freeze
|
@@ -71,72 +88,42 @@ module Netzke
|
|
71
88
|
@name = conf[:name].nil? ? short_component_class_name.underscore : conf[:name].to_s
|
72
89
|
@global_id = parent.nil? ? @name : "#{parent.global_id}__#{@name}"
|
73
90
|
@flash = []
|
74
|
-
|
91
|
+
|
75
92
|
# initialize @components and @items
|
76
93
|
normalize_components_in_items
|
77
94
|
# auto_collect_actions_from_config_and_js_properties
|
78
95
|
end
|
79
|
-
|
80
|
-
# Short component class name, e.g.:
|
81
|
-
# Netzke::Module::SomeComponent => Module::SomeComponent
|
82
|
-
def self.short_component_class_name
|
83
|
-
self.name.sub(/^Netzke::/, "")
|
84
|
-
end
|
85
96
|
|
86
|
-
#
|
87
|
-
def self.constantize_class_name(class_name)
|
88
|
-
"#{class_name}".constantize rescue "Netzke::#{class_name}".constantize
|
89
|
-
end
|
90
|
-
|
97
|
+
# Proxy to the equally named class method
|
91
98
|
def constantize_class_name(class_name)
|
92
99
|
self.class.constantize_class_name(class_name)
|
93
100
|
end
|
94
101
|
|
95
|
-
#
|
96
|
-
def self.instance_by_config(config)
|
97
|
-
constantize_class_name(config[:class_name]).new(config)
|
98
|
-
end
|
99
|
-
|
100
|
-
def logger
|
101
|
-
if defined?(Rails)
|
102
|
-
Rails.logger
|
103
|
-
else
|
104
|
-
require 'logger'
|
105
|
-
Logger.new(STDOUT)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# 'Netzke::Grid' => 'Grid'
|
102
|
+
# Proxy to the equally named class method
|
110
103
|
def short_component_class_name
|
111
104
|
self.class.short_component_class_name
|
112
105
|
end
|
113
|
-
|
114
|
-
def flash(flash_hash)
|
115
|
-
level = flash_hash.keys.first
|
116
|
-
raise "Unknown message level for flash" unless %(notice warning error).include?(level.to_s)
|
117
|
-
@flash << {:level => level, :msg => flash_hash[level]}
|
118
|
-
end
|
119
106
|
|
120
|
-
|
121
|
-
res = read_inheritable_attribute(attr_name) || {}
|
122
|
-
# We don't want here any values from the superclass (which is the consequence of using inheritable attributes).
|
123
|
-
res == self.superclass.read_inheritable_attribute(attr_name) ? {} : res
|
124
|
-
end
|
125
|
-
|
126
|
-
# override this method to do stuff at the moment of loading by some parent
|
107
|
+
# Override this method to do stuff at the moment of first-time loading
|
127
108
|
def before_load
|
128
|
-
# component_session.clear - we don't do it anymore
|
129
109
|
end
|
130
110
|
|
111
|
+
private
|
131
112
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
113
|
+
def logger #:nodoc:
|
114
|
+
if defined?(Rails)
|
115
|
+
Rails.logger
|
116
|
+
else
|
117
|
+
require 'logger'
|
118
|
+
Logger.new(STDOUT)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def flash(flash_hash) #:nodoc:
|
123
|
+
level = flash_hash.keys.first
|
124
|
+
raise "Unknown message level for flash" unless %(notice warning error).include?(level.to_s)
|
125
|
+
@flash << {:level => level, :msg => flash_hash[level]}
|
138
126
|
end
|
139
|
-
end
|
140
127
|
|
141
128
|
end
|
142
129
|
end
|