netzke-core 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +16 -1
- data/Gemfile +12 -0
- data/README.md +22 -15
- data/Rakefile +19 -38
- data/app/controllers/netzke_controller.rb +1 -79
- data/javascripts/ext.js +17 -13
- data/lib/netzke/base.rb +6 -2
- data/lib/netzke/core/action_config.rb +7 -0
- data/lib/netzke/core/actions.rb +6 -32
- data/lib/netzke/core/client_class.rb +1 -1
- data/lib/netzke/core/component_config.rb +1 -1
- data/lib/netzke/core/composition.rb +17 -111
- data/lib/netzke/core/config_to_dsl_delegator.rb +0 -7
- data/lib/netzke/core/configuration.rb +48 -0
- data/lib/netzke/core/dsl_support.rb +71 -0
- data/lib/netzke/core/dynamic_assets.rb +10 -1
- data/lib/netzke/core/embedding.rb +2 -2
- data/lib/netzke/core/html.rb +29 -0
- data/lib/netzke/core/javascript.rb +32 -26
- data/lib/netzke/core/railz/action_view_ext/ext.rb +2 -2
- data/lib/netzke/core/railz/controller_extensions.rb +96 -3
- data/lib/netzke/core/railz/routes.rb +14 -3
- data/lib/netzke/core/ruby_ext/array.rb +4 -18
- data/lib/netzke/core/ruby_ext/hash.rb +19 -25
- data/lib/netzke/core/ruby_ext/time_with_zone.rb +1 -1
- data/lib/netzke/core/ruby_ext.rb +0 -2
- data/lib/netzke/core/session.rb +8 -1
- data/lib/netzke/core/state.rb +3 -3
- data/lib/netzke/core/version.rb +1 -1
- data/lib/netzke/core.rb +15 -7
- data/lib/netzke-core.rb +2 -9
- data/tasks/app_test_tasks.rake +94 -0
- data/tasks/rake_helper.rb +51 -0
- data/test/core_test_app/README +2 -2
- data/test/core_test_app/app/assets/javascripts/expect/expect.js +1253 -0
- data/test/core_test_app/app/assets/javascripts/mocha/mocha.js +5340 -0
- data/test/core_test_app/app/assets/stylesheets/mocha/mocha.css +231 -0
- data/test/core_test_app/app/components/{component_with_actions.rb → actions.rb} +7 -9
- data/test/core_test_app/app/components/{some_composite.rb → composition.rb} +16 -5
- data/test/core_test_app/app/components/{component_with_custom_css → css_inclusion}/stylesheets/custom.css +2 -2
- data/test/core_test_app/app/components/css_inclusion.rb +12 -0
- data/test/core_test_app/app/components/{component_loader/javascripts/component_loader.js → dynamic_loading/javascripts/dynamic_loading.js} +9 -1
- data/test/core_test_app/app/components/{component_loader.rb → dynamic_loading.rb} +12 -5
- data/test/core_test_app/app/components/{server_caller/javascripts/server_caller.js → endpoints/javascripts/endpoints.js} +10 -6
- data/test/core_test_app/app/components/{server_caller.rb → endpoints.rb} +12 -8
- data/test/core_test_app/app/components/{extended_server_caller.rb → endpoints_extended.rb} +6 -4
- data/test/core_test_app/app/components/ext_direct/composite.rb +5 -1
- data/test/core_test_app/app/components/feedback.rb +26 -0
- data/test/core_test_app/app/components/haml_panel/html/body.html.haml +10 -0
- data/test/core_test_app/app/components/haml_panel/html/server_response.html.haml +3 -0
- data/test/core_test_app/app/components/haml_panel.rb +32 -0
- data/test/core_test_app/app/components/hello_world.rb +1 -0
- data/test/core_test_app/app/components/js_inclusion/javascripts/extra_one.js +2 -0
- data/test/core_test_app/app/components/js_inclusion/javascripts/extra_two.js +2 -0
- data/test/core_test_app/app/components/js_inclusion/javascripts/js_inclusion.js +5 -0
- data/test/core_test_app/app/components/{component_with_js_mixin → js_inclusion}/javascripts/method_set_one.js +0 -0
- data/test/core_test_app/app/components/{component_with_js_mixin → js_inclusion}/javascripts/method_set_two.js +0 -0
- data/test/core_test_app/app/components/{component_with_js_mixin.rb → js_inclusion.rb} +3 -3
- data/test/core_test_app/app/components/js_inclusion_extended/javascripts/some_method_set.js +5 -0
- data/test/core_test_app/app/components/js_inclusion_extended.rb +6 -0
- data/test/core_test_app/app/components/loaded_css_inclusion.rb +22 -0
- data/test/core_test_app/app/components/{localized_panel.rb → localization.rb} +5 -5
- data/test/core_test_app/app/components/localization_extended.rb +2 -0
- data/test/core_test_app/app/components/persistence.rb +60 -0
- data/test/core_test_app/app/components/persistence_with_shared_state.rb +7 -0
- data/test/core_test_app/app/components/plugin_with_actions.rb +24 -0
- data/test/core_test_app/app/components/plugin_with_components.rb +3 -3
- data/test/core_test_app/app/components/plugin_with_endpoints.rb +29 -0
- data/test/core_test_app/app/components/plugins.rb +9 -0
- data/test/core_test_app/app/components/{kinda_complex_component → ruby_modules}/basic_stuff.rb +1 -1
- data/test/core_test_app/app/components/{kinda_complex_component → ruby_modules}/extra_stuff.rb +3 -3
- data/test/core_test_app/app/components/{kinda_complex_component.rb → ruby_modules.rb} +1 -1
- data/test/core_test_app/app/components/scoped/deeply_scoped/scoping.rb +10 -0
- data/test/core_test_app/app/components/scoped/scoping.rb +8 -0
- data/test/core_test_app/app/components/scoped/scoping_extended.rb +8 -0
- data/test/core_test_app/app/components/self_reloading.rb +25 -0
- data/test/core_test_app/app/components/server_counter/javascripts/server_counter.js +4 -4
- data/test/core_test_app/app/components/server_counter.rb +10 -10
- data/test/core_test_app/app/components/simple_authentication_component.rb +1 -0
- data/test/core_test_app/app/components/simple_component.rb +0 -4
- data/test/core_test_app/app/components/simple_composite.rb +1 -1
- data/test/core_test_app/app/components/simple_form_with_file_upload.rb +1 -2
- data/test/core_test_app/app/components/simple_tab_panel.rb +5 -3
- data/test/core_test_app/app/components/{panel_with_tools.rb → tools.rb} +3 -3
- data/test/core_test_app/app/components/window_with_simple_component.rb +1 -0
- data/test/core_test_app/app/controllers/alternative_controller.rb +10 -0
- data/test/core_test_app/app/controllers/specs_controller.rb +11 -0
- data/test/core_test_app/app/views/layouts/application.html.erb +19 -1
- data/test/core_test_app/app/views/simple_rails/multiple_nested.html.erb +2 -2
- data/test/core_test_app/config/boot.rb +3 -10
- data/test/core_test_app/config/environments/development.rb +1 -0
- data/test/core_test_app/config/initializers/netzke.rb +4 -1
- data/test/core_test_app/config/locales/en.yml +11 -4
- data/test/core_test_app/config/locales/es.yml +1 -4
- data/test/core_test_app/config/routes.rb +10 -1
- data/test/core_test_app/core_test_app.tmproj +254 -0
- data/test/core_test_app/db/development.sqlite3 +0 -0
- data/test/core_test_app/{lib/tasks/.gitkeep → db/test.sqlite3} +0 -0
- data/test/core_test_app/log/development.log +78046 -0
- data/test/core_test_app/log/production.log +18 -0
- data/test/core_test_app/log/test.log +120048 -0
- data/test/core_test_app/rails_app.tmproj +324 -0
- data/test/core_test_app/tmp/cache/assets/C8B/BF0/sprockets%2F54de2792b036d1dab855f88599503551 +0 -0
- data/test/core_test_app/tmp/cache/assets/C92/5A0/sprockets%2F39e75754782ee12179bf35c9a0971d80 +0 -0
- data/test/core_test_app/tmp/cache/assets/C99/720/sprockets%2F981d5a1b957a012e380b22011a6d176d +0 -0
- data/test/core_test_app/tmp/cache/assets/C9F/750/sprockets%2F20ce3d64040a5d3a0a8883bd60754356 +0 -0
- data/test/core_test_app/tmp/cache/assets/CC4/C00/sprockets%2Fc615df52887d8c2e67e8413576a419c5 +0 -0
- data/test/core_test_app/tmp/cache/assets/CF1/3F0/sprockets%2Fc69ee42924fab565a3533d56473ce878 +0 -0
- data/test/core_test_app/tmp/cache/assets/D0E/870/sprockets%2Fa593bf4fac106add88c9434141a49663 +0 -0
- data/test/core_test_app/tmp/cache/assets/D14/8E0/sprockets%2F20748e8d1d7d090d122904a9fe6f18fc +0 -0
- data/test/core_test_app/tmp/cache/assets/D3E/DA0/sprockets%2Fa175f1ac5996544b908ba3ba3f64c4f3 +0 -0
- data/test/core_test_app/tmp/cache/assets/D43/C00/sprockets%2F7bc60c758776356d615ab5edff201ee2 +0 -0
- data/test/core_test_app/tmp/cache/assets/D4B/C50/sprockets%2F8483b7e322da338e8f9eb3b30a957e9a +0 -0
- data/test/core_test_app/tmp/cache/assets/D64/090/sprockets%2F5a01ff309c3f2503eb5e4f5667cca4b3 +0 -0
- data/test/core_test_app/tmp/cache/assets/D8B/FB0/sprockets%2F7a86225caaa389f1be600b4f3a2d1ef0 +0 -0
- data/test/core_test_app/tmp/cache/assets/D98/9C0/sprockets%2F18b80e8fe200aebc522e561a867ea6fb +0 -0
- data/test/core_test_app/tmp/cache/assets/DB0/6E0/sprockets%2F03e33f5a4779eeb48bcfc86ee717fb55 +0 -0
- data/test/core_test_app/tmp/cache/assets/DED/7E0/sprockets%2Feaedd52ba538f19e4ab543a3e20ce2c4 +0 -0
- data/test/core_test_app/tmp/cache/assets/E07/FF0/sprockets%2Fb3c071e0a6de36f041adbbdaa8ab060b +0 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214105940.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214110642.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214110749.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214110750.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214111025.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214111027.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214111213.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214111214.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214111332.html +40 -0
- data/test/core_test_app/tmp/capybara/capybara-20101214111333.html +40 -0
- data/test/core_test_app/{spec/component → tmp/pids/passenger.3000.pid.lock} +0 -0
- metadata +370 -133
- data/.autotest +0 -1
- data/.travis.yml +0 -18
- data/Manifest +0 -50
- data/config/ci/before-travis.sh +0 -10
- data/install.rb +0 -1
- data/lib/netzke/core/options_hash.rb +0 -27
- data/lib/netzke/core/ruby_ext/string.rb +0 -26
- data/lib/netzke/core/ruby_ext/symbol.rb +0 -13
- data/netzke-core.gemspec +0 -253
- data/test/core_test_app/.gitignore +0 -4
- data/test/core_test_app/.powrc +0 -4
- data/test/core_test_app/.rvmrc +0 -1
- data/test/core_test_app/Gemfile +0 -19
- data/test/core_test_app/Gemfile.lock +0 -147
- data/test/core_test_app/app/components/border_layout_panel.rb +0 -4
- data/test/core_test_app/app/components/card_component_loader.rb +0 -25
- data/test/core_test_app/app/components/component_with_custom_css.rb +0 -11
- data/test/core_test_app/app/components/component_with_js_mixin/javascripts/component_with_js_mixin.js +0 -5
- data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_one.js +0 -2
- data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_two.js +0 -2
- data/test/core_test_app/app/components/component_with_nested_through.rb +0 -28
- data/test/core_test_app/app/components/component_with_required_js.rb +0 -24
- data/test/core_test_app/app/components/dsl_delegated_properties.rb +0 -4
- data/test/core_test_app/app/components/dsl_delegated_properties_base.rb +0 -5
- data/test/core_test_app/app/components/extended_component_with_actions.rb +0 -9
- data/test/core_test_app/app/components/extended_component_with_js_mixin/javascripts/some_method_set.js +0 -5
- data/test/core_test_app/app/components/extended_component_with_js_mixin.rb +0 -10
- data/test/core_test_app/app/components/extended_localized_panel.rb +0 -2
- data/test/core_test_app/app/components/included.js +0 -5
- data/test/core_test_app/app/components/inline_composite.rb +0 -13
- data/test/core_test_app/app/components/loader_of_component_with_custom_css.rb +0 -23
- data/test/core_test_app/app/components/multipane_component_loader.rb +0 -41
- data/test/core_test_app/app/components/nested_component.rb +0 -17
- data/test/core_test_app/app/components/panel_with_plugin.rb +0 -9
- data/test/core_test_app/app/components/scoped_components/deep_scoped_components/some_deep_scoped_component.rb +0 -10
- data/test/core_test_app/app/components/scoped_components/extended_scoped_component.rb +0 -8
- data/test/core_test_app/app/components/scoped_components/some_scoped_component.rb +0 -8
- data/test/core_test_app/app/components/some_ext_component.rb +0 -8
- data/test/core_test_app/app/components/some_plugin.rb +0 -40
- data/test/core_test_app/app/components/stateful_component.rb +0 -46
- data/test/core_test_app/app/components/stateful_component_with_shared_state.rb +0 -11
- data/test/core_test_app/config/database.yml.travis +0 -11
- data/test/core_test_app/db/schema.rb +0 -29
- data/test/core_test_app/features/actions_and_tools.feature +0 -22
- data/test/core_test_app/features/basic.feature +0 -7
- data/test/core_test_app/features/client-server.feature +0 -19
- data/test/core_test_app/features/complex_component.feature +0 -18
- data/test/core_test_app/features/component.feature +0 -10
- data/test/core_test_app/features/component_loader.feature +0 -52
- data/test/core_test_app/features/composition.feature +0 -45
- data/test/core_test_app/features/config_to_dsl_delegation.feature +0 -10
- data/test/core_test_app/features/custom_css.feature +0 -17
- data/test/core_test_app/features/ext.direct.feature +0 -32
- data/test/core_test_app/features/file_inclusion.feature +0 -10
- data/test/core_test_app/features/i18n.feature +0 -35
- data/test/core_test_app/features/inheritance.feature +0 -18
- data/test/core_test_app/features/js_include.feature +0 -20
- data/test/core_test_app/features/nested_views.feature +0 -10
- data/test/core_test_app/features/persistence.feature +0 -34
- data/test/core_test_app/features/plugin.feature +0 -16
- data/test/core_test_app/features/rails_views.feature +0 -16
- data/test/core_test_app/features/scopes.feature +0 -14
- data/test/core_test_app/features/step_definitions/custom_css_steps.rb +0 -7
- data/test/core_test_app/features/step_definitions/generic_steps.rb +0 -64
- data/test/core_test_app/features/step_definitions/web_steps.rb +0 -219
- data/test/core_test_app/features/support/env.rb +0 -58
- data/test/core_test_app/features/support/paths.rb +0 -42
- data/test/core_test_app/spec/action_config_spec.rb +0 -15
- data/test/core_test_app/spec/actions_spec.rb +0 -96
- data/test/core_test_app/spec/base_spec.rb +0 -35
- data/test/core_test_app/spec/client_class_spec.rb +0 -17
- data/test/core_test_app/spec/composition_spec.rb +0 -118
- data/test/core_test_app/spec/core_ext_spec.rb +0 -27
- data/test/core_test_app/spec/endpoint_response_spec.rb +0 -17
- data/test/core_test_app/spec/javascript_spec.rb +0 -33
- data/test/core_test_app/spec/js_class_config_scope.rb +0 -37
- data/test/core_test_app/spec/panel_spec.rb +0 -11
- data/test/core_test_app/spec/services_spec.rb +0 -16
- data/test/core_test_app/spec/spec.opt +0 -2
- data/test/core_test_app/spec/spec_helper.rb +0 -27
- data/test/core_test_app/spec/state_spec.rb +0 -20
- data/test/core_test_app/vendor/plugins/.gitkeep +0 -0
- data/test/unit/core_ext_test.rb +0 -8
- data/test/unit/netzke_core_test.rb +0 -178
- data/uninstall.rb +0 -1
@@ -33,13 +33,6 @@ module Netzke::Core
|
|
33
33
|
|
34
34
|
class_attribute :delegated_defaults
|
35
35
|
self.delegated_defaults = {}
|
36
|
-
|
37
|
-
delegated_options.each do |property|
|
38
|
-
inherited_class.class.send(:define_method, property, lambda { |value|
|
39
|
-
self.delegated_defaults = self.delegated_defaults.dup if self.superclass.respond_to?(:delegated_defaults) && self.delegated_defaults == self.superclass.delegated_defaults
|
40
|
-
self.delegated_defaults[property.to_sym] = value
|
41
|
-
})
|
42
|
-
end
|
43
36
|
end
|
44
37
|
|
45
38
|
def configure(c)
|
@@ -59,5 +59,53 @@ module Netzke::Core
|
|
59
59
|
def config
|
60
60
|
@config ||= ActiveSupport::OrderedOptions.new
|
61
61
|
end
|
62
|
+
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# During the normalization of config object, +extend_item+ is being called with each item found (recursively) in there.
|
67
|
+
# For example, symbols representing nested child components get replaced with a proper config hash, same goes for actions (see +Composition+ and +Actions+ respectively).
|
68
|
+
# Override to do any additional checks/enhancements. See, for example, +Netzke::Basepack::WrapLazyLoaded+ or +Netzke::Basepack::Fields+.
|
69
|
+
# @return [Object|nil] normalized item or nil. If nil is returned, this item will be excluded from the config.
|
70
|
+
def extend_item(item)
|
71
|
+
item.is_a?(Hash) && item[:excluded] ? nil : item
|
72
|
+
end
|
73
|
+
|
74
|
+
# Used for detecting actions and components referred by symbols. For example, say, action +do_something+ is declared. Then:
|
75
|
+
#
|
76
|
+
# item #=> :do_something
|
77
|
+
# item = detect_and_normalize :action, item
|
78
|
+
# item #=> {netzke_action: :do_something, text: 'Do it'} # uses action declaration
|
79
|
+
def detect_and_normalize(thing, item)
|
80
|
+
if item.is_a?(Symbol) && thing_config = send(thing.to_s.pluralize)[item]
|
81
|
+
item = {:"netzke_#{thing}" => item, excluded: thing_config[:excluded]}
|
82
|
+
elsif item.is_a?(Hash)
|
83
|
+
# replace `action` key with `netzke_action`, which will be looked for at the JS side
|
84
|
+
item[:"netzke_#{thing}"] = item.delete(thing) if item[thing]
|
85
|
+
end
|
86
|
+
item
|
87
|
+
end
|
88
|
+
|
89
|
+
# We'll build a couple of useful instance variables here:
|
90
|
+
#
|
91
|
+
# +components_in_config+ - an array of components (by name) referred in items
|
92
|
+
# +normalized_config+ - a config that has all the config extensions applied
|
93
|
+
def normalize_config
|
94
|
+
@components_in_config = []
|
95
|
+
c = config.dup
|
96
|
+
config.each_pair do |k, v|
|
97
|
+
c.delete(k) if self.class.server_side_config_options.include?(k.to_sym)
|
98
|
+
if v.is_a?(Array)
|
99
|
+
c[k] = v.netzke_deep_map{|el| extend_item(el)}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
@normalized_config = c
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Hash] config with all placeholders (like child components referred by symbols) expanded
|
106
|
+
def normalized_config
|
107
|
+
# make sure we call normalize_config first
|
108
|
+
@normalized_config || (normalize_config || true) && @normalized_config
|
109
|
+
end
|
62
110
|
end
|
63
111
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Netzke
|
2
|
+
module Core
|
3
|
+
module DslSupport
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# It's the easiest to be explained by an example:
|
8
|
+
#
|
9
|
+
# declare_dsl_for :components
|
10
|
+
#
|
11
|
+
# This creates:
|
12
|
+
#
|
13
|
+
# 1) DSL method `component` for declaration of child component in a given class, e.g.:
|
14
|
+
#
|
15
|
+
# component :simple_panel do |c|
|
16
|
+
# # ...
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Each call to the created `component` method results in an instance method:
|
20
|
+
#
|
21
|
+
# def simple_panel_component(c)
|
22
|
+
# # ...
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# 2) Instance method `components` that returns a hash of all components configs. This hash is built by passing a new instance of `Netzke::Core::ComponentConfig` to each of the methods described in 1). Presence of `Netzke::Core::ComponentConfig` is assumed.
|
26
|
+
#
|
27
|
+
# Besides components, this method is being used in Core for DSL for actions.
|
28
|
+
def declare_dsl_for(things)
|
29
|
+
things = things.to_s
|
30
|
+
storage_attribute = :"_declared_#{things}"
|
31
|
+
|
32
|
+
class_attribute storage_attribute
|
33
|
+
send("#{storage_attribute}=", [])
|
34
|
+
|
35
|
+
define_dsl_method(things, storage_attribute)
|
36
|
+
define_collector_method(things, storage_attribute)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def define_dsl_method(things, storage_attribute)
|
41
|
+
thing = things.singularize
|
42
|
+
|
43
|
+
define_singleton_method thing do |name, &block|
|
44
|
+
self.send("#{storage_attribute}=", self.send(storage_attribute) | [name])
|
45
|
+
method_name = "#{name}_#{thing}"
|
46
|
+
define_method(method_name, &(block || ->(c){c}))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def define_collector_method(things, storage_attribute)
|
51
|
+
thing = things.singularize
|
52
|
+
config_class = "Netzke::Core::#{thing.camelcase}Config".constantize
|
53
|
+
|
54
|
+
define_method things do
|
55
|
+
# memoization
|
56
|
+
return instance_variable_get("@#{things}") if instance_variable_get("@#{things}")
|
57
|
+
|
58
|
+
config_hash = self.class.send(storage_attribute).inject({}) do |out, name|
|
59
|
+
c = config_class.new(name, self)
|
60
|
+
send("#{name}_#{thing}", c)
|
61
|
+
c.set_defaults!
|
62
|
+
out.merge(name.to_sym => c.excluded ? {excluded: true} : c)
|
63
|
+
end
|
64
|
+
|
65
|
+
instance_variable_set "@#{things}", config_hash
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -16,7 +16,7 @@ module Netzke
|
|
16
16
|
res << f.read
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
strip_js_comments(res)
|
20
20
|
end
|
21
21
|
|
22
22
|
def ext_css
|
@@ -31,6 +31,14 @@ module Netzke
|
|
31
31
|
res
|
32
32
|
end
|
33
33
|
|
34
|
+
def strip_js_comments(js_string)
|
35
|
+
if defined?(::Rails) && !::Rails.env.development? && compressor = ::Rails.application.assets.js_compressor
|
36
|
+
compressor.processor.call(nil, js_string)
|
37
|
+
else
|
38
|
+
js_string
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
34
42
|
private
|
35
43
|
|
36
44
|
# Generates initial javascript code that is dependent on Rails settings
|
@@ -44,6 +52,7 @@ module Netzke
|
|
44
52
|
res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}#{Netzke::Core.ext_uri}';}
|
45
53
|
|
46
54
|
res << %{Netzke.core.directMaxRetries = #{Netzke::Core.js_direct_max_retries};}
|
55
|
+
res << %{Netzke.core.FeedbackDelay = #{Netzke::Core.js_feedback_delay};}
|
47
56
|
|
48
57
|
res.join("\n")
|
49
58
|
end
|
@@ -3,12 +3,12 @@ module Netzke::Core
|
|
3
3
|
module Embedding
|
4
4
|
# Instantiating
|
5
5
|
def js_component_instance
|
6
|
-
%Q{Netzke.page.#{name.
|
6
|
+
%Q{Netzke.page.#{name.to_s.camelize(:lower)} = Ext.create("#{self.class.js_config.class_alias}", #{js_config.netzke_jsonify.to_json});}
|
7
7
|
end
|
8
8
|
|
9
9
|
# Rendering
|
10
10
|
def js_component_render
|
11
|
-
%Q{Netzke.page.#{name.
|
11
|
+
%Q{Netzke.page.#{name.to_s.camelize(:lower)}.render("#{name.to_s.split('_').join('-')}-netzke");} unless self.class.js_config.xtype == "netzkewindow"
|
12
12
|
end
|
13
13
|
|
14
14
|
# Container for rendering
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Netzke
|
2
|
+
module Core
|
3
|
+
# Provides support for HTML rendering (currently HAML only)
|
4
|
+
module Html
|
5
|
+
# Will render an HTML template found in +{component_location}/html/+ For example:
|
6
|
+
#
|
7
|
+
# class MyComponent < Netzke::Base
|
8
|
+
# def js_configure(c)
|
9
|
+
# super
|
10
|
+
# c.html = render(:body)
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# This will render the HAML file located in +app/components/my_component/html/body.html.haml
|
15
|
+
# The implementation is very simplistic at the moment - e.g. no caching, no support for .erb
|
16
|
+
def render(what)
|
17
|
+
callr = caller.first
|
18
|
+
engine = Haml::Engine.new(File.read(expand_html_path(what, callr)))
|
19
|
+
engine.method(:render).call(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def expand_html_path(sym, callr = nil)
|
25
|
+
%Q(#{callr.split(".rb:").first}/html/#{sym}.html.haml)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -43,35 +43,39 @@ module Netzke::Core
|
|
43
43
|
def js_configure(c)
|
44
44
|
c.merge!(normalized_config)
|
45
45
|
|
46
|
-
#
|
47
|
-
c.
|
48
|
-
|
49
|
-
# Configuration for all of our non-lazy-loaded children specified here. We can refer to them in +items+ so they get instantiated by Ext.
|
50
|
-
c.netzke_components = js_components unless js_components.empty?
|
51
|
-
|
52
|
-
# Endpoints (besides the default "deliver_component" - JavaScript side already knows about it)
|
53
|
-
endpoints = self.class.endpoints.keys - [:deliver_component]
|
54
|
-
|
55
|
-
# pass them as strings, not as symbols
|
56
|
-
c.endpoints = endpoints.map(&:to_s) unless endpoints.empty?
|
46
|
+
# So we can use getComponent(<component_name>) to retrieve a child component
|
47
|
+
c.item_id ||= name
|
57
48
|
|
58
|
-
|
59
|
-
|
49
|
+
%w[id netzke_components endpoints xtype alias i18n netzke_plugins flash].each do |thing|
|
50
|
+
js_thing = send "js_#{thing}"
|
51
|
+
c[thing] = js_thing if js_thing.present?
|
52
|
+
end
|
60
53
|
|
61
|
-
#
|
62
|
-
|
54
|
+
# reset component session
|
55
|
+
# TODO: also remove empty hashes from the global session
|
56
|
+
component_session.clear
|
57
|
+
end
|
63
58
|
|
64
|
-
|
65
|
-
|
59
|
+
def js_xtype
|
60
|
+
self.class.js_config.xtype
|
61
|
+
end
|
66
62
|
|
67
|
-
|
63
|
+
# Ext.createByAlias may be used to instantiate the component.
|
64
|
+
def js_alias
|
65
|
+
self.class.js_config.class_alias
|
66
|
+
end
|
68
67
|
|
69
|
-
|
68
|
+
# Endpoints (besides the default "deliver_component" - JavaScript side already knows about it)
|
69
|
+
def js_endpoints
|
70
|
+
self.class.endpoints.keys - [:deliver_component]
|
71
|
+
end
|
70
72
|
|
71
|
-
|
72
|
-
|
73
|
+
def js_netzke_plugins
|
74
|
+
plugins.map{ |p| p.to_s.camelcase(:lower) }
|
75
|
+
end
|
73
76
|
|
74
|
-
|
77
|
+
def js_flash
|
78
|
+
session && session[:flash]
|
75
79
|
end
|
76
80
|
|
77
81
|
# Instance-level client class config. The result of this method (a hash) is converted to a JSON object and passed as options to the constructor of our JavaScript class.
|
@@ -88,21 +92,23 @@ module Netzke::Core
|
|
88
92
|
end
|
89
93
|
end
|
90
94
|
|
95
|
+
alias js_netzke_components js_components
|
96
|
+
|
91
97
|
# All the JS-code required by this instance of the component to be instantiated in the browser.
|
92
98
|
# It includes JS-classes for the parents, eagerly loaded child components, and itself.
|
93
99
|
def js_missing_code(cached = [])
|
94
100
|
code = dependency_classes.inject("") do |r,k|
|
95
|
-
cached.include?(k.js_config.xtype) ? r : r + k.js_config.code_with_dependencies
|
101
|
+
cached.include?(k.js_config.xtype) ? r : r + k.js_config.code_with_dependencies
|
96
102
|
end
|
97
|
-
code.blank? ? nil : code
|
103
|
+
code.blank? ? nil : Netzke::Core::DynamicAssets.strip_js_comments(code)
|
98
104
|
end
|
99
105
|
|
100
106
|
private
|
101
107
|
|
102
108
|
# Merges all the translations in the class hierarchy
|
103
109
|
# Note: this method can't be moved out to ClientClass, because I18n is loaded only once, when other Ruby classes are evaluated; so, this must remain at instance level.
|
104
|
-
def
|
105
|
-
@
|
110
|
+
def js_i18n
|
111
|
+
@js_i18n ||= self.class.netzke_ancestors.inject({}) do |r,klass|
|
106
112
|
hsh = klass.js_config.translated_properties.inject({}) { |h,t| h.merge(t => I18n.t("#{klass.i18n_id}.#{t}")) }
|
107
113
|
r.merge(hsh)
|
108
114
|
end
|
@@ -8,7 +8,7 @@ module Netzke
|
|
8
8
|
|
9
9
|
def netzke_ext_css_include(params)
|
10
10
|
# ExtJS base
|
11
|
-
res = ["#{Netzke::Core.ext_uri}/resources/css/ext-#{params[:theme]}"]
|
11
|
+
res = ["#{Netzke::Core.ext_uri}/resources/css/ext-#{params[:theme]}.css"]
|
12
12
|
|
13
13
|
# Netzke-related dynamic css
|
14
14
|
res << netzke_path(:ext)
|
@@ -22,7 +22,7 @@ module Netzke
|
|
22
22
|
res = []
|
23
23
|
|
24
24
|
# ExtJS
|
25
|
-
res << (params[:minified] ? "#{Netzke::Core.ext_uri}/ext-all" : "#{Netzke::Core.ext_uri}/ext-all-debug")
|
25
|
+
res << (params[:minified] ? "#{Netzke::Core.ext_uri}/ext-all.js" : "#{Netzke::Core.ext_uri}/ext-all-debug.js")
|
26
26
|
|
27
27
|
# Ext I18n
|
28
28
|
res << "#{Netzke::Core.ext_uri}/locale/ext-lang-#{I18n.locale}" if I18n.locale != :en
|
@@ -2,16 +2,109 @@ module Netzke
|
|
2
2
|
module Railz
|
3
3
|
# Before each request, Netzke::Base.controller and Netzke::Base.session are set, to be accessible from components.
|
4
4
|
module ControllerExtensions
|
5
|
-
|
6
|
-
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
send(:before_filter, :set_controller_and_session)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Handles Ext.Direct RPC calls
|
12
|
+
def direct
|
13
|
+
if params['_json'] # this is a batched request
|
14
|
+
response = []
|
15
|
+
params['_json'].each do |batch|
|
16
|
+
# response << invoke_endpoint(batch)
|
17
|
+
response << direct_response(batch, invoke_endpoint(batch))
|
18
|
+
end
|
19
|
+
else # this is a single request
|
20
|
+
response = direct_response(params, invoke_endpoint(params))
|
21
|
+
end
|
22
|
+
|
23
|
+
render text: response.to_json, layout: false
|
24
|
+
end
|
25
|
+
|
26
|
+
# On-the-fly generation of public/netzke/ext.[js|css]
|
27
|
+
def ext
|
28
|
+
respond_to do |format|
|
29
|
+
format.js {
|
30
|
+
render :text => Netzke::Core::DynamicAssets.ext_js(form_authenticity_token)
|
31
|
+
}
|
32
|
+
|
33
|
+
format.css {
|
34
|
+
render :text => Netzke::Core::DynamicAssets.ext_css
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Old-way action used at multi-part form submission (endpointUrl)
|
40
|
+
def dispatcher
|
41
|
+
endpoint_dispatch(params[:address])
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def direct_response(request_params, endpoint_response)
|
47
|
+
path, action, params, tid = parse_request_params(request_params)
|
48
|
+
component_name, *sub_components = path.split('__')
|
49
|
+
|
50
|
+
# We render text/plain, so that the browser never modifies our response
|
51
|
+
response.headers["Content-Type"] = "text/plain; charset=utf-8"
|
52
|
+
|
53
|
+
{ :type => "rpc",
|
54
|
+
:tid => tid,
|
55
|
+
:action => component_name,
|
56
|
+
:method => action,
|
57
|
+
:result => ActiveSupport::JSON::Variable.new(endpoint_response.netzke_jsonify.to_json)
|
58
|
+
}
|
7
59
|
end
|
8
60
|
|
9
|
-
|
61
|
+
def invoke_endpoint(request_params)
|
62
|
+
path, action, params, tid = parse_request_params(request_params)
|
63
|
+
|
64
|
+
component_name, *sub_components = path.split('__')
|
65
|
+
components_in_session = session[:netzke_components]
|
66
|
+
|
67
|
+
if components_in_session
|
68
|
+
component_instance = Netzke::Base.instance_by_config(components_in_session[component_name.to_sym])
|
69
|
+
component_instance.invoke_endpoint((sub_components + [action]).join("__"), params)
|
70
|
+
else
|
71
|
+
{:netzke_component_not_in_session => true}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_request_params(params)
|
76
|
+
path = params[:act]
|
77
|
+
action = params[:method].underscore
|
78
|
+
ep_params = params[:data].try(:first) # Rails >= 3.2.11 returns nil in request_params[:data]
|
79
|
+
tid = params[:tid]
|
80
|
+
|
81
|
+
[path, action, ep_params, tid]
|
82
|
+
end
|
83
|
+
|
84
|
+
# The dispatcher for the old-style requests (used for multi-part form submission). The URL contains the name of the component,
|
85
|
+
# as well as the method of this component to be called, according to the double underscore notation.
|
86
|
+
# E.g.: some_grid__post_grid_data.
|
87
|
+
def endpoint_dispatch(endpoint_path)
|
88
|
+
component_name, *sub_components = endpoint_path.split('__')
|
89
|
+
component_instance = Netzke::Base.instance_by_config(session[:netzke_components][component_name.to_sym])
|
90
|
+
|
91
|
+
# We can't do this here; this method is only used for classic form submission, and the response from the server should be the (default) "text/html"
|
92
|
+
# response.headers["Content-Type"] = "text/plain; charset=utf-8"
|
93
|
+
|
94
|
+
render :text => component_instance.invoke_endpoint(sub_components.join("__"), params).netzke_jsonify.to_json, :layout => false
|
95
|
+
end
|
10
96
|
|
11
97
|
def set_controller_and_session
|
12
98
|
Netzke::Base.controller = self
|
13
99
|
Netzke::Base.session = session
|
14
100
|
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
# inform AbstractController::Base that methods direct, ext, and dispatcher are actually actions
|
105
|
+
def action_method?(name)
|
106
|
+
%w(direct ext dispatcher).include?(name.to_s) || super
|
107
|
+
end
|
15
108
|
end
|
16
109
|
end
|
17
110
|
end
|
@@ -1,10 +1,21 @@
|
|
1
1
|
module ActionDispatch::Routing
|
2
2
|
class Mapper
|
3
|
-
#
|
3
|
+
# Enables routes for Netzke assets and endpoint calls (by default routes to NetzkeController). The default URL is "/netzke", but this can be changed:
|
4
4
|
#
|
5
5
|
# netzke "/some/path/netzke"
|
6
|
-
|
7
|
-
|
6
|
+
#
|
7
|
+
# If you want to use your own controller instead of NetzkeController, you can specify it like this:
|
8
|
+
#
|
9
|
+
# netzke "/netzke", controller: :admin
|
10
|
+
#
|
11
|
+
# This will make Netzke use AdminController. Note, that in that case AdminController MUST implement the actions required by Netzke. The way to do this is to include Netzke::Railz::ControllerExtensions in your controller, e.g.:
|
12
|
+
#
|
13
|
+
# class AdminController < ApplicationController
|
14
|
+
# include Netzke::Railz::ControllerExtensions
|
15
|
+
# end
|
16
|
+
def netzke(prefix = "/netzke", options = {})
|
17
|
+
controller = options[:controller] || :netzke
|
18
|
+
match "#{prefix}/:action(.:format)", to: controller.to_s, as: 'netzke'
|
8
19
|
end
|
9
20
|
end
|
10
21
|
end
|
@@ -1,23 +1,9 @@
|
|
1
1
|
class Array
|
2
|
-
def
|
3
|
-
self.map{ |el| el.respond_to?(:
|
2
|
+
def netzke_deep_map(&block)
|
3
|
+
self.map{ |el| el.respond_to?(:netzke_deep_map) ? block.call(el.netzke_deep_map(&block)) : block.call(el) }.compact
|
4
4
|
end
|
5
5
|
|
6
|
-
def
|
7
|
-
self.map{ |el| el.is_a?(Array) || el.is_a?(Hash) ? 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
|
6
|
+
def netzke_jsonify
|
7
|
+
self.map{ |el| el.is_a?(Array) || el.is_a?(Hash) ? el.netzke_jsonify : el }
|
22
8
|
end
|
23
9
|
end
|
@@ -1,47 +1,41 @@
|
|
1
1
|
class Hash
|
2
|
-
def
|
2
|
+
def netzke_deep_map(&block)
|
3
3
|
self.dup.tap do |h|
|
4
4
|
h.each_pair do |k,v|
|
5
|
-
h[k] = v.
|
5
|
+
h[k] = v.netzke_deep_map(&block) if v.respond_to?('netzke_deep_map')
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
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
|
10
|
+
def netzke_jsonify
|
17
11
|
self.inject({}) do |h,(k,v)|
|
18
|
-
new_key =
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
new_key = if k.is_a?(ActiveSupport::JSON::Variable)
|
13
|
+
k
|
14
|
+
elsif k.is_a?(String)
|
15
|
+
k.camelize(:lower)
|
16
|
+
elsif k.is_a?(Symbol)
|
17
|
+
k.to_s.camelize(:lower).to_sym
|
18
|
+
else
|
19
|
+
k
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
def to_nifty_json
|
26
|
-
self.jsonify.to_json
|
27
|
-
end
|
22
|
+
new_value = v.is_a?(Array) || v.is_a?(Hash) ? v.netzke_jsonify : v
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
freeze
|
24
|
+
h.merge(new_key => new_value)
|
25
|
+
end
|
32
26
|
end
|
33
27
|
|
34
28
|
# From http://rubyworks.github.com/facets
|
35
|
-
def
|
29
|
+
def netzke_update_keys #:yield:
|
36
30
|
if block_given?
|
37
31
|
keys.each { |old_key| store(yield(old_key), delete(old_key)) }
|
38
32
|
else
|
39
|
-
to_enum(:
|
33
|
+
to_enum(:netzke_update_keys)
|
40
34
|
end
|
41
35
|
end
|
42
36
|
|
43
|
-
def
|
44
|
-
|
37
|
+
def netzke_literalize_keys
|
38
|
+
netzke_update_keys{ |k| ActiveSupport::JSON::Variable.new(k.to_s) }
|
45
39
|
self
|
46
40
|
end
|
47
41
|
end
|
data/lib/netzke/core/ruby_ext.rb
CHANGED
data/lib/netzke/core/session.rb
CHANGED
@@ -4,13 +4,20 @@ module Netzke::Core
|
|
4
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
5
|
class ComponentSessionProxy < Object
|
6
6
|
def initialize(component_id)
|
7
|
-
@
|
7
|
+
@component_id = component_id
|
8
|
+
Netzke::Base.session ||= {}
|
9
|
+
Netzke::Base.session[:netzke_sessions] ||= {}
|
10
|
+
@session = Netzke::Base.session[:netzke_sessions][@component_id] ||= {}
|
8
11
|
end
|
9
12
|
|
10
13
|
# Delegate everything to session
|
11
14
|
def method_missing(method, *args)
|
12
15
|
@session.send(method, *args)
|
13
16
|
end
|
17
|
+
|
18
|
+
def clear
|
19
|
+
Netzke::Base.session[:netzke_sessions].delete(@component_id)
|
20
|
+
end
|
14
21
|
end
|
15
22
|
|
16
23
|
# Component-specific session.
|
data/lib/netzke/core/state.rb
CHANGED
@@ -26,15 +26,15 @@ module Netzke::Core
|
|
26
26
|
#
|
27
27
|
# state[:position] #=> {:x => 100, :y => 200}
|
28
28
|
#
|
29
|
-
# May be overridden by persistence subsystems. The object returned by this should implement
|
29
|
+
# May be overridden by persistence subsystems. The object returned by this should implement the following methods:
|
30
30
|
#
|
31
31
|
# * []
|
32
32
|
# * []=
|
33
33
|
# * delete(key)
|
34
34
|
# * clear
|
35
35
|
def state
|
36
|
-
session[:
|
37
|
-
session[:
|
36
|
+
session[:netzke_states] ||= {}
|
37
|
+
session[:netzke_states][persistence_key] ||= {}
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|