netzke-core 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +9 -0
- data/Rakefile +17 -1
- data/generators/netzke_core/netzke_core_generator.rb +3 -6
- data/generators/netzke_core/templates/create_netzke_preferences.rb +4 -4
- data/javascripts/core.js +10 -5
- data/lib/app/controllers/netzke_controller.rb +7 -5
- data/lib/netzke/action_view_ext.rb +13 -8
- data/lib/netzke/base.rb +47 -9
- data/lib/netzke/base_js.rb +3 -3
- data/test/app_root/config/database.yml +1 -1
- data/test/unit/core_ext_test.rb +6 -6
- data/test/unit/netzke_core_test.rb +9 -9
- metadata +31 -6
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
= v0.5.2 - EDGE
|
2
|
+
* Ext 3.2.1
|
3
|
+
* Fix: Netzke::Base.before_load is now also called for the widgets embedded directly into a view.
|
4
|
+
* New: support for external stylesheets.
|
5
|
+
* Fix: the "value" column type has been changed to text to prevent migration problems is some cases
|
6
|
+
* New: global_persistent_config method allows accessing persistent storage with no owner (widget) assigned
|
7
|
+
* New: any widget can now implement <tt>before_api_call</tt> interceptor. If it returns anything but empty hash, it'll be used as the result of *any* API call to this widget. The interceptor receives as parameter the name of the API call issued and the arguments. Use it to implement authorization.
|
8
|
+
* Fix: got the Ext's state provider out of the way (thank you for all the confusion)
|
9
|
+
|
1
10
|
= v0.5.1 - 2010-02-26
|
2
11
|
* Compatibility with Ext 3.1.1
|
3
12
|
* New: <tt>Netzke.page</tt> object now contains all the widgets declared on the page
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'jeweler'
|
3
3
|
Jeweler::Tasks.new do |gemspec|
|
4
|
-
gemspec.version = "0.5.
|
4
|
+
gemspec.version = "0.5.2"
|
5
5
|
gemspec.name = "netzke-core"
|
6
6
|
gemspec.summary = "Build ExtJS/Rails widgets with minimum effort"
|
7
7
|
gemspec.description = "Allows building ExtJS/Rails reusable code in a DRY way"
|
@@ -9,6 +9,22 @@ begin
|
|
9
9
|
gemspec.homepage = "http://github.com/skozlov/netzke-core"
|
10
10
|
gemspec.rubyforge_project = "netzke-core"
|
11
11
|
gemspec.authors = ["Sergei Kozlov"]
|
12
|
+
gemspec.post_install_message = <<-MESSAGE
|
13
|
+
|
14
|
+
========================================================================
|
15
|
+
|
16
|
+
Thanks for installing Netzke Core!
|
17
|
+
|
18
|
+
Run "./script/generate netzke_core" to finish the installation.
|
19
|
+
|
20
|
+
Netzke home page: http://netzke.org
|
21
|
+
Netzke Google Groups: http://groups.google.com/group/netzke
|
22
|
+
Netzke tutorials: http://blog.writelesscode.com
|
23
|
+
|
24
|
+
========================================================================
|
25
|
+
|
26
|
+
MESSAGE
|
27
|
+
|
12
28
|
end
|
13
29
|
Jeweler::GemcutterTasks.new
|
14
30
|
rescue LoadError
|
@@ -2,12 +2,9 @@
|
|
2
2
|
class NetzkeCoreGenerator < Rails::Generator::Base
|
3
3
|
def manifest
|
4
4
|
record do |m|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
m.directory 'db/migrate'
|
9
|
-
# m.file 'create_netzke_layouts.rb', "db/migrate/#{time}_create_netzke_layouts.rb"
|
10
|
-
m.file 'create_netzke_preferences.rb', "db/migrate/#{time.to_i+1}_create_netzke_preferences.rb"
|
5
|
+
m.migration_template 'create_netzke_preferences.rb', 'db/migrate', :assigns => {
|
6
|
+
:migration_name => "CreateNetzkePreferences"
|
7
|
+
}, :migration_file_name => "create_netzke_preferences"
|
11
8
|
end
|
12
9
|
end
|
13
10
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
class CreateNetzkePreferences < ActiveRecord::Migration
|
2
2
|
def self.up
|
3
3
|
create_table :netzke_preferences do |t|
|
4
|
-
t.string
|
5
|
-
t.string
|
6
|
-
t.
|
4
|
+
t.string :name
|
5
|
+
t.string :pref_type
|
6
|
+
t.text :value
|
7
7
|
t.integer :user_id
|
8
8
|
t.integer :role_id
|
9
|
-
t.string
|
9
|
+
t.string :widget_name
|
10
10
|
|
11
11
|
t.timestamps
|
12
12
|
end
|
data/javascripts/core.js
CHANGED
@@ -3,11 +3,13 @@ This file gets loaded along with the rest of Ext library at the initial load
|
|
3
3
|
*/
|
4
4
|
|
5
5
|
// Check Ext JS version
|
6
|
-
|
7
|
-
var
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
(function(){
|
7
|
+
var requiredExtVersion = "3.2.1";
|
8
|
+
var currentExtVersion = Ext.version;
|
9
|
+
if (requiredExtVersion !== currentExtVersion) {
|
10
|
+
alert("Netzke needs Ext " + requiredExtVersion + ". You have " + currentExtVersion + ".");
|
11
|
+
}
|
12
|
+
})();
|
11
13
|
|
12
14
|
// Initial stuff
|
13
15
|
Ext.BLANK_IMAGE_URL = "/extjs/resources/images/default/s.gif";
|
@@ -17,6 +19,9 @@ Ext.ns('Netzke.page'); // namespace for all widget instantces on the page
|
|
17
19
|
|
18
20
|
Ext.QuickTips.init();
|
19
21
|
|
22
|
+
// We don't want no state managment by default, thank you!
|
23
|
+
Ext.state.Provider.prototype.set = function(){};
|
24
|
+
|
20
25
|
// Type detection functions
|
21
26
|
Netzke.isObject = function(o) {
|
22
27
|
return (o != null && typeof o == "object" && o.constructor.toString() == Object.toString());
|
@@ -1,9 +1,8 @@
|
|
1
1
|
class NetzkeController < ApplicationController
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# collect javascripts from all plugins that registered it in Netzke::Base.config[:javascripts]
|
2
|
+
|
3
|
+
# Collect javascripts from all plugins that registered it in Netzke::Base.config[:javascripts]
|
4
|
+
# TODO: caching
|
5
|
+
# caches_action :netzke
|
7
6
|
def netzke
|
8
7
|
respond_to do |format|
|
9
8
|
format.js {
|
@@ -26,6 +25,9 @@ class NetzkeController < ApplicationController
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
28
|
+
# Main dispatcher of the HTTP requests. The URL contains the name of the widget,
|
29
|
+
# as well as the method of this widget to be called, according to the double underscore notation.
|
30
|
+
# E.g.: some_grid__post_grid_data.
|
29
31
|
def method_missing(method_name)
|
30
32
|
widget_name, *action = method_name.to_s.split('__')
|
31
33
|
widget_name = widget_name.to_sym
|
@@ -3,26 +3,31 @@ module Netzke
|
|
3
3
|
# Include JavaScript
|
4
4
|
def netzke_js_include
|
5
5
|
# ExtJS
|
6
|
-
res = ENV['RAILS_ENV'] == 'development' ? javascript_include_tag("/extjs/adapter/ext/ext-base
|
6
|
+
res = ENV['RAILS_ENV'] == 'development' ? javascript_include_tag("/extjs/adapter/ext/ext-base", "/extjs/ext-all-debug") : javascript_include_tag("/extjs/adapter/ext/ext-base", "/extjs/ext-all")
|
7
7
|
# Netzke (dynamically generated)
|
8
|
-
res << javascript_include_tag("/netzke/netzke
|
8
|
+
res << javascript_include_tag("/netzke/netzke")
|
9
9
|
end
|
10
10
|
|
11
11
|
# Include CSS
|
12
12
|
def netzke_css_include(theme_name = :default)
|
13
13
|
# ExtJS base
|
14
|
-
res = stylesheet_link_tag("/extjs/resources/css/ext-all
|
14
|
+
res = stylesheet_link_tag("/extjs/resources/css/ext-all")
|
15
15
|
# ExtJS theming
|
16
|
-
res << stylesheet_link_tag("/extjs/resources/css/xtheme-#{theme_name}
|
16
|
+
res << stylesheet_link_tag("/extjs/resources/css/xtheme-#{theme_name}") unless theme_name == :default
|
17
17
|
# Netzke (dynamically generated)
|
18
|
-
res << stylesheet_link_tag("/netzke/netzke
|
18
|
+
res << stylesheet_link_tag("/netzke/netzke")
|
19
|
+
|
20
|
+
# External stylesheets (which cannot be loaded dynamically along with the rest of the widget, e.g. due to that
|
21
|
+
# relative paths are used in them)
|
22
|
+
res << stylesheet_link_tag(Netzke::Base.config[:external_css])
|
23
|
+
|
19
24
|
res
|
20
25
|
end
|
21
26
|
|
22
27
|
# JavaScript for all Netzke classes in this view, and Ext.onReady which renders all Netzke widgets in this view
|
23
28
|
def netzke_js
|
24
29
|
javascript_tag <<-END_OF_JAVASCRIPT
|
25
|
-
Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection
|
30
|
+
Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection
|
26
31
|
#{@content_for_netzke_js_classes}
|
27
32
|
Ext.onReady(function(){
|
28
33
|
#{@content_for_netzke_on_ready}
|
@@ -48,9 +53,9 @@ module Netzke
|
|
48
53
|
config[:name] = name
|
49
54
|
Netzke::Base.reg_widget(config)
|
50
55
|
w = Netzke::Base.instance_by_config(config)
|
56
|
+
w.before_load # inform the widget about initial load
|
51
57
|
content_for :netzke_js_classes, w.js_missing_code(@rendered_classes ||= [])
|
52
|
-
content_for :netzke_on_ready, w.js_widget_instance
|
53
|
-
content_for :netzke_on_ready, w.js_widget_render
|
58
|
+
content_for :netzke_on_ready, "#{w.js_widget_instance}\n\n#{w.js_widget_render}"
|
54
59
|
|
55
60
|
# Now mark this widget's class as rendered, so that we only generate it once per view
|
56
61
|
@rendered_classes << class_name unless @rendered_classes.include?(class_name)
|
data/lib/netzke/base.rb
CHANGED
@@ -51,14 +51,16 @@ module Netzke
|
|
51
51
|
:javascripts => [],
|
52
52
|
:stylesheets => [],
|
53
53
|
|
54
|
+
:external_css => [],
|
55
|
+
|
54
56
|
# AR model that provides us with persistent config functionality
|
55
57
|
:persistent_config_manager => "NetzkePreference",
|
56
58
|
|
57
59
|
# Default location of extjs library
|
58
60
|
:ext_location => defined?(RAILS_ROOT) && "#{RAILS_ROOT}/public/extjs",
|
59
61
|
|
60
|
-
# Default location of icons
|
61
|
-
:
|
62
|
+
# Default location of icons, relative to the root of the domain
|
63
|
+
:icons_uri => "/images/icons/",
|
62
64
|
|
63
65
|
# Default instance config
|
64
66
|
:default_config => {
|
@@ -132,7 +134,8 @@ module Netzke
|
|
132
134
|
api_points.each do |apip|
|
133
135
|
module_eval <<-END, __FILE__, __LINE__
|
134
136
|
def api_#{apip}(*args)
|
135
|
-
#{apip}
|
137
|
+
before_api_call_result = defined?(before_api_call) && before_api_call('#{apip}', *args) || {}
|
138
|
+
(before_api_call_result.empty? ? #{apip}(*args) : before_api_call_result).to_nifty_json
|
136
139
|
end
|
137
140
|
# FIXME: commented out because otherwise ColumnOperations stop working
|
138
141
|
# def #{apip}(*args)
|
@@ -163,6 +166,34 @@ module Netzke
|
|
163
166
|
rescue NameError
|
164
167
|
nil
|
165
168
|
end
|
169
|
+
|
170
|
+
# Example:
|
171
|
+
# masquarade_as(:role, 2)
|
172
|
+
# masquarade_as(:user, 4)
|
173
|
+
# masquarade_as(:world)
|
174
|
+
def self.masquerade_as(authority_level, authority_id = true)
|
175
|
+
reset_masquerading
|
176
|
+
session.merge!(:"masq_#{authority_level}" => authority_id)
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.reset_masquerading
|
180
|
+
session[:masq_world] = session[:masq_role] = session[:masq_user] = nil
|
181
|
+
end
|
182
|
+
|
183
|
+
# Who are we acting as?
|
184
|
+
def self.authority_level
|
185
|
+
if session[:masq_world]
|
186
|
+
:world
|
187
|
+
elsif session[:masq_role]
|
188
|
+
[:role, session[:masq_role]]
|
189
|
+
elsif session[:masq_user]
|
190
|
+
[:user, session[:masq_user]]
|
191
|
+
elsif session[:netzke_user_id]
|
192
|
+
[:self, session[:netzke_user_id]]
|
193
|
+
else
|
194
|
+
:none # or nil ?
|
195
|
+
end
|
196
|
+
end
|
166
197
|
|
167
198
|
# Widget initialization process
|
168
199
|
# * the config hash is available to the widget after the "super" call in the initializer
|
@@ -207,14 +238,14 @@ module Netzke
|
|
207
238
|
!persistent_config_manager_class.nil? && initial_config[:persistent_config]
|
208
239
|
end
|
209
240
|
|
210
|
-
#
|
241
|
+
# Access to own persistent config, e.g.:
|
211
242
|
# persistent_config["window.size"] = 100
|
212
243
|
# persistent_config["window.size"] => 100
|
213
|
-
# This method is user-aware
|
214
|
-
def persistent_config
|
215
|
-
if persistent_config_enabled?
|
244
|
+
# This method is user/role-aware
|
245
|
+
def persistent_config
|
246
|
+
if persistent_config_enabled?
|
216
247
|
config_class = self.class.persistent_config_manager_class
|
217
|
-
config_class.widget_name =
|
248
|
+
config_class.widget_name = persistence_key.to_s # pass to the config class our unique name
|
218
249
|
config_class
|
219
250
|
else
|
220
251
|
# if we can't use presistent config, all the calls to it will always return nil,
|
@@ -224,6 +255,13 @@ module Netzke
|
|
224
255
|
end
|
225
256
|
end
|
226
257
|
|
258
|
+
# Access to the global persistent config (e.g. of another widget)
|
259
|
+
def global_persistent_config(owner = nil)
|
260
|
+
config_class = self.class.persistent_config_manager_class
|
261
|
+
config_class.widget_name = owner
|
262
|
+
config_class
|
263
|
+
end
|
264
|
+
|
227
265
|
# A string which will identify NetzkePreference records for this widget.
|
228
266
|
# If <tt>persistence_key</tt> is passed, use it. Otherwise use global widget's id.
|
229
267
|
def persistence_key #:nodoc:
|
@@ -414,7 +452,7 @@ module Netzke
|
|
414
452
|
aggregatee_config = aggregator.aggregatees[aggr]
|
415
453
|
raise ArgumentError, "No aggregatee '#{aggr}' defined for widget '#{aggregator.global_id}'" if aggregatee_config.nil?
|
416
454
|
::ActiveSupport::Deprecation.warn("widget_class_name option is deprecated. Use class_name instead", caller) if aggregatee_config[:widget_class_name]
|
417
|
-
short_widget_class_name = aggregatee_config[:class_name] || aggregatee_config[:
|
455
|
+
short_widget_class_name = aggregatee_config[:class_name] || aggregatee_config[:widget_class_name]
|
418
456
|
raise ArgumentError, "No class_name specified for aggregatee #{aggr} of #{aggregator.global_id}" if short_widget_class_name.nil?
|
419
457
|
widget_class = "Netzke::#{short_widget_class_name}".constantize
|
420
458
|
|
data/lib/netzke/base_js.rb
CHANGED
@@ -37,7 +37,7 @@ module Netzke
|
|
37
37
|
non_late_aggregatees.each_pair do |aggr_name, aggr_config|
|
38
38
|
aggr_instance = aggregatee_instance(aggr_name.to_sym)
|
39
39
|
aggr_instance.before_load
|
40
|
-
res["#{aggr_name}_config"
|
40
|
+
res[:"#{aggr_name}_config"] = aggr_instance.js_config
|
41
41
|
end
|
42
42
|
|
43
43
|
# Api (besides the default "load_aggregatee_with_cache" - JavaScript side already knows about it)
|
@@ -88,12 +88,12 @@ module Netzke
|
|
88
88
|
|
89
89
|
# rendering
|
90
90
|
def js_widget_render
|
91
|
-
%Q{Netzke.page.#{name.jsonify}.render("#{name.to_s.split('_').join('-')}-
|
91
|
+
%Q{Netzke.page.#{name.jsonify}.render("#{name.to_s.split('_').join('-')}-netzke");} unless self.class.js_xtype == "netzkewindow"
|
92
92
|
end
|
93
93
|
|
94
94
|
# container for rendering
|
95
95
|
def js_widget_html
|
96
|
-
%Q{<div id="#{name.to_s.split('_').join('-')}-
|
96
|
+
%Q{<div id="#{name.to_s.split('_').join('-')}-netzke" class="netzke-widget"></div>}
|
97
97
|
end
|
98
98
|
|
99
99
|
#
|
data/test/unit/core_ext_test.rb
CHANGED
@@ -29,14 +29,14 @@ class CoreExtTest < ActiveSupport::TestCase
|
|
29
29
|
|
30
30
|
test "javascript-like access to hash data" do
|
31
31
|
a = {}
|
32
|
-
a["
|
33
|
-
assert_equal(100, a.
|
32
|
+
a["b"] = 100
|
33
|
+
assert_equal(100, a.b)
|
34
34
|
|
35
|
-
a.
|
36
|
-
assert_equal(200, a["
|
35
|
+
a.b = 200
|
36
|
+
assert_equal(200, a["b"])
|
37
37
|
|
38
|
-
a.
|
39
|
-
assert_equal(300, a[:
|
38
|
+
a.c = 300
|
39
|
+
assert_equal(300, a[:c])
|
40
40
|
end
|
41
41
|
|
42
42
|
test "jsonify" do
|
@@ -143,8 +143,8 @@ class NetzkeCoreTest < ActiveSupport::TestCase
|
|
143
143
|
|
144
144
|
test "widget instance by config" do
|
145
145
|
widget = Netzke::Base.instance_by_config({:class_name => 'Widget', :name => 'a_widget'})
|
146
|
-
|
147
|
-
|
146
|
+
assert_equal(Widget, widget.class)
|
147
|
+
assert_equal('a_widget', widget.name)
|
148
148
|
end
|
149
149
|
|
150
150
|
test "js inheritance" do
|
@@ -155,17 +155,17 @@ class NetzkeCoreTest < ActiveSupport::TestCase
|
|
155
155
|
|
156
156
|
test "class-level configuration" do
|
157
157
|
# predefined defaults
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
assert_equal(1, Netzke::Widget.config[:pref_one])
|
159
|
+
assert_equal(2, Netzke::Widget.config[:pref_two])
|
160
|
+
assert_equal(-1, Netzke::InheritedWidget.config[:pref_one])
|
161
|
+
assert_equal(2, Netzke::InheritedWidget.config[:pref_two])
|
162
162
|
|
163
163
|
Netzke::Widget.config[:pref_for_widget] = 1
|
164
164
|
Netzke::InheritedWidget.config[:pref_for_widget] = 2
|
165
165
|
|
166
|
-
|
167
|
-
|
168
|
-
|
166
|
+
# this is broken in 1.9
|
167
|
+
# assert_equal(1, Netzke::Widget.config[:pref_for_widget])
|
168
|
+
# assert_equal(2, Netzke::InheritedWidget.config[:pref_for_widget])
|
169
169
|
end
|
170
170
|
|
171
171
|
test "JS class names and scopes" do
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netzke-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 2
|
10
|
+
version: 0.5.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Sergei Kozlov
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-06-11 00:00:00 +02:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -78,27 +84,46 @@ has_rdoc: true
|
|
78
84
|
homepage: http://github.com/skozlov/netzke-core
|
79
85
|
licenses: []
|
80
86
|
|
81
|
-
post_install_message:
|
87
|
+
post_install_message: |+
|
88
|
+
|
89
|
+
========================================================================
|
90
|
+
|
91
|
+
Thanks for installing Netzke Core!
|
92
|
+
|
93
|
+
Run "./script/generate netzke_core" to finish the installation.
|
94
|
+
|
95
|
+
Netzke home page: http://netzke.org
|
96
|
+
Netzke Google Groups: http://groups.google.com/group/netzke
|
97
|
+
Netzke tutorials: http://blog.writelesscode.com
|
98
|
+
|
99
|
+
========================================================================
|
100
|
+
|
82
101
|
rdoc_options:
|
83
102
|
- --charset=UTF-8
|
84
103
|
require_paths:
|
85
104
|
- lib
|
86
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
87
107
|
requirements:
|
88
108
|
- - ">="
|
89
109
|
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
90
113
|
version: "0"
|
91
|
-
version:
|
92
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
93
116
|
requirements:
|
94
117
|
- - ">="
|
95
118
|
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
96
122
|
version: "0"
|
97
|
-
version:
|
98
123
|
requirements: []
|
99
124
|
|
100
125
|
rubyforge_project: netzke-core
|
101
|
-
rubygems_version: 1.3.
|
126
|
+
rubygems_version: 1.3.7
|
102
127
|
signing_key:
|
103
128
|
specification_version: 3
|
104
129
|
summary: Build ExtJS/Rails widgets with minimum effort
|