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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Readme.md +8 -2
  4. data/VERSION +1 -1
  5. data/app/volt/controllers/notices_controller.rb +1 -1
  6. data/app/volt/models/user.rb +2 -2
  7. data/app/volt/tasks/live_query/live_query_pool.rb +1 -1
  8. data/app/volt/tasks/query_tasks.rb +1 -1
  9. data/app/volt/tasks/store_tasks.rb +1 -1
  10. data/app/volt/tasks/user_tasks.rb +2 -2
  11. data/lib/volt/boot.rb +2 -2
  12. data/lib/volt/cli/asset_compile.rb +31 -27
  13. data/lib/volt/cli.rb +64 -65
  14. data/lib/volt/config.rb +25 -23
  15. data/lib/volt/console.rb +17 -16
  16. data/lib/volt/controllers/model_controller.rb +82 -80
  17. data/lib/volt/data_stores/data_store.rb +2 -2
  18. data/lib/volt/data_stores/mongo_driver.rb +2 -2
  19. data/lib/volt/extra_core/inflections.rb +2 -2
  20. data/lib/volt/extra_core/inflector/inflections.rb +185 -183
  21. data/lib/volt/extra_core/inflector/methods.rb +50 -48
  22. data/lib/volt/extra_core/string.rb +2 -2
  23. data/lib/volt/models/array_model.rb +93 -92
  24. data/lib/volt/models/cursor.rb +3 -2
  25. data/lib/volt/models/model.rb +248 -251
  26. data/lib/volt/models/model_hash_behaviour.rb +44 -44
  27. data/lib/volt/models/model_helpers.rb +38 -36
  28. data/lib/volt/models/model_state.rb +16 -17
  29. data/lib/volt/models/model_wrapper.rb +25 -24
  30. data/lib/volt/models/persistors/array_store.rb +145 -143
  31. data/lib/volt/models/persistors/base.rb +18 -16
  32. data/lib/volt/models/persistors/flash.rb +24 -22
  33. data/lib/volt/models/persistors/local_store.rb +46 -44
  34. data/lib/volt/models/persistors/model_identity_map.rb +10 -8
  35. data/lib/volt/models/persistors/model_store.rb +76 -76
  36. data/lib/volt/models/persistors/params.rb +19 -17
  37. data/lib/volt/models/persistors/query/query_listener.rb +65 -63
  38. data/lib/volt/models/persistors/query/query_listener_pool.rb +12 -10
  39. data/lib/volt/models/persistors/store.rb +28 -28
  40. data/lib/volt/models/persistors/store_factory.rb +12 -10
  41. data/lib/volt/models/persistors/store_state.rb +33 -31
  42. data/lib/volt/models/url.rb +96 -104
  43. data/lib/volt/models/validations.rb +56 -54
  44. data/lib/volt/models/validators/length_validator.rb +24 -22
  45. data/lib/volt/models/validators/presence_validator.rb +14 -12
  46. data/lib/volt/page/bindings/attribute_binding.rb +106 -106
  47. data/lib/volt/page/bindings/base_binding.rb +23 -21
  48. data/lib/volt/page/bindings/component_binding.rb +3 -1
  49. data/lib/volt/page/bindings/content_binding.rb +34 -34
  50. data/lib/volt/page/bindings/each_binding.rb +113 -113
  51. data/lib/volt/page/bindings/event_binding.rb +38 -34
  52. data/lib/volt/page/bindings/if_binding.rb +56 -54
  53. data/lib/volt/page/bindings/template_binding/grouped_controllers.rb +24 -22
  54. data/lib/volt/page/bindings/template_binding.rb +182 -185
  55. data/lib/volt/page/channel.rb +79 -77
  56. data/lib/volt/page/channel_stub.rb +29 -27
  57. data/lib/volt/page/document.rb +6 -5
  58. data/lib/volt/page/document_events.rb +54 -52
  59. data/lib/volt/page/page.rb +139 -138
  60. data/lib/volt/page/string_template_renderer.rb +36 -36
  61. data/lib/volt/page/sub_context.rb +26 -25
  62. data/lib/volt/page/targets/attribute_section.rb +27 -25
  63. data/lib/volt/page/targets/attribute_target.rb +7 -6
  64. data/lib/volt/page/targets/base_section.rb +27 -26
  65. data/lib/volt/page/targets/binding_document/base_node.rb +3 -1
  66. data/lib/volt/page/targets/binding_document/component_node.rb +85 -82
  67. data/lib/volt/page/targets/binding_document/html_node.rb +11 -9
  68. data/lib/volt/page/targets/dom_section.rb +78 -77
  69. data/lib/volt/page/targets/dom_target.rb +8 -6
  70. data/lib/volt/page/targets/dom_template.rb +90 -88
  71. data/lib/volt/page/targets/helpers/comment_searchers.rb +51 -49
  72. data/lib/volt/page/tasks.rb +59 -57
  73. data/lib/volt/page/template_renderer.rb +17 -14
  74. data/lib/volt/page/url_tracker.rb +26 -24
  75. data/lib/volt/reactive/computation.rb +87 -88
  76. data/lib/volt/reactive/dependency.rb +30 -28
  77. data/lib/volt/reactive/eventable.rb +64 -62
  78. data/lib/volt/reactive/hash_dependency.rb +25 -23
  79. data/lib/volt/reactive/reactive_accessors.rb +34 -32
  80. data/lib/volt/reactive/reactive_array.rb +162 -162
  81. data/lib/volt/reactive/reactive_hash.rb +37 -35
  82. data/lib/volt/router/routes.rb +99 -101
  83. data/lib/volt/server/component_handler.rb +20 -21
  84. data/lib/volt/server/component_templates.rb +72 -70
  85. data/lib/volt/server/html_parser/attribute_scope.rb +109 -99
  86. data/lib/volt/server/html_parser/each_scope.rb +17 -16
  87. data/lib/volt/server/html_parser/if_view_scope.rb +51 -49
  88. data/lib/volt/server/html_parser/sandlebars_parser.rb +184 -177
  89. data/lib/volt/server/html_parser/textarea_scope.rb +24 -22
  90. data/lib/volt/server/html_parser/view_handler.rb +66 -65
  91. data/lib/volt/server/html_parser/view_parser.rb +23 -21
  92. data/lib/volt/server/html_parser/view_scope.rb +142 -141
  93. data/lib/volt/server/rack/asset_files.rb +81 -79
  94. data/lib/volt/server/rack/component_code.rb +17 -15
  95. data/lib/volt/server/rack/component_html_renderer.rb +14 -12
  96. data/lib/volt/server/rack/component_paths.rb +72 -71
  97. data/lib/volt/server/rack/index_files.rb +36 -39
  98. data/lib/volt/server/rack/opal_files.rb +43 -41
  99. data/lib/volt/server/rack/source_map_server.rb +23 -21
  100. data/lib/volt/server/socket_connection_handler.rb +46 -45
  101. data/lib/volt/server/socket_connection_handler_stub.rb +21 -19
  102. data/lib/volt/server.rb +60 -58
  103. data/lib/volt/spec/setup.rb +3 -3
  104. data/lib/volt/tasks/dispatcher.rb +24 -23
  105. data/lib/volt/tasks/task_handler.rb +35 -33
  106. data/lib/volt/utils/ejson.rb +8 -6
  107. data/lib/volt/utils/generic_counting_pool.rb +33 -31
  108. data/lib/volt/utils/generic_pool.rb +73 -70
  109. data/lib/volt/utils/local_storage.rb +42 -38
  110. data/lib/volt/volt/environment.rb +1 -1
  111. data/lib/volt.rb +44 -42
  112. data/spec/apps/kitchen_sink/app/main/assets/css/todos.css +28 -0
  113. data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
  114. data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +2 -2
  115. data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +17 -0
  116. data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -0
  117. data/spec/apps/kitchen_sink/app/main/views/todos/index.html +24 -0
  118. data/spec/apps/kitchen_sink/config.ru +1 -1
  119. data/spec/controllers/reactive_accessors_spec.rb +5 -5
  120. data/spec/extra_core/inflector_spec.rb +2 -2
  121. data/spec/integration/list_spec.rb +68 -0
  122. data/spec/models/model_spec.rb +57 -57
  123. data/spec/models/persistors/params_spec.rb +6 -6
  124. data/spec/models/persistors/store_spec.rb +7 -7
  125. data/spec/models/validations_spec.rb +3 -3
  126. data/spec/page/bindings/content_binding_spec.rb +7 -7
  127. data/spec/page/bindings/template_binding_spec.rb +4 -5
  128. data/spec/page/sub_context_spec.rb +2 -2
  129. data/spec/reactive/computation_spec.rb +10 -10
  130. data/spec/reactive/dependency_spec.rb +2 -2
  131. data/spec/reactive/eventable_spec.rb +4 -4
  132. data/spec/reactive/reactive_array_spec.rb +13 -13
  133. data/spec/router/routes_spec.rb +5 -5
  134. data/spec/server/html_parser/sandlebars_parser_spec.rb +9 -9
  135. data/spec/server/html_parser/view_parser_spec.rb +27 -27
  136. data/spec/server/rack/asset_files_spec.rb +5 -5
  137. data/spec/server/rack/component_paths_spec.rb +2 -2
  138. data/spec/tasks/live_query_spec.rb +2 -2
  139. data/spec/tasks/query_tasks.rb +1 -1
  140. data/spec/tasks/query_tracker_spec.rb +1 -1
  141. data/spec/templates/targets/binding_document/component_node_spec.rb +2 -2
  142. data/spec/utils/generic_counting_pool_spec.rb +2 -2
  143. data/spec/utils/generic_pool_spec.rb +2 -2
  144. data/templates/component/controllers/main_controller.rb +1 -1
  145. data/templates/model/model.rb.tt +2 -2
  146. data/templates/newgem/app/newgem/controllers/main_controller.rb.tt +2 -2
  147. data/templates/project/app/main/controllers/main_controller.rb +1 -1
  148. data/templates/project/config.ru +1 -1
  149. metadata +10 -3
  150. data/app/volt/assets/js/vertxbus.js +0 -216
