isomorfeus-react 16.9.9 → 16.9.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95359f47e37838bc5837fa240509800bcbcc9379738bbfce624647d30ba40763
4
- data.tar.gz: 92bdcd861c9e9ffdabbe8a5e4dc33f50216ea1be9dafdb94615cfe0fb11a11f9
3
+ metadata.gz: 75729fef22a55df3ac3e157a7d7a52db075e43d99e9c46e81aef63824fdabdba
4
+ data.tar.gz: 26501bbbd44cca1c7e4f5e7d6ea1312b9ddabc7f298d3c8e0367097c10f11906
5
5
  SHA512:
6
- metadata.gz: 6f23a39561194d77079a20fa6090abef89e17e7a8aec9f714e1bcb1e4487cf7236fe10e2d7517a2701ba8b283a6a250f5f5d891ede4cd69699a9f20d8559c0c8
7
- data.tar.gz: 4ef5e72e196ddbd3975749ebae0db1115beaa4f2d53d0b20084e6150dd2241e9b0389e897cb20886ef0f866280665c325947da5aaf020dbb375ec88b73514323
6
+ metadata.gz: 1fc0991c90a58f4756246b9b26fe85cf0e8d64b24779fce4cac1aaf0846045bcf3bdb2a24896a781aad5af3188dcd754a12be2fb6a1163589cfeabd937f9eab3
7
+ data.tar.gz: c31e70784c55858c182cce6c194a472ca7476a355046c4d2dba9faf63f92df59b5560b156e6b4eff5c9d6a2ee80aad1862c053ce2048bc237f2e57d8c5dd309a
@@ -38,6 +38,9 @@ if RUBY_ENGINE == 'opal'
38
38
  end
39
39
 
40
40
  # props
41
+ require 'isomorfeus/props/validate_hash_proxy'
42
+ require 'isomorfeus/props/validator'
43
+ require 'lucid_prop_declaration/mixin'
41
44
  require 'react/component/props'
42
45
 
43
46
  # HTML Elements support
@@ -65,7 +68,6 @@ if RUBY_ENGINE == 'opal'
65
68
  # require 'react/component/unsafe_api'
66
69
  require 'react/component/initializer'
67
70
  require 'react/component/native_component_constructor'
68
- require 'react/component/native_component_validate_prop'
69
71
  require 'react/component/state'
70
72
  require 'react/component/match'
71
73
  require 'react/component/location'
@@ -97,7 +99,6 @@ if RUBY_ENGINE == 'opal'
97
99
  require 'lucid_component/app_store_proxy'
98
100
  require 'lucid_component/class_store_proxy'
99
101
  require 'lucid_component/instance_store_proxy'
100
- require 'lucid_component/api'
101
102
  require 'lucid_component/initializer'
102
103
  require 'lucid_component/native_component_constructor'
103
104
  require 'lucid_component/event_handler'
@@ -121,6 +122,11 @@ else
121
122
  require 'react/version'
122
123
  require 'isomorfeus/config'
123
124
 
125
+ # props
126
+ require 'isomorfeus/props/validate_hash_proxy'
127
+ require 'isomorfeus/props/validator'
128
+ require 'lucid_prop_declaration/mixin'
129
+
124
130
  Isomorfeus.env = ENV['RACK_ENV']
125
131
 
126
132
  if Isomorfeus.production?
