isomorfeus-react 16.10.0 → 16.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +64 -0
  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 +10 -0
  12. data/lib/isomorfeus-react.rb +145 -0
  13. data/lib/isomorfeus/config.rb +130 -0
  14. data/lib/isomorfeus/props/validate_hash_proxy.rb +178 -0
  15. data/lib/isomorfeus/props/validator.rb +131 -0
  16. data/lib/isomorfeus/react_view_helper.rb +130 -0
  17. data/lib/isomorfeus/top_level.rb +86 -0
  18. data/lib/isomorfeus/top_level_ssr.rb +28 -0
  19. data/lib/lucid_app/api.rb +30 -0
  20. data/lib/lucid_app/base.rb +7 -0
  21. data/lib/lucid_app/context.rb +7 -0
  22. data/lib/lucid_app/mixin.rb +20 -0
  23. data/lib/lucid_app/native_component_constructor.rb +105 -0
  24. data/lib/lucid_component/app_store_defaults.rb +36 -0
  25. data/lib/lucid_component/app_store_proxy.rb +38 -0
  26. data/lib/lucid_component/base.rb +7 -0
  27. data/lib/lucid_component/class_store_proxy.rb +41 -0
  28. data/lib/lucid_component/component_class_store_defaults.rb +38 -0
  29. data/lib/lucid_component/component_instance_store_defaults.rb +35 -0
  30. data/lib/lucid_component/event_handler.rb +17 -0
  31. data/lib/lucid_component/initializer.rb +12 -0
  32. data/lib/lucid_component/instance_store_proxy.rb +45 -0
  33. data/lib/lucid_component/mixin.rb +18 -0
  34. data/lib/lucid_component/native_component_constructor.rb +116 -0
  35. data/lib/lucid_component/reducers.rb +48 -0
  36. data/lib/lucid_component/store_api.rb +38 -0
  37. data/lib/lucid_component/styles_support.rb +37 -0
  38. data/lib/lucid_material/app/base.rb +9 -0
  39. data/lib/lucid_material/app/mixin.rb +22 -0
  40. data/lib/lucid_material/app/native_component_constructor.rb +107 -0
  41. data/lib/lucid_material/component/base.rb +9 -0
  42. data/lib/lucid_material/component/mixin.rb +20 -0
  43. data/lib/lucid_material/component/native_component_constructor.rb +118 -0
  44. data/lib/lucid_prop_declaration/mixin.rb +91 -0
  45. data/lib/react.rb +195 -0
  46. data/lib/react/active_support_support.rb +13 -0
  47. data/lib/react/children.rb +35 -0
  48. data/lib/react/component/api.rb +80 -0
  49. data/lib/react/component/base.rb +9 -0
  50. data/lib/react/component/callbacks.rb +106 -0
  51. data/lib/react/component/elements.rb +60 -0
  52. data/lib/react/component/event_handler.rb +19 -0
  53. data/lib/react/component/features.rb +47 -0
  54. data/lib/react/component/history.rb +36 -0
  55. data/lib/react/component/initializer.rb +11 -0
  56. data/lib/react/component/location.rb +15 -0
  57. data/lib/react/component/match.rb +31 -0
  58. data/lib/react/component/mixin.rb +19 -0
  59. data/lib/react/component/native_component_constructor.rb +93 -0
  60. data/lib/react/component/props.rb +59 -0
  61. data/lib/react/component/resolution.rb +70 -0
  62. data/lib/react/component/should_component_update.rb +14 -0
  63. data/lib/react/component/state.rb +52 -0
  64. data/lib/react/component/styles.rb +27 -0
  65. data/lib/react/component/unsafe_api.rb +33 -0
  66. data/lib/react/context_wrapper.rb +46 -0
  67. data/lib/react/function_component/api.rb +63 -0
  68. data/lib/react/function_component/base.rb +9 -0
  69. data/lib/react/function_component/creator.rb +32 -0
  70. data/lib/react/function_component/event_handler.rb +13 -0
  71. data/lib/react/function_component/mixin.rb +14 -0
  72. data/lib/react/function_component/resolution.rb +62 -0
  73. data/lib/react/memo_component/base.rb +9 -0
  74. data/lib/react/memo_component/creator.rb +32 -0
  75. data/lib/react/memo_component/mixin.rb +14 -0
  76. data/lib/react/native_constant_wrapper.rb +26 -0
  77. data/lib/react/pure_component/base.rb +9 -0
  78. data/lib/react/pure_component/mixin.rb +18 -0
  79. data/lib/react/ref.rb +13 -0
  80. data/lib/react/synthetic_event.rb +53 -0
  81. data/lib/react/version.rb +3 -0
  82. data/lib/react_dom.rb +47 -0
  83. data/lib/react_dom_server.rb +19 -0
  84. metadata +84 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eed204f4b128a4296d4020a328a82236818c7903a650b9053f4a874e96d44d10
