Skip to content

Commit 6882280

Browse files
committed
ready to test native element rewrite
1 parent 1ad396c commit 6882280

File tree

10 files changed

+93
-47
lines changed

10 files changed

+93
-47
lines changed

ruby/hyper-component/Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ gem 'hyper-state', path: '../hyper-state'
77
unless ENV['OPAL_VERSION']&.match("0.11")
88
gem 'opal-browser', git: 'https://github.com/opal/opal-browser'
99
end
10+
gem 'hyper-trace', path: '../hyper-trace'
1011

1112
#gem 'puma', '~> 3.11.0' # As of adding, version 3.12.0 isn't working so we are locking
1213
gemspec

ruby/hyper-component/lib/hyperstack/component/children.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def each(&block)
2222
%x{
2323
React.Children.forEach(#{@children}, function(context){
2424
#{
25-
element = Element.new(`context`)
25+
element = Element.new(`context`, :wrap_child)
2626
block.call(element)
2727
collection << element
2828
}

ruby/hyper-component/lib/hyperstack/component/element.rb

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,73 @@ module Component
1515
# by using method missing
1616
#
1717
class Element
18-
include Native::Wrapper
1918

20-
alias_native :element_type, :type
21-
alias_native :props, :props
19+
# $$typeof: Symbol(react.element)
20+
# key: null
21+
# props: {}
22+
# ref: null
23+
# type: "div"
24+
# _ _owner: null
2225

23-
attr_reader :type
26+
attr_reader :type
27+
28+
attr_reader :element_type # change this so name does not conflict - change to element type
2429
attr_reader :properties
2530
attr_reader :block
31+
attr_reader :to_n
2632

2733
attr_accessor :waiting_on_resources
2834

29-
def initialize(native_element, type = nil, properties = {}, block = nil)
30-
@type = type
35+
def set_native_attributes(native_element)
36+
@key = `native_element.key`
37+
@props = `native_element.props`
38+
@ref = `native_element.ref`
39+
@type = `native_element.type`
40+
@_owner = `native_element._owner`
41+
@_props_as_hash = Hash.new(@props)
42+
end
43+
44+
def props
45+
@_props_as_hash
46+
end
47+
48+
def convert_string(native_element, element_type, props, block)
49+
return native_element unless `native_element['$is_a?']`
50+
return native_element unless native_element.is_a? String
51+
raise "Internal Error Element.new called with string, but non-nil props or block" if !props.empty? || block
52+
53+
if element_type == :wrap_child
54+
`React.createElement(React.Fragment, null, [native_element])`
55+
else
56+
`React.createElement(native_element, null)`
57+
end
58+
end
59+
60+
def initialize(native_element, element_type = nil, properties = {}, block = nil)
61+
62+
native_element = convert_string(native_element, element_type, properties, block)
63+
@element_type = element_type unless element_type == :wrap_child
3164
@properties = (`typeof #{properties} === 'undefined'` ? nil : properties) || {}
3265
@block = block
33-
@native = native_element
66+
`#{self}.$$typeof = native_element.$$typeof`
67+
@to_n = self
68+
set_native_attributes(native_element)
69+
rescue Exception
70+
end
71+
72+
def children
73+
`#{@props}.children`
3474
end
3575

3676
def _update_ref(x)
37-
@ref = x
77+
@_ref = x
3878
@_child_element._update_ref(x) if @_child_element
3979
end
4080

41-
def ref
42-
return @ref if @ref
43-
raise("The instance of #{self.type} has not been mounted yet") if properties[:ref]
44-
raise("Attempt to get a ref on #{self.type} which is a static component.")
81+
def ref # this will not conflict with React's on ref attribute okay because its $ref!!!
82+
return @_ref if @_ref
83+
raise("The instance of #{self.element_type} has not been mounted yet") if properties[:ref]
84+
raise("Attempt to get a ref on #{self.element_type} which is a static component.")
4585
end
4686

4787
def dom_node
@@ -57,7 +97,7 @@ def on(*event_names, &block)
5797
merge_event_prop!(event_name, &block)
5898
any_found = true
5999
end
60-
@native = `React.cloneElement(#{@native}, #{@properties.shallow_to_n})` if any_found
100+
set_native_attributes(`React.cloneElement(#{self}, #{@properties.shallow_to_n})`) if any_found
61101
self
62102
end
63103

@@ -69,22 +109,23 @@ def render(*props)
69109
if props.empty?
70110
Hyperstack::Internal::Component::RenderingContext.render(self)
71111
else
72-
props = Hyperstack::Internal::Component::ReactWrapper.convert_props(@type, @properties, *props)
112+
props = Hyperstack::Internal::Component::ReactWrapper.convert_props(element_type, @properties, *props)
73113
@_child_element = Hyperstack::Internal::Component::RenderingContext.render(
74-
Element.new(`React.cloneElement(#{@native}, #{props.shallow_to_n})`,
75-
type, props, block)
114+
Element.new(`React.cloneElement(#{self}, #{props.shallow_to_n})`,
115+
element_type, props, block)
76116
)
77117
end
78118
end
79119

80120
# Delete (remove) element from rendering context, the element may later be added back in
81121
# using the render method.
82122

83-
def delete
123+
def ~
84124
Hyperstack::Internal::Component::RenderingContext.delete(self)
85125
end
86126
# Deprecated version of delete method
87-
alias as_node delete
127+
alias as_node ~
128+
alias delete ~
88129

89130
private
90131

@@ -109,7 +150,7 @@ def merge_event_prop!(event_name, &block)
109150
merge_built_in_event_prop! name, &block
110151
elsif event_name == :enter
111152
merge_built_in_event_prop!('onKeyDown') { |evt| yield(evt) if evt.key_code == 13 }
112-
elsif @type.instance_variable_get('@native_import')
153+
elsif element_type.instance_variable_get('@native_import')
113154
merge_component_event_prop! name, &block
114155
else
115156
merge_component_event_prop! "on_#{event_name}", &block

ruby/hyper-component/lib/hyperstack/internal/component/class_methods.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def before_receive_props(*args, &block)
5050
def render(container = nil, params = {}, &block)
5151
Tags.included(self)
5252
if container
53-
container = container.type if container.is_a? Hyperstack::Component::Element
53+
container = container.element_type if container.is_a? Hyperstack::Component::Element
5454
define_method(:__hyperstack_component_render) do
5555
__hyperstack_component_select_wrappers do
5656
RenderingContext.render(container, params) do

ruby/hyper-component/lib/hyperstack/internal/component/haml.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def method_missing(class_name, args = {}, &new_block)
2828
self,
2929
Hyperstack::Internal::Component::RenderingContext.build do
3030
Hyperstack::Internal::Component::RenderingContext.render(
31-
type, @properties, args, class: haml_class_name(class_name), &new_block
31+
element_type, @properties, args, class: haml_class_name(class_name), &new_block
3232
)
3333
end
3434
)