@@ -0,0 +1,180 @@
1
+ module Isomorfeus
2
+ module Props
3
+ class ValidateHashProxy
4
+ DEFAULT_HASH = { required: true, validate: {} }
5
+
6
+ def initialize
7
+ @validation_hash = DEFAULT_HASH
8
+ end
9
+
10
+ def is
11
+ self
12
+ end
13
+ alias_method :and, :is
14
+ alias_method :has, :is
15
+ alias_method :with, :is
16
+
17
+ def cast
18
+ @validation_hash[:cast] = true
19
+ self
20
+ end
21
+
22
+ def default(v)
23
+ @validation_hash[:required] = false
24
+ @validation_hash[:default] = v
25
+ self
26
+ end
27
+
28
+ def ensure(v = nil, &block)
29
+ if block_given?
30
+ @validation_hash[:ensure_block] = block
31
+ else
32
+ @validation_hash[:ensure] = v
33
+ end
34
+ self
35
+ end
36
+
37
+ def exact_class(t_class)
38
+ @validation_hash[:class] = t_class
39
+ self
40
+ end
41
+
42
+ def greater_than(v)
43
+ @validation_hash[:validate][:gt] = v
44
+ self
45
+ end
46
+ alias_method :gt, :greater_than
47
+
48
+ def is_a(i_class)
49
+ @validation_hash[:is_a] = i_class
50
+ self
51
+ end
52
+
53
+ def keys(*keys)
54
+ @validation_hash[:validate][:hash_keys] = keys
55
+ self
56
+ end
57
+
58
+ def size(l)
59
+ @validation_hash[:validate][:size] = v
60
+ self
61
+ end
62
+ alias_method :length, :size
63
+
64
+ def less_than(v)
65
+ @validation_hash[:validate][:lt] = v
66
+ self
67
+ end
68
+ alias_method :lt, :less_than
69
+
70
+ def matches(regexp)
71
+ @validation_hash[:validate][:matches] = regexp
72
+ self
73
+ end
74
+
75
+ def max(l)
76
+ @validation_hash[:validate][:max] = l
77
+ self
78
+ end
79
+
80
+ def max_size(l)
81
+ @validation_hash[:validate][:max_size] = l
82
+ self
83
+ end
84
+ alias_method :max_length, :max_size
85
+
86
+ def min(l)
87
+ @validation_hash[:validate][:min] = l
88
+ self
89
+ end
90
+
91
+ def min_size(l)
92
+ @validation_hash[:validate][:min_size] = l
93
+ self
94
+ end
95
+ alias_method :min_length, :min_size
96
+
97
+ def negative
98
+ @validation_hash[:validate][:direction] = :negative
99
+ self
100
+ end
101
+
102
+ def optional
103
+ @validation_hash[:required] = false
104
+ self
105
+ end
106
+
107
+ def positive
108
+ @validation_hash[:validate][:direction] = :positive
109
+ self
110
+ end
111
+
112
+ def required
113
+ @validation_hash[:required] = true
114
+ self
115
+ end
116
+
117
+ def test(&block)
118
+ @validation_hash[:validate][:test] = block
119
+ self
120
+ end
121
+ alias_method :condition, :test
122
+ alias_method :check, :test
123
+
124
+ # types
125
+
126
+ def Array
127
+ @validation_hash[:class] = Array
128
+ self
129
+ end
130
+
131
+ def Boolean
132
+ @validation_hash[:type] = :boolean
133
+ self
134
+ end
135
+
136
+ def Enumerable
137
+ @validation_hash[:is_a] = Enumerable
138
+ self
139
+ end
140
+
141
+ def Float
142
+ @validation_hash[:class] = Float
143
+ self
144
+ end
145
+
146
+ def Hash
147
+ @validation_hash[:class] = Hash
148
+ self
149
+ end
150
+
151
+ def Integer
152
+ @validation_hash[:class] = Integer
153
+ self
154
+ end
155
+
156
+ def String
157
+ @validation_hash[:class] = String
158
+ self
159
+ end
160
+
161
+ # sub types
162
+
163
+ def Email
164
+ @validation_hash[:type] = :string
165
+ @validation_hash[:validate][:sub_type] = :email
166
+ self
167
+ end
168
+
169
+ def Url
170
+ @validation_hash[:type] = :string
171
+ @validation_hash[:validate][:sub_type] = :url
172
+ self
173
+ end
174
+
175
+ def to_h
176
+ @validation_hash
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,129 @@
1
+ module Isomorfeus
2
+ module Props
3
+ class Validator
4
+ def intialize(source_class, prop, value, options)
5
+ @c = source_class
6
+ @p = prop
7
+ @v = value
8
+ @o = options
9
+ end
10
+
11
+ def validate!
12
+ ensured = ensure!
13
+ unless ensured
14
+ cast!
15
+ type!
16
+ end
17
+ run_checks!
18
+ true
19
+ end
20
+
21
+ private
22
+
23
+ # basic tests
24
+
25
+ def cast!
26
+ if @o.key?(:cast)
27
+ begin
28
+ @v = case @o[:class]
29
+ when Integer then value.to_i
30
+ when String then value.to_s
31
+ when Float then value.to_f
32
+ when Array then value.to_a
33
+ when Hash then value.to_h
34
+ end
35
+ @v = !!@v if @o[:type] == :boolean
36
+ rescue
37
+ raise "#{@c}: #{@p} cast failed" unless value.class == @o[:class]
38
+ end
39
+ end
40
+ end
41
+
42
+ def ensure!
43
+ if @o.key?(:ensure)
44
+ @v = @o[:ensure] unless @v
45
+ true
46
+ elsif @o.key?(:ensure_block)
47
+ @v = @o[:ensure_block].call(@v)
48
+ true
49
+ else
50
+ false
51
+ end
52
+ end
53
+
54
+ def type!
55
+ if @o.key?(:class)
56
+ raise "#{@c}: #{@p} class not #{@o[:class]}" unless value.class == @o[:class]
57
+ elsif @o.key?(:is_a)
58
+ raise "#{@c}: #{@p} is not a #{@o[:is_a]}" unless value.is_a?(@o[:is_a])
59
+ elsif @o.key?(:type)
60
+ case @o[:type]
61
+ when :boolean
62
+ raise "#{@c}: #{@p} is not a boolean" unless value.class == TrueClass || value.class == FalseClass
63
+ end
64
+ end
65
+ end
66
+
67
+ # all other checks
68
+
69
+ def run_checks!
70
+ @o[:validate].each do |m, l|
71
+ send('c_' + m, l)
72
+ end
73
+ end
74
+
75
+ # specific validations
76
+ def c_gt(v)
77
+ raise "#{@c}: #{@p} not greater than #{v}!" unless @v > v
78
+ end
79
+
80
+ def c_lt(v)
81
+ raise "#{@c}: #{@p} not less than #{v}!" unless @v < v
82
+ end
83
+
84
+ def c_keys(v)
85
+ raise "#{@c}: #{@p} keys dont fit!" unless @v.keys.sort == v.sort
86
+ end
87
+
88
+ def c_size(v)
89
+ raise "#{@c}: #{@p} length/size is not #{v}" unless @v.size == v
90
+ end
91
+
92
+ def c_matches(v)
93
+ raise "#{@c}: #{@p} does not match #{v}" unless v.matches?(@v)
94
+ end
95
+
96
+ def c_max(v)
97
+ raise "#{@c}: #{@p} is larger than #{v}" unless @v <= v
98
+ end
99
+
100
+ def c_min(v)
101
+ raise "#{@c}: #{@p} is smaller than #{v}" unless @v >= v
102
+ end
103
+
104
+ def c_max_size(v)
105
+ raise "#{@c}: #{@p} is larger than #{v}" unless @v.size <= v
106
+ end
107
+
108
+ def c_min_size(v)
109
+ raise "#{@c}: #{@p} is smaller than #{v}" unless @v.size >= v
110
+ end
111
+
112
+ def c_direction(v)
113
+ raise "#{@c}: #{@p} is positive" if v == :negative && @v >= 0
114
+ raise "#{@c}: #{@p} is negative" if v == :positive && @v < 0
115
+ end
116
+
117
+ def c_test
118
+ raise "#{@c}: #{@p} test condition check failed" unless @o[:test].call(@v)
119
+ end
120
+
121
+ def c_sub_type(v)
122
+ case v
123
+ when :email
124
+ when :url
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -3,7 +3,7 @@ module LucidApp
3
3
  def self.included(base)
