volt 0.7.23 → 0.8.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +8 -1
- data/CHANGELOG.md +22 -0
- data/Gemfile +8 -0
- data/Guardfile +2 -2
- data/Readme.md +139 -136
- data/VERSION +1 -1
- data/app/volt/assets/js/setImmediate.js +175 -0
- data/app/volt/tasks/live_query/data_store.rb +0 -2
- data/app/volt/tasks/live_query/live_query.rb +4 -4
- data/docs/GETTING_STARTED.md +24 -3
- data/docs/WHY.md +1 -22
- data/lib/volt.rb +20 -1
- data/lib/volt/console.rb +20 -0
- data/lib/volt/controllers/model_controller.rb +25 -11
- data/lib/volt/extra_core/object.rb +2 -14
- data/lib/volt/extra_core/string.rb +4 -0
- data/lib/volt/models.rb +0 -1
- data/lib/volt/models/array_model.rb +8 -16
- data/lib/volt/models/cursor.rb +1 -1
- data/lib/volt/models/model.rb +40 -60
- data/lib/volt/models/model_hash_behaviour.rb +10 -24
- data/lib/volt/models/model_helpers.rb +2 -2
- data/lib/volt/models/model_state.rb +1 -1
- data/lib/volt/models/model_wrapper.rb +4 -4
- data/lib/volt/models/persistors/array_store.rb +44 -28
- data/lib/volt/models/persistors/base.rb +1 -1
- data/lib/volt/models/persistors/model_store.rb +1 -1
- data/lib/volt/models/persistors/params.rb +5 -1
- data/lib/volt/models/persistors/query/query_listener.rb +2 -0
- data/lib/volt/models/persistors/store.rb +3 -2
- data/lib/volt/models/persistors/store_state.rb +7 -2
- data/lib/volt/models/url.rb +35 -29
- data/lib/volt/models/validations.rb +7 -17
- data/lib/volt/page/bindings/attribute_binding.rb +57 -39
- data/lib/volt/page/bindings/base_binding.rb +0 -14
- data/lib/volt/page/bindings/content_binding.rb +15 -18
- data/lib/volt/page/bindings/each_binding.rb +67 -34
- data/lib/volt/page/bindings/if_binding.rb +15 -12
- data/lib/volt/page/bindings/template_binding.rb +77 -59
- data/lib/volt/page/bindings/template_binding/grouped_controllers.rb +19 -4
- data/lib/volt/page/channel.rb +22 -38
- data/lib/volt/page/channel_stub.rb +3 -6
- data/lib/volt/page/page.rb +24 -26
- data/lib/volt/page/string_template_renderer.rb +46 -0
- data/lib/volt/page/sub_context.rb +7 -1
- data/lib/volt/page/targets/binding_document/component_node.rb +11 -9
- data/lib/volt/page/tasks.rb +3 -2
- data/lib/volt/page/url_tracker.rb +4 -3
- data/lib/volt/reactive/computation.rb +131 -0
- data/lib/volt/reactive/dependency.rb +71 -0
- data/lib/volt/reactive/eventable.rb +82 -0
- data/lib/volt/reactive/hash_dependency.rb +36 -0
- data/lib/volt/{controllers → reactive}/reactive_accessors.rb +8 -11
- data/lib/volt/reactive/reactive_array.rb +100 -193
- data/lib/volt/reactive/reactive_hash.rb +49 -0
- data/lib/volt/server/html_parser/attribute_scope.rb +24 -4
- data/lib/volt/server/html_parser/if_view_scope.rb +15 -15
- data/lib/volt/server/html_parser/view_scope.rb +31 -1
- data/spec/apps/kitchen_sink/Gemfile +4 -8
- data/spec/apps/kitchen_sink/app/main/config/dependencies.rb +8 -0
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +8 -1
- data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +8 -0
- data/spec/apps/kitchen_sink/app/main/views/main/bindings.html +73 -0
- data/spec/apps/kitchen_sink/app/main/views/main/index.html +6 -1
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +26 -6
- data/spec/apps/kitchen_sink/app/main/views/main/store.html +6 -0
- data/spec/controllers/reactive_accessors_spec.rb +13 -15
- data/spec/integration/bindings_spec.rb +159 -0
- data/spec/integration/templates_spec.rb +15 -0
- data/spec/models/model_spec.rb +130 -228
- data/spec/reactive/computation_spec.rb +63 -0
- data/spec/reactive/dependency_spec.rb +5 -0
- data/spec/reactive/eventable_spec.rb +48 -0
- data/spec/reactive/reactive_array_spec.rb +97 -0
- data/spec/router/routes_spec.rb +26 -27
- data/spec/server/html_parser/view_parser_spec.rb +3 -21
- data/spec/server/rack/asset_files_spec.rb +1 -1
- data/templates/project/app/main/views/main/main.html +2 -2
- metadata +29 -41
- data/lib/volt/extra_core/time.rb +0 -16
- data/lib/volt/page/draw_cycle.rb +0 -31
- data/lib/volt/page/memory_test.rb +0 -26
- data/lib/volt/page/reactive_template.rb +0 -32
- data/lib/volt/reactive/array_extensions.rb +0 -12
- data/lib/volt/reactive/destructive_methods.rb +0 -19
- data/lib/volt/reactive/event_chain.rb +0 -125
- data/lib/volt/reactive/events.rb +0 -216
- data/lib/volt/reactive/object_tracking.rb +0 -14
- data/lib/volt/reactive/reactive_block.rb +0 -88
- data/lib/volt/reactive/reactive_generator.rb +0 -44
- data/lib/volt/reactive/reactive_tags.rb +0 -71
- data/lib/volt/reactive/reactive_value.rb +0 -427
- data/lib/volt/reactive/string_extensions.rb +0 -31
- data/spec/integration/test_integration_spec.rb +0 -14
- data/spec/models/event_chain_spec.rb +0 -150
- data/spec/models/model_buffers_spec.rb +0 -9
- data/spec/models/old_model_spec.rb +0 -67
- data/spec/models/reactive_array_spec.rb +0 -364
- data/spec/models/reactive_block_spec.rb +0 -13
- data/spec/models/reactive_call_times_spec.rb +0 -28
- data/spec/models/reactive_generator_spec.rb +0 -58
- data/spec/models/reactive_tags_spec.rb +0 -35
- data/spec/models/reactive_value_spec.rb +0 -370
- data/spec/models/store_spec.rb +0 -16
- data/spec/models/string_extensions_spec.rb +0 -57
|
@@ -2,24 +2,23 @@ require 'volt/page/bindings/base_binding'
|
|
|
2
2
|
|
|
3
3
|
class ContentBinding < BaseBinding
|
|
4
4
|
def initialize(page, target, context, binding_name, getter)
|
|
5
|
+
# puts "New Content Binding: #{self.inspect}"
|
|
5
6
|
super(page, target, context, binding_name)
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
-
@
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
8
|
+
# Listen for changes
|
|
9
|
+
@computation = -> do
|
|
10
|
+
begin
|
|
11
|
+
update(@context.instance_eval(&getter))
|
|
12
|
+
rescue => e
|
|
13
|
+
Volt.logger.error("ContentBinding Error: #{e.inspect}")
|
|
14
|
+
update('')
|
|
15
|
+
end
|
|
16
|
+
end.watch!
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
def update
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
puts "GOT CUR: #{value.inspect}"
|
|
22
|
-
end
|
|
19
|
+
def update(value)
|
|
20
|
+
# TODORW:
|
|
21
|
+
value = value.nil? ? '' : value
|
|
23
22
|
|
|
24
23
|
# Exception values display the exception as a string
|
|
25
24
|
value = value.to_s
|
|
@@ -30,10 +29,8 @@ class ContentBinding < BaseBinding
|
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
def remove
|
|
33
|
-
if @
|
|
34
|
-
|
|
35
|
-
@changed_listener = nil
|
|
36
|
-
end
|
|
32
|
+
@computation.stop if @computation
|
|
33
|
+
@computation = nil
|
|
37
34
|
|
|
38
35
|
super
|
|
39
36
|
end
|
|
@@ -7,40 +7,57 @@ class EachBinding < BaseBinding
|
|
|
7
7
|
@item_name = variable_name
|
|
8
8
|
@template_name = template_name
|
|
9
9
|
|
|
10
|
-
# Find the source for the content binding
|
|
11
|
-
@value = value_from_getter(getter)
|
|
12
|
-
|
|
13
10
|
@templates = []
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
# update
|
|
17
|
-
reload
|
|
12
|
+
@getter = getter
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
@
|
|
21
|
-
@removed_listener = @value.on('removed') { |_, position| item_removed(position) }
|
|
14
|
+
# Listen for changes
|
|
15
|
+
@computation = -> { reload }.watch!
|
|
22
16
|
end
|
|
23
17
|
|
|
24
18
|
# When a changed event happens, we update to the new size.
|
|
25
19
|
def reload
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
begin
|
|
21
|
+
value = @context.instance_eval(&@getter)
|
|
22
|
+
rescue => e
|
|
23
|
+
Volt.logger.error("EachBinding Error: #{e.inspect}")
|
|
24
|
+
value = []
|
|
25
|
+
end
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
# Since we're checking things like size, we don't want this to be re-triggered on a
|
|
28
|
+
# size change, so we run without tracking.
|
|
29
|
+
Computation.run_without_tracking do
|
|
30
|
+
# puts "RELOAD:-------------- #{value.inspect}"
|
|
31
|
+
# Adjust to the new size
|
|
32
|
+
values = current_values(value)
|
|
33
|
+
@value = values
|
|
34
|
+
|
|
35
|
+
@added_listener.remove if @added_listener
|
|
36
|
+
@removed_listener.remove if @removed_listener
|
|
37
|
+
|
|
38
|
+
if @value.respond_to?(:on)
|
|
39
|
+
@added_listener = @value.on('added') { |position| item_added(position) }
|
|
40
|
+
@removed_listener = @value.on('removed') { |position| item_removed(position) }
|
|
34
41
|
end
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
|
|
43
|
+
templates_size = @templates.size
|
|
44
|
+
values_size = values.size
|
|
45
|
+
|
|
46
|
+
# Start over, re-create all nodes
|
|
47
|
+
(templates_size-1).downto(0) do |index|
|
|
37
48
|
item_removed(index)
|
|
38
49
|
end
|
|
50
|
+
0.upto(values_size-1) do |index|
|
|
51
|
+
item_added(index)
|
|
52
|
+
end
|
|
39
53
|
end
|
|
40
54
|
end
|
|
41
55
|
|
|
42
56
|
def item_removed(position)
|
|
43
|
-
|
|
57
|
+
# Remove dependency
|
|
58
|
+
@templates[position].context.locals[:index_dependency].remove
|
|
59
|
+
|
|
60
|
+
# puts "REMOVE AT: #{position.inspect} - #{@templates[position].inspect} - #{@templates.inspect}"
|
|
44
61
|
@templates[position].remove_anchors
|
|
45
62
|
@templates[position].remove
|
|
46
63
|
@templates.delete_at(position)
|
|
@@ -50,7 +67,6 @@ class EachBinding < BaseBinding
|
|
|
50
67
|
end
|
|
51
68
|
|
|
52
69
|
def item_added(position)
|
|
53
|
-
# ObjectTracker.enable_cache
|
|
54
70
|
binding_name = @@binding_number
|
|
55
71
|
@@binding_number += 1
|
|
56
72
|
|
|
@@ -62,15 +78,28 @@ class EachBinding < BaseBinding
|
|
|
62
78
|
dom_section.insert_anchor_before(binding_name, @templates[position].binding_name)
|
|
63
79
|
end
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
# TODORW: :parent => @value may change
|
|
82
|
+
item_context = SubContext.new({:_index_value => position, :parent => @value}, @context)
|
|
83
|
+
item_context.locals[@item_name.to_sym] = Proc.new { @value[item_context.locals[:_index_value]] }
|
|
67
84
|
|
|
68
|
-
|
|
85
|
+
position_dependency = Dependency.new
|
|
86
|
+
item_context.locals[:index_dependency] = position_dependency
|
|
87
|
+
|
|
88
|
+
# Get and set index
|
|
89
|
+
item_context.locals[:index=] = Proc.new do |val|
|
|
90
|
+
position_dependency.changed!
|
|
91
|
+
item_context.locals[:_index_value] = val
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
item_context.locals[:index] = Proc.new do
|
|
95
|
+
position_dependency.depend
|
|
96
|
+
item_context.locals[:_index_value]
|
|
97
|
+
end
|
|
69
98
|
|
|
70
99
|
item_template = TemplateRenderer.new(@page, @target, item_context, binding_name, @template_name)
|
|
71
100
|
@templates.insert(position, item_template)
|
|
72
101
|
|
|
73
|
-
|
|
102
|
+
update_indexes_after(position)
|
|
74
103
|
end
|
|
75
104
|
|
|
76
105
|
# When items are added or removed in the middle of the list, we need
|
|
@@ -78,18 +107,15 @@ class EachBinding < BaseBinding
|
|
|
78
107
|
def update_indexes_after(start_index)
|
|
79
108
|
size = @templates.size
|
|
80
109
|
if size > 0
|
|
81
|
-
puts @templates.inspect
|
|
82
110
|
start_index.upto(size-1) do |index|
|
|
83
|
-
@templates[index].context.locals[:index].
|
|
111
|
+
@templates[index].context.locals[:index=].call(index)
|
|
84
112
|
end
|
|
85
113
|
end
|
|
86
114
|
end
|
|
87
115
|
|
|
88
|
-
def current_values
|
|
89
|
-
values = @value.cur
|
|
90
|
-
|
|
116
|
+
def current_values(values)
|
|
91
117
|
return [] if values.is_a?(Model) || values.is_a?(Exception)
|
|
92
|
-
values = values.attributes
|
|
118
|
+
values = values.attributes if values.respond_to?(:attributes)
|
|
93
119
|
|
|
94
120
|
return values
|
|
95
121
|
end
|
|
@@ -97,17 +123,24 @@ class EachBinding < BaseBinding
|
|
|
97
123
|
|
|
98
124
|
# When this each_binding is removed, cleanup.
|
|
99
125
|
def remove
|
|
126
|
+
@computation.stop
|
|
127
|
+
@computation = nil
|
|
128
|
+
|
|
129
|
+
# Clear value
|
|
130
|
+
@value = nil
|
|
131
|
+
|
|
100
132
|
@added_listener.remove
|
|
101
133
|
@added_listener = nil
|
|
102
134
|
|
|
103
|
-
@changed_listener.remove
|
|
104
|
-
@changed_listener = nil
|
|
105
|
-
|
|
106
135
|
@removed_listener.remove
|
|
107
136
|
@removed_listener = nil
|
|
108
137
|
|
|
109
138
|
if @templates
|
|
110
|
-
@templates.
|
|
139
|
+
template_count = @templates.size
|
|
140
|
+
template_count.times do |index|
|
|
141
|
+
item_removed(template_count - index - 1)
|
|
142
|
+
end
|
|
143
|
+
# @templates.compact.each(&:remove)
|
|
111
144
|
@templates = nil
|
|
112
145
|
end
|
|
113
146
|
|
|
@@ -13,13 +13,7 @@ class IfBinding < BaseBinding
|
|
|
13
13
|
getter, template_name = branch
|
|
14
14
|
|
|
15
15
|
if getter.present?
|
|
16
|
-
|
|
17
|
-
value = value_from_getter(getter)
|
|
18
|
-
|
|
19
|
-
if value.reactive?
|
|
20
|
-
# Trigger change when value changes
|
|
21
|
-
@listeners << value.on('changed') { update }
|
|
22
|
-
end
|
|
16
|
+
value = getter
|
|
23
17
|
else
|
|
24
18
|
# A nil value means this is an unconditional else branch, it
|
|
25
19
|
# should always be true
|
|
@@ -29,7 +23,7 @@ class IfBinding < BaseBinding
|
|
|
29
23
|
@branches << [value, template_name]
|
|
30
24
|
end
|
|
31
25
|
|
|
32
|
-
update
|
|
26
|
+
@computation = -> { update }.watch!
|
|
33
27
|
end
|
|
34
28
|
|
|
35
29
|
def update
|
|
@@ -38,10 +32,19 @@ class IfBinding < BaseBinding
|
|
|
38
32
|
@branches.each do |branch|
|
|
39
33
|
value, template_name = branch
|
|
40
34
|
|
|
41
|
-
|
|
35
|
+
if value.is_a?(Proc)
|
|
36
|
+
begin
|
|
37
|
+
current_value = @context.instance_eval(&value)
|
|
38
|
+
rescue => e
|
|
39
|
+
Volt.logger.error("IfBinding:#{object_id} error: #{e.inspect}\n" + `value.toString()`)
|
|
40
|
+
current_value = false
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
current_value = value
|
|
44
|
+
end
|
|
42
45
|
|
|
43
46
|
# TODO: A bug in opal requires us to check == true
|
|
44
|
-
if current_value.
|
|
47
|
+
if current_value && !current_value.nil? && !current_value.is_a?(Exception)
|
|
45
48
|
# This branch is currently true
|
|
46
49
|
true_template = template_name
|
|
47
50
|
break
|
|
@@ -64,8 +67,8 @@ class IfBinding < BaseBinding
|
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
def remove
|
|
67
|
-
|
|
68
|
-
@
|
|
70
|
+
@computation.stop if @computation
|
|
71
|
+
@computation = nil
|
|
69
72
|
|
|
70
73
|
@template.remove if @template
|
|
71
74
|
|
|
@@ -11,28 +11,10 @@ class TemplateBinding < BaseBinding
|
|
|
11
11
|
|
|
12
12
|
@current_template = nil
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
@path, section, @options = value_from_getter(getter)
|
|
16
|
-
|
|
17
|
-
if section.is_a?(String)
|
|
18
|
-
# Render this as a section
|
|
19
|
-
@section = section
|
|
20
|
-
else
|
|
21
|
-
# Use the value passed in as the default arguments
|
|
22
|
-
@arguments = section
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Sometimes we want multiple template bindings to share the same controller (usually
|
|
26
|
-
# when displaying a :Title and a :Body), this instance tracks those.
|
|
27
|
-
if @options && (controller_group = @options[:controller_group])
|
|
28
|
-
@grouped_controller = GroupedControllers.new(controller_group)
|
|
29
|
-
end
|
|
14
|
+
@getter = getter
|
|
30
15
|
|
|
31
16
|
# Run the initial render
|
|
32
|
-
update
|
|
33
|
-
|
|
34
|
-
@path_changed_listener = @path.on('changed') { queue_update } if @path.reactive?
|
|
35
|
-
@section_changed_listener = @section.on('changed') { queue_update } if @section && @section.reactive?
|
|
17
|
+
@computation = -> { update(*@context.instance_eval(&getter)) }.watch!
|
|
36
18
|
end
|
|
37
19
|
|
|
38
20
|
def setup_path(binding_in_path)
|
|
@@ -112,43 +94,88 @@ class TemplateBinding < BaseBinding
|
|
|
112
94
|
return nil, nil
|
|
113
95
|
end
|
|
114
96
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
97
|
+
def update(path, section_or_arguments=nil, options={})
|
|
98
|
+
Computation.run_without_tracking do
|
|
99
|
+
# Remove existing template and call _removed
|
|
100
|
+
controller_send(:"#{@action}_removed") if @action && @controller
|
|
101
|
+
@current_template.remove if @current_template
|
|
119
102
|
|
|
120
|
-
|
|
121
|
-
end
|
|
103
|
+
@options = options
|
|
122
104
|
|
|
123
|
-
|
|
124
|
-
|
|
105
|
+
# A blank path needs to load a missing template, otherwise it tries to load
|
|
106
|
+
# the same template.
|
|
107
|
+
path = path.blank? ? '---missing---' : path
|
|
125
108
|
|
|
126
|
-
|
|
109
|
+
section = nil
|
|
110
|
+
@arguments = nil
|
|
127
111
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
112
|
+
if section_or_arguments.is_a?(String)
|
|
113
|
+
# Render this as a section
|
|
114
|
+
section = section_or_arguments
|
|
115
|
+
else
|
|
116
|
+
# Use the value passed in as the default arguments
|
|
117
|
+
@arguments = section_or_arguments
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Sometimes we want multiple template bindings to share the same controller (usually
|
|
121
|
+
# when displaying a :Title and a :Body), this instance tracks those.
|
|
122
|
+
if @options && (controller_group = @options[:controller_group])
|
|
123
|
+
@grouped_controller = GroupedControllers.new(controller_group)
|
|
124
|
+
else
|
|
125
|
+
clear_grouped_controller
|
|
134
126
|
end
|
|
127
|
+
|
|
128
|
+
full_path, controller_path = path_for_template(path, section)
|
|
129
|
+
render_template(full_path, controller_path)
|
|
130
|
+
|
|
131
|
+
queue_clear_grouped_controller
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# On the next tick, we clear the grouped controller so that any changes to template paths
|
|
136
|
+
# will create a new controller and trigger the action.
|
|
137
|
+
def queue_clear_grouped_controller
|
|
138
|
+
if Volt.in_browser?
|
|
139
|
+
# In the browser, we want to keep a grouped controller around during a single run
|
|
140
|
+
# of the event loop. To make that happen, we clear it on the next tick.
|
|
141
|
+
`setImmediate(function() {`
|
|
142
|
+
clear_grouped_controller
|
|
143
|
+
`})`
|
|
144
|
+
else
|
|
145
|
+
# For the backend, clear it immediately
|
|
146
|
+
clear_grouped_controller
|
|
135
147
|
end
|
|
148
|
+
end
|
|
136
149
|
|
|
137
|
-
|
|
150
|
+
def clear_grouped_controller
|
|
151
|
+
if @grouped_controller
|
|
152
|
+
@grouped_controller.clear
|
|
153
|
+
@grouped_controller = nil
|
|
154
|
+
end
|
|
138
155
|
end
|
|
139
156
|
|
|
140
157
|
# The context for templates can be either a controller, or the original context.
|
|
141
158
|
def render_template(full_path, controller_path)
|
|
142
|
-
|
|
159
|
+
if @arguments
|
|
160
|
+
args = [SubContext.new(@arguments)]
|
|
161
|
+
else
|
|
162
|
+
args = []
|
|
163
|
+
end
|
|
143
164
|
|
|
144
165
|
@controller = nil
|
|
145
166
|
|
|
146
167
|
# Fetch grouped controllers if we're grouping
|
|
147
168
|
@controller = @grouped_controller.get if @grouped_controller
|
|
148
169
|
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
|
|
170
|
+
# The action to be called and rendered
|
|
171
|
+
@action = nil
|
|
172
|
+
|
|
173
|
+
if @controller
|
|
174
|
+
# Track that we're using the group controller
|
|
175
|
+
@grouped_controller.inc if @grouped_controller
|
|
176
|
+
else
|
|
177
|
+
# Otherwise, make a new controller
|
|
178
|
+
controller_class, @action = get_controller(controller_path)
|
|
152
179
|
|
|
153
180
|
if controller_class
|
|
154
181
|
# Setup the controller
|
|
@@ -158,7 +185,7 @@ class TemplateBinding < BaseBinding
|
|
|
158
185
|
end
|
|
159
186
|
|
|
160
187
|
# Trigger the action
|
|
161
|
-
@
|
|
188
|
+
controller_send(@action) if @action
|
|
162
189
|
|
|
163
190
|
# Track the grouped controller
|
|
164
191
|
@grouped_controller.set(@controller) if @grouped_controller
|
|
@@ -177,24 +204,12 @@ class TemplateBinding < BaseBinding
|
|
|
177
204
|
@controller.section = @current_template.dom_section
|
|
178
205
|
end
|
|
179
206
|
|
|
180
|
-
if @
|
|
181
|
-
@controller.dom_ready
|
|
182
|
-
end
|
|
207
|
+
controller_send(:"#{@action}_ready") if @action
|
|
183
208
|
end
|
|
184
209
|
end
|
|
185
210
|
|
|
186
211
|
def remove
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if @path_changed_listener
|
|
190
|
-
@path_changed_listener.remove
|
|
191
|
-
@path_changed_listener = nil
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
if @section_changed_listener
|
|
195
|
-
@section_changed_listener.remove
|
|
196
|
-
@section_changed_listener = nil
|
|
197
|
-
end
|
|
212
|
+
clear_grouped_controller
|
|
198
213
|
|
|
199
214
|
if @current_template
|
|
200
215
|
# Remove the template if one has been rendered, when the template binding is
|
|
@@ -205,16 +220,19 @@ class TemplateBinding < BaseBinding
|
|
|
205
220
|
super
|
|
206
221
|
|
|
207
222
|
if @controller
|
|
208
|
-
#
|
|
209
|
-
if @controller.respond_to?(:dom_removed)
|
|
210
|
-
@controller.dom_removed
|
|
211
|
-
end
|
|
223
|
+
controller_send(:"#{@action}_removed") if @action
|
|
212
224
|
|
|
213
225
|
@controller = nil
|
|
214
226
|
end
|
|
215
227
|
end
|
|
216
228
|
|
|
217
229
|
private
|
|
230
|
+
# Sends the action to the controller if it exists
|
|
231
|
+
def controller_send(action_name)
|
|
232
|
+
if @controller.respond_to?(action_name)
|
|
233
|
+
@controller.send(action_name)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
218
236
|
|
|
219
237
|
# Fetch the controller class
|
|
220
238
|
def get_controller(controller_path)
|