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,115 +1,117 @@
|
|
|
1
1
|
require 'volt/page/targets/helpers/comment_searchers'
|
|
2
2
|
|
|
3
|
+
module Volt
|
|
3
4
|
# A dom template is used to optimize going from a template name to
|
|
4
5
|
# dom nodes and bindings. It stores a copy of the template's parsed
|
|
5
6
|
# dom nodes, then when a new instance is requested, it updates the
|
|
6
7
|
# dom markers (comments) for new binding numbers and returns a cloneNode'd
|
|
7
8
|
# version of the dom nodes and the bindings.
|
|
8
|
-
class DomTemplate
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def initialize(page, template_name)
|
|
12
|
-
template = page.templates[template_name]
|
|
13
|
-
|
|
14
|
-
if template
|
|
15
|
-
html = template['html']
|
|
16
|
-
@bindings = template['bindings']
|
|
17
|
-
else
|
|
18
|
-
html = "<div>-- < missing template #{template_name.inspect.gsub('<', '<').gsub('>', '>')} > --</div>"
|
|
19
|
-
@bindings = {}
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
@nodes = build_from_html(html)
|
|
9
|
+
class DomTemplate
|
|
10
|
+
include CommentSearchers
|
|
23
11
|
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
def initialize(page, template_name)
|
|
13
|
+
template = page.templates[template_name]
|
|
26
14
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
if template
|
|
16
|
+
html = template['html']
|
|
17
|
+
@bindings = template['bindings']
|
|
18
|
+
else
|
|
19
|
+
html = "<div>-- < missing template #{template_name.inspect.gsub('<', '<').gsub('>', '>')} > --</div>"
|
|
20
|
+
@bindings = {}
|
|
21
|
+
end
|
|
30
22
|
|
|
31
|
-
|
|
23
|
+
@nodes = build_from_html(html)
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
track_binding_anchors
|
|
26
|
+
end
|
|
35
27
|
|
|
28
|
+
# Returns the dom nodes and bindings
|
|
29
|
+
def make_new
|
|
30
|
+
bindings = update_binding_anchors!(`self.nodes`)
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
# to them so they can be quickly updated without using xpath to find them again.
|
|
39
|
-
def track_binding_anchors
|
|
40
|
-
@binding_anchors = {}
|
|
41
|
-
|
|
42
|
-
# Loop through the bindings, find in nodes.
|
|
43
|
-
@bindings.each_pair do |name,binding|
|
|
44
|
-
if name.is_a?(String)
|
|
45
|
-
# Find the dom node for an attribute anchor
|
|
46
|
-
node = nil
|
|
47
|
-
%x{
|
|
48
|
-
node = self.nodes.querySelector('#' + name);
|
|
49
|
-
}
|
|
50
|
-
@binding_anchors[name] = node
|
|
51
|
-
else
|
|
52
|
-
# Find the dom node for a comment anchor
|
|
53
|
-
start_comment = find_by_comment("$#{name}", @nodes)
|
|
54
|
-
end_comment = find_by_comment("$/#{name}", @nodes)
|
|
32
|
+
new_nodes = `self.nodes.cloneNode(true)`
|
|
55
33
|
|
|
56
|
-
|
|
57
|
-
end
|
|
34
|
+
return [new_nodes, bindings]
|
|
58
35
|
end
|
|
59
|
-
end
|
|
60
36
|
|
|
61
|
-
# Takes the binding_anchors and updates them with new numbers (comments and id's)
|
|
62
|
-
# then returns the bindings updated to the new numbers.
|
|
63
|
-
def update_binding_anchors!(nodes)
|
|
64
|
-
new_bindings = {}
|
|
65
37
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
38
|
+
# Finds each of the binding anchors in the temp dom, then stores a reference
|
|
39
|
+
# to them so they can be quickly updated without using xpath to find them again.
|
|
40
|
+
def track_binding_anchors
|
|
41
|
+
@binding_anchors = {}
|
|
69
42
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
43
|
+
# Loop through the bindings, find in nodes.
|
|
44
|
+
@bindings.each_pair do |name, binding|
|
|
45
|
+
if name.is_a?(String)
|
|
46
|
+
# Find the dom node for an attribute anchor
|
|
47
|
+
node = nil
|
|
48
|
+
%x{
|
|
49
|
+
node = self.nodes.querySelector('#' + name);
|
|
50
|
+
}
|
|
51
|
+
@binding_anchors[name] = node
|
|
77
52
|
else
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
|
|
53
|
+
# Find the dom node for a comment anchor
|
|
54
|
+
start_comment = find_by_comment("$#{name}", @nodes)
|
|
55
|
+
end_comment = find_by_comment("$/#{name}", @nodes)
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
new_bindings[name] = @bindings[name]
|
|
57
|
+
@binding_anchors[name] = [start_comment, end_comment]
|
|
84
58
|
end
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Takes the binding_anchors and updates them with new numbers (comments and id's)
|
|
63
|
+
# then returns the bindings updated to the new numbers.
|
|
64
|
+
def update_binding_anchors!(nodes)
|
|
65
|
+
new_bindings = {}
|
|
66
|
+
|
|
67
|
+
@binding_anchors.each_pair do |name, anchors|
|
|
68
|
+
new_name = @@binding_number
|
|
69
|
+
@@binding_number += 1
|
|
70
|
+
|
|
71
|
+
if name.is_a?(String)
|
|
72
|
+
if name[0..1] == 'id'
|
|
73
|
+
# A generated id
|
|
74
|
+
# update the id
|
|
75
|
+
`anchors.setAttribute('id', 'id' + new_name);`
|
|
76
|
+
|
|
77
|
+
new_bindings["id#{new_name}"] = @bindings[name]
|
|
78
|
+
else
|
|
79
|
+
# Assume a fixed id, should not be updated
|
|
80
|
+
# TODO: Might want to check the page to see if a node
|
|
81
|
+
# with this id already exists and raise if it does.
|
|
82
|
+
|
|
83
|
+
# Copy from existing binding
|
|
84
|
+
new_bindings[name] = @bindings[name]
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
start_comment, end_comment = anchors
|
|
88
|
+
|
|
89
|
+
%x{
|
|
90
|
+
if (start_comment.textContent) {
|
|
91
|
+
// direct update
|
|
92
|
+
start_comment.textContent = " $" + new_name + " ";
|
|
93
|
+
end_comment.textContent = " $/" + new_name + " ";
|
|
94
|
+
} else if (start_comment.innerText) {
|
|
95
|
+
start_comment.innerText = " $" + new_name + " ";
|
|
96
|
+
end_comment.innerText = " $/" + new_name + " ";
|
|
97
|
+
} else {
|
|
98
|
+
// phantomjs doesn't work with textContent, so we replace the nodes
|
|
99
|
+
// and update the references
|
|
100
|
+
start_comment.nodeValue = " $" + new_name + " ";
|
|
101
|
+
end_comment.nodeValue = " $/" + new_name + " ";
|
|
102
|
+
}
|
|
101
103
|
}
|
|
102
|
-
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
# %x{
|
|
106
|
+
# start_comment.innerText = " $" + new_name + " ";
|
|
107
|
+
# end_comment.innerText = " $/" + new_name + " ";
|
|
108
|
+
# }
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
new_bindings[new_name] = @bindings[name]
|
|
111
|
+
end
|
|
110
112
|
end
|
|
111
|
-
end
|
|
112
113
|
|
|
113
|
-
|
|
114
|
+
return new_bindings
|
|
115
|
+
end
|
|
114
116
|
end
|
|
115
|
-
end
|
|
117
|
+
end
|
|
@@ -1,66 +1,68 @@
|
|
|
1
|
-
module
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
NO_XPATH = false
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def find_by_comment(text, in_node=`document`)
|
|
9
|
-
if NO_XPATH
|
|
10
|
-
return find_by_comment_without_xml(text, in_node)
|
|
1
|
+
module Volt
|
|
2
|
+
module CommentSearchers
|
|
3
|
+
if RUBY_PLATFORM == 'opal'
|
|
4
|
+
NO_XPATH = `!!window._phantom || !document.evaluate`
|
|
11
5
|
else
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
%x{
|
|
15
|
-
node = document.evaluate("//comment()[. = ' " + text + " ']", in_node, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null).iterateNext();
|
|
16
|
-
}
|
|
17
|
-
return node
|
|
6
|
+
NO_XPATH = false
|
|
18
7
|
end
|
|
19
|
-
end
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
9
|
+
def find_by_comment(text, in_node=`document`)
|
|
10
|
+
if NO_XPATH
|
|
11
|
+
return find_by_comment_without_xml(text, in_node)
|
|
12
|
+
else
|
|
13
|
+
node = nil
|
|
14
|
+
|
|
15
|
+
%x{
|
|
16
|
+
node = document.evaluate("//comment()[. = ' " + text + " ']", in_node, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null).iterateNext();
|
|
28
17
|
}
|
|
18
|
+
return node
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# PhantomJS does not support xpath in document.evaluate
|
|
23
|
+
def find_by_comment_without_xml(text, in_node)
|
|
24
|
+
match_text = " #{text} "
|
|
25
|
+
%x{
|
|
26
|
+
function walk(node) {
|
|
27
|
+
if (node.nodeType === 8 && node.nodeValue === match_text) {
|
|
28
|
+
return node;
|
|
29
|
+
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
var children = node.childNodes;
|
|
32
|
+
if (children) {
|
|
33
|
+
for (var i=0;i < children.length;i++) {
|
|
34
|
+
var matched = walk(children[i]);
|
|
35
|
+
if (matched) {
|
|
36
|
+
return matched;
|
|
37
|
+
}
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
return walk(in_node);
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
}
|
|
48
|
+
end
|
|
48
49
|
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
# Returns an unattached div with the nodes from the passed
|
|
52
|
+
# in html.
|
|
53
|
+
def build_from_html(html)
|
|
54
|
+
temp_div = nil
|
|
55
|
+
%x{
|
|
56
|
+
temp_div = document.createElement('div');
|
|
57
|
+
var doc = jQuery.parseHTML(html);
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if (doc) {
|
|
60
|
+
for (var i=0;i < doc.length;i++) {
|
|
61
|
+
temp_div.appendChild(doc[i]);
|
|
62
|
+
}
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
temp_div
|
|
66
|
+
end
|
|
65
67
|
end
|
|
66
|
-
end
|
|
68
|
+
end
|
data/lib/volt/page/tasks.rb
CHANGED
|
@@ -1,77 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
module Volt
|
|
2
|
+
# The tasks class provides an interface to call tasks on
|
|
3
|
+
# the backend server.
|
|
4
|
+
class Tasks
|
|
5
|
+
def initialize(page)
|
|
6
|
+
@page = page
|
|
7
|
+
@promise_id = 0
|
|
8
|
+
@promises = {}
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
page.channel.on('message') do |*args|
|
|
11
|
+
received_message(*args)
|
|
12
|
+
end
|
|
11
13
|
end
|
|
12
|
-
end
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
def call(class_name, method_name, *args)
|
|
16
|
+
promise_id = @promise_id
|
|
17
|
+
@promise_id += 1
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Track the callback
|
|
20
|
+
promise = Promise.new
|
|
21
|
+
@promises[promise_id] = promise
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
# TODO: Timeout on these callbacks
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
@page.channel.send_message([promise_id, class_name, method_name, *args])
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
promise
|
|
28
|
+
end
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
def received_message(name, promise_id, *args)
|
|
32
|
+
case name
|
|
33
|
+
when 'added', 'removed', 'updated', 'changed'
|
|
34
|
+
notify_query(name, *args)
|
|
35
|
+
when 'response'
|
|
36
|
+
response(promise_id, *args)
|
|
37
|
+
when 'reload'
|
|
38
|
+
reload
|
|
39
|
+
end
|
|
38
40
|
end
|
|
39
|
-
end
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
# When a request is sent to the backend, it can attach a callback,
|
|
43
|
+
# this is called from the backend to pass to the callback.
|
|
44
|
+
def response(promise_id, result, error)
|
|
45
|
+
promise = @promises.delete(promise_id)
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
if promise
|
|
48
|
+
if error
|
|
49
|
+
# TODO: full error handling
|
|
50
|
+
puts "Task Response: #{error.inspect}"
|
|
51
|
+
promise.reject(error)
|
|
52
|
+
else
|
|
53
|
+
promise.resolve(result)
|
|
54
|
+
end
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
|
-
end
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
# Called when the backend sends a notification to change the results of
|
|
59
|
+
# a query.
|
|
60
|
+
def notify_query(method_name, collection, query, *args)
|
|
61
|
+
query_obj = Persistors::ArrayStore.query_pool.lookup(collection, query)
|
|
62
|
+
query_obj.send(method_name, *args)
|
|
63
|
+
end
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
def reload
|
|
66
|
+
# Stash the current page value
|
|
67
|
+
value = JSON.dump($page.page.to_h)
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
# If this browser supports session storage, store the page, so it will
|
|
70
|
+
# be in the same state when we reload.
|
|
71
|
+
if `sessionStorage`
|
|
72
|
+
`sessionStorage.setItem('___page', value);`
|
|
73
|
+
end
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
$page.page._reloading = true
|
|
76
|
+
`window.location.reload(false);`
|
|
77
|
+
end
|
|
76
78
|
end
|
|
77
79
|
end
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
require 'volt/page/bindings/base_binding'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
super(page, target, context, binding_name)
|
|
3
|
+
module Volt
|
|
4
|
+
class TemplateRenderer < BaseBinding
|
|
5
|
+
attr_reader :context
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
def initialize(page, target, context, binding_name, template_name)
|
|
8
|
+
super(page, target, context, binding_name)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
@sub_bindings = []
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
bindings = self.dom_section.set_content_to_template(page, template_name)
|
|
13
|
+
|
|
14
|
+
bindings.each_pair do |id, bindings_for_id|
|
|
15
|
+
bindings_for_id.each do |binding|
|
|
16
|
+
@sub_bindings << binding.call(page, target, context, id)
|
|
17
|
+
end
|
|
15
18
|
end
|
|
16
19
|
end
|
|
17
|
-
end
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
def remove
|
|
22
|
+
@sub_bindings.each(&:remove)
|
|
23
|
+
@sub_bindings = []
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
super
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
end
|
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# the
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
module Volt
|
|
2
|
+
# The URLTracker is responsible for updating the url when
|
|
3
|
+
# a param changes, or updating the url model/params when
|
|
4
|
+
# the browser url changes.
|
|
5
|
+
class UrlTracker
|
|
6
|
+
def initialize(page)
|
|
7
|
+
@page = page
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
if Volt.client?
|
|
10
|
+
that = self
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
# Setup popstate on the dom ready event. Prevents an extra
|
|
13
|
+
# popstate trigger
|
|
14
|
+
%x{
|
|
15
|
+
var first = true;
|
|
16
|
+
window.addEventListener("popstate", function(e) {
|
|
17
|
+
if (first === false) {
|
|
18
|
+
that.$url_updated();
|
|
19
|
+
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
first = false;
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
return true;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
|
-
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
def url_updated(first_call=false)
|
|
30
|
+
@page.url.parse(`document.location.href`)
|
|
31
|
+
@page.url.update! unless first_call
|
|
32
|
+
end
|
|
31
33
|
end
|
|
32
34
|
end
|