react-rails 1.7.2 → 1.8.0

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
  SHA1:
3
- metadata.gz: 317dcc49fd51fff94c69147c9cb9a66863af8cc1
4
- data.tar.gz: 747c8e7a64afc813f317ee0e87c687b510027ace
3
+ metadata.gz: 14415b72eed9bf0a03780737bbaad51eee104435
4
+ data.tar.gz: 2b2a2dd99a46a493ae2597ebb1f5c031e30eec99
5
5
  SHA512:
6
- metadata.gz: dece437df496cb2260286e513821886ea394a1f445b26b2d435b4b87444365ba14055ce2748aa282343992b80751b6a0178e062ab4b9a6ccb94db1cdba314d46
7
- data.tar.gz: 59c476692c2cc549607a01bd662c57f5c0c1786af55ebcc8a75696ecf6a816aec001508cda55ab4ec309d884e2c2e2c98f71ddee9fa2544b87a71e72fe7be2a2
6
+ metadata.gz: 0b59ba10ae649678f0ae74a6e427e7911da83e212df6b26593818778c30d6100d93f5797e8632e584e02cf873a5289e2fefc318bc922693fef12fb405e9ca63d
7
+ data.tar.gz: e7525c73b8ce2262b555295510af870f715886c441b3614f5b8fd223fae372c34583a2bb676faeef3824e27bfb6ce6248840dc1fb819128eb329ca52f287020b
@@ -8,7 +8,18 @@
8
8
 
9
9
  #### Bug Fixes
10
10
 
11
- ## 1.7.2 (Jun3 19, 2016)
11
+ ## 1.8.0 (June 29, 2016)
12
+
13
+ #### New Features
14
+
15
+ - Sprockets 4 Support 🎉 #560
16
+ - Depend on Railties, not Rails #558
17
+ - Don't depend on `sprockets/railtie` #558
18
+ - Expose `React.camelize_props(props_hash)` #556
19
+ - Add `rails generate react:ujs --output=...` for copying the UJS into your app #557
20
+ - Support Babel 6 module exports & extension point `ReactRailsUJS.getConstructor` #503
21
+
22
+ ## 1.7.2 (June 19, 2016)
12
23
 
13
24
  #### New Features
14
25
 
@@ -42,6 +42,30 @@
42
42
  }
43
43
  },
44
44
 
45
+ // Get the constructor for a className
46
+ getConstructor: function(className) {
47
+ // Assume className is simple and can be found at top-level (window).
48
+ // Fallback to eval to handle cases like 'My.React.ComponentName'.
49
+ // Also, try to gracefully import Babel 6 style default exports
50
+ //
51
+ var constructor;
52
+
53
+ // Try to access the class globally first
54
+ constructor = window[className];
55
+
56
+ // If that didn't work, try eval
57
+ if (!constructor) {
58
+ constructor = eval.call(window, className);
59
+ }
60
+
61
+ // Lastly, if there is a default attribute try that
62
+ if (constructor && constructor.default) {
63
+ constructor = constructor.default;
64
+ }
65
+
66
+ return constructor;
67
+ },
68
+
45
69
  // Within `searchSelector`, find nodes which should have React components
46
70
  // inside them, and mount them with their props.