@@ -2,235 +2,232 @@ require 'volt/page/bindings/base_binding'
2
2
  require 'volt/page/template_renderer'
3
3
  require 'volt/page/bindings/template_binding/grouped_controllers'
4
4
 
5
- class TemplateBinding < BaseBinding
6
- def initialize(page, target, context, binding_name, binding_in_path, getter)
7
- super(page, target, context, binding_name)
8
-
9
- # Binding in path is the path for the template this binding is in
10
- setup_path(binding_in_path)
11
-
12
- @current_template = nil
13
-
14
- # Run the initial render
15
- @computation = -> do
16
- # Don't try to render if this has been removed
17
- if @context
18
- # Render
19
- update(*@context.instance_eval(&getter))
20
- end
21
- end.watch!
22
- end
5
+ module Volt
6
+ class TemplateBinding < BaseBinding
7
+ def initialize(page, target, context, binding_name, binding_in_path, getter)
8
+ super(page, target, context, binding_name)
9
+
10
+ # Binding in path is the path for the template this binding is in
11
+ setup_path(binding_in_path)
12
+
13
+ @current_template = nil
14
+
15
+ # Run the initial render
16
+ @computation = -> do
17
+ # Don't try to render if this has been removed
18
+ if @context
19
+ # Render
20
+ update(*@context.instance_eval(&getter))
21
+ end
22
+ end.watch!
23
+ end
23
24
 
