netzke-core 0.7.7 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -2
- data/CHANGELOG.md +572 -0
- data/LICENSE +7 -1
- data/README.md +345 -29
- data/Rakefile +3 -3
- data/app/controllers/netzke_controller.rb +37 -48
- data/config/ci/before-travis.sh +3 -4
- data/javascripts/base.js +86 -150
- data/javascripts/ext.js +180 -210
- data/javascripts/{core_extensions.js → js_extensions.js} +0 -0
- data/lib/netzke-core.rb +16 -6
- data/lib/netzke/base.rb +84 -107
- data/lib/netzke/core.rb +7 -41
- data/lib/netzke/core/action_config.rb +37 -0
- data/lib/netzke/core/actions.rb +123 -0
- data/lib/netzke/core/client_class.rb +252 -0
- data/lib/netzke/core/component_config.rb +12 -0
- data/lib/netzke/core/composition.rb +274 -0
- data/lib/netzke/core/config_to_dsl_delegator.rb +69 -0
- data/lib/netzke/core/configuration.rb +63 -0
- data/lib/netzke/core/css_config.rb +51 -0
- data/lib/netzke/core/dynamic_assets.rb +19 -49
- data/lib/netzke/{embedding.rb → core/embedding.rb} +4 -6
- data/lib/netzke/core/endpoint_response.rb +15 -0
- data/lib/netzke/core/javascript.rb +111 -0
- data/lib/netzke/core/panel.rb +11 -0
- data/lib/netzke/{plugins.rb → core/plugins.rb} +10 -5
- data/lib/netzke/core/railz.rb +4 -0
- data/lib/netzke/{railz → core/railz}/action_view_ext.rb +22 -18
- data/lib/netzke/core/railz/action_view_ext/ext.rb +49 -0
- data/lib/netzke/core/railz/controller_extensions.rb +17 -0
- data/lib/netzke/core/railz/engine.rb +16 -0
- data/lib/netzke/core/railz/routes.rb +10 -0
- data/lib/netzke/core/ruby_ext.rb +5 -0
- data/lib/netzke/core/ruby_ext/array.rb +23 -0
- data/lib/netzke/core/ruby_ext/hash.rb +47 -0
- data/lib/netzke/{core_ext → core/ruby_ext}/string.rb +2 -7
- data/lib/netzke/core/ruby_ext/symbol.rb +13 -0
- data/lib/netzke/{core_ext → core/ruby_ext}/time_with_zone.rb +0 -0
- data/lib/netzke/core/services.rb +130 -0
- data/lib/netzke/core/session.rb +15 -19
- data/lib/netzke/core/state.rb +40 -0
- data/lib/netzke/core/stylesheets.rb +48 -0
- data/lib/netzke/core/version.rb +2 -2
- data/lib/netzke/plugin.rb +8 -11
- data/netzke-core.gemspec +69 -59
- data/test/core_test_app/Gemfile +2 -20
- data/test/core_test_app/Gemfile.lock +65 -74
- data/test/core_test_app/app/components/card_component_loader.rb +4 -4
- data/test/core_test_app/app/components/component_loader.rb +40 -120
- data/test/core_test_app/app/components/component_loader/javascripts/component_loader.js +49 -0
- data/test/core_test_app/app/components/component_with_actions.rb +61 -47
- data/test/core_test_app/app/components/component_with_custom_css.rb +8 -5
- data/test/core_test_app/app/components/component_with_js_mixin.rb +11 -5
- data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_one.js +1 -1
- data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_two.js +1 -1
- data/test/core_test_app/app/components/component_with_js_mixin/javascripts/method_set_one.js +1 -1
- data/test/core_test_app/app/components/component_with_nested_through.rb +2 -2
- data/test/core_test_app/app/components/component_with_prebuilt_toolbar_control.rb +12 -0
- data/test/core_test_app/app/components/component_with_prebuilt_toolbar_control/javascripts/component_with_prebuilt_toolbar_control.js +12 -0
- data/test/core_test_app/app/components/component_with_required_js.rb +24 -0
- data/test/core_test_app/app/components/configurable_on_class_level.rb +8 -0
- data/test/core_test_app/app/components/dsl_delegated_properties.rb +4 -0
- data/test/core_test_app/app/components/dsl_delegated_properties_base.rb +5 -0
- data/test/core_test_app/app/components/dynamic_tab_panel/javascripts/dynamic_tab_panel.js +2 -2
- data/test/core_test_app/app/components/ext_direct/composite.rb +32 -33
- data/test/core_test_app/app/components/ext_direct/details.rb +2 -4
- data/test/core_test_app/app/components/ext_direct/selector.rb +20 -22
- data/test/core_test_app/app/components/ext_direct/statistics.rb +2 -4
- data/test/core_test_app/app/components/extended_component_with_actions.rb +7 -3
- data/test/core_test_app/app/components/extended_component_with_js_mixin.rb +7 -4
- data/test/core_test_app/app/components/extended_component_with_js_mixin/javascripts/some_method_set.js +1 -1
- data/test/core_test_app/app/components/extended_server_caller.rb +20 -14
- data/test/core_test_app/app/components/hello_world.rb +23 -0
- data/test/core_test_app/app/components/hello_world/javascripts/hello_world.js +12 -0
- data/test/core_test_app/app/components/included.js +2 -2
- data/test/core_test_app/app/components/kinda_complex_component.rb +1 -3
- data/test/core_test_app/app/components/kinda_complex_component/basic_stuff.rb +15 -17
- data/test/core_test_app/app/components/kinda_complex_component/extra_stuff.rb +4 -5
- data/test/core_test_app/app/components/loader_of_component_with_custom_css.rb +14 -5
- data/test/core_test_app/app/components/localized_panel.rb +23 -25
- data/test/core_test_app/app/components/multipane_component_loader.rb +19 -20
- data/test/core_test_app/app/components/nested_component.rb +4 -5
- data/test/core_test_app/app/components/panel_with_plugin.rb +8 -3
- data/test/core_test_app/app/components/panel_with_tools.rb +15 -14
- data/test/core_test_app/app/components/plugin_with_components.rb +20 -12
- data/test/core_test_app/app/components/scoped_components/deep_scoped_components/some_deep_scoped_component.rb +5 -2
- data/test/core_test_app/app/components/scoped_components/extended_scoped_component.rb +5 -2
- data/test/core_test_app/app/components/scoped_components/some_scoped_component.rb +5 -2
- data/test/core_test_app/app/components/server_caller.rb +39 -17
- data/test/core_test_app/app/components/server_caller/javascripts/server_caller.js +42 -0
- data/test/core_test_app/app/components/server_counter.rb +18 -82
- data/test/core_test_app/app/components/server_counter/javascripts/server_counter.js +53 -0
- data/test/core_test_app/app/components/simple_authentication_component.rb +46 -0
- data/test/core_test_app/app/components/simple_component.rb +8 -3
- data/test/core_test_app/app/components/simple_composite.rb +12 -0
- data/test/core_test_app/app/components/simple_form_with_file_upload.rb +49 -0
- data/test/core_test_app/app/components/simple_panel.rb +2 -2
- data/test/core_test_app/app/components/simple_tab_panel.rb +24 -3
- data/test/core_test_app/app/components/simple_window.rb +4 -2
- data/test/core_test_app/app/components/some_composite.rb +77 -48
- data/test/core_test_app/app/components/some_plugin.rb +31 -30
- data/test/core_test_app/app/components/stateful_component.rb +46 -0
- data/test/core_test_app/app/components/stateful_component_with_shared_state.rb +11 -0
- data/test/core_test_app/app/components/window_with_simple_component.rb +14 -0
- data/test/core_test_app/app/views/layouts/application.html.erb +1 -1
- data/test/core_test_app/app/views/simple_rails/multiple_nested.html.erb +7 -19
- data/test/core_test_app/app/views/simple_rails/panel.html.erb +1 -0
- data/test/core_test_app/config/database.yml.travis +3 -5
- data/test/core_test_app/config/environments/production.rb +1 -1
- data/test/core_test_app/config/initializers/netzke.rb +3 -1
- data/test/core_test_app/config/locales/en.yml +9 -4
- data/test/core_test_app/config/locales/es.yml +4 -2
- data/test/core_test_app/config/routes.rb +2 -8
- data/test/core_test_app/db/schema.rb +3 -11
- data/test/core_test_app/features/actions_and_tools.feature +1 -0
- data/test/core_test_app/features/client-server.feature +7 -0
- data/test/core_test_app/features/component_loader.feature +13 -13
- data/test/core_test_app/features/composition.feature +14 -0
- data/test/core_test_app/features/config_to_dsl_delegation.feature +10 -0
- data/test/core_test_app/features/file_inclusion.feature +1 -1
- data/test/core_test_app/features/i18n.feature +4 -4
- data/test/core_test_app/features/js_include.feature +1 -1
- data/test/core_test_app/features/persistence.feature +21 -5
- data/test/core_test_app/features/step_definitions/generic_steps.rb +14 -0
- data/test/core_test_app/features/support/paths.rb +0 -3
- data/test/core_test_app/public/images/icons/accept.png +0 -0
- data/test/core_test_app/public/images/icons/anchor.png +0 -0
- data/test/core_test_app/public/images/icons/tick.png +0 -0
- data/test/core_test_app/spec/action_config_spec.rb +15 -0
- data/test/core_test_app/spec/{component/actions_spec.rb → actions_spec.rb} +38 -36
- data/test/core_test_app/spec/base_spec.rb +35 -0
- data/test/core_test_app/spec/client_class_spec.rb +17 -0
- data/test/core_test_app/spec/component +0 -0
- data/test/core_test_app/spec/composition_spec.rb +118 -0
- data/test/core_test_app/spec/core_ext_spec.rb +3 -14
- data/test/core_test_app/spec/endpoint_response_spec.rb +17 -0
- data/test/core_test_app/spec/javascript_spec.rb +33 -0
- data/test/core_test_app/spec/js_class_config_scope.rb +37 -0
- data/test/core_test_app/spec/panel_spec.rb +11 -0
- data/test/core_test_app/spec/services_spec.rb +16 -0
- data/test/core_test_app/spec/state_spec.rb +20 -0
- data/test/unit/core_ext_test.rb +0 -53
- data/test/unit/netzke_core_test.rb +11 -11
- metadata +76 -62
- data/CHANGELOG.rdoc +0 -325
- data/javascripts/touch.js +0 -58
- data/lib/netzke/actions.rb +0 -107
- data/lib/netzke/composition.rb +0 -224
- data/lib/netzke/config_to_dsl_delegator.rb +0 -43
- data/lib/netzke/configuration.rb +0 -195
- data/lib/netzke/core/masquerading.rb +0 -34
- data/lib/netzke/core_ext.rb +0 -6
- data/lib/netzke/core_ext/array.rb +0 -30
- data/lib/netzke/core_ext/hash.rb +0 -86
- data/lib/netzke/core_ext/symbol.rb +0 -21
- data/lib/netzke/ext_component.rb +0 -25
- data/lib/netzke/inheritance.rb +0 -31
- data/lib/netzke/javascript.rb +0 -382
- data/lib/netzke/javascript/scopes.rb +0 -39
- data/lib/netzke/railz.rb +0 -4
- data/lib/netzke/railz/action_view_ext/ext.rb +0 -64
- data/lib/netzke/railz/action_view_ext/touch.rb +0 -52
- data/lib/netzke/railz/controller_extensions.rb +0 -33
- data/lib/netzke/railz/engine.rb +0 -48
- data/lib/netzke/railz/routes.rb +0 -7
- data/lib/netzke/services.rb +0 -101
- data/lib/netzke/session.rb +0 -54
- data/lib/netzke/state.rb +0 -91
- data/lib/netzke/stylesheets.rb +0 -65
- data/test/core_test_app/app/components/component_with_included_js.rb +0 -16
- data/test/core_test_app/app/components/component_with_session_persistence.rb +0 -35
- data/test/core_test_app/app/components/deprecated/server_caller.rb +0 -20
- data/test/core_test_app/app/components/dynamic_tab_panel.rb +0 -19
- data/test/core_test_app/app/components/hello_world_component.rb +0 -31
- data/test/core_test_app/app/components/touch/hello_world_component.rb +0 -25
- data/test/core_test_app/app/components/touch/server_caller.rb +0 -28
- data/test/core_test_app/app/components/touch/simple_carousel.rb +0 -17
- data/test/core_test_app/app/controllers/touch_controller.rb +0 -6
- data/test/core_test_app/app/helpers/touch_helper.rb +0 -2
- data/test/core_test_app/app/views/layouts/touch.html.erb +0 -13
- data/test/core_test_app/db/migrate/20110110132720_create_netzke_component_states.rb +0 -20
- data/test/core_test_app/features/step_definitions/touch_steps.rb +0 -3
- data/test/core_test_app/features/touch.feature +0 -10
- data/test/core_test_app/gemfiles/rails3_1.gemfile +0 -16
- data/test/core_test_app/gemfiles/rails3_2.gemfile +0 -16
- data/test/core_test_app/spec/component/base_spec.rb +0 -36
- data/test/core_test_app/spec/component/component_spec.rb +0 -20
- data/test/core_test_app/spec/component/composition_spec.rb +0 -132
- data/test/core_test_app/spec/component/configuration_spec.rb +0 -61
- data/test/core_test_app/spec/component/javascript_spec.rb +0 -16
- data/test/core_test_app/spec/component/state_spec.rb +0 -18
@@ -1,26 +1,30 @@
|
|
1
|
-
require 'netzke/railz/action_view_ext/ext'
|
2
|
-
require 'netzke/railz/action_view_ext/touch'
|
1
|
+
require 'netzke/core/railz/action_view_ext/ext'
|
3
2
|
module Netzke
|
4
3
|
module Railz
|
5
4
|
module ActionViewExt
|
6
5
|
include Ext
|
7
|
-
include Touch
|
8
6
|
|
9
|
-
# A helper to
|
7
|
+
# A helper to load Netzke and Ext JS files. Usually used in the layout.
|
10
8
|
#
|
11
9
|
# Params:
|
12
|
-
#
|
13
|
-
# * :theme - the name of theme to apply
|
14
|
-
# * :cache - enable Rails caching of assets
|
10
|
+
#
|
11
|
+
# * :theme - the name of theme to apply; follows simple convention of including css files named "ext-(theme)".
|
15
12
|
#
|
16
13
|
# E.g.:
|
17
|
-
# <%= netzke_init :theme => :grey %>
|
18
14
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
15
|
+
# <%= load_netzke theme: "neptune" %>
|
16
|
+
#
|
17
|
+
# Other theme options that may work (unless Sencha introduces some/other conventions):
|
18
|
+
#
|
19
|
+
# - all (standard)
|
20
|
+
# - all-gray
|
21
|
+
# - all-access
|
22
|
+
#
|
23
|
+
# * :minified - set to +true+ to load minified JS and CSS for Ext JS also in development env
|
24
|
+
def load_netzke(params = {})
|
22
25
|
Netzke::Core.platform = params[:platform] || :ext
|
23
|
-
|
26
|
+
params[:minified] = !Rails.env.development? if params[:minified].nil?
|
27
|
+
params[:theme] ||= :all
|
24
28
|
|
25
29
|
raw([netzke_css_include(params), netzke_css(params), netzke_js_include(params), netzke_js(params)].join("\n"))
|
26
30
|
end
|
@@ -40,11 +44,11 @@ module Netzke
|
|
40
44
|
|
41
45
|
config[:name] = name
|
42
46
|
|
43
|
-
# Register the component in session
|
44
|
-
Netzke::Core.reg_component(config)
|
45
|
-
|
46
47
|
cmp = Netzke::Base.instance_by_config(config)
|
47
|
-
|
48
|
+
|
49
|
+
# Register the component in session
|
50
|
+
session[:netzke_components] ||= {}
|
51
|
+
session[:netzke_components][cmp.js_id.to_sym] = config
|
48
52
|
|
49
53
|
content_for :netzke_js_classes, raw(cmp.js_missing_code(@rendered_classes))
|
50
54
|
|
@@ -53,7 +57,7 @@ module Netzke
|
|
53
57
|
content_for :netzke_on_ready, raw("#{cmp.js_component_instance}\n\n#{cmp.js_component_render}")
|
54
58
|
|
55
59
|
# Now mark all this component's dependency classes (including self) as rendered (by storing their xtypes), so that we only generate a class once per view
|
56
|
-
@rendered_classes = (@rendered_classes + cmp.dependency_classes.map
|
60
|
+
@rendered_classes = (@rendered_classes + cmp.dependency_classes.map{|k| k.js_config.xtype}).uniq
|
57
61
|
|
58
62
|
# Return the html for this component
|
59
63
|
raw(cmp.js_component_html)
|
@@ -79,7 +83,7 @@ module Netzke
|
|
79
83
|
send :"netzke_#{Netzke::Core.platform}_js_include", params
|
80
84
|
end
|
81
85
|
|
82
|
-
# Inline JavaScript for all Netzke classes on the page, as well as Ext.onReady
|
86
|
+
# Inline JavaScript for all Netzke classes on the page, as well as Ext.onReady, which renders Netzke components in this view after the page is loaded
|
83
87
|
def netzke_js(params = {})
|
84
88
|
send :"netzke_#{Netzke::Core.platform}_js", params
|
85
89
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Netzke
|
2
|
+
module Railz
|
3
|
+
module ActionViewExt
|
4
|
+
# Implementation of Ext-specific Netzke helpers
|
5
|
+
module Ext
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def netzke_ext_css_include(params)
|
10
|
+
# ExtJS base
|
11
|
+
res = ["#{Netzke::Core.ext_uri}/resources/css/ext-#{params[:theme]}"]
|
12
|
+
|
13
|
+
# Netzke-related dynamic css
|
14
|
+
res << netzke_path(:ext)
|
15
|
+
|
16
|
+
res += Netzke::Core.external_ext_css
|
17
|
+
|
18
|
+
stylesheet_link_tag(*res)
|
19
|
+
end
|
20
|
+
|
21
|
+
def netzke_ext_js_include(params)
|
22
|
+
res = []
|
23
|
+
|
24
|
+
# ExtJS
|
25
|
+
res << (params[:minified] ? "#{Netzke::Core.ext_uri}/ext-all" : "#{Netzke::Core.ext_uri}/ext-all-debug")
|
26
|
+
|
27
|
+
# Ext I18n
|
28
|
+
res << "#{Netzke::Core.ext_uri}/locale/ext-lang-#{I18n.locale}" if I18n.locale != :en
|
29
|
+
|
30
|
+
# Netzke-related dynamic JavaScript
|
31
|
+
res << netzke_path(:ext)
|
32
|
+
|
33
|
+
javascript_include_tag(*res)
|
34
|
+
end
|
35
|
+
|
36
|
+
def netzke_ext_js(params)
|
37
|
+
res = []
|
38
|
+
res << content_for(:netzke_js_classes)
|
39
|
+
|
40
|
+
res << "Ext.onReady(function(){"
|
41
|
+
res << content_for(:netzke_on_ready)
|
42
|
+
res << "});"
|
43
|
+
|
44
|
+
javascript_tag(res.join("\n"))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Netzke
|
2
|
+
module Railz
|
3
|
+
# Before each request, Netzke::Base.controller and Netzke::Base.session are set, to be accessible from components.
|
4
|
+
module ControllerExtensions
|
5
|
+
def self.included(base)
|
6
|
+
base.send(:before_filter, :set_controller_and_session)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def set_controller_and_session
|
12
|
+
Netzke::Base.controller = self
|
13
|
+
Netzke::Base.session = session
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Netzke
|
2
|
+
module Railz
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
initializer "netzke.core" do |app|
|
5
|
+
app.config.eager_load_paths -= ["#{app.config.root}/app/components"]
|
6
|
+
app.config.autoload_paths += ["#{app.config.root}/app/components"]
|
7
|
+
end
|
8
|
+
|
9
|
+
# before loading initializers
|
10
|
+
config.before_initialize do |app|
|
11
|
+
Netzke::Core.ext_path = Rails.root.join('public', Netzke::Core.ext_uri[1..-1])
|
12
|
+
Netzke::Core.with_icons = File.exists?("#{::Rails.root}/public#{Netzke::Core.icons_uri}") if Netzke::Core.with_icons.nil?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module ActionDispatch::Routing
|
2
|
+
class Mapper
|
3
|
+
# Enable routes for Netzke assets and endpoint calls. By default the URL is "/netzke", but this can be changed by providing an argument:
|
4
|
+
#
|
5
|
+
# netzke "/some/path/netzke"
|
6
|
+
def netzke(prefix = "/netzke")
|
7
|
+
match "#{prefix}/:action(.:format)", to: "netzke", as: 'netzke'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Array
|
2
|
+
def deep_map(&block)
|
3
|
+
self.map{ |el| el.respond_to?(:deep_map) ? block.call(el.deep_map(&block)) : block.call(el) }.compact
|
4
|
+
end
|
5
|
+
|
6
|
+
def jsonify
|
7
|
+
self.map{ |el| el.is_a?(Array) || el.is_a?(Hash) ? el.jsonify : el }
|
8
|
+
end
|
9
|
+
|
10
|
+
# Camelizes the keys of hashes and converts them to JSON
|
11
|
+
def to_nifty_json
|
12
|
+
self.jsonify.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
def deep_each_pair(&block)
|
16
|
+
self.each{ |el| el.respond_to?('deep_each_pair') && el.deep_each_pair(&block) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def deep_freeze
|
20
|
+
each { |j| j.deep_freeze if j.respond_to? :deep_freeze }
|
21
|
+
freeze
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Hash
|
2
|
+
def deep_map(&block)
|
3
|
+
self.dup.tap do |h|
|
4
|
+
h.each_pair do |k,v|
|
5
|
+
h[k] = v.deep_map(&block) if v.respond_to?('deep_map')
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def deep_each_pair(&block)
|
11
|
+
self.each_pair do |k,v|
|
12
|
+
v.respond_to?('deep_each_pair') ? v.deep_each_pair(&block) : yield(k,v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def jsonify
|
17
|
+
self.inject({}) do |h,(k,v)|
|
18
|
+
new_key = (k.is_a?(String) || k.is_a?(Symbol)) && !k.is_a?(ActiveSupport::JSON::Variable) ? k.jsonify : k
|
19
|
+
new_value = v.is_a?(Array) || v.is_a?(Hash) ? v.jsonify : v
|
20
|
+
h.merge(new_key => new_value)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# First camelizes the keys, then convert the whole hash to JSON
|
25
|
+
def to_nifty_json
|
26
|
+
self.jsonify.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
def deep_freeze
|
30
|
+
each { |k,v| v.deep_freeze if v.respond_to? :deep_freeze }
|
31
|
+
freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
# From http://rubyworks.github.com/facets
|
35
|
+
def update_keys #:yield:
|
36
|
+
if block_given?
|
37
|
+
keys.each { |old_key| store(yield(old_key), delete(old_key)) }
|
38
|
+
else
|
39
|
+
to_enum(:update_keys)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def literalize_keys
|
44
|
+
update_keys{ |k| k.to_s.l }
|
45
|
+
self
|
46
|
+
end
|
47
|
+
end
|
@@ -1,14 +1,10 @@
|
|
1
1
|
class String
|
2
2
|
def jsonify
|
3
|
-
|
4
|
-
# '_some_string' should become '_someString' and not 'SomeString'
|
5
|
-
'_' + self[1..-1].camelize(:lower)
|
6
|
-
else
|
7
|
-
self.camelize(:lower)
|
8
|
-
end
|
3
|
+
self.camelize(:lower)
|
9
4
|
end
|
10
5
|
|
11
6
|
# Converts self to "literal JSON"-string - one that doesn't get quotes appended when being sent "to_json" method
|
7
|
+
# TODO: get rid of it
|
12
8
|
def l
|
13
9
|
ActiveSupport::JSON::Variable.new(self)
|
14
10
|
end
|
@@ -27,5 +23,4 @@ class String
|
|
27
23
|
def to_b
|
28
24
|
self != "false"
|
29
25
|
end
|
30
|
-
|
31
26
|
end
|
File without changes
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Netzke::Core
|
2
|
+
# The client-server communication between the JavaScript and Ruby side of a component is provided by means of "endpoints".
|
3
|
+
#
|
4
|
+
# == Defining an endpoint
|
5
|
+
#
|
6
|
+
# An endpoint is defined through the +endpoint+ class method on the Ruby class:
|
7
|
+
#
|
8
|
+
# endpoint :do_something do |params, this|
|
9
|
+
# # ...
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# The first block argument will contain the hash of arguments provided at the moment of calling the endpoint from the JavaScript side (see "Calling an endpoint from JavaScript").
|
13
|
+
# The second block argument is used for "calling" JavaScript methods as a response from the server (see "Envoking JavaScript methods from the server").
|
14
|
+
#
|
15
|
+
# == Calling an endpoint from JavaScript
|
16
|
+
#
|
17
|
+
# By defining the endpoint on the Ruby class, the client side automatically gets an equally named (but camelcased) method that is used to call the endpoint at the server. In the previous example, that would be +doSomething+. Its signature goes as follows:
|
18
|
+
#
|
19
|
+
# this.doSomething(argsObject, callbackFunction, scope);
|
20
|
+
#
|
21
|
+
# * +argsObject+ is what the server side will receive as the +params+ argument
|
22
|
+
# * +callbackFunction+ (optional) will be called after the server successfully processes the request
|
23
|
+
# * +scope+ (optional) the scope in which +callbackFunction+ will be called
|
24
|
+
#
|
25
|
+
# The callback function can optionally receive an argument set by the endpoint at the server (see "Providing the argument to the callback function").
|
26
|
+
#
|
27
|
+
# == Envoking JavaScript methods from the server
|
28
|
+
#
|
29
|
+
# An endpoint, after doing some useful job at the server, is able to instruct the client side of the component to call multiple methods (preserving the call order) with provided arguments. It's done by using the second parameter of the endpoint block (which is illustratively called 'this'):
|
30
|
+
#
|
31
|
+
# endpoint :do_something do |params, this|
|
32
|
+
# # ... do the thing
|
33
|
+
# this.set_title("New title")
|
34
|
+
# this.add_class("some-extra-css")
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# This will result in successive calling the +setTitle+ and +addClass+ methods on the JavaScript instance of our component.
|
38
|
+
#
|
39
|
+
# Besides "calling" methods on the current component itself, it's also possible to address its instantiated children at any level of the hierarchy:
|
40
|
+
#
|
41
|
+
# endpoint :do_something do |params, this|
|
42
|
+
# # ... do the thing
|
43
|
+
# this.east_panel_component.set_title("New east panel title")
|
44
|
+
# this.east_panel_component.deep_nested_component.do_something_very_special("With", "some", "arguments")
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# == Providing arguments to the callback function
|
48
|
+
#
|
49
|
+
# The callback function provided at the moment of calling an endpoint may receive an argument set by the endpoint by "calling" the special +netzke_set_result+ method. :
|
50
|
+
#
|
51
|
+
# endpoint :do_something do |params, this|
|
52
|
+
# # ... do the thing
|
53
|
+
# this.netzke_set_result(42)
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# By calling the endpoint from the client side like this:
|
57
|
+
#
|
58
|
+
# this.doSomething({}, function(result){ console.debug(result); });
|
59
|
+
#
|
60
|
+
# ... the value of +result+ after the execution of the endpoint will be set to 42. Using this mechanism can be seen as doing an asyncronous call to a function at the server, which returns a value.
|
61
|
+
#
|
62
|
+
# == Overriding an endpoint
|
63
|
+
#
|
64
|
+
# When overriding an endpoint, you can call the original endpoint by using +super+ and explicitely providing the block parameters to it:
|
65
|
+
#
|
66
|
+
# endpoint :do_something do |params, this|
|
67
|
+
# super(params, this)
|
68
|
+
# this.doMore
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# If you want to reuse the original arguments set in +super+, you can access them from the +this+ object. Provided we are overriding the +do_something+ endpoint from the example in "Envoking JavaScript methods from the server", we will have:
|
72
|
+
#
|
73
|
+
# endpoint :do_something do |params, this|
|
74
|
+
# super(params, this)
|
75
|
+
# original_arguments_for_set_title = this.set_title # => ["New title"]
|
76
|
+
# original_arguments_for_add_class = this.add_class # => ["some-extra-css"]
|
77
|
+
# end
|
78
|
+
module Services
|
79
|
+
extend ActiveSupport::Concern
|
80
|
+
|
81
|
+
included do
|
82
|
+
# Returns all endpoints as a hash
|
83
|
+
class_attribute :endpoints
|
84
|
+
self.endpoints = {}
|
85
|
+
end
|
86
|
+
|
87
|
+
module ClassMethods
|
88
|
+
def endpoint(name, options = {}, &block)
|
89
|
+
register_endpoint(name)
|
90
|
+
define_method("#{name}_endpoint", &block)
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
|
95
|
+
# Registers an endpoint at the class level
|
96
|
+
def register_endpoint(ep)
|
97
|
+
self.endpoints = self.endpoints.dup if self.superclass.respond_to?(:endpoints) && self.endpoints == self.superclass.endpoints # only dup for the first endpoint declaration
|
98
|
+
self.endpoints[ep.to_sym] = true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Invokes an endpoint call
|
103
|
+
# +endpoint+ may contain the path to the endpoint in a component down the hierarchy, e.g.:
|
104
|
+
#
|
105
|
+
# invoke_endpoint(:users__center__get_data, params)
|
106
|
+
def invoke_endpoint(endpoint, params)
|
107
|
+
if self.class.endpoints[endpoint.to_sym]
|
108
|
+
endpoint_response = Netzke::Core::EndpointResponse.new
|
109
|
+
send("#{endpoint}_endpoint", params, endpoint_response)
|
110
|
+
|
111
|
+
endpoint_response
|
112
|
+
else
|
113
|
+
# Let's try to find it recursively in a component down the hierarchy
|
114
|
+
child_component, *action = endpoint.to_s.split('__')
|
115
|
+
child_component = child_component.to_sym
|
116
|
+
action = !action.empty? && action.join("__").to_sym
|
117
|
+
|
118
|
+
raise RuntimeError, "Component '#{self.class.name}' does not have endpoint '#{endpoint}'" if !action
|
119
|
+
|
120
|
+
if components[child_component]
|
121
|
+
component_instance(child_component).invoke_endpoint(action, params)
|
122
|
+
else
|
123
|
+
# component_missing can be overridden if necessary
|
124
|
+
component_missing(child_component)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
data/lib/netzke/core/session.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
-
module Netzke
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Netzke::Core
|
2
|
+
# Implements component-specific session manupulation.
|
3
|
+
module Session
|
4
|
+
# Instance of this class is returned through component_session, and allows writing/reading to/from the session part reserved for a specific component (specified by component's js_id).
|
5
|
+
class ComponentSessionProxy < Object
|
6
|
+
def initialize(component_id)
|
7
|
+
@session = Netzke::Base.session.nil? ? {} : Netzke::Base.session[component_id] ||= {}
|
7
8
|
end
|
8
9
|
|
9
|
-
#
|
10
|
-
def
|
11
|
-
session
|
12
|
-
end
|
13
|
-
|
14
|
-
def current_user
|
15
|
-
Netzke::Core.controller.respond_to?(Netzke::Core.current_user_method) && Netzke::Core.controller.send(Netzke::Core.current_user_method) || nil
|
10
|
+
# Delegate everything to session
|
11
|
+
def method_missing(method, *args)
|
12
|
+
@session.send(method, *args)
|
16
13
|
end
|
14
|
+
end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
session[:netzke_components][config[:name]] = config
|
22
|
-
end
|
16
|
+
# Component-specific session.
|
17
|
+
def component_session
|
18
|
+
@component_session_proxy ||= ComponentSessionProxy.new(js_id)
|
23
19
|
end
|
24
20
|
end
|
25
|
-
end
|
21
|
+
end
|