isomorfeus-react 16.8.9 → 16.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/lib/browser/delegate_native.rb +70 -0
  4. data/lib/browser/element.rb +176 -0
  5. data/lib/browser/element/canvas.rb +17 -0
  6. data/lib/browser/element/media.rb +78 -0
  7. data/lib/browser/event.rb +92 -0
  8. data/lib/browser/event_target.rb +39 -0
  9. data/lib/browser/file_list.rb +125 -0
  10. data/lib/browser/iterable.rb +15 -0
  11. data/lib/isomorfeus-react-material-ui.rb +1 -31
  12. data/lib/isomorfeus-react.rb +112 -5
  13. data/lib/isomorfeus/execution_environment.rb +8 -2
  14. data/lib/isomorfeus/top_level_browser.rb +1 -1
  15. data/lib/lucid_app/mixin.rb +1 -1
  16. data/lib/lucid_component/app_store_defaults.rb +36 -0
  17. data/lib/lucid_component/app_store_proxy.rb +40 -0
  18. data/lib/lucid_component/class_store_proxy.rb +43 -0
  19. data/lib/lucid_component/component_class_store_defaults.rb +38 -0
  20. data/lib/lucid_component/component_instance_store_defaults.rb +35 -0
  21. data/lib/lucid_component/initializer.rb +3 -3
  22. data/lib/lucid_component/instance_store_proxy.rb +47 -0
  23. data/lib/lucid_component/mixin.rb +1 -1
  24. data/lib/lucid_component/reducers.rb +46 -0
  25. data/lib/lucid_component/store_api.rb +38 -0
  26. data/lib/lucid_material/app/mixin.rb +1 -1
  27. data/lib/lucid_material/component/mixin.rb +1 -1
  28. data/lib/react.rb +1 -2
  29. data/lib/react/component/api.rb +4 -0
  30. data/lib/react/component/features.rb +5 -1
  31. data/lib/react/component/mixin.rb +1 -1
  32. data/lib/react/component/props.rb +1 -1
  33. data/lib/react/function_component/api.rb +5 -25
  34. data/lib/react/pure_component/mixin.rb +1 -1
  35. data/lib/react/synthetic_event.rb +3 -3
  36. data/lib/react/version.rb +1 -1
  37. data/lib/react_dom.rb +1 -1
  38. metadata +22 -36
  39. data/lib/isomorfeus-react-base.rb +0 -57
  40. data/lib/isomorfeus-react-component.rb +0 -20
  41. data/lib/isomorfeus-react-lucid.rb +0 -39
  42. data/lib/isomorfeus-react-redux-component.rb +0 -25
  43. data/lib/react/redux_component/api.rb +0 -40
  44. data/lib/react/redux_component/app_store_defaults.rb +0 -38
  45. data/lib/react/redux_component/app_store_proxy.rb +0 -43
  46. data/lib/react/redux_component/base.rb +0 -9
  47. data/lib/react/redux_component/class_store_proxy.rb +0 -46
  48. data/lib/react/redux_component/component_class_store_defaults.rb +0 -40
  49. data/lib/react/redux_component/component_instance_store_defaults.rb +0 -37
  50. data/lib/react/redux_component/initializer.rb +0 -14
  51. data/lib/react/redux_component/instance_store_proxy.rb +0 -50
  52. data/lib/react/redux_component/mixin.rb +0 -19
  53. data/lib/react/redux_component/native_component_constructor.rb +0 -144
  54. data/lib/react/redux_component/reducers.rb +0 -48