24
- def setup_path(binding_in_path)
25
- path_parts = binding_in_path.split('/')
26
- @collection_name = path_parts[0]
27
- @controller_name = path_parts[1]
28
- @page_name = path_parts[2]
29
- end
25
+ def setup_path(binding_in_path)
26
+ path_parts = binding_in_path.split('/')
27
+ @collection_name = path_parts[0]
28
+ @controller_name = path_parts[1]
29
+ @page_name = path_parts[2]
30
+ end
30
31
 
31
- # Returns true if there is a template at the path
32
- def check_for_template?(path)
33
- @page.templates[path]
34
- end
32
+ # Returns true if there is a template at the path
33
+ def check_for_template?(path)
34
+ @page.templates[path]
35
+ end
35
36
 
36
- # Takes in a lookup path and returns the full path for the matching
37
- # template. Also returns the controller and action name if applicable.
38
- #
39
- # Looking up a path is fairly simple. There are 4 parts needed to find
40
- # the html to be rendered. File paths look like this:
41
- # app/{component}/views/{controller_name}/{view}.html
42
- # Within the html file may be one or more sections.
43
- # 1. component (app/{comp})
44
- # 2. controller
45
- # 3. view
46
- # 4. sections
47
- #
48
- # When searching for a file, the lookup starts at the section, and moves up.
49
- # when moving up, default values are provided for the section, then view/section, etc..
50
- # until a file is either found or the component level is reached.
51
- #
52
- # The defaults are as follows:
53
- # 1. component - main
54
- # 2. controller - main
55
- # 3. view - main
56
- # 4. section - body
57
- def path_for_template(lookup_path, force_section=nil)
58
- parts = lookup_path.split('/')
59
- parts_size = parts.size
60
-
61
- default_parts = ['main', 'main', 'index', 'body']
62
-
63
- # When forcing a sub template, we can default the sub template section
64
- default_parts[-1] = force_section if force_section
65
-
66
- (5 - parts_size).times do |path_position|
67
- # If they passed in a force_section, we can skip the first
68
- next if force_section && path_position == 0
69
-
70
- full_path = [@collection_name, @controller_name, @page_name, nil]
71
-
72
- start_at = full_path.size - parts_size - path_position
73
-
74
- full_path.size.times do |index|
75
- if index >= start_at
76
- if part = parts[index-start_at]
77
- full_path[index] = part
78
- else
79
- full_path[index] = default_parts[index]
37
+ # Takes in a lookup path and returns the full path for the matching
38
+ # template. Also returns the controller and action name if applicable.
39
+ #
40
+ # Looking up a path is fairly simple. There are 4 parts needed to find
41
+ # the html to be rendered. File paths look like this:
42
+ # app/{component}/views/{controller_name}/{view}.html
43
+ # Within the html file may be one or more sections.
44
+ # 1. component (app/{comp})
45
+ # 2. controller
46
+ # 3. view
47
+ # 4. sections
48
+ #
49
+ # When searching for a file, the lookup starts at the section, and moves up.
50
+ # when moving up, default values are provided for the section, then view/section, etc..
51
+ # until a file is either found or the component level is reached.
52
+ #
53
+ # The defaults are as follows:
54
+ # 1. component - main
55
+ # 2. controller - main
56
+ # 3. view - main
57
+ # 4. section - body
58
+ def path_for_template(lookup_path, force_section=nil)
59
+ parts = lookup_path.split('/')
60
+ parts_size = parts.size
61
+
62
+ default_parts = ['main', 'main', 'index', 'body']
63
+
64
+ # When forcing a sub template, we can default the sub template section
65
+ default_parts[-1] = force_section if force_section
66
+
67
+ (5 - parts_size).times do |path_position|
68
+ # If they passed in a force_section, we can skip the first
69
+ next if force_section && path_position == 0
70
+
71
+ full_path = [@collection_name, @controller_name, @page_name, nil]
72
+
73
+ start_at = full_path.size - parts_size - path_position
74
+
75
+ full_path.size.times do |index|
76
+ if index >= start_at
77
+ if (part = parts[index - start_at])
78
+ full_path[index] = part
79
+ else
80
+ full_path[index] = default_parts[index]
81
+ end
80
82
  end
