netzke-core 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +1 -1
- data/.gitignore +4 -2
- data/CHANGELOG.rdoc +37 -15
- data/README.rdoc +93 -28
- data/Rakefile +5 -7
- data/TODO +24 -3
- data/app/controllers/netzke_controller.rb +70 -0
- data/app/models/netzke_preference.rb +170 -0
- data/autotest/discover.rb +2 -3
- data/features/actions.feature +13 -0
- data/features/basic.feature +7 -0
- data/features/client-server.feature +15 -0
- data/features/complex_component.feature +18 -0
- data/features/component.feature +13 -0
- data/features/component_loader.feature +31 -0
- data/features/composition.feature +32 -0
- data/features/custom_css.feature +17 -0
- data/features/file_inclusion.feature +13 -0
- data/features/inheritance.feature +19 -0
- data/features/persistence.feature +16 -0
- data/features/scopes.feature +17 -0
- data/features/step_definitions/custom_css_steps.rb +7 -0
- data/features/step_definitions/generic_steps.rb +15 -0
- data/features/step_definitions/web_steps.rb +219 -0
- data/features/support/env.rb +62 -0
- data/features/support/paths.rb +45 -0
- data/generators/netzke_core/USAGE +3 -3
- data/generators/netzke_core/netzke_core_generator.rb +8 -0
- data/install.rb +1 -1
- data/javascripts/core.js +542 -499
- data/lib/generators/migration_helper.rb +32 -0
- data/lib/generators/netzke/USAGE +9 -0
- data/lib/generators/netzke/core_generator.rb +24 -0
- data/lib/netzke/actions.rb +102 -0
- data/lib/netzke/base.rb +77 -529
- data/lib/netzke/composition.rb +251 -0
- data/lib/netzke/configuration.rb +134 -0
- data/lib/netzke/core/masquerading.rb +34 -0
- data/lib/netzke/core/session.rb +30 -0
- data/lib/netzke/core/version.rb +11 -0
- data/lib/netzke/core.rb +53 -0
- data/lib/netzke/core_ext/array.rb +30 -0
- data/lib/netzke/core_ext/hash.rb +84 -0
- data/lib/netzke/core_ext/string.rb +26 -0
- data/lib/netzke/core_ext/symbol.rb +13 -0
- data/lib/netzke/core_ext/time_with_zone.rb +7 -0
- data/lib/netzke/core_ext.rb +5 -141
- data/lib/netzke/embedding.rb +21 -0
- data/lib/netzke/ext_component.rb +25 -0
- data/lib/netzke/javascript.rb +248 -0
- data/lib/netzke/persistence.rb +118 -0
- data/lib/netzke/rails/action_view_ext.rb +103 -0
- data/lib/netzke/{controller_extensions.rb → rails/controller_extensions.rb} +7 -2
- data/lib/netzke/rails/routes.rb +7 -0
- data/lib/netzke/services.rb +68 -0
- data/lib/netzke/session.rb +35 -0
- data/lib/netzke/stylesheets.rb +52 -0
- data/lib/netzke-core.rb +28 -29
- data/netzke-core.gemspec +253 -0
- data/spec/component/actions_spec.rb +94 -0
- data/spec/component/base_spec.rb +25 -0
- data/spec/component/composition_spec.rb +132 -0
- data/spec/component/javascript_spec.rb +15 -0
- data/spec/core_ext_spec.rb +16 -0
- data/spec/spec.opt +2 -0
- data/spec/spec_helper.rb +35 -0
- data/{test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb → templates/core/create_netzke_preferences.rb} +4 -4
- data/test/rails_app/.gitignore +4 -0
- data/test/rails_app/Gemfile +36 -0
- data/test/rails_app/Gemfile.lock +137 -0
- data/test/rails_app/README +15 -0
- data/test/rails_app/Rakefile +7 -0
- data/test/rails_app/app/components/border_layout_panel.rb +4 -0
- data/test/rails_app/app/components/component_loader.rb +59 -0
- data/test/rails_app/app/components/component_with_actions.rb +58 -0
- data/test/rails_app/app/components/component_with_custom_css.rb +8 -0
- data/test/rails_app/app/components/component_with_included_js.rb +16 -0
- data/test/rails_app/app/components/component_with_session_persistence.rb +25 -0
- data/test/rails_app/app/components/custom.css +3 -0
- data/test/rails_app/app/components/deprecated/server_caller.rb +20 -0
- data/test/rails_app/app/components/extended_component_with_actions.rb +5 -0
- data/test/rails_app/app/components/extended_server_caller.rb +18 -0
- data/test/rails_app/app/components/included.js +5 -0
- data/test/rails_app/app/components/kinda_complex_component/basic_stuff.rb +35 -0
- data/test/rails_app/app/components/kinda_complex_component/extra_stuff.rb +16 -0
- data/test/rails_app/app/components/kinda_complex_component.rb +7 -0
- data/test/rails_app/app/components/loader_of_component_with_custom_css.rb +15 -0
- data/test/rails_app/app/components/scoped_components/deep_scoped_components/some_deep_scoped_component.rb +7 -0
- data/test/rails_app/app/components/scoped_components/extended_scoped_component.rb +5 -0
- data/test/rails_app/app/components/scoped_components/some_scoped_component.rb +5 -0
- data/test/rails_app/app/components/server_caller.rb +21 -0
- data/test/rails_app/app/components/simple_component.rb +5 -0
- data/test/rails_app/app/components/simple_tab_panel.rb +27 -0
- data/test/rails_app/app/components/simple_window.rb +3 -0
- data/test/rails_app/app/components/some_composite.rb +65 -0
- data/test/rails_app/app/components/some_ext_component.rb +8 -0
- data/test/{app_root → rails_app}/app/controllers/application_controller.rb +1 -0
- data/test/rails_app/app/controllers/components_controller.rb +12 -0
- data/test/rails_app/app/controllers/multiple_components_controller.rb +2 -0
- data/test/rails_app/app/controllers/welcome_controller.rb +5 -0
- data/test/rails_app/app/helpers/application_helper.rb +2 -0
- data/test/rails_app/app/views/layouts/application.html.erb +13 -0
- data/test/rails_app/app/views/multiple_components/set_one.html.erb +3 -0
- data/test/rails_app/config/application.rb +45 -0
- data/test/rails_app/config/boot.rb +13 -0
- data/test/rails_app/config/database.yml +22 -0
- data/test/rails_app/config/environment.rb +6 -0
- data/test/rails_app/config/environments/development.rb +22 -0
- data/test/rails_app/config/environments/production.rb +49 -0
- data/test/rails_app/config/environments/test.rb +35 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_app/config/initializers/inflections.rb +10 -0
- data/test/rails_app/config/initializers/mime_types.rb +5 -0
- data/test/rails_app/config/initializers/netzke.rb +3 -0
- data/test/rails_app/config/initializers/secret_token.rb +7 -0
- data/test/rails_app/config/initializers/session_store.rb +8 -0
- data/test/rails_app/config/locales/en.yml +5 -0
- data/test/rails_app/config/routes.rb +64 -0
- data/test/rails_app/config.ru +4 -0
- data/test/rails_app/db/development_structure.sql +4 -0
- data/{generators/netzke_core/templates/create_netzke_preferences.rb → test/rails_app/db/migrate/20100905214933_create_netzke_preferences.rb} +1 -3
- data/test/rails_app/db/schema.rb +24 -0
- data/test/rails_app/db/seeds.rb +7 -0
- data/test/{app_root/config/environments/in_memory.rb → rails_app/lib/tasks/.gitkeep} +0 -0
- data/test/rails_app/public/404.html +26 -0
- data/test/rails_app/public/422.html +26 -0
- data/test/rails_app/public/500.html +26 -0
- data/test/{app_root/config/environments/mysql.rb → rails_app/public/favicon.ico} +0 -0
- data/test/rails_app/public/images/rails.png +0 -0
- data/test/rails_app/public/robots.txt +5 -0
- data/test/rails_app/script/rails +6 -0
- data/test/{app_root/config/environments/postgresql.rb → rails_app/vendor/plugins/.gitkeep} +0 -0
- data/test/unit/netzke_core_test.rb +74 -75
- data/test/unit/netzke_preference_test.rb +2 -2
- metadata +176 -48
- data/lib/app/controllers/netzke_controller.rb +0 -46
- data/lib/app/models/netzke_preference.rb +0 -171
- data/lib/netzke/action_view_ext.rb +0 -81
- data/lib/netzke/base_js.rb +0 -339
- data/lib/netzke/routing.rb +0 -9
- data/test/app_root/app/models/role.rb +0 -3
- data/test/app_root/app/models/user.rb +0 -3
- data/test/app_root/config/boot.rb +0 -115
- data/test/app_root/config/database.yml +0 -31
- data/test/app_root/config/environment.rb +0 -14
- data/test/app_root/config/environments/sqlite.rb +0 -0
- data/test/app_root/config/environments/sqlite3.rb +0 -0
- data/test/app_root/config/routes.rb +0 -4
- data/test/app_root/db/migrate/20090423214303_create_roles.rb +0 -11
- data/test/app_root/db/migrate/20090423222114_create_users.rb +0 -12
- data/test/app_root/lib/console_with_fixtures.rb +0 -4
- data/test/app_root/script/console +0 -7
data/.autotest
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'autotest/redgreen'
|
1
|
+
# require 'autotest/redgreen'
|
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,10 +1,32 @@
|
|
1
|
-
= v0.
|
2
|
-
*
|
3
|
-
*
|
4
|
-
|
5
|
-
|
6
|
-
*
|
7
|
-
|
1
|
+
= v0.6.0 - 2010-10-24
|
2
|
+
* Rails3 compatibility, thorough rewrite
|
3
|
+
* Much more thorough testing
|
4
|
+
|
5
|
+
* API backward incompatibility
|
6
|
+
* +ext_config+ config level is removed; put all that configuration in the top level
|
7
|
+
* mentioning actions in the +bbar+, +tbar+, etc, should be explicit, e.g.:
|
8
|
+
|
9
|
+
:bbar => [:apply.action, :delete.action]
|
10
|
+
|
11
|
+
* +late_aggregatee+ is now +lazy_loading+
|
12
|
+
* +aggregatees+ are now +components+
|
13
|
+
* +widgets+ are now +components+, too
|
14
|
+
* +api+ is now +endpoint+
|
15
|
+
* +persistent_config_enabled?+ is now +persistence_enabled?+
|
16
|
+
* Using the +js_extend_properties+ class method in your components in deprecated (and maybe even broken). Use +js_property+ (or +js_properties+) and +js_method+ instead (see multiple examples in test/rails_app)
|
17
|
+
* the +load_component_with_cache+ endpoint renamed to +deliver_component+
|
18
|
+
|
19
|
+
* New
|
20
|
+
* +ext+ helper in the views to embed any (pure) Ext component into a view
|
21
|
+
* +component+ DSL method to declare child components
|
22
|
+
* +config+ DSL method to set the configuration of an instance
|
23
|
+
* +action+ DSL method to configure actions
|
24
|
+
* +js_method+ DSL method to define (public) methods in JS class
|
25
|
+
* +js_property+ DSL method to define (public) properties in JS class
|
26
|
+
* +endpoint+ DSL method to define server endpoints
|
27
|
+
|
28
|
+
* Different deprecations throughout the code
|
29
|
+
|
8
30
|
= v0.5.3 - 2010-06-14
|
9
31
|
* Fix: Getting rid of deprecation warnings about tasks not sitting in lib.
|
10
32
|
|
@@ -47,7 +69,7 @@
|
|
47
69
|
* Code: lightly better test coverage
|
48
70
|
* New: <tt>Netzke::Base#global_id_by_reference</tt> method
|
49
71
|
* Compatibility: resolving conflicts with the <tt>api</tt> property in some Ext v3.0 components
|
50
|
-
* Fix: <tt>
|
72
|
+
* Fix: <tt>deliver_component</tt> was throwing exception when the requested component wasn't defined
|
51
73
|
* New: <tt>persistent_config_id</tt> configuration option allows specifying an id by which persistent configuration is identified for the widget. Handy if different homogeneous widgets need to share the same persistent configuration.
|
52
74
|
* New: <tt>Netzke::Base#persistent_config</tt> method now accepts an optional boolean parameter signalizing that the configuration is global (not bound to a widget)
|
53
75
|
* Impr: cleaner handling of actions and toolbars; fbar configuration introduced.
|
@@ -60,10 +82,10 @@
|
|
60
82
|
* Internal: the JavaScript instance now knows if persistent config is enabled (by checking this.persistentConfig).
|
61
83
|
* Fix: solving the "Node cannot be inserted at the specified point in the hierarchy" problem by being more strict with duplicated IDs for elements on the same page.
|
62
84
|
* Fix: Ext 3.0 compatibility.
|
63
|
-
* Impr: <tt>
|
85
|
+
* Impr: <tt>getChildComponent</tt> now allows referring to a widget like this: "parent__parent__some_widget__some_nested_widget"
|
64
86
|
|
65
87
|
= v0.4.3
|
66
|
-
* Fix: reworking
|
88
|
+
* Fix: reworking loadComponent()-related code, closing a security flaw when a malicious browser could send any configuration options to instantiate the widget being loaded.
|
67
89
|
|
68
90
|
= v0.4.2 - 2009-09-11
|
69
91
|
* Fix: the API call (at the JavaScript side) was ignoring the callback parameter.
|
@@ -95,7 +117,7 @@
|
|
95
117
|
* New: widgets now can check session[:netzke_just_logged_in] and session[:netzke_just_logged_out] automatically set by Netzke after login/logout
|
96
118
|
|
97
119
|
= v0.2.11
|
98
|
-
* Introduction of
|
120
|
+
* Introduction of getOwnerComponent()-method to Ext.Component. It provides the Netzke widget this Component belongs to.
|
99
121
|
|
100
122
|
= v0.2.10
|
101
123
|
* Removed dependency on 'json' gem.
|
@@ -117,11 +139,11 @@
|
|
117
139
|
= v0.2.6
|
118
140
|
* FeedackGhost is now capable of displaying multiple flash messages.
|
119
141
|
* Dependencies slightly refactored.
|
120
|
-
* An informative exception added to Base#
|
142
|
+
* An informative exception added to Base#component_instance.
|
121
143
|
* JS-level inheritance enabled.
|
122
|
-
* Work-around for the problem with Ext 2.2.1 in
|
144
|
+
* Work-around for the problem with Ext 2.2.1 in loadComponent.
|
123
145
|
* Events "<action_id>click" added to the widgets along with the actions.
|
124
|
-
*
|
146
|
+
* component_missing method added to Netzke::Base - called when a non-existing aggregate of a widget is tried to be invoked
|
125
147
|
* Code readability improvements.
|
126
148
|
|
127
149
|
= v0.2.5
|
@@ -132,7 +154,7 @@
|
|
132
154
|
|
133
155
|
= v0.2.3
|
134
156
|
* FeedbackGhost will show the feedback on the top of the screen independent of the page scrolling.
|
135
|
-
* Ext.Panel#
|
157
|
+
* Ext.Panel#loadComponent will accept null as url to delete the currently loaded widget
|
136
158
|
* Bug fix: persistent_config works again
|
137
159
|
|
138
160
|
= v0.2.2
|
data/README.rdoc
CHANGED
@@ -1,60 +1,125 @@
|
|
1
1
|
= netzke-core
|
2
|
-
Create Ext JS + Rails reusable components (widgets) with minimum effort.
|
3
2
|
|
4
|
-
|
3
|
+
Create Ext JS + Rails components with minimum effort.
|
5
4
|
|
6
|
-
|
5
|
+
This is the bare bones of the Netzke framework. Use it to build your own components from scratch. For pre-built components (like panels, grids, forms, trees, applications), see the netzke-basepack (http://github.com/skozlov/netzke-basepack) project.
|
7
6
|
|
8
|
-
|
9
|
-
For the latest ("edge") stuff, install as plugin (recommended!):
|
7
|
+
The idea behind the Netzke framework is that it allows you write reusable client/server code. Create a component, and then embed it straight to your Rails' view, load it dynamically into your Ext-based applications, or use it as a building block for other (composite) components. For more info, see the links below.
|
10
8
|
|
11
|
-
|
9
|
+
== Requirements
|
12
10
|
|
13
|
-
|
11
|
+
* Rails >= 3.0.0
|
12
|
+
* Ruby >= 1.9.2 (1.8.7 should work, but may not be supported as diligently)
|
13
|
+
* Ext >= 3.3.0
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
== Installation
|
16
|
+
|
17
|
+
For the latest ("edge") stuff, tell bundler to get the gem straight from github:
|
18
18
|
|
19
|
-
|
19
|
+
gem 'netzke-core', :git => "git://github.com/skozlov/netzke-core.git"
|
20
20
|
|
21
|
-
|
21
|
+
Or install as plugin:
|
22
|
+
|
23
|
+
rails plugin install git://github.com/skozlov/netzke-core.git
|
24
|
+
|
25
|
+
Netzke assumes that your ExtJS library is in public/extjs (which may be a symbolic link):
|
26
|
+
|
27
|
+
ln -s ~/code/sencha/ext-3.3.0 public/extjs
|
22
28
|
|
23
29
|
== Usage
|
24
|
-
Here's how to embed a Netzke widget into your Rails view.
|
25
30
|
|
26
|
-
|
31
|
+
Let's create a simple "Hello world!" component and embed it into a Rails' view. It'll be an Ext.Panel-based component with a button that triggers a client-server communication.
|
32
|
+
|
33
|
+
Create YOUR_APP/app/components/hello_world_component.rb, and put in the following content:
|
34
|
+
|
35
|
+
class HelloWorldComponent < Netzke::Base
|
36
|
+
# Ext.Panel's config option "title"
|
37
|
+
js_property :title, "My Hello World Component"
|
38
|
+
|
39
|
+
# Bottom bar with an automatically created action
|
40
|
+
js_property :bbar, [:bug_server.action]
|
41
|
+
|
42
|
+
# Method in the JS class that (by default) processes the action's "click" event
|
43
|
+
js_method :on_bug_server, <<-JS
|
44
|
+
function(){
|
45
|
+
// Remotely calling the server's method greet_the_world (defined below)
|
46
|
+
this.greetTheWorld();
|
47
|
+
}
|
48
|
+
JS
|
49
|
+
|
50
|
+
# Server's method that gets called from the JS
|
51
|
+
endpoint :greet_the_world do |params|
|
52
|
+
# Tell the client side to call its method showGreeting with "Hello World!" as parameter
|
53
|
+
{:show_greeting => "Hello World!"}
|
54
|
+
end
|
55
|
+
|
56
|
+
# Another method in the JS class that gets remotely called by the server side
|
57
|
+
js_method :show_greeting, <<-JS
|
58
|
+
function(greeting){
|
59
|
+
this.body.update("Server says: " + greeting);
|
60
|
+
}
|
61
|
+
JS
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
To embed a Netzke component into your Rails view do the following:
|
66
|
+
|
67
|
+
1. In your layout, within the "head" tag, use the <tt>netzke_init</tt> helper to include all the necessary JavaScript and styles.
|
27
68
|
|
28
69
|
<%= netzke_init %>
|
29
|
-
|
30
|
-
2. In config/routes.rb declare the Netzke routes:
|
31
70
|
|
32
|
-
|
71
|
+
You can optionally specify an Ext theme:
|
72
|
+
|
73
|
+
<%= netzke_init :ext_theme => 'grey' %>
|
74
|
+
|
75
|
+
2. In your view use the <tt>netzke</tt> helper to embed the component:
|
76
|
+
|
77
|
+
<%= netzke :hello_world_component %>
|
78
|
+
|
79
|
+
That's it. While playing with the component, use Firebug or similar tool to check the AJAX requests to understand better what's going on behind the scenes. Also check the source code of the page embedding the component.
|
80
|
+
|
81
|
+
== Running tests
|
82
|
+
|
83
|
+
netzke-core is bundled with cucumber and RSpec tests. Before you can run them, you must link your Ext JS library to test/rails_app/public, e.g. (from plugin's root):
|
84
|
+
|
85
|
+
ln -s ~/code/sencha/ext-3.3.0 test/rails_app/public/extjs
|
86
|
+
|
87
|
+
For cucumber tests:
|
88
|
+
|
89
|
+
cucumber features
|
33
90
|
|
34
|
-
|
91
|
+
RSpec tests:
|
35
92
|
|
36
|
-
|
93
|
+
rspec spec
|
37
94
|
|
38
|
-
|
95
|
+
== Testing playground
|
96
|
+
|
97
|
+
The bundled test/rails_app application is also a convenient playground to learn more about the framework, as it may be run as a stand-alone Rails app. It's also a pretty good source of examples. After starting it, access any of the app/components/netzke test components by using the following url:
|
98
|
+
|
99
|
+
http://localhost:3000/components/<name of the component's class>
|
39
100
|
|
40
|
-
|
101
|
+
e.g.:
|
102
|
+
|
103
|
+
http://localhost:3000/components/ServerCaller
|
41
104
|
|
42
|
-
|
105
|
+
or, for scoped components:
|
43
106
|
|
44
|
-
|
107
|
+
http://localhost:3000/components/ScopedComponents::SomeScopedComponent
|
45
108
|
|
46
|
-
|
109
|
+
== Migrating from 0.5.x
|
110
|
+
|
111
|
+
There have been a significant amount of changes that made 0.6 version backward-incompatible. Please, refer to CHANGELOG.rdoc for the (hopefully) full list of changes that most certainly would make your current application break. Additionally, this wiki page may be of some help, too: http://github.com/skozlov/netzke-core/wiki/Upgrading-from-0.5.x-to-0.6.0
|
47
112
|
|
48
113
|
== More info
|
49
|
-
|
114
|
+
Netzke website: http://netzke.org
|
50
115
|
|
51
|
-
|
116
|
+
Live-demo with sample code: http://demo.netzke.org
|
52
117
|
|
53
118
|
Tutorials: http://blog.writelesscode.com
|
54
119
|
|
55
|
-
|
120
|
+
Twitter: http://twitter.com/skozlov
|
56
121
|
|
57
|
-
The netzke-basepack project (pre-built full-featured
|
122
|
+
The netzke-basepack project (pre-built full-featured components): http://github.com/skozlov/netzke-basepack
|
58
123
|
|
59
124
|
---
|
60
125
|
|
data/Rakefile
CHANGED
@@ -1,31 +1,29 @@
|
|
1
1
|
begin
|
2
2
|
require 'jeweler'
|
3
|
+
require './lib/netzke/core/version'
|
3
4
|
Jeweler::Tasks.new do |gemspec|
|
4
|
-
gemspec.version =
|
5
|
+
gemspec.version = Netzke::Core::Version::STRING
|
5
6
|
gemspec.name = "netzke-core"
|
6
|
-
gemspec.summary = "Build ExtJS/Rails
|
7
|
+
gemspec.summary = "Build ExtJS/Rails components with minimum effort"
|
7
8
|
gemspec.description = "Allows building ExtJS/Rails reusable code in a DRY way"
|
8
9
|
gemspec.email = "sergei@playcode.nl"
|
9
10
|
gemspec.homepage = "http://github.com/skozlov/netzke-core"
|
10
11
|
gemspec.rubyforge_project = "netzke-core"
|
11
12
|
gemspec.authors = ["Sergei Kozlov"]
|
12
|
-
gemspec.add_dependency("
|
13
|
+
gemspec.add_dependency("activesupport", ">=3.0.1")
|
13
14
|
gemspec.post_install_message = <<-MESSAGE
|
14
15
|
|
15
16
|
========================================================================
|
16
17
|
|
17
18
|
Thanks for installing Netzke Core!
|
18
19
|
|
19
|
-
Don't forget to run "./script/generate netzke_core" for each Rails
|
20
|
-
app that will be using this gem.
|
21
|
-
|
22
20
|
Netzke home page: http://netzke.org
|
23
21
|
Netzke Google Groups: http://groups.google.com/group/netzke
|
24
22
|
Netzke tutorials: http://blog.writelesscode.com
|
25
23
|
|
26
24
|
========================================================================
|
27
25
|
|
28
|
-
|
26
|
+
MESSAGE
|
29
27
|
|
30
28
|
end
|
31
29
|
Jeweler::GemcutterTasks.new
|
data/TODO
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
Make plugin-wide javascripts and stylesheets load automatically.
|
2
|
+
Caching - investigate reusing (fragment?) caching of Rails.
|
3
|
+
Use Ext.Direct in the Netzke controller.
|
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
|
+
|
10
|
+
|
11
|
+
= Ideas that didn't work out
|
12
|
+
|
13
|
+
== Making value from super-class accessible in the block parameters in endpoints, e.g.:
|
14
|
+
|
15
|
+
endpoint :call_server do |params, orig|
|
16
|
+
orig.merge(:set_title => orig[:set_title] + " extended")
|
17
|
+
end
|
18
|
+
|
19
|
+
Bad idea because calling the super method is often required AFTER doing something in the override, not BEFORE. For example, deliver_component in GridPanel in Basepack is overridden to reconfigure the components on the fly before actually delivering the component (i.e. calling super).
|
20
|
+
So, to override an endpoint, simply define a method with endpoint's name, e.g.:
|
21
|
+
|
22
|
+
def call_server(params)
|
23
|
+
super.merge(...)
|
24
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class NetzkeController < ApplicationController
|
2
|
+
|
3
|
+
# Collect javascripts and stylesheets from all plugins that registered it in Netzke::Core.javascripts
|
4
|
+
# TODO: caching
|
5
|
+
# caches_action :netzke
|
6
|
+
def netzke
|
7
|
+
respond_to do |format|
|
8
|
+
format.js {
|
9
|
+
res = initial_dynamic_javascript << "\n"
|
10
|
+
Netzke::Core.javascripts.each do |path|
|
11
|
+
f = File.new(path)
|
12
|
+
res << f.read
|
13
|
+
end
|
14
|
+
|
15
|
+
# If JS classes are not inserted into the main page, we need to render all the classes needed to load the page that includes us
|
16
|
+
# (i.e. netzke/netzke.js) here
|
17
|
+
if !Netzke::Core.javascript_on_main_page
|
18
|
+
rendered_classes = []
|
19
|
+
Netzke::Core.session[:netzke_components].each_pair do |k,v|
|
20
|
+
component = Netzke::Base.instance_by_config(v)
|
21
|
+
res << component.js_missing_code(rendered_classes.map(&:name))
|
22
|
+
rendered_classes += component.dependency_classes
|
23
|
+
rendered_classes.uniq!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
render :text => defined?(::Rails) && ::Rails.env.production? ? res.strip_js_comments : res
|
28
|
+
}
|
29
|
+
|
30
|
+
format.css {
|
31
|
+
res = ""
|
32
|
+
Netzke::Core.stylesheets.each do |path|
|
33
|
+
f = File.new(path)
|
34
|
+
res << f.read
|
35
|
+
end
|
36
|
+
render :text => res
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Main dispatcher of the HTTP requests. The URL contains the name of the component,
|
42
|
+
# as well as the method of this component to be called, according to the double underscore notation.
|
43
|
+
# E.g.: some_grid__post_grid_data.
|
44
|
+
def method_missing(method_name)
|
45
|
+
component_name, *action = method_name.to_s.split('__')
|
46
|
+
component_name = component_name.to_sym
|
47
|
+
action = !action.empty? && action.join("__").to_sym
|
48
|
+
|
49
|
+
if action
|
50
|
+
w_instance = Netzke::Base.instance_by_config(Netzke::Core.session[:netzke_components][component_name])
|
51
|
+
# only component's actions starting with "endpoint_" are accessible from outside (security)
|
52
|
+
endpoint_action = action.to_s.index('__') ? action : "endpoint_#{action}"
|
53
|
+
render :text => w_instance.send(endpoint_action, params), :layout => false
|
54
|
+
else
|
55
|
+
super
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
# Generates initial javascript code that is dependent on Rails environement
|
61
|
+
def initial_dynamic_javascript
|
62
|
+
res = []
|
63
|
+
res << %(Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection)
|
64
|
+
res << %{Ext.ns('Netzke');}
|
65
|
+
res << %{Netzke.RelativeUrlRoot = '#{ActionController::Base.config.relative_url_root}';}
|
66
|
+
res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}/extjs';}
|
67
|
+
res.join("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
class NetzkePreference < ActiveRecord::Base
|
2
|
+
serialize :value
|
3
|
+
|
4
|
+
# belongs_to :user
|
5
|
+
# belongs_to :role
|
6
|
+
|
7
|
+
# ELEMENTARY_CONVERTION_METHODS= {'Fixnum' => 'to_i', 'String' => 'to_s', 'Float' => 'to_f', 'Symbol' => 'to_sym'}
|
8
|
+
|
9
|
+
# def self.component_name=(value)
|
10
|
+
# @@component_name = value
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# def self.component_name
|
14
|
+
# @@component_name ||= nil
|
15
|
+
# end
|
16
|
+
|
17
|
+
# def normalized_value
|
18
|
+
# klass = read_attribute(:pref_type)
|
19
|
+
# norm_value = read_attribute(:value)
|
20
|
+
#
|
21
|
+
# case klass
|
22
|
+
# when nil then r = norm_value # do not cast
|
23
|
+
# when 'Boolean' then r = norm_value == 'false' ? false : (norm_value == 'true' || norm_value)
|
24
|
+
# when 'NilClass' then r = nil
|
25
|
+
# when 'Array', 'Hash' then r = ActiveSupport::JSON.decode(norm_value)
|
26
|
+
# else
|
27
|
+
# r = norm_value.send(ELEMENTARY_CONVERTION_METHODS[klass])
|
28
|
+
# end
|
29
|
+
# r
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# def normalized_value=(new_value)
|
33
|
+
# case new_value.class.name
|
34
|
+
# when "Array" then write_attribute(:value, new_value.to_json)
|
35
|
+
# when "Hash" then write_attribute(:value, new_value.to_json)
|
36
|
+
# else write_attribute(:value, new_value.to_s)
|
37
|
+
# end
|
38
|
+
# write_attribute(:pref_type, [TrueClass, FalseClass].include?(new_value.class) ? 'Boolean' : new_value.class.to_s)
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# def self.[](pref_name)
|
42
|
+
# pref_name = normalize_preference_name(pref_name)
|
43
|
+
# pref = self.pref_to_read(pref_name)
|
44
|
+
# pref && pref.normalized_value
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# def self.[]=(pref_name, new_value)
|
48
|
+
# pref_name = normalize_preference_name(pref_name)
|
49
|
+
# pref = self.pref_to_write(pref_name)
|
50
|
+
#
|
51
|
+
# # if assigning nil, simply delete the eventually found preference
|
52
|
+
# if new_value.nil?
|
53
|
+
# pref && pref.destroy
|
54
|
+
# else
|
55
|
+
# # pref ||= self.new(conditions(pref_name))
|
56
|
+
# pref.normalized_value = new_value
|
57
|
+
# pref.save!
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
# Overwrite pref_to_read, pref_to_write methods, and find_all_for_component if you want a different way of
|
64
|
+
# identifying the proper preference based on your own authorization strategy.
|
65
|
+
#
|
66
|
+
# The default strategy is:
|
67
|
+
# 1) if no masq_user or masq_role defined
|
68
|
+
# pref_to_read will search for the preference for user first, then for user's role
|
69
|
+
# pref_to_write will always find or create a preference for the current user (never for its role)
|
70
|
+
# 2) if masq_user or masq_role is defined
|
71
|
+
# pref_to_read and pref_to_write will always take the masquerade into account, e.g. reads/writes will go to
|
72
|
+
# the user/role specified
|
73
|
+
#
|
74
|
+
def self.pref_to_read(name)
|
75
|
+
name = name.to_s
|
76
|
+
session = Netzke::Core.session
|
77
|
+
cond = {:key => name}
|
78
|
+
|
79
|
+
if session[:masq_user]
|
80
|
+
# first, get the prefs for this user it they exist
|
81
|
+
res = self.where(cond.merge({:user_id => session[:masq_user]})).first
|
82
|
+
|
83
|
+
# if it doesn't exist, get them for the user's role
|
84
|
+
user = User.where(session[:masq_user])
|
85
|
+
res ||= self.where(cond.merge({:role_id => user.role.id})).first
|
86
|
+
|
87
|
+
# if it doesn't exist either, get them for the World (role_id = 0)
|
88
|
+
res ||= self.where(cond.merge({:role_id => 0})).first
|
89
|
+
elsif session[:masq_role]
|
90
|
+
# first, get the prefs for this role
|
91
|
+
res = self.where(cond.merge({:role_id => session[:masq_role]})).first
|
92
|
+
# if it doesn't exist, get them for the World (role_id = 0)
|
93
|
+
res ||= self.where(cond.merge({:role_id => 0})).first
|
94
|
+
elsif session[:netzke_user_id]
|
95
|
+
user = User.where(session[:netzke_user_id])
|
96
|
+
# first, get the prefs for this user
|
97
|
+
res = self.where(cond.merge({:user_id => user.id})).first
|
98
|
+
# if it doesn't exist, get them for the user's role
|
99
|
+
res ||= self.where(cond.merge({:role_id => user.role.id})).first
|
100
|
+
# if it doesn't exist either, get them for the World (role_id = 0)
|
101
|
+
res ||= self.where(cond.merge({:role_id => 0})).first
|
102
|
+
else
|
103
|
+
res = self.where(cond).first
|
104
|
+
end
|
105
|
+
|
106
|
+
res
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.pref_to_write(name)
|
110
|
+
name = name.to_s
|
111
|
+
session = Netzke::Core.session
|
112
|
+
cond = {:key => name}
|
113
|
+
|
114
|
+
if session[:masq_user]
|
115
|
+
cond.merge!({:user_id => session[:masq_user]})
|
116
|
+
# first, try to find the preference for masq_user
|
117
|
+
res = self.where(cond).first
|
118
|
+
# if it doesn't exist, create it
|
119
|
+
res ||= self.new(cond)
|
120
|
+
elsif session[:masq_role]
|
121
|
+
# first, delete all the corresponding preferences for the users that have this role
|
122
|
+
Role.where(session[:masq_role]).users.each do |u|
|
123
|
+
self.delete_all(cond.merge({:user_id => u.id}))
|
124
|
+
end
|
125
|
+
cond.merge!({:role_id => session[:masq_role]})
|
126
|
+
res = self.where(cond).first
|
127
|
+
res ||= self.new(cond)
|
128
|
+
elsif session[:masq_world]
|
129
|
+
# first, delete all the corresponding preferences for all users and roles
|
130
|
+
self.delete_all(cond)
|
131
|
+
# then, create the new preference for the World (role_id = 0)
|
132
|
+
res = self.new(cond.merge(:role_id => 0))
|
133
|
+
elsif session[:netzke_user_id]
|
134
|
+
res = self.where(cond.merge({:user_id => session[:netzke_user_id]})).first
|
135
|
+
res ||= self.new(cond.merge({:user_id => session[:netzke_user_id]}))
|
136
|
+
else
|
137
|
+
res = self.where(cond).first
|
138
|
+
res ||= self.new(cond)
|
139
|
+
end
|
140
|
+
res
|
141
|
+
end
|
142
|
+
|
143
|
+
# def self.find_all_for_component(name)
|
144
|
+
# session = Netzke::Core.session
|
145
|
+
# cond = {:component_name => name}
|
146
|
+
#
|
147
|
+
# if session[:masq_user] || session[:masq_role]
|
148
|
+
# cond.merge!({:user_id => session[:masq_user], :role_id => session[:masq_role]})
|
149
|
+
# res = self.where(cond).all
|
150
|
+
# elsif session[:netzke_user_id]
|
151
|
+
# user = User.where(session[:netzke_user_id])
|
152
|
+
# res = self.where(cond.merge({:user_id => session[:netzke_user_id]})).all
|
153
|
+
# res += self.where(cond.merge({:role_id => user.role.try(:id)})).all
|
154
|
+
# else
|
155
|
+
# res = self.where(cond).all
|
156
|
+
# end
|
157
|
+
#
|
158
|
+
# res
|
159
|
+
# end
|
160
|
+
|
161
|
+
# def self.delete_all_for_component(name)
|
162
|
+
# self.destroy(find_all_for_component(name))
|
163
|
+
# end
|
164
|
+
#
|
165
|
+
# private
|
166
|
+
# def self.normalize_preference_name(name)
|
167
|
+
# name.to_s.gsub(".", "__").gsub("/", "__")
|
168
|
+
# end
|
169
|
+
|
170
|
+
end
|
data/autotest/discover.rb
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
Autotest.add_discovery
|
2
|
-
|
3
|
-
end
|
1
|
+
Autotest.add_discovery { "rails" }
|
2
|
+
Autotest.add_discovery { "rspec2" }
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Actions
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: Pressing button should result in corresponding actions
|
8
|
+
When I go to the ComponentWithActions test page
|
9
|
+
Then I should see "Disabled action"
|
10
|
+
And button "Disabled action" should be disabled
|
11
|
+
|
12
|
+
When I press "Some action"
|
13
|
+
Then I should see "Some action was triggered"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Client/server communication
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@selenium
|
7
|
+
Scenario: Ask server to set our title
|
8
|
+
Given I am on the ServerCaller test page
|
9
|
+
Then I should see "Server Caller"
|
10
|
+
|
11
|
+
# When I execute "Ext.getCmp('server_caller').buttons.first().fireEvent('click');"
|
12
|
+
When I press "Call server"
|
13
|
+
Then I should see "All quiet here on the server"
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: Complex component
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: Complex component must render properly
|
8
|
+
When I go to the KindaComplexComponent test page
|
9
|
+
Then I should see "Panel One"
|
10
|
+
And I should see "Panel Two"
|
11
|
+
And I should see "Server Caller"
|
12
|
+
|
13
|
+
@javascript
|
14
|
+
Scenario: The last tab of the complex component is a Netzke component that just works
|
15
|
+
Given I am on the KindaComplexComponent test page
|
16
|
+
When I follow "Server Caller"
|
17
|
+
And I press "Call server"
|
18
|
+
Then I should see "All quiet here on the server"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Testing Netzke::Base
|
2
|
+
In order to value
|
3
|
+
As a role
|
4
|
+
I want feature
|
5
|
+
|
6
|
+
@javascript
|
7
|
+
Scenario: A panel should render nicely
|
8
|
+
When I go to the SimpleComponent test page
|
9
|
+
Then I should see "SimpleComponent"
|
10
|
+
And I should see "Inner text"
|
11
|
+
|
12
|
+
|
13
|
+
|