ruby/hyper-component/lib/hyperstack/internal/component/rendering_context.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@ def quiet_test(component)
1919
raise NotQuiet.new("#{component} is waiting on resources")
2020
end
2121

22+
def render_string(string)
23+
@buffer ||= []
24+
@buffer << string
25+
end
26+
2227
def render(name, *args, &block)
2328
was_outer_most = !@not_outer_most
2429
@not_outer_most = true
2530
remove_nodes_from_args(args)
26-
@buffer ||= [] unless @buffer
31+
@buffer ||= [] #unless @buffer
2732
if block
2833
element = build do
2934
saved_waiting_on_resources = nil #waiting_on_resources what was the purpose of this its used below to or in with the current elements waiting_for_resources
@@ -200,10 +205,10 @@ def para(*args, &block)
200205
def br
201206
# see above comment
202207
return send(:br) if respond_to?(:hyper_component?) && hyper_component?
203-
204-
Hyperstack::Internal::Component::RenderingContext.render(:span) do
205-
Hyperstack::Internal::Component::RenderingContext.render(to_s)
206-
Hyperstack::Internal::Component::RenderingContext.render(:br)
208+
209+
Hyperstack::Internal::Component::RenderingContext.render(Hyperstack::Internal::Component::Tags::FRAGMENT) do
210+
Hyperstack::Internal::Component::RenderingContext.render(Hyperstack::Internal::Component::Tags::FRAGMENT) { to_s }
211+
Hyperstack::Internal::Component::RenderingContext.render(Hyperstack::Internal::Component::Tags::BR)
207212
end
208213
end
209214

