reactrb 0.8.7 → 0.8.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -1
- data/README.md +1 -1
- data/lib/react/api.rb +1 -0
- data/lib/react/component/class_methods.rb +6 -1
- data/lib/react/element.rb +107 -29
- data/lib/react/rendering_context.rb +47 -15
- data/lib/reactive-ruby/version.rb +1 -1
- data/lib/reactrb/new-event-name-convention.rb +11 -0
- data/spec/react/component_spec.rb +71 -0
- data/spec/react/element_spec.rb +75 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56bb10a0b7e0570fcd71cd6eb8a84b683d7c5477
|
4
|
+
data.tar.gz: 6f3556f79685a0ed59fa24e3adffe9865f2c37d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 659a94fbc934575d85084a11a0006ccb358abe68cf9a77553bf2d64e794bd5eb424ff1399dfaac62cb37d7b4c5c7ec5c00b225eae49939b01af24262de989b42
|
7
|
+
data.tar.gz: e42a8bf45da2475c6069b10956a770bdbffb73ee53cb96f72f1021a7e7e832b9cab9fc381e3ba11f29e08fbbccf3e513fa0ffbb1258cfa4c9ad6ef97024cc9d5
|
data/CHANGELOG.md
CHANGED
@@ -6,7 +6,7 @@ This project *tries* to adhere to [Semantic Versioning](http://semver.org/), eve
|
|
6
6
|
Changes are grouped as follows:
|
7
7
|
- **Added** for new features.
|
8
8
|
- **Changed** for changes in existing functionality.
|
9
|
-
- **Deprecated** for once-stable features removed in upcoming releases.
|
9
|
+
- **Deprecated** for once-stable features to be removed in upcoming releases.
|
10
10
|
- **Removed** for deprecated features removed in this release.
|
11
11
|
- **Fixed** for any bug fixes.
|
12
12
|
- **Security** to invite users to upgrade in case of vulnerabilities.
|
@@ -18,7 +18,35 @@ Whitespace conventions:
|
|
18
18
|
- 1 spaces before normal text
|
19
19
|
-->
|
20
20
|
|
21
|
+
## [0.8.8] - 2016-07-13
|
21
22
|
|
23
|
+
### Added
|
24
|
+
|
25
|
+
- More helpful error messages on render failures (#152)
|
26
|
+
- `Element#on('<my_event_name>')` subscribes `my_event_name` (#153)
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
|
30
|
+
- `Element#on(:event)` subscribes to `on_event` for reactrb components and `onEvent` for native components. (#153)
|
31
|
+
|
32
|
+
### Deprecated
|
33
|
+
|
34
|
+
- `Element#(:event)` subscription to `_onEvent` is deprecated. Once you have changed params named `_on...` to `on_...` you can `require 'reactrb/new-event-name-convention.rb'` to avoid spurious react warning messages. (#153)
|
35
|
+
|
36
|
+
|
37
|
+
### Fixed
|
38
|
+
|
39
|
+
- when using the Element['#container'].render... method generates spurious react error (#154)
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
## [0.8.7] - 2016-07-08
|
45
|
+
|
46
|
+
|
47
|
+
### Fixed
|
48
|
+
|
49
|
+
- Opal 0.10.x compatibility
|
22
50
|
|
23
51
|
|
24
52
|
## [0.8.6] - 2016-06-30
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ Install the gem, or load the js library
|
|
21
21
|
|
22
22
|
+ add `gem 'reactrb'` to your gem file or
|
23
23
|
+ `gem install reactrb` or
|
24
|
-
+ install (or load via cdn) [
|
24
|
+
+ install (or load via cdn) [reactrb-express.js](http://github.com/reactrb/reactrb-express)
|
25
25
|
|
26
26
|
For gem installation it is highly recommended to read [the getting started section at reactrb.org](http://reactrb.org/docs/getting-started.html)
|
27
27
|
|
data/lib/react/api.rb
CHANGED
@@ -2,6 +2,11 @@ module React
|
|
2
2
|
module Component
|
3
3
|
# class level methods (macros) for components
|
4
4
|
module ClassMethods
|
5
|
+
|
6
|
+
def reactrb_component?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
5
10
|
def backtrace(*args)
|
6
11
|
@dont_catch_exceptions = (args[0] == :none)
|
7
12
|
@backtrace_off = @dont_catch_exceptions || (args[0] == :off)
|
@@ -43,7 +48,7 @@ module React
|
|
43
48
|
_componentValidator: %x{
|
44
49
|
function(props, propName, componentName) {
|
45
50
|
var errors = #{validator.validate(Hash.new(`props`))};
|
46
|
-
var error = new Error(#{"In component
|
51
|
+
var error = new Error(#{"In component `#{name}`\n" + `errors`.join("\n")});
|
47
52
|
return #{`errors`.count > 0 ? `error` : `undefined`};
|
48
53
|
}
|
49
54
|
}
|
data/lib/react/element.rb
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
require 'react/ext/string'
|
2
2
|
|
3
3
|
module React
|
4
|
+
#
|
5
|
+
# Wraps the React Native element class
|
6
|
+
#
|
7
|
+
# adds the #on method to add event handlers to the element
|
8
|
+
#
|
9
|
+
# adds the #render method to place elements in the DOM and
|
10
|
+
# #delete (alias/deprecated #as_node) method to remove elements from the DOM
|
11
|
+
#
|
12
|
+
# handles the haml style class notation so that
|
13
|
+
# div.bar.blat becomes div(class: "bar blat")
|
14
|
+
# by using method missing
|
15
|
+
#
|
4
16
|
class Element
|
5
17
|
include Native
|
6
18
|
|
@@ -20,58 +32,124 @@ module React
|
|
20
32
|
@native = native_element
|
21
33
|
end
|
22
34
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
#{yield React::Event.new(`event`)}
|
29
|
-
}
|
30
|
-
}}
|
31
|
-
else
|
32
|
-
{"_on#{name}" => %x{
|
33
|
-
function(){
|
34
|
-
#{yield *Array(`arguments`)}
|
35
|
-
}
|
36
|
-
}}
|
37
|
-
end
|
38
|
-
@native = `React.cloneElement(#{self.to_n}, #{props.to_n})`
|
39
|
-
@properties.merge! props
|
35
|
+
# Attach event handlers.
|
36
|
+
|
37
|
+
def on(*event_names, &block)
|
38
|
+
event_names.each { |event_name| merge_event_prop!(event_name, &block) }
|
39
|
+
@native = `React.cloneElement(#{to_n}, #{properties.to_n})`
|
40
40
|
self
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
# Render element into DOM in the current rendering context.
|
44
|
+
# Used for elements that are not yet in DOM, i.e. they are provided as children
|
45
|
+
# or they have been explicitly removed from the rendering context using the delete method.
|
46
|
+
|
47
|
+
def render(props = {})
|
44
48
|
if props.empty?
|
45
49
|
React::RenderingContext.render(self)
|
46
50
|
else
|
47
51
|
React::RenderingContext.render(
|
48
52
|
Element.new(
|
49
|
-
`React.cloneElement(#{
|
50
|
-
type,
|
51
|
-
properties.merge(props),
|
52
|
-
block
|
53
|
+
`React.cloneElement(#{to_n}, #{API.convert_props(props)})`,
|
54
|
+
type, properties.merge(props), block
|
53
55
|
)
|
54
56
|
)
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
60
|
+
# Delete (remove) element from rendering context, the element may later be added back in
|
61
|
+
# using the render method.
|
62
|
+
|
63
|
+
def delete
|
64
|
+
React::RenderingContext.delete(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Deprecated version of delete method
|
68
|
+
|
69
|
+
def as_node
|
70
|
+
React::RenderingContext.as_node(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Any other method applied to an element will be treated as class name (haml style) thus
|
74
|
+
# div.foo.bar(id: :fred) is the same as saying div(class: "foo bar", id: :fred)
|
75
|
+
#
|
76
|
+
# single underscores become dashes, and double underscores become a single underscore
|
77
|
+
#
|
78
|
+
# params may be provide to each class (but typically only to the last for easy reading.)
|
79
|
+
|
58
80
|
def method_missing(class_name, args = {}, &new_block)
|
59
|
-
class_name = class_name.
|
81
|
+
class_name = class_name.gsub(/__|_/, '__' => '_', '_' => '-')
|
60
82
|
new_props = properties.dup
|
61
|
-
new_props[
|
83
|
+
new_props[:class] = "\
|
84
|
+
#{class_name} #{new_props[:class]} #{args.delete(:class)} #{args.delete(:className)}\
|
85
|
+
".split(' ').uniq.join(' ')
|
62
86
|
new_props.merge! args
|
63
87
|
React::RenderingContext.replace(
|
64
88
|
self,
|
65
|
-
|
89
|
+
RenderingContext.build { RenderingContext.render(type, new_props, &new_block) }
|
66
90
|
)
|
67
91
|
end
|
68
92
|
|
69
|
-
|
70
|
-
|
93
|
+
private
|
94
|
+
|
95
|
+
# built in events, events going to native components, and events going to reactrb
|
96
|
+
|
97
|
+
# built in events will have their event param translated to the Event wrapper
|
98
|
+
# and the name will camelcased and have on prefixed, so :click becomes onClick.
|
99
|
+
#
|
100
|
+
# events emitting from native components are assumed to have the same camel case and
|
101
|
+
# on prefixed.
|
102
|
+
#
|
103
|
+
# events emitting from reactrb components will just have on_ prefixed. So
|
104
|
+
# :play_button_pushed attaches to the :on_play_button_pushed param
|
105
|
+
#
|
106
|
+
# in all cases the default name convention can be overriden by wrapping in <...> brackets.
|
107
|
+
# So on("<MyEvent>") will attach to the "MyEvent" param.
|
108
|
+
|
109
|
+
def merge_event_prop!(event_name, &block)
|
110
|
+
if event_name =~ /^<(.+)>$/
|
111
|
+
merge_component_event_prop! event_name.gsub(/^<(.+)>$/, '\1'), &block
|
112
|
+
elsif React::Event::BUILT_IN_EVENTS.include?(name = "on#{event_name.event_camelize}")
|
113
|
+
merge_built_in_event_prop! name, &block
|
114
|
+
elsif @type.instance_variable_get('@native_import')
|
115
|
+
merge_component_event_prop! name, &block
|
116
|
+
else
|
117
|
+
merge_deprecated_component_event_prop! event_name, &block
|
118
|
+
merge_component_event_prop! "on_#{event_name}", &block
|
119
|
+
end
|
71
120
|
end
|
72
121
|
|
73
|
-
def
|
74
|
-
|
122
|
+
def merge_built_in_event_prop!(prop_name)
|
123
|
+
@properties.merge!(
|
124
|
+
prop_name => %x{
|
125
|
+
function(event){
|
126
|
+
return #{yield(React::Event.new(`event`))}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
def merge_component_event_prop!(prop_name)
|
133
|
+
@properties.merge!(
|
134
|
+
prop_name => %x{
|
135
|
+
function(){
|
136
|
+
return #{yield(*Array(`arguments`))}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
)
|
140
|
+
end
|
141
|
+
|
142
|
+
def merge_deprecated_component_event_prop!(event_name)
|
143
|
+
prop_name = "_on#{event_name.event_camelize}"
|
144
|
+
fn = %x{function(){#{
|
145
|
+
React::Component.deprecation_warning(
|
146
|
+
"In future releases React::Element#on('#{event_name}') will no longer respond "\
|
147
|
+
"to the '#{prop_name}' emitter.\n"\
|
148
|
+
"Rename your emitter param to 'on_#{event_name}' or use .on('<#{prop_name}>')"
|
149
|
+
)}
|
150
|
+
return #{yield(*Array(`arguments`))}
|
151
|
+
}}
|
152
|
+
@properties.merge!(prop_name => fn)
|
75
153
|
end
|
76
154
|
end
|
77
155
|
end
|
@@ -13,24 +13,12 @@ module React
|
|
13
13
|
|
14
14
|
def self.render(name, *args, &block)
|
15
15
|
remove_nodes_from_args(args)
|
16
|
-
@buffer
|
16
|
+
@buffer ||= [] unless @buffer
|
17
17
|
if block
|
18
18
|
element = build do
|
19
19
|
saved_waiting_on_resources = waiting_on_resources
|
20
20
|
self.waiting_on_resources = nil
|
21
|
-
|
22
|
-
# Todo figure out how children rendering should happen, probably should have special method that pushes children into the buffer
|
23
|
-
# i.e. render_child/render_children that takes Element/Array[Element] and does the push into the buffer
|
24
|
-
if !name && ( # !name means called from outer render so we check that it has rendered correctly
|
25
|
-
(@buffer.count > 1) || # should only render one element
|
26
|
-
(@buffer.count == 1 && @buffer.last != result) || # it should return that element
|
27
|
-
(@buffer.count == 0 && !(result.is_a?(String) || (result.respond_to?(:acts_as_string?) && result.acts_as_string?) || result.is_a?(Element))) #for convience we will also convert the return value to a span if its a string
|
28
|
-
)
|
29
|
-
raise "a components render method must generate and return exactly 1 element or a string"
|
30
|
-
end
|
31
|
-
|
32
|
-
@buffer << result.to_s if result.is_a? String || (result.respond_to?(:acts_as_string?) && result.acts_as_string?) # For convience we push the last return value on if its a string
|
33
|
-
@buffer << result if result.is_a?(Element) && @buffer.count == 0
|
21
|
+
run_child_block(name.nil?, &block)
|
34
22
|
if name
|
35
23
|
buffer = @buffer.dup
|
36
24
|
React.create_element(name, *args) { buffer }.tap do |element|
|
@@ -44,7 +32,6 @@ module React
|
|
44
32
|
end
|
45
33
|
elsif name.is_a? React::Element
|
46
34
|
element = name
|
47
|
-
# I BELIEVE WAITING ON RESOURCES SHOULD ALREADY BE SET
|
48
35
|
else
|
49
36
|
element = React.create_element(name, *args)
|
50
37
|
element.waiting_on_resources = waiting_on_resources
|
@@ -78,6 +65,51 @@ module React
|
|
78
65
|
value.as_node if value.is_a?(Element) rescue nil
|
79
66
|
end if args[0] && args[0].is_a?(Hash)
|
80
67
|
end
|
68
|
+
|
69
|
+
# run_child_block gathers the element(s) generated by a child block.
|
70
|
+
# for example when rendering this div: div { "hello".span; "goodby".span }
|
71
|
+
# two child Elements will be generated.
|
72
|
+
#
|
73
|
+
# the final value of the block should either be
|
74
|
+
# 1 an object that responds to :acts_as_string?
|
75
|
+
# 2 a string,
|
76
|
+
# 3 an element that is NOT yet pushed on the rendering buffer
|
77
|
+
# 4 or the last element pushed on the buffer
|
78
|
+
#
|
79
|
+
# in case 1 we change the object to a string, and then it becomes case 2
|
80
|
+
# in case 2 we automatically push the string onto the buffer
|
81
|
+
# in case 3 we also push the Element onto the buffer IF the buffer is empty
|
82
|
+
# case 4 requires no special processing
|
83
|
+
#
|
84
|
+
# Once we have taken care of these special cases we do a check IF we are in an
|
85
|
+
# outer rendering scope. In this case react only allows us to generate 1 Element
|
86
|
+
# so we insure that is the case, and also check to make sure that element in the buffer
|
87
|
+
# is the element returned
|
88
|
+
|
89
|
+
def self.run_child_block(is_outer_scope)
|
90
|
+
result = yield
|
91
|
+
result = result.to_s if result.try :acts_as_string?
|
92
|
+
@buffer << result if result.is_a?(String) || (result.is_a?(Element) && @buffer.empty?)
|
93
|
+
raise_render_error(result) if is_outer_scope && @buffer != [result]
|
94
|
+
end
|
95
|
+
|
96
|
+
# heurestically raise a meaningful error based on the situation
|
97
|
+
|
98
|
+
def self.raise_render_error(result)
|
99
|
+
improper_render 'A different element was returned than was generated within the DSL.',
|
100
|
+
'Possibly improper use of Element#delete.' if @buffer.count == 1
|
101
|
+
improper_render "Instead #{@buffer.count} elements were generated.",
|
102
|
+
'Do you want to wrap your elements in a div?' if @buffer.count > 1
|
103
|
+
improper_render "Instead the component #{result} was returned.",
|
104
|
+
"Did you mean #{result}()?" if result.try :reactrb_component?
|
105
|
+
improper_render "Instead the #{result.class} #{result} was returned.",
|
106
|
+
'You may need to convert this to a string.'
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.improper_render(message, solution)
|
110
|
+
raise "a component's render method must generate and return exactly 1 element or a string.\n"\
|
111
|
+
" #{message} #{solution}"
|
112
|
+
end
|
81
113
|
end
|
82
114
|
|
83
115
|
class ::Object
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# rubocop:disable Style/FileName
|
2
|
+
# require 'reactrb/new-event-name-convention' to remove missing param declaration "_onXXXX"
|
3
|
+
if RUBY_ENGINE == 'opal'
|
4
|
+
# removes generation of the deprecated "_onXXXX" event param syntax
|
5
|
+
module React
|
6
|
+
class Element
|
7
|
+
def merge_deprecated_component_event_prop!(event_name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -477,6 +477,77 @@ describe React::Component do
|
|
477
477
|
end
|
478
478
|
end
|
479
479
|
|
480
|
+
describe 'Anonymous Component' do
|
481
|
+
it "will not generate spurious warning messages" do
|
482
|
+
foo = Class.new(React::Component::Base)
|
483
|
+
foo.class_eval do
|
484
|
+
def render; "hello" end
|
485
|
+
end
|
486
|
+
|
487
|
+
%x{
|
488
|
+
var log = [];
|
489
|
+
var org_warn_console = window.console.warn;
|
490
|
+
var org_error_console = window.console.error
|
491
|
+
window.console.warn = window.console.error = function(str){log.push(str)}
|
492
|
+
}
|
493
|
+
renderToDocument(foo)
|
494
|
+
`window.console.warn = org_warn_console; window.console.error = org_error_console;`
|
495
|
+
expect(`log`).to eq([])
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe 'Render Error Handling' do
|
500
|
+
before(:each) do
|
501
|
+
%x{
|
502
|
+
window.test_log = [];
|
503
|
+
window.org_warn_console = window.console.warn;
|
504
|
+
window.org_error_console = window.console.error
|
505
|
+
window.console.warn = window.console.error = function(str){window.test_log.push(str)}
|
506
|
+
}
|
507
|
+
end
|
508
|
+
it "will generate a message if render returns something other than an Element or a String" do
|
509
|
+
foo = Class.new(React::Component::Base)
|
510
|
+
foo.class_eval do
|
511
|
+
def render; Hash.new; end
|
512
|
+
end
|
513
|
+
|
514
|
+
renderToDocument(foo)
|
515
|
+
`window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
|
516
|
+
expect(`test_log`.first).to match /Instead the Hash \{\} was returned/
|
517
|
+
end
|
518
|
+
it "will generate a message if render returns a Component class" do
|
519
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
520
|
+
foo = Class.new(React::Component::Base)
|
521
|
+
foo.class_eval do
|
522
|
+
def render; Foo; end
|
523
|
+
end
|
524
|
+
|
525
|
+
renderToDocument(foo)
|
526
|
+
`window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
|
527
|
+
expect(`test_log`.first).to match /Did you mean Foo()/
|
528
|
+
end
|
529
|
+
it "will generate a message if more than 1 element is generated" do
|
530
|
+
foo = Class.new(React::Component::Base)
|
531
|
+
foo.class_eval do
|
532
|
+
def render; "hello".span; "goodby".span; end
|
533
|
+
end
|
534
|
+
|
535
|
+
renderToDocument(foo)
|
536
|
+
`window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
|
537
|
+
expect(`test_log`.first).to match /Instead 2 elements were generated/
|
538
|
+
end
|
539
|
+
it "will generate a message if the element generated is not the element returned" do
|
540
|
+
foo = Class.new(React::Component::Base)
|
541
|
+
foo.class_eval do
|
542
|
+
def render; "hello".span; "goodby".span.delete; end
|
543
|
+
end
|
544
|
+
|
545
|
+
renderToDocument(foo)
|
546
|
+
`window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
|
547
|
+
expect(`test_log`.first).to match /A different element was returned than was generated within the DSL/
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
480
551
|
describe 'Event handling' do
|
481
552
|
before do
|
482
553
|
stub_const 'Foo', Class.new
|
data/spec/react/element_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
if opal?
|
4
|
+
# require 'reactrb/new-event-name-convention' # this require will get rid of any error messages but
|
5
|
+
# the on method will no longer attach to the param prefixed with _on
|
4
6
|
describe React::Element do
|
5
7
|
it 'bridges `type` of native React.Element attributes' do
|
6
8
|
element = React.create_element('div')
|
@@ -17,7 +19,79 @@ describe React::Element do
|
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
|
-
describe 'Event
|
22
|
+
describe 'Component Event Subscription' do
|
23
|
+
|
24
|
+
it 'will subscribe to a component event param' do
|
25
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
26
|
+
Foo.class_eval do
|
27
|
+
param :on_event, type: Proc, default: nil, allow_nil: true
|
28
|
+
def render
|
29
|
+
params.on_event
|
30
|
+
end
|
31
|
+
end
|
32
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'will subscribe to multiple component event params' do
|
36
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
37
|
+
Foo.class_eval do
|
38
|
+
param :on_event1, type: Proc, default: nil, allow_nil: true
|
39
|
+
param :on_event2, type: Proc, default: nil, allow_nil: true
|
40
|
+
def render
|
41
|
+
params.on_event1+params.on_event2
|
42
|
+
end
|
43
|
+
end
|
44
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event1, :event2) {'works!'})).to eq('<span>works!works!</span>')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'will subscribe to a native components event param' do
|
48
|
+
%x{
|
49
|
+
window.NativeComponent = React.createClass({
|
50
|
+
displayName: "HelloMessage",
|
51
|
+
render: function render() {
|
52
|
+
return React.createElement("span", null, this.props.onEvent());
|
53
|
+
}
|
54
|
+
})
|
55
|
+
}
|
56
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
57
|
+
Foo.class_eval do
|
58
|
+
imports "NativeComponent"
|
59
|
+
end
|
60
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'will subscribe to a component event param with a non-default name' do
|
64
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
65
|
+
Foo.class_eval do
|
66
|
+
param :my_event, type: Proc, default: nil, allow_nil: true
|
67
|
+
def render
|
68
|
+
params.my_event
|
69
|
+
end
|
70
|
+
end
|
71
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on("<my_event>") {'works!'})).to eq('<span>works!</span>')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'will subscribe to a component event param using the deprecated naming convention and generate a message' do
|
75
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
76
|
+
Foo.class_eval do
|
77
|
+
param :_onEvent, type: Proc, default: nil, allow_nil: true
|
78
|
+
def render
|
79
|
+
params._onEvent
|
80
|
+
end
|
81
|
+
end
|
82
|
+
%x{
|
83
|
+
var log = [];
|
84
|
+
var org_warn_console = window.console.warn;
|
85
|
+
var org_error_console = window.console.error;
|
86
|
+
window.console.warn = window.console.error = function(str){log.push(str)}
|
87
|
+
}
|
88
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
89
|
+
`window.console.warn = org_warn_console; window.console.error = org_error_console;`
|
90
|
+
expect(`log`).to eq(["Warning: Failed propType: In component `Foo`\nProvided prop `on_event` not specified in spec", "Warning: Deprecated feature used in React::Component. In future releases React::Element#on('event') will no longer respond to the '_onEvent' emitter.\nRename your emitter param to 'on_event' or use .on('<_onEvent>')"])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'Builtin Event subscription' do
|
21
95
|
it 'is subscribable through `on(:event_name)` method' do
|
22
96
|
expect { |b|
|
23
97
|
element = React.create_element("div").on(:click, &b)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reactrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chang
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-07-
|
13
|
+
date: 2016-07-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: opal
|
@@ -377,6 +377,7 @@ files:
|
|
377
377
|
- lib/reactive-ruby/version.rb
|
378
378
|
- lib/reactrb.rb
|
379
379
|
- lib/reactrb/auto-import.rb
|
380
|
+
- lib/reactrb/new-event-name-convention.rb
|
380
381
|
- lib/sources/react-latest.js
|
381
382
|
- lib/sources/react-v13.js
|
382
383
|
- lib/sources/react-v14.js
|