volt 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.md +47 -40
  3. data/VERSION +1 -1
  4. data/app/volt/controllers/notices_controller.rb +3 -3
  5. data/app/volt/tasks/live_query/data_store.rb +2 -2
  6. data/app/volt/tasks/live_query/live_query.rb +20 -20
  7. data/app/volt/tasks/live_query/live_query_pool.rb +6 -6
  8. data/app/volt/tasks/live_query/query_tracker.rb +15 -15
  9. data/app/volt/tasks/query_tasks.rb +13 -13
  10. data/app/volt/tasks/store_tasks.rb +7 -7
  11. data/app/volt/views/notices/index.html +17 -18
  12. data/lib/volt/assets/test.rb +2 -2
  13. data/lib/volt/benchmark/benchmark.rb +25 -23
  14. data/lib/volt/cli/asset_compile.rb +11 -0
  15. data/lib/volt/cli/new_gem.rb +16 -16
  16. data/lib/volt/cli.rb +14 -12
  17. data/lib/volt/console.rb +5 -6
  18. data/lib/volt/controllers/model_controller.rb +18 -18
  19. data/lib/volt/extra_core/array.rb +4 -4
  20. data/lib/volt/extra_core/hash.rb +3 -3
  21. data/lib/volt/extra_core/object.rb +6 -6
  22. data/lib/volt/extra_core/string.rb +6 -6
  23. data/lib/volt/extra_core/symbol.rb +5 -5
  24. data/lib/volt/extra_core/time.rb +4 -4
  25. data/lib/volt/extra_core/true_false.rb +6 -6
  26. data/lib/volt/extra_core/try.rb +9 -9
  27. data/lib/volt/models/array_model.rb +26 -26
  28. data/lib/volt/models/model.rb +35 -35
  29. data/lib/volt/models/model_hash_behaviour.rb +15 -15
  30. data/lib/volt/models/model_helpers.rb +8 -8
  31. data/lib/volt/models/model_wrapper.rb +6 -6
  32. data/lib/volt/models/persistors/array_store.rb +36 -36
  33. data/lib/volt/models/persistors/base.rb +6 -6
  34. data/lib/volt/models/persistors/flash.rb +5 -5
  35. data/lib/volt/models/persistors/model_identity_map.rb +2 -2
  36. data/lib/volt/models/persistors/model_store.rb +22 -22
  37. data/lib/volt/models/persistors/params.rb +3 -3
  38. data/lib/volt/models/persistors/query/query_listener.rb +14 -14
  39. data/lib/volt/models/persistors/query/query_listener_pool.rb +2 -2
  40. data/lib/volt/models/persistors/store.rb +8 -8
  41. data/lib/volt/models/persistors/store_factory.rb +2 -2
  42. data/lib/volt/models/url.rb +37 -37
  43. data/lib/volt/page/bindings/attribute_binding.rb +14 -14
  44. data/lib/volt/page/bindings/base_binding.rb +9 -9
  45. data/lib/volt/page/bindings/component_binding.rb +7 -7
  46. data/lib/volt/page/bindings/content_binding.rb +3 -3
  47. data/lib/volt/page/bindings/each_binding.rb +13 -13
  48. data/lib/volt/page/bindings/event_binding.rb +4 -4
  49. data/lib/volt/page/bindings/if_binding.rb +12 -12
  50. data/lib/volt/page/bindings/template_binding.rb +30 -30
  51. data/lib/volt/page/channel.rb +19 -19
  52. data/lib/volt/page/channel_stub.rb +6 -6
  53. data/lib/volt/page/document.rb +2 -2
  54. data/lib/volt/page/document_events.rb +4 -4
  55. data/lib/volt/page/draw_cycle.rb +3 -3
  56. data/lib/volt/page/memory_test.rb +6 -6
  57. data/lib/volt/page/page.rb +19 -19
  58. data/lib/volt/page/reactive_template.rb +9 -9
  59. data/lib/volt/page/sub_context.rb +5 -5
  60. data/lib/volt/page/targets/attribute_section.rb +9 -9
  61. data/lib/volt/page/targets/attribute_target.rb +3 -3
  62. data/lib/volt/page/targets/base_section.rb +2 -2
  63. data/lib/volt/page/targets/binding_document/component_node.rb +23 -23
  64. data/lib/volt/page/targets/binding_document/html_node.rb +2 -2
  65. data/lib/volt/page/targets/dom_section.rb +40 -38
  66. data/lib/volt/page/targets/dom_target.rb +2 -2
  67. data/lib/volt/page/tasks.rb +12 -12
  68. data/lib/volt/page/template_renderer.rb +4 -4
  69. data/lib/volt/page/url_tracker.rb +6 -6
  70. data/lib/volt/reactive/array_extensions.rb +2 -2
  71. data/lib/volt/reactive/destructive_methods.rb +5 -5
  72. data/lib/volt/reactive/event_chain.rb +25 -25
  73. data/lib/volt/reactive/events.rb +33 -33
  74. data/lib/volt/reactive/object_tracker.rb +21 -21
  75. data/lib/volt/reactive/object_tracking.rb +2 -2
  76. data/lib/volt/reactive/reactive_array.rb +57 -57
  77. data/lib/volt/reactive/reactive_tags.rb +16 -16
  78. data/lib/volt/reactive/reactive_value.rb +72 -72
  79. data/lib/volt/reactive/string_extensions.rb +3 -3
  80. data/lib/volt/router/routes.rb +22 -23
  81. data/lib/volt/server/component_handler.rb +5 -5
  82. data/lib/volt/server/component_templates.rb +14 -11
  83. data/lib/volt/server/html_parser/attribute_scope.rb +116 -0
  84. data/lib/volt/server/html_parser/each_scope.rb +18 -0
  85. data/lib/volt/server/html_parser/if_view_scope.rb +71 -0
  86. data/lib/volt/server/html_parser/sandlebars_parser.rb +219 -0
  87. data/lib/volt/server/html_parser/textarea_scope.rb +31 -0
  88. data/lib/volt/server/html_parser/view_handler.rb +82 -0
  89. data/lib/volt/server/html_parser/view_parser.rb +23 -0
  90. data/lib/volt/server/html_parser/view_scope.rb +145 -0
  91. data/lib/volt/server/rack/asset_files.rb +17 -17
  92. data/lib/volt/server/rack/component_paths.rb +18 -18
  93. data/lib/volt/server/rack/index_files.rb +8 -8
  94. data/lib/volt/server/rack/opal_files.rb +11 -11
  95. data/lib/volt/server/socket_connection_handler.rb +13 -13
  96. data/lib/volt/server/socket_connection_handler_stub.rb +2 -2
  97. data/lib/volt/server.rb +18 -18
  98. data/lib/volt/tasks/dispatcher.rb +5 -5
  99. data/lib/volt/utils/ejson.rb +2 -2
  100. data/lib/volt/utils/generic_counting_pool.rb +8 -8
  101. data/lib/volt/utils/generic_pool.rb +16 -16
  102. data/lib/volt/volt/environment.rb +4 -4
  103. data/lib/volt.rb +6 -6
  104. data/spec/integration/test_integration_spec.rb +2 -2
  105. data/spec/models/event_chain_spec.rb +38 -38
  106. data/spec/models/model_spec.rb +128 -128
  107. data/spec/models/old_model_spec.rb +17 -17
  108. data/spec/models/persistors/params_spec.rb +3 -3
  109. data/spec/models/persistors/store_spec.rb +7 -7
  110. data/spec/models/reactive_array_spec.rb +82 -82
  111. data/spec/models/reactive_generator_spec.rb +11 -11
  112. data/spec/models/reactive_tags_spec.rb +6 -6
  113. data/spec/models/reactive_value_spec.rb +70 -70
  114. data/spec/models/store_spec.rb +4 -4
  115. data/spec/models/string_extensions_spec.rb +13 -13
  116. data/spec/page/bindings/content_binding_spec.rb +6 -6
  117. data/spec/page/sub_context_spec.rb +1 -1
  118. data/spec/router/routes_spec.rb +3 -3
  119. data/spec/server/html_parser/sample_page.html +595 -0
  120. data/spec/server/html_parser/sandlebars_parser_spec.rb +192 -0
  121. data/spec/server/html_parser/view_parser_spec.rb +286 -0
  122. data/spec/server/rack/asset_files_spec.rb +6 -6
  123. data/spec/server/rack/component_paths_spec.rb +5 -5
  124. data/spec/spec_helper.rb +4 -5
  125. data/spec/store/mongo_spec.rb +3 -3
  126. data/spec/tasks/live_query_spec.rb +6 -6
  127. data/spec/tasks/query_tasks.rb +4 -4
  128. data/spec/tasks/query_tracker_spec.rb +20 -20
  129. data/spec/templates/targets/binding_document/component_node_spec.rb +4 -4
  130. data/spec/templates/template_binding_spec.rb +28 -28
  131. data/spec/utils/generic_counting_pool_spec.rb +5 -5
  132. data/spec/utils/generic_pool_spec.rb +14 -14
  133. data/templates/newgem/app/newgem/views/index/index.html +1 -2
  134. data/templates/project/app/home/config/dependencies.rb +1 -1
  135. data/templates/project/app/home/controllers/index_controller.rb +1 -1
  136. data/templates/project/app/home/views/index/about.html +4 -6
  137. data/templates/project/app/home/views/index/home.html +4 -5
  138. data/templates/project/app/home/views/index/index.html +8 -9
  139. data/templates/project/spec/spec_helper.rb +1 -1
  140. metadata +17 -8
  141. data/lib/volt/server/binding_setup.rb +0 -2
  142. data/lib/volt/server/if_binding_setup.rb +0 -31
  143. data/lib/volt/server/scope.rb +0 -43
  144. data/lib/volt/server/template_parser.rb +0 -453
  145. 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
@@ -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
@@ -3,5 +3,5 @@
3
3
  # events
4
4
 
5
5
  class Document
6
-
7
- end
6
+
7
+ end
@@ -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
@@ -2,8 +2,8 @@ class DrawCycle
2
2
  def initialize
3
3
  @queue = {}
4
4
  end
5
-
5
+
6
6
  def queue(binding)
7
-
7
+
8
8
  end
9
- end
9
+ end