isomorfeus-react 16.8.9 → 16.9.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.
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,39 @@
1
+ module Browser
2
+ module EventTarget
3
+ # Add the block as a handler for the specified event name. Will use either
4
+ # `addEventListener` or `addListener` if they exist.
5
+ #
6
+ # @param event_name [String] the name of the event
7
+ # @return [Proc] the block to pass to `off` to remove this handler
8
+ # @yieldparam event [Browser::Event] the event object
9
+ def on event_name, &block
10
+ wrapper = proc { |event| block.call Event.new(event) }
11
+
12
+ if `#@native.addEventListener !== undefined`
13
+ `#@native.addEventListener(event_name, wrapper)`
14
+ elsif `#@native.addListener !== undefined`
15
+ `#@native.addListener(event_name, wrapper)`
16
+ else
17
+ warn "[Browser] Not entirely sure how to add an event listener to #{self}"
18
+ end
19
+
20
+ wrapper
21
+ end
22
+
23
+ # Remove an event handler
24
+ #
25
+ # @param event_name [String] the name of the event
26
+ # @block the handler to remove, as returned from `on`
27
+ def off event_name, &block
28
+ if `#@native.removeEventListener !== undefined`
29
+ `#@native.removeEventListener(event_name, block)`
30
+ elsif `#@native.removeListener !== undefined`
31
+ `#@native.removeListener(event_name, block)`
32
+ else
33
+ warn "[Browser] Not entirely sure how to remove an event listener from #{self}"
34
+ end
35
+
36
+ nil
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,125 @@
1
+ module Browser
2
+ class FileList
3
+ include Enumerable
4
+
5
+ # @param native [JS] the native FileList object to wrap
6
+ def initialize native
7
+ @native = `#{native} || []`
8
+ @files = length.times.each_with_object([]) { |index, array|
9
+ array[index] = File.new(`#@native[index]`)
10
+ }
11
+ end
12
+
13
+ # @param index [Integer] the index of the file in the list
14
+ # @return [Browser::FileList::File] the file at the specified index
15
+ def [] index
16
+ @files[index]
17
+ end
18
+
19
+ # @return [Integer] the number of files in this list
20
+ def length
21
+ `#@native.length`
22
+ end
23
+ alias size length
24
+
25
+ # Call the given block for each file in the list
26
+ #
27
+ # @yieldparam file [Browser::FileList::File]
28
+ def each &block
29
+ @files.each do |file|
30
+ block.call file
31
+ end
32
+ end
33
+
34
+ # Convert this FileList into an array
35
+ def to_a
36
+ @files.dup # Don't return a value that can mutate our internal state
37
+ end
38
+ alias to_ary to_a
39
+
40
+ # @return [String] a string representation of this FileList
41
+ def to_s
42
+ @files.to_s
43
+ end
44
+
45
+ # An individual item in a FileList
46
+ class File
47
+ attr_reader :data
48
+
49
+ # @param native [JS] the native File object to wrap
50
+ def initialize native
51
+ @native = native
52
+ @data = nil
53
+ end
54
+
55
+ # @return [String] the filename
56
+ def name
57
+ `#@native.name`
58
+ end
59
+
60
+ # @return [Integer] the size of this file on disk
61
+ def size
62
+ `#@native.size`
63
+ end
64
+
65
+ # @return [String] the MIME type of the file, detected by the browser
66
+ def type
67
+ `#@native.type`
68
+ end
69
+
70
+ # @return [Time] the timestamp of the file
71
+ def last_modified
72
+ `#@native.lastModifiedDate`
73
+ end
74
+
75
+ # Read the file from disk into memory
76
+ #
77
+ # @return [Promise] a promise that resolves when finished loading and
78
+ # rejects if an error occurs while loading.
79
+ def read
80
+ promise = Promise.new
81
+ reader = FileReader.new
82
+ reader.on :load do
83
+ result = reader.result
84
+
85
+ @data = result
86
+ promise.resolve result
87
+ end
88
+
89
+ reader.on :error do
90
+ promise.reject reader.result
91
+ end
92
+
93
+ reader.read_as_binary_string self
94
+
95
+ promise
96
+ end
97
+
98
+ # Convert to the native object
99
+ #
100
+ # @return [JS.HTMLElement] the underlying native element
101
+ def to_n
102
+ @native
103
+ end
104
+
105
+ # The object that reads the file from disk.
106
+ #
107
+ # @api private
108
+ class FileReader
109
+ include EventTarget
110
+
111
+ def initialize
112
+ @native = `new FileReader()`
113
+ end
114
+
115
+ def result
116
+ `#@native.result`
117
+ end
118
+
119
+ def read_as_binary_string file
120
+ `#@native.readAsBinaryString(#{file.to_n})`
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,15 @@
1
+ module Browser
2
+ class Iterable
3
+ include Enumerable
4
+
5
+ def initialize js_iterable
6
+ @js_iterable = js_iterable
7
+ end
8
+
9
+ def each
10
+ `#@js_iterable.length`.times do |i|
11
+ yield `#@js_iterable[i]`
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,34 +1,4 @@
1
- require 'isomorfeus-react-base'
2
-
3
- # basics
4
- require 'react/component/native_component_validate_prop'
5
- require 'react/component/event_handler'
6
- require 'react/component/api'
7
- require 'react/component/callbacks'
8
- require 'react/component/resolution'
9
- require 'react/component/state'
10
- require 'react/component/should_component_update'
11
- require 'react/redux_component/api'
12
- require 'react/redux_component/app_store_defaults'
13
- require 'react/redux_component/component_class_store_defaults'
14
- require 'react/redux_component/component_instance_store_defaults'
15
- require 'react/redux_component/app_store_proxy'
16
- require 'react/redux_component/class_store_proxy'
17
- require 'react/redux_component/instance_store_proxy'
18
- require 'react/redux_component/reducers'
19
-
20
- require 'react/component/styles'
21
- # init component reducers
22
- React::ReduxComponent::Reducers.add_component_reducers_to_store
23
-
24
- # init LucidApplicationContext (Store Provider and Consumer)
25
- require 'lucid_app/context'
26
- LucidApp::Context.create_application_context
27
-
28
- require 'lucid_component/api'
29
- require 'lucid_component/event_handler'
30
- require 'lucid_component/initializer'
31
- require 'lucid_app/api'
1
+ require 'isomorfeus-react'
32
2
 