81
83
  end
82
- end
83
84
 
84
- path = full_path.join('/')
85
- if check_for_template?(path)
86
- controller = nil
85
+ path = full_path.join('/')
86
+ if check_for_template?(path)
87
+ controller = nil
87
88
 
88
- # Don't return a controller if we are just getting another section
89
- # from the same controller
90
- if path_position >= 1
91
- # Lookup the controller
92
- controller = [full_path[0], full_path[1] + '_controller', full_path[2]]
89
+ # Don't return a controller if we are just getting another section
90
+ # from the same controller
91
+ if path_position >= 1
92
+ # Lookup the controller
93
+ controller = [full_path[0], full_path[1] + '_controller', full_path[2]]
94
+ end
95
+ return path, controller
93
96
  end
94
- return path, controller
95
97
  end
98
+
99
+ return nil, nil
96
100
  end
97
101
 
98
- return nil, nil
99
- end
102
+ def update(path, section_or_arguments=nil, options={})
103
+ Computation.run_without_tracking do
104
+ # Remove existing template and call _removed
105
+ controller_send(:"#{@action}_removed") if @action && @controller
106
+ @current_template.remove if @current_template
100
107
 
101
- def update(path, section_or_arguments=nil, options={})
102
- Computation.run_without_tracking do
103
- # Remove existing template and call _removed
104
- controller_send(:"#{@action}_removed") if @action && @controller
105
- @current_template.remove if @current_template
108
+ @options = options
106
109
 