47
71
  mountComponents: function(searchSelector) {
@@ -50,10 +74,7 @@
50
74
  for (var i = 0; i < nodes.length; ++i) {
51
75
  var node = nodes[i];
52
76
  var className = node.getAttribute(window.ReactRailsUJS.CLASS_NAME_ATTR);
53
-
54
- // Assume className is simple and can be found at top-level (window).
55
- // Fallback to eval to handle cases like 'My.React.ComponentName'.
56
- var constructor = window[className] || eval.call(window, className);
77
+ var constructor = this.getConstructor(className);
57
78
  var propsJson = node.getAttribute(window.ReactRailsUJS.PROPS_ATTR);
58
79
  var props = propsJson && JSON.parse(propsJson);
59
80
 
@@ -0,0 +1,44 @@
1
+ module React
2
+ module Generators
3
+ class UjsGenerator < ::Rails::Generators::Base
4
+ desc "Create a custom copy of react_ujs for your application"
5
+
6
+ class_option :output, required: true, desc: "File path for new react_ujs.js"
7
+
8
+ class_option :turbolinks, type: :boolean, default: true, desc: "Include Turbolinks 5 support?"
9
+ class_option :turbolinks_classic, type: :boolean, default: true, desc: "Include Turbolinks 2.4 / 3 support?"
10
+ class_option :turbolinks_classic_deprecated, type: :boolean, default: true, desc: "Include Turbolinks < 2.4 support?"
11
+ class_option :pjax, type: :boolean, default: true, desc: "Include PJAX support?"
12
+ class_option :native, type: :boolean, default: true, desc: "Include native events support?"
13
+
14
+ EVENT_SUPPORT_OPTIONS = [
15
+ :turbolinks,
16
+ :turbolinks_classic,
17
+ :turbolinks_classic_deprecated,
18
+ :pjax,
19
+ :native,
20
+ ]
21
+
22
+ def create_ujs_file
23
+ files_to_merge = ["react_ujs_mount.js"]
24
+
25
+ EVENT_SUPPORT_OPTIONS.each do |event_support_option|
26
+ if options[event_support_option]
27
+ files_to_merge << "react_ujs_#{event_support_option}.js"
28
+ end
29
+ end
30
+
31
+ files_to_merge << "react_ujs_event_setup.js"
32
+
33
+ asset_dir = File.expand_path("../../../assets/javascripts", __FILE__)
34
+
35
+ custom_ujs_content = files_to_merge
36
+ .map { |filename| File.read(File.join(asset_dir, filename)) }
37
+ .join("\n")
38
+
39
+ new_ujs_path = options[:output]
40
+ create_file(new_ujs_path, custom_ujs_content)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,4 +1,4 @@
1
+ require 'react'
1
2
  require 'react/jsx'
2
3
  require 'react/rails'
3
4
  require 'react/server_rendering'
4
-
@@ -0,0 +1,19 @@
1
+ module React
2
+ # Recursively camelize `props`, returning a new Hash
3
+ # @param props [Object] If it's a Hash or Array, it will be recursed. Otherwise it will be returned.
4
+ # @return [Hash] a new hash whose keys are camelized strings
5
+ def self.camelize_props(props)
6
+ case props
7
+ when Hash
8
+ props.each_with_object({}) do |(key, value), new_props|
9
+ new_key = key.to_s.camelize(:lower)
10
+ new_value = camelize_props(value)
11
+ new_props[new_key] = new_value
12
+ end
13
+ when Array
14
+ props.map { |item| camelize_props(item) }
15
+ else
16
+ props
17
+ end
18
+ end
19
+ end
@@ -1,6 +1,7 @@
1
1
  require 'babel/transpiler'
2
2
  module React
3
3
  module JSX
4
+ # A {React::JSX}-compliant transformer which uses `Babel::Transpiler` to transform JSX.
4
5
  class BabelTransformer
5
6
  DEPRECATED_OPTIONS = [:harmony, :strip_types, :asset_path]
6
7
  DEFAULT_TRANSFORM_OPTIONS = { blacklist: ['spec.functionName', 'validation.react', 'strict'] }
@@ -1,5 +1,6 @@
1
1
  module React
2
2
  module JSX
3
+ # A {React::JSX}-compliant transformer which uses the deprecated `JSXTransformer.js` to transform JSX.
3
4
  class JSXTransformer
4
5
  DEFAULT_ASSET_PATH = 'JSXTransformer.js'
5
6
 
@@ -1,5 +1,6 @@
1
1
  module React
2
2
  module JSX
3
+ # A Sprockets 3+-compliant processor
3
4
  class Processor
4
5
  def self.call(input)
5
6
  JSX::transform(input[:data])
@@ -2,7 +2,7 @@ require 'tilt'
2
2
 
3
3
  module React
4
4
  module JSX
5
-
5
+ # Sprockets 2-compliant processor
6
6
  class Template < Tilt::Template
7
7
  self.default_mime_type = 'application/javascript'
8
8
 
@@ -1,13 +1,23 @@
1
1
  module React
2
2
  module Rails
3
+ # This class accepts some options for which build you want, then exposes where you can find
4
+ # them. In general, these paths should be added to the sprockets environment.
3
5
  class AssetVariant
4
6
  GEM_ROOT = Pathname.new('../../../../').expand_path(__FILE__)
5
- attr_reader :react_build, :react_directory, :jsx_directory
7
+ # @return [String] "production" or "development"
8
+ attr_reader :react_build
6
9
 
10
+ # @return [String] The path which contains the specified React.js build as "react.js"
11
+ attr_reader :react_directory
12
+
13
+ # @return [String] The path which contains the JSX Transformer
14
+ attr_reader :jsx_directory
15
+
16
+ # @param [Hash] Options for the asset variant
17
+ # @option variant [Symbol] if `:production`, use the minified React.js build
18
+ # @option addons [Boolean] if true, use a React.js build with all addons
7
19
  def initialize(options={})
8
- # We want to include different files in dev/prod. The development builds
9
- # contain console logging for invariants and logging to help catch
10
- # common mistakes. These are all stripped out in the production build.
20
+
11
21
  @react_build = options[:variant] == :production ? 'production' : 'development'
12
22
  options[:addons] && @react_build += '-with-addons'
13
23
 
@@ -24,7 +24,9 @@ module React
24
24
  # on the client.
25
25
  def react_component(name, props = {}, options = {}, &block)
26
26
  options = {:tag => options} if options.is_a?(Symbol)
27
- props = camelize_props_key(props) if camelize_props_switch
27
+ if camelize_props_switch
28
+ props = React.camelize_props(props)
29
+ end
28
30
 
29
31
  prerender_options = options[:prerender]
30
32
  if prerender_options
@@ -45,23 +47,6 @@ module React
45
47
 
46
48
  content_tag(html_tag, '', html_options, &block)
47
49
  end
48
-
49
- private
50
-
51
- def camelize_props_key(props)
52
- return props unless props.is_a?(Hash)
53
- props.inject({}) do |h, (k,v)|
54
- h[k.to_s.camelize(:lower)] = case v
55
- when Hash
56
- camelize_props_key(v)
57
- when Array
58
- v.map {|i| camelize_props_key(i) }
59
- else
60
- v
61
- end
62
- h
63
- end
64
- end
65
50
  end
66
51
  end
67
52
  end
@@ -1,18 +1,35 @@
1
- class React::Rails::ControllerRenderer
2
- include React::Rails::ViewHelper
3
- include ActionView::Helpers::TagHelper
4
- include ActionView::Helpers::TextHelper
1
+ module React
2
+ module Rails
3
+ # A renderer class suitable for `ActionController::Renderers`.
4
+ # It is associated to `:component` in the Railtie.
5
+ #
6
+ # It is prerendered with {React::ServerRendering}.
7
+ #
8
+ # @example Rendering a component from a controller
9
+ # class TodosController < ApplicationController
10
+ # def index
11
+ # @todos = Todo.all
12
+ # render component: 'TodoList', props: { todos: @todos }, tag: 'span', class: 'todo'
13
+ # end
14
+ # end
15
+ class ControllerRenderer
16
+ include React::Rails::ViewHelper
17
+ include ActionView::Helpers::TagHelper
18
+ include ActionView::Helpers::TextHelper
5
19
 
6
- attr_accessor :output_buffer
20
+ attr_accessor :output_buffer
7
21
 
8
- def initialize(options={})
9
- controller = options[:controller]
10
- @__react_component_helper = controller.__react_component_helper
11
- end
22
+ def initialize(options={})
23
+ controller = options[:controller]
24
+ @__react_component_helper = controller.__react_component_helper
25
+ end
12
26
 
13
- def call(name, options, &block)
14
- props = options.fetch(:props, {})
15
- options = options.slice(:data, :aria, :tag, :class, :id).merge(prerender: true)
16
- react_component(name, props, options, &block)
27
+ # @return [String] Prerendered HTML for `component_name` with `options[:props]`
28
+ def call(component_name, options, &block)
29
+ props = options.fetch(:props, {})
30
+ options = options.slice(:data, :aria, :tag, :class, :id).merge(prerender: true)
31
+ react_component(component_name, props, options, &block)
32
+ end
33
+ end
17
34
  end
18
35
  end
@@ -59,8 +59,10 @@ module React
59
59
  addons: app.config.react.addons,
60
60
  })