ruby/hyper-component/spec/client_features/children_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def self.get_children
2626

2727
it 'is enumerable' do
2828
expect_evaluate_ruby do
29-
InitTest.get_children.map { |elem| elem.element_type }
29+
InitTest.get_children.map { |elem| elem.type }
3030
end.to eq(['a', 'li'])
3131
end
3232

@@ -40,7 +40,7 @@ def self.get_children
4040
describe '#each' do
4141
it 'returns an array of elements' do
4242
expect_evaluate_ruby do
43-
nodes = InitTest.get_children.each { |elem| elem.element_type }
43+
nodes = InitTest.get_children.each { |elem| elem.type }
4444
[nodes.class.name, nodes.map(&:class)]
4545
end.to eq(["Array", ["Hyperstack::Component::Element", "Hyperstack::Component::Element"]])
4646
end
@@ -80,7 +80,7 @@ def self.get_children
8080

8181
it 'is enumerable containing single element' do
8282
expect_evaluate_ruby do
83-
InitTest.get_children.map { |elem| elem.element_type }
83+
InitTest.get_children.map { |elem| elem.type }
8484
end.to eq(["a"])
8585
end
8686

@@ -117,7 +117,7 @@ def self.get_children
117117

118118
it 'is enumerable containing no elements' do
119119
expect_evaluate_ruby do
120-
InitTest.get_children.map { |elem| elem.element_type }
120+
InitTest.get_children.map { |elem| elem.type }
121121
end.to eq([])
122122
end
123123

ruby/hyper-component/spec/client_features/component_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ class Bar < Hyperloop::Component
297297
end
298298
class Foo < Hyperloop::Component
299299
render do
300-
Bar.insert_element(p: "param") { "child"}
300+
Bar.insert_element(p: "param") { "child" }
301301
end
302302
end
303303
end
@@ -859,7 +859,7 @@ class Foo
859859
end
860860
expect_evaluate_ruby("CHILDREN.class.name").to eq('Hyperstack::Component::Children')
861861
expect_evaluate_ruby("CHILDREN.count").to eq(2)
862-
expect_evaluate_ruby("CHILDREN.map(&:element_type)").to eq(['a', 'li'])
862+
expect_evaluate_ruby("CHILDREN.map(&:type)").to eq(['a', 'li'])
863863
end
864864

865865
it 'returns an empty Enumerator if there are no children' do

ruby/hyper-component/spec/client_features/dsl_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class Foo
107107
end
108108
expect(
109109
find(
110-
'div[data-react-class="Hyperstack.Internal.Component.TopLevelRailsComponent"] div.foo span'
110+
'div[data-react-class="Hyperstack.Internal.Component.TopLevelRailsComponent"] div.foo'
111111
)['innerHTML']
112112
).to eq 'hello<br>'
113113
end
@@ -238,22 +238,22 @@ class Foo
238238
expect(page.body[-60..-19]).to include('<span class="the-class">hello</span>')
239239
end
240240

241-
it "can generate a unrendered node using the .as_node method" do # DIV { "hello" }.as_node
241+
it "can generate a unrendered node using the ~ operator" do
242242
mount 'Foo' do
243243
class Foo
244244
include Hyperstack::Component
245245
render do
246-
SPAN(data: {size: 12}) { "hello".span.as_node.class.name }.as_node.render
246+
(~SPAN(data: {size: 12}) { (~"hello".span).class.name }).render
247247
end
248248
end
249249
end
250250
expect(page.body[-80..-19]).to include('<span data-size="12">Hyperstack::Component::Element</span>')
251251
end
252252

