netzke-core 0.5.1 → 0.5.2
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 +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
|