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,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