@@ -0,0 +1,43 @@
1
+ module LucidComponent
2
+ class ClassStoreProxy
3
+ def initialize(component_instance, access_key = 'state')
4
+ @native_component_instance = component_instance.to_n
5
+ @component_instance = component_instance
6
+ @component_name = component_instance.class.to_s
7
+ @access_key = access_key
8
+ end
9
+
10
+ def method_missing(key, *args, &block)
11
+ @native_component_instance.JS.register_used_store_path(['component_class_state', @component_name, key])
12
+ if `args.length > 0`
13
+ # set class state, simply a dispatch
14
+ action = { type: 'COMPONENT_CLASS_STATE', class: @component_name, name: (`key.endsWith('=')` ? key.chop : key), value: args[0] }
15
+ Isomorfeus.store.dispatch(action)
16
+ else
17
+ # get class state
18
+ # check if we have a component local state value
19
+ if @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:component_class_state].JS[@component_name] &&
20
+ @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:component_class_state].JS[@component_name].JS.hasOwnProperty(key)
21
+ return @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:component_class_state].JS[@component_name].JS[key]
22
+ elsif @component_instance.class.default_class_store_defined && @component_instance.class.class_store.to_h.key?(key)
23
+ # check if a default value was given
24
+ return @component_instance.class.class_store.to_h[key]
25
+ end
26
+ # otherwise return nil
27
+ return nil
28
+ end
29
+ end
30
+
31
+ def dispatch(action)
32
+ Isomorfeus.store.dispatch(action)
33
+ end
34
+
35
+ def subscribe(&block)
36
+ Isomorfeus.store.subscribe(&block)
37
+ end
38
+
39
+ def unsubscribe(unsubscriber)
40
+ `unsubscriber()`
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ module LucidComponent
2
+ class ComponentClassStoreDefaults
3
+ def initialize(state, component_name)
4
+ @state = state
5
+ @component_name = component_name
6
+ if @state.isomorfeus_store
7
+ @state.isomorfeus_store.merge!(component_class_state: { @component_name => {} })
8
+ else
9
+ @state.isomorfeus_store = { component_class_state: { @component_name => {} } }
10
+ end
11
+ end
12
+
13
+ def method_missing(key, *args, &block)
14
+ if `args.length > 0`
15
+ # set initial class state
16
+ key = key.chop if `key.endsWith('=')`
17
+ @state.isomorfeus_store[:component_class_state][@component_name][key] = args[0]
18
+ current_state = Isomorfeus.store.get_state
19
+ if !(current_state[:component_class_state].key?(@component_name) && current_state[:component_class_state][@component_name].key?(key))
20
+ Isomorfeus.store.dispatch(type: 'COMPONENT_CLASS_STATE', class: @component_name, name: key, value: args[0])
21
+ end
22
+ else
23
+ # get class state
24
+
25
+ # check if we have a component local state value
26
+
27
+ if @state.isomorfeus_store[:component_class_state][@component_name].key?(key)
28
+ return @state.isomorfeus_store[:component_class_state][@component_name][key]
29
+ end
30
+ end
31
+ nil
32
+ end
33
+
34
+ def to_h
35
+ @state.isomorfeus_store[:component_class_state][@component_name]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ module LucidComponent
2
+ class ComponentInstanceStoreDefaults
3
+ def initialize(state, component_name)
4
+ @state = {}
5
+ @component_name = component_name
6
+ end
7
+
8
+ def method_missing(key, *args, &block)
9
+ if `args.length > 0`
10
+ # set initial class state
11
+ key = key.chop if `key.endsWith('=')`
12
+ @state[key] = args[0]
13
+ current_state = Isomorfeus.store.get_state
14
+ if !(current_state[:component_state].key?(@component_name) &&
15
+ current_state[:component_state][@component_name].key?(:instance_defaults) &&
16
+ current_state[:component_state][@component_name][:instance_defaults].key?(key))
17
+ Isomorfeus.store.dispatch(type: 'COMPONENT_CLASS_STATE', class: @component_name, name: :instance_defaults, value: { key => args[0]})
18
+ end
19
+ else
20
+ # get class state
21
+
22
+ # check if we have a component local state value
23
+
24
+ if @state.key?(key)
25
+ return @state[key]
26
+ end
27
+ end
28
+ nil
29
+ end
30
+
31
+ def to_h
32
+ @state
33
+ end
34
+ end
35
+ end
@@ -2,11 +2,11 @@ module LucidComponent
2
2
  module Initializer
3
3
  def initialize(native_component)
4
4
  @native = native_component
5
- @app_store = `Opal.React.ReduxComponent.AppStoreProxy.$new(#{self}, 'props')`
6
- @class_store = `Opal.React.ReduxComponent.ClassStoreProxy.$new(#{self}, 'props')`
5
+ @app_store = `Opal.LucidComponent.AppStoreProxy.$new(#{self}, 'props')`
6
+ @class_store = `Opal.LucidComponent.ClassStoreProxy.$new(#{self}, 'props')`
7
7
  @props = `Opal.React.Component.Props.$new(#@native)`
