volt 0.8.14 → 0.8.15
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/.gitignore +1 -1
- data/Readme.md +8 -2
- data/VERSION +1 -1
- data/app/volt/controllers/notices_controller.rb +1 -1
- data/app/volt/models/user.rb +2 -2
- data/app/volt/tasks/live_query/live_query_pool.rb +1 -1
- data/app/volt/tasks/query_tasks.rb +1 -1
- data/app/volt/tasks/store_tasks.rb +1 -1
- data/app/volt/tasks/user_tasks.rb +2 -2
- data/lib/volt/boot.rb +2 -2
- data/lib/volt/cli/asset_compile.rb +31 -27
- data/lib/volt/cli.rb +64 -65
- data/lib/volt/config.rb +25 -23
- data/lib/volt/console.rb +17 -16
- data/lib/volt/controllers/model_controller.rb +82 -80
- data/lib/volt/data_stores/data_store.rb +2 -2
- data/lib/volt/data_stores/mongo_driver.rb +2 -2
- data/lib/volt/extra_core/inflections.rb +2 -2
- data/lib/volt/extra_core/inflector/inflections.rb +185 -183
- data/lib/volt/extra_core/inflector/methods.rb +50 -48
- data/lib/volt/extra_core/string.rb +2 -2
- data/lib/volt/models/array_model.rb +93 -92
- data/lib/volt/models/cursor.rb +3 -2
- data/lib/volt/models/model.rb +248 -251
- data/lib/volt/models/model_hash_behaviour.rb +44 -44
- data/lib/volt/models/model_helpers.rb +38 -36
- data/lib/volt/models/model_state.rb +16 -17
- data/lib/volt/models/model_wrapper.rb +25 -24
- data/lib/volt/models/persistors/array_store.rb +145 -143
- data/lib/volt/models/persistors/base.rb +18 -16
- data/lib/volt/models/persistors/flash.rb +24 -22
- data/lib/volt/models/persistors/local_store.rb +46 -44
- data/lib/volt/models/persistors/model_identity_map.rb +10 -8
- data/lib/volt/models/persistors/model_store.rb +76 -76
- data/lib/volt/models/persistors/params.rb +19 -17
- data/lib/volt/models/persistors/query/query_listener.rb +65 -63
- data/lib/volt/models/persistors/query/query_listener_pool.rb +12 -10
- data/lib/volt/models/persistors/store.rb +28 -28
- data/lib/volt/models/persistors/store_factory.rb +12 -10
- data/lib/volt/models/persistors/store_state.rb +33 -31
- data/lib/volt/models/url.rb +96 -104
- data/lib/volt/models/validations.rb +56 -54
- data/lib/volt/models/validators/length_validator.rb +24 -22
- data/lib/volt/models/validators/presence_validator.rb +14 -12
- data/lib/volt/page/bindings/attribute_binding.rb +106 -106
- data/lib/volt/page/bindings/base_binding.rb +23 -21
- data/lib/volt/page/bindings/component_binding.rb +3 -1
- data/lib/volt/page/bindings/content_binding.rb +34 -34
- data/lib/volt/page/bindings/each_binding.rb +113 -113
- data/lib/volt/page/bindings/event_binding.rb +38 -34
- data/lib/volt/page/bindings/if_binding.rb +56 -54
- data/lib/volt/page/bindings/template_binding/grouped_controllers.rb +24 -22
- data/lib/volt/page/bindings/template_binding.rb +182 -185
- data/lib/volt/page/channel.rb +79 -77
- data/lib/volt/page/channel_stub.rb +29 -27
- data/lib/volt/page/document.rb +6 -5
- data/lib/volt/page/document_events.rb +54 -52
- data/lib/volt/page/page.rb +139 -138
- data/lib/volt/page/string_template_renderer.rb +36 -36
- data/lib/volt/page/sub_context.rb +26 -25
- data/lib/volt/page/targets/attribute_section.rb +27 -25
- data/lib/volt/page/targets/attribute_target.rb +7 -6
- data/lib/volt/page/targets/base_section.rb +27 -26
- data/lib/volt/page/targets/binding_document/base_node.rb +3 -1
- data/lib/volt/page/targets/binding_document/component_node.rb +85 -82
- data/lib/volt/page/targets/binding_document/html_node.rb +11 -9
- data/lib/volt/page/targets/dom_section.rb +78 -77
- data/lib/volt/page/targets/dom_target.rb +8 -6
- data/lib/volt/page/targets/dom_template.rb +90 -88
- data/lib/volt/page/targets/helpers/comment_searchers.rb +51 -49
- data/lib/volt/page/tasks.rb +59 -57
- data/lib/volt/page/template_renderer.rb +17 -14
- data/lib/volt/page/url_tracker.rb +26 -24
- data/lib/volt/reactive/computation.rb +87 -88
- data/lib/volt/reactive/dependency.rb +30 -28
- data/lib/volt/reactive/eventable.rb +64 -62
- data/lib/volt/reactive/hash_dependency.rb +25 -23
- data/lib/volt/reactive/reactive_accessors.rb +34 -32
- data/lib/volt/reactive/reactive_array.rb +162 -162
- data/lib/volt/reactive/reactive_hash.rb +37 -35
- data/lib/volt/router/routes.rb +99 -101
- data/lib/volt/server/component_handler.rb +20 -21
- data/lib/volt/server/component_templates.rb +72 -70
- data/lib/volt/server/html_parser/attribute_scope.rb +109 -99
- data/lib/volt/server/html_parser/each_scope.rb +17 -16
- data/lib/volt/server/html_parser/if_view_scope.rb +51 -49
- data/lib/volt/server/html_parser/sandlebars_parser.rb +184 -177
- data/lib/volt/server/html_parser/textarea_scope.rb +24 -22
- data/lib/volt/server/html_parser/view_handler.rb +66 -65
- data/lib/volt/server/html_parser/view_parser.rb +23 -21
- data/lib/volt/server/html_parser/view_scope.rb +142 -141
- data/lib/volt/server/rack/asset_files.rb +81 -79
- data/lib/volt/server/rack/component_code.rb +17 -15
- data/lib/volt/server/rack/component_html_renderer.rb +14 -12
- data/lib/volt/server/rack/component_paths.rb +72 -71
- data/lib/volt/server/rack/index_files.rb +36 -39
- data/lib/volt/server/rack/opal_files.rb +43 -41
- data/lib/volt/server/rack/source_map_server.rb +23 -21
- data/lib/volt/server/socket_connection_handler.rb +46 -45
- data/lib/volt/server/socket_connection_handler_stub.rb +21 -19
- data/lib/volt/server.rb +60 -58
- data/lib/volt/spec/setup.rb +3 -3
- data/lib/volt/tasks/dispatcher.rb +24 -23
- data/lib/volt/tasks/task_handler.rb +35 -33
- data/lib/volt/utils/ejson.rb +8 -6
- data/lib/volt/utils/generic_counting_pool.rb +33 -31
- data/lib/volt/utils/generic_pool.rb +73 -70
- data/lib/volt/utils/local_storage.rb +42 -38
- data/lib/volt/volt/environment.rb +1 -1
- data/lib/volt.rb +44 -42
- data/spec/apps/kitchen_sink/app/main/assets/css/todos.css +28 -0
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
- data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +2 -2
- data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +17 -0
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -0
- data/spec/apps/kitchen_sink/app/main/views/todos/index.html +24 -0
- data/spec/apps/kitchen_sink/config.ru +1 -1
- data/spec/controllers/reactive_accessors_spec.rb +5 -5
- data/spec/extra_core/inflector_spec.rb +2 -2
- data/spec/integration/list_spec.rb +68 -0
- data/spec/models/model_spec.rb +57 -57
- data/spec/models/persistors/params_spec.rb +6 -6
- data/spec/models/persistors/store_spec.rb +7 -7
- data/spec/models/validations_spec.rb +3 -3
- data/spec/page/bindings/content_binding_spec.rb +7 -7
- data/spec/page/bindings/template_binding_spec.rb +4 -5
- data/spec/page/sub_context_spec.rb +2 -2
- data/spec/reactive/computation_spec.rb +10 -10
- data/spec/reactive/dependency_spec.rb +2 -2
- data/spec/reactive/eventable_spec.rb +4 -4
- data/spec/reactive/reactive_array_spec.rb +13 -13
- data/spec/router/routes_spec.rb +5 -5
- data/spec/server/html_parser/sandlebars_parser_spec.rb +9 -9
- data/spec/server/html_parser/view_parser_spec.rb +27 -27
- data/spec/server/rack/asset_files_spec.rb +5 -5
- data/spec/server/rack/component_paths_spec.rb +2 -2
- data/spec/tasks/live_query_spec.rb +2 -2
- data/spec/tasks/query_tasks.rb +1 -1
- data/spec/tasks/query_tracker_spec.rb +1 -1
- data/spec/templates/targets/binding_document/component_node_spec.rb +2 -2
- data/spec/utils/generic_counting_pool_spec.rb +2 -2
- data/spec/utils/generic_pool_spec.rb +2 -2
- data/templates/component/controllers/main_controller.rb +1 -1
- data/templates/model/model.rb.tt +2 -2
- data/templates/newgem/app/newgem/controllers/main_controller.rb.tt +2 -2
- data/templates/project/app/main/controllers/main_controller.rb +1 -1
- data/templates/project/config.ru +1 -1
- metadata +10 -3
- data/app/volt/assets/js/vertxbus.js +0 -216
|
@@ -1,151 +1,151 @@
|
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
module Volt
|
|
4
|
+
class EachBinding < BaseBinding
|
|
5
|
+
def initialize(page, target, context, binding_name, getter, variable_name, template_name)
|
|
6
|
+
super(page, target, context, binding_name)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
@item_name = variable_name
|
|
9
|
+
@template_name = template_name
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
@templates = []
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
@getter = getter
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# When a changed event happens, we update to the new size.
|
|
19
|
-
def reload
|
|
20
|
-
begin
|
|
21
|
-
value = @context.instance_eval(&@getter)
|
|
22
|
-
rescue => e
|
|
23
|
-
Volt.logger.error("EachBinding Error: #{e.inspect}")
|
|
24
|
-
value = []
|
|
15
|
+
# Listen for changes
|
|
16
|
+
@computation = -> { reload }.watch!
|
|
25
17
|
end
|
|
26
18
|
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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) }
|
|
19
|
+
# When a changed event happens, we update to the new size.
|
|
20
|
+
def reload
|
|
21
|
+
begin
|
|
22
|
+
value = @context.instance_eval(&@getter)
|
|
23
|
+
rescue => e
|
|
24
|
+
Volt.logger.error("EachBinding Error: #{e.inspect}")
|
|
25
|
+
value = []
|
|
41
26
|
end
|
|
42
27
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
28
|
+
# Since we're checking things like size, we don't want this to be re-triggered on a
|
|
29
|
+
# size change, so we run without tracking.
|
|
30
|
+
Computation.run_without_tracking do
|
|
31
|
+
# puts "RELOAD:-------------- #{value.inspect}"
|
|
32
|
+
# Adjust to the new size
|
|
33
|
+
values = current_values(value)
|
|
34
|
+
@value = values
|
|
35
|
+
|
|
36
|
+
@added_listener.remove if @added_listener
|
|
37
|
+
@removed_listener.remove if @removed_listener
|
|
38
|
+
|
|
39
|
+
if @value.respond_to?(:on)
|
|
40
|
+
@added_listener = @value.on('added') { |position| item_added(position) }
|
|
41
|
+
@removed_listener = @value.on('removed') { |position| item_removed(position) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
templates_size = @templates.size
|
|
45
|
+
values_size = values.size
|
|
46
|
+
|
|
47
|
+
# Start over, re-create all nodes
|
|
48
|
+
(templates_size-1).downto(0) do |index|
|
|
49
|
+
item_removed(index)
|
|
50
|
+
end
|
|
51
|
+
0.upto(values_size-1) do |index|
|
|
52
|
+
item_added(index)
|
|
53
|
+
end
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
|
-
end
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
def item_removed(position)
|
|
58
|
+
# Remove dependency
|
|
59
|
+
@templates[position].context.locals[:index_dependency].remove
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
# puts "REMOVE AT: #{position.inspect} - #{@templates[position].inspect} - #{@templates.inspect}"
|
|
62
|
+
@templates[position].remove_anchors
|
|
63
|
+
@templates[position].remove
|
|
64
|
+
@templates.delete_at(position)
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
# Removed at the position, update context for every item after this position
|
|
67
|
+
update_indexes_after(position)
|
|
68
|
+
end
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
def item_added(position)
|
|
71
|
+
binding_name = @@binding_number
|
|
72
|
+
@@binding_number += 1
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
if position >= @templates.size
|
|
75
|
+
# Setup new bindings in the spot we want to insert the item
|
|
76
|
+
dom_section.insert_anchor_before_end(binding_name)
|
|
77
|
+
else
|
|
78
|
+
# Insert the item before an existing item
|
|
79
|
+
dom_section.insert_anchor_before(binding_name, @templates[position].binding_name)
|
|
80
|
+
end
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
# TODORW: :parent => @value may change
|
|
83
|
+
item_context = SubContext.new({:_index_value => position, :parent => @value}, @context)
|
|
84
|
+
item_context.locals[@item_name.to_sym] = Proc.new { @value[item_context.locals[:_index_value]] }
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
position_dependency = Dependency.new
|
|
87
|
+
item_context.locals[:index_dependency] = position_dependency
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
# Get and set index
|
|
90
|
+
item_context.locals[:index=] = Proc.new do |val|
|
|
91
|
+
position_dependency.changed!
|
|
92
|
+
item_context.locals[:_index_value] = val
|
|
93
|
+
end
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
item_context.locals[:index] = Proc.new do
|
|
96
|
+
position_dependency.depend
|
|
97
|
+
item_context.locals[:_index_value]
|
|
98
|
+
end
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
item_template = TemplateRenderer.new(@page, @target, item_context, binding_name, @template_name)
|
|
101
|
+
@templates.insert(position, item_template)
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
update_indexes_after(position)
|
|
104
|
+
end
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
# When items are added or removed in the middle of the list, we need
|
|
107
|
+
# to update each templates index value.
|
|
108
|
+
def update_indexes_after(start_index)
|
|
109
|
+
size = @templates.size
|
|
110
|
+
if size > 0
|
|
111
|
+
start_index.upto(size-1) do |index|
|
|
112
|
+
@templates[index].context.locals[:index=].call(index)
|
|
113
|
+
end
|
|
112
114
|
end
|
|
113
115
|
end
|
|
114
|
-
end
|
|
115
116
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
def current_values(values)
|
|
118
|
+
return [] if values.is_a?(Model) || values.is_a?(Exception)
|
|
119
|
+
values = values.attributes if values.respond_to?(:attributes)
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
return values
|
|
122
|
+
end
|
|
122
123
|
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
# When this each_binding is removed, cleanup.
|
|
126
|
+
def remove
|
|
127
|
+
@computation.stop
|
|
128
|
+
@computation = nil
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
# Clear value
|
|
131
|
+
@value = nil
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
@added_listener.remove
|
|
134
|
+
@added_listener = nil
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
@removed_listener.remove
|
|
137
|
+
@removed_listener = nil
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
if @templates
|
|
140
|
+
template_count = @templates.size
|
|
141
|
+
template_count.times do |index|
|
|
142
|
+
item_removed(template_count - index - 1)
|
|
143
|
+
end
|
|
144
|
+
# @templates.compact.each(&:remove)
|
|
145
|
+
@templates = nil
|
|
142
146
|
end
|
|
143
|
-
# @templates.compact.each(&:remove)
|
|
144
|
-
@templates = nil
|
|
145
|
-
end
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
super
|
|
149
|
+
end
|
|
148
150
|
end
|
|
149
|
-
|
|
150
|
-
|
|
151
151
|
end
|
|
@@ -1,50 +1,54 @@
|
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
|
2
2
|
|
|
3
|
+
module Volt
|
|
3
4
|
# TODO: We need to figure out how we want to wrap JS events
|
|
4
|
-
class JSEvent
|
|
5
|
-
|
|
6
|
-
def initialize(js_event)
|
|
7
|
-
@js_event = js_event
|
|
8
|
-
end
|
|
5
|
+
class JSEvent
|
|
6
|
+
attr_reader :js_event
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
def initialize(js_event)
|
|
9
|
+
@js_event = js_event
|
|
10
|
+
end
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
def key_code
|
|
13
|
+
`this.js_event.keyCode`
|
|
14
|
+
end
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
def stop!
|
|
17
|
+
`this.js_event.stopPropagation();`
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def prevent_default!
|
|
21
|
+
`this.js_event.preventDefault();`
|
|
22
|
+
end
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
def target
|
|
25
|
+
`this.js_event.toElement`
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
|
-
end
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
class EventBinding < BaseBinding
|
|
29
|
-
|
|
30
|
-
def initialize(page, target, context, binding_name, event_name, call_proc)
|
|
31
|
-
super(page, target, context, binding_name)
|
|
32
|
-
@event_name = event_name
|
|
30
|
+
class EventBinding < BaseBinding
|
|
31
|
+
attr_accessor :context, :binding_name
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
def initialize(page, target, context, binding_name, event_name, call_proc)
|
|
34
|
+
super(page, target, context, binding_name)
|
|
35
|
+
@event_name = event_name
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
end
|
|
37
|
+
handler = Proc.new do |js_event|
|
|
38
|
+
event = JSEvent.new(js_event)
|
|
39
|
+
event.prevent_default! if event_name == 'submit'
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
# Call the proc the user setup for the event in context,
|
|
42
|
+
# pass in the wrapper for the JS event
|
|
43
|
+
result = @context.instance_exec(event, &call_proc)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
@listener = @page.events.add(event_name, self, handler)
|
|
47
|
+
end
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
# Remove the event binding
|
|
50
|
+
def remove
|
|
51
|
+
@page.events.remove(@event_name, self)
|
|
52
|
+
end
|
|
49
53
|
end
|
|
50
54
|
end
|
|
@@ -1,77 +1,79 @@
|
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
module Volt
|
|
4
|
+
class IfBinding < BaseBinding
|
|
5
|
+
def initialize(page, target, context, binding_name, branches)
|
|
6
|
+
super(page, target, context, binding_name)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
getter, template_name = branches[0]
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
@branches = []
|
|
11
|
+
@listeners = []
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
branches.each do |branch|
|
|
14
|
+
getter, template_name = branch
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
if getter.present?
|
|
17
|
+
value = getter
|
|
18
|
+
else
|
|
19
|
+
# A nil value means this is an unconditional else branch, it
|
|
20
|
+
# should always be true
|
|
21
|
+
value = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@branches << [value, template_name]
|
|
21
25
|
end
|
|
22
26
|
|
|
23
|
-
@
|
|
27
|
+
@computation = -> { update }.watch!
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
current_value =
|
|
30
|
+
def update
|
|
31
|
+
# Find the true branch
|
|
32
|
+
true_template = nil
|
|
33
|
+
@branches.each do |branch|
|
|
34
|
+
value, template_name = branch
|
|
35
|
+
|
|
36
|
+
if value.is_a?(Proc)
|
|
37
|
+
begin
|
|
38
|
+
current_value = @context.instance_eval(&value)
|
|
39
|
+
rescue => e
|
|
40
|
+
Volt.logger.error("IfBinding:#{object_id} error: #{e.inspect}\n" + `value.toString()`)
|
|
41
|
+
current_value = false
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
current_value = value
|
|
41
45
|
end
|
|
42
|
-
else
|
|
43
|
-
current_value = value
|
|
44
|
-
end
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
# TODO: A bug in opal requires us to check == true
|
|
48
|
+
if current_value && !current_value.nil? && !current_value.is_a?(Exception)
|
|
49
|
+
# This branch is currently true
|
|
50
|
+
true_template = template_name
|
|
51
|
+
break
|
|
52
|
+
end
|
|
51
53
|
end
|
|
52
|
-
end
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
# Change out the template only if the true branch has changed.
|
|
56
|
+
if @last_true_template != true_template
|
|
57
|
+
@last_true_template = true_template
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
if @template
|
|
60
|
+
@template.remove
|
|
61
|
+
@template = nil
|
|
62
|
+
end
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
if true_template
|
|
65
|
+
@template = TemplateRenderer.new(@page, @target, @context, binding_name, true_template)
|
|
66
|
+
end
|
|
65
67
|
end
|
|
66
68
|
end
|
|
67
|
-
end
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
def remove
|
|
71
|
+
@computation.stop if @computation
|
|
72
|
+
@computation = nil
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
@template.remove if @template
|
|
74
75
|
|
|
75
|
-
|
|
76
|
+
super
|
|
77
|
+
end
|
|
76
78
|
end
|
|
77
79
|
end
|
|
@@ -2,35 +2,37 @@
|
|
|
2
2
|
# on a name. This class keeps track of the number of templates using this controller
|
|
3
3
|
# and clears it once no one else is using it. Use #get or #inc to add to the count.
|
|
4
4
|
# #clear removes 1 from the count. When the count is 0, delete the controller.
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
module Volt
|
|
6
|
+
class GroupedControllers
|
|
7
|
+
@@controllers = {}
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
def initialize(name)
|
|
10
|
+
@name = name
|
|
11
|
+
end
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
def get
|
|
14
|
+
return (controller = self.controller) && controller[0]
|
|
15
|
+
end
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
def set(controller)
|
|
18
|
+
@@controllers[@name] = [controller, 1]
|
|
19
|
+
end
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def inc
|
|
22
|
+
controller[1] += 1
|
|
23
|
+
end
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
def clear
|
|
26
|
+
controller = self.controller
|
|
27
|
+
controller[1] -= 1
|
|
28
|
+
if controller[1] == 0
|
|
29
|
+
@@controllers.delete(@name)
|
|
30
|
+
end
|
|
29
31
|
end
|
|
30
|
-
end
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
private
|
|
33
34
|
def controller
|
|
34
35
|
@@controllers[@name]
|
|
35
36
|
end
|
|
36
|
-
end
|
|
37
|
+
end
|
|
38
|
+
end
|