Skip to content

Commit a5ecb43

Browse files
committed
generalize to reactive block
1 parent bf185a7 commit a5ecb43

File tree

6 files changed

+82
-62
lines changed

6 files changed

+82
-62
lines changed

lib/volt/page/bindings/event_binding.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ def key_code
1111
`this.js_event.keyCode`
1212
end
1313

14-
def stop
15-
# `this.js_event.stopPropagation();`
14+
def stop!
15+
`this.js_event.stopPropagation();`
16+
end
17+
18+
def prevent_default!
1619
`this.js_event.preventDefault();`
1720
end
1821

@@ -30,7 +33,7 @@ def initialize(page, target, context, binding_name, event_name, call_proc)
3033

3134
handler = Proc.new do |js_event|
3235
event = JSEvent.new(js_event)
33-
event.stop if event_name == 'submit'
36+
event.prevent_default! if event_name == 'submit'
3437

3538
# Call the proc the user setup for the event in context,
3639
# pass in the wrapper for the JS event

lib/volt/reactive/reactive_array.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
require 'volt/reactive/object_tracking'
2-
require 'volt/reactive/reactive_count'
2+
require 'volt/reactive/reactive_block'
33

44
class ReactiveArray# < Array
55
include ReactiveTags
@@ -244,7 +244,7 @@ def inspect
244244
# end
245245
def count(&block)
246246
if block
247-
return ReactiveCount.new(self, block)
247+
return ReactiveBlock.new(self, block)
248248
else
249249
@array.count
250250
end

lib/volt/reactive/reactive_count.rb renamed to lib/volt/reactive/reactive_block.rb

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
class ReactiveCount
1+
class ReactiveBlock
22
include ReactiveTags
33

44
def reactive?
@@ -14,27 +14,10 @@ def cur
1414
direct_count
1515
end
1616

17-
# After events are bound, we keep a cache of each cell's count
18-
# value, and base the results
19-
def cached_count
20-
@cached_results = []
21-
22-
23-
end
24-
2517
# Before events are bound, when .cur is called, we simply
2618
# run the count on the source object.
2719
def direct_count
28-
count = 0
29-
@source.cur.size.times do |index|
30-
val = @source[index]
31-
result = @block.call(val).cur
32-
if result == true
33-
count += 1
34-
end
35-
end
36-
37-
count
20+
@source.cur.array.count(&@block)
3821
end
3922

4023
def setup_listeners

lib/volt/server/html_parser/sandlebars_parser.rb

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class SandlebarsParser
1313
def self.truth_hash(array)
1414
hash = {}
1515
array.each {|v| hash[v] = true }
16-
16+
1717
return hash
1818
end
1919