8
8
  @state = `Opal.React.Component.State.$new(#@native)`
9
- @store = `Opal.React.ReduxComponent.InstanceStoreProxy.$new(#{self}, 'props')`
9
+ @store = `Opal.LucidComponent.InstanceStoreProxy.$new(#{self}, 'props')`
10
10
  end
11
11
  end
12
12
  end
@@ -0,0 +1,47 @@
1
+ module LucidComponent
2
+ class InstanceStoreProxy
3
+ def initialize(component_instance, access_key = 'state')
4
+ @native_component_instance = component_instance.to_n
5
+ @component_instance = component_instance
6
+ @component_object_id = component_instance.object_id.to_s
7
+ @access_key = access_key
8
+ end
9
+
10
+ def method_missing(key, *args, &block)
11
+ @native_component_instance.JS.register_used_store_path(['component_state', @component_object_id, key])
12
+ if `args.length > 0`
13
+ # set instance state, simply a dispatch
14
+
15
+ action = { type: 'COMPONENT_STATE', object_id: @component_object_id, name: (`key.endsWith('=')` ? key.chop : key), value: args[0] }
16
+ Isomorfeus.store.dispatch(action)
17
+
18
+ else
19
+ # get instance state
20
+
21
+ if @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:component_state].JS[@component_object_id] &&
22
+ @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:component_state].JS[@component_object_id].JS.hasOwnProperty(key)
23
+ # check if we have a component local state value
24
+ return @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:component_state].JS[@component_object_id].JS[key]
25
+ elsif @component_instance.class.default_instance_store_defined && @component_instance.class.store.to_h.key?(key)
26
+ # check if a default value was given
27
+ return @component_instance.class.store.to_h[key]
28
+ end
29
+
30
+ # otherwise return nil
31
+ return nil
32
+ end
33
+ end
34
+
35
+ def dispatch(action)
36
+ Isomorfeus.store.dispatch(action)
37
+ end
38
+
39
+ def subscribe(&block)
40
+ Isomorfeus.store.subscribe(&block)
41
+ end
42
+
43
+ def unsubscribe(unsubscriber)
44
+ `unsubscriber()`
45
+ end
46
+ end
47
+ end
@@ -8,7 +8,7 @@ module LucidComponent
8
8
  base.include(::React::Component::Elements)
9
9
  base.include(::React::Component::API)
10
10
  base.include(::React::Component::Callbacks)
11
- base.include(::React::ReduxComponent::API)
11
+ base.include(::LucidComponent::StoreAPI)
12
12
  base.include(::LucidComponent::API)
13
13
  base.include(::LucidComponent::Initializer)
14
14
  base.include(::React::Component::Features)