4
4
  base.include(::Native::Wrapper)
5
5
  base.extend(::LucidApp::NativeComponentConstructor)
6
- base.extend(::React::Component::NativeComponentValidateProp)
6
+ base.extend(::LucidPropDeclaration::Mixin)
7
7
  base.extend(::React::Component::ShouldComponentUpdate)
8
8
  base.extend(::React::Component::EventHandler)
9
9
  base.include(::React::Component::Elements)
@@ -74,6 +74,11 @@ module LucidApp
74
74
  componentWillUnmount() {
75
75
  if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
76
76
  }
77
+ validateProp(props, propName, componentName) {
78
+ try { base.$validate_prop(propName, props[propName]) }
79
+ catch (e) { return new Error(componentName + ": Error: prop validation failed: " + e.message); }
80
+ return null;
81
+ }
77
82
  }
78
83
  }
79
84
  end
@@ -3,13 +3,12 @@ module LucidComponent
3
3
  def self.included(base)
4
4
  base.include(::Native::Wrapper)
5
5
  base.extend(::LucidComponent::NativeComponentConstructor)
6
- base.extend(::React::Component::NativeComponentValidateProp)
6
+ base.extend(::LucidPropDeclaration::Mixin)
7
7
  base.extend(::LucidComponent::EventHandler)