61
61
 
62
- sprockets_env = app.assets || app.config.assets # sprockets-rails 3.x attaches this at a different config
63
- sprockets_env.version = [sprockets_env.version, "react-#{asset_variant.react_build}",].compact.join('-')
62
+ sprockets_env = app.assets || app.config.try(:assets) # sprockets-rails 3.x attaches this at a different config
63
+ if !sprockets_env.nil?
64
+ sprockets_env.version = [sprockets_env.version, "react-#{asset_variant.react_build}",].compact.join('-')
65
+ end
64
66
 
65
67
  end
66
68
 
@@ -70,8 +72,10 @@ module React
70
72
  addons: app.config.react.addons,
71
73
  })
72
74
 
73
- app.config.assets.paths << asset_variant.react_directory
74
- app.config.assets.paths << asset_variant.jsx_directory
75
+ if app.config.respond_to?(:assets)
76
+ app.config.assets.paths << asset_variant.react_directory
77
+ app.config.assets.paths << asset_variant.jsx_directory
78
+ end
75
79
  end
76
80
 
77
81
  config.after_initialize do |app|
@@ -93,14 +97,20 @@ module React
93
97
  end
94
98
 
95
99
  initializer "react_rails.setup_engine", :group => :all do |app|
96
- sprockets_env = app.assets || Sprockets # Sprockets 3.x expects this in a different place
97
- if Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new("4.x")
98
- sprockets_env.register_mime_type("application/jsx", extensions: [".jsx", ".js.jsx", ".es.jsx", ".es6.jsx"])
99
- sprockets_env.register_transformer("application/jsx", "application/javascript", React::JSX::Processor)
100
- elsif Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new("3.0.0")
101
- sprockets_env.register_engine(".jsx", React::JSX::Processor, mime_type: "application/javascript")
102
- else
103
- sprockets_env.register_engine(".jsx", React::JSX::Template)
100
+ # Sprockets 3.x expects this in a different place
101
+ sprockets_env = app.assets || defined?(Sprockets) && Sprockets
102
+
103
+ if !sprockets_env.nil?
104
+ if Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new("4.x")
105
+ sprockets_env.register_mime_type("application/jsx", extensions: [".jsx", ".js.jsx", ".es.jsx", ".es6.jsx"])
106
+ sprockets_env.register_transformer("application/jsx", "application/javascript", React::JSX::Processor)
107
+ sprockets_env.register_mime_type("application/jsx+coffee", extensions: [".jsx.coffee", ".js.jsx.coffee"])
108
+ sprockets_env.register_transformer("application/jsx+coffee", "application/jsx", Sprockets::CoffeeScriptProcessor)
109
+ elsif Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new("3.0.0")
110
+ sprockets_env.register_engine(".jsx", React::JSX::Processor, mime_type: "application/javascript")
111
+ else
112
+ sprockets_env.register_engine(".jsx", React::JSX::Template)
113
+ end
104
114
  end