107
- @options = options
110
+ # A blank path needs to load a missing template, otherwise it tries to load
111
+ # the same template.
112
+ path = path.blank? ? '---missing---' : path
108
113
 
109
- # A blank path needs to load a missing template, otherwise it tries to load
110
- # the same template.
111
- path = path.blank? ? '---missing---' : path
114
+ section = nil
115
+ @arguments = nil
112
116
 
113
- section = nil
114
- @arguments = nil
117
+ if section_or_arguments.is_a?(String)
118
+ # Render this as a section
119
+ section = section_or_arguments
120
+ else
121
+ # Use the value passed in as the default arguments
122
+ @arguments = section_or_arguments
123
+ end
115
124
 
116
- if section_or_arguments.is_a?(String)
117
- # Render this as a section
118
- section = section_or_arguments
119
- else
120
- # Use the value passed in as the default arguments
121
- @arguments = section_or_arguments
125
+ # Sometimes we want multiple template bindings to share the same controller (usually
126
+ # when displaying a :Title and a :Body), this instance tracks those.
127
+ if @options && (controller_group = @options[:controller_group])
128
+ @grouped_controller = GroupedControllers.new(controller_group)
129
+ else
130
+ clear_grouped_controller
131
+ end
132
+
133
+ full_path, controller_path = path_for_template(path, section)
134
+ render_template(full_path, controller_path)
135
+
136
+ queue_clear_grouped_controller
122
137
  end
138
+ end
123
139
 
124
- # Sometimes we want multiple template bindings to share the same controller (usually
125
- # when displaying a :Title and a :Body), this instance tracks those.
126
- if @options && (controller_group = @options[:controller_group])
127
- @grouped_controller = GroupedControllers.new(controller_group)
140
+ # On the next tick, we clear the grouped controller so that any changes to template paths
141
+ # will create a new controller and trigger the action.
142
+ def queue_clear_grouped_controller
143
+ if Volt.in_browser?
144
+ # In the browser, we want to keep a grouped controller around during a single run
145
+ # of the event loop. To make that happen, we clear it on the next tick.
146
+ `setImmediate(function() {`
147
+ clear_grouped_controller
148
+ `});`
128
149
  else
150
+ # For the backend, clear it immediately
129
151
  clear_grouped_controller
130
152
  end
131
-
132
- full_path, controller_path = path_for_template(path, section)
133
- render_template(full_path, controller_path)
134
-
135
- queue_clear_grouped_controller
136
153
  end
137
- end
138
154
 