8
8
  base.include(::React::Component::Elements)
9
9
  base.include(::React::Component::API)
10
10
  base.include(::React::Component::Callbacks)
11
11
  base.include(::LucidComponent::StoreAPI)
12
- base.include(::LucidComponent::API)
13
12
  base.include(::LucidComponent::Initializer)
14
13
  base.include(::React::Component::Features)
15
14
  base.include(::React::Component::Resolution)
@@ -123,27 +123,8 @@ module LucidComponent
123
123
  return false;
124
124
  }
125
125
  validateProp(props, propName, componentName) {
126
- if (propName === "isomorfeus_store") { return null };
127
- var prop_data = base.lucid_react_component.propValidations[propName];
128
- if (!prop_data) { return true; };
129
- var value = props[propName];
130
- var result;
131
- if (typeof prop_data.ruby_class != "undefined") {
132
- result = (value.$class() == prop_data.ruby_class);
133
- if (!result) {
134
- return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
135
- }
136
- } else if (typeof prop_data.is_a != "undefined") {
137
- result = value["$is_a?"](prop_data.is_a);
138
- if (!result) {
139
- return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
140
- }
141
- }
142
- if (typeof prop_data.required != "undefined") {
143
- if (prop_data.required && (typeof props[propName] == "undefined")) {
144
- return new Error('Prop ' + propName + ' is required but not given!');
145
- }
146
- }
126
+ try { base.$validate_prop(propName, props[propName]) }
127
+ catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
147
128
  return null;
148
129
  }
149
130
  }
@@ -4,6 +4,7 @@ module LucidMaterial
4
4
  def self.included(base)
5
5
  base.include(::Native::Wrapper)
6
6
  base.extend(::LucidMaterial::App::NativeComponentConstructor)
7
+ base.extend(::LucidPropDeclaration::Mixin)
7
8
  base.extend(::React::Component::ShouldComponentUpdate)
8
9
  base.extend(::LucidComponent::EventHandler)
9
10
  base.include(::React::Component::Elements)
@@ -77,27 +77,8 @@ module LucidMaterial
77
77
  if (typeof this.unsubscriber === "function") { this.unsubscriber(); };
78
78
  }
79
79
  validateProp(props, propName, componentName) {
80
- if (propName === "isomorfeus_store") { return null };
81
- var prop_data = base.lucid_react_component.propValidations[propName];
82
- if (!prop_data) { return true; };
83
- var value = props[propName];
84
- var result;
85
- if (typeof prop_data.ruby_class != "undefined") {
86
- result = (value.$class() == prop_data.ruby_class);
87
- if (!result) {
88
- return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
89
- }
90
- } else if (typeof prop_data.is_a != "undefined") {
91
- result = value["$is_a?"](prop_data.is_a);
92
- if (!result) {
93
- return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
94
- }
95
- }
96
- if (typeof prop_data.required != "undefined") {
97
- if (prop_data.required && (typeof props[propName] == "undefined")) {
98
- return new Error('Prop ' + propName + ' is required but not given!');
99
- }
100
- }
80
+ try { base.$validate_prop(propName, props[propName]) }
81
+ catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
101
82
  return null;
102
83
  }
