netzke-core 0.6.7 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +36 -1
- data/{README.markdown → README.md} +17 -15
- data/Rakefile +1 -1
- data/TODO +4 -4
- data/app/controllers/netzke_controller.rb +8 -3
- data/javascripts/base.js +71 -68
- data/javascripts/ext.js +182 -111
- data/lib/netzke/actions.rb +2 -1
- data/lib/netzke/base.rb +5 -1
- data/lib/netzke/composition.rb +2 -2
- data/lib/netzke/configuration.rb +1 -1
- data/lib/netzke/core/dynamic_assets.rb +7 -7
- data/lib/netzke/core/session.rb +4 -0
- data/lib/netzke/core/version.rb +2 -2
- data/lib/netzke/core.rb +23 -30
- data/lib/netzke/core_ext/symbol.rb +1 -1
- data/lib/netzke/embedding.rb +1 -1
- data/lib/netzke/ext_component.rb +2 -2
- data/lib/netzke/javascript.rb +70 -39
- data/lib/netzke/plugin.rb +15 -0
- data/lib/netzke/plugins.rb +29 -0
- data/lib/netzke/railz/action_view_ext/ext.rb +13 -16
- data/lib/netzke/railz/action_view_ext/touch.rb +3 -3
- data/lib/netzke/railz/action_view_ext.rb +0 -3
- data/lib/netzke/railz/engine.rb +34 -29
- data/lib/netzke/services.rb +1 -1
- data/lib/netzke/state.rb +2 -2
- data/lib/netzke-core.rb +1 -0
- data/netzke-core.gemspec +108 -9
- data/stylesheets/core.css +25 -5
- data/test/rails_app/Gemfile +1 -1
- data/test/rails_app/Gemfile.lock +37 -36
- data/test/rails_app/app/components/component_loader.rb +36 -24
- data/test/rails_app/app/components/component_with_js_mixin/javascripts/component_with_js_mixin.js +5 -0
- data/test/rails_app/app/components/component_with_js_mixin.rb +3 -1
- data/test/rails_app/app/components/component_with_nested_through.rb +28 -0
- data/test/rails_app/app/components/component_with_session_persistence.rb +7 -5
- data/test/rails_app/app/components/dynamic_tab_panel/javascripts/dynamic_tab_panel.js +9 -0
- data/test/rails_app/app/components/dynamic_tab_panel.rb +19 -0
- data/test/rails_app/app/components/extended_server_caller.rb +6 -5
- data/test/rails_app/app/components/loader_of_component_with_custom_css.rb +7 -8
- data/test/rails_app/app/components/localized_panel.rb +10 -1
- data/test/rails_app/app/components/nested_component.rb +18 -0
- data/test/rails_app/app/components/panel_with_plugin.rb +4 -0
- data/test/rails_app/app/components/panel_with_tools.rb +19 -0
- data/test/rails_app/app/components/plugin_with_components.rb +14 -0
- data/test/rails_app/app/components/server_caller.rb +1 -1
- data/test/rails_app/app/components/server_counter.rb +1 -1
- data/test/rails_app/app/components/simple_component.rb +2 -0
- data/test/rails_app/app/components/simple_tab_panel.rb +21 -21
- data/test/rails_app/app/components/simple_window.rb +1 -1
- data/test/rails_app/app/components/some_composite.rb +3 -2
- data/test/rails_app/app/components/some_plugin.rb +39 -0
- data/test/rails_app/app/controllers/application_controller.rb +1 -1
- data/test/rails_app/app/controllers/components_controller.rb +1 -1
- data/test/rails_app/app/views/layouts/touch.html.erb +1 -1
- data/test/rails_app/config/application.rb +0 -2
- data/test/rails_app/config/initializers/netzke.rb +2 -1
- data/test/rails_app/config/locales/es.yml +1 -0
- data/test/rails_app/features/{actions.feature → actions_and_tools.feature} +8 -0
- data/test/rails_app/features/client-server.feature +0 -1
- data/test/rails_app/features/complex_component.feature +1 -1
- data/test/rails_app/features/component_loader.feature +7 -0
- data/test/rails_app/features/composition.feature +2 -2
- data/test/rails_app/features/custom_css.feature +1 -1
- data/test/rails_app/features/i18n.feature +3 -0
- data/test/rails_app/features/js_include.feature +2 -0
- data/test/rails_app/features/nested_views.feature +5 -4
- data/test/rails_app/features/plugin.feature +16 -0
- data/test/rails_app/features/step_definitions/generic_steps.rb +21 -2
- data/test/rails_app/features/touch.feature +10 -10
- data/test/rails_app/spec/component/component_spec.rb +20 -0
- metadata +106 -10
- data/app/models/netzke_preference.rb +0 -170
data/javascripts/ext.js
CHANGED
@@ -1,83 +1,109 @@
|
|
1
|
+
// Enable Ext 4 migration errors traceback display
|
2
|
+
if (Ext.Compat) Ext.Compat.showErrors = true;
|
3
|
+
|
1
4
|
// Because of Netzke's double-underscore notation, Ext.TabPanel should have a different id-delimiter (yes, this should be in netzke-core)
|
2
5
|
Ext.TabPanel.prototype.idDelimiter = "___";
|
3
6
|
|
4
7
|
Ext.QuickTips.init();
|
5
8
|
|
6
9
|
// We don't want no state managment by default, thank you!
|
7
|
-
Ext.state.Provider.prototype.set =
|
10
|
+
Ext.state.Provider.prototype.set = Ext.emptyFn;
|
8
11
|
|
9
|
-
//
|
12
|
+
// Checking Ext JS version: both major and minor versions must be the same
|
10
13
|
(function(){
|
11
|
-
var
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
var requiredVersionMajor = 4,
|
15
|
+
requiredVersionMinor = 0,
|
16
|
+
extVersion = Ext.getVersion('extjs'),
|
17
|
+
currentVersionMajor = extVersion.getMajor(),
|
18
|
+
currentVersionMinor = extVersion.getMinor(),
|
19
|
+
requiredString = "" + requiredVersionMajor + "." + requiredVersionMinor + ".x",
|
20
|
+
currentString = "" + currentVersionMajor + "." + currentVersionMinor + ".x";
|
21
|
+
|
22
|
+
if (requiredVersionMajor != currentVersionMajor || requiredVersionMinor != currentVersionMinor) {
|
23
|
+
Netzke.warning("Ext " + requiredString + " required. You have " + currentString + ".");
|
15
24
|
}
|
16
25
|
})();
|
17
26
|
|
18
|
-
Netzke
|
27
|
+
// FeedbackGhost is a little class that displays unified feedback from Netzke components.
|
28
|
+
Ext.define('Netzke.FeedbackGhost', {
|
29
|
+
showFeedback: function(msg){
|
30
|
+
if (!msg) Netzke.exception("Netzke.FeedbackGhost#showFeedback: wrong number of arguments (0 for 1)");
|
31
|
+
if (Ext.isObject(msg)) {
|
32
|
+
this.msg(msg.level.camelize(), msg.msg);
|
33
|
+
} else if (Ext.isArray(msg)) {
|
34
|
+
Ext.each(msg, function(m) { this.showFeedback(m); }, this);
|
35
|
+
} else {
|
36
|
+
this.msg(null, msg); // no header for now
|
37
|
+
}
|
38
|
+
},
|
39
|
+
|
40
|
+
msg: function(title, format){
|
41
|
+
if(!this.msgCt){
|
42
|
+
this.msgCt = Ext.core.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
|
43
|
+
}
|
44
|
+
var s = Ext.String.format.apply(String, Array.prototype.slice.call(arguments, 1));
|
45
|
+
var m = Ext.core.DomHelper.append(this.msgCt, this.createBox(title, s), true);
|
46
|
+
m.hide();
|
47
|
+
m.slideIn('t').ghost("t", { delay: 1000, remove: true});
|
48
|
+
},
|
49
|
+
|
50
|
+
createBox: function(t, s){
|
51
|
+
if (t) {
|
52
|
+
return '<div class="msg"><h3>' + t + '</h3><p>' + s + '</p></div>';
|
53
|
+
} else {
|
54
|
+
return '<div class="msg"><p>' + s + '</p></div>';
|
55
|
+
}
|
56
|
+
}
|
57
|
+
});
|
58
|
+
|
59
|
+
// Mix it into every Netzke component as feedbackGhost
|
60
|
+
Netzke.componentMixin.feedbackGhost = Ext.create("Netzke.FeedbackGhost");
|
61
|
+
|
62
|
+
Ext.define('Netzke.classes.NetzkeRemotingProvider', {
|
63
|
+
extend: 'Ext.direct.RemotingProvider',
|
64
|
+
|
19
65
|
getCallData: function(t){
|
20
66
|
return {
|
21
67
|
act: t.action, // rails doesn't really support having a parameter named "action"
|
22
68
|
method: t.method,
|
23
69
|
data: t.data,
|
24
70
|
type: 'rpc',
|
25
|
-
tid: t.
|
71
|
+
tid: t.id
|
26
72
|
}
|
27
73
|
},
|
28
74
|
|
29
75
|
addAction: function(action, methods) {
|
30
76
|
var cls = this.namespace[action] || (this.namespace[action] = {});
|
31
77
|
for(var i = 0, len = methods.length; i < len; i++){
|
32
|
-
|
33
|
-
|
34
|
-
|
78
|
+
method = Ext.create('Ext.direct.RemotingMethod', methods[i]);
|
79
|
+
cls[method.name] = this.createHandler(action, method);
|
80
|
+
}
|
35
81
|
},
|
36
82
|
|
37
|
-
//
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
// - server will respond with status 500, indicating a fault
|
44
|
-
// - in the response, server will respond with the result from tid 1
|
45
|
-
// - client marks tid 1 as success (deletes the transaction from pending), and will retry 2 and 3 - this is the
|
46
|
-
// change in Ext.direct.RemotingProvider's default behaviour
|
47
|
-
onData: function(opt, success, xhr){
|
48
|
-
var events=this.getEvents(xhr);
|
49
|
-
|
50
|
-
for(var i = 0, len = events.length; i < len; i++){
|
51
|
-
var e = events[i],
|
52
|
-
t = this.getTransaction(e);
|
53
|
-
this.fireEvent('data', this, e);
|
54
|
-
if(t){
|
55
|
-
this.doCallback(t, e, true);
|
56
|
-
Ext.Direct.removeTransaction(t);
|
57
|
-
}
|
83
|
+
// HACK: Ext JS 4.0.0 retry mechanism is broken
|
84
|
+
getTransaction: function(opt) {
|
85
|
+
if (opt.$className == "Ext.direct.Transaction") {
|
86
|
+
return opt;
|
87
|
+
} else {
|
88
|
+
return this.callParent([opt]);
|
58
89
|
}
|
59
|
-
|
60
|
-
Netzke.classes.NetzkeRemotingProvider.superclass.onData.call(this, opt, success, xhr);
|
61
90
|
}
|
62
|
-
|
63
91
|
});
|
64
92
|
|
65
93
|
Netzke.directProvider = new Netzke.classes.NetzkeRemotingProvider({
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
94
|
+
type: "remoting", // create a Ext.direct.RemotingProvider
|
95
|
+
url: Netzke.RelativeUrlRoot + "/netzke/direct/", // url to connect to the Ext.Direct server-side router.
|
96
|
+
namespace: "Netzke.providers", // namespace to create the Remoting Provider in
|
97
|
+
actions: {},
|
98
|
+
maxRetries: Netzke.core.directMaxRetries,
|
99
|
+
enableBuffer: true, // buffer/batch requests within 10ms timeframe
|
100
|
+
timeout: 30000 // 30s timeout per request
|
73
101
|
});
|
74
102
|
|
75
103
|
Ext.Direct.addProvider(Netzke.directProvider);
|
76
104
|
|
105
|
+
// Methods/properties that each and every Netzke component will have
|
77
106
|
Ext.apply(Netzke.classes.Core.Mixin, {
|
78
|
-
height: 400,
|
79
|
-
border: false,
|
80
|
-
|
81
107
|
/*
|
82
108
|
Mask shown during loading of a component. Set to false to not mask. Pass config for Ext.LoadMask for configuring msg/cls, etc.
|
83
109
|
Set msg to null if mask without any msg is desirable.
|
@@ -90,12 +116,17 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
90
116
|
|
91
117
|
this.detectActions(this);
|
92
118
|
|
119
|
+
// Detects component placeholders in the passed object (typically, "items"),
|
120
|
+
// and merges them with the corresponding config from this.netzkeComponents.
|
121
|
+
// This way it becomes ready to be instantiated properly by Ext.
|
93
122
|
this.detectComponents(this.items);
|
94
123
|
|
95
124
|
this.normalizeTools();
|
96
125
|
|
97
126
|
this.processEndpoints();
|
98
127
|
|
128
|
+
this.processPlugins();
|
129
|
+
|
99
130
|
// This is where the references to different callback functions will be stored
|
100
131
|
this.callbackHash = {};
|
101
132
|
|
@@ -120,20 +151,21 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
120
151
|
},
|
121
152
|
|
122
153
|
/*
|
123
|
-
Dynamically creates methods for endpoints, so that we could later call them like: this.myEndpointMethod()
|
154
|
+
Dynamically creates methods for endpoints, so that we could later call them like: this.myEndpointMethod()
|
124
155
|
*/
|
125
156
|
processEndpoints: function(){
|
126
157
|
var endpoints = this.endpoints || [];
|
127
158
|
endpoints.push('deliver_component'); // all Netzke components get this endpoint
|
128
159
|
var directActions = [];
|
129
|
-
var that=this;
|
160
|
+
var that = this;
|
130
161
|
|
131
162
|
Ext.each(endpoints, function(intp){
|
132
163
|
directActions.push({"name":intp.camelize(true), "len":1});
|
133
164
|
this[intp.camelize(true)] = function(arg, callback, scope) {
|
134
165
|
Netzke.runningRequests++;
|
135
|
-
|
136
|
-
|
166
|
+
|
167
|
+
scope = scope || that;
|
168
|
+
Netzke.providers[this.id][intp.camelize(true)].call(scope, arg, function(result, remotingEvent) {
|
137
169
|
if(remotingEvent.message) {
|
138
170
|
console.error("RPC event indicates an error: ", remotingEvent);
|
139
171
|
throw new Error(remotingEvent.message);
|
@@ -157,8 +189,8 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
157
189
|
// Create an event for each action (so that higher-level components could interfere)
|
158
190
|
this.addEvents(tool.id+'click');
|
159
191
|
|
160
|
-
var handler =
|
161
|
-
normTools.push({
|
192
|
+
var handler = Ext.Function.bind(this.toolActionHandler, this, [tool]);
|
193
|
+
normTools.push({type : tool, handler : handler, scope : this});
|
162
194
|
}, this);
|
163
195
|
this.tools = normTools;
|
164
196
|
}
|
@@ -176,7 +208,7 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
176
208
|
// Configure the action
|
177
209
|
var actionConfig = Ext.apply({}, this.actions[name]); // do not modify original this.actions
|
178
210
|
actionConfig.customHandler = actionConfig.handler;
|
179
|
-
actionConfig.handler =
|
211
|
+
actionConfig.handler = Ext.Function.bind(this.actionHandler, this); // handler common for all actions
|
180
212
|
actionConfig.name = name;
|
181
213
|
normActions[name] = new Ext.Action(actionConfig);
|
182
214
|
}
|
@@ -195,7 +227,7 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
195
227
|
o.handler = this[o.handler.camelize(true)].createDelegate(this);
|
196
228
|
}
|
197
229
|
// TODO: this should be configurable!
|
198
|
-
Ext.each(["bbar", "tbar", "fbar", "menu", "items", "contextMenu", "buttons"], function(key){
|
230
|
+
Ext.each(["bbar", "tbar", "fbar", "menu", "items", "contextMenu", "buttons", "dockedItems"], function(key){
|
199
231
|
if (o[key]) {
|
200
232
|
var items = [].concat(o[key]); // we need to do it in order to esure that this instance has a separate bbar/tbar/etc, NOT shared via class' prototype
|
201
233
|
delete(o[key]);
|
@@ -220,13 +252,14 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
220
252
|
},
|
221
253
|
|
222
254
|
/*
|
223
|
-
|
255
|
+
Dynamically loads a Netzke component.
|
256
|
+
Config options:
|
224
257
|
'name' (required) - the name of the child component to load
|
225
|
-
'container' - the id of a panel with the 'fit' layout where the loaded component will be
|
226
|
-
'callback' - function that gets called after the component is loaded
|
227
|
-
'scope' - scope for the callback
|
258
|
+
'container' - if specified, the id (or instance) of a panel with the 'fit' layout where the loaded component will be added to; the previously existing component will be destroyed
|
259
|
+
'callback' - function that gets called after the component is loaded; it receives the component's instance as parameter
|
260
|
+
'scope' - scope for the callback
|
228
261
|
*/
|
229
|
-
|
262
|
+
loadNetzkeComponent: function(params){
|
230
263
|
if (params.id) {
|
231
264
|
params.name = params.id;
|
232
265
|
Netzke.deprecationWarning("Using 'id' in loadComponent is deprecated. Use 'name' instead.");
|
@@ -272,10 +305,17 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
272
305
|
this.deliverComponent(serverParams);
|
273
306
|
},
|
274
307
|
|
308
|
+
// DEPRECATED in favor or loadNetzkeComponent
|
309
|
+
loadComponent: function(params) {
|
310
|
+
Netzke.deprecationWarning("loadComponent is deprecated in favor of loadNetzkeComponent");
|
311
|
+
params.container = params.container || this.getId(); // for backward compatibility
|
312
|
+
this.loadNetzkeComponent(params);
|
313
|
+
},
|
314
|
+
|
275
315
|
/*
|
276
316
|
Called by the server after we ask him to load a component
|
277
317
|
*/
|
278
|
-
componentDelivered
|
318
|
+
componentDelivered: function(config){
|
279
319
|
// retrieve the loading config for this component
|
280
320
|
var storedConfig = this.componentsBeingLoaded[config.name] || {};
|
281
321
|
delete this.componentsBeingLoaded[config.name];
|
@@ -285,8 +325,21 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
285
325
|
storedConfig.loadMaskCmp.destroy();
|
286
326
|
}
|
287
327
|
|
288
|
-
|
289
|
-
|
328
|
+
var componentInstance = Ext.createByAlias(config.alias, config);
|
329
|
+
|
330
|
+
if (storedConfig.container) {
|
331
|
+
var containerCmp = Ext.isString(storedConfig.container) ? Ext.getCmp(storedConfig.container) : storedConfig.container;
|
332
|
+
// containerCmp.insertNetzkeComponent(componentInstance);
|
333
|
+
containerCmp.removeAll();
|
334
|
+
containerCmp.add(componentInstance);
|
335
|
+
|
336
|
+
if (containerCmp.isVisible()) {
|
337
|
+
containerCmp.doLayout();
|
338
|
+
} else {
|
339
|
+
// if loaded into a hidden container, we need a little trick
|
340
|
+
containerCmp.on('show', function(cmp){ cmp.doLayout(); }, {single: true});
|
341
|
+
}
|
342
|
+
}
|
290
343
|
|
291
344
|
if (storedConfig.callback) {
|
292
345
|
storedConfig.callback.call(storedConfig.scope || this, componentInstance);
|
@@ -295,10 +348,22 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
295
348
|
this.fireEvent('componentload', componentInstance);
|
296
349
|
},
|
297
350
|
|
351
|
+
componentDeliveryFailed: function(params) {
|
352
|
+
var storedConfig = this.componentsBeingLoaded[params.componentName] || {};
|
353
|
+
delete this.componentsBeingLoaded[params.componentName];
|
354
|
+
|
355
|
+
if (storedConfig.loadMaskCmp) {
|
356
|
+
storedConfig.loadMaskCmp.hide();
|
357
|
+
storedConfig.loadMaskCmp.destroy();
|
358
|
+
}
|
359
|
+
|
360
|
+
this.netzkeFeedback({msg: params.msg, level: "Error"});
|
361
|
+
},
|
362
|
+
|
298
363
|
/*
|
299
|
-
Instantiates and renders a component with given config and container
|
364
|
+
DEPRECATED. Instantiates and renders a component with given config and container.
|
300
365
|
*/
|
301
|
-
instantiateAndRenderComponent
|
366
|
+
instantiateAndRenderComponent: function(config, containerId){
|
302
367
|
var componentInstance;
|
303
368
|
if (containerId) {
|
304
369
|
var container = Ext.getCmp(containerId);
|
@@ -310,24 +375,9 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
310
375
|
},
|
311
376
|
|
312
377
|
/*
|
313
|
-
|
314
|
-
Arg: an JS object with the following keys:
|
315
|
-
- id: id of the receiving container
|
316
|
-
- config: configuration of the component to be instantiated and inserted into the container
|
378
|
+
Returns parent Netzke component
|
317
379
|
*/
|
318
|
-
|
319
|
-
// var cont = Ext.getCmp(params.container);
|
320
|
-
// if (cont) {
|
321
|
-
// cont.instantiateChild(params.config);
|
322
|
-
// } else {
|
323
|
-
// this.instantiateChild(params.config);
|
324
|
-
// }
|
325
|
-
// },
|
326
|
-
|
327
|
-
/*
|
328
|
-
Returns the parent component
|
329
|
-
*/
|
330
|
-
getParent: function(){
|
380
|
+
getParentNetzkeComponent: function(){
|
331
381
|
// simply cutting the last part of the id: some_parent__a_kid__a_great_kid => some_parent__a_kid
|
332
382
|
var idSplit = this.id.split("__");
|
333
383
|
idSplit.pop();
|
@@ -336,61 +386,65 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
336
386
|
return parentId === "" ? null : Ext.getCmp(parentId);
|
337
387
|
},
|
338
388
|
|
389
|
+
// DEPRECATED
|
390
|
+
getParent: function() {
|
391
|
+
Netzke.deprecationWarning("getParent is deprecated in favor of getParentNetzkeComponent");
|
392
|
+
return this.getParentNetzkeComponent();
|
393
|
+
},
|
394
|
+
|
339
395
|
/*
|
340
|
-
Reloads current component (calls the parent to reload
|
396
|
+
Reloads current component (calls the parent to reload us as its component)
|
341
397
|
*/
|
342
|
-
reload
|
343
|
-
var parent = this.
|
398
|
+
reload: function(){
|
399
|
+
var parent = this.getParentNetzkeComponent();
|
344
400
|
if (parent) {
|
345
|
-
parent.
|
401
|
+
parent.loadNetzkeComponent({id:this.localId(parent), container:this.ownerCt.id});
|
346
402
|
} else {
|
347
403
|
window.location.reload();
|
348
404
|
}
|
349
405
|
},
|
350
406
|
|
351
407
|
/*
|
352
|
-
Reconfigures the component
|
408
|
+
DEPRECATED: Reconfigures the component
|
353
409
|
*/
|
354
410
|
reconfigure: function(config){
|
355
411
|
this.ownerCt.instantiateChild(config)
|
356
412
|
},
|
357
413
|
|
358
|
-
|
359
|
-
|
414
|
+
/*
|
415
|
+
Instantiates and returns a Netzke component by its name.
|
416
|
+
*/
|
417
|
+
instantiateChildNetzkeComponent: function(name) {
|
418
|
+
name = name.camelize(true);
|
419
|
+
return Ext.createByAlias(this.netzkeComponents[name].alias, this.netzkeComponents[name])
|
420
|
+
},
|
421
|
+
|
422
|
+
/*
|
423
|
+
Returns *instantiated* child component by its relative id, which may contain the 'parent' part to walk _up_ the hierarchy
|
424
|
+
*/
|
425
|
+
getChildNetzkeComponent: function(id){
|
360
426
|
if (id === "") {return this};
|
361
427
|
id = id.underscore();
|
362
428
|
var split = id.split("__");
|
363
429
|
if (split[0] === 'parent') {
|
364
430
|
split.shift();
|
365
431
|
var childInParentScope = split.join("__");
|
366
|
-
return this.
|
432
|
+
return this.getParentNetzkeComponent().getChildNetzkeComponent(childInParentScope);
|
367
433
|
} else {
|
368
434
|
return Ext.getCmp(this.id+"__"+id);
|
369
435
|
}
|
370
436
|
},
|
371
437
|
|
372
|
-
//
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
if (this.initialConfig.menu) {this.addMenu(this.initialConfig.menu, this);}
|
377
|
-
|
378
|
-
// generic events
|
379
|
-
this.addEvents(
|
380
|
-
'componentload' // fired when a child is dynamically loaded
|
381
|
-
);
|
382
|
-
|
383
|
-
// Cleaning up on destroy
|
384
|
-
this.on('beforedestroy', function(){
|
385
|
-
this.cleanUpMenu();
|
386
|
-
}, this);
|
387
|
-
|
388
|
-
this.callbackHash = {};
|
389
|
-
|
390
|
-
if (this.afterConstructor) this.afterConstructor(config);
|
438
|
+
// DEPRECATED
|
439
|
+
getChildComponent: function(id) {
|
440
|
+
Netzke.deprecationWarning("getChildComponent is deprecated in favor of getChildNetzkeComponent");
|
441
|
+
return this.getChildNetzkeComponent(id);
|
391
442
|
},
|
392
443
|
|
393
|
-
|
444
|
+
/*
|
445
|
+
Provides a visual feedback. TODO: refactor
|
446
|
+
*/
|
447
|
+
netzkeFeedback: function(msg){
|
394
448
|
if (this.initialConfig && this.initialConfig.quiet) {
|
395
449
|
return false;
|
396
450
|
}
|
@@ -413,8 +467,16 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
413
467
|
}
|
414
468
|
},
|
415
469
|
|
416
|
-
//
|
417
|
-
|
470
|
+
// DEPRECATED in favor of netzkeFeedback
|
471
|
+
feedback: function(msg) {
|
472
|
+
Netzke.deprecationWarning("feedback is deprecated in favor of netzkeFeedback");
|
473
|
+
this.netzkeFeedback(msg);
|
474
|
+
},
|
475
|
+
|
476
|
+
/*
|
477
|
+
Common handler for all netzke's actions. <tt>comp</tt> is the Component that triggered the action (e.g. button or menu item)
|
478
|
+
*/
|
479
|
+
actionHandler: function(comp){
|
418
480
|
var actionName = comp.name;
|
419
481
|
// If firing corresponding event doesn't return false, call the handler
|
420
482
|
if (this.fireEvent(actionName+'click', comp)) {
|
@@ -429,7 +491,7 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
429
491
|
},
|
430
492
|
|
431
493
|
// Common handler for tools
|
432
|
-
toolActionHandler
|
494
|
+
toolActionHandler: function(tool){
|
433
495
|
// If firing corresponding event doesn't return false, call the handler
|
434
496
|
if (this.fireEvent(tool.id+'click')) {
|
435
497
|
var methodName = "on"+tool.camelize();
|
@@ -438,5 +500,14 @@ Ext.apply(Netzke.classes.Core.Mixin, {
|
|
438
500
|
}
|
439
501
|
},
|
440
502
|
|
503
|
+
processPlugins: function() {
|
504
|
+
if (this.netzkePlugins) {
|
505
|
+
if (!this.plugins) this.plugins = [];
|
506
|
+
Ext.each(this.netzkePlugins, function(p){
|
507
|
+
this.plugins.push(this.instantiateChildNetzkeComponent(p));
|
508
|
+
}, this);
|
509
|
+
}
|
510
|
+
},
|
511
|
+
|
441
512
|
onComponentLoad:Ext.emptyFn // gets overridden
|
442
513
|
});
|
data/lib/netzke/actions.rb
CHANGED
@@ -103,7 +103,8 @@ module Netzke
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def uri_to_icon(icon)
|
106
|
-
Netzke::Core.with_icons ? Netzke::Core.icons_uri
|
106
|
+
Netzke::Core.with_icons ? [Netzke::Core.controller.config.relative_url_root, Netzke::Core.icons_uri, '/', icon.to_s, ".png"].join : nil
|
107
107
|
end
|
108
|
+
|
108
109
|
end
|
109
110
|
end
|
data/lib/netzke/base.rb
CHANGED
@@ -6,6 +6,7 @@ require 'netzke/stylesheets'
|
|
6
6
|
require 'netzke/inheritance'
|
7
7
|
require 'netzke/services'
|
8
8
|
require 'netzke/composition'
|
9
|
+
require 'netzke/plugins'
|
9
10
|
require 'netzke/configuration'
|
10
11
|
require 'netzke/state'
|
11
12
|
require 'netzke/embedding'
|
@@ -36,6 +37,7 @@ module Netzke
|
|
36
37
|
include Inheritance
|
37
38
|
include Services
|
38
39
|
include Composition
|
40
|
+
include Plugins
|
39
41
|
include Stylesheets
|
40
42
|
include Embedding
|
41
43
|
include Actions
|
@@ -74,7 +76,9 @@ module Netzke
|
|
74
76
|
|
75
77
|
# Instance of component by config
|
76
78
|
def instance_by_config(config)
|
77
|
-
|
79
|
+
klass = config[:klass] || constantize_class_name(config[:class_name])
|
80
|
+
raise NameError, "Netzke: Unknown component #{config[:class_name]}" if klass.nil?
|
81
|
+
klass.new(config)
|
78
82
|
end
|
79
83
|
|
80
84
|
# The ID used to locate this component's block in locale files
|
data/lib/netzke/composition.rb
CHANGED
@@ -46,7 +46,7 @@ module Netzke
|
|
46
46
|
:component_delivered => component.js_config
|
47
47
|
}]
|
48
48
|
else
|
49
|
-
{:
|
49
|
+
{:component_delivery_failed => {:component_name => component_name, :msg => "Couldn't load component '#{component_name}'"}}
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -113,7 +113,7 @@ module Netzke
|
|
113
113
|
|
114
114
|
# All components for this instance, which includes components defined on class level, and components detected in :items
|
115
115
|
def components
|
116
|
-
@components ||= self.class.registered_components.inject({}){ |res, name| res.merge(name.to_sym => send(COMPONENT_METHOD_NAME % name)) }
|
116
|
+
@components ||= self.class.registered_components.inject({}){ |res, name| res.merge(name.to_sym => send(COMPONENT_METHOD_NAME % name)) }.merge(config[:components] || {})
|
117
117
|
end
|
118
118
|
|
119
119
|
def eager_loaded_components
|
data/lib/netzke/configuration.rb
CHANGED
@@ -30,8 +30,8 @@ module Netzke
|
|
30
30
|
res
|
31
31
|
end
|
32
32
|
|
33
|
-
def ext_js
|
34
|
-
res = initial_dynamic_javascript << "\n"
|
33
|
+
def ext_js(form_authenticity_token)
|
34
|
+
res = initial_dynamic_javascript(form_authenticity_token) << "\n"
|
35
35
|
|
36
36
|
include_base_js(res)
|
37
37
|
|
@@ -61,16 +61,16 @@ module Netzke
|
|
61
61
|
|
62
62
|
protected
|
63
63
|
|
64
|
-
# Generates initial javascript code that is dependent on Rails
|
65
|
-
def initial_dynamic_javascript
|
64
|
+
# Generates initial javascript code that is dependent on Rails settings
|
65
|
+
def initial_dynamic_javascript(form_authenticity_token)
|
66
66
|
res = []
|
67
|
-
|
67
|
+
res << %(Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection)
|
68
68
|
res << %{Ext.ns('Netzke');}
|
69
69
|
res << %{Ext.ns('Netzke.core');}
|
70
70
|
res << %{Netzke.RelativeUrlRoot = '#{ActionController::Base.config.relative_url_root}';}
|
71
|
-
res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}
|
71
|
+
res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}#{Netzke::Core.ext_uri}';}
|
72
72
|
|
73
|
-
res << %{Netzke.core.directMaxRetries =
|
73
|
+
res << %{Netzke.core.directMaxRetries = #{Netzke::Core.js_direct_max_retries};}
|
74
74
|
|
75
75
|
res.join("\n")
|
76
76
|
end
|
data/lib/netzke/core/session.rb
CHANGED
@@ -11,6 +11,10 @@ module Netzke
|
|
11
11
|
session[:_netzke_next_request_is_first_after_logout] = true
|
12
12
|
end
|
13
13
|
|
14
|
+
def current_user
|
15
|
+
Netzke::Core.controller.respond_to?(Netzke::Core.current_user_method) && Netzke::Core.controller.send(Netzke::Core.current_user_method) || nil
|
16
|
+
end
|
17
|
+
|
14
18
|
# Register the configuration for the component in the session, and also remember that the code for it has been rendered
|
15
19
|
def reg_component(config)
|
16
20
|
session[:netzke_components] ||= {}
|