139
- # On the next tick, we clear the grouped controller so that any changes to template paths
140
- # will create a new controller and trigger the action.
141
- def queue_clear_grouped_controller
142
- if Volt.in_browser?
143
- # In the browser, we want to keep a grouped controller around during a single run
144
- # of the event loop. To make that happen, we clear it on the next tick.
145
- `setImmediate(function() {`
146
- clear_grouped_controller
147
- `})`
148
- else
149
- # For the backend, clear it immediately
150
- clear_grouped_controller
155
+ def clear_grouped_controller
156
+ if @grouped_controller
157
+ @grouped_controller.clear
158
+ @grouped_controller = nil
159
+ end
151
160
  end
152
- end
153
161
 
154
- def clear_grouped_controller
155
- if @grouped_controller
156
- @grouped_controller.clear
157
- @grouped_controller = nil
158
- end
159
- end
162
+ # The context for templates can be either a controller, or the original context.
163
+ def render_template(full_path, controller_path)
164
+ args = @arguments ? [SubContext.new(@arguments)] : []
160
165
 
161
- # The context for templates can be either a controller, or the original context.
162
- def render_template(full_path, controller_path)
163
- if @arguments
164
- args = [SubContext.new(@arguments)]
165
- else
166
- args = []
167
- end
166
+ @controller = nil
167
+
168
+ # Fetch grouped controllers if we're grouping
169
+ @controller = @grouped_controller.get if @grouped_controller
168
170
 
169
- @controller = nil
171
+ # The action to be called and rendered
172
+ @action = nil
170
173
 
171
- # Fetch grouped controllers if we're grouping
172
- @controller = @grouped_controller.get if @grouped_controller
174
+ if @controller
175
+ # Track that we're using the group controller
176
+ @grouped_controller.inc if @grouped_controller
177
+ else
178
+ # Otherwise, make a new controller
179
+ controller_class, @action = get_controller(controller_path)
173
180
 
174
- # The action to be called and rendered
175
- @action = nil
181
+ if controller_class
182
+ # Setup the controller
183
+ @controller = controller_class.new(*args)
184
+ else
185
+ @controller = ModelController.new(*args)
186
+ end
176
187
 
177
- if @controller
178
- # Track that we're using the group controller
179
- @grouped_controller.inc if @grouped_controller
180
- else
181
- # Otherwise, make a new controller
182
- controller_class, @action = get_controller(controller_path)
188
+ # Trigger the action
189
+ controller_send(@action) if @action
183
190
 
184
- if controller_class
185
- # Setup the controller
186
- @controller = controller_class.new(*args)
187
- else
188
- @controller = ModelController.new(*args)
191
+ # Track the grouped controller
192
+ @grouped_controller.set(@controller) if @grouped_controller
189
193
  end
190
194
 
191
- # Trigger the action
192
- controller_send(@action) if @action
195
+ @current_template = TemplateRenderer.new(@page, @target, @controller, @binding_name, full_path)
193
196
 
194
- # Track the grouped controller
195
- @grouped_controller.set(@controller) if @grouped_controller
197
+ call_ready
196
198
  end
197
199
 
198
- @current_template = TemplateRenderer.new(@page, @target, @controller, @binding_name, full_path)
199
-
200
- call_ready
201
- end
200
+ def call_ready
201
+ if @controller
202
+ # Set the current section on the controller if it wants so it can manipulate
203
+ # the dom if needed
204
+ if @controller.respond_to?(:section=)
205
+ @controller.section = @current_template.dom_section
206
+ end
202
207
 
203
- def call_ready
204
- if @controller
205
- # Set the current section on the controller if it wants so it can manipulate
206
- # the dom if needed
207
- if @controller.respond_to?(:section=)
208
- @controller.section = @current_template.dom_section
208
+ controller_send(:"#{@action}_ready") if @action
209
209
  end
210
-
211
- controller_send(:"#{@action}_ready") if @action
212
210
  end
213
- end
214
211
 
215
- def remove
216
- clear_grouped_controller
212
+ def remove
213
+ clear_grouped_controller
217
214
 