103
84
  }
@@ -4,13 +4,12 @@ module LucidMaterial
4
4
  def self.included(base)
5
5
  base.include(::Native::Wrapper)
6
6
  base.extend(::LucidMaterial::Component::NativeComponentConstructor)
7
- base.extend(::React::Component::NativeComponentValidateProp)
7
+ base.extend(::LucidPropDeclaration::Mixin)
8
8
  base.extend(::LucidComponent::EventHandler)
9
9
  base.include(::React::Component::Elements)
10
10
  base.include(::React::Component::API)
11
11
  base.include(::React::Component::Callbacks)
12
12
  base.include(::LucidComponent::StoreAPI)
13
- base.include(::LucidComponent::API)
14
13
  base.include(::LucidMaterial::Component::API)
15
14
  base.include(::LucidComponent::Initializer)
16
15
  base.include(::React::Component::Features)
@@ -119,27 +119,8 @@ module LucidMaterial
119
119
  return false;
120
120
  }
121
121
  validateProp(props, propName, componentName) {
122
- if (propName === "isomorfeus_store") { return null };
123
- var prop_data = base.lucid_react_component.propValidations[propName];
124
- if (!prop_data) { return true; };
125
- var value = props[propName];
126
- var result;
127
- if (typeof prop_data.ruby_class != "undefined") {
128
- result = (value.$class() == prop_data.ruby_class);
129
- if (!result) {
130
- return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
131
- }
132
- } else if (typeof prop_data.is_a != "undefined") {
133
- result = value["$is_a?"](prop_data.is_a);
134
- if (!result) {
135
- return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
136
- }
137
- }
138
- if (typeof prop_data.required != "undefined") {
139
- if (prop_data.required && (typeof props[propName] == "undefined")) {
140
- return new Error('Prop ' + propName + ' is required but not given!');
141
- }
142
- }
122
+ try { base.$validate_prop(propName, props[propName]) }
123
+ catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
143
124
  return null;
144
125
  }
145
126
  };