105
115
  end
106
116
  end
@@ -2,6 +2,6 @@ module React
2
2
  module Rails
3
3
  # If you change this, make sure to update VERSIONS.md
4
4
  # And the version hint in README.md, if needed
5
- VERSION = '1.7.2'
5
+ VERSION = "1.8.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul O’Shannessy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-20 00:00:00.000000000 Z
11
+ date: 2016-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: 2.0.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: rails
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '3.2'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '3.2'
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: coffee-script-source
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -221,7 +235,7 @@ dependencies:
221
235
  - !ruby/object:Gem::Version
222
236
  version: '0'
223
237
  - !ruby/object:Gem::Dependency
224
- name: rails
238
+ name: railties
225
239
  requirement: !ruby/object:Gem::Requirement
226
240
  requirements:
227
241
  - - ">="
@@ -307,10 +321,12 @@ files:
307
321
  - lib/assets/react-source/production/react.js
308
322
  - lib/generators/react/component_generator.rb
309
323
  - lib/generators/react/install_generator.rb
324
+ - lib/generators/react/ujs_generator.rb
310
325
  - lib/generators/templates/component.es6.jsx
311
326
  - lib/generators/templates/component.js.jsx
312
327
  - lib/generators/templates/component.js.jsx.coffee
313
328
  - lib/react-rails.rb
329
+ - lib/react.rb
314
330
  - lib/react/jsx.rb
315
331
  - lib/react/jsx/babel_transformer.rb
316
332
  - lib/react/jsx/jsx_transformer.rb