hyper-react 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +27 -0
- data/.gitignore +36 -0
- data/.rubocop.yml +1159 -0
- data/.travis.yml +29 -0
- data/Appraisals +20 -0
- data/CHANGELOG.md +93 -0
- data/Gemfile +6 -0
- data/LICENSE +19 -0
- data/README.md +121 -0
- data/Rakefile +33 -0
- data/UPGRADING.md +24 -0
- data/component-name-lookup.md +145 -0
- data/config.ru +25 -0
- data/gemfiles/opal_0.8_react_13.gemfile +13 -0
- data/gemfiles/opal_0.8_react_14.gemfile +13 -0
- data/gemfiles/opal_0.8_react_15.gemfile +13 -0
- data/gemfiles/opal_0.9_react_13.gemfile +13 -0
- data/gemfiles/opal_0.9_react_14.gemfile +13 -0
- data/gemfiles/opal_0.9_react_15.gemfile +13 -0
- data/hyper-react.gemspec +43 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +4 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +2 -0
- data/lib/generators/reactive_ruby/test_app/templates/boot.rb.erb +6 -0
- data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
- data/lib/generators/reactive_ruby/test_app/templates/test_application.rb.erb +13 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/layouts/test_layout.html.erb +0 -0
- data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +109 -0
- data/lib/hyper-react.rb +52 -0
- data/lib/rails-helpers/top_level_rails_component.rb +54 -0
- data/lib/react-sources/react-server.js +2 -0
- data/lib/react/api.rb +162 -0
- data/lib/react/callbacks.rb +42 -0
- data/lib/react/children.rb +30 -0
- data/lib/react/component.rb +139 -0
- data/lib/react/component/api.rb +50 -0
- data/lib/react/component/base.rb +9 -0
- data/lib/react/component/class_methods.rb +214 -0
- data/lib/react/component/dsl_instance_methods.rb +27 -0
- data/lib/react/component/params.rb +6 -0
- data/lib/react/component/props_wrapper.rb +83 -0
- data/lib/react/component/should_component_update.rb +98 -0
- data/lib/react/component/tags.rb +144 -0
- data/lib/react/element.rb +168 -0
- data/lib/react/event.rb +76 -0
- data/lib/react/ext/hash.rb +9 -0
- data/lib/react/ext/string.rb +8 -0
- data/lib/react/hash.rb +13 -0
- data/lib/react/native_library.rb +92 -0
- data/lib/react/object.rb +15 -0
- data/lib/react/observable.rb +29 -0
- data/lib/react/react-source.rb +9 -0
- data/lib/react/rendering_context.rb +142 -0
- data/lib/react/state.rb +190 -0
- data/lib/react/test.rb +16 -0
- data/lib/react/test/dsl.rb +17 -0
- data/lib/react/test/matchers/render_html_matcher.rb +49 -0
- data/lib/react/test/rspec.rb +15 -0
- data/lib/react/test/session.rb +46 -0
- data/lib/react/top_level.rb +132 -0
- data/lib/react/validator.rb +136 -0
- data/lib/reactive-ruby/component_loader.rb +49 -0
- data/lib/reactive-ruby/isomorphic_helpers.rb +197 -0
- data/lib/reactive-ruby/rails.rb +7 -0
- data/lib/reactive-ruby/rails/component_mount.rb +46 -0
- data/lib/reactive-ruby/rails/controller_helper.rb +15 -0
- data/lib/reactive-ruby/rails/railtie.rb +14 -0
- data/lib/reactive-ruby/serializers.rb +15 -0
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +42 -0
- data/lib/reactive-ruby/version.rb +3 -0
- data/lib/reactrb/auto-import.rb +32 -0
- data/lib/reactrb/deep-compare.rb +24 -0
- data/lib/reactrb/new-event-name-convention.rb +11 -0
- data/lib/sources/react-latest.js +21169 -0
- data/lib/sources/react-v13.js +21645 -0
- data/lib/sources/react-v14.js +20821 -0
- data/lib/sources/react-v15.js +21170 -0
- data/logo1.png +0 -0
- data/logo2.png +0 -0
- data/logo3.png +0 -0
- data/path_release_steps.md +9 -0
- data/spec/controller_helper_spec.rb +34 -0
- data/spec/index.html.erb +10 -0
- data/spec/react/callbacks_spec.rb +106 -0
- data/spec/react/children_spec.rb +76 -0
- data/spec/react/component/base_spec.rb +32 -0
- data/spec/react/component_spec.rb +872 -0
- data/spec/react/dsl_spec.rb +296 -0
- data/spec/react/element_spec.rb +136 -0
- data/spec/react/event_spec.rb +24 -0
- data/spec/react/native_library_spec.rb +344 -0
- data/spec/react/observable_spec.rb +7 -0
- data/spec/react/opal_jquery_extensions_spec.rb +66 -0
- data/spec/react/param_declaration_spec.rb +258 -0
- data/spec/react/react_spec.rb +209 -0
- data/spec/react/state_spec.rb +55 -0
- data/spec/react/test/dsl_spec.rb +43 -0
- data/spec/react/test/matchers/render_html_matcher_spec.rb +83 -0
- data/spec/react/test/rspec_spec.rb +62 -0
- data/spec/react/test/session_spec.rb +100 -0
- data/spec/react/test/utils_spec.rb +45 -0
- data/spec/react/top_level_component_spec.rb +96 -0
- data/spec/react/tutorial/tutorial_spec.rb +36 -0
- data/spec/react/validator_spec.rb +124 -0
- data/spec/reactive-ruby/component_loader_spec.rb +71 -0
- data/spec/reactive-ruby/isomorphic_helpers_spec.rb +155 -0
- data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +10 -0
- data/spec/reactive-ruby/rails/component_mount_spec.rb +66 -0
- data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +35 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/support/react/spec_helpers.rb +64 -0
- data/spec/vendor/es5-shim.min.js +6 -0
- data/spec/vendor/jquery-2.2.4.min.js +4 -0
- metadata +387 -0
data/.travis.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1
|
6
|
+
- jruby-19mode
|
7
|
+
before_script:
|
8
|
+
- phantomjs --version
|
9
|
+
script:
|
10
|
+
- bundle exec rake test_app
|
11
|
+
- bundle exec rake
|
12
|
+
gemfile:
|
13
|
+
- gemfiles/opal_0.8_react_13.gemfile
|
14
|
+
- gemfiles/opal_0.8_react_14.gemfile
|
15
|
+
- gemfiles/opal_0.8_react_15.gemfile
|
16
|
+
- gemfiles/opal_0.9_react_13.gemfile
|
17
|
+
- gemfiles/opal_0.9_react_14.gemfile
|
18
|
+
- gemfiles/opal_0.9_react_15.gemfile
|
19
|
+
|
20
|
+
# These two setup seems to run indefinitely long
|
21
|
+
# further investigation required.
|
22
|
+
matrix:
|
23
|
+
exclude:
|
24
|
+
- rvm: jruby-19mode
|
25
|
+
gemfile: gemfiles/opal_0.9_react_13.gemfile
|
26
|
+
- rvm: jruby-19mode
|
27
|
+
gemfile: gemfiles/opal_0.9_react_14.gemfile
|
28
|
+
- rvm: jruby-19mode
|
29
|
+
gemfile: gemfiles/opal_0.9_react_15.gemfile
|
data/Appraisals
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
opal_versions = ['0.8', '0.9']
|
2
|
+
react_versions_map = {
|
3
|
+
'13' => '~> 1.3.3',
|
4
|
+
'14' => '~> 1.6.2',
|
5
|
+
'15' => '~> 1.8.2'
|
6
|
+
}
|
7
|
+
opal_rails_versions_map = {
|
8
|
+
'0.8' => '~> 0.8.1',
|
9
|
+
'0.9' => '~> 0.9.0',
|
10
|
+
}
|
11
|
+
|
12
|
+
opal_versions.each do |opal_v|
|
13
|
+
react_versions_map.each do |react_v, react_rails_v|
|
14
|
+
appraise "opal-#{opal_v}-react-#{react_v}" do
|
15
|
+
gem 'opal', "~> #{opal_v}.0"
|
16
|
+
gem 'opal-rails', opal_rails_versions_map[opal_v]
|
17
|
+
gem 'react-rails', react_rails_v, require: false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file starting with v0.8.6.
|
4
|
+
This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
|
5
|
+
|
6
|
+
Changes are grouped as follows:
|
7
|
+
- **Added** for new features.
|
8
|
+
- **Changed** for changes in existing functionality.
|
9
|
+
- **Deprecated** for once-stable features to be removed in upcoming releases.
|
10
|
+
- **Removed** for deprecated features removed in this release.
|
11
|
+
- **Fixed** for any bug fixes.
|
12
|
+
- **Security** to invite users to upgrade in case of vulnerabilities.
|
13
|
+
|
14
|
+
<!--
|
15
|
+
Whitespace conventions:
|
16
|
+
- 4 spaces before ## titles
|
17
|
+
- 2 spaces before ### titles
|
18
|
+
- 1 spaces before normal text
|
19
|
+
-->
|
20
|
+
|
21
|
+
## [0.10.0] - 2016-10-30
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
- This gem is now renamed to `hyper-react`, see [UPGRADING](UPGRADING.md) for details.
|
26
|
+
|
27
|
+
### Fixed
|
28
|
+
|
29
|
+
- ReactJS functional stateless component could not be imported from `NativeLibrary`. Note that functional component is only supported in React v14+. (#162)
|
30
|
+
- Prerender log got accumulated between reqeusts. (#176)
|
31
|
+
|
32
|
+
## [0.9.0] - 2016-10-19
|
33
|
+
|
34
|
+
### Added
|
35
|
+
|
36
|
+
- `react/react-source` is the suggested way to include ReactJS sources now. Simply require `react/react-source` immediately before the `require "reactrb"` in your Opal code will make it work.
|
37
|
+
|
38
|
+
### Deprecated
|
39
|
+
|
40
|
+
- `react-latest` & `react-v1x` is deprecated. Use `react/react-source` instead.
|
41
|
+
|
42
|
+
### Removed
|
43
|
+
|
44
|
+
- `opal-browser` is removed from runtime dependency. (#133) You will have to add `gem 'opal-browser'` to your gemfile (recommended) or remove all references to opal-browser from your manifest files.
|
45
|
+
|
46
|
+
### Fixed
|
47
|
+
|
48
|
+
- `$window#on` in `opal-jquery` is broken. (#166)
|
49
|
+
- `Element#render` trigger unnecessary re-mounts when called multiple times. (#170)
|
50
|
+
- Gets rid of react warnings about updating state during render (#155)
|
51
|
+
- Multiple HAML classes (i.e. div.foo.bar) was not working (regression introduced in 0.8.8)
|
52
|
+
- Don't send nil (null) to form components as the value string (#157)
|
53
|
+
- Process `params` (props) correctly when using `Element#on` or `Element#render` (#158)
|
54
|
+
- Deprecate shallow param compare (#156)
|
55
|
+
|
56
|
+
|
57
|
+
## [0.8.8] - 2016-07-13
|
58
|
+
|
59
|
+
### Added
|
60
|
+
|
61
|
+
- More helpful error messages on render failures (#152)
|
62
|
+
- `Element#on('<my_event_name>')` subscribes to `my_event_name` (#153)
|
63
|
+
|
64
|
+
### Changed
|
65
|
+
|
66
|
+
- `Element#on(:event)` subscribes to `on_event` for reactrb components and `onEvent` for native components. (#153)
|
67
|
+
|
68
|
+
### Deprecated
|
69
|
+
|
70
|
+
- `Element#on(: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)
|
71
|
+
|
72
|
+
|
73
|
+
### Fixed
|
74
|
+
|
75
|
+
- The `Element['#container'].render...` method generates a spurious react error (#154)
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
## [0.8.7] - 2016-07-08
|
81
|
+
|
82
|
+
|
83
|
+
### Fixed
|
84
|
+
|
85
|
+
- Opal 0.10.x compatibility
|
86
|
+
|
87
|
+
|
88
|
+
## [0.8.6] - 2016-06-30
|
89
|
+
|
90
|
+
|
91
|
+
### Fixed
|
92
|
+
|
93
|
+
- Method missing within a component was being reported as `incorrect const name` (#151)
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2015 Yi-Cheng Chang (http://github.com/zetachang)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# hyper-react
|
2
|
+
|
3
|
+
[![Join the chat at https://gitter.im/reactrb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/reactrb/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
|
+
[![Build Status](https://travis-ci.org/ruby-hyperloop/reactrb.svg?branch=master)](https://travis-ci.org/reactrb/reactrb)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/reactrb/reactrb/badges/gpa.svg)](https://codeclimate.com/github/reactrb/reactrb)
|
6
|
+
[![Gem Version](https://badge.fury.io/rb/reactrb.svg)](https://badge.fury.io/rb/reactrb)
|
7
|
+
|
8
|
+
**hyper-react is an [Opal Ruby](http://opalrb.org) wrapper of
|
9
|
+
[React.js library](https://facebook.github.io/react)**.
|
10
|
+
|
11
|
+
It lets you write reactive UI components, with Ruby's elegance using the tried
|
12
|
+
and true React.js engine. :heart:
|
13
|
+
|
14
|
+
Visit [ruby-hyperloop.io](http://ruby-hyperloop.io) for the full story.
|
15
|
+
|
16
|
+
### Important: `react.rb`, `reactive-ruby` and `reactrb` gems are **deprecated**. See [**UPGRADING**](UPGRADING.md) for details.
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Install the gem, or load the js library
|
21
|
+
|
22
|
+
1. Add `gem 'hyper-react'` to your **Gemfile**
|
23
|
+
2. Or `gem install hyper-react`
|
24
|
+
3. Or install (or load via cdn) from [reactrb-express.js](http://github.com/ruby-hyperloop/reactrb-express)
|
25
|
+
|
26
|
+
For gem installation it is highly recommended to read the [getting started](http://ruby-hyperloop.io/get_started/) and [installation](http://ruby-hyperloop.io/installation/) guides at [ruby-hyperloop.io.](http://ruby-hyperloop.io)
|
27
|
+
|
28
|
+
## Quick Overview
|
29
|
+
|
30
|
+
A component is a plain ruby class with a `#render` method defined.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class HelloMessage
|
34
|
+
def render
|
35
|
+
React.create_element("div") { "Hello World!" }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
puts React.render_to_static_markup(React.create_element(HelloMessage))
|
40
|
+
|
41
|
+
# => '<div>Hello World!</div>'
|
42
|
+
```
|
43
|
+
|
44
|
+
### React::Component
|
45
|
+
|
46
|
+
You can simply include `React::Component` to get the power of a complete DSL to generate html markup, event handlers and it also provides a full set of class macros to define states, parameters, and lifecycle callbacks.
|
47
|
+
|
48
|
+
As events occur, components update their state, which causes them to rerender, and perhaps pass new parameters to lower level components, thus causing them to rerender.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
class HelloWorld < React::Component::Base
|
52
|
+
param :time, type: Time
|
53
|
+
render do
|
54
|
+
p do
|
55
|
+
span { "Hello, " }
|
56
|
+
input(type: :text, placeholder: "Your Name Here")
|
57
|
+
span { "! It is #{params.time}"}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
every(1) do
|
63
|
+
Element["#example"].render do
|
64
|
+
HelloWorld(time: Time.now)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
hyper-react components are *isomorphic* (or *univeral*) meaning they can run on the server as well as the client.
|
70
|
+
|
71
|
+
hyper-react integrates well with Rails, Sinatra, and simple static sites, and can be added to existing web pages very easily.
|
72
|
+
|
73
|
+
Under the hood the actual work is effeciently done by the [React.js](https://facebook.github.io/react) engine.
|
74
|
+
|
75
|
+
|
76
|
+
## Why ?
|
77
|
+
|
78
|
+
+ *Single Language:* Use Ruby everywhere, no JS, markup languages, or JSX
|
79
|
+
+ *Powerful DSL:* Describe HTML and event handlers with a minimum of fuss
|
80
|
+
+ *Ruby Goodness:* Use all the features of Ruby to create reusable, maintainable UI code
|
81
|
+
+ *React Simplicity:* Nothing is taken away from the React.js model
|
82
|
+
+ *Enhanced Features:* Enhanced parameter and state management and other new features
|
83
|
+
+ *Plays well with Others:* Works with other frameworks, React.js components, Rails, Sinatra and static web pages
|
84
|
+
|
85
|
+
## Problems, Questions, Issues
|
86
|
+
|
87
|
+
+ [Stack Overflow](http://stackoverflow.com/questions/tagged/react.rb) tag `react.rb` for specific problems.
|
88
|
+
+ [Gitter.im](https://gitter.im/reactrb/chat) for general questions, discussion, and interactive help.
|
89
|
+
+ [Github Issues](https://github.com/reactrb/reactrb/issues) for bugs, feature enhancements, etc.
|
90
|
+
|
91
|
+
|
92
|
+
## Roadmap
|
93
|
+
|
94
|
+
Version 0.10.x **will not be** 100% backward compatible with 0.3.0 (`react.rb`) or 0.7.x (`reactive-ruby`).
|
95
|
+
|
96
|
+
Please let us know either at [Gitter.im](https://gitter.im/reactrb/chat) or [via an issue](https://github.com/reactrb/reactrb/issues) if you have specific concerns with the upgrade from 0.3.0 to 0.10.x.
|
97
|
+
|
98
|
+
## Developing
|
99
|
+
|
100
|
+
`git clone` the project.
|
101
|
+
|
102
|
+
To play with some live examples, refer to https://github.com/ruby-hyperloop/reactrb-examples.
|
103
|
+
|
104
|
+
Note that these are very simple examples, for the purpose of showing how to configure the gem in various server environments. For more examples and information see [ruby-hyperloop.io.](http://ruby-hyperloop.io)
|
105
|
+
|
106
|
+
## Testing
|
107
|
+
|
108
|
+
1. Run `bundle exec rake test_app` to generate a dummy test app.
|
109
|
+
2. `bundle exec appraisal install` to generate separate gemfiles for different environments.
|
110
|
+
2. `bundle exec appraisal opal-0.9-react-15 rake` to run test for opal-0.9 & react-v0.15.
|
111
|
+
|
112
|
+
## Contributions
|
113
|
+
|
114
|
+
This project is still in early stage, so discussion, bug reports and PRs are
|
115
|
+
really welcome :wink:.
|
116
|
+
|
117
|
+
|
118
|
+
## License
|
119
|
+
|
120
|
+
In short, hyper-react is available under the MIT license. See the LICENSE file for
|
121
|
+
more info.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
# Store the BUNDLE_GEMFILE env, since rake or rspec seems to clean it
|
6
|
+
# while invoking task.
|
7
|
+
ENV['REAL_BUNDLE_GEMFILE'] = ENV['BUNDLE_GEMFILE']
|
8
|
+
|
9
|
+
require 'rspec/core/rake_task'
|
10
|
+
require 'opal/rspec/rake_task'
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new('ruby:rspec')
|
13
|
+
|
14
|
+
Opal::RSpec::RakeTask.new('opal:rspec') do |s, task|
|
15
|
+
s.append_path 'spec/vendor'
|
16
|
+
s.index_path = 'spec/index.html.erb'
|
17
|
+
task.timeout = 80000 if task
|
18
|
+
end
|
19
|
+
|
20
|
+
task :test do
|
21
|
+
Rake::Task['ruby:rspec'].invoke
|
22
|
+
Rake::Task['opal:rspec'].invoke
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'generators/reactive_ruby/test_app/test_app_generator'
|
26
|
+
desc "Generates a dummy app for testing"
|
27
|
+
task :test_app do
|
28
|
+
ReactiveRuby::TestAppGenerator.start
|
29
|
+
puts "Setting up test app database..."
|
30
|
+
system("bundle exec rake db:drop db:create db:migrate > #{File::NULL}")
|
31
|
+
end
|
32
|
+
|
33
|
+
task default: [ :test ]
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## Upgrading to hyper-react from Reactrb
|
2
|
+
|
3
|
+
Follow these steps to upgrade:
|
4
|
+
|
5
|
+
1. Replace `reactrb` with `hyper-react` both in **Gemfile** and any `require`s in your code.
|
6
|
+
2. To include the React.js source, the suggested way is to add `require 'react/react-source'` before `require 'hyper-react'`. This will use the copy of React.js source from `react-rails` gem.
|
7
|
+
|
8
|
+
## Upgrading to Reactrb
|
9
|
+
|
10
|
+
The original gem `react.rb` was superceeded by `reactive-ruby`, which has had over 15,000 downloads. This name has now been superceeded by `reactrb` (see #144 for detailed discussion on why.)
|
11
|
+
|
12
|
+
Going forward the name `reactrb` will be used consistently as the organization name, the gem name, the domain name, the twitter handle, etc.
|
13
|
+
|
14
|
+
The first initial version of `reactrb` is 0.8.x.
|
15
|
+
|
16
|
+
It is very unlikely that there will be any more releases of the `reactive-ruby` gem, so users should upgrade to `reactrb`.
|
17
|
+
|
18
|
+
There are no syntactic or semantic breaking changes between `reactrb` v 0.8.x and
|
19
|
+
previous versions, however the `reactrb` gem does *not* include the react-js source as previous versions did. This allows you to pick the react js source compatible with other gems and react js components you may be using.
|
20
|
+
|
21
|
+
Follow these steps to upgrade:
|
22
|
+
|
23
|
+
1. Replace `reactive-ruby` with `reactrb` both in **Gemfile** and any `require`s in your code.
|
24
|
+
2. To include the React.js source, the suggested way is to add `require 'react/react-source'` before `require 'reactrb'`. This will use the copy of React.js source from `react-rails` gem.
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#### Notes on how component names are looked up
|
2
|
+
|
3
|
+
Given:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
|
7
|
+
class Blat < React::Component::Base
|
8
|
+
|
9
|
+
render do
|
10
|
+
Bar()
|
11
|
+
Foo::Bar()
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class Bar < React::Component::Base
|
17
|
+
end
|
18
|
+
|
19
|
+
module Foo
|
20
|
+
|
21
|
+
class Bar < React::Component::Base
|
22
|
+
|
23
|
+
render do
|
24
|
+
Blat()
|
25
|
+
Baz()
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Baz < React::Component::Base
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
The problem is that method lookup is different than constant lookup. We can prove it by running this code:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
def try_it(test, &block)
|
39
|
+
puts "trying #{test}"
|
40
|
+
result = yield
|
41
|
+
puts "success#{': '+result.to_s if result}"
|
42
|
+
rescue Exception => e
|
43
|
+
puts "failed: #{e}"
|
44
|
+
ensure
|
45
|
+
puts "---------------------------------"
|
46
|
+
end
|
47
|
+
|
48
|
+
module Boom
|
49
|
+
|
50
|
+
Bar = 12
|
51
|
+
|
52
|
+
def self.Bar
|
53
|
+
puts " Boom::Bar says hi"
|
54
|
+
end
|
55
|
+
|
56
|
+
class Baz
|
57
|
+
def doit
|
58
|
+
try_it("Bar()") { Bar() }
|
59
|
+
try_it("Boom::Bar()") {Boom::Bar()}
|
60
|
+
try_it("Bar") { Bar }
|
61
|
+
try_it("Boom::Bar") { Boom::Bar }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
Boom::Baz.new.doit
|
69
|
+
```
|
70
|
+
|
71
|
+
which prints:
|
72
|
+
|
73
|
+
```text
|
74
|
+
trying Bar()
|
75
|
+
failed: Bar: undefined method `Bar' for #<Boom::Baz:0x774>
|
76
|
+
---------------------------------
|
77
|
+
trying Boom::Bar()
|
78
|
+
Boom::Bar says hi
|
79
|
+
success
|
80
|
+
---------------------------------
|
81
|
+
trying Bar
|
82
|
+
success: 12
|
83
|
+
---------------------------------
|
84
|
+
trying Boom::Bar
|
85
|
+
success: 12
|
86
|
+
---------------------------------
|
87
|
+
```
|
88
|
+
|
89
|
+
[try-it](http://opalrb.org/try/?code:def%20try_it(test%2C%20%26block)%0A%20%20puts%20%22trying%20%23%7Btest%7D%22%0A%20%20result%20%3D%20yield%0A%20%20puts%20%22success%23%7B%27%3A%20%27%2Bresult.to_s%20if%20result%7D%22%0Arescue%20Exception%20%3D%3E%20e%0A%20%20puts%20%22failed%3A%20%23%7Be%7D%22%0Aensure%0A%20%20puts%20%22---------------------------------%22%0Aend%0A%0Amodule%20Boom%0A%20%20%0A%20%20Bar%20%3D%2012%0A%20%20%0A%20%20def%20self.Bar%0A%20%20%20%20puts%20%22%20%20%20Boom%3A%3ABar%20says%20hi%22%0A%20%20end%0A%0A%20%20class%20Baz%0A%20%20%20%20def%20doit%0A%20%20%20%20%20%20try_it(%22Bar()%22)%20%7B%20Bar()%20%7D%0A%20%20%20%20%20%20try_it(%22Boom%3A%3ABar()%22)%20%7BBoom%3A%3ABar()%7D%0A%20%20%20%20%20%20try_it(%22Bar%22)%20%7B%20Bar%20%7D%0A%20%20%20%20%20%20try_it(%22Boom%3A%3ABar%22)%20%7B%20Boom%3A%3ABar%20%7D%0A%20%20%20%20end%0A%20%20end%0Aend%0A%20%20%0A%0A%0ABoom%3A%3ABaz.new.doit)
|
90
|
+
|
91
|
+
|
92
|
+
What we need to do is:
|
93
|
+
|
94
|
+
1. when defining a component class `Foo`, also define in the same scope that Foo is being defined a method `self.Foo` that will accept Foo's params and child block, and render it.
|
95
|
+
|
96
|
+
2. As long as a name is qualified with at least one scope (i.e. `ModName::Foo()`) everything will work out, but if we say just `Foo()` then the only way I believe out of this is to handle it via method_missing, and let method_missing do a const_get on the method_name (which will return the class) and then render that component.
|
97
|
+
|
98
|
+
#### details
|
99
|
+
|
100
|
+
To define `self.Foo` in the same scope level as the class `Foo`, we need code like this:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
def register_component_dsl_method(component)
|
104
|
+
split_name = component.name && component.name.split('::')
|
105
|
+
return unless split_name && split_name.length > 2
|
106
|
+
component_name = split_name.last
|
107
|
+
parent = split_name.inject([Module]) { |nesting, next_const| nesting + [nesting.last.const_get(next_const)] }[-2]
|
108
|
+
class << parent
|
109
|
+
define_method component_name do |*args, &block|
|
110
|
+
React::RenderingContext.render(name, *args, &block)
|
111
|
+
end
|
112
|
+
define_method "#{component_name}_as_node" do |*args, &block|
|
113
|
+
React::Component.deprecation_warning("..._as_node is deprecated. Render component and then use the .node method instead")
|
114
|
+
send(component_name, *args, &block).node
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
module React
|
120
|
+
module Component
|
121
|
+
def self.included(base)
|
122
|
+
...
|
123
|
+
register_component_dsl_method(base.name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
The component's method_missing function will look like this:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
def method_missing(name, *args, &block)
|
133
|
+
if name =~ /_as_node$/
|
134
|
+
React::Component.deprecation_warning("..._as_node is deprecated. Render component and then use the .node method instead")
|
135
|
+
method_missing(name.gsub(/_as_node$/,""), *args, &block).node
|
136
|
+
else
|
137
|
+
component = const_get name if defined? name
|
138
|
+
React::RenderingContext.render(nil, component, *args, &block)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
### other related issues
|
144
|
+
|
145
|
+
The Kernel#p method conflicts with the <p> tag. However the p method can be invoked on any object so we are going to go ahead and use it, and deprecate the para method.
|