@@ -0,0 +1,89 @@
1
+ module LucidPropDeclaration
2
+ module Mixin
3
+ if RUBY_ENGINE == 'opal'
4
+ def self.extended(base)
5
+
6
+ def prop(prop_name, validate_hash = { required: true })
7
+ validate_hash = validate_hash.to_h if validate_hash.class == Isomorfeus::Props::ValidateHashProxy
8
+ if validate_hash.key?(:default)
9
+ %x{
10
+ if (base.lucid_react_component) {
11
+ let react_prop_name = Opal.React.lower_camelize(prop_name);
12
+ #{value = validate_hash[:default]}
13
+ if (!base.lucid_react_component.defaultProps) { base.lucid_react_component.defaultProps = {}; }
14
+ base.lucid_react_component.defaultProps[react_prop_name] = value;
15
+ if (!base.lucid_react_component.propTypes) { base.lucid_react_component.propTypes = {}; }
16
+ base.lucid_react_component.propTypes[react_prop_name] = base.lucid_react_component.prototype.validateProp;
17
+ } else if (base.react_component) {
18
+ let react_prop_name = Opal.React.lower_camelize(prop_name);
19
+ #{value = validate_hash[:default]}
20
+ if (!base.react_component.defaultProps) { base.react_component.defaultProps = {}; }
21
+ base.react_component.defaultProps[react_prop_name] = value;
22
+ if (!base.react_component.propTypes) { base.react_component.propTypes = {}; }
23
+ base.react_component.propTypes[react_prop_name] = base.react_component.prototype.validateProp;
24
+ }
25
+ }
26
+ end
27
+ declared_props[prop_name.to_sym] = validate_hash
28
+ end
29
+ end
30
+
31
+ def validate_function
32
+ %x{
33
+ if (typeof base.validate_function === 'undefined') {
34
+ base.validate_function = function(props_object) {
35
+ return base.$validate_props(`Opal.Hash.new(props_object)`)
36
+ }
37
+ }
38
+ return base.validate_function;
39
+ }
40
+ end
41
+
42
+ def validate_prop_function(prop)
43
+ function_name = "validate_#{prop}_function"
44
+ %x{
45
+ if (typeof base[function_name] === 'undefined') {
46
+ base[function_name] = function(value) {
47
+ return base.$validate_prop(prop, value);
48
+ }
49
+ }
50
+ return base[function_name];
51
+ }
52
+ end
53
+ else
54
+ def prop(prop_name, validate_hash = { required: true })
55
+ validate_hash = validate_hash.to_h if validate_hash.class == Isomorfeus::Props::ValidateHashProxy
56
+ declared_props[prop_name.to_sym] = validate_hash
57
+ end
58
+ end
59
+
60
+ def declared_props
61
+ @declared_props ||= {}
62
+ end
63
+
64
+ def validate
65
+ Isomorfeus::Props::ValidateHashProxy.new
66
+ end
67
+
68
+ def validate_prop(prop, value)
69
+ return false unless declared_props.key?(prop)
70
+ validator = Isomorfeus::Props::Validator.new(self, prop, value, declared_props[prop])
71
+ validator.validate!
72
+ true
73
+ end
74
+
75
+ def validate_props(props)
76
+ declared_props.each_key do |prop|
77
+ if declared_props[prop].key?(:required) && declared_props[prop][:required] && !props.key?[prop]
78
+ raise "Required prop #{prop} not given!"
79
+ end
80
+ end
81
+ result = true
82
+ props.each do |p, v|
83
+ r = validate_prop(p, v)
84
+ result = false unless r
85
+ end
86
+ result
87
+ end
88
+ end
89
+ end
@@ -44,57 +44,6 @@ module React
44
44
  @default_state = React::Component::State.new(`native_state`)
45
45
  end
46
46
 
47
- def prop(name, options = `null`)
48
- name = `Opal.React.lower_camelize(name)`
49
- if options
50
- if options.key?(:default)
51
- %x{
52
- if (typeof self.react_component.defaultProps == "undefined") {
53
- self.react_component.defaultProps = {};
54
- }
55
- self.react_component.defaultProps[name] = options.$fetch("default");
56
- }
57
- end
58
- if options.key?(:class)
59
- %x{
60
- Opal.React.set_validate_prop(self, name);
61
- self.react_component.propValidations[name].ruby_class = options.$fetch("class");
62
- }
63
- elsif options.key?(:is_a)
64
- %x{
65
- Opal.React.set_validate_prop(self, name);
66
- self.react_component.propValidations[name].is_a = options.$fetch("is_a");
67
- }
68
- end
69
- if options.key?(:required)
70
- %x{
71
- Opal.React.set_validate_prop(self, name);
72
- self.react_component.propValidations[name].required = options.$fetch("required");
73
- }
74
- elsif !options.key?(:default)
75
- %x{
76
- Opal.React.set_validate_prop(self, name);
77
- self.react_component.propValidations[name].required = true;
78
- }
79
- end
80
- else
81
- %x{
82
- Opal.React.set_validate_prop(self, name);
83
- self.react_component.propValidations[name].required = true;
84
- }
85
- end
86
- end
87
-
88
- def default_props
89
- return @default_props if @default_props
90
- %x{
91
- if (typeof self.react_component.defaultProps == "undefined") {
92
- self.lucid_react_component.defaultProps = {};
93
- }
94
- }
95
- @default_props = `Opal.React.Component.Props.$new({props: self.react_component.defaultProps})`
96
- end
97
-
98
47
  def render(&block)
99
48
  `base.render_block = block`
100
49
  end
@@ -4,13 +4,12 @@ module React
4
4
  def self.included(base)
5
5
  base.include(::Native::Wrapper)
6
6
  base.extend(::React::Component::NativeComponentConstructor)
7
- base.extend(::React::Component::NativeComponentValidateProp)
7
+ base.extend(::LucidPropDeclaration::Mixin)
8
8
  base.extend(::React::Component::ShouldComponentUpdate)