33
3
  # LucidMaterial::Component
34
4
  require 'lucid_material/component/api'
@@ -1,14 +1,121 @@
1
1
  if RUBY_ENGINE == 'opal'
2
- require 'isomorfeus-react-base'
3
- require 'isomorfeus-react-component'
4
- require 'isomorfeus-react-redux-component'
5
- require 'isomorfeus-react-lucid'
2
+ require 'opal'
3
+ require 'opal-autoloader'
4
+ require 'native'
5
+ require 'promise'
6
+ require 'active_support/core_ext/string'
7
+ require 'react/active_support_support'
8
+ require 'isomorfeus-redux'
9
+
10
+ require 'isomorfeus/execution_environment'
11
+
12
+ if Isomorfeus.on_browser?
13
+ require 'browser/event'
14
+ require 'browser/event_target'
15
+ require 'browser/delegate_native'
16
+ require 'browser/element'
17
+ end
18
+
19
+ require 'isomorfeus/config'
20
+
21
+ # allow mounting of components
22
+ if Isomorfeus.on_browser?
23
+ require 'isomorfeus/top_level_browser'
24
+ else
25
+ require 'isomorfeus/top_level_ssr'
26
+ end
27
+
28
+ # react
29
+ require 'react/version'
30
+ require 'react'
31
+ require 'react/synthetic_event'
32
+ require 'react/ref'
33
+ require 'react/children'
34
+ if Isomorfeus.on_browser?
35
+ require 'react_dom'
36
+ else
37
+ require 'react_dom_server'
38
+ end
39
+
40
+ # props
41
+ require 'react/component/props'
42
+
43
+ # HTML Elements support
44
+ require 'react/component/elements'
45
+
46
+ # React Features
47
+ require 'react/component/features'
48
+ require 'react/context_wrapper'
49
+ require 'react/native_constant_wrapper'
50
+
51
+ # Function Component
52
+ require 'react/function_component/resolution'
53
+ require 'react/function_component/api'
54
+ require 'react/function_component/event_handler'
55
+ require 'react/function_component/creator'
56
+ require 'react/function_component/mixin'
57
+ require 'react/function_component/base'
58
+ require 'react/memo_component/creator'
59
+ require 'react/memo_component/mixin'
60
+ require 'react/memo_component/base'
61
+
62
+ # React::Component
63
+ require 'react/component/api'
64
+ require 'react/component/callbacks'
65
+ # require 'react/component/unsafe_api'
66
+ require 'react/component/initializer'
67
+ require 'react/component/native_component_constructor'
68
+ require 'react/component/native_component_validate_prop'
69
+ require 'react/component/state'
70
+ require 'react/component/match'
71
+ require 'react/component/location'
72
+ require 'react/component/history'
73
+ require 'react/component/resolution'
74
+ require 'react/component/should_component_update'
75
+ require 'react/component/event_handler'
76
+ require 'react/component/styles'
77
+ require 'react/component/mixin'
78
+ require 'react/component/base'
79
+
80
+ # React::PureComponent
81
+ require 'react/pure_component/mixin'
82
+ require 'react/pure_component/base'
83
+
84
+ # init component reducers
85
+ require 'lucid_component/reducers'
86
+ LucidComponent::Reducers.add_component_reducers_to_store
87
+
88
+ # init LucidApplicationContext (Store Provider and Consumer)
89
+ require 'lucid_app/context'
90
+ LucidApp::Context.create_application_context
91
+
92
+ # LucidComponent
93
+ require 'lucid_component/store_api'
94
+ require 'lucid_component/app_store_defaults'
95
+ require 'lucid_component/component_class_store_defaults'
96
+ require 'lucid_component/component_instance_store_defaults'
97
+ require 'lucid_component/app_store_proxy'
98
+ require 'lucid_component/class_store_proxy'
99
+ require 'lucid_component/instance_store_proxy'
100
+ require 'lucid_component/api'
101
+ require 'lucid_component/initializer'
102
+ require 'lucid_component/native_component_constructor'
103
+ require 'lucid_component/event_handler'
104
+ require 'lucid_component/mixin'
105
+ require 'lucid_component/base'
106
+
107
+ # LucidApp
108
+ require 'lucid_app/api'
109
+ require 'lucid_app/native_component_constructor'
110
+ require 'lucid_app/mixin'
111
+ require 'lucid_app/base'
112
+
113
+ Opal::Autoloader.add_load_path('components')
6
114
  else
