react-rails 1.7.2 → 1.8.0

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