9
9
  base.extend(::React::Component::EventHandler)
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)
14
13
  base.include(::React::Component::Initializer)
15
14
  base.include(::React::Component::Features)
16
15
  base.include(::React::Component::Resolution)
@@ -80,6 +80,11 @@ module React
80
80
  return false;
81
81
  }
82
82
  }
83
+ validateProp(props, propName, componentName) {
84
+ try { base.$validate_prop(propName, props[propName]) }
85
+ catch (e) { return new Error(componentName + " Error: prop validation failed: " + e.message); }
86
+ return null;
87
+ }
83
88
  }
84
89
  }
85
90
  end
@@ -4,12 +4,11 @@ module React
4
4
  def self.included(base)
5
5
  base.include(::Native::Wrapper)
6
6
  base.extend(::React::Component::NativeComponentConstructor)
7
- base.extend(::React::Component::NativeComponentValidateProp)
7
+ base.extend(::LucidPropDeclaration::Mixin)
8
8
  base.extend(::React::Component::EventHandler)
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)
13
12
  base.include(::React::Component::Initializer)
14
13
  base.include(::React::Component::Features)
15
14
  base.include(::React::Component::Resolution)
data/lib/react/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module React
2
- VERSION = '16.9.9'
2
+ VERSION = '16.9.10'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isomorfeus-react
3
3
  version: !ruby/object:Gem::Version
4
- version: 16.9.9
4
+ version: 16.9.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-22 00:00:00.000000000 Z
11
+ date: 2019-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -170,6 +170,8 @@ files:
170
170
  - lib/isomorfeus-react.rb
171
171
  - lib/isomorfeus/config.rb
172
172
  - lib/isomorfeus/execution_environment.rb
173
+ - lib/isomorfeus/props/validate_hash_proxy.rb
174
+ - lib/isomorfeus/props/validator.rb
173
175
  - lib/isomorfeus/react_view_helper.rb
174
176
  - lib/isomorfeus/top_level_browser.rb
175
177
  - lib/isomorfeus/top_level_ssr.rb
@@ -178,7 +180,6 @@ files:
178
180
  - lib/lucid_app/context.rb
179
181
  - lib/lucid_app/mixin.rb
180
182
  - lib/lucid_app/native_component_constructor.rb
181
- - lib/lucid_component/api.rb
182
183
  - lib/lucid_component/app_store_defaults.rb
183
184
  - lib/lucid_component/app_store_proxy.rb
184
185
  - lib/lucid_component/base.rb
@@ -199,6 +200,7 @@ files:
199
200
  - lib/lucid_material/component/base.rb
200
201
  - lib/lucid_material/component/mixin.rb
201
202
  - lib/lucid_material/component/native_component_constructor.rb
203
+ - lib/lucid_prop_declaration/mixin.rb
202
204
  - lib/react.rb
203
205
  - lib/react/active_support_support.rb
204
206
  - lib/react/children.rb
@@ -214,7 +216,6 @@ files:
214
216
  - lib/react/component/match.rb
215
217
  - lib/react/component/mixin.rb
216
218
  - lib/react/component/native_component_constructor.rb
217
- - lib/react/component/native_component_validate_prop.rb
218
219
  - lib/react/component/props.rb
219
220
  - lib/react/component/resolution.rb
220
221
  - lib/react/component/should_component_update.rb