@@ -0,0 +1,46 @@
1
+ module LucidComponent
2
+ module Reducers
3
+ class << self
4
+ attr_reader :component_reducers_added
5
+
6
+ def add_component_reducers_to_store
7
+ unless component_reducers_added
8
+ @_component_reducers_added = true
9
+ component_reducer = Redux.create_reducer do |prev_state, action|
10
+ case action[:type]
11
+ when 'COMPONENT_STATE'
12
+ if action.key?(:set_state)
13
+ action[:set_state]
14
+ else
15
+ new_state = {}.merge!(prev_state) # make a copy of state
16
+ new_state[action[:object_id]] = {} unless new_state.key?(action[:object_id])
17
+ new_state[action[:object_id]].merge!(action[:name] => action[:value])
18
+ new_state
19
+ end
20
+ else
21
+ prev_state
22
+ end
23
+ end
24
+
25
+ component_class_reducer = Redux.create_reducer do |prev_state, action|
26
+ case action[:type]
27
+ when 'COMPONENT_CLASS_STATE'
28
+ if action.key?(:set_state)
29
+ action[:set_state]
30
+ else
31
+ new_state = {}.merge!(prev_state) # make a copy of state
32
+ new_state[action[:class]] = {} unless new_state.key?(action[:class])
33
+ new_state[action[:class]].merge!(action[:name] => action[:value])
34
+ new_state
35
+ end
36
+ else
37
+ prev_state
38
+ end
39
+ end
40
+
41
+ Redux::Store.add_reducers(component_state: component_reducer, component_class_state: component_class_reducer)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,38 @@
1
+ module LucidComponent
2
+ module StoreAPI
3
+ def self.included(base)
4
+ base.instance_exec do
5
+ attr_accessor :app_store
6
+ attr_accessor :class_store
7
+ attr_accessor :store
8
+
9
+ def default_app_store_defined
10
+ @default_app_store_defined
11
+ end
12
+
13
+ def default_class_store_defined
14
+ @default_class_store_defined
15
+ end
16
+
17
+ def default_instance_store_defined
18
+ @default_instance_store_defined
19
+ end
20
+
21
+ def app_store
22
+ @default_app_store_defined = true
23
+ @default_app_store ||= ::LucidComponent::AppStoreDefaults.new(state, self.to_s)
24
+ end
25
+
26
+ def class_store
27
+ @default_class_store_defined = true
28
+ @default_class_store ||= ::LucidComponent::ComponentClassStoreDefaults.new(state, self.to_s)
29
+ end
30
+
31
+ def store
32
+ @default_instance_store_defined = true
33
+ @default_instance_store ||= ::LucidComponent::ComponentInstanceStoreDefaults.new(state, self.to_s)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -9,7 +9,7 @@ module LucidMaterial
9
9
  base.include(::React::Component::Elements)
10
10
  base.include(::React::Component::API)
11
11
  base.include(::React::Component::Callbacks)
12
- base.include(::React::ReduxComponent::API)
12
+ base.include(::LucidComponent::StoreAPI)
13
13
  base.include(::LucidMaterial::Component::API)
14
14
  base.include(::LucidApp::API)
15
15
  base.include(::LucidComponent::Initializer)
@@ -9,7 +9,7 @@ module LucidMaterial
9
9
  base.include(::React::Component::Elements)
10
10
  base.include(::React::Component::API)
11
11
  base.include(::React::Component::Callbacks)
12
- base.include(::React::ReduxComponent::API)
12
+ base.include(::LucidComponent::StoreAPI)
13
13
  base.include(::LucidComponent::API)
14
14
  base.include(::LucidMaterial::Component::API)
15
15
  base.include(::LucidComponent::Initializer)
data/lib/react.rb CHANGED
@@ -26,8 +26,7 @@ module React
26
26
 