253-
it "the delete method (alias as_node) removes the node from the render buffer" do
253+
it "~ operator removes the node from the render buffer" do
254254
mount 'Foo' do
255255
class Foo < Hyperloop::Component
256-
render { "hello".span; "goodby".span.delete }
256+
render { "hello".span; ~"goodby".span }
257257
end
258258
end
259259
expect(find('span').text).to eq('hello')

ruby/hyper-component/spec/client_features/react_spec.rb

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
end
1212

1313
it "should return false is passed a non React element" do
14-
1514
expect_evaluate_ruby do
1615
element = Hyperstack::Component::Element.new(JS.call(:eval, "{}"))
1716
Hyperstack::Component::ReactAPI.is_valid_element?(element)
@@ -35,7 +34,7 @@
3534
ELEMENT = Hyperstack::Component::ReactAPI.create_element('div') { "lorem ipsum" }
3635
end
3736
expect_evaluate_ruby("Hyperstack::Component::ReactAPI.is_valid_element?(ELEMENT)").to eq(true)
38-
expect_evaluate_ruby("ELEMENT.props.children").to eq("lorem ipsum")
37+
expect_evaluate_ruby("ELEMENT.children").to eq("lorem ipsum")
3938
end
4039

4140
it "should create a valid element with children as array when block yield Array of element" do
@@ -46,7 +45,7 @@
4645
end
4746
end
4847
expect_evaluate_ruby("Hyperstack::Component::ReactAPI.is_valid_element?(ELEMENT)").to eq(true)
49-
expect_evaluate_ruby("ELEMENT.props.children.length").to eq(3)
48+
expect_evaluate_ruby("ELEMENT.children.length").to eq(3)
5049
end
5150

5251
it "should render element with children as array when block yield Array of element" do
@@ -88,7 +87,7 @@ def props
8887
true
8988
end
9089
expect_evaluate_ruby("INSTANCE.props[:children].is_a?(Array)").to be_falsy
91-
expect_evaluate_ruby("INSTANCE.props[:children][:type]").to eq("span")
90+
expect_evaluate_ruby("INSTANCE.props[:children].type").to eq("span")
9291
end
9392

9493
it "should render element with more than one children correctly" do
@@ -116,7 +115,7 @@ def props
116115
param :foo
117116
end
118117
element = Hyperstack::Component::ReactAPI.create_element(Foo, foo: "bar")
119-
element.props.foo
118+
element.props[:foo]
120119
end.to eq("bar")
121120
end
122121

@@ -180,23 +179,23 @@ def self.count
180179

181180
expect_evaluate_ruby do
182181
element = Hyperstack::Component::ReactAPI.create_element("div", class_name: "foo")
183-
element.props.className
182+
element.props[:className]
184183
end.to eq("foo")
185184
end
186185

187186
it "should allow custom property" do
188187

189188
expect_evaluate_ruby do
190189
element = Hyperstack::Component::ReactAPI.create_element("div", foo: "bar")
191-
element.props.foo
190+
element.props[:foo]
192191
end.to eq("bar")
193192
end
194193

195194
it "should not camel-case custom property" do
196195

197196
expect_evaluate_ruby do
198197
element = Hyperstack::Component::ReactAPI.create_element("div", foo_bar: "foo")
199-
element.props.foo_bar
198+
element.props[:foo_bar]
200199
end.to eq("foo")
201200
end
202201
end
@@ -206,7 +205,7 @@ def self.count
206205

207206
expect_evaluate_ruby do
208207
element = Hyperstack::Component::ReactAPI.create_element("div", class_name: "foo bar")
209-
element.props.className
208+
element.props[:className]
210209
end.to eq("foo bar")
211210
end
212211
end

0 commit comments

Comments
 (0)