4
- data.tar.gz: 94171afa5509ae6f9aa08c3697d925a997efb9cd2c23b2cf5a5a11a1c06d477b
3
+ metadata.gz: 0f0643b4e28b59ef5b2f108031cb864569b512d8cfde42f878bd78ca2b8b33a8
4
+ data.tar.gz: d87221984e4755183dca32a3e22ea69bd0e04e86350563675c8132698ed0758b
5
5
  SHA512:
6
- metadata.gz: 2570138f724adf2d0c9879dcc0bfd11e54a762b771202ef7391257b5ce138294371885a8423764cb487c23b1b4e814ac193e300204f7a48505d317e4b318fb93
7
- data.tar.gz: 21e74ad6c96774fd4205d432b64bcf356ba6023f64f47141b9524abf77a238abc66d53f9cd70d88e3336027d55e2fad3921d4524bab3af5ab7708ef4689bd2f2
6
+ metadata.gz: 9f62a599178ffe14165db090194d40d34c2de1408478a6e6f4cbdb6e5f1115a7253c9b7d17e858d5dad550a56d6bb9784d94491d50e01b3fea32bd86352ca2c1
7
+ data.tar.gz: 17ffcecfe921feb30928617f7f01710dc76c4da3b4d5d3f56d3fd9faa35eed13ed5b26996b3a9b0cf6f48800aa25e01721c3d243ffc351c87363baf35002fc2e
@@ -0,0 +1,64 @@
1
+ # isomorfeus-react
2
+
3
+ Develop React components for Opal Ruby along with very easy to use and advanced React-Redux Components.
4
+
5
+ ## Community and Support
6
+ At the [Isomorfeus Framework Project](http://isomorfeus.com)
7
+
8
+ ## Versioning
9
+ isomorfeus-react version follows the React version which features and API it implements.
10
+ Isomorfeus-react 16.8.x implements features and the API of React 16.8 and should be used with React 16.8
11
+
12
+ ## Documentation
13
+
14
+ - [Installation](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/installation.md)
15
+
16
+ Because isomorfeus-react follows closely the React principles/implementation/API and Documentation, most things of the official React documentation
17
+ apply, but in the Ruby way, see:
18
+ - https://reactjs.org/docs/getting-started.html
19
+
20
+ Component Types:
21
+ - [Class Component](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/class_component.md)
22
+ - [Pure Component](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/pure_component.md)
23
+ - [Function and Memo Component](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/function_component.md)
24
+ - [Lucid App, Lucid Component](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/lucid_component.md)
25
+ - [LucidMaterial App, LucidMaterial Component](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/lucid_material_component.md) - support for [MaterialUI](https://material-ui.com)
26
+ - [React Javascript Component](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/javascript_component.md)
27
+
28
+ Which component to use?
29
+ - Usually LucidApp and LucidComponent along with some imported javascript components.
30
+
31
+ Specific to Class, Pure, Lucid and LucidMaterial Components:
32
+ - [Events](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/events.md)
33
+ - [Lifecycle Callbacks](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/lifecycle_callbacks.md)
34
+ - [Props](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/props.md)
35
+ - [State](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/state.md)
36
+
37
+ For all Components:
38
+ - [Accessibility](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/accessibility.md)
39
+ - [Render Blocks](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/render_blocks.md)
40
+ - [Rendering HTML or SVG Elements](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/rendering_elements.md)
41
+
42
+ Special React Features:
43
+ - [Context](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/context.md)
44
+ - [Fragments](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/fragments.md)
45
+ - [Portals](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/portals.md)
46
+ - [Refs](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/refs.md)
47
+ - [StrictMode](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/strict_mode.md)
48
+
49
+ Other Features:
50
+ - [Code Splitting and Lazy Loading](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/code_splitting_lazy_loading.md)
51
+ - [Hot Module Reloading](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/hot_module_relaoding.md)
52
+ - [Server Side Rendering](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/server_side_rendering.md)
53
+ - [Using React Router](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/react_router.md)
54
+ - [Isomorfeus Helpers](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/isomorfeus_helpers.md)
55
+ - [Reducing Asset Size](https://github.com/isomorfeus/isomorfeus-react/blob/master/ruby/docs/reducing_asset_size.md)
56
+
57
+ ### Development Tools
58
+ The React Developer Tools allow for analyzing, debugging and profiling components. A very helpful toolset and working very nice with isomorfeus-react:
59
+ https://github.com/facebook/react-devtools
60
+
61
+ ### Specs and Benchmarks
62
+ - clone repo
63
+ - `bundle install`
64
+ - `rake`
@@ -0,0 +1,70 @@
1
+ module Browser
2
+ module DelegateNative
3
+ # Provides a default initializer. This should be overridden in all but the
4
+ # simplest cases.
5
+ def initialize native
6
+ @native = native
7
+ end
8
+
9
+ # Fall back to native properties. If the message sent to this element is not
10
+ # recognized, it checks to see if it is a property of the native element. It
11
+ # also checks for variations of the message name, such as:
12
+ #
13
+ # :supported? => [:supported, :isSupported]
14
+ #
15
+ # If a property with the specified message name is found and it is a
16
+ # function, that function is invoked with `args`. Otherwise, the property
17
+ # is returned as is.
18
+ def method_missing message, *args, &block
19
+ property_name = property_for_message(message)
20
+ property = `#@native[#{property_name}]`
21
+
22
+ # translate setting a property
23
+ if message.end_with? '='
24
+ return `#@native[#{property_name}] = args[0]`
25
+ end
26
+
27
+ # If the native element doesn't have this property, bubble it up
28
+ super unless `#{property_name} in #@native`
29
+
30
+ if `property === false`
31
+ return false
32
+ elsif `typeof(property) === 'number' && isNaN(property)`
33
+ return nil
34
+ else
35
+ property = `property == null ? nil : property`
36
+ end
37
+
38
+ # If it's a method, call it. Otherwise, return it.
39
+ if `typeof(property) === 'function'`
40
+ `property.apply(#@native, args)`
41
+ else
42
+ property
43
+ end
44
+ end
45
+
46
+ def respond_to_missing? message, include_all
47
+ return true if message.end_with? '='
48
+ return true if property_for_message(message)
49
+
50
+ false
51
+ end
52
+
53
+ def property_for_message message
54
+ camel_cased_message = message
55
+ .gsub(/_\w/) { |match| `match[1]`.upcase }
56
+ .sub(/=$/, '')
57
+
58
+ # translate `supported?` to `supported` or `isSupported`
59
+ if message.end_with? '?'
60
+ camel_cased_message = camel_cased_message.chop
61
+ property_type = `typeof(#@native[camel_cased_message])`
62
+ if property_type == 'undefined'
63
+ camel_cased_message = "is#{camel_cased_message[0].upcase}#{camel_cased_message[1..-1]}"
64
+ end
65
+ end
66
+
67
+ camel_cased_message
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,176 @@
1
+ module Browser
2
+ autoload :FileList, 'browser/file_list'
3
+ autoload :Iterable, 'browser/iterable'
4
+
5
+ # Wrap a native DOM element
6
+ class Element
7
+ include EventTarget
8
+ include DelegateNative
9
+
10
+ @tags = Hash.new(self)
11
+
12
+ def self.element *tags, &block
13
+ tags.each do |tag|
14
+ @tags
15
+ .fetch(tag) { @tags[tag] = const_set(tag.capitalize, Class.new(self)) }
16
+ .class_exec(&block)
17
+ end
18
+ end
19
+
20
+ def self.new(native)
21
+ element = @tags[`(#{native}.tagName || '')`.downcase].allocate
22
+ element.initialize native
23
+ element
24
+ end
25
+
26
+ # @param native [JS] The native DOM element to wrap
27
+ def initialize native
28
+ @native = native
29
+ end
30
+
31
+ # Replace all child elements with the given element
32
+ #
33
+ # @param element [Browser::Element] The Browser element with which to replace
34
+ # this element's contents
35
+ def inner_dom= element
36
+ clear
37
+ append element
38
+ end
39
+
40
+ # The contents of this element as an HTML string
41
+ #
42
+ # @return [String] the HTML representation of this element's contents
43
+ def inner_html
44
+ `#@native.innerHTML`
45
+ end
46
+
47
+ # Use the supplied HTML string to replace this element's contents
48
+ #
49
+ # @param html [String] the HTML with which to replace this elements contents
50
+ def inner_html= html
51
+ `#@native.innerHTML = html`
52
+ end
53
+
54
+ # This element's direct child elements
55
+ #
56
+ # @return [Array<Browser::Element>] list of this element's children
57
+ def children
58
+ elements = []
59
+
60
+ %x{
61
+ var children = #@native.children;
62
+ for(var i = 0; i < children.length; i++) {
63
+ elements[i] = #{Element.new(`children[i]`)};
64
+ }
65
+ }
66
+
67
+ elements
68
+ end
69
+
70
+ # Determine whether this element has any contents
71
+ #
72
+ # @return [Boolean] true if the element has no children, false otherwise
73
+ def empty?
74
+ `#@native.children.length === 0`
75
+ end
76
+
77
+ # Remove all contents from this element. After this call, `empty?` will
78
+ # return `true`.
79
+ #
80
+ # @return [Browser::Element] self
81
+ def clear
82
+ if %w(input textarea).include? type
83
+ `#@native.value = null`
84
+ else
85
+ children.each do |child|
86
+ remove_child child
87
+ end
88
+ end
89
+
90
+ self
91
+ end
92
+
93
+ # Remove the specified child element
94
+ #
95
+ # @param child [Browser::Element] the child element to remove
96
+ def remove_child child
97
+ `#@native.removeChild(child['native'] ? child['native'] : child)`
98
+ end
99
+
100
+ # This element's type. For example: "div", "span", "p"
101
+ #
102
+ # @return [String] the HTML tag name for this element
103
+ def type
104
+ `#@native.nodeName`.downcase
105
+ end
106
+
107
+ # Append the specified element as a child element
108
+ #
109
+ # @param element [Browser::Element, JS] the element to insert
110
+ def append node
111
+ `#@native.appendChild(node['native'] ? node['native'] : node)`
112
+ self
113
+ end
114
+
115
+ # Methods for <input /> elements
116
+
117
+ # A checkbox's checked status
118
+ #
119
+ # @return [Boolean] true if the checkbox is checked, false otherwise
120
+ def checked?
121
+ `!!#@native.checked`
122
+ end
123
+
124
+ # Get the currently selected file for this input. This is only useful for
125
+ # file inputs without the `multiple` property set.
126
+ #
127
+ # @return [Browser::File] the file selected by the user
128
+ def file
129
+ files.first
130
+ end
131
+
132
+ # Get the currently selected files for this input. This is only useful for
133
+ # file inputs with the `multiple` property set.
134
+ #
135
+ # @return [Browser::FileList] the currently selected files for this input
136
+ def files
137
+ FileList.new(`#@native.files`)
138
+ end
139
+
140
+ # Determine whether this is the same element
141
+ #
142
+ # @return [boolean] true if the element is the same, false otherwise
143
+ def ==(other)
144
+ `#@native === #{other.to_n}`
145
+ end
146
+
147
+ # Set the specified attribute to the specified value
148
+ def []= attribute, value
149
+ `#@native.setAttribute(#{attribute}, #{value})`
150
+ end
151
+
152
+ # Return the specified attribute
153
+ #
154
+ # @return [String] the value for the specified attribute
155
+ def [] attribute
156
+ `#@native.getAttribute(#{attribute})`
157
+ end
158
+
159
+ def query_selector selector
160
+ result = super
161
+
162
+ Element.new(result) if result
163
+ end
164
+
165
+ def query_selector_all selector
166
+ Iterable.new(super).map { |element| Element.new(element) }
167
+ end
168
+
169
+ # The native representation of this element.
170
+ #
171
+ # @return [JS] the native element wrapped by this object.
172
+ def to_n
173
+ @native
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,17 @@
1
+ module Browser
2
+ class Element
3
+ element :canvas do
4
+ def context(type='2d')
5
+ Context.new(`#@native.getContext(#{type})`)
6
+ end
7
+
8
+ class Context
9
+ include DelegateNative
10
+
11
+ def initialize native
12
+ @native = native
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,78 @@
1
+ module Browser
2
+ class Element
3
+ element :video, :audio do
4
+ def buffered
5
+ TimeRanges.new(`#@native.buffered`)
6
+ end
7
+
8
+ def played
9
+ TimeRanges.new(`#@native.played`)
10
+ end
11
+
12
+ def seekable
13
+ TimeRanges.new(`#@native.seekable`)
14
+ end
15
+
16
+ def network_state
17
+ case `#@native.networkState`
18
+ when `HTMLMediaElement.NETWORK_EMPTY` then :no_data
19
+ when `HTMLMediaElement.NETWORK_IDLE` then :idle
20
+ when `HTMLMediaElement.NETWORK_LOADING` then :loading
21
+ when `HTMLMediaElement.NETWORK_NO_SOURCE` then :no_source
22
+ end
23
+ end
24
+ end
25
+
26
+ element :video do
27
+ def fullscreen
28
+ fullscreen = %w(
29
+ requestFullScreen
30
+ requestFullscreen
31
+ webkitRequestFullScreen
32
+ webkitRequestFullscreen
33
+ mozRequestFullScreen
34
+ msRequestFullscreen
35
+ ).find { |prop| `!!#@native[prop]` }
36
+
37
+ if fullscreen
38
+ `#@native[fullscreen]()`
39
+ else
40
+ warn "[#{self.class}] Cannot determine the method to full-screen a video"
41
+ super
42
+ end
43
+ end
44
+ alias request_fullscreen fullscreen
45
+ end
46
+
47
+ class TimeRanges
48
+ include Enumerable
49
+
50
+ def initialize native
51
+ @native = native
52
+ end
53
+
54
+ def to_n
55
+ @native
56
+ end
57
+
58
+ def each
59
+ `#@native.length`.times do |i|
60
+ yield TimeRange.new(`#@native.start(i)`, `#@native.end(i)`)
61
+ end
62
+
63
+ self
64
+ end
65
+ end
66
+
67
+ class TimeRange
68
+ attr_reader :start, :end
69
+
70
+ def initialize start, _end
71
+ @start = start
72
+ @end = _end
73
+ end
74
+
75
+ alias begin start
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,92 @@
1
+ module Browser
2
+ # Wrapper for JS events
3
+ class Event
4
+ # @param [JS] the native event to wrap
5
+ def initialize native
6
+ @native = native
7
+ end
8
+
9
+ # Prevent the runtime from executing this event's default behavior. For
10
+ # example, prevent navigation after clicking a link.
11
+ #
12
+ # @return [Browser::Event] self
13
+ def prevent
14
+ `#@native.preventDefault()`
15
+ self
16
+ end
17
+
18
+ # Prevent the runtime from bubbling this event up the hierarchy. This is
19
+ # typically used to keep an event local to the element on which it was
20
+ # triggered, such as keeping a click event on a button from unintentionally
21
+ # triggering a handler on a parent element.
22
+ #
23
+ # @return self
24
+ def stop_propagation
25
+ `#@native.stopPropagation()`
26
+ self
27
+ end
28
+
29
+ # @return [Boolean] true if `prevent` has been called on this event, false
30
+ # otherwise
31
+ def prevented?
32
+ `#@native.defaultPrevented`
33
+ end
34
+
35
+ # @return [Boolean] true if the Meta/Command/Windows key was pressed when
36
+ # this event fired, false otherwise
37
+ def meta?
38
+ `#@native.metaKey`
39
+ end
40
+
41
+ # @return [Boolean] true if the Shift key was pressed when this event fired,
42
+ # false otherwise
43
+ def shift?
44
+ `#@native.shiftKey`
45
+ end
46
+
47
+ # @return [Boolean] true if the Ctrl key was pressed when this event fired,
48
+ # false otherwise
49
+ def ctrl?
50
+ `#@native.ctrlKey`
51
+ end
52
+
53
+ # @return [Boolean] true if the Alt key was pressed when this event fired,
54
+ # false otherwise
55
+ def alt?
56
+ `#@native.altKey`
57
+ end
58
+
59
+ # The target for this event
60
+ #
61
+ # @return [Browser::Element] the element on which this event was triggered
62
+ # @todo Handle non-DOM events here
63
+ def target
64
+ Element.new(`#@native.target`)
65
+ end
66
+
67
+ # @return [Numeric] the key code associated with this event. Only useful for
68
+ # keyboard-based events.
69
+ def code
70
+ `#@native.keyCode`
71
+ end
72
+
73
+ # Return properties on the event not covered by Ruby methods.
74
+ def method_missing name, *args
75
+ property = name.gsub(/_[a-z]/) { |match| match[-1, 1].upcase }
76
+ value = `#@native[property]`
77
+
78
+ if `!!value && #{Proc === value}`
79
+ value.call(*args)
80
+ elsif `value == null`
81
+ nil
82
+ else
83
+ value
84
+ end
85
+ end
86
+
87
+ # @return [JS] the native event wrapped by this object.
88
+ def to_n
89
+ @native
90
+ end
91
+ end
92
+ end