27
27
  self.native_element_or_component_to_ruby = function (element) {
28
28
  if (typeof element.__ruby_instance !== 'undefined') { return element.__ruby_instance }
29
- if (element instanceof Element) { return #{Browser::DOM::Element.new(`element`)} }
30
- if (element instanceof Node) { return #{Browser::DOM::Node.new(`element`)} }
29
+ if (element instanceof Element || element instanceof Node) { return #{Browser::Element.new(`element`)} }
31
30
  return element;
32
31
  };
33
32
 
@@ -101,6 +101,10 @@ module React
101
101
  end
102
102
  end
103
103
 
104
+ def display_name
105
+ @native.JS[:displayName]
106
+ end
107
+
104
108
  def force_update(&block)
105
109
  if block_given?
106
110
  # this maybe needs instance_exec too
@@ -8,7 +8,7 @@ module React
8
8
  def Portal(element_or_query, &block)
9
9
  if `(typeof element_or_query === 'string')` || (`(typeof element_or_query.$class === 'function')` && element_or_query.class == String)
10
10
  element = `document.body.querySelector(element_or_query)`
11
- elsif `(typeof element_or_query.$is_a === 'function')` && element_or_query.is_a?(Browser::DOM::Node)
11
+ elsif `(typeof element_or_query.$is_a === 'function')` && element_or_query.is_a?(Browser::Element)
12
12
  element = element_or_query.to_n
13
13
  else
14
14
  element = element_or_query
@@ -30,6 +30,10 @@ module React
30
30
  }
31
31
  end
32
32
 
33
+ def Profiler(*args, &block)
34
+ `Opal.React.internal_prepare_args_and_render(Opal.global.React.Profiler, args, block)`
35
+ end
36
+
33
37
  def StrictMode(*args, &block)
34
38
  `Opal.React.internal_prepare_args_and_render(Opal.global.React.StrictMode, args, block)`
35
39
  end
@@ -10,7 +10,7 @@ module React
10
10
  base.include(::React::Component::Elements)
11
11
  base.include(::React::Component::API)
12
12
  base.include(::React::Component::Callbacks)
13
- base.include(::React::Component::UnsafeAPI)
13
+ # base.include(::React::Component::UnsafeAPI)
14
14
  base.include(::React::Component::Initializer)
15
15
  base.include(::React::Component::Features)
16
16
  base.include(::React::Component::Resolution)
@@ -55,4 +55,4 @@ module React
55
55
  end
56
56
  end
57
57
  end
58
- end
58
+ end
@@ -8,11 +8,7 @@ module React
8
8
  end
9
9
 
10
10
  def use_callback(deps, &block)
11
- %x{
12
- Opal.global.React.useCallback(function() {
13
- #{block.call}
14
- }, deps);
15
- }
11
+ `Opal.global.React.useCallback(function() { #{block.call} }, deps)`
16
12
  end
17
13
 
18
14
  def use_context(context)
@@ -25,36 +21,20 @@ module React
25
21
  end
26
22
 
27
23
  def use_effect(&block)
28
- %x{
29
- Opal.global.React.useEffect(function() {
30
- #{block.call}
31
- });
32
- }
24
+ `Opal.global.React.useEffect(function() { #{block.call} })`
33
25
  end
34
26
 
35
27
  def use_imperative_handle(ref, *deps, &block)
36
28
  native_ref = `(typeof ref.$is_wrapped_ref !== 'undefined')` ? ref.to_n : ref
37
- %x{
38
- Opal.global.React.useImperativeHandle(native_ref, function() {
39
- #{block.call}
40
- }, deps);
41
- }
29
+ `Opal.global.React.useImperativeHandle(native_ref, function() { #{block.call} }, deps)`
42
30
  end
43
31
 
44
32
  def use_layout_effect(&block)
45
- %x{
46
- Opal.global.React.useLayoutEffect(function() {
47
- #{block.call}
48
- });
49
- }
33
+ `Opal.global.React.useLayoutEffect(function() { #{block.call} })`
50
34
  end
51
35
 
52
36
  def use_memo(*deps, &block)
53
- %x{
54
- Opal.global.React.useMemo(function() {
55
- #{block.call}
56
- }, deps);
57
- }
37
+ `Opal.global.React.useMemo(function() { #{block.call} }, deps)`
58
38
  end
59
39
 
60
40
  def use_reducer(inital_state, &block)
@@ -9,7 +9,7 @@ module React
9
9
  base.include(::React::Component::Elements)
10
10
  base.include(::React::Component::API)
11
11
  base.include(::React::Component::Callbacks)
12
- base.include(::React::Component::UnsafeAPI)
12
+ # base.include(::React::Component::UnsafeAPI)
13
13
  base.include(::React::Component::Initializer)
14
14
  base.include(::React::Component::Features)
15
15
  base.include(::React::Component::Resolution)
@@ -35,7 +35,7 @@ module React
35
35
  native_boolean_accessors :altKey, :bubbles, :cancelable, :ctrlKey, :defaultPrevented, :isPrimary, :isTrusted, :metaKey, :repeat, :shiftKey
36
36
 
37
37
  def current_target
38
- Browser::Event::Target.convert(@native.JS[:currentTarget])
38
+ Browser::Element.new(@native.JS[:currentTarget])
39
39
  end
40
40
 
41
41
  def native_event
@@ -43,11 +43,11 @@ module React
43
43
  end
44
44
 
45
45
  def related_target
46
- Browser::Event::Target.convert(@native.JS[:relatedTarget])
46
+ Browser::Element.new(@native.JS[:relatedTarget])
47
47
  end
48
48
 
49
49
  def target
50
- Browser::Event::Target.convert(@native.JS[:target])
50
+ Browser::Element.new(@native.JS[:target])
51
51
  end
52
52
  end
53
53
  end