218
- if @current_template
219
- # Remove the template if one has been rendered, when the template binding is
220
- # removed.
221
- @current_template.remove
222
- end
215
+ if @current_template
216
+ # Remove the template if one has been rendered, when the template binding is
217
+ # removed.
218
+ @current_template.remove
219
+ end
223
220
 
224
- super
221
+ super
225
222
 
226
- if @controller
227
- controller_send(:"#{@action}_removed") if @action
223
+ if @controller
224
+ controller_send(:"#{@action}_removed") if @action
228
225
 
229
- @controller = nil
226
+ @controller = nil
227
+ end
230
228
  end
231
- end
232
229
 
233
- private
230
+ private
234
231
  # Sends the action to the controller if it exists
235
232
  def controller_send(action_name)
236
233
  if @controller.respond_to?(action_name)
@@ -245,7 +242,7 @@ class TemplateBinding < BaseBinding
245
242
  action = controller_path[-1]
246
243
 
247
244
  # Get the constant parts
248
- parts = controller_path[0..-2].map {|v| v.gsub('-', '_').camelize }
245
+ parts = controller_path[0..-2].map { |v| v.gsub('-', '_').camelize }
249
246
 
250
247
  # Home doesn't get namespaced
251
248
  if parts.first == 'Main'
@@ -265,5 +262,5 @@ class TemplateBinding < BaseBinding
265
262
 
266
263
  return obj, action
267
264
  end
268
-
265
+ end
269
266
  end
@@ -4,101 +4,103 @@ require 'json'
4
4
  require 'volt/reactive/reactive_accessors'
5
5
  require 'volt/reactive/eventable'
6
6
 
7
- class Channel
8
- include ReactiveAccessors
9
- include Eventable
10
-
11
- reactive_accessor :connected, :status, :error, :reconnect_interval, :retry_count
7
+ module Volt
8
+ class Channel
9
+ include ReactiveAccessors
10
+ include Eventable
11
+
12
+ reactive_accessor :connected, :status, :error, :reconnect_interval, :retry_count
13
+
14
+ def initialize
15
+ @socket = nil
16
+ self.status = :opening
17
+ self.connected = false
18
+ self.error = nil
19
+ self.retry_count = 0
20
+ @queue = []
21
+
22
+ connect!
23
+ end
12
24
 
13
- def initialize
14
- @socket = nil
15
- self.status = :opening
16
- self.connected = false
17
- self.error = nil
18
- self.retry_count = 0
19
- @queue = []
25
+ def connected?
26
+ self.connected
27
+ end
20
28
 
21
- connect!
22
- end
29
+ def connect!
30
+ %x{
31
+ this.socket = new SockJS('/channel');
23
32
 
24
- def connected?
25
- self.connected
26
- end
33
+ this.socket.onopen = function() {
34
+ self.$opened();
35
+ };
27
36
 
28
- def connect!
29
- %x{
30
- this.socket = new SockJS('/channel');
37
+ this.socket.onmessage = function(message) {
38
+ self['$message_received'](message.data);
39
+ };
31
40
 
32
- this.socket.onopen = function() {
33
- self.$opened();
34
- };
41
+ this.socket.onclose = function(error) {
42
+ self.$closed(error);
43
+ };
44
+ }
45
+ end
35
46
 
36
- this.socket.onmessage = function(message) {
37
- self['$message_received'](message.data);
38
- };
47
+ def opened
48
+ old_status = @status
49
+ @status = :open
50
+ @connected = true
51
+ @reconnect_interval = nil
52
+ @retry_count = 0
53
+ @queue.each do |message|
54
+ send_message(message)
55
+ end
56
+ end
39
57
 
40
- this.socket.onclose = function(error) {
41
- self.$closed(error);
42
- };
43
- }
44
- end
58
+ def closed(error)
59
+ self.status = :closed
60
+ self.connected = false
61
+ self.error = `error.reason`
45
62
 
46
- def opened
47
- old_status = @status
48
- @status = :open
49
- @connected = true
50
- @reconnect_interval = nil
51
- @retry_count = 0
52
- @queue.each do |message|
53
- send_message(message)
63
+ reconnect!
54
64
  end
