volt 0.4.9 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,72 +0,0 @@
1
- require 'volt/models/params_array'
2
-
3
- # All url related data is stored in params. This includes the main uri
4
- # in addition to any query parameters. The router is responsible for
5
- # converting any uri sections into params. Sections in the uri will
6
- # override any specified parameters.
7
- #
8
- # The params value can be updated the same way a model would be, only
9
- # the updates will trigger an updated url via the browser history api.
10
- # TODO: Support # for browsers without the history api.
11
- class Params < Model
12
- def initialize(*args)
13
- super(*args)
14
- end
15
-
16
- def deep_clone
17
- new_obj = clone
18
-
19
- new_obj.attributes = new_obj.attributes.dup
20
-
21
- new_obj
22
- end
23
-
24
- tag_method(:delete) do
25
- destructive!
26
- end
27
- def delete(*args)
28
- super
29
-
30
- value_updated
31
- end
32
-
33
- def method_missing(method_name, *args, &block)
34
- result = super
35
-
36
- if method_name[0] == '_' && method_name[-1] == '='
37
- # Trigger value updated after an assignment
38
- self.value_updated
39
- end
40
-
41
- return result
42
- end
43
-
44
- def value_updated
45
- # Once the initial url has been parsed and set into the attributes,
46
- # start triggering updates on change events.
47
- # TODO: This is a temp solution, we need to make it so value_updated
48
- # is called after the reactive_value has been updated.
49
- if RUBY_PLATFORM == 'opal'
50
- %x{
51
- if (window.setTimeout && this.$run_update.bind) {
52
- if (window.paramsUpdateTimer) {
53
- clearTimeout(window.paramsUpdateTimer);
54
- }
55
- window.paramsUpdateTimer = setTimeout(this.$run_update.bind(this), 0);
56
- }
57
- }
58
- end
59
- end
60
-
61
- def run_update
62
- $page.params.trigger!('child_changed') if Volt.client?
63
- end
64
-
65
- def new_model(*args)
66
- Params.new(*args)
67
- end
68
-
69
- def new_array_model(*args)
70
- ParamsArray.new(*args)
71
- end
72
- end
@@ -1,9 +0,0 @@
1
- class ParamsArray < ArrayModel
2
- def new_model(*args)
3
- Params.new(*args)
4
- end
5
-
6
- def new_array_model(*args)
7
- ParamsArray.new(*args)
8
- end
9
- end
@@ -1,183 +0,0 @@
1
- require 'volt/models/store_array'
2
-
3
- class Store < Model
4
- ID_CHARS = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map {|v| v.to_a }.flatten
5
-
6
- @@identity_map = {}
7
-
8
- attr_reader :state
9
-
10
- def initialize(tasks=nil, *args)
11
- @tasks = tasks
12
- @state = :not_loaded
13
-
14
- super(*args)
15
-
16
- track_in_identity_map if attributes && attributes[:_id]
17
-
18
- value_updated
19
- end
20
-
21
- def self.from_id(id)
22
- @@identity_map[id]
23
- end
24
-
25
- def event_added(event, scope_provider, first)
26
- if first && event == :changed
27
- # Start listening
28
- ensure_id
29
- change_channel_connection("add")
30
- end
31
- end
32
-
33
- def event_removed(event, no_more_events)
34
- if no_more_events && event == :changed
35
- # Stop listening
36
- change_channel_connection("remove")
37
- end
38
- end
39
-
40
- def change_channel_connection(add_or_remove)
41
- if attributes && path.size > 1
42
- channel_name = "#{path[-2]}##{attributes[:_id]}"
43
- puts "Event Added: #{channel_name} -- #{attributes.inspect}"
44
- @tasks.call('ChannelTasks', "#{add_or_remove}_listener", channel_name)
45
- end
46
- end
47
-
48
- def self.update(model_id, data)
49
- model = @@identity_map[model_id]
50
-
51
- if model
52
- data.each_pair do |key, value|
53
- if key != '_id'
54
- model.send(:"#{key}=", value)
55
- end
56
- end
57
- end
58
- end
59
-
60
- def generate_id
61
- id = []
62
- 12.times { id << ID_CHARS.sample }
63
-
64
- return id.join
65
- end
66
-
67
- def method_missing(method_name, *args, &block)
68
- if method_name[-1] == ']'
69
- # Load the model
70
- self.load!
71
- end
72
-
73
- result = super
74
-
75
- if method_name[0] == '_' && method_name[-1] == '='
76
- # Trigger value updated after an assignment
77
- self.value_updated
78
- end
79
-
80
- return result
81
- end
82
-
83
- def track_in_identity_map
84
- @@identity_map[attributes[:_id]] = self
85
- end
86
-
87
- # When called, will setup an id if there is not one
88
- def ensure_id
89
- # No id yet, lets create one
90
- if attributes && !attributes[:_id]
91
- self.attributes[:_id] = generate_id
92
- track_in_identity_map
93
- end
94
- end
95
-
96
- def value_updated
97
- path_size = path.size
98
- if !(defined?($loading_models) && $loading_models) && @tasks && path_size > 0 && !nil?
99
-
100
- ensure_id
101
-
102
- if path_size > 3 && parent && source = parent.parent
103
- self.attributes[:"#{path[-4].singularize}_id"] = source._id
104
- end
105
-
106
- # puts "Save: #{collection} - #{attrs.inspect}"
107
- @tasks.call('StoreTasks', 'save', collection, self_attributes)
108
- end
109
- end
110
-
111
- # Return the attributes that are only for this store, not any sub-associations.
112
- def self_attributes
113
- # Don't store any sub-stores, those will do their own saving.
114
- attrs = attributes.reject {|k,v| v.is_a?(Model) || v.is_a?(ArrayModel) }
115
- end
116
-
117
- def collection(path=nil)
118
- path ||= self.path
119
-
120
- collection_name = path.last
121
- collection_name = path[-2] if collection_name == :[]
122
-
123
- return collection_name
124
- end
125
-
126
- # On stores, we store the model so we don't have to look it up
127
- # every time we do a read.
128
- def read_new_model(method_name)
129
- # On stores, plural associations are automatically assumed to be
130
- # collections.
131
- if method_name.plural?
132
- model = new_array_model([], self, path + [method_name])
133
- else
134
- model = new_model(nil, self, path + [method_name])
135
- end
136
-
137
- self.attributes ||= {}
138
- attributes[method_name] = model
139
-
140
- if model.is_a?(StoreArray)# && model.state == :not_loaded
141
- model.load!
142
- end
143
-
144
- return model
145
- end
146
-
147
-
148
- # When called, this model is deleted from its current parent collection
149
- # and from the database
150
- def delete!
151
- if path.size == 0
152
- raise "Not in a collection"
153
- end
154
-
155
- # TEMP: Find this model in the parent's collection
156
- parent.each_with_index do |child,index|
157
- puts "CHECK #{child.inspect} vs #{self.inspect}"
158
- if child._id == self._id
159
- puts "FOUND AT: #{index}"
160
- parent.delete_at(index)
161
- break
162
- end
163
- end
164
-
165
- # Send to the DB that we got deleted
166
- unless $loading_models
167
- puts "delete #{collection} - #{attributes[:_id]}"
168
- @tasks.call('StoreTasks', 'delete', collection, attributes[:_id])
169
- end
170
- end
171
-
172
- def inspect
173
- "<#{self.class.to_s}-#{@state} #{attributes.inspect}>"
174
- end
175
-
176
- def new_model(attributes={}, parent=nil, path=nil, class_paths=nil)
177
- return Store.new(@tasks, attributes, parent, path, class_paths)
178
- end
179
-
180
- def new_array_model(*args)
181
- StoreArray.new(@tasks, *args)
182
- end
183
- end
@@ -1,82 +0,0 @@
1
- class StoreArray < ArrayModel
2
- attr_reader :state
3
-
4
- def initialize(tasks=nil, array=[], parent=nil, path=nil)
5
- @tasks = tasks
6
- @state = :not_loaded
7
-
8
- super(array, parent, path)
9
-
10
- # TEMP: TODO: Setup the listeners right away
11
- change_channel_connection('add', 'added')
12
- change_channel_connection('add', 'removed')
13
- end
14
-
15
- # def event_added(event, scope_provider, first)
16
- # puts "New event1: #{event.inspect} - #{first}"
17
- # if first && [:added, :removed].include?(event)
18
- # # Start listening for added items on the collection
19
- #
20
- # change_channel_connection('add', event)
21
- # end
22
- # end
23
- #
24
- # def event_removed(event, no_more_events)
25
- # if no_more_events && [:added, :removed].include?(event)
26
- # # Stop listening
27
- # change_channel_connection("remove", event)
28
- # end
29
- # end
30
-
31
-
32
- def load!
33
- if @state == :not_loaded
34
- @state = :loading
35
-
36
- if @tasks && path.last.plural?
37
- # Check to see the parents scope so we can only lookup associated
38
- # models.
39
- scope = {}
40
-
41
- # Scope to the parent
42
- if path.size > 1 && attributes && attributes[:_id].true?
43
- scope[:"#{path[-2].singularize}_id"] = _id
44
- end
45
-
46
- puts "Load At Scope: #{scope.inspect}"
47
-
48
- load_child_models(scope)
49
- end
50
- end
51
-
52
- return self
53
- end
54
-
55
- def load_child_models(scope)
56
- # puts "FIND: #{collection(path).inspect} at #{scope.inspect}"
57
- @tasks.call('StoreTasks', 'find', path.last, scope) do |results|
58
- # TODO: Globals evil, replace
59
- $loading_models = true
60
- results.each do |result|
61
- self << Store.new(@tasks, result, self, path + [:[]], @class_paths)
62
- end
63
- $loading_models = false
64
- end
65
- end
66
-
67
- def change_channel_connection(add_or_remove, event)
68
- if @tasks && parent.attributes && path.size != 0
69
- channel_name = "#{path[-1]}-#{event}"
70
- puts "Listen on #{channel_name} - #{add_or_remove}"
71
- @tasks.call('ChannelTasks', "#{add_or_remove}_listener", channel_name)
72
- end
73
- end
74
-
75
- def new_model(*args)
76
- Store.new(@tasks, *args)
77
- end
78
-
79
- def new_array_model(*args)
80
- StoreArray.new(@tasks, *args)
81
- end
82
- end
@@ -1,16 +0,0 @@
1
- require 'volt/models'
2
-
3
- describe Params do
4
- it "should stay as params classes when used" do
5
- a = Params.new
6
- expect(a._test.class).to eq(Params)
7
-
8
- expect(a._test._cool.class).to eq(Params)
9
-
10
- a._items << {_name: 'Test'}
11
-
12
- expect(a._items.class).to eq(ParamsArray)
13
- expect(a._items[0].class).to eq(Params)
14
- expect(a._items[0]._name.class).to eq(String)
15
- end
16
- end