hyper-component 0.12.3 → 0.99.0
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 +5 -5
- data/.codeclimate.yml +27 -0
- data/.gitignore +42 -41
- data/.travis.yml +29 -0
- data/CHANGELOG.md +143 -0
- data/DOCS.md +1515 -0
- data/Gemfile +5 -2
- data/Gemfile.lock +244 -193
- data/LICENSE +5 -7
- data/README.md +49 -0
- data/Rakefile +40 -0
- data/hyper-component.gemspec +41 -31
- data/lib/hyper-component.rb +44 -9
- data/lib/rails-helpers/top_level_rails_component.rb +79 -0
- data/lib/react/api.rb +270 -0
- data/lib/react/callbacks.rb +42 -0
- data/lib/react/children.rb +38 -0
- data/lib/react/component.rb +189 -0
- data/lib/react/component/api.rb +70 -0
- data/lib/react/component/base.rb +13 -0
- data/lib/react/component/class_methods.rb +175 -0
- data/lib/react/component/dsl_instance_methods.rb +23 -0
- data/lib/react/component/params.rb +6 -0
- data/lib/react/component/props_wrapper.rb +90 -0
- data/lib/react/component/should_component_update.rb +99 -0
- data/lib/react/component/tags.rb +116 -0
- data/lib/react/config.rb +5 -0
- data/lib/react/element.rb +159 -0
- data/lib/react/event.rb +76 -0
- data/lib/react/ext/hash.rb +9 -0
- data/lib/react/ext/opal-jquery/element.rb +37 -0
- data/lib/react/ext/string.rb +8 -0
- data/lib/react/native_library.rb +87 -0
- data/lib/react/object.rb +15 -0
- data/lib/react/react-source-server.rb +3 -0
- data/lib/react/react-source.rb +17 -0
- data/lib/react/ref_callback.rb +31 -0
- data/lib/react/rendering_context.rb +149 -0
- data/lib/react/server.rb +19 -0
- data/lib/react/state_wrapper.rb +23 -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 +56 -0
- data/lib/react/test/rspec.rb +15 -0
- data/lib/react/test/session.rb +37 -0
- data/lib/react/test/utils.rb +71 -0
- data/lib/react/to_key.rb +26 -0
- data/lib/react/top_level.rb +110 -0
- data/lib/react/top_level_render.rb +28 -0
- data/lib/react/validator.rb +132 -0
- data/lib/reactive-ruby/component_loader.rb +43 -0
- data/lib/reactive-ruby/isomorphic_helpers.rb +233 -0
- data/lib/reactive-ruby/rails.rb +8 -0
- data/lib/reactive-ruby/rails/component_mount.rb +48 -0
- data/lib/reactive-ruby/rails/controller_helper.rb +14 -0
- data/lib/reactive-ruby/rails/railtie.rb +20 -0
- data/lib/reactive-ruby/serializers.rb +23 -0
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +46 -0
- data/lib/reactive-ruby/server_rendering/hyper_asset_container.rb +46 -0
- data/lib/{hyperloop/component → reactive-ruby}/version.rb +1 -1
- data/lib/reactrb/auto-import.rb +27 -0
- data/misc/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +3 -0
- data/misc/generators/reactive_ruby/test_app/templates/assets/javascripts/server_rendering.js +5 -0
- data/misc/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +2 -0
- data/misc/generators/reactive_ruby/test_app/templates/boot.rb.erb +6 -0
- data/misc/generators/reactive_ruby/test_app/templates/script/rails +5 -0
- data/misc/generators/reactive_ruby/test_app/templates/test_application.rb.erb +13 -0
- data/misc/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
- data/misc/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
- data/misc/generators/reactive_ruby/test_app/templates/views/layouts/test_layout.html.erb +0 -0
- data/misc/generators/reactive_ruby/test_app/test_app_generator.rb +121 -0
- data/misc/how-component-name-lookup-works.md +145 -0
- data/misc/hyperloop-logo-small-pink.png +0 -0
- data/misc/logo1.png +0 -0
- data/misc/logo2.png +0 -0
- data/misc/logo3.png +0 -0
- data/path_release_steps.md +9 -0
- metadata +260 -37
- data/CODE_OF_CONDUCT.md +0 -49
data/lib/react/event.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module React
|
2
|
+
class Event
|
3
|
+
include Native
|
4
|
+
alias_native :bubbles, :bubbles
|
5
|
+
alias_native :cancelable, :cancelable
|
6
|
+
alias_native :current_target, :currentTarget
|
7
|
+
alias_native :default_prevented, :defaultPrevented
|
8
|
+
alias_native :event_phase, :eventPhase
|
9
|
+
alias_native :is_trusted?, :isTrusted
|
10
|
+
alias_native :native_event, :nativeEvent
|
11
|
+
alias_native :target, :target
|
12
|
+
alias_native :timestamp, :timeStamp
|
13
|
+
alias_native :event_type, :type
|
14
|
+
alias_native :prevent_default, :preventDefault
|
15
|
+
alias_native :stop_propagation, :stopPropagation
|
16
|
+
# Clipboard
|
17
|
+
alias_native :clipboard_data, :clipboardData
|
18
|
+
# Keyboard
|
19
|
+
alias_native :alt_key, :altKey
|
20
|
+
alias_native :char_code, :charCode
|
21
|
+
alias_native :ctrl_key, :ctrlKey
|
22
|
+
alias_native :get_modifier_state, :getModifierState
|
23
|
+
alias_native :key, :key
|
24
|
+
alias_native :key_code, :keyCode
|
25
|
+
alias_native :locale, :locale
|
26
|
+
alias_native :location, :location
|
27
|
+
alias_native :meta_key, :metaKey
|
28
|
+
alias_native :repeat, :repeat
|
29
|
+
alias_native :shift_key, :shiftKey
|
30
|
+
alias_native :which, :which
|
31
|
+
# Focus
|
32
|
+
alias_native :related_target, :relatedTarget
|
33
|
+
# Mouse
|
34
|
+
# aliased above: alias_native :alt_key, :altKey
|
35
|
+
alias_native :button, :button
|
36
|
+
alias_native :buttons, :buttons
|
37
|
+
alias_native :client_x, :clientX
|
38
|
+
alias_native :client_y, :clientY
|
39
|
+
# aliased above: alias_native :ctrl_key, :ctrlKey
|
40
|
+
alias_native :get_modifier_state, :getModifierState
|
41
|
+
# aliased above: alias_native :meta_key, :metaKey
|
42
|
+
alias_native :page_x, :pageX
|
43
|
+
alias_native :page_y, :pageY
|
44
|
+
# aliased above: alias_native :related_target, :relatedTarget
|
45
|
+
alias_native :screen_x, :screen_x
|
46
|
+
alias_native :screen_y, :screen_y
|
47
|
+
# aliased above: alias_native :shift_key, :shift_key
|
48
|
+
# Touch
|
49
|
+
# aliased above: alias_native :alt_key, :altKey
|
50
|
+
alias_native :changed_touches, :changedTouches
|
51
|
+
# aliased above: alias_native :ctrl_key, :ctrlKey
|
52
|
+
# aliased above: alias_native :get_modifier_state, :getModifierState
|
53
|
+
# aliased above: alias_native :meta_key, :metaKey
|
54
|
+
# aliased above: alias_native :shift_key, :shiftKey
|
55
|
+
alias_native :target_touches, :targetTouches
|
56
|
+
alias_native :touches, :touches
|
57
|
+
# UI
|
58
|
+
alias_native :detail, :detail
|
59
|
+
alias_native :view, :view
|
60
|
+
# Wheel
|
61
|
+
alias_native :delta_mode, :deltaMode
|
62
|
+
alias_native :delta_x, :deltaX
|
63
|
+
alias_native :delta_y, :deltaY
|
64
|
+
alias_native :delta_z, :deltaZ
|
65
|
+
|
66
|
+
BUILT_IN_EVENTS = %w{onCopy onCut onPaste onKeyDown onKeyPress onKeyUp
|
67
|
+
onFocus onBlur onChange onInput onSubmit onClick onContextMenu onDoubleClick onDrag
|
68
|
+
onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop
|
69
|
+
onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver
|
70
|
+
onMouseUp onSelect onTouchCancel onTouchEnd onTouchMove onTouchStart onScroll onWheel}
|
71
|
+
|
72
|
+
def initialize(native_event)
|
73
|
+
@native = native_event
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Element.instance_eval do
|
2
|
+
def self.find(selector)
|
3
|
+
selector = begin
|
4
|
+
selector.dom_node
|
5
|
+
rescue
|
6
|
+
selector
|
7
|
+
end if `#{selector}.$dom_node !== undefined`
|
8
|
+
`$(#{selector})`
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.[](selector)
|
12
|
+
find(selector)
|
13
|
+
end
|
14
|
+
|
15
|
+
define_method :render do |container = nil, params = {}, &block|
|
16
|
+
if `#{self.to_n}._reactrb_component_class === undefined`
|
17
|
+
`#{self.to_n}._reactrb_component_class = #{Class.new(Hyperloop::Component)}`
|
18
|
+
end
|
19
|
+
klass = `#{self.to_n}._reactrb_component_class`
|
20
|
+
klass.class_eval do
|
21
|
+
render(container, params, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
React.render(React.create_element(`#{self.to_n}._reactrb_component_class`), self)
|
25
|
+
end
|
26
|
+
|
27
|
+
# mount_components is useful for dynamically generated page segments for example
|
28
|
+
# see react-rails documentation for more details
|
29
|
+
|
30
|
+
%x{
|
31
|
+
$.fn.mount_components = function() {
|
32
|
+
this.each(function(e) { ReactRailsUJS.mountComponents(e[0]) })
|
33
|
+
return this;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
Element.expose :mount_components
|
37
|
+
end if Object.const_defined?('Element')
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module React
|
2
|
+
# NativeLibrary handles importing JS libraries. Importing native components is handled
|
3
|
+
# by the React::Base. It also provides several methods used by auto-import.rb
|
4
|
+
|
5
|
+
# A NativeLibrary is simply a wrapper that holds the name of the native js library.
|
6
|
+
# It responds to const_missing and method_missing by looking up objects within the js library.
|
7
|
+
# If the object is a react component it is wrapped by a reactrb component class, otherwise
|
8
|
+
# a nested NativeLibrary is returned.
|
9
|
+
|
10
|
+
# Two macros are provided: imports (for naming the native library) and renames which allows
|
11
|
+
# the members of a library to be given different names within the ruby name space.
|
12
|
+
|
13
|
+
# Public methods used by auto-import.rb are import_const_from_native and find_and_render_component
|
14
|
+
class NativeLibrary
|
15
|
+
class << self
|
16
|
+
def imports(native_name)
|
17
|
+
@native_prefix = "#{native_name}."
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def rename(rename_list)
|
22
|
+
# rename_list is a hash in the form: native_name => ruby_name, native_name => ruby_name
|
23
|
+
rename_list.each do |js_name, ruby_name|
|
24
|
+
native_name = lookup_native_name(js_name)
|
25
|
+
if lookup_native_name(js_name)
|
26
|
+
create_component_wrapper(self, native_name, ruby_name) ||
|
27
|
+
create_library_wrapper(self, native_name, ruby_name)
|
28
|
+
else
|
29
|
+
raise "class #{name} < React::NativeLibrary could not import #{js_name}. "\
|
30
|
+
"Native value #{scope_native_name(js_name)} is undefined."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def import_const_from_native(klass, const_name, create_library)
|
36
|
+
native_name = lookup_native_name(const_name) ||
|
37
|
+
lookup_native_name(const_name[0].downcase + const_name[1..-1])
|
38
|
+
native_name && (
|
39
|
+
create_component_wrapper(klass, native_name, const_name) || (
|
40
|
+
create_library &&
|
41
|
+
create_library_wrapper(klass, native_name, const_name)))
|
42
|
+
end
|
43
|
+
|
44
|
+
def const_missing(const_name)
|
45
|
+
import_const_from_native(self, const_name, true) || super
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(method, *args, &block)
|
49
|
+
component_class = const_get(method) if const_defined?(method, false)
|
50
|
+
component_class ||= import_const_from_native(self, method, false)
|
51
|
+
raise 'could not import a react component named: '\
|
52
|
+
"#{scope_native_name method}" unless component_class
|
53
|
+
React::RenderingContext.render(component_class, *args, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def lookup_native_name(js_name)
|
59
|
+
native_name = scope_native_name(js_name)
|
60
|
+
`eval(#{native_name}) !== undefined && native_name`
|
61
|
+
# rubocop:disable Lint/RescueException # that is what eval raises in Opal >= 0.10.
|
62
|
+
rescue Exception
|
63
|
+
nil
|
64
|
+
# rubocop:enable Lint/RescueException
|
65
|
+
end
|
66
|
+
|
67
|
+
def scope_native_name(js_name)
|
68
|
+
"#{@native_prefix}#{js_name}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_component_wrapper(klass, native_name, ruby_name)
|
72
|
+
if React::API.native_react_component?(native_name)
|
73
|
+
new_klass = klass.const_set ruby_name, Class.new
|
74
|
+
new_klass.class_eval do
|
75
|
+
include Hyperloop::Component::Mixin
|
76
|
+
imports native_name
|
77
|
+
end
|
78
|
+
new_klass
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_library_wrapper(klass, native_name, ruby_name)
|
83
|
+
klass.const_set ruby_name, Class.new(React::NativeLibrary).imports(native_name)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/react/object.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Lazy load HTML tag constants in the form DIV or A
|
2
|
+
# This is needed to allow for a HAML expression like this DIV.my_class
|
3
|
+
class Object
|
4
|
+
class << self
|
5
|
+
alias _reactrb_tag_original_const_missing const_missing
|
6
|
+
|
7
|
+
def const_missing(const_name)
|
8
|
+
# Opal uses const_missing to initially define things,
|
9
|
+
# so we always call the original, and respond to the exception
|
10
|
+
_reactrb_tag_original_const_missing(const_name)
|
11
|
+
rescue StandardError => e
|
12
|
+
React::Component::Tags.html_tag_class_for(const_name) || raise(e)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
if RUBY_ENGINE == 'opal'
|
2
|
+
%x{
|
3
|
+
var ms = [
|
4
|
+
"Warning: `react/react-source` is deprecated, ",
|
5
|
+
"use `react/react-source-browser` or `react/react-source-server` instead."
|
6
|
+
]
|
7
|
+
console.error(ms.join(""));
|
8
|
+
}
|
9
|
+
require 'react.js'
|
10
|
+
require "react-server.js"
|
11
|
+
else
|
12
|
+
require "react/config"
|
13
|
+
require "react/rails/asset_variant"
|
14
|
+
variant = Hyperloop.env.production? ? 'production' : 'development'
|
15
|
+
react_directory = React::Rails::AssetVariant.new({environment: variant}).react_directory
|
16
|
+
Opal.append_path react_directory.untaint
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'react/native_library'
|
2
|
+
|
3
|
+
module React
|
4
|
+
module RefsCallbackExtension
|
5
|
+
end
|
6
|
+
|
7
|
+
class API
|
8
|
+
class << self
|
9
|
+
alias :orig_convert_props :convert_props
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.convert_props(properties)
|
13
|
+
props = self.orig_convert_props(properties)
|
14
|
+
props.map do |key, value|
|
15
|
+
if key == "ref" && value.is_a?(Proc)
|
16
|
+
new_proc = Proc.new do |native_inst|
|
17
|
+
if `#{native_inst} !== null && #{native_inst}.__opalInstance !== undefined && #{native_inst}.__opalInstance !== null`
|
18
|
+
value.call(`#{native_inst}.__opalInstance`)
|
19
|
+
elsif `#{native_inst} !== null && ReactDOM.findDOMNode !== undefined && #{native_inst}.nodeType === undefined`
|
20
|
+
value.call(`ReactDOM.findDOMNode(#{native_inst})`) # react >= v0.15.`)
|
21
|
+
else
|
22
|
+
value.call(native_inst)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
props[key] = new_proc
|
26
|
+
end
|
27
|
+
end
|
28
|
+
props
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module React
|
2
|
+
class RenderingContext
|
3
|
+
class << self
|
4
|
+
attr_accessor :waiting_on_resources
|
5
|
+
|
6
|
+
def render(name, *args, &block)
|
7
|
+
was_outer_most = !@not_outer_most
|
8
|
+
@not_outer_most = true
|
9
|
+
remove_nodes_from_args(args)
|
10
|
+
@buffer ||= [] unless @buffer
|
11
|
+
if block
|
12
|
+
element = build do
|
13
|
+
saved_waiting_on_resources = waiting_on_resources
|
14
|
+
self.waiting_on_resources = nil
|
15
|
+
run_child_block(name.nil?, &block)
|
16
|
+
if name
|
17
|
+
buffer = @buffer.dup
|
18
|
+
React::API.create_element(name, *args) { buffer }.tap do |element|
|
19
|
+
element.waiting_on_resources = saved_waiting_on_resources || !!buffer.detect { |e| e.waiting_on_resources if e.respond_to?(:waiting_on_resources) }
|
20
|
+
element.waiting_on_resources ||= waiting_on_resources if buffer.last.is_a?(String)
|
21
|
+
end
|
22
|
+
elsif @buffer.last.is_a? React::Element
|
23
|
+
@buffer.last.tap { |element| element.waiting_on_resources ||= saved_waiting_on_resources }
|
24
|
+
else
|
25
|
+
buffer_s = @buffer.last.to_s
|
26
|
+
React::RenderingContext.render(:span) { buffer_s }.tap { |element| element.waiting_on_resources = saved_waiting_on_resources }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
elsif name.is_a? React::Element
|
30
|
+
element = name
|
31
|
+
else
|
32
|
+
element = React::API.create_element(name, *args)
|
33
|
+
element.waiting_on_resources = waiting_on_resources
|
34
|
+
end
|
35
|
+
@buffer << element
|
36
|
+
self.waiting_on_resources = nil
|
37
|
+
element
|
38
|
+
ensure
|
39
|
+
@not_outer_most = @buffer = nil if was_outer_most
|
40
|
+
end
|
41
|
+
|
42
|
+
def build
|
43
|
+
current = @buffer
|
44
|
+
@buffer = []
|
45
|
+
return_val = yield @buffer
|
46
|
+
@buffer = current
|
47
|
+
return_val
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete(element)
|
51
|
+
@buffer.delete(element)
|
52
|
+
element
|
53
|
+
end
|
54
|
+
alias as_node delete
|
55
|
+
|
56
|
+
def rendered?(element)
|
57
|
+
@buffer.include? element
|
58
|
+
end
|
59
|
+
|
60
|
+
def replace(e1, e2)
|
61
|
+
@buffer[@buffer.index(e1)] = e2
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_nodes_from_args(args)
|
65
|
+
args[0].each do |key, value|
|
66
|
+
begin
|
67
|
+
value.delete if value.is_a?(Element) # deletes Element from buffer
|
68
|
+
rescue Exception
|
69
|
+
end
|
70
|
+
end if args[0] && args[0].is_a?(Hash)
|
71
|
+
end
|
72
|
+
|
73
|
+
# run_child_block gathers the element(s) generated by a child block.
|
74
|
+
# for example when rendering this div: div { "hello".span; "goodby".span }
|
75
|
+
# two child Elements will be generated.
|
76
|
+
#
|
77
|
+
# the final value of the block should either be
|
78
|
+
# 1 an object that responds to :acts_as_string?
|
79
|
+
# 2 a string,
|
80
|
+
# 3 an element that is NOT yet pushed on the rendering buffer
|
81
|
+
# 4 or the last element pushed on the buffer
|
82
|
+
#
|
83
|
+
# in case 1 we render a span
|
84
|
+
# in case 2 we automatically push the string onto the buffer
|
85
|
+
# in case 3 we also push the Element onto the buffer IF the buffer is empty
|
86
|
+
# case 4 requires no special processing
|
87
|
+
#
|
88
|
+
# Once we have taken care of these special cases we do a check IF we are in an
|
89
|
+
# outer rendering scope. In this case react only allows us to generate 1 Element
|
90
|
+
# so we insure that is the case, and also check to make sure that element in the buffer
|
91
|
+
# is the element returned
|
92
|
+
|
93
|
+
def run_child_block(is_outer_scope)
|
94
|
+
result = yield
|
95
|
+
if result.respond_to?(:acts_as_string?) && result.acts_as_string?
|
96
|
+
# hyper-mesh DummyValues respond to acts_as_string, and must
|
97
|
+
# be converted to spans INSIDE the parent, otherwise the waiting_on_resources
|
98
|
+
# flag will get set in the wrong context
|
99
|
+
React::RenderingContext.render(:span) { result.to_s }
|
100
|
+
elsif result.is_a?(String) || (result.is_a?(React::Element) && @buffer.empty?)
|
101
|
+
@buffer << result
|
102
|
+
end
|
103
|
+
raise_render_error(result) if is_outer_scope && @buffer != [result]
|
104
|
+
end
|
105
|
+
|
106
|
+
# heurestically raise a meaningful error based on the situation
|
107
|
+
|
108
|
+
def raise_render_error(result)
|
109
|
+
improper_render 'A different element was returned than was generated within the DSL.',
|
110
|
+
'Possibly improper use of Element#delete.' if @buffer.count == 1
|
111
|
+
improper_render "Instead #{@buffer.count} elements were generated.",
|
112
|
+
'Do you want to wrap your elements in a div?' if @buffer.count > 1
|
113
|
+
improper_render "Instead the component #{result} was returned.",
|
114
|
+
"Did you mean #{result}()?" if result.try :reactrb_component?
|
115
|
+
improper_render "Instead the #{result.class} #{result} was returned.",
|
116
|
+
'You may need to convert this to a string.'
|
117
|
+
end
|
118
|
+
|
119
|
+
def improper_render(message, solution)
|
120
|
+
raise "a component's render method must generate and return exactly 1 element or a string.\n"\
|
121
|
+
" #{message} #{solution}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class Object
|
128
|
+
[:span, :td, :th, :while_loading].each do |tag|
|
129
|
+
define_method(tag) do |*args, &block|
|
130
|
+
args.unshift(tag)
|
131
|
+
return send(*args, &block) if is_a? React::Component
|
132
|
+
React::RenderingContext.render(*args) { to_s }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def para(*args, &block)
|
137
|
+
args.unshift(:p)
|
138
|
+
return send(*args, &block) if is_a? React::Component
|
139
|
+
React::RenderingContext.render(*args) { to_s }
|
140
|
+
end
|
141
|
+
|
142
|
+
def br
|
143
|
+
return send(:br) if is_a? React::Component
|
144
|
+
React::RenderingContext.render(:span) do
|
145
|
+
React::RenderingContext.render(to_s)
|
146
|
+
React::RenderingContext.render(:br)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/react/server.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module React
|
2
|
+
module Server
|
3
|
+
def self.render_to_string(element)
|
4
|
+
if !(`typeof ReactDOMServer === 'undefined'`)
|
5
|
+
React::RenderingContext.build { `ReactDOMServer.renderToString(#{element.to_n})` } # v0.15+
|
6
|
+
else
|
7
|
+
raise "renderToString is not defined. In React >= v15 you must import it with ReactDOMServer"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.render_to_static_markup(element)
|
12
|
+
if !(`typeof ReactDOMServer === 'undefined'`)
|
13
|
+
React::RenderingContext.build { `ReactDOMServer.renderToStaticMarkup(#{element.to_n})` } # v0.15+
|
14
|
+
else
|
15
|
+
raise "renderToStaticMarkup is not defined. In React >= v15 you must import it with ReactDOMServer"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|