@@ -1,82 +0,0 @@
1
- module LucidComponent
2
- module API
3
- def self.included(base)
4
- base.instance_exec do
5
- def prop(name, options = `null`)
6
- name = `Opal.React.lower_camelize(name)`
7
- if options
8
- if options.key?(:default)
9
- %x{
10
- if (typeof self.lucid_react_component.defaultProps == "undefined") {
11
- self.lucid_react_component.defaultProps = { isomorfeus_store: Opal.Hash.$new() };
12
- }
13
- self.lucid_react_component.defaultProps[name] = options.$fetch("default");
14
- }
15
- end
16
- if options.key?(:class)
17
- %x{
18
- if (typeof self.lucid_react_component.propTypes == "undefined") {
19
- self.lucid_react_component.propTypes = {};
20
- self.lucid_react_component.propValidations = {};
21
- self.lucid_react_component.propValidations[name] = {};
22
- }
23
- self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
24
- self.lucid_react_component.propValidations[name].ruby_class = options.$fetch("class");
25
- }
26
- elsif options.key?(:is_a)
27
- %x{
28
- if (typeof self.lucid_react_component.propTypes == "undefined") {
29
- self.lucid_react_component.propTypes = {};
30
- self.lucid_react_component.propValidations = {};
31
- self.lucid_react_component.propValidations[name] = {};
32
- }
33
- self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
34
- self.lucid_react_component.propValidations[name].is_a = options.$fetch("is_a");
35
- }
36
- end
37
- if options.key?(:required)
38
- %x{
39
- if (typeof self.lucid_react_component.propTypes == "undefined") {
40
- self.lucid_react_component.propTypes = {};
41
- self.lucid_react_component.propValidations = {};
42
- self.lucid_react_component.propValidations[name] = {};
43
- }
44
- self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
45
- self.lucid_react_component.propValidations[name].required = options.$fetch("required");
46
- }
47
- elsif !options.key?(:default)
48
- %x{
49
- if (typeof self.lucid_react_component.propTypes == "undefined") {
50
- self.lucid_react_component.propTypes = {};
51
- self.lucid_react_component.propValidations = {};
52
- }
53
- self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
54
- self.lucid_react_component.propValidations[name].required = true;
55
- }
56
- end
57
- else
58
- %x{
59
- if (typeof self.lucid_react_component.propTypes == "undefined") {
60
- self.lucid_react_component.propTypes = {};
61
- self.lucid_react_component.propValidations = {};
62
- self.lucid_react_component.propValidations[name] = {};
63
- }
64
- self.lucid_react_component.propTypes[name] = self.lucid_react_component.prototype.validateProp;
65
- self.lucid_react_component.propValidations[name].required = true;
66
- }
67
- end
68
- end
69
-
70
- def default_props
71
- return @default_props if @default_props
72
- %x{
73
- if (typeof self.lucid_react_component.defaultProps == "undefined") {
74
- self.lucid_react_component.defaultProps = { isomorfeus_store: Opal.Hash.$new() };
75
- }
76
- }
77
- @default_props = React::Component::Props.new(`{props: self.lucid_react_component.defaultProps}`)
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,37 +0,0 @@
1
- module React
2
- module Component
3
- module NativeComponentValidateProp
4
- # for should_component_update we apply ruby semantics for comparing props
5
- # to do so, we convert the props to ruby hashes and then compare
6
- # this makes sure, that for example rubys Nil object gets handled properly
7
- def self.extended(base)
8
- # language=JS
9
- %x{
10
- base.react_component.prototype.validateProp = function(props, propName, componentName) {
11
- var prop_data = base.react_component.propValidations[propName];
12
- if (!prop_data) { return true; };
13
- var value = props[propName];
14
- var result;
15
- if (typeof prop_data.ruby_class != "undefined") {
16
- result = (value.$class() == prop_data.ruby_class);
17
- if (!result) {
18
- return new Error('Invalid prop ' + propName + '! Expected ' + prop_data.ruby_class.$to_s() + ' but was ' + value.$class().$to_s() + '!');
19
- }
20
- } else if (typeof prop_data.is_a != "undefined") {
21
- result = value["$is_a?"](prop_data.is_a);
22
- if (!result) {
23
- return new Error('Invalid prop ' + propName + '! Expected a child of ' + prop_data.is_a.$to_s() + '!');
24
- }
25
- }
26
- if (typeof prop_data.required != "undefined") {
27
- if (prop_data.required && (typeof props[propName] == "undefined")) {
28
- return new Error('Prop ' + propName + ' is required but not given!');
29
- }
30
- }
31
- return null;
32
- }
33
- }
34
- end
35
- end
36
- end
37
- end