reactrb 0.7.42

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 (173) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +6 -0
  3. data/.gitignore +33 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE +19 -0
  7. data/README.md +117 -0
  8. data/Rakefile +28 -0
  9. data/config.ru +16 -0
  10. data/example/examples/Gemfile +7 -0
  11. data/example/examples/app/basics.js.rb +42 -0
  12. data/example/examples/app/items.rb +11 -0
  13. data/example/examples/app/jquery.js +5 -0
  14. data/example/examples/app/nodes.rb +61 -0
  15. data/example/examples/app/react-router.js +6 -0
  16. data/example/examples/app/react_api_demo.rb +29 -0
  17. data/example/examples/app/rerendering.rb +72 -0
  18. data/example/examples/app/reuse.rb +59 -0
  19. data/example/examples/app/show.rb +52 -0
  20. data/example/examples/config.ru +38 -0
  21. data/example/rails-tutorial/.gitignore +17 -0
  22. data/example/rails-tutorial/Gemfile +51 -0
  23. data/example/rails-tutorial/README.rdoc +28 -0
  24. data/example/rails-tutorial/Rakefile +6 -0
  25. data/example/rails-tutorial/app/assets/images/.keep +0 -0
  26. data/example/rails-tutorial/app/assets/javascripts/application.rb +15 -0
  27. data/example/rails-tutorial/app/assets/stylesheets/application.css +15 -0
  28. data/example/rails-tutorial/app/controllers/application_controller.rb +6 -0
  29. data/example/rails-tutorial/app/controllers/concerns/.keep +0 -0
  30. data/example/rails-tutorial/app/controllers/home_controller.rb +6 -0
  31. data/example/rails-tutorial/app/helpers/application_helper.rb +2 -0
  32. data/example/rails-tutorial/app/mailers/.keep +0 -0
  33. data/example/rails-tutorial/app/models/.keep +0 -0
  34. data/example/rails-tutorial/app/models/concerns/.keep +0 -0
  35. data/example/rails-tutorial/app/views/components.rb +3 -0
  36. data/example/rails-tutorial/app/views/components/home/show.rb +47 -0
  37. data/example/rails-tutorial/app/views/layouts/application.html.erb +14 -0
  38. data/example/rails-tutorial/bin/bundle +3 -0
  39. data/example/rails-tutorial/bin/rails +8 -0
  40. data/example/rails-tutorial/bin/rake +8 -0
  41. data/example/rails-tutorial/bin/setup +29 -0
  42. data/example/rails-tutorial/bin/spring +15 -0
  43. data/example/rails-tutorial/config.ru +4 -0
  44. data/example/rails-tutorial/config/application.rb +26 -0
  45. data/example/rails-tutorial/config/boot.rb +3 -0
  46. data/example/rails-tutorial/config/database.yml +25 -0
  47. data/example/rails-tutorial/config/environment.rb +5 -0
  48. data/example/rails-tutorial/config/environments/development.rb +41 -0
  49. data/example/rails-tutorial/config/environments/production.rb +79 -0
  50. data/example/rails-tutorial/config/environments/test.rb +42 -0
  51. data/example/rails-tutorial/config/initializers/assets.rb +11 -0
  52. data/example/rails-tutorial/config/initializers/backtrace_silencers.rb +7 -0
  53. data/example/rails-tutorial/config/initializers/cookies_serializer.rb +3 -0
  54. data/example/rails-tutorial/config/initializers/filter_parameter_logging.rb +4 -0
  55. data/example/rails-tutorial/config/initializers/inflections.rb +16 -0
  56. data/example/rails-tutorial/config/initializers/mime_types.rb +4 -0
  57. data/example/rails-tutorial/config/initializers/session_store.rb +3 -0
  58. data/example/rails-tutorial/config/initializers/wrap_parameters.rb +14 -0
  59. data/example/rails-tutorial/config/locales/en.yml +23 -0
  60. data/example/rails-tutorial/config/routes.rb +59 -0
  61. data/example/rails-tutorial/config/secrets.yml +22 -0
  62. data/example/rails-tutorial/db/seeds.rb +7 -0
  63. data/example/rails-tutorial/lib/assets/.keep +0 -0
  64. data/example/rails-tutorial/lib/tasks/.keep +0 -0
  65. data/example/rails-tutorial/log/.keep +0 -0
  66. data/example/rails-tutorial/public/404.html +67 -0
  67. data/example/rails-tutorial/public/422.html +67 -0
  68. data/example/rails-tutorial/public/500.html +66 -0
  69. data/example/rails-tutorial/public/favicon.ico +0 -0
  70. data/example/rails-tutorial/public/robots.txt +5 -0
  71. data/example/rails-tutorial/test/controllers/.keep +0 -0
  72. data/example/rails-tutorial/test/fixtures/.keep +0 -0
  73. data/example/rails-tutorial/test/helpers/.keep +0 -0
  74. data/example/rails-tutorial/test/integration/.keep +0 -0
  75. data/example/rails-tutorial/test/mailers/.keep +0 -0
  76. data/example/rails-tutorial/test/models/.keep +0 -0
  77. data/example/rails-tutorial/test/test_helper.rb +10 -0
  78. data/example/rails-tutorial/vendor/assets/javascripts/.keep +0 -0
  79. data/example/rails-tutorial/vendor/assets/stylesheets/.keep +0 -0
  80. data/example/sinatra-tutorial/.DS_Store +0 -0
  81. data/example/sinatra-tutorial/Gemfile +5 -0
  82. data/example/sinatra-tutorial/README.md +8 -0
  83. data/example/sinatra-tutorial/_comments.json +42 -0
  84. data/example/sinatra-tutorial/app/example.rb +290 -0
  85. data/example/sinatra-tutorial/app/jquery.js +5 -0
  86. data/example/sinatra-tutorial/config.ru +58 -0
  87. data/example/sinatra-tutorial/public/base.css +62 -0
  88. data/example/todos/Gemfile +11 -0
  89. data/example/todos/README.md +37 -0
  90. data/example/todos/Rakefile +8 -0
  91. data/example/todos/app/application.rb +22 -0
  92. data/example/todos/app/components/app.react.rb +61 -0
  93. data/example/todos/app/components/footer.react.rb +31 -0
  94. data/example/todos/app/components/todo_item.react.rb +46 -0
  95. data/example/todos/app/components/todo_list.react.rb +25 -0
  96. data/example/todos/app/models/todo.rb +19 -0
  97. data/example/todos/config.ru +14 -0
  98. data/example/todos/index.html.haml +16 -0
  99. data/example/todos/spec/todo_spec.rb +28 -0
  100. data/example/todos/vendor/base.css +410 -0
  101. data/example/todos/vendor/bg.png +0 -0
  102. data/example/todos/vendor/jquery.js +4 -0
  103. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +4 -0
  104. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +2 -0
  105. data/lib/generators/reactive_ruby/test_app/templates/boot.rb.erb +6 -0
  106. data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
  107. data/lib/generators/reactive_ruby/test_app/templates/test_application.rb.erb +13 -0
  108. data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
  109. data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
  110. data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +105 -0
  111. data/lib/rails-helpers/top_level_rails_component.rb +54 -0
  112. data/lib/react/api.rb +127 -0
  113. data/lib/react/callbacks.rb +42 -0
  114. data/lib/react/component.rb +269 -0
  115. data/lib/react/component/api.rb +50 -0
  116. data/lib/react/component/base.rb +9 -0
  117. data/lib/react/component/class_methods.rb +190 -0
  118. data/lib/react/component/props_wrapper.rb +82 -0
  119. data/lib/react/element.rb +77 -0
  120. data/lib/react/event.rb +76 -0
  121. data/lib/react/ext/hash.rb +9 -0
  122. data/lib/react/ext/string.rb +8 -0
  123. data/lib/react/native_library.rb +53 -0
  124. data/lib/react/observable.rb +29 -0
  125. data/lib/react/rendering_context.rb +109 -0
  126. data/lib/react/state.rb +140 -0
  127. data/lib/react/top_level.rb +97 -0
  128. data/lib/react/validator.rb +136 -0
  129. data/lib/reactive-ruby/component_loader.rb +45 -0
  130. data/lib/reactive-ruby/isomorphic_helpers.rb +196 -0
  131. data/lib/reactive-ruby/rails.rb +7 -0
  132. data/lib/reactive-ruby/rails/component_mount.rb +44 -0
  133. data/lib/reactive-ruby/rails/controller_helper.rb +13 -0
  134. data/lib/reactive-ruby/rails/railtie.rb +14 -0
  135. data/lib/reactive-ruby/serializers.rb +15 -0
  136. data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +42 -0
  137. data/lib/reactive-ruby/version.rb +3 -0
  138. data/lib/reactrb.rb +50 -0
  139. data/lib/sources/react-latest.js +21167 -0
  140. data/lib/sources/react-v13.js +21642 -0
  141. data/lib/sources/react-v14.js +20818 -0
  142. data/lib/sources/react-v15.js +21167 -0
  143. data/logo1.png +0 -0
  144. data/logo2.png +0 -0
  145. data/logo3.png +0 -0
  146. data/path_release_steps.md +9 -0
  147. data/reactrb.gemspec +43 -0
  148. data/spec/controller_helper_spec.rb +22 -0
  149. data/spec/index.html.erb +12 -0
  150. data/spec/react/callbacks_spec.rb +106 -0
  151. data/spec/react/component/base_spec.rb +36 -0
  152. data/spec/react/component_spec.rb +721 -0
  153. data/spec/react/dsl_spec.rb +161 -0
  154. data/spec/react/element_spec.rb +47 -0
  155. data/spec/react/event_spec.rb +24 -0
  156. data/spec/react/native_library_spec.rb +10 -0
  157. data/spec/react/observable_spec.rb +7 -0
  158. data/spec/react/param_declaration_spec.rb +286 -0
  159. data/spec/react/react_spec.rb +211 -0
  160. data/spec/react/state_spec.rb +26 -0
  161. data/spec/react/top_level_component_spec.rb +68 -0
  162. data/spec/react/tutorial/tutorial_spec.rb +35 -0
  163. data/spec/react/validator_spec.rb +128 -0
  164. data/spec/reactive-ruby/component_loader_spec.rb +68 -0
  165. data/spec/reactive-ruby/isomorphic_helpers_spec.rb +155 -0
  166. data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +9 -0
  167. data/spec/reactive-ruby/rails/component_mount_spec.rb +66 -0
  168. data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +35 -0
  169. data/spec/spec_helper.rb +109 -0
  170. data/spec/support/react/spec_helpers.rb +57 -0
  171. data/spec/vendor/es5-shim.min.js +6 -0
  172. data/spec/vendor/jquery-2.2.4.min.js +4 -0
  173. metadata +441 -0
