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,121 +1,120 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
module Volt
|
|
2
|
+
class Computation
|
|
3
|
+
@@current = nil
|
|
4
|
+
@@flush_queue = []
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
def self.current=(val)
|
|
7
|
+
@@current = val
|
|
8
|
+
end
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
def self.current
|
|
11
|
+
@@current
|
|
12
|
+
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
def initialize(computation)
|
|
15
|
+
@computation = computation
|
|
16
|
+
@invalidations = []
|
|
17
|
+
end
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
# Runs the computation
|
|
20
|
+
def compute!
|
|
21
|
+
@invalidated = false
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
unless @stopped
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
@computing = true
|
|
26
|
+
run_in do
|
|
27
|
+
@computation.call
|
|
28
|
+
end
|
|
29
|
+
@computing = false
|
|
28
30
|
end
|
|
29
|
-
@computing = false
|
|
30
31
|
end
|
|
31
|
-
end
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
def on_invalidate(&callback)
|
|
34
|
+
if @invalidated
|
|
35
|
+
# Call invalidate now, since its already invalidated
|
|
36
|
+
Computation.run_without_tracking do
|
|
37
|
+
callback.call
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
# Store the invalidation
|
|
41
|
+
@invalidations << callback
|
|
38
42
|
end
|
|
39
|
-
else
|
|
40
|
-
# Store the invalidation
|
|
41
|
-
@invalidations << callback
|
|
42
43
|
end
|
|
43
|
-
end
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
# Calling invalidate removes the computation from all of
|
|
46
|
+
# its dependencies. This keeps its dependencies from
|
|
47
|
+
# invalidating it again.
|
|
48
|
+
def invalidate!
|
|
49
|
+
unless @invalidated
|
|
50
|
+
@invalidated = true
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
if !@stopped && !@computing
|
|
53
|
+
@@flush_queue << self
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
# If we are in the browser, we queue a flush for the next tick
|
|
56
|
+
if Volt.in_browser?
|
|
57
|
+
self.class.queue_flush!
|
|
58
|
+
end
|
|
58
59
|
end
|
|
59
|
-
end
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
invalidations = @invalidations
|
|
62
|
+
@invalidations = []
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
invalidations.each do |invalidation|
|
|
65
|
+
invalidation.call
|
|
66
|
+
end
|
|
66
67
|
end
|
|
67
68
|
end
|
|
68
|
-
end
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
# Stop re-run of the computations
|
|
71
|
+
def stop
|
|
72
|
+
unless @stopped
|
|
73
|
+
@stopped = true
|
|
74
|
+
invalidate!
|
|
75
|
+
end
|
|
75
76
|
end
|
|
76
|
-
end
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
end
|
|
78
|
+
# Runs in this computation as the current computation, returns the computation
|
|
79
|
+
def run_in
|
|
80
|
+
previous = Computation.current
|
|
81
|
+
Computation.current = self
|
|
82
|
+
yield
|
|
83
|
+
Computation.current = previous
|
|
84
|
+
self
|
|
85
|
+
end
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
def self.run_without_tracking
|
|
88
|
+
previous = Computation.current
|
|
89
|
+
Computation.current = nil
|
|
90
|
+
return_value = yield
|
|
91
|
+
Computation.current = previous
|
|
92
|
+
return_value
|
|
93
|
+
end
|
|
93
94
|
|
|
94
|
-
return return_value
|
|
95
|
-
end
|
|
96
95
|
|
|
96
|
+
def self.flush!
|
|
97
|
+
raise "Can't flush while in a flush" if @flushing
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
@flushing = true
|
|
100
|
+
# clear any timers
|
|
101
|
+
@timer = nil
|
|
100
102
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
@timer = nil
|
|
103
|
+
computations = @@flush_queue
|
|
104
|
+
@@flush_queue = []
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
computations.each do |computation|
|
|
107
|
+
computation.compute!
|
|
108
|
+
end
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
computation.compute!
|
|
110
|
+
@flushing = false
|
|
110
111
|
end
|
|
111
112
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
# Flush once everything else has finished running
|
|
118
|
-
@timer = `setImmediate(function() { self['$flush!'](); });`
|
|
113
|
+
def self.queue_flush!
|
|
114
|
+
if !@timer
|
|
115
|
+
# Flush once everything else has finished running
|
|
116
|
+
@timer = `setImmediate(function() { self['$flush!'](); });`
|
|
117
|
+
end
|
|
119
118
|
end
|
|
120
119
|
end
|
|
121
120
|
end
|
|
@@ -123,7 +122,7 @@ end
|
|
|
123
122
|
|
|
124
123
|
class Proc
|
|
125
124
|
def watch!
|
|
126
|
-
|
|
125
|
+
Volt::Computation.new(self).run_in do
|
|
127
126
|
# run self
|
|
128
127
|
self.call
|
|
129
128
|
end
|
|
@@ -27,45 +27,47 @@ class Set
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
module Volt
|
|
31
|
+
class Dependency
|
|
32
|
+
def initialize
|
|
33
|
+
@dependencies = Set.new
|
|
34
|
+
end
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
def depend
|
|
37
|
+
# If there is no @dependencies, don't depend because it has been removed
|
|
38
|
+
return unless @dependencies
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
current = Computation.current
|
|
41
|
+
if current
|
|
42
|
+
added = @dependencies.add?(current)
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
if added
|
|
45
|
+
# puts "Added #{self.inspect} to #{current.inspect}"
|
|
46
|
+
current.on_invalidate do
|
|
47
|
+
# If @dependencies is nil, this Dependency has been removed
|
|
48
|
+
@dependencies.delete(current) if @dependencies
|
|
49
|
+
end
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
end
|
|
51
|
-
end
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
def changed!
|
|
55
|
+
deps = @dependencies
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
# If no deps, dependency has been removed
|
|
58
|
+
return unless deps
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
@dependencies = Set.new
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
deps.each do |dep|
|
|
63
|
+
dep.invalidate!
|
|
64
|
+
end
|
|
63
65
|
end
|
|
64
|
-
end
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
# Called when a dependency is no longer needed
|
|
68
|
+
def remove
|
|
69
|
+
changed!
|
|
70
|
+
@dependencies = nil
|
|
71
|
+
end
|
|
70
72
|
end
|
|
71
73
|
end
|
|
@@ -1,82 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def call(*args)
|
|
9
|
-
@callback.call(*args) unless @removed
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def remove
|
|
13
|
-
@removed = true
|
|
1
|
+
module Volt
|
|
2
|
+
class Listener
|
|
3
|
+
def initialize(klass, event, callback)
|
|
4
|
+
@klass = klass
|
|
5
|
+
@event = event
|
|
6
|
+
@callback = callback
|
|
7
|
+
end
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
def call(*args)
|
|
10
|
+
@callback.call(*args) unless @removed
|
|
11
|
+
end
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@callback = nil
|
|
20
|
-
end
|
|
13
|
+
def remove
|
|
14
|
+
@removed = true
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
"<Listener:#{object_id} event=#{@event}>"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
16
|
+
@klass.remove_listener(@event, self)
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
listener = Listener.new(self, event, callback)
|
|
31
|
-
@listeners ||= {}
|
|
32
|
-
@listeners[event] ||= []
|
|
33
|
-
@listeners[event] << listener
|
|
34
|
-
|
|
35
|
-
first_for_event = @listeners[event].size == 1
|
|
36
|
-
first = first_for_event && @listeners.size == 1
|
|
37
|
-
|
|
38
|
-
# Let the included class know that an event was registered. (if it cares)
|
|
39
|
-
if self.respond_to?(:event_added)
|
|
40
|
-
# call event added passing the event, the scope, and a boolean if it
|
|
41
|
-
# is the first time this event has been added.
|
|
42
|
-
self.event_added(event, first, first_for_event)
|
|
18
|
+
# Make things easier on the GC
|
|
19
|
+
@klass = nil
|
|
20
|
+
@callback = nil
|
|
43
21
|
end
|
|
44
22
|
|
|
45
|
-
|
|
23
|
+
def inspect
|
|
24
|
+
"<Listener:#{object_id} event=#{@event}>"
|
|
25
|
+
end
|
|
46
26
|
end
|
|
47
27
|
|
|
48
|
-
|
|
49
|
-
event
|
|
28
|
+
module Eventable
|
|
29
|
+
def on(event, &callback)
|
|
30
|
+
event = event.to_sym
|
|
31
|
+
listener = Listener.new(self, event, callback)
|
|
32
|
+
@listeners ||= {}
|
|
33
|
+
@listeners[event] ||= []
|
|
34
|
+
@listeners[event] << listener
|
|
35
|
+
|
|
36
|
+
first_for_event = @listeners[event].size == 1
|
|
37
|
+
first = first_for_event && @listeners.size == 1
|
|
38
|
+
|
|
39
|
+
# Let the included class know that an event was registered. (if it cares)
|
|
40
|
+
if self.respond_to?(:event_added)
|
|
41
|
+
# call event added passing the event, the scope, and a boolean if it
|
|
42
|
+
# is the first time this event has been added.
|
|
43
|
+
self.event_added(event, first, first_for_event)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
return listener
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def trigger!(event, *args)
|
|
50
|
+
event = event.to_sym
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
return unless @listeners && @listeners[event]
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
# TODO: We have to dup here because one trigger might remove another
|
|
55
|
+
@listeners[event].dup.each do |listener|
|
|
56
|
+
# Call the event on each listener
|
|
57
|
+
listener.call(*args)
|
|
58
|
+
end
|
|
57
59
|
end
|
|
58
|
-
end
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
def remove_listener(event, listener)
|
|
62
|
+
event = event.to_sym
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
raise "Unable to delete #{event} from #{self.inspect}" unless @listeners && @listeners[event]
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
@listeners[event].delete(listener)
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
last_for_event = @listeners[event].size == 0
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
if last_for_event
|
|
71
|
+
# No registered listeners now on this event
|
|
72
|
+
@listeners.delete(event)
|
|
73
|
+
end
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
last = last_for_event && @listeners.size == 0
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
# Let the class we're included on know that we removed a listener (if it cares)
|
|
78
|
+
if self.respond_to?(:event_removed)
|
|
79
|
+
# Pass in the event and a boolean indicating if it is the last event
|
|
80
|
+
self.event_removed(event, last, last_for_event)
|
|
81
|
+
end
|
|
80
82
|
end
|
|
81
83
|
end
|
|
82
|
-
end
|
|
84
|
+
end
|
|
@@ -1,35 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
module Volt
|
|
2
|
+
class HashDependency
|
|
3
|
+
def initialize
|
|
4
|
+
@hash_depedencies = {}
|
|
5
|
+
end
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
def depend(key)
|
|
8
|
+
ensure_key(key).depend
|
|
9
|
+
end
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
def changed!(key)
|
|
12
|
+
ensure_key(key).changed!
|
|
13
|
+
end
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
def delete(key)
|
|
16
|
+
dep = @hash_depedencies[key]
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if dep
|
|
19
|
+
dep.changed!
|
|
20
|
+
dep.remove
|
|
21
|
+
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
@hash_depedencies.delete(key)
|
|
24
|
+
end
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
def changed_all!
|
|
27
|
+
@hash_depedencies.each_pair do |key, value|
|
|
28
|
+
value.changed!
|
|
29
|
+
end
|
|
28
30
|
end
|
|
29
|
-
end
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
private
|
|
32
33
|
def ensure_key(key)
|
|
33
34
|
@hash_depedencies[key] ||= Dependency.new
|
|
34
35
|
end
|
|
36
|
+
end
|
|
35
37
|
end
|
|
@@ -1,45 +1,47 @@
|
|
|
1
|
-
module
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
module Volt
|
|
2
|
+
module ReactiveAccessors
|
|
3
|
+
|
|
4
|
+
module ClassMethods
|
|
5
|
+
# Create a method to read a reactive value from an instance value. If it
|
|
6
|
+
# is not setup, create it so it can be updated through the reactive value
|
|
7
|
+
# at a later point.
|
|
8
|
+
def __reactive_dependency_get(var_name)
|
|
9
|
+
value_dep = instance_variable_get(:"@__#{var_name}_dependency")
|
|
10
|
+
value_dep ||= instance_variable_set(:"@__#{var_name}_dependency", Dependency.new)
|
|
11
|
+
end
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
def reactive_reader(*names)
|
|
14
|
+
names.each do |name|
|
|
15
|
+
var_name = :"@#{name}"
|
|
16
|
+
define_method(name.to_sym) do
|
|
17
|
+
value = instance_variable_get(var_name)
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
self.class.__reactive_dependency_get(name).depend
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
value
|
|
22
|
+
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
|
-
end
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
def reactive_writer(*names)
|
|
27
|
+
names.each do |name|
|
|
28
|
+
var_name = :"@#{name}"
|
|
29
|
+
define_method(:"#{name}=") do |new_value|
|
|
30
|
+
instance_variable_set(var_name, new_value)
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
self.class.__reactive_dependency_get(name).changed!
|
|
33
|
+
end
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
|
-
end
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
def reactive_accessor(*names)
|
|
38
|
+
reactive_reader(*names)
|
|
39
|
+
reactive_writer(*names)
|
|
40
|
+
end
|
|
39
41
|
end
|
|
40
|
-
end
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
def self.included(base)
|
|
44
|
+
base.send :extend, ClassMethods
|
|
45
|
+
end
|
|
44
46
|
end
|
|
45
|
-
end
|
|
47
|
+
end
|