55
- end
56
65
 
57
- def closed(error)
58
- self.status = :closed
59
- self.connected = false
60
- self.error = `error.reason`
66
+ def reconnect!
67
+ self.status = :reconnecting
68
+ self.reconnect_interval ||= 0
69
+ self.reconnect_interval += (2000 + rand(5000))
70
+ self.retry_count += 1
61
71
 
62
- reconnect!
63
- end
64
-
65
- def reconnect!
66
- self.status = :reconnecting
67
- self.reconnect_interval ||= 0
68
- self.reconnect_interval += (2000 + rand(5000))
69
- self.retry_count += 1
72
+ interval = self.reconnect_interval
70
73
 
71
- interval = self.reconnect_interval
74
+ %x{
75
+ setTimeout(function() {
76
+ self['$connect!']();
77
+ }, interval);
78
+ }
79
+ end
72
80
 
73
- %x{
74
- setTimeout(function() {
75
- self['$connect!']();
76
- }, interval);
77
- }
78
- end
81
+ def message_received(message)
82
+ message = JSON.parse(message)
79
83
 
80
- def message_received(message)
81
- message = JSON.parse(message)
84
+ trigger!('message', *message)
85
+ end
82
86
 
83
- trigger!('message', *message)
84
- end
87
+ def send_message(message)
88
+ if self.status != :open
89
+ @queue << message
90
+ else
91
+ # TODO: Temp: wrap message in an array, so we're sure its valid JSON
92
+ message = JSON.dump([message])
93
+ %x{
94
+ this.socket.send(message);
95
+ }
96
+ end
97
+ end
85
98
 
86
- def send_message(message)
87
- if self.status != :open
88
- @queue << message
89
- else
90
- # TODO: Temp: wrap message in an array, so we're sure its valid JSON
91
- message = JSON.dump([message])
99
+ def close!
100
+ self.status = :closed
92
101
  %x{
93
- this.socket.send(message);
102
+ this.socket.close();
94
103
  }
95
104
  end
96
105
  end
97
-
98
- def close!
99
- self.status = :closed
100
- %x{
101
- this.socket.close();
102
- }
103
- end
104
106
  end
@@ -4,32 +4,34 @@
4
4
  require 'volt/tasks/dispatcher'
5
5
  require 'volt/reactive/eventable'
6
6
 
7
- # Behaves the same as the Channel class, only the Channel class uses
8
- # sockjs to pass messages to the backend. ChannelStub, simply passes
9
- # them directly to SocketConnectionHandlerStub.
10
- class ChannelStub
11
- include Eventable
12
-
13
- attr_reader :state, :error, :reconnect_interval
14
-
15
- def initiailze
16
- @state = :connected
17
- end
18
-
19
- def opened
20
- trigger!('open')
21
- trigger!('changed')
22
- end
23
-
24
- def message_received(*message)
25
- trigger!('message', *message)
26
- end
27
-
28
- def send_message(message)
29
- SocketConnectionHandlerStub.new(self).process_message(message)
30
- end
31
-
32
- def close!
33
- raise "close! should not be called on the backend channel"
7
+ module Volt
8
+ # Behaves the same as the Channel class, only the Channel class uses
9
+ # sockjs to pass messages to the backend. ChannelStub, simply passes
10
+ # them directly to SocketConnectionHandlerStub.
11
+ class ChannelStub
12
+ include Eventable
13
+
14
+ attr_reader :state, :error, :reconnect_interval
15
+
16
+ def initiailze
17
+ @state = :connected
18
+ end
19
+
20
+ def opened
21
+ trigger!('open')
22
+ trigger!('changed')
23
+ end
24
+
25
+ def message_received(*message)
26
+ trigger!('message', *message)
27
+ end
28
+
29
+ def send_message(message)
30
+ SocketConnectionHandlerStub.new(self).process_message(message)
31
+ end
32
+
33
+ def close!
34
+ raise "close! should not be called on the backend channel"
35
+ end
34
36
  end
35
37
  end