netzke-core 0.6.4 → 0.6.5
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.
- data/CHANGELOG.rdoc +19 -0
- data/README.markdown +43 -0
- data/TODO +1 -5
- data/app/controllers/netzke_controller.rb +47 -15
- data/config/database.yml +2 -0
- data/features/component_loader.feature +6 -1
- data/features/composition.feature +2 -0
- data/features/js_include.feature +18 -0
- data/features/nested_views.feature +9 -0
- data/features/persistence.feature +6 -4
- data/features/support/paths.rb +3 -0
- data/javascripts/core.js +166 -519
- data/javascripts/ext.js +355 -0
- data/javascripts/touch.js +47 -0
- data/lib/netzke/actions.rb +31 -38
- data/lib/netzke/base.rb +48 -6
- data/lib/netzke/composition.rb +52 -63
- data/lib/netzke/configuration.rb +6 -2
- data/lib/netzke/core/version.rb +2 -2
- data/lib/netzke/core.rb +22 -15
- data/lib/netzke/javascript/scopes.rb +39 -0
- data/lib/netzke/javascript.rb +145 -114
- data/lib/netzke/railz/action_view_ext/ext.rb +59 -0
- data/lib/netzke/railz/action_view_ext/touch.rb +50 -0
- data/lib/netzke/railz/action_view_ext.rb +86 -0
- data/lib/netzke/railz/controller_extensions.rb +33 -0
- data/lib/netzke/{rails → railz}/routes.rb +0 -0
- data/lib/netzke/railz.rb +3 -0
- data/lib/netzke/session.rb +18 -3
- data/lib/netzke/state.rb +42 -15
- data/lib/netzke/stylesheets.rb +23 -8
- data/lib/netzke-core.rb +23 -16
- data/netzke-core.gemspec +52 -10
- data/spec/component/base_spec.rb +11 -0
- data/spec/component/javascript_spec.rb +3 -2
- data/spec/component/state_spec.rb +18 -0
- data/spec/spec_helper.rb +1 -1
- data/test/rails_app/Gemfile +3 -2
- data/test/rails_app/Gemfile.lock +73 -71
- data/test/rails_app/app/components/component_loader.rb +39 -4
- data/test/rails_app/app/components/{custom.css → component_with_custom_css/stylesheets/custom.css} +0 -0
- data/test/rails_app/app/components/component_with_custom_css.rb +2 -2
- data/test/rails_app/app/components/component_with_js_mixin/javascripts/extra_one.js +2 -0
- data/test/rails_app/app/components/component_with_js_mixin/javascripts/extra_two.js +2 -0
- data/test/rails_app/app/components/component_with_js_mixin/javascripts/method_set_one.js +6 -0
- data/test/rails_app/app/components/component_with_js_mixin/javascripts/method_set_two.js +5 -0
- data/test/rails_app/app/components/component_with_js_mixin.rb +8 -0
- data/test/rails_app/app/components/component_with_session_persistence.rb +10 -3
- data/test/rails_app/app/components/extended_component_with_js_mixin/javascripts/some_method_set.js +5 -0
- data/test/rails_app/app/components/extended_component_with_js_mixin.rb +7 -0
- data/test/rails_app/app/components/hello_world_component.rb +31 -0
- data/test/rails_app/app/components/server_caller.rb +1 -1
- data/test/rails_app/app/components/simple_panel.rb +2 -0
- data/test/rails_app/app/components/touch/hello_world_component.rb +25 -0
- data/test/rails_app/app/components/touch/server_caller.rb +28 -0
- data/test/rails_app/app/components/touch/simple_carousel.rb +17 -0
- data/test/rails_app/app/controllers/components_controller.rb +6 -1
- data/test/rails_app/app/controllers/touch_controller.rb +6 -0
- data/test/rails_app/app/helpers/touch_helper.rb +2 -0
- data/test/rails_app/app/views/components/panel_with_autoload.html.erb +2 -0
- data/test/rails_app/app/views/components/some_tab_panel.html.erb +11 -0
- data/test/rails_app/app/views/layouts/nested.html.erb +5 -0
- data/test/rails_app/app/views/layouts/touch.html.erb +13 -0
- data/test/rails_app/config/initializers/netzke.rb +1 -1
- data/test/rails_app/config/locales/en.yml +7 -1
- data/test/rails_app/config/routes.rb +10 -1
- data/test/rails_app/db/migrate/20110110132720_create_netzke_component_states.rb +20 -0
- data/test/rails_app/db/schema.rb +14 -1
- data/test/rails_app/spec/controllers/touch_controller_spec.rb +5 -0
- data/test/rails_app/spec/helpers/touch_helper_spec.rb +15 -0
- data/test/unit/netzke_core_test.rb +2 -6
- metadata +53 -11
- data/README.rdoc +0 -136
- data/lib/netzke/rails/action_view_ext.rb +0 -103
- data/lib/netzke/rails/controller_extensions.rb +0 -31
- data/test/rails_app/db/migrate/20100905214933_create_netzke_preferences.rb +0 -16
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
= v0.6.5 - 2011-01-14
|
2
|
+
* enhancements
|
3
|
+
* Various fixes for IE
|
4
|
+
* Support for Sencha Touch
|
5
|
+
* An endpoint can now "call" JavaScript functions that accept multiple parameters, by specifying an array, e.g.:
|
6
|
+
{:some_js_function => [arg1, arg2]}
|
7
|
+
* New API: +js_mixin+ method to "mixin" JavaScript objects from external files (see RDocs).
|
8
|
+
* New JS class +componentLoadMask+ property to configure a mask when a component gets dynamically loaded with +loadComponent+. Accepts the same configuration as Ext.LoadMask.
|
9
|
+
* +js_include+ and +css_include+ accept both symbols and strings, where strings would contain full paths to the included file, whereas symbols get expanded to full paths following simple conventions (see RDocs for details).
|
10
|
+
* Make some of +Netzke::Core+ setup happen earlier in the loading process, so that we can safely use it while defining components.
|
11
|
+
* Performance improvements by memoizing +Base.constantize_class_name+.
|
12
|
+
* I18n for actions, see +Netzke::Actions+.
|
13
|
+
|
14
|
+
* bug fix
|
15
|
+
* The "componentload" event now gets fired after a component is dynamically loaded. The handler receives the instance of the loaded component.
|
16
|
+
* Feedback does not insert a new div every time being called
|
17
|
+
* JS class caching was broken for name-scoped classes
|
18
|
+
* When a component was dynamically loaded into a hidden container, it wasn't shown when the container got shown next time
|
19
|
+
|
1
20
|
= v0.6.4 - 2010-11-05
|
2
21
|
* enhancements
|
3
22
|
* Implemented Netzke.isLoading(), useful for testing
|
data/README.markdown
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
## Netzke Core
|
2
|
+
|
3
|
+
Netzke Core is the bare bones of the [Netzke framework](https://github.com/skozlov/netzke). For pre-built full-featured components (like grids, forms, tab/accordion panels, applications, etc), see [netzke-basepack](http://github.com/skozlov/netzke-basepack) (Ext JS).
|
4
|
+
|
5
|
+
Netzke Core takes the burden of implementing the following key aspects of the framework:
|
6
|
+
|
7
|
+
* JavaScript class generation
|
8
|
+
* Client-server communication
|
9
|
+
* Extendibility of components (with OOP, in both Ruby and JavaScript)
|
10
|
+
* Unlimited nesting (composition)
|
11
|
+
* Dynamic component loading
|
12
|
+
* JavaScript class caching
|
13
|
+
* Inclusion of “external” JavaScript CSS files
|
14
|
+
* ... and more
|
15
|
+
|
16
|
+
All this provides for fast, low-traffic, robust, highly maintainable applications.
|
17
|
+
|
18
|
+
### Getting started
|
19
|
+
|
20
|
+
* Follow the simple [installation](https://github.com/skozlov/netzke-core/wiki/Installation) steps.
|
21
|
+
* Learn how to build the [Hello World!](https://github.com/skozlov/netzke-core/wiki/Hello-world-extjs) component.
|
22
|
+
* Dive into the [documentation](https://github.com/skozlov/netzke/wiki).
|
23
|
+
* Get help on the [Google Groups](http://groups.google.com/group/netzke).
|
24
|
+
|
25
|
+
### Sencha Touch support
|
26
|
+
|
27
|
+
Netzke Core has support for Sencha Touch, so you can create components for mobile web apps as easily.
|
28
|
+
|
29
|
+
* Learn how to build the [Hello World!](https://github.com/skozlov/netzke-core/wiki/Hello-world-touch) Sencha Touch component.
|
30
|
+
|
31
|
+
### Testing and playing with Netzke Core
|
32
|
+
|
33
|
+
Netzke Core is bundled with Cucumber and RSpec tests. If you would like to contribute to the project, you may want to learn how to [run the tests](https://github.com/skozlov/netzke-core/wiki/Automated-testing).
|
34
|
+
|
35
|
+
Besides, the bundled test application is a convenient [playground](https://github.com/skozlov/netzke-core/wiki/Playground) for those who search to experiment with the framework.
|
36
|
+
|
37
|
+
### Useful links
|
38
|
+
* [Project website](http://netzke.org).
|
39
|
+
* [Documentation](https://github.com/skozlov/netzke/wiki).
|
40
|
+
* [Live-demo](http://demo.netzke.org) (with sample code).
|
41
|
+
* [Twitter](http://twitter.com/skozlov).
|
42
|
+
|
43
|
+
*Copyright (c) 2008-2010 Sergei Kozlov, released under the MIT license*
|
data/TODO
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
|
1
|
+
Caching for netzke_controller-provided JS and CSS.
|
2
2
|
Caching - investigate reusing (fragment?) caching of Rails.
|
3
3
|
Use Ext.Direct in the Netzke controller.
|
4
4
|
Let specify per API point if it will use a GET or a POST request.
|
5
|
-
Re-work generators
|
6
|
-
|
7
|
-
Some day
|
8
|
-
* make gzipping generated JS code possible
|
9
5
|
|
10
6
|
|
11
7
|
= Ideas that didn't work out
|
@@ -3,41 +3,73 @@ class NetzkeController < ApplicationController
|
|
3
3
|
# Collect javascripts and stylesheets from all plugins that registered it in Netzke::Core.javascripts
|
4
4
|
# TODO: caching
|
5
5
|
# caches_action :netzke
|
6
|
-
def
|
6
|
+
def ext
|
7
7
|
respond_to do |format|
|
8
8
|
format.js {
|
9
9
|
res = initial_dynamic_javascript << "\n"
|
10
|
-
|
10
|
+
|
11
|
+
# Core JavaScript
|
12
|
+
res << File.new(File.expand_path("../../../javascripts/core.js", __FILE__)).read
|
13
|
+
# Ext-specific JavaScript
|
14
|
+
res << File.new(File.expand_path("../../../javascripts/ext.js", __FILE__)).read
|
15
|
+
|
16
|
+
# Pluggable JavaScript (used by other Netzke-powered gems like netzke-basepack)
|
17
|
+
Netzke::Core.ext_javascripts.each do |path|
|
11
18
|
f = File.new(path)
|
12
19
|
res << f.read
|
13
20
|
end
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
render :text => defined?(::Rails) && ::Rails.env.production? ? res.strip_js_comments : res
|
23
|
+
}
|
24
|
+
|
25
|
+
format.css {
|
26
|
+
res = File.new(File.expand_path("../../../stylesheets/core.css", __FILE__)).read
|
27
|
+
|
28
|
+
# Pluggable stylesheets (may be used by other Netzke-powered gems like netzke-basepack)
|
29
|
+
Netzke::Core.ext_stylesheets.each do |path|
|
30
|
+
f = File.new(path)
|
31
|
+
res << f.read
|
32
|
+
end
|
33
|
+
|
34
|
+
render :text => res
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def touch
|
40
|
+
respond_to do |format|
|
41
|
+
format.js {
|
42
|
+
res = initial_dynamic_javascript << "\n"
|
43
|
+
|
44
|
+
# Core JavaScript
|
45
|
+
res << File.new(File.expand_path("../../../javascripts/core.js", __FILE__)).read
|
46
|
+
# Touch-specific JavaScript
|
47
|
+
res << File.new(File.expand_path("../../../javascripts/touch.js", __FILE__)).read
|
48
|
+
|
49
|
+
# Pluggable JavaScript (may be used by other Netzke-powered gems like netzke-basepack)
|
50
|
+
Netzke::Core.touch_javascripts.each do |path|
|
51
|
+
f = File.new(path)
|
52
|
+
res << f.read
|
25
53
|
end
|
26
54
|
|
27
55
|
render :text => defined?(::Rails) && ::Rails.env.production? ? res.strip_js_comments : res
|
28
56
|
}
|
29
57
|
|
30
58
|
format.css {
|
31
|
-
res = ""
|
32
|
-
|
59
|
+
res = File.new(File.expand_path("../../../stylesheets/core.css", __FILE__)).read
|
60
|
+
|
61
|
+
# Pluggable stylesheets (may be used by other Netzke-powered gems like netzke-basepack)
|
62
|
+
Netzke::Core.touch_stylesheets.each do |path|
|
33
63
|
f = File.new(path)
|
34
64
|
res << f.read
|
35
65
|
end
|
66
|
+
|
36
67
|
render :text => res
|
37
68
|
}
|
38
69
|
end
|
39
70
|
end
|
40
71
|
|
72
|
+
|
41
73
|
# Main dispatcher of the HTTP requests. The URL contains the name of the component,
|
42
74
|
# as well as the method of this component to be called, according to the double underscore notation.
|
43
75
|
# E.g.: some_grid__post_grid_data.
|
@@ -67,4 +99,4 @@ class NetzkeController < ApplicationController
|
|
67
99
|
res.join("\n")
|
68
100
|
end
|
69
101
|
|
70
|
-
end
|
102
|
+
end
|
data/config/database.yml
ADDED
@@ -19,7 +19,6 @@ Feature: Component loader
|
|
19
19
|
When I press "Load with feedback"
|
20
20
|
Then I should see "Callback invoked!"
|
21
21
|
|
22
|
-
|
23
22
|
@selenium
|
24
23
|
Scenario: Component loader should load a window component with another component in it
|
25
24
|
Given I am on the ComponentLoader test page
|
@@ -27,4 +26,10 @@ Feature: Component loader
|
|
27
26
|
Then I should see "Simple Component Inside Window"
|
28
27
|
And I should see "Inner text"
|
29
28
|
|
29
|
+
@selenium
|
30
|
+
Scenario: Component loader should load a component with params properly
|
31
|
+
Given I am on the ComponentLoader test page
|
32
|
+
When I press "Load with params"
|
33
|
+
Then I should see "Simple Component with changed HTML"
|
34
|
+
|
30
35
|
|
@@ -23,9 +23,11 @@ Feature: Composition
|
|
23
23
|
Scenario: Server should be able to address (deeply) nested components
|
24
24
|
Given I am on the SomeComposite test page
|
25
25
|
When I press "Update west from server"
|
26
|
+
And I sleep 1 second
|
26
27
|
Then I should see "Here's an update for west panel"
|
27
28
|
|
28
29
|
When I press "Update east south from server"
|
30
|
+
And I sleep 1 second
|
29
31
|
Then I should see "Here's an update for south panel in east panel"
|
30
32
|
|
31
33
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: JsMixins
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: ComponentWithJsMixin should behave
|
8
|
+
Given I am on the ComponentWithJsMixin test page
|
9
|
+
When I press "Action one"
|
10
|
+
Then I should see "Action One triggered!"
|
11
|
+
When I press "Action two"
|
12
|
+
Then I should see "Action Two triggered!"
|
13
|
+
|
14
|
+
@javascript
|
15
|
+
Scenario: ExtendedComponentWithJsMixin should behave, too
|
16
|
+
Given I am on the ExtendedComponentWithJsMixin test page
|
17
|
+
When I press "Action three"
|
18
|
+
Then I should see "Action Three triggered!"
|
@@ -6,11 +6,13 @@ Feature: Persistence
|
|
6
6
|
@javascript
|
7
7
|
Scenario: The component with persistence should be able to store and retrieve a persistence setting
|
8
8
|
When I go to the ComponentWithSessionPersistence test page
|
9
|
-
Then I should see "
|
9
|
+
Then I should see "Default Title"
|
10
|
+
And I should see "Default HTML"
|
11
|
+
But I should not see "Title From Session"
|
12
|
+
And I should not see "HTML from session"
|
10
13
|
|
11
14
|
When I press "Tell server to store new title"
|
12
15
|
And I go to the ComponentWithSessionPersistence test page
|
13
|
-
Then I should see "
|
14
|
-
|
15
|
-
|
16
|
+
Then I should see "Title From Session"
|
17
|
+
And I should see "HTML from session"
|
16
18
|
|
data/features/support/paths.rb
CHANGED
data/javascripts/core.js
CHANGED
@@ -11,7 +11,7 @@ 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
12
|
|
13
13
|
Netzke.isLoading=function () {
|
14
|
-
|
14
|
+
return Netzke.runningRequests!=0;
|
15
15
|
}
|
16
16
|
Netzke.runningRequests=0
|
17
17
|
|
@@ -23,25 +23,17 @@ Netzke.deprecationWarning = function(msg){
|
|
23
23
|
}
|
24
24
|
};
|
25
25
|
|
26
|
-
// Check Ext JS version
|
27
|
-
(function(){
|
28
|
-
var requiredExtVersion = "3.3.0";
|
29
|
-
var currentExtVersion = Ext.version;
|
30
|
-
if (requiredExtVersion !== currentExtVersion) {
|
31
|
-
Netzke.deprecationWarning("Netzke needs Ext " + requiredExtVersion + ". You have " + currentExtVersion + ".");
|
32
|
-
}
|
33
|
-
})();
|
34
|
-
|
35
26
|
Ext.ns('Netzke.page'); // namespace for all component instantces on the page
|
36
27
|
Ext.ns('Netzke.classes'); // namespace for all component classes
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
Ext.
|
42
|
-
|
43
|
-
|
44
|
-
|
28
|
+
Ext.ns('Netzke.classes.Core'); // namespace for all component classes
|
29
|
+
|
30
|
+
Netzke.chainApply = function(){
|
31
|
+
var res = {};
|
32
|
+
Ext.each(arguments, function(o){
|
33
|
+
Ext.apply(res, o);
|
34
|
+
});
|
35
|
+
return res;
|
36
|
+
};
|
45
37
|
|
46
38
|
// Some Ruby-ish String extensions
|
47
39
|
// from http://code.google.com/p/inflection-js/
|
@@ -84,532 +76,179 @@ String.prototype.underscore = function() {
|
|
84
76
|
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
|
85
77
|
.replace(/-/g, '_')
|
86
78
|
.toLowerCase();
|
87
|
-
}
|
79
|
+
};
|
88
80
|
|
89
81
|
// Usefull when using mixins
|
90
82
|
Netzke.aliasMethodChain = function(klass, method, feature) {
|
91
83
|
klass[method + "Without" + feature.capitalize()] = klass[method];
|
92
84
|
klass[method] = klass[method + "With" + feature.capitalize()];
|
93
|
-
}
|
94
|
-
|
95
|
-
// Properties/methods common to all component classes
|
96
|
-
Netzke.componentMixin = function(receiver){
|
97
|
-
return {
|
98
|
-
height: 400,
|
99
|
-
border: false,
|
100
|
-
isNetzke: true, // to distinguish Netzke components from regular Ext components
|
101
|
-
latestResult: {}, // latest result returned from the server via an API call
|
102
|
-
|
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
|
-
|
111
|
-
/* initComponent common for all Netzke components */
|
112
|
-
initComponentWithNetzke : function(){
|
113
|
-
this.normalizeActions();
|
114
|
-
|
115
|
-
this.detectActions(this);
|
116
|
-
|
117
|
-
this.detectComponents(this.items);
|
85
|
+
};
|
118
86
|
|
119
|
-
|
87
|
+
Netzke.cache = [];
|
120
88
|
|
121
|
-
|
89
|
+
// Registering a Netzke component
|
90
|
+
Netzke.reg = function(xtype, klass) {
|
91
|
+
if (!Ext.ComponentMgr.types[xtype]) {
|
92
|
+
Ext.reg(xtype, klass);
|
93
|
+
Netzke.cache.push(xtype);
|
94
|
+
}
|
95
|
+
};
|
122
96
|
|
123
|
-
|
124
|
-
this.callbackHash = {};
|
97
|
+
Netzke.classes.Core.Mixin = {};
|
125
98
|
|
126
|
-
|
127
|
-
|
99
|
+
// Properties/methods common to all Netzke component classes
|
100
|
+
Netzke.componentMixin = Ext.applyIf(Netzke.classes.Core.Mixin, {
|
101
|
+
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
|
+
// },
|
128
110
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
}
|
140
|
-
}
|
111
|
+
/*
|
112
|
+
Dynamically creates methods for api points, so that we could later call them like: this.myEndpointMethod()
|
113
|
+
*/
|
114
|
+
processEndpoints: function(){
|
115
|
+
var endpoints = this.endpoints || [];
|
116
|
+
endpoints.push('deliver_component'); // all Netzke components get this endpoint
|
117
|
+
Ext.each(endpoints, function(intp){
|
118
|
+
this[intp.camelize(true)] = function(args, callback, scope){ this.callServer(intp, args, callback, scope); }
|
119
|
+
}, this);
|
120
|
+
},
|
141
121
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
122
|
+
/*
|
123
|
+
Detects component placeholders in the passed object (typically, "items"),
|
124
|
+
and merges them with the corresponding config from this.components.
|
125
|
+
This way it becomes ready to be instantiated properly by Ext.
|
126
|
+
*/
|
127
|
+
detectComponents: function(o){
|
128
|
+
if (Ext.isObject(o)) {
|
129
|
+
if (o.items) this.detectComponents(o.items);
|
130
|
+
} else if (Ext.isArray(o)) {
|
131
|
+
var a = o;
|
132
|
+
Ext.each(a, function(el, i){
|
133
|
+
if (el.component) {
|
134
|
+
a[i] = Ext.apply(this.components[el.component.camelize(true)], el);
|
135
|
+
delete a[i].component;
|
136
|
+
} else if (el.items) this.detectComponents(el.items);
|
157
137
|
}, this);
|
158
|
-
}
|
159
|
-
|
160
|
-
normalizeTools: function() {
|
161
|
-
if (this.tools) {
|
162
|
-
var normTools = [];
|
163
|
-
Ext.each(this.tools, function(tool){
|
164
|
-
// Create an event for each action (so that higher-level components could interfere)
|
165
|
-
this.addEvents(tool.id+'click');
|
166
|
-
|
167
|
-
var handler = this.toolActionHandler.createDelegate(this, [tool]);
|
168
|
-
normTools.push({id : tool, handler : handler, scope : this});
|
169
|
-
}, this);
|
170
|
-
this.tools = normTools;
|
171
|
-
}
|
172
|
-
},
|
173
|
-
|
174
|
-
/*
|
175
|
-
Replaces actions configs with Ext.Action instances, assigning default handler to them
|
176
|
-
*/
|
177
|
-
normalizeActions : function(){
|
178
|
-
var normActions = {};
|
179
|
-
for (var name in this.actions) {
|
180
|
-
// Create an event for each action (so that higher-level components could interfere)
|
181
|
-
this.addEvents(name+'click');
|
182
|
-
|
183
|
-
// Configure the action
|
184
|
-
var actionConfig = this.actions[name];
|
185
|
-
actionConfig.customHandler = actionConfig.handler;
|
186
|
-
actionConfig.handler = this.actionHandler.createDelegate(this); // handler common for all actions
|
187
|
-
actionConfig.name = name;
|
188
|
-
normActions[name] = new Ext.Action(actionConfig);
|
189
|
-
}
|
190
|
-
delete(this.actions);
|
191
|
-
this.actions = normActions;
|
192
|
-
},
|
193
|
-
|
194
|
-
/*
|
195
|
-
Detects action configs in the passed object, and replaces them with instances of Ext.Action created by normalizeActions().
|
196
|
-
This detects action in arbitrary level of nesting, which means you can put any other components in your toolbar, and inside of them specify menus/items or even toolbars.
|
197
|
-
*/
|
198
|
-
detectActions: function(o){
|
199
|
-
if (Ext.isObject(o)) {
|
200
|
-
if ((typeof o.handler === 'string') && Ext.isFunction(this[o.handler.camelize(true)])) {
|
201
|
-
// This button config has a handler specified as string - replace it with reference to a real function if it exists
|
202
|
-
o.handler = this[o.handler.camelize(true)].createDelegate(this);
|
203
|
-
}
|
204
|
-
// TODO: this should be configurable!
|
205
|
-
Ext.each(["bbar", "tbar", "fbar", "menu", "items", "contextMenu", "buttons"], function(key){
|
206
|
-
if (o[key]) {
|
207
|
-
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
|
208
|
-
delete(o[key]);
|
209
|
-
o[key] = items;
|
210
|
-
this.detectActions(o[key]);
|
211
|
-
}
|
212
|
-
}, this);
|
213
|
-
} else if (Ext.isArray(o)) {
|
214
|
-
var a = o;
|
215
|
-
Ext.each(a, function(el, i){
|
216
|
-
if (Ext.isObject(el)) {
|
217
|
-
if (el.action) {
|
218
|
-
if (!this.actions[el.action.camelize(true)]) throw "Netzke: action '"+el.action+"' not defined";
|
219
|
-
a[i] = this.actions[el.action.camelize(true)];
|
220
|
-
delete(el);
|
221
|
-
} else {
|
222
|
-
this.detectActions(el);
|
223
|
-
}
|
224
|
-
}
|
225
|
-
}, this);
|
226
|
-
}
|
227
|
-
},
|
228
|
-
|
229
|
-
/*
|
230
|
-
Detects component placeholders in the passed object (typically, "items"),
|
231
|
-
and merges them with the corresponding config from this.components.
|
232
|
-
This way it becomes ready to be instantiated properly by Ext.
|
233
|
-
*/
|
234
|
-
detectComponents: function(o){
|
235
|
-
if (Ext.isObject(o)) {
|
236
|
-
if (o.items) this.detectComponents(o.items);
|
237
|
-
} else if (Ext.isArray(o)) {
|
238
|
-
var a = o;
|
239
|
-
Ext.each(a, function(el, i){
|
240
|
-
if (el.component) {
|
241
|
-
a[i] = Ext.apply(this.components[el.component.camelize(true)], el);
|
242
|
-
delete a[i].component;
|
243
|
-
} else if (el.items) this.detectComponents(el.items);
|
244
|
-
}, this);
|
245
|
-
}
|
246
|
-
},
|
247
|
-
|
248
|
-
/*
|
249
|
-
Loads a component. Config options:
|
250
|
-
'name' (required) - the name of the child component to load
|
251
|
-
'container' - the id of a panel with the 'fit' layout where the loaded component will be instantiated
|
252
|
-
'callback' - function that gets called after the component is loaded. It receives the component's instance as parameter.
|
253
|
-
'scope' - scope for the callback.
|
254
|
-
*/
|
255
|
-
loadComponent: function(params){
|
256
|
-
if (params.id) {
|
257
|
-
params.name = params.id;
|
258
|
-
Netzke.deprecationWarning("Using 'id' in loadComponent is deprecated. Use 'name' instead.");
|
259
|
-
}
|
260
|
-
|
261
|
-
params.name = params.name.underscore();
|
262
|
-
|
263
|
-
// 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.
|
264
|
-
var serverParams = params.params || {};
|
265
|
-
serverParams.name = params.name;
|
266
|
-
|
267
|
-
// Build the list of already loaded ("cached") classes
|
268
|
-
serverParams.cache = [];
|
269
|
-
|
270
|
-
for (var klass in Netzke.classes) {
|
271
|
-
serverParams.cache.push(klass);
|
272
|
-
}
|
273
|
-
|
274
|
-
serverParams.cache = serverParams.cache.join();
|
275
|
-
|
276
|
-
var storedConfig = this.componentsBeingLoaded[params.name] = {};
|
277
|
-
|
278
|
-
// Remember where the loaded component should be inserted into
|
279
|
-
if (params.container) {
|
280
|
-
storedConfig.container = params.container;
|
281
|
-
}
|
282
|
-
|
283
|
-
// remember the passed callback for the future (per loaded component, as there may be simultaneous ongoing calls)
|
284
|
-
if (params.callback) {
|
285
|
-
storedConfig.callback = params.callback;
|
286
|
-
storedConfig.scope = params.scope;
|
287
|
-
// this.callbackHash[params.name.underscore()] = params.callback;
|
288
|
-
}
|
289
|
-
|
290
|
-
// remove the old component if the container is specified
|
291
|
-
if (params.container) Ext.getCmp(params.container).removeChild();
|
138
|
+
}
|
139
|
+
},
|
292
140
|
|
293
|
-
|
294
|
-
|
295
|
-
|
141
|
+
/*
|
142
|
+
Evaluates CSS
|
143
|
+
*/
|
144
|
+
evalCss : function(code){
|
145
|
+
var head = Ext.fly(document.getElementsByTagName('head')[0]);
|
146
|
+
Ext.DomHelper.append(head, {
|
147
|
+
tag: 'style',
|
148
|
+
type: 'text/css',
|
149
|
+
html: code
|
150
|
+
});
|
151
|
+
},
|
296
152
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
delete this.componentsBeingLoaded[config.name];
|
153
|
+
/*
|
154
|
+
Evaluates JS
|
155
|
+
*/
|
156
|
+
evalJs : function(code){
|
157
|
+
eval(code);
|
158
|
+
},
|
304
159
|
|
305
|
-
|
160
|
+
/*
|
161
|
+
Gets id in the context of provided parent.
|
162
|
+
For example, the components "properties", being a child of "books" has global id "books__properties",
|
163
|
+
which *is* its widegt's real id. This methods, with the instance of "books" passed as parameter,
|
164
|
+
returns "properties".
|
165
|
+
*/
|
166
|
+
localId : function(parent){
|
167
|
+
return this.id.replace(parent.id + "__", "");
|
168
|
+
},
|
306
169
|
|
307
|
-
|
308
|
-
|
309
|
-
|
170
|
+
/*
|
171
|
+
Executes a bunch of methods. This method is called almost every time a communication to the server takes place.
|
172
|
+
Thus the server side of a component can provide any set of commands to its client side.
|
173
|
+
Args:
|
174
|
+
- instructions: array of methods, in the order of execution.
|
175
|
+
Each item is an object in one of the following 2 formats:
|
176
|
+
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
|
177
|
+
2) {component:component_id, methods:arrayOfMethods}, used for recursive call to bulkExecute on some child component
|
178
|
+
|
179
|
+
Example:
|
180
|
+
- [
|
181
|
+
// the same as this.feedback("Your order is accepted")
|
182
|
+
{feedback: "You order is accepted"},
|
183
|
+
|
184
|
+
// the same as this.getChildComponent('users').bulkExecute([{setTitle:'Suprise!'}, {setDisabled:true}])
|
185
|
+
{component:'users', methods:[{setTitle:'Suprise!'}, {setDisabled:true}] },
|
186
|
+
|
187
|
+
// ... etc:
|
188
|
+
{updateStore:{records:[[1, 'Name1'],[2, 'Name2']], total:10}},
|
189
|
+
{setColums:[{},{}]},
|
190
|
+
{setMenus:[{},{}]},
|
191
|
+
...
|
192
|
+
]
|
193
|
+
*/
|
194
|
+
bulkExecute : function(instructions){
|
195
|
+
if (Ext.isArray(instructions)) {
|
196
|
+
Ext.each(instructions, function(instruction){ this.bulkExecute(instruction)}, this);
|
197
|
+
} else {
|
198
|
+
for (var instr in instructions) {
|
199
|
+
if (Ext.isFunction(this[instr])) {
|
200
|
+
// Executing the method. If arguments are an array, expand that into arguments.
|
201
|
+
this[instr].apply(this, Ext.isArray(instructions[instr]) ? instructions[instr] : [instructions[instr]]);
|
310
202
|
} else {
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
if (storedConfig.callback) {
|
315
|
-
storedConfig.callback.call(storedConfig.scope || this, componentInstance);
|
316
|
-
}
|
317
|
-
}
|
318
|
-
},
|
319
|
-
|
320
|
-
/*
|
321
|
-
Instantiates and inserts a component into a container with layout 'fit'.
|
322
|
-
Arg: an JS object with the following keys:
|
323
|
-
- id: id of the receiving container
|
324
|
-
- config: configuration of the component to be instantiated and inserted into the container
|
325
|
-
*/
|
326
|
-
// renderComponentInContainer : function(params){
|
327
|
-
// var cont = Ext.getCmp(params.container);
|
328
|
-
// if (cont) {
|
329
|
-
// cont.instantiateChild(params.config);
|
330
|
-
// } else {
|
331
|
-
// this.instantiateChild(params.config);
|
332
|
-
// }
|
333
|
-
// },
|
334
|
-
|
335
|
-
/*
|
336
|
-
Returns the parent component
|
337
|
-
*/
|
338
|
-
getParent: function(){
|
339
|
-
// simply cutting the last part of the id: some_parent__a_kid__a_great_kid => some_parent__a_kid
|
340
|
-
var idSplit = this.id.split("__");
|
341
|
-
idSplit.pop();
|
342
|
-
var parentId = idSplit.join("__");
|
343
|
-
|
344
|
-
return parentId === "" ? null : Ext.getCmp(parentId);
|
345
|
-
},
|
346
|
-
|
347
|
-
/*
|
348
|
-
Reloads current component (calls the parent to reload it as its component)
|
349
|
-
*/
|
350
|
-
reload : function(){
|
351
|
-
var parent = this.getParent();
|
352
|
-
if (parent) {
|
353
|
-
parent.loadComponent({id:this.localId(parent), container:this.ownerCt.id});
|
354
|
-
} else {
|
355
|
-
window.location.reload();
|
356
|
-
}
|
357
|
-
},
|
358
|
-
|
359
|
-
/*
|
360
|
-
Gets id in the context of provided parent.
|
361
|
-
For example, the components "properties", being a child of "books" has global id "books__properties",
|
362
|
-
which *is* its widegt's real id. This methods, with the instance of "books" passed as parameter,
|
363
|
-
returns "properties".
|
364
|
-
*/
|
365
|
-
localId : function(parent){
|
366
|
-
return this.id.replace(parent.id + "__", "");
|
367
|
-
},
|
368
|
-
|
369
|
-
/*
|
370
|
-
Reconfigures the component
|
371
|
-
*/
|
372
|
-
reconfigure: function(config){
|
373
|
-
this.ownerCt.instantiateChild(config)
|
374
|
-
},
|
375
|
-
|
376
|
-
/*
|
377
|
-
Evaluates CSS
|
378
|
-
*/
|
379
|
-
evalCss : function(code){
|
380
|
-
var linkTag = document.createElement('style');
|
381
|
-
linkTag.type = 'text/css';
|
382
|
-
linkTag.innerHTML = code;
|
383
|
-
document.body.appendChild(linkTag);
|
384
|
-
},
|
385
|
-
|
386
|
-
/*
|
387
|
-
Evaluates JS
|
388
|
-
*/
|
389
|
-
evalJs : function(code){
|
390
|
-
eval(code);
|
391
|
-
},
|
392
|
-
|
393
|
-
/*
|
394
|
-
Executes a bunch of methods. This method is called almost every time a communication to the server takes place.
|
395
|
-
Thus the server side of a component can provide any set of commands to its client side.
|
396
|
-
Args:
|
397
|
-
- instructions: array of methods, in the order of execution.
|
398
|
-
Each item is an object in one of the following 2 formats:
|
399
|
-
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
|
400
|
-
2) {component:component_id, methods:arrayOfMethods}, used for recursive call to bulkExecute on some child component
|
401
|
-
|
402
|
-
Example:
|
403
|
-
- [
|
404
|
-
// the same as this.feedback("Your order is accepted")
|
405
|
-
{feedback: "You order is accepted"},
|
406
|
-
|
407
|
-
// the same as this.getChildComponent('users').bulkExecute([{setTitle:'Suprise!'}, {setDisabled:true}])
|
408
|
-
{component:'users', methods:[{setTitle:'Suprise!'}, {setDisabled:true}] },
|
409
|
-
|
410
|
-
// ... etc:
|
411
|
-
{updateStore:{records:[[1, 'Name1'],[2, 'Name2']], total:10}},
|
412
|
-
{setColums:[{},{}]},
|
413
|
-
{setMenus:[{},{}]},
|
414
|
-
...
|
415
|
-
]
|
416
|
-
*/
|
417
|
-
bulkExecute : function(instructions){
|
418
|
-
if (Ext.isArray(instructions)) {
|
419
|
-
Ext.each(instructions, function(instruction){ this.bulkExecute(instruction)}, this);
|
420
|
-
} else {
|
421
|
-
for (var instr in instructions) {
|
422
|
-
if (Ext.isFunction(this[instr])) {
|
423
|
-
this[instr].apply(this, [instructions[instr]]); // execute the method
|
203
|
+
var childComponent = this.getChildComponent(instr);
|
204
|
+
if (childComponent) {
|
205
|
+
childComponent.bulkExecute(instructions[instr]);
|
424
206
|
} else {
|
425
|
-
|
426
|
-
if (childComponent) {
|
427
|
-
childComponent.bulkExecute(instructions[instr]);
|
428
|
-
} else {
|
429
|
-
throw "Netzke: Unknown method or child component '" + instr +"' in component '" + this.id + "'"
|
430
|
-
}
|
207
|
+
throw "Netzke: Unknown method or child component '" + instr +"' in component '" + this.id + "'"
|
431
208
|
}
|
432
209
|
}
|
433
210
|
}
|
434
|
-
}
|
435
|
-
|
436
|
-
// Get the child component
|
437
|
-
getChildComponent : function(id){
|
438
|
-
if (id === "") {return this};
|
439
|
-
id = id.underscore();
|
440
|
-
var split = id.split("__");
|
441
|
-
if (split[0] === 'parent') {
|
442
|
-
split.shift();
|
443
|
-
var childInParentScope = split.join("__");
|
444
|
-
return this.getParent().getChildComponent(childInParentScope);
|
445
|
-
} else {
|
446
|
-
return Ext.getCmp(this.id+"__"+id);
|
447
|
-
}
|
448
|
-
},
|
449
|
-
|
450
|
-
// Common handler for all component's actions. <tt>comp</tt> is the Component that triggered the action (e.g. button or menu item)
|
451
|
-
// actionHandler : function(comp){
|
452
|
-
// var actionName = comp.name;
|
453
|
-
// // If firing corresponding event doesn't return false, call the handler
|
454
|
-
// if (this.fireEvent(actionName+'click', comp)) {
|
455
|
-
// var action = this.actions[actionName];
|
456
|
-
// var customHandler = action.initialConfig.customHandler;
|
457
|
-
// var methodName = (customHandler && customHandler.camelize(true)) || "on" + actionName.camelize();
|
458
|
-
// if (!this[methodName]) {throw "Netzke: action handler '" + methodName + "' is undefined"}
|
459
|
-
//
|
460
|
-
// // call the handler passing it the triggering component
|
461
|
-
// this[methodName](comp);
|
462
|
-
// }
|
463
|
-
// },
|
464
|
-
//
|
465
|
-
// // Common handler for tools
|
466
|
-
// toolActionHandler : function(tool){
|
467
|
-
// // If firing corresponding event doesn't return false, call the handler
|
468
|
-
// if (this.fireEvent(tool.id+'click')) {
|
469
|
-
// var methodName = "on"+tool.camelize();
|
470
|
-
// if (!this[methodName]) {throw "Netzke: handler for tool '"+tool+"' is undefined"}
|
471
|
-
// this[methodName]();
|
472
|
-
// }
|
473
|
-
// },
|
474
|
-
|
475
|
-
// Returns API url based on provided API point
|
476
|
-
buildApiUrl: function(endpoint){
|
477
|
-
Netzke.deprecationWarning("buildApiUrl() is deprecated. Use endpointUrl() first");
|
478
|
-
return this.endpointUrl(endpoint);
|
479
|
-
},
|
480
|
-
|
481
|
-
endpointUrl: function(endpoint){
|
482
|
-
return Netzke.RelativeUrlRoot + "/netzke/" + this.id + "__" + endpoint;
|
483
|
-
},
|
484
|
-
|
485
|
-
// Does the call to the server and processes the response
|
486
|
-
callServer : function(intp, params, callback, scope){
|
487
|
-
Netzke.runningRequests++;
|
488
|
-
if (!params) params = {};
|
489
|
-
Ext.Ajax.request({
|
490
|
-
params: params,
|
491
|
-
url: this.endpointUrl(intp),
|
492
|
-
callback: function(options, success, response){
|
493
|
-
if (success && response.responseText) {
|
494
|
-
// execute commands from server
|
495
|
-
this.bulkExecute(Ext.decode(response.responseText));
|
496
|
-
|
497
|
-
// provide callback if needed
|
498
|
-
if (typeof callback == 'function') {
|
499
|
-
if (!scope) scope = this;
|
500
|
-
callback.apply(scope, [this.latestResult]);
|
501
|
-
}
|
502
|
-
}
|
503
|
-
},
|
504
|
-
scope : this
|
505
|
-
});
|
506
|
-
Netzke.runningRequests--;
|
507
|
-
},
|
508
|
-
|
509
|
-
setResult: function(result) {
|
510
|
-
this.latestResult = result;
|
511
|
-
},
|
512
|
-
|
513
|
-
// At this moment component is fully initializied
|
514
|
-
commonAfterConstructor : function(config){
|
515
|
-
|
516
|
-
// Add the menus
|
517
|
-
if (this.initialConfig.menu) {this.addMenu(this.initialConfig.menu, this);}
|
518
|
-
|
519
|
-
// generic events
|
520
|
-
this.addEvents(
|
521
|
-
'componentload' // fired when a child is dynamically loaded
|
522
|
-
);
|
523
|
-
|
524
|
-
// Cleaning up on destroy
|
525
|
-
this.on('beforedestroy', function(){
|
526
|
-
this.cleanUpMenu();
|
527
|
-
}, this);
|
528
|
-
|
529
|
-
this.callbackHash = {};
|
211
|
+
}
|
212
|
+
},
|
530
213
|
|
531
|
-
|
532
|
-
|
214
|
+
// Returns API url based on provided API point
|
215
|
+
buildApiUrl: function(endpoint){
|
216
|
+
Netzke.deprecationWarning("buildApiUrl() is deprecated. Use endpointUrl() instead.");
|
217
|
+
return this.endpointUrl(endpoint);
|
218
|
+
},
|
533
219
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
}
|
220
|
+
endpointUrl: function(endpoint){
|
221
|
+
return Netzke.RelativeUrlRoot + "/netzke/" + this.id + "__" + endpoint;
|
222
|
+
},
|
538
223
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
224
|
+
// Does the call to the server and processes the response
|
225
|
+
callServer : function(intp, params, callback, scope){
|
226
|
+
Netzke.runningRequests++;
|
227
|
+
if (!params) params = {};
|
228
|
+
Ext.Ajax.request({
|
229
|
+
params: params,
|
230
|
+
url: this.endpointUrl(intp),
|
231
|
+
callback: function(options, success, response){
|
232
|
+
if (success && response.responseText) {
|
233
|
+
// execute commands from server
|
234
|
+
this.bulkExecute(Ext.decode(response.responseText));
|
235
|
+
|
236
|
+
// provide callback if needed
|
237
|
+
if (typeof callback == 'function') {
|
238
|
+
if (!scope) scope = this;
|
239
|
+
callback.apply(scope, [this.latestResult]);
|
552
240
|
}
|
553
241
|
}
|
554
|
-
}
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
// owner = this;
|
560
|
-
// }
|
561
|
-
//
|
562
|
-
// if (!!this.hostMenu) {
|
563
|
-
// this.hostMenu(menu, owner);
|
564
|
-
// } else {
|
565
|
-
// if (this.ownerComponent) {
|
566
|
-
// this.ownerComponent.addMenu(menu, owner);
|
567
|
-
// }
|
568
|
-
// }
|
569
|
-
// },
|
570
|
-
//
|
571
|
-
// cleanUpMenu : function(owner){
|
572
|
-
// if (!owner) {
|
573
|
-
// owner = this;
|
574
|
-
// }
|
575
|
-
//
|
576
|
-
// if (!!this.unhostMenu) {
|
577
|
-
// this.unhostMenu(owner);
|
578
|
-
// } else {
|
579
|
-
// if (this.ownerComponent) {
|
580
|
-
// this.ownerComponent.cleanUpMenu(owner);
|
581
|
-
// }
|
582
|
-
// }
|
583
|
-
// },
|
584
|
-
|
585
|
-
// Common handler for all component's actions. <tt>comp</tt> is the Component that triggered the action (e.g. button or menu item)
|
586
|
-
actionHandler : function(comp){
|
587
|
-
var actionName = comp.name;
|
588
|
-
// If firing corresponding event doesn't return false, call the handler
|
589
|
-
if (this.fireEvent(actionName+'click', comp)) {
|
590
|
-
var action = this.actions[actionName];
|
591
|
-
var customHandler = action.initialConfig.customHandler;
|
592
|
-
var methodName = (customHandler && customHandler.camelize(true)) || "on" + actionName.camelize();
|
593
|
-
if (!this[methodName]) {throw "Netzke: action handler '" + methodName + "' is undefined"}
|
594
|
-
|
595
|
-
// call the handler passing it the triggering component
|
596
|
-
this[methodName](comp);
|
597
|
-
}
|
598
|
-
},
|
599
|
-
|
600
|
-
// Common handler for tools
|
601
|
-
toolActionHandler : function(tool){
|
602
|
-
// If firing corresponding event doesn't return false, call the handler
|
603
|
-
if (this.fireEvent(tool.id+'click')) {
|
604
|
-
var methodName = "on"+tool.camelize();
|
605
|
-
if (!this[methodName]) {throw "Netzke: handler for tool '"+tool+"' is undefined"}
|
606
|
-
this[methodName]();
|
607
|
-
}
|
608
|
-
},
|
242
|
+
},
|
243
|
+
scope : this
|
244
|
+
});
|
245
|
+
Netzke.runningRequests--;
|
246
|
+
},
|
609
247
|
|
610
|
-
|
248
|
+
setResult: function(result) {
|
249
|
+
this.latestResult = result;
|
611
250
|
}
|
612
|
-
}
|
251
|
+
});
|
613
252
|
|
614
253
|
|
615
254
|
// Netzke extensions for Ext.Container
|
@@ -623,7 +262,14 @@ Ext.override(Ext.Container, {
|
|
623
262
|
} else {
|
624
263
|
this.remove(this.getNetzkeComponent()); // first delete previous component
|
625
264
|
this.add(instance);
|
626
|
-
|
265
|
+
|
266
|
+
// Sometimes a child is getting loaded into a hidden container...
|
267
|
+
if (this.isVisible()) {
|
268
|
+
this.doLayout();
|
269
|
+
} else {
|
270
|
+
this.on('show', function(cmp){cmp.doLayout();}, {single: true});
|
271
|
+
}
|
272
|
+
|
627
273
|
}
|
628
274
|
return instance;
|
629
275
|
},
|
@@ -654,7 +300,6 @@ Ext.override(Ext.Container, {
|
|
654
300
|
removeChild : function(){
|
655
301
|
this.remove(this.getNetzkeComponent());
|
656
302
|
}
|
657
|
-
|
658
303
|
});
|
659
304
|
|
660
305
|
|
@@ -672,7 +317,9 @@ Ext.apply(Netzke.FeedbackGhost.prototype, {
|
|
672
317
|
|
673
318
|
var showBox = function(msg, lvl){
|
674
319
|
if (!lvl) {lvl = 'notice'};
|
675
|
-
|
320
|
+
|
321
|
+
var msgCt = Ext.get('netzke-feedback') || Ext.DomHelper.insertFirst(document.body, {id: 'netzke-feedback', 'class':'netzke-feedback'}, true);
|
322
|
+
|
676
323
|
var m = Ext.DomHelper.append(msgCt, {html:createBox(msg,lvl)}, true);
|
677
324
|
m.slideIn('t').pause(2).ghost("b", {remove:true});
|
678
325
|
}
|