reactrb 0.8.7 → 0.8.8
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/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
|