@@ -23,64 +23,64 @@ def self.truth_hash(array)
2323
ATTRIBUTES = /([-\:A-Za-z0-9_]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/
2424

2525
# Types of elements
26-
BLOCK = truth_hash(%w{address applet blockquote button center dd del dir div dl dt fieldset form frameset hr iframe ins isindex li map menu noframes noscript object ol p pre script table tbody td tfoot th thead tr ul})
26+
BLOCK = truth_hash(%w{a address applet blockquote button center dd del dir div dl dt fieldset form frameset hr iframe ins isindex li map menu noframes noscript object ol p pre script table tbody td tfoot th thead tr ul})
2727
EMPTY = truth_hash(%w{area base basefont br col frame hr img input isindex link meta param embed})
28-
INLINE = truth_hash(%w{a abbr acronym applet b basefont bdo big br button cite code del dfn em font i iframe img input ins kbd label map object q s samp script select small span strike strong sub sup textarea tt u var})
28+
INLINE = truth_hash(%w{abbr acronym applet b basefont bdo big br button cite code del dfn em font i iframe img input ins kbd label map object q s samp script select small span strike strong sub sup textarea tt u var})
2929
CLOSE_SELF = truth_hash(%w{colgroup dd dt li options p td tfoot th thead tr})
3030
SPECIAL = truth_hash(%w{script style})
31-
31+
3232
FILL_IN_ATTRIBUTES = truth_hash(%w{checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected})
33-
33+
3434
def initialize(html, handler, file_path=nil)
3535
@html = StringScanner.new(html)
3636
@handler = handler
3737
@file_path = file_path
38-
38+
3939
@stack = []
40-
40+
4141
parse
4242
end
43-
43+
4444
def last
4545
@stack.last
4646
end
47-
47+
4848
def parse
4949
loop do
5050
if last && SPECIAL[last]
5151
# In a script or style tag, just look for the first end
5252
close_tag = "</#{last}>"
5353
body = @html.scan_until(/#{close_tag}/)
5454
body = body[0..((-1 * close_tag.size)-1)]
55-
55+
5656
body = body.gsub(/\<\!--(.*?)--\>/, "\\1").gsub(/\<\!\[CDATA\[(.*?)\]\]\>/, "\\1")
57-
57+
5858
text(body)
59-
59+
6060
end_tag(last, last)
6161
elsif @html.scan(/\<\!--/)
6262
# start comment
6363
comment = @html.scan_until(/--\>/)
6464
comment = comment[0..-4]
65-
65+
6666
@handler.comment(comment) if @handler.respond_to?(:comment)
6767
elsif (tag = @html.scan(START_TAG))
6868
tag_name = @html[1]
6969
rest = @html[2]
7070
unary = @html[3]
71-
71+
7272
start_tag(tag, tag_name, rest, unary)
7373
elsif @html.scan(END_TAG)
7474
tag_name = @html[1]
75-
75+
7676
end_tag(tag_name, tag_name)
7777
elsif (escaped = @html.scan(/\{\{\{(.*?)\}\}\}([^\}]|$)/))
7878
# Anything between {{{ and }}} is escaped and not processed (treaded as text)
7979
if escaped[-1] != '}'
8080
# Move back if we matched a new non } for close, skip if we hit the end
8181
@html.pos = @html.pos - 1
8282
end
83-
83+
8484
text(@html[1])
8585
elsif (binding = @html.scan(/\{/))
8686
# We are in text mode and matched the start of a binding
@@ -93,14 +93,14 @@ def parse
9393
break
9494
end
9595
end
96-
96+
9797
end_tag(nil, nil)
9898
end
99-
99+
100100
def text(text)
101101
@handler.text(text) if @handler.respond_to?(:text)
102102
end
103-
103+
104104
# Findings the end of a binding
105105
def start_binding
106106
binding = ''
@@ -109,7 +109,7 @@ def start_binding
109109
# scan until we reach a { or }
110110
loop do
111111
binding << @html.scan_until(/([\{\}\n]|\Z)/)
112-
112+
113113
match = @html[1]
114114
if match == '}'
115115
# close
@@ -126,23 +126,23 @@ def start_binding
126126
raise "should not reach here"
127127
end
128128
end
129-
129+
130130
binding = binding[0..-2]
131-
@handler.binding(binding) if @handler.respond_to?(:binding)
131+
@handler.binding(binding) if @handler.respond_to?(:binding)
132132
end
133-
133+
134134
def raise_parse_error(error)
135135
line_number = @html.pre_match.count("\n") + 1
136-
136+
137137
error_str = error + " on line: #{line_number}"
138138
error_str += " of #{@file_path}" if @file_path
139139

140140
raise HTMLParseError, error_str
141141
end
142-
142+
143143
def start_tag(tag, tag_name, rest, unary)
144144
section_tag = tag_name[0] == ':' && tag_name[1] =~ /[A-Z]/
145-
145+
146146
tag_name = tag_name.downcase
147147

148148
# handle doctype so we get it output exactly the same way
@@ -157,45 +157,45 @@ def start_tag(tag, tag_name, rest, unary)
157157
end_tag(nil, last)
158158
end
159159
end
160-
160+
161161
# Some tags close themselves when a new one of themselves is reached.
162162
# ex, a tr will close the previous tr
163163
if CLOSE_SELF[tag_name] && last == tag_name
164164
end_tag(nil, tag_name)
165165
end
166-
166+
167167
unary = EMPTY[tag_name] || !unary.blank?
168-
168+
169169
# Section tag's are also unary
170170
unless unary || section_tag
171171
@stack.push(tag_name)
172172
end
173-
173+
174174
if @handler.respond_to?(:start_tag)
175175
attributes = {}
176-
176+
177177
# Take the rest string and extract the attributes, filling in any
178178
# "fill in" attribute values if not provided.
179179
rest.scan(ATTRIBUTES).each do |match|
180180
name = match[0]
181-
181+
182182
value = match[1] || match[2] || match[3] || FILL_IN_ATTRIBUTES[name] || ''
183-
183+
184184
attributes[name] = value
185185
end
186-
186+
187187
if section_tag
188188
@handler.start_section(tag_name, attributes, unary)
189189
else
190190
@handler.start_tag(tag_name, attributes, unary)
191191
end
192192
end
193193
end
194-
194+
195195
def end_tag(tag, tag_name)
196196
# If no tag name is provided, close all the way up
197197
new_size = 0
198-
198+
199199
if tag
200200
# Find the closest tag that closes.
201201
(@stack.size-1).downto(0) do |index|
@@ -205,7 +205,7 @@ def end_tag(tag, tag_name)
205205
end
206206
end
207207
end
208-
208+
209209
if new_size >= 0
210210
if @handler.respond_to?(:end_tag)
211211
(@stack.size-1).downto(new_size) do |index|

spec/models/reactive_array_spec.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,4 +327,38 @@
327327
expect(count).to eq(0)
328328
end
329329
end
330+
331+
# describe "concat, diff" do
332+
# it "should concat two arrays and trigger added/removed through" do
333+
# a = ReactiveValue.new(ReactiveArray.new([1,2,3]))
334+
# b = ReactiveValue.new(ReactiveArray.new([1,2,3]))
335+
#
336+
# c = a + b
337+
#
338+
# count = 0
339+
# # c.on('added') { count += 1 }
340+
# c.on('changed') { count += 1 }
341+
# expect(count).to eq(0)
342+
#
343+
# b << 4
344+
#
345+
# expect(count).to eq(1)
346+
# end
347+
# end
348+
349+
describe "array methods" do
350+
it "should handle compact with events" do
351+
a = ReactiveValue.new(ReactiveArray.new([1,2,nil,3]))
352+
353+
count = 0
354+
last_position = nil
355+
compact = a.compact
356+
compact.on('changed') { count += 1 }
357+
expect(count).to eq(0)
358+
359+
a << 4
360+
361+
expect(count).to eq(1)
362+
end
363+
end
330364
end

spec/models/reactive_count_spec.rb renamed to spec/models/reactive_block_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'volt/models'
22

3-
describe ReactiveCount do
3+
describe ReactiveBlock do
44
it "should call cur through the reactive count to the number" do
55
model = ReactiveValue.new(Model.new)
66

0 commit comments

Comments
 (0)