7
115
  require 'oj'
8
116
  require 'opal'
9
117
  require 'opal-activesupport'
10
118
  require 'opal-autoloader'
11
- require 'opal-browser'
12
119
  require 'isomorfeus-redux'
13
120
  require 'isomorfeus-speednode'
14
121
  require 'react/version'
@@ -1,18 +1,24 @@
1
1
  module Isomorfeus
2
2
  if RUBY_ENGINE == 'opal'
3
3
  class << self
4
+ attr_accessor :on_browser
5
+ attr_accessor :on_ssr
6
+
4
7
  def on_browser?
5
- !on_ssr?
8
+ @on_browser
6
9
  end
7
10
 
8
11
  def on_ssr?
9
- !!`((typeof process !== 'undefined') && (typeof process.release !== "undefined") && (process.release.name === 'node'))`
12
+ @on_ssr
10
13
  end
11
14
 
12
15
  def on_server?
13
16
  false
14
17
  end
15
18
  end
19
+
20
+ self.on_ssr = `!!((typeof process !== 'undefined') && (typeof process.release !== "undefined") && (process.release.name === 'node'))`
21
+ self.on_browser = !on_ssr
16
22
  else
17
23
  class << self
18
24
  def on_browser?
@@ -45,7 +45,7 @@ module Isomorfeus
45
45
  def self.mount_component(component, props, element_or_query, hydrated = false)
