volt 0.6.5 → 0.7.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/Readme.md +47 -40
- data/VERSION +1 -1
- data/app/volt/controllers/notices_controller.rb +3 -3
- data/app/volt/tasks/live_query/data_store.rb +2 -2
- data/app/volt/tasks/live_query/live_query.rb +20 -20
- data/app/volt/tasks/live_query/live_query_pool.rb +6 -6
- data/app/volt/tasks/live_query/query_tracker.rb +15 -15
- data/app/volt/tasks/query_tasks.rb +13 -13
- data/app/volt/tasks/store_tasks.rb +7 -7
- data/app/volt/views/notices/index.html +17 -18
- data/lib/volt/assets/test.rb +2 -2
- data/lib/volt/benchmark/benchmark.rb +25 -23
- data/lib/volt/cli/asset_compile.rb +11 -0
- data/lib/volt/cli/new_gem.rb +16 -16
- data/lib/volt/cli.rb +14 -12
- data/lib/volt/console.rb +5 -6
- data/lib/volt/controllers/model_controller.rb +18 -18
- data/lib/volt/extra_core/array.rb +4 -4
- data/lib/volt/extra_core/hash.rb +3 -3
- data/lib/volt/extra_core/object.rb +6 -6
- data/lib/volt/extra_core/string.rb +6 -6
- data/lib/volt/extra_core/symbol.rb +5 -5
- data/lib/volt/extra_core/time.rb +4 -4
- data/lib/volt/extra_core/true_false.rb +6 -6
- data/lib/volt/extra_core/try.rb +9 -9
- data/lib/volt/models/array_model.rb +26 -26
- data/lib/volt/models/model.rb +35 -35
- data/lib/volt/models/model_hash_behaviour.rb +15 -15
- data/lib/volt/models/model_helpers.rb +8 -8
- data/lib/volt/models/model_wrapper.rb +6 -6
- data/lib/volt/models/persistors/array_store.rb +36 -36
- data/lib/volt/models/persistors/base.rb +6 -6
- data/lib/volt/models/persistors/flash.rb +5 -5
- data/lib/volt/models/persistors/model_identity_map.rb +2 -2
- data/lib/volt/models/persistors/model_store.rb +22 -22
- data/lib/volt/models/persistors/params.rb +3 -3
- data/lib/volt/models/persistors/query/query_listener.rb +14 -14
- data/lib/volt/models/persistors/query/query_listener_pool.rb +2 -2
- data/lib/volt/models/persistors/store.rb +8 -8
- data/lib/volt/models/persistors/store_factory.rb +2 -2
- data/lib/volt/models/url.rb +37 -37
- data/lib/volt/page/bindings/attribute_binding.rb +14 -14
- data/lib/volt/page/bindings/base_binding.rb +9 -9
- data/lib/volt/page/bindings/component_binding.rb +7 -7
- data/lib/volt/page/bindings/content_binding.rb +3 -3
- data/lib/volt/page/bindings/each_binding.rb +13 -13
- data/lib/volt/page/bindings/event_binding.rb +4 -4
- data/lib/volt/page/bindings/if_binding.rb +12 -12
- data/lib/volt/page/bindings/template_binding.rb +30 -30
- data/lib/volt/page/channel.rb +19 -19
- data/lib/volt/page/channel_stub.rb +6 -6
- data/lib/volt/page/document.rb +2 -2
- data/lib/volt/page/document_events.rb +4 -4
- data/lib/volt/page/draw_cycle.rb +3 -3
- data/lib/volt/page/memory_test.rb +6 -6
- data/lib/volt/page/page.rb +19 -19
- data/lib/volt/page/reactive_template.rb +9 -9
- data/lib/volt/page/sub_context.rb +5 -5
- data/lib/volt/page/targets/attribute_section.rb +9 -9
- data/lib/volt/page/targets/attribute_target.rb +3 -3
- data/lib/volt/page/targets/base_section.rb +2 -2
- data/lib/volt/page/targets/binding_document/component_node.rb +23 -23
- data/lib/volt/page/targets/binding_document/html_node.rb +2 -2
- data/lib/volt/page/targets/dom_section.rb +40 -38
- data/lib/volt/page/targets/dom_target.rb +2 -2
- data/lib/volt/page/tasks.rb +12 -12
- data/lib/volt/page/template_renderer.rb +4 -4
- data/lib/volt/page/url_tracker.rb +6 -6
- data/lib/volt/reactive/array_extensions.rb +2 -2
- data/lib/volt/reactive/destructive_methods.rb +5 -5
- data/lib/volt/reactive/event_chain.rb +25 -25
- data/lib/volt/reactive/events.rb +33 -33
- data/lib/volt/reactive/object_tracker.rb +21 -21
- data/lib/volt/reactive/object_tracking.rb +2 -2
- data/lib/volt/reactive/reactive_array.rb +57 -57
- data/lib/volt/reactive/reactive_tags.rb +16 -16
- data/lib/volt/reactive/reactive_value.rb +72 -72
- data/lib/volt/reactive/string_extensions.rb +3 -3
- data/lib/volt/router/routes.rb +22 -23
- data/lib/volt/server/component_handler.rb +5 -5
- data/lib/volt/server/component_templates.rb +14 -11
- data/lib/volt/server/html_parser/attribute_scope.rb +116 -0
- data/lib/volt/server/html_parser/each_scope.rb +18 -0
- data/lib/volt/server/html_parser/if_view_scope.rb +71 -0
- data/lib/volt/server/html_parser/sandlebars_parser.rb +219 -0
- data/lib/volt/server/html_parser/textarea_scope.rb +31 -0
- data/lib/volt/server/html_parser/view_handler.rb +82 -0
- data/lib/volt/server/html_parser/view_parser.rb +23 -0
- data/lib/volt/server/html_parser/view_scope.rb +145 -0
- data/lib/volt/server/rack/asset_files.rb +17 -17
- data/lib/volt/server/rack/component_paths.rb +18 -18
- data/lib/volt/server/rack/index_files.rb +8 -8
- data/lib/volt/server/rack/opal_files.rb +11 -11
- data/lib/volt/server/socket_connection_handler.rb +13 -13
- data/lib/volt/server/socket_connection_handler_stub.rb +2 -2
- data/lib/volt/server.rb +18 -18
- data/lib/volt/tasks/dispatcher.rb +5 -5
- data/lib/volt/utils/ejson.rb +2 -2
- data/lib/volt/utils/generic_counting_pool.rb +8 -8
- data/lib/volt/utils/generic_pool.rb +16 -16
- data/lib/volt/volt/environment.rb +4 -4
- data/lib/volt.rb +6 -6
- data/spec/integration/test_integration_spec.rb +2 -2
- data/spec/models/event_chain_spec.rb +38 -38
- data/spec/models/model_spec.rb +128 -128
- data/spec/models/old_model_spec.rb +17 -17
- data/spec/models/persistors/params_spec.rb +3 -3
- data/spec/models/persistors/store_spec.rb +7 -7
- data/spec/models/reactive_array_spec.rb +82 -82
- data/spec/models/reactive_generator_spec.rb +11 -11
- data/spec/models/reactive_tags_spec.rb +6 -6
- data/spec/models/reactive_value_spec.rb +70 -70
- data/spec/models/store_spec.rb +4 -4
- data/spec/models/string_extensions_spec.rb +13 -13
- data/spec/page/bindings/content_binding_spec.rb +6 -6
- data/spec/page/sub_context_spec.rb +1 -1
- data/spec/router/routes_spec.rb +3 -3
- data/spec/server/html_parser/sample_page.html +595 -0
- data/spec/server/html_parser/sandlebars_parser_spec.rb +192 -0
- data/spec/server/html_parser/view_parser_spec.rb +286 -0
- data/spec/server/rack/asset_files_spec.rb +6 -6
- data/spec/server/rack/component_paths_spec.rb +5 -5
- data/spec/spec_helper.rb +4 -5
- data/spec/store/mongo_spec.rb +3 -3
- data/spec/tasks/live_query_spec.rb +6 -6
- data/spec/tasks/query_tasks.rb +4 -4
- data/spec/tasks/query_tracker_spec.rb +20 -20
- data/spec/templates/targets/binding_document/component_node_spec.rb +4 -4
- data/spec/templates/template_binding_spec.rb +28 -28
- data/spec/utils/generic_counting_pool_spec.rb +5 -5
- data/spec/utils/generic_pool_spec.rb +14 -14
- data/templates/newgem/app/newgem/views/index/index.html +1 -2
- data/templates/project/app/home/config/dependencies.rb +1 -1
- data/templates/project/app/home/controllers/index_controller.rb +1 -1
- data/templates/project/app/home/views/index/about.html +4 -6
- data/templates/project/app/home/views/index/home.html +4 -5
- data/templates/project/app/home/views/index/index.html +8 -9
- data/templates/project/spec/spec_helper.rb +1 -1
- metadata +17 -8
- data/lib/volt/server/binding_setup.rb +0 -2
- data/lib/volt/server/if_binding_setup.rb +0 -31
- data/lib/volt/server/scope.rb +0 -43
- data/lib/volt/server/template_parser.rb +0 -453
- data/spec/server/template_parser_spec.rb +0 -50
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# 2. target - an DomTarget or AttributeTarget
|
|
8
8
|
# 3. context - the context object the binding will be evaluated in
|
|
9
9
|
# 4. binding_name - the id for the comment (or id for attributes) where the
|
|
10
|
-
# binding will be inserted.
|
|
10
|
+
# binding will be inserted.
|
|
11
11
|
class BaseBinding
|
|
12
12
|
attr_accessor :target, :context, :binding_name
|
|
13
13
|
|
|
@@ -24,31 +24,31 @@ class BaseBinding
|
|
|
24
24
|
def section
|
|
25
25
|
@section ||= target.section(@binding_name)
|
|
26
26
|
end
|
|
27
|
-
|
|
28
|
-
def remove
|
|
27
|
+
|
|
28
|
+
def remove
|
|
29
29
|
section.remove
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
# Clear any references
|
|
32
32
|
@target = nil
|
|
33
33
|
@context = nil
|
|
34
34
|
@section = nil
|
|
35
35
|
end
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
def remove_anchors
|
|
38
38
|
section.remove_anchors
|
|
39
39
|
end
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
def queue_update
|
|
42
42
|
if Volt.server?
|
|
43
43
|
# Run right away
|
|
44
44
|
update
|
|
45
45
|
else
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
def value_from_getter(getter)
|
|
51
51
|
# Evaluate the getter proc in the context
|
|
52
52
|
return @context.instance_eval(&getter)
|
|
53
53
|
end
|
|
54
|
-
end
|
|
54
|
+
end
|
|
@@ -3,21 +3,21 @@ require 'volt/page/bindings/template_binding'
|
|
|
3
3
|
# Component bindings are the same as template bindings, but handle components
|
|
4
4
|
# and do not pass their context through
|
|
5
5
|
class ComponentBinding < TemplateBinding
|
|
6
|
-
# The context for a component binding can be either the controller, or the
|
|
6
|
+
# The context for a component binding can be either the controller, or the
|
|
7
7
|
# component arguments (@model), with the $page as the context. This gives
|
|
8
8
|
# components access to the page collections.
|
|
9
9
|
def render_template(full_path, controller_name)
|
|
10
10
|
# TODO: at the moment a :body section and a :title will both initialize different
|
|
11
|
-
# controllers. Maybe we should have a way to tie them together?
|
|
11
|
+
# controllers. Maybe we should have a way to tie them together?
|
|
12
12
|
controller_class = get_controller(controller_name)
|
|
13
13
|
model_with_parent = {parent: @context}.merge(@model || {})
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
if controller_class
|
|
16
|
-
# The user provided a controller, pass in the model as an argument (in a
|
|
16
|
+
# The user provided a controller, pass in the model as an argument (in a
|
|
17
17
|
# sub-context)
|
|
18
18
|
args = []
|
|
19
19
|
args << SubContext.new(model_with_parent) if @model
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
current_context = controller_class.new(*args)
|
|
22
22
|
@controller = current_context
|
|
23
23
|
else
|
|
@@ -27,7 +27,7 @@ class ComponentBinding < TemplateBinding
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
@current_template = TemplateRenderer.new(@page, @target, current_context, @binding_name, full_path)
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
call_ready
|
|
32
32
|
end
|
|
33
|
-
end
|
|
33
|
+
end
|
|
@@ -18,10 +18,10 @@ class ContentBinding < BaseBinding
|
|
|
18
18
|
|
|
19
19
|
def update
|
|
20
20
|
value = @value.cur.or('')
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
# Exception values display the exception as a string
|
|
23
23
|
value = value.to_s
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
# Update the html in this section
|
|
26
26
|
# TODO: Move the formatter into another class.
|
|
27
27
|
section.html = value.gsub("\n", "<br />\n")
|
|
@@ -37,4 +37,4 @@ class ContentBinding < BaseBinding
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
end
|
|
40
|
+
end
|
|
@@ -21,7 +21,7 @@ class EachBinding < BaseBinding
|
|
|
21
21
|
@changed_listener = @value.on('changed') { reload }
|
|
22
22
|
@removed_listener = @value.on('removed') { |_, position| item_removed(position) }
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
# When a change event comes through, its most likely upstream, so the whole
|
|
26
26
|
# array might have changed. In this case, just reload the whole thing
|
|
27
27
|
# TODO: Track to make sure the changed event isn't being called too often (it is currently)
|
|
@@ -31,14 +31,14 @@ class EachBinding < BaseBinding
|
|
|
31
31
|
if @templates
|
|
32
32
|
@templates.each do |template|
|
|
33
33
|
template.remove_anchors
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
# TODO: Make sure this is being removed since we already removed the anchors
|
|
36
36
|
template.remove
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
@templates = []
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
# Run update again to rebuild
|
|
43
43
|
update
|
|
44
44
|
|
|
@@ -50,7 +50,7 @@ class EachBinding < BaseBinding
|
|
|
50
50
|
@templates[position].remove_anchors
|
|
51
51
|
@templates[position].remove
|
|
52
52
|
@templates.delete_at(position)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
# Removed at the position, update context for every item after this position
|
|
55
55
|
update_indexes_after(position)
|
|
56
56
|
end
|
|
@@ -65,21 +65,21 @@ class EachBinding < BaseBinding
|
|
|
65
65
|
# Setup new bindings in the spot we want to insert the item
|
|
66
66
|
section.insert_anchor_before_end(binding_name)
|
|
67
67
|
else
|
|
68
|
-
# Insert the item before an existing item
|
|
68
|
+
# Insert the item before an existing item
|
|
69
69
|
section.insert_anchor_before(binding_name, @templates[position].binding_name)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
index = ReactiveValue.new(position)
|
|
73
73
|
value = @value[index]
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
item_context = SubContext.new({@item_name => value, :index => index, :parent => @value}, @context)
|
|
76
76
|
|
|
77
77
|
item_template = TemplateRenderer.new(@page, @target, item_context, binding_name, @template_name)
|
|
78
78
|
@templates.insert(position, item_template)
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
update_indexes_after(position)
|
|
81
81
|
end
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
# When items are added or removed in the middle of the list, we need
|
|
84
84
|
# to update each templates index value.
|
|
85
85
|
def update_indexes_after(start_index)
|
|
@@ -111,18 +111,18 @@ class EachBinding < BaseBinding
|
|
|
111
111
|
# puts "Remove Each"
|
|
112
112
|
@added_listener.remove
|
|
113
113
|
@added_listener = nil
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
@changed_listener.remove
|
|
116
116
|
@changed_listener = nil
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
@removed_listener.remove
|
|
119
119
|
@removed_listener = nil
|
|
120
120
|
|
|
121
121
|
@templates.each(&:remove)
|
|
122
122
|
@templates = nil
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
super
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
|
|
128
|
-
end
|
|
128
|
+
end
|
|
@@ -6,7 +6,7 @@ class JSEvent
|
|
|
6
6
|
def initialize(js_event)
|
|
7
7
|
@js_event = js_event
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def key_code
|
|
11
11
|
`this.js_event.keyCode`
|
|
12
12
|
end
|
|
@@ -16,7 +16,7 @@ class JSEvent
|
|
|
16
16
|
# `this.js_event.stopPropagation();`
|
|
17
17
|
`this.js_event.preventDefault();`
|
|
18
18
|
end
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
def target
|
|
21
21
|
`this.js_event.toElement`
|
|
22
22
|
end
|
|
@@ -28,7 +28,7 @@ class EventBinding < BaseBinding
|
|
|
28
28
|
def initialize(page, target, context, binding_name, event_name, call_proc)
|
|
29
29
|
super(page, target, context, binding_name)
|
|
30
30
|
@event_name = event_name
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
handler = Proc.new do |js_event|
|
|
33
33
|
event = JSEvent.new(js_event)
|
|
34
34
|
event.stop if event_name == 'submit'
|
|
@@ -46,4 +46,4 @@ class EventBinding < BaseBinding
|
|
|
46
46
|
# puts "REMOVE EL FOR #{@event}"
|
|
47
47
|
@page.events.remove(@event_name, self)
|
|
48
48
|
end
|
|
49
|
-
end
|
|
49
|
+
end
|
|
@@ -9,10 +9,10 @@ class IfBinding < BaseBinding
|
|
|
9
9
|
|
|
10
10
|
@branches = []
|
|
11
11
|
@listeners = []
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
branches.each do |branch|
|
|
14
14
|
getter, template_name = branch
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
if getter.present?
|
|
17
17
|
# Lookup the value
|
|
18
18
|
value = value_from_getter(getter)
|
|
@@ -26,19 +26,19 @@ class IfBinding < BaseBinding
|
|
|
26
26
|
# should always be true
|
|
27
27
|
value = true
|
|
28
28
|
end
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
@branches << [value, template_name]
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
update
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
def update
|
|
37
37
|
# Find the true branch
|
|
38
38
|
true_template = nil
|
|
39
39
|
@branches.each do |branch|
|
|
40
40
|
value, template_name = branch
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
# TODO: A bug in opal requires us to check == true
|
|
43
43
|
if value.cur.true? == true
|
|
44
44
|
# This branch is currently true
|
|
@@ -46,28 +46,28 @@ class IfBinding < BaseBinding
|
|
|
46
46
|
break
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
# Change out the template only if the true branch has changed.
|
|
51
51
|
if @last_true_template != true_template
|
|
52
52
|
@last_true_template = true_template
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
if @template
|
|
55
55
|
@template.remove
|
|
56
56
|
@template = nil
|
|
57
57
|
end
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
if true_template
|
|
60
60
|
@template = TemplateRenderer.new(@page, @target, @context, binding_name, true_template)
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
def remove
|
|
66
66
|
# Remove all listeners on any reactive values
|
|
67
67
|
@listeners.each(&:remove)
|
|
68
68
|
|
|
69
69
|
@template.remove if @template
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
super
|
|
72
72
|
end
|
|
73
|
-
end
|
|
73
|
+
end
|
|
@@ -5,17 +5,17 @@ class TemplateBinding < BaseBinding
|
|
|
5
5
|
def initialize(page, target, context, binding_name, binding_in_path, getter)
|
|
6
6
|
# puts "New template binding: #{context.inspect} - #{binding_name.inspect}"
|
|
7
7
|
super(page, target, context, binding_name)
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
# Binding in path is the path for the template this binding is in
|
|
10
10
|
setup_path(binding_in_path)
|
|
11
11
|
|
|
12
12
|
@current_template = nil
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
# puts "GETTER: #{value_from_getter(getter).inspect}"
|
|
15
15
|
|
|
16
16
|
# Find the source for the getter binding
|
|
17
17
|
@path, section = value_from_getter(getter)
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
if section.is_a?(String)
|
|
20
20
|
# Render this as a section
|
|
21
21
|
@section = section
|
|
@@ -30,19 +30,19 @@ class TemplateBinding < BaseBinding
|
|
|
30
30
|
@path_changed_listener = @path.on('changed') { update } if @path.reactive?
|
|
31
31
|
@section_changed_listener = @section.on('changed') { update } if @section && @section.reactive?
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
def setup_path(binding_in_path)
|
|
35
35
|
path_parts = binding_in_path.split('/')
|
|
36
36
|
@collection_name = path_parts[0]
|
|
37
37
|
@controller_name = path_parts[1]
|
|
38
38
|
@page_name = path_parts[2]
|
|
39
39
|
end
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
# Returns true if there is a template at the path
|
|
42
42
|
def check_for_template?(path)
|
|
43
43
|
@page.templates[path]
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
# Takes in a lookup path and returns the full path for the matching
|
|
47
47
|
# template. Also returns the controller name if applicable.
|
|
48
48
|
#
|
|
@@ -72,16 +72,16 @@ class TemplateBinding < BaseBinding
|
|
|
72
72
|
|
|
73
73
|
# When forcing a sub template, we can default the sub template section
|
|
74
74
|
default_parts[-1] = force_section if force_section
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
(5 - parts_size).times do |path_position|
|
|
77
77
|
# If they passed in a force_section, we can skip the first
|
|
78
78
|
next if force_section && path_position == 0
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
full_path = [@collection_name, @controller_name, @page_name, nil]
|
|
81
81
|
|
|
82
82
|
offset = 0
|
|
83
83
|
start_at = full_path.size - parts_size - path_position
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
full_path.size.times do |index|
|
|
86
86
|
if index >= start_at
|
|
87
87
|
if part = parts[index-start_at]
|
|
@@ -102,7 +102,7 @@ class TemplateBinding < BaseBinding
|
|
|
102
102
|
return path, controller
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
return nil, nil
|
|
107
107
|
end
|
|
108
108
|
|
|
@@ -110,7 +110,7 @@ class TemplateBinding < BaseBinding
|
|
|
110
110
|
full_path, controller_name = path_for_template(@path.cur, @section.cur)
|
|
111
111
|
|
|
112
112
|
@current_template.remove if @current_template
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
if @model
|
|
115
115
|
# Load in any procs
|
|
116
116
|
@model.each_pair do |key,value|
|
|
@@ -119,19 +119,19 @@ class TemplateBinding < BaseBinding
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
render_template(full_path, controller_name)
|
|
124
124
|
end
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
# The context for templates can be either a controller, or the original context.
|
|
127
|
-
def render_template(full_path, controller_name)
|
|
127
|
+
def render_template(full_path, controller_name)
|
|
128
128
|
# TODO: at the moment a :body section and a :title will both initialize different
|
|
129
129
|
# controllers. Maybe we should have a way to tie them together?
|
|
130
130
|
controller_class = get_controller(controller_name)
|
|
131
131
|
if controller_class
|
|
132
132
|
args = []
|
|
133
133
|
args << SubContext.new(@model) if @model
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
# Setup the controller
|
|
136
136
|
current_context = controller_class.new(*args)
|
|
137
137
|
@controller = current_context
|
|
@@ -141,21 +141,21 @@ class TemplateBinding < BaseBinding
|
|
|
141
141
|
@controller = nil
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
@current_template = TemplateRenderer.new(@page, @target, current_context, @binding_name, full_path)
|
|
145
|
-
|
|
144
|
+
@current_template = TemplateRenderer.new(@page, @target, current_context, @binding_name, full_path)
|
|
145
|
+
|
|
146
146
|
call_ready
|
|
147
147
|
end
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
def call_ready
|
|
150
150
|
if @controller
|
|
151
151
|
if @controller.respond_to?(:section=)
|
|
152
152
|
@controller.section = @current_template.section
|
|
153
153
|
end
|
|
154
|
-
|
|
154
|
+
|
|
155
155
|
if @controller.respond_to?(:dom_ready)
|
|
156
156
|
@controller.dom_ready
|
|
157
157
|
end
|
|
158
|
-
end
|
|
158
|
+
end
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def remove
|
|
@@ -168,7 +168,7 @@ class TemplateBinding < BaseBinding
|
|
|
168
168
|
@section_changed_listener.remove
|
|
169
169
|
@section_changed_listener = nil
|
|
170
170
|
end
|
|
171
|
-
|
|
171
|
+
|
|
172
172
|
if @current_template
|
|
173
173
|
# Remove the template if one has been rendered, when the template binding is
|
|
174
174
|
# removed.
|
|
@@ -176,31 +176,31 @@ class TemplateBinding < BaseBinding
|
|
|
176
176
|
end
|
|
177
177
|
|
|
178
178
|
super
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
if @controller
|
|
181
181
|
# Let the controller know we removed
|
|
182
182
|
if @controller.respond_to?(:dom_removed)
|
|
183
183
|
@controller.dom_removed
|
|
184
184
|
end
|
|
185
|
-
|
|
185
|
+
|
|
186
186
|
@controller = nil
|
|
187
187
|
end
|
|
188
188
|
end
|
|
189
|
-
|
|
189
|
+
|
|
190
190
|
private
|
|
191
|
-
|
|
191
|
+
|
|
192
192
|
# Fetch the controller class
|
|
193
193
|
def get_controller(controller_name)
|
|
194
194
|
return nil unless controller_name && controller_name.size > 0
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
# Get the constant parts
|
|
197
197
|
parts = controller_name.map {|v| v.gsub('-', '_').camelize }
|
|
198
|
-
|
|
198
|
+
|
|
199
199
|
# Home doesn't get namespaced
|
|
200
200
|
if parts.first == 'Home'
|
|
201
201
|
parts.shift
|
|
202
202
|
end
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
# Do const lookups starting at object and working our way down.
|
|
205
205
|
# So Volt::ProgressBar would lookup Volt, then ProgressBar on Volt.
|
|
206
206
|
obj = Object
|
|
@@ -211,8 +211,8 @@ class TemplateBinding < BaseBinding
|
|
|
211
211
|
return nil
|
|
212
212
|
end
|
|
213
213
|
end
|
|
214
|
-
|
|
214
|
+
|
|
215
215
|
return obj
|
|
216
216
|
end
|
|
217
|
-
|
|
217
|
+
|
|
218
218
|
end
|
data/lib/volt/page/channel.rb
CHANGED
|
@@ -5,9 +5,9 @@ require 'json'
|
|
|
5
5
|
|
|
6
6
|
class Channel
|
|
7
7
|
include ReactiveTags
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
attr_reader :status, :error, :reconnect_interval
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def initialize
|
|
12
12
|
@socket = nil
|
|
13
13
|
@status = :opening
|
|
@@ -15,18 +15,18 @@ class Channel
|
|
|
15
15
|
@error = nil
|
|
16
16
|
@retry_count = 0
|
|
17
17
|
@queue = []
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
connect!
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
def connected?
|
|
23
23
|
@connected
|
|
24
24
|
end
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
def retry_count
|
|
27
27
|
@retry_count
|
|
28
28
|
end
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
def connect!
|
|
31
31
|
%x{
|
|
32
32
|
this.socket = new SockJS('/channel');
|
|
@@ -38,13 +38,13 @@ class Channel
|
|
|
38
38
|
this.socket.onmessage = function(message) {
|
|
39
39
|
self['$message_received'](message.data);
|
|
40
40
|
};
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
this.socket.onclose = function(error) {
|
|
43
43
|
self.$closed(error);
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
end
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
def opened
|
|
49
49
|
@status = :open
|
|
50
50
|
@connected = true
|
|
@@ -53,7 +53,7 @@ class Channel
|
|
|
53
53
|
@queue.each do |message|
|
|
54
54
|
send_message(message)
|
|
55
55
|
end
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
trigger!('open')
|
|
58
58
|
trigger!('changed')
|
|
59
59
|
end
|
|
@@ -62,36 +62,36 @@ class Channel
|
|
|
62
62
|
@status = :closed
|
|
63
63
|
@connected = false
|
|
64
64
|
@error = `error.reason`
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
trigger!('closed')
|
|
67
67
|
trigger!('changed')
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
reconnect!
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
def reconnect!
|
|
73
73
|
@status = :reconnecting
|
|
74
74
|
@reconnect_interval ||= 0
|
|
75
75
|
@reconnect_interval += (2000 + rand(5000))
|
|
76
76
|
@retry_count += 1
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
# Trigger changed for reconnect interval
|
|
79
79
|
trigger!('changed')
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
interval = @reconnect_interval
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
%x{
|
|
84
84
|
setTimeout(function() {
|
|
85
85
|
self['$connect!']();
|
|
86
86
|
}, interval);
|
|
87
87
|
}
|
|
88
88
|
end
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
def message_received(message)
|
|
91
91
|
message = JSON.parse(message)
|
|
92
92
|
trigger!('message', nil, *message)
|
|
93
93
|
end
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
tag_method(:send_message) do
|
|
96
96
|
destructive!
|
|
97
97
|
end
|
|
@@ -106,11 +106,11 @@ class Channel
|
|
|
106
106
|
}
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
def close!
|
|
111
111
|
@status = :closed
|
|
112
112
|
%x{
|
|
113
113
|
this.socket.close();
|
|
114
114
|
}
|
|
115
115
|
end
|
|
116
|
-
end
|
|
116
|
+
end
|
|
@@ -11,28 +11,28 @@ class ChannelStub
|
|
|
11
11
|
include ReactiveTags
|
|
12
12
|
|
|
13
13
|
attr_reader :state, :error, :reconnect_interval
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
def initiailze
|
|
16
16
|
@state = :connected
|
|
17
17
|
end
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def opened
|
|
20
20
|
trigger!('open')
|
|
21
21
|
trigger!('changed')
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
def message_received(*message)
|
|
25
25
|
trigger!('message', nil, *message)
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
tag_method(:send_message) do
|
|
29
29
|
destructive!
|
|
30
30
|
end
|
|
31
31
|
def send_message(message)
|
|
32
32
|
SocketConnectionHandlerStub.new(self).process_message(message)
|
|
33
33
|
end
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
def close!
|
|
36
36
|
raise "close! should not be called on the backend channel"
|
|
37
37
|
end
|
|
38
|
-
end
|
|
38
|
+
end
|
data/lib/volt/page/document.rb
CHANGED
|
@@ -33,7 +33,7 @@ class DocumentEvents
|
|
|
33
33
|
|
|
34
34
|
loop do
|
|
35
35
|
# Lookup the handler, make sure to not assume the group
|
|
36
|
-
# exists.
|
|
36
|
+
# exists.
|
|
37
37
|
# TODO: Sometimes the event doesn't exist, but we still get
|
|
38
38
|
# an event.
|
|
39
39
|
handlers = @events[event_name]
|
|
@@ -52,7 +52,7 @@ class DocumentEvents
|
|
|
52
52
|
element = element.parent
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
nil
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -70,11 +70,11 @@ class DocumentEvents
|
|
|
70
70
|
# from the document
|
|
71
71
|
if @events[event].size == 0
|
|
72
72
|
@events.delete(event)
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
# Remove the event from the body
|
|
75
75
|
%x{
|
|
76
76
|
$('body').unbind(event);
|
|
77
77
|
}
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
|
-
end
|
|
80
|
+
end
|