@@ -0,0 +1,9 @@
1
+ class Hash
2
+ def shallow_to_n
3
+ hash = `{}`
4
+ self.map do |key, value|
5
+ `hash[#{key}] = #{value}`
6
+ end
7
+ hash
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ class String
2
+ def event_camelize
3
+ `#{self}.replace(/(^|_)([^_]+)/g, function(match, pre, word, index) {
4
+ var capitalize = true;
5
+ return capitalize ? word.substr(0,1).toUpperCase()+word.substr(1) : word;
6
+ })`
7
+ end
8
+ end
@@ -0,0 +1,53 @@
1
+ module React
2
+ class NativeLibrary
3
+ def self.renames_and_exclusions
4
+ @renames_and_exclusions ||= {}
5
+ end
6
+
7
+ def self.libraries
8
+ @libraries ||= []
9
+ end
10
+
11
+ def self.const_missing(name)
12
+ if renames_and_exclusions.has_key? name
13
+ if native_name = renames_and_exclusions[name]
14
+ native_name
15
+ else
16
+ super
17
+ end
18
+ else
19
+ libraries.each do |library|
20
+ native_name = "#{library}.#{name}"
21
+ native_component = `eval(#{native_name})` rescue nil
22
+ React::API.import_native_component(name, native_component) and return name if native_component and `native_component != undefined`
23
+ end
24
+ name
25
+ end
26
+ end
27
+
28
+ def self.method_missing(n, *args, &block)
29
+ name = n
30
+ if name =~ /_as_node$/
31
+ node_only = true
32
+ name = name.gsub(/_as_node$/, "")
33
+ end
34
+ unless name = const_get(name)
35
+ return super
36
+ end
37
+ React::RenderingContext.build_or_render(node_only, name, *args, &block)
38
+ rescue
39
+ end
40
+
41
+ def self.imports(library)
42
+ libraries << library
43
+ end
44
+
45
+ def self.rename(rename_list={})
46
+ renames_and_exclusions.merge!(rename_list.invert)
47
+ end
48
+
49
+ def self.exclude(*exclude_list)
50
+ renames_and_exclusions.merge(Hash[exclude_list.map {|k| [k, nil]}])
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,29 @@
1
+ module React
2
+ class Observable
3
+ def initialize(value, on_change = nil, &block)
4
+ @value = value
5
+ @on_change = on_change || block
6
+ end
7
+
8
+ def method_missing(method_sym, *args, &block)
9
+ @value.send(method_sym, *args, &block).tap { |result| @on_change.call @value }
10
+ end
11
+
12
+ def respond_to?(method, *args)
13
+ if [:call, :to_proc].include? method
14
+ true
15
+ else
16
+ @value.respond_to? method, *args
17
+ end
18
+ end
19
+
20
+ def call(new_value)
21
+ @on_change.call new_value
22
+ @value = new_value
23
+ end
24
+
25
+ def to_proc
26
+ lambda { |arg = @value| @on_change.call arg }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,109 @@
1
+ module React
2
+ class RenderingContext
3
+ class << self
4
+ attr_accessor :waiting_on_resources
5
+ end
6
+
7
+ def self.build_or_render(node_only, name, *args, &block)
8
+ if node_only
9
+ React::RenderingContext.build { React::RenderingContext.render(name, *args, &block) }.to_n
10
+ else
11
+ React::RenderingContext.render(name, *args, &block)
12
+ end
13
+ end
14
+
15
+ def self.render(name, *args, &block)
16
+ remove_nodes_from_args(args)
17
+ @buffer = [] unless @buffer
18
+ if block
19
+ element = build do
20
+ saved_waiting_on_resources = waiting_on_resources
21
+ self.waiting_on_resources = nil
22
+ result = block.call
23
+ # Todo figure out how children rendering should happen, probably should have special method that pushes children into the buffer
24
+ # i.e. render_child/render_children that takes Element/Array[Element] and does the push into the buffer
25
+ if !name && ( # !name means called from outer render so we check that it has rendered correctly
26
+ (@buffer.count > 1) || # should only render one element
27
+ (@buffer.count == 1 && @buffer.last != result) || # it should return that element
28
+ (@buffer.count == 0 && !(result.is_a?(String) || (result.respond_to?(:acts_as_string?) && result.acts_as_string?) || result.is_a?(Element))) #for convience we will also convert the return value to a span if its a string
29
+ )
30
+ raise "a components render method must generate and return exactly 1 element or a string"
31
+ end
32
+
33
+ @buffer << result.to_s if result.is_a? String || (result.respond_to?(:acts_as_string?) && result.acts_as_string?) # For convience we push the last return value on if its a string
34
+ @buffer << result if result.is_a?(Element) && @buffer.count == 0
35
+ if name
36
+ buffer = @buffer.dup
37
+ React.create_element(name, *args) { buffer }.tap do |element|
38
+ element.waiting_on_resources = saved_waiting_on_resources || !!buffer.detect { |e| e.waiting_on_resources if e.respond_to?(:waiting_on_resources) }
39
+ end
40
+ elsif @buffer.last.is_a? React::Element
41
+ @buffer.last.tap { |element| element.waiting_on_resources ||= saved_waiting_on_resources }
42
+ else
43
+ @buffer.last.to_s.span.tap { |element| element.waiting_on_resources = saved_waiting_on_resources }
44
+ end
45
+ end
46
+ elsif name.is_a? React::Element
47
+ element = name
48
+ # I BELIEVE WAITING ON RESOURCES SHOULD ALREADY BE SET
49
+ else
50
+ element = React.create_element(name, *args)
51
+ element.waiting_on_resources = waiting_on_resources
52
+ end
53
+ @buffer << element
54
+ self.waiting_on_resources = nil
55
+ element
56
+ end
57
+
58
+ def self.build(&block)
59
+ current = @buffer
60
+ @buffer = []
61
+ return_val = yield @buffer
62
+ @buffer = current
63
+ return_val
64
+ #ensure
65
+ # @buffer = current
66
+ # return_val
67
+ end
68
+
69
+ def self.as_node(element)
70
+ @buffer.delete(element)
71
+ element
72
+ end
73
+
74
+ class << self; alias_method :delete, :as_node; end
75
+
76
+ def self.replace(e1, e2)
77
+ @buffer[@buffer.index(e1)] = e2
78
+ end
79
+
80
+ def self.remove_nodes_from_args(args)
81
+ args[0].each do |key, value|
82
+ value.as_node if value.is_a?(Element) rescue nil
83
+ end if args[0] && args[0].is_a?(Hash)
84
+ end
85
+ end
86
+
87
+ class ::Object
88
+ alias_method :old_method_missing, :method_missing
89
+
90
+ ["span", "para", "td", "th", "while_loading"].each do |tag|
91
+ define_method(tag) do | *args, &block |
92
+ args.unshift(tag)
93
+ return self.method_missing(*args, &block) if self.is_a? React::Component
94
+ React::RenderingContext.render(*args) { self.to_s }
95
+ end
96
+ end
97
+
98
+ def para(*args, &block)
99
+ args.unshift("p")
100
+ return self.method_missing(*args, &block) if self.is_a? React::Component
101
+ React::RenderingContext.render(*args) { self.to_s }
102
+ end
103
+
104
+ def br
105
+ return self.method_missing(*["br"]) if self.is_a? React::Component
106
+ React::RenderingContext.render("span") { React::RenderingContext.render(self.to_s); React::RenderingContext.render("br") }
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,140 @@
1
+ module React
2
+ class StateWrapper < BasicObject
3
+ def initialize(native, from)
4
+ @state_hash = Hash.new(`#{native}.state`)
5
+ @from = from
6
+ end
7
+
8
+ def [](state)
9
+ @state_hash[state]
10
+ end
11
+
12
+ def []=(state, new_value)
13
+ @state_hash[state] = new_value
14
+ end
15
+
16
+ def method_missing(method, *args)
17
+ if match = method.match(/^(.+)\!$/)
18
+ if args.count > 0
19
+ current_value = State.get_state(@from, match[1])
20
+ State.set_state(@from, $1, args[0])
21
+ current_value
22
+ else
23
+ current_state = State.get_state(@from, match[1])
24
+ State.set_state(@from, $1, current_state)
25
+ Observable.new(current_state) do |update|
26
+ State.set_state(@from, $1, update)
27
+ end
28
+ end
29
+ else
30
+ State.get_state(@from, method)
31
+ end
32
+ end
33
+ end
34
+
35
+ class State
36
+ class << self
37
+ attr_reader :current_observer
38
+
39
+ def initialize_states(object, initial_values) # initialize objects' name/value pairs
40
+ states[object].merge!(initial_values || {})
41
+ end
42
+
43
+ def get_state(object, name, current_observer = @current_observer)
44
+ # get current value of name for object, remember that the current object depends on this state, current observer can be overriden with last param
45
+ new_observers[current_observer][object] << name if current_observer && !new_observers[current_observer][object].include?(name)
46
+ states[object][name]
47
+ end
48
+
49
+ def set_state2(object, name, value) # set object's name state to value, tell all observers it has changed. Observers must implement update_react_js_state
50
+ object_needs_notification = object.respond_to? :update_react_js_state
51
+ observers_by_name[object][name].dup.each do |observer|
52
+ observer.update_react_js_state(object, name, value)
53
+ object_needs_notification = false if object == observer
54
+ end
55
+ object.update_react_js_state(nil, name, value) if object_needs_notification
56
+ end
57
+
58
+ def set_state(object, name, value, delay=nil)
59
+ states[object][name] = value
60
+ if delay
61
+ @delayed_updates ||= []
62
+ @delayed_updates << [object, name, value]
63
+ @delayed_updater ||= after(0.001) do
64
+ delayed_updates = @delayed_updates
65
+ @delayed_updates = []
66
+ @delayed_updater = nil
67
+ delayed_updates.each do |object, name, value|
68
+ set_state2(object, name, value)
69
+ end
70
+ end
71
+ else
72
+ set_state2(object, name, value)
73
+ end
74
+ value
75
+ end
76
+
77
+ def will_be_observing?(object, name, current_observer)
78
+ current_observer && new_observers[current_observer][object].include?(name)
79
+ end
80
+
81
+ def is_observing?(object, name, current_observer)
82
+ current_observer && observers_by_name[object][name].include?(current_observer)
83
+ end
84
+
85
+ def update_states_to_observe(current_observer = @current_observer) # should be called after the last after_render callback, currently called after components render method
86
+ raise "update_states_to_observer called outside of watch block" unless current_observer
87
+ current_observers[current_observer].each do |object, names|
88
+ names.each do |name|
89
+ observers_by_name[object][name].delete(current_observer)
90
+ end
91
+ end
92
+ observers = current_observers[current_observer] = new_observers[current_observer]
93
+ new_observers.delete(current_observer)
94
+ observers.each do |object, names|
95
+ names.each do |name|
96
+ observers_by_name[object][name] << current_observer
97
+ end
98
+ end
99
+ end
100
+
101
+ def remove # call after component is unmounted
102
+ raise "remove called outside of watch block" unless @current_observer
103
+ current_observers[@current_observer].each do |object, names|
104
+ names.each do |name|
105
+ observers_by_name[object][name].delete(@current_observer)
106
+ end
107
+ end
108
+ current_observers.delete(@current_observer)
109
+ end
110
+
111
+ def set_state_context_to(observer) # wrap all execution that may set or get states in a block so we know which observer is executing
112
+ if `typeof window.reactive_ruby_timing !== 'undefined'`
113
+ @nesting_level = (@nesting_level || 0) + 1
114
+ start_time = Time.now.to_f
115
+ observer_name = (observer.class.respond_to?(:name) ? observer.class.name : observer.to_s) rescue "object:#{observer.object_id}"
116
+ end
117
+ saved_current_observer = @current_observer
118
+ @current_observer = observer
119
+ return_value = yield
120
+ return_value
121
+ ensure
122
+ @current_observer = saved_current_observer
123
+ @nesting_level = [0, @nesting_level - 1].max if `typeof window.reactive_ruby_timing !== 'undefined'`
124
+ return_value
125
+ end
126
+
127
+ def states
128
+ @states ||= Hash.new { |h, k| h[k] = {} }
129
+ end
130
+
131
+ [:new_observers, :current_observers, :observers_by_name].each do |method_name|
132
+ define_method(method_name) do
133
+ instance_variable_get("@#{method_name}") or
134
+ instance_variable_set("@#{method_name}", Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = [] } })
135
+ end
136
+ end
137
+
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,97 @@
1
+ require "native"
2
+ require 'active_support'
3
+ require 'react/component/base'
4
+
5
+ module React
6
+ HTML_TAGS = %w(a abbr address area article aside audio b base bdi bdo big blockquote body br
7
+ button canvas caption cite code col colgroup data datalist dd del details dfn
8
+ dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
9
+ h6 head header hr html i iframe img input ins kbd keygen label legend li link
10
+ main map mark menu menuitem meta meter nav noscript object ol optgroup option
11
+ output p param picture pre progress q rp rt ruby s samp script section select
12
+ small source span strong style sub summary sup table tbody td textarea tfoot th
13
+ thead time title tr track u ul var video wbr)
14
+ ATTRIBUTES = %w(accept acceptCharset accessKey action allowFullScreen allowTransparency alt
15
+ async autoComplete autoPlay cellPadding cellSpacing charSet checked classID
16
+ className cols colSpan content contentEditable contextMenu controls coords
17
+ crossOrigin data dateTime defer dir disabled download draggable encType form
18
+ formAction formEncType formMethod formNoValidate formTarget frameBorder height
19
+ hidden href hrefLang htmlFor httpEquiv icon id label lang list loop manifest
20
+ marginHeight marginWidth max maxLength media mediaGroup method min multiple
21
+ muted name noValidate open pattern placeholder poster preload radioGroup
22
+ readOnly rel required role rows rowSpan sandbox scope scrolling seamless
23
+ selected shape size sizes span spellCheck src srcDoc srcSet start step style
24
+ tabIndex target title type useMap value width wmode dangerouslySetInnerHTML)
25
+
26
+ def self.create_element(type, properties = {}, &block)
27
+ React::API.create_element(type, properties, &block)
28
+ end
29
+
30
+ def self.render(element, container)
31
+ container = `container.$$class ? container[0] : container`
32
+ if !(`typeof ReactDOM === 'undefined'`)
33
+ component = Native(`ReactDOM.render(#{element.to_n}, container, function(){#{yield if block_given?}})`) # v0.15+
34
+ elsif !(`typeof React.renderToString === 'undefined'`)
35
+ component = Native(`React.render(#{element.to_n}, container, function(){#{yield if block_given?}})`)
36
+ else
37
+ raise "render is not defined. In React >= v15 you must import it with ReactDOM"
38
+ end
39
+
40
+ component.class.include(React::Component::API)
41
+ component
42
+ end
43
+
44
+ def self.is_valid_element(element)
45
+ element.kind_of?(React::Element) && `React.isValidElement(#{element.to_n})`
46
+ end
47
+
48
+ def self.render_to_string(element)
49
+ if !(`typeof ReactDOMServer === 'undefined'`)
50
+ React::RenderingContext.build { `ReactDOMServer.renderToString(#{element.to_n})` } # v0.15+
51
+ elsif !(`typeof React.renderToString === 'undefined'`)
52
+ React::RenderingContext.build { `React.renderToString(#{element.to_n})` }
53
+ else
54
+ raise "renderToString is not defined. In React >= v15 you must import it with ReactDOMServer"
55
+ end
56
+ end
57
+
58
+ def self.render_to_static_markup(element)
59
+ if !(`typeof ReactDOMServer === 'undefined'`)
60
+ React::RenderingContext.build { `ReactDOMServer.renderToStaticMarkup(#{element.to_n})` } # v0.15+
61
+ elsif !(`typeof React.renderToString === 'undefined'`)
62
+ React::RenderingContext.build { `React.renderToStaticMarkup(#{element.to_n})` }
63
+ else
64
+ raise "renderToStaticMarkup is not defined. In React >= v15 you must import it with ReactDOMServer"
65
+ end
66
+ end
67
+
68
+ def self.unmount_component_at_node(node)
69
+ if !(`typeof ReactDOM === 'undefined'`)
70
+ `ReactDOM.unmountComponentAtNode(node.$$class ? node[0] : node)` # v0.15+
71
+ elsif !(`typeof React.renderToString === 'undefined'`)
72
+ `React.unmountComponentAtNode(node.$$class ? node[0] : node)`
73
+ else
74
+ raise "unmountComponentAtNode is not defined. In React >= v15 you must import it with ReactDOM"
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ Element.instance_eval do
81
+
82
+ class ::Element::DummyContext < React::Component::Base
83
+ end
84
+
85
+ def self.find(selector)
86
+ selector = selector.dom_node if selector.respond_to? :dom_node rescue selector
87
+ `$(#{selector})`
88
+ end
89
+
90
+ def self.[](selector)
91
+ find(selector)
92
+ end
93
+
94
+ def render(&block)
95
+ React.render(React::RenderingContext.render(nil) {::Element::DummyContext.new.instance_eval &block}, self)
96
+ end
97
+ end if Object.const_defined?("Element")