46
46
  if `(typeof element_or_query === 'string')` || (`(typeof element_or_query.$class === 'function')` && element_or_query.class == String)
47
47
  element = `document.body.querySelector(element_or_query)`
48
- elsif `(typeof element_or_query.$is_a === 'function')` && element_or_query.is_a?(Browser::DOM::Node)
48
+ elsif `(typeof element_or_query.$is_a === 'function')` && element_or_query.is_a?(Browser::Element)
49
49
  element = element_or_query.to_n
50
50
  else
51
51
  element = element_or_query
@@ -9,7 +9,7 @@ module LucidApp
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(::LucidApp::API)
14
14
  base.include(::LucidComponent::Initializer)
15
15
  base.include(::React::Component::Features)
@@ -0,0 +1,36 @@
1
+ module LucidComponent
2
+ class AppStoreDefaults
3
+ def initialize(state, component_name)
4
+ @state = state
5
+ if @state.isomorfeus_store
6
+ @state.isomorfeus_store.merge!(application_state: {})
7
+ else
8
+ @state.isomorfeus_store = { application_state: {}}
9
+ end
10
+ end
11
+
12
+ def method_missing(key, *args, &block)
13
+ if `args.length > 0`
14
+ # set initial class state
15
+ key = key.chop if `key.endsWith('=')`
16
+ @state.isomorfeus_store[:application_state][key] = args[0]
17
+ current_state = Isomorfeus.store.get_state
18
+ if !(current_state[:application_state].key?(key))
19
+ Isomorfeus.store.dispatch(type: 'APPLICATION_STATE', name: key, value: args[0])
20
+ end
21
+ else
22
+ # get class state
23
+
24
+ # check if we have a component local state value
25
+ if @state.isomorfeus_store[:application_state].key?(key)
26
+ return @state.isomorfeus_store[:application_state][key]
27
+ end
28
+ end
29
+ nil
30
+ end
31
+
32
+ def to_h
33
+ @state.isomorfeus_store[:application_state]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ module LucidComponent
2
+ class AppStoreProxy
3
+ def initialize(component_instance, access_key = 'state')
4
+ @native_component_instance = component_instance.to_n
5
+ @component_instance = component_instance
6
+ @access_key = access_key
7
+ end
8
+
9
+ def method_missing(key, *args, &block)
10
+ @native_component_instance.JS.register_used_store_path(['application_state', key])
11
+ if `args.length > 0`
12
+ # set class state, simply a dispatch
13
+ action = { type: 'APPLICATION_STATE', name: (`key.endsWith('=')` ? key.chop : key), value: args[0] }
14
+ Isomorfeus.store.dispatch(action)
15
+ else
16
+ # check if we have a component local state value
17
+ if `this.native_component_instance[this.access_key]["isomorfeus_store"]["application_state"].hasOwnProperty(key)`
18
+ return @native_component_instance.JS[@access_key].JS[:isomorfeus_store].JS[:application_state].JS[key]
19
+ elsif @component_instance.class.default_app_store_defined && @component_instance.class.app_store.to_h.key?(key)
20
+ # check if a default value was given
21
+ return @component_instance.class.app_store.to_h[key]
22
+ end
23
+ # otherwise return nil
24
+ return nil
25
+ end
26
+ end
27
+
28
+ def dispatch(action)
29
+ Isomorfeus.store.dispatch(action)
30
+ end
31
+
32
+ def subscribe(&block)
33
+ Isomorfeus.store.subscribe(&block)
34
+ end
35
+
36
+ def unsubscribe(unsubscriber)
37
+ `unsubscriber()`
38
+